Files
epgphp/update.php
mxdabc 57dae083a6 init: Upload Code From Github
要提交的变更:
	修改:     README.md
	新文件:   README_zh-CN.md
	新文件:   assets/CHANGELOG.md
	新文件:   assets/Parsedown.php
	新文件:   assets/css/login.css
	新文件:   assets/css/manage.css
	新文件:   assets/defaultConfig.json
	新文件:   assets/defaultIconList.json
	新文件:   assets/html/favicon.ico
	新文件:   assets/html/login.html
	新文件:   assets/html/manage.html
	新文件:   assets/js/console.js
	新文件:   assets/js/manage.js
	新文件:   assets/opencc/composer.json
	新文件:   assets/opencc/composer.lock
	新文件:   assets/opencc/vendor/autoload.php
	新文件:   assets/opencc/vendor/bin/opencc
	新文件:   assets/opencc/vendor/composer/ClassLoader.php
	新文件:   assets/opencc/vendor/composer/InstalledVersions.php
	新文件:   assets/opencc/vendor/composer/LICENSE
	新文件:   assets/opencc/vendor/composer/autoload_classmap.php
	新文件:   assets/opencc/vendor/composer/autoload_files.php
	新文件:   assets/opencc/vendor/composer/autoload_namespaces.php
	新文件:   assets/opencc/vendor/composer/autoload_psr4.php
	新文件:   assets/opencc/vendor/composer/autoload_real.php
	新文件:   assets/opencc/vendor/composer/autoload_static.php
	新文件:   assets/opencc/vendor/composer/installed.json
	新文件:   assets/opencc/vendor/composer/installed.php
	新文件:   assets/opencc/vendor/composer/platform_check.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/.editorconfig
	新文件:   assets/opencc/vendor/overtrue/php-opencc/.github/FUNDING.yml
	新文件:   assets/opencc/vendor/overtrue/php-opencc/.github/workflows/test.yml
	新文件:   assets/opencc/vendor/overtrue/php-opencc/LICENSE
	新文件:   assets/opencc/vendor/overtrue/php-opencc/README.md
	新文件:   assets/opencc/vendor/overtrue/php-opencc/bin/build
	新文件:   assets/opencc/vendor/overtrue/php-opencc/bin/opencc
	新文件:   assets/opencc/vendor/overtrue/php-opencc/composer.json
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/HKVariants.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/HKVariantsRevPhrases.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/JPShinjitaiCharacters.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/JPShinjitaiPhrases.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/JPVariants.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/README.md
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/STCharacters.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/STPhrases.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TSCharacters.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TSPhrases.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TWPhrasesIT.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TWPhrasesName.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TWPhrasesOther.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TWVariants.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/dictionary/TWVariantsRevPhrases.txt
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/HKVariants.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/HKVariantsRev.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/HKVariantsRevPhrases.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/JPShinjitaiCharacters.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/JPShinjitaiPhrases.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/JPVariants.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/JPVariantsRev.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/STCharacters.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/STPhrases.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TSCharacters.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TSPhrases.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWPhrases.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWPhrasesIT.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWPhrasesName.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWPhrasesOther.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWPhrasesRev.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWVariants.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWVariantsRev.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/data/parsed/TWVariantsRevPhrases.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/Console/BuildCommand.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/Console/ConvertCommand.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/Contracts/ConverterInterface.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/Converter.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/Dictionary.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/OpenCC.php
	新文件:   assets/opencc/vendor/overtrue/php-opencc/src/Strategy.php
	新文件:   assets/opencc/vendor/psr/container/.gitignore
	新文件:   assets/opencc/vendor/psr/container/LICENSE
	新文件:   assets/opencc/vendor/psr/container/README.md
	新文件:   assets/opencc/vendor/psr/container/composer.json
	新文件:   assets/opencc/vendor/psr/container/src/ContainerExceptionInterface.php
	新文件:   assets/opencc/vendor/psr/container/src/ContainerInterface.php
	新文件:   assets/opencc/vendor/psr/container/src/NotFoundExceptionInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Application.php
	新文件:   assets/opencc/vendor/symfony/console/Attribute/AsCommand.php
	新文件:   assets/opencc/vendor/symfony/console/CHANGELOG.md
	新文件:   assets/opencc/vendor/symfony/console/CI/GithubActionReporter.php
	新文件:   assets/opencc/vendor/symfony/console/Color.php
	新文件:   assets/opencc/vendor/symfony/console/Command/Command.php
	新文件:   assets/opencc/vendor/symfony/console/Command/CompleteCommand.php
	新文件:   assets/opencc/vendor/symfony/console/Command/DumpCompletionCommand.php
	新文件:   assets/opencc/vendor/symfony/console/Command/HelpCommand.php
	新文件:   assets/opencc/vendor/symfony/console/Command/LazyCommand.php
	新文件:   assets/opencc/vendor/symfony/console/Command/ListCommand.php
	新文件:   assets/opencc/vendor/symfony/console/Command/LockableTrait.php
	新文件:   assets/opencc/vendor/symfony/console/Command/SignalableCommandInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Command/TraceableCommand.php
	新文件:   assets/opencc/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php
	新文件:   assets/opencc/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
	新文件:   assets/opencc/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/CompletionInput.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/CompletionSuggestions.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/Output/BashCompletionOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/Output/FishCompletionOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Completion/Suggestion.php
	新文件:   assets/opencc/vendor/symfony/console/ConsoleEvents.php
	新文件:   assets/opencc/vendor/symfony/console/Cursor.php
	新文件:   assets/opencc/vendor/symfony/console/DataCollector/CommandDataCollector.php
	新文件:   assets/opencc/vendor/symfony/console/Debug/CliRequest.php
	新文件:   assets/opencc/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/ApplicationDescription.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/Descriptor.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/DescriptorInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/JsonDescriptor.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/TextDescriptor.php
	新文件:   assets/opencc/vendor/symfony/console/Descriptor/XmlDescriptor.php
	新文件:   assets/opencc/vendor/symfony/console/Event/ConsoleCommandEvent.php
	新文件:   assets/opencc/vendor/symfony/console/Event/ConsoleErrorEvent.php
	新文件:   assets/opencc/vendor/symfony/console/Event/ConsoleEvent.php
	新文件:   assets/opencc/vendor/symfony/console/Event/ConsoleSignalEvent.php
	新文件:   assets/opencc/vendor/symfony/console/Event/ConsoleTerminateEvent.php
	新文件:   assets/opencc/vendor/symfony/console/EventListener/ErrorListener.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/CommandNotFoundException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/ExceptionInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/InvalidArgumentException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/InvalidOptionException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/LogicException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/MissingInputException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/NamespaceNotFoundException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/RunCommandFailedException.php
	新文件:   assets/opencc/vendor/symfony/console/Exception/RuntimeException.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/NullOutputFormatter.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/OutputFormatter.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/OutputFormatterInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/OutputFormatterStyle.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
	新文件:   assets/opencc/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/DebugFormatterHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/DescriptorHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/Dumper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/FormatterHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/Helper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/HelperInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/HelperSet.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/InputAwareHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/OutputWrapper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/ProcessHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/ProgressBar.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/ProgressIndicator.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/QuestionHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/Table.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/TableCell.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/TableCellStyle.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/TableRows.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/TableSeparator.php
	新文件:   assets/opencc/vendor/symfony/console/Helper/TableStyle.php
	新文件:   assets/opencc/vendor/symfony/console/Input/ArgvInput.php
	新文件:   assets/opencc/vendor/symfony/console/Input/ArrayInput.php
	新文件:   assets/opencc/vendor/symfony/console/Input/Input.php
	新文件:   assets/opencc/vendor/symfony/console/Input/InputArgument.php
	新文件:   assets/opencc/vendor/symfony/console/Input/InputAwareInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Input/InputDefinition.php
	新文件:   assets/opencc/vendor/symfony/console/Input/InputInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Input/InputOption.php
	新文件:   assets/opencc/vendor/symfony/console/Input/StreamableInputInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Input/StringInput.php
	新文件:   assets/opencc/vendor/symfony/console/LICENSE
	新文件:   assets/opencc/vendor/symfony/console/Logger/ConsoleLogger.php
	新文件:   assets/opencc/vendor/symfony/console/Messenger/RunCommandContext.php
	新文件:   assets/opencc/vendor/symfony/console/Messenger/RunCommandMessage.php
	新文件:   assets/opencc/vendor/symfony/console/Messenger/RunCommandMessageHandler.php
	新文件:   assets/opencc/vendor/symfony/console/Output/AnsiColorMode.php
	新文件:   assets/opencc/vendor/symfony/console/Output/BufferedOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Output/ConsoleOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Output/ConsoleOutputInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Output/ConsoleSectionOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Output/NullOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Output/Output.php
	新文件:   assets/opencc/vendor/symfony/console/Output/OutputInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Output/StreamOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Output/TrimmedBufferOutput.php
	新文件:   assets/opencc/vendor/symfony/console/Question/ChoiceQuestion.php
	新文件:   assets/opencc/vendor/symfony/console/Question/ConfirmationQuestion.php
	新文件:   assets/opencc/vendor/symfony/console/Question/Question.php
	新文件:   assets/opencc/vendor/symfony/console/README.md
	新文件:   assets/opencc/vendor/symfony/console/Resources/bin/hiddeninput.exe
	新文件:   assets/opencc/vendor/symfony/console/Resources/completion.bash
	新文件:   assets/opencc/vendor/symfony/console/Resources/completion.fish
	新文件:   assets/opencc/vendor/symfony/console/Resources/completion.zsh
	新文件:   assets/opencc/vendor/symfony/console/SignalRegistry/SignalMap.php
	新文件:   assets/opencc/vendor/symfony/console/SignalRegistry/SignalRegistry.php
	新文件:   assets/opencc/vendor/symfony/console/SingleCommandApplication.php
	新文件:   assets/opencc/vendor/symfony/console/Style/OutputStyle.php
	新文件:   assets/opencc/vendor/symfony/console/Style/StyleInterface.php
	新文件:   assets/opencc/vendor/symfony/console/Style/SymfonyStyle.php
	新文件:   assets/opencc/vendor/symfony/console/Terminal.php
	新文件:   assets/opencc/vendor/symfony/console/Tester/ApplicationTester.php
	新文件:   assets/opencc/vendor/symfony/console/Tester/CommandCompletionTester.php
	新文件:   assets/opencc/vendor/symfony/console/Tester/CommandTester.php
	新文件:   assets/opencc/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php
	新文件:   assets/opencc/vendor/symfony/console/Tester/TesterTrait.php
	新文件:   assets/opencc/vendor/symfony/console/composer.json
	新文件:   assets/opencc/vendor/symfony/deprecation-contracts/CHANGELOG.md
	新文件:   assets/opencc/vendor/symfony/deprecation-contracts/LICENSE
	新文件:   assets/opencc/vendor/symfony/deprecation-contracts/README.md
	新文件:   assets/opencc/vendor/symfony/deprecation-contracts/composer.json
	新文件:   assets/opencc/vendor/symfony/deprecation-contracts/function.php
	新文件:   assets/opencc/vendor/symfony/polyfill-ctype/Ctype.php
	新文件:   assets/opencc/vendor/symfony/polyfill-ctype/LICENSE
	新文件:   assets/opencc/vendor/symfony/polyfill-ctype/README.md
	新文件:   assets/opencc/vendor/symfony/polyfill-ctype/bootstrap.php
	新文件:   assets/opencc/vendor/symfony/polyfill-ctype/bootstrap80.php
	新文件:   assets/opencc/vendor/symfony/polyfill-ctype/composer.json
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-grapheme/Grapheme.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-grapheme/LICENSE
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-grapheme/README.md
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-grapheme/bootstrap.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-grapheme/composer.json
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/LICENSE
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/Normalizer.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/README.md
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/bootstrap.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php
	新文件:   assets/opencc/vendor/symfony/polyfill-intl-normalizer/composer.json
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/LICENSE
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/Mbstring.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/README.md
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/bootstrap.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/bootstrap80.php
	新文件:   assets/opencc/vendor/symfony/polyfill-mbstring/composer.json
	新文件:   assets/opencc/vendor/symfony/process/CHANGELOG.md
	新文件:   assets/opencc/vendor/symfony/process/Exception/ExceptionInterface.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/InvalidArgumentException.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/LogicException.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/ProcessFailedException.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/ProcessSignaledException.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/ProcessTimedOutException.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/RunProcessFailedException.php
	新文件:   assets/opencc/vendor/symfony/process/Exception/RuntimeException.php
	新文件:   assets/opencc/vendor/symfony/process/ExecutableFinder.php
	新文件:   assets/opencc/vendor/symfony/process/InputStream.php
	新文件:   assets/opencc/vendor/symfony/process/LICENSE
	新文件:   assets/opencc/vendor/symfony/process/Messenger/RunProcessContext.php
	新文件:   assets/opencc/vendor/symfony/process/Messenger/RunProcessMessage.php
	新文件:   assets/opencc/vendor/symfony/process/Messenger/RunProcessMessageHandler.php
	新文件:   assets/opencc/vendor/symfony/process/PhpExecutableFinder.php
	新文件:   assets/opencc/vendor/symfony/process/PhpProcess.php
	新文件:   assets/opencc/vendor/symfony/process/PhpSubprocess.php
	新文件:   assets/opencc/vendor/symfony/process/Pipes/AbstractPipes.php
	新文件:   assets/opencc/vendor/symfony/process/Pipes/PipesInterface.php
	新文件:   assets/opencc/vendor/symfony/process/Pipes/UnixPipes.php
	新文件:   assets/opencc/vendor/symfony/process/Pipes/WindowsPipes.php
	新文件:   assets/opencc/vendor/symfony/process/Process.php
	新文件:   assets/opencc/vendor/symfony/process/ProcessUtils.php
	新文件:   assets/opencc/vendor/symfony/process/README.md
	新文件:   assets/opencc/vendor/symfony/process/composer.json
	新文件:   assets/opencc/vendor/symfony/service-contracts/Attribute/Required.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/Attribute/SubscribedService.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/CHANGELOG.md
	新文件:   assets/opencc/vendor/symfony/service-contracts/LICENSE
	新文件:   assets/opencc/vendor/symfony/service-contracts/README.md
	新文件:   assets/opencc/vendor/symfony/service-contracts/ResetInterface.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/ServiceCollectionInterface.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/ServiceLocatorTrait.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/ServiceMethodsSubscriberTrait.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/ServiceProviderInterface.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/ServiceSubscriberInterface.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php
	新文件:   assets/opencc/vendor/symfony/service-contracts/composer.json
	新文件:   assets/opencc/vendor/symfony/string/AbstractString.php
	新文件:   assets/opencc/vendor/symfony/string/AbstractUnicodeString.php
	新文件:   assets/opencc/vendor/symfony/string/ByteString.php
	新文件:   assets/opencc/vendor/symfony/string/CHANGELOG.md
	新文件:   assets/opencc/vendor/symfony/string/CodePointString.php
	新文件:   assets/opencc/vendor/symfony/string/Exception/ExceptionInterface.php
	新文件:   assets/opencc/vendor/symfony/string/Exception/InvalidArgumentException.php
	新文件:   assets/opencc/vendor/symfony/string/Exception/RuntimeException.php
	新文件:   assets/opencc/vendor/symfony/string/Inflector/EnglishInflector.php
	新文件:   assets/opencc/vendor/symfony/string/Inflector/FrenchInflector.php
	新文件:   assets/opencc/vendor/symfony/string/Inflector/InflectorInterface.php
	新文件:   assets/opencc/vendor/symfony/string/LICENSE
	新文件:   assets/opencc/vendor/symfony/string/LazyString.php
	新文件:   assets/opencc/vendor/symfony/string/README.md
	新文件:   assets/opencc/vendor/symfony/string/Resources/data/wcswidth_table_wide.php
	新文件:   assets/opencc/vendor/symfony/string/Resources/data/wcswidth_table_zero.php
	新文件:   assets/opencc/vendor/symfony/string/Resources/functions.php
	新文件:   assets/opencc/vendor/symfony/string/Slugger/AsciiSlugger.php
	新文件:   assets/opencc/vendor/symfony/string/Slugger/SluggerInterface.php
	新文件:   assets/opencc/vendor/symfony/string/UnicodeString.php
	新文件:   assets/opencc/vendor/symfony/string/composer.json
	新文件:   assets/phpliteadmin.php
	新文件:   config/Caddyfile
	新文件:   config/nginx.conf
	新文件:   cron.php
	新文件:   cron/requirements.txt
	新文件:   cron/update.py
	新文件:   index.php
	新文件:   manage.php
	新文件:   public.php
	新文件:   update.php
2025-08-02 19:59:41 +08:00

588 lines
22 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @file update.php
* @brief 更新脚本
*
* 该脚本用于定期从配置的 XML 源下载节目数据,并将其存入 SQLite 数据库中。
*
* 作者: Tak
* GitHub: https://github.com/taksssss/EPG-Server
* 二次开发: mxdabc
* Github: https://github.com/mxdabc/epgphp
*/
// 禁用 PHP 输出缓冲
ob_implicit_flush(true);
@ob_end_flush();
// 设置 header防止浏览器缓存输出
header('X-Accel-Buffering: no');
// 显示 favicon
echo '<link rel="icon" href="assets/html/favicon.ico" type="image/x-icon">';
echo '<title>更新数据</title>';
// 引入公共脚本
require_once 'public.php';
ini_set('memory_limit', '256M');
// 设置超时时间为20分钟
set_time_limit(20*60);
// 删除过期数据和日志
function deleteOldData($db, &$log_messages) {
global $Config, $thresholdDate;
// 删除 t.xml 和 t.xml.gz 文件
@unlink(__DIR__ . '/t.xml');
@unlink(__DIR__ . '/t.xml.gz');
logMessage($log_messages, "[Start] 开始生成数据...");
echo "<strong>请注意:在生成数据期间无法访问XMLTV文件和API接口</strong>";
echo "<br>";
// 循环清理过期数据
$tables = [
'epg_data' => ['date', '清理EPG数据'],
'update_log' => ['timestamp', '清理更新日志'],
'cron_log' => ['timestamp', '清理定时日志']
];
foreach ($tables as $table => $values) {
list($column, $logMessage) = $values;
$stmt = $db->prepare("DELETE FROM $table WHERE $column < :thresholdDate");
$stmt->bindValue(':thresholdDate', $thresholdDate, PDO::PARAM_STR);
$stmt->execute();
logMessage($log_messages, "[{$logMessage}] 共 {$stmt->rowCount()} 条。");
}
// 清理 memcached 数据
if (class_exists('Memcached')) {
$memcached = new Memcached();
if ($memcached->addServer('127.0.0.1', 11211)) {
$memcached->flush();
logMessage($log_messages, "[Memcached] 已清空。");
} else {
logMessage($log_messages, "[Memcached] 状态异常。");
}
} else {
logMessage($log_messages, "[Memcached] 未安装。");
}
// 清理 redis 数据
if (class_exists('Redis')) {
$redis = new Redis();
try {
$redis->connect('127.0.0.1', 6379);
if (!empty($Config['redis_password'])) {
$redis->auth($Config['redis_password']);
}
$redis->flushAll();
logMessage($log_messages, "[Redis] 已清空。");
} catch (Exception $e) {
logMessage($log_messages, "[Redis] 状态异常:" . $e->getMessage());
}
} else {
logMessage($log_messages, "[Redis] 未安装。");
}
echo "<br>";
}
// 格式化时间函数,同时转化为 UTC+8 时间
function getFormatTime($time, $overwrite_time_zone) {
if (empty($time)) return ['', ''];
$time = $overwrite_time_zone ? substr($time, 0, -5) . $overwrite_time_zone : $time;
$time = str_replace(' ', '', $time);
$datetime = DateTime::createFromFormat('YmdHisO', $time);
if (!$datetime) return [null, null];
$datetime->setTimezone(new DateTimeZone('+0800'));
return [$datetime->format('Y-m-d'), $datetime->format('H:i')];
}
// 辅助函数:将日期和时间格式化为 XMLTV 格式
function formatTime($date, $time) {
return date('YmdHis O', strtotime("$date $time"));
}
// 获取限定频道列表及映射关系
function getGenList($db) {
global $Config;
$channels = $db->query("SELECT channel FROM gen_list")->fetchAll(PDO::FETCH_COLUMN);
if (empty($channels)) {
return ['gen_list_mapping' => [], 'gen_list' => []];
}
$channelsSimplified = explode("\n", t2s(implode("\n", $channels)));
$allEpgChannels = $db->query("SELECT DISTINCT channel FROM epg_data WHERE date = DATE('now')")
->fetchAll(PDO::FETCH_COLUMN); // 避免匹配只有历史 EPG 的频道
$gen_list_mapping = [];
$cleanedChannels = array_map('cleanChannelName', $channelsSimplified);
foreach ($cleanedChannels as $index => $cleanedChannel) {
$bestMatch = $cleanedChannel; // 默认使用清理后的频道名
$bestMatchLength = 0; // 初始为0表示未找到任何匹配
foreach ($allEpgChannels as $epgChannel) {
if (strcasecmp($cleanedChannel, $epgChannel) === 0) {
$bestMatch = $epgChannel;
break; // 精确匹配,立即跳出循环
}
// 模糊匹配并选择最长的频道名称
if ((stripos($epgChannel, $cleanedChannel) === 0 || stripos($cleanedChannel, $epgChannel) !== false)
&& strlen($epgChannel) > $bestMatchLength) {
$bestMatch = $epgChannel;
$bestMatchLength = strlen($epgChannel); // 更新为更长的匹配
}
}
// 将原始频道名称添加到映射数组中
$gen_list_mapping[$bestMatch][] = $channels[$index];
}
return [
'gen_list_mapping' => $gen_list_mapping,
'gen_list' => array_unique($cleanedChannels)
];
}
// 获取频道指定 EPG 关系
function getChannelBindEPG() {
global $Config;
$channelBindEPG = [];
foreach ($Config['channel_bind_epg'] ?? [] as $epg_src => $channels) {
foreach (array_map('trim', explode(',', $channels)) as $channel) {
$channelBindEPG[$channel][] = $epg_src;
}
}
return $channelBindEPG;
}
// 下载 XML 数据并存入数据库
function downloadXmlData($xml_url, $userAgent, $db, &$log_messages, $gen_list) {
global $Config;
$xml_data = downloadData($xml_url, $userAgent);
if ($xml_data !== false && stripos($xml_data, 'not found') === false) {
if (substr($xml_data, 0, 2) === "\x1F\x8B") { // 通过魔数判断 .gz 文件
$xml_data = gzdecode($xml_data);
if ($xml_data === false) {
logMessage($log_messages, ' [解压缩失败!!!]');
return;
}
}
// 获取文件大小(字节)并转换为 KB/MB
$fileSize = strlen($xml_data);
$fileSizeReadable = $fileSize >= 1048576
? round($fileSize / 1048576, 2) . ' MB'
: round($fileSize / 1024, 2) . ' KB';
logMessage($log_messages, "[下载] 成功: xml 文件 {$fileSizeReadable}");
$xml_data = preg_replace('/[\x00-\x1F]/u', ' ', $xml_data); // 清除所有控制字符
if (isset($Config['all_chs']) && $Config['all_chs']) { $xml_data = t2s($xml_data); }
$db->beginTransaction();
try {
$processCount = processXmlData($xml_url, $xml_data, $db, $gen_list);
$db->commit();
logMessage($log_messages, "[更新] 成功:共 {$processCount}");
} catch (Exception $e) {
$db->rollBack();
logMessage($log_messages, "[处理数据出错], 错误原因: " . $e->getMessage());
}
} else {
logMessage($log_messages, "[下载EPG数据] 失败!!!");
}
echo "<br>";
}
// 处理 XML 数据并逐步存入数据库
function processXmlData($xml_url, $xml_data, $db, $gen_list) {
global $Config, $processedRecords, $channel_bind_epg, $thresholdDate;
// 统计处理数据量
$processCount = 0;
$reader = new XMLReader();
if (!$reader->XML($xml_data)) {
throw new Exception("无法解析 XML 数据");
}
$cleanChannelNames = [];
// 读取频道数据
while ($reader->read() && $reader->name !== 'channel');
while ($reader->name === 'channel') {
$channel = new SimpleXMLElement($reader->readOuterXML());
$channelId = (string)$channel['id'];
$cleanChannelNames[$channelId] = cleanChannelName((string)$channel->{'display-name'});
$reader->next('channel');
}
// 繁简转换和频道筛选
$simplifiedChannelNames = (isset($Config['all_chs']) && $Config['all_chs']) ?
$cleanChannelNames : explode("\n", t2s(implode("\n", $cleanChannelNames)));
$channelNamesMap = [];
foreach ($cleanChannelNames as $channelId => $channelName) {
$channelNameSimplified = array_shift($simplifiedChannelNames);
// 假如 channel_bind_epg 存在且频道在其中有记录,且不为当前 xml_url直接跳过
if (!empty($channel_bind_epg) &&
isset($channel_bind_epg[$channelNameSimplified]) &&
!in_array($xml_url, $channel_bind_epg[$channelNameSimplified])
) {
continue; // 跳过当前循环,继续处理下一个
}
// 当 gen_list_enable 为 0 时,插入所有数据
if (empty($Config['gen_list_enable'])) {
$channelNamesMap[$channelId] = $channelNameSimplified;
continue;
}
$matchFound = false;
foreach ($gen_list as $item) {
if (stripos($channelNameSimplified, $item) !== false ||
stripos($item, $channelNameSimplified) !== false) {
$matchFound = true;
break;
}
}
if ($matchFound) {
$channelNamesMap[$channelId] = $channelNameSimplified;
}
}
$reader->close();
$reader->XML($xml_data); // 重置 XMLReader
while ($reader->read() && $reader->name !== 'programme');
$currentChannelProgrammes = [];
$crossDayProgrammes = []; // 保存跨天的节目数据
// 修正 epg.pw 时区错误
$overwrite_time_zone = strpos($xml_data, 'epg.pw') !== false ? '+0800' : '';
while ($reader->name === 'programme') {
$programme = new SimpleXMLElement($reader->readOuterXML());
[$startDate, $startTime] = getFormatTime((string)$programme['start'], $overwrite_time_zone);
[$endDate, $endTime] = getFormatTime((string)$programme['stop'], $overwrite_time_zone);
// 判断数据是否符合设定期限
if (empty($startDate) || $startDate < $thresholdDate || empty($endDate)) {
$reader->next('programme');
continue;
}
$channelId = (string)$programme['channel'];
$channelName = $channelNamesMap[$channelId] ?? null;
$recordKey = $channelName . '-' . $startDate;
// 优先处理跨天数据
if (isset($crossDayProgrammes[$channelId][$startDate]) && !isset($processedRecords[$recordKey])) {
$currentChannelProgrammes[$channelId]['diyp_data'][$startDate] = array_merge(
$currentChannelProgrammes[$channelId]['diyp_data'][$startDate] ?? [],
$crossDayProgrammes[$channelId][$startDate]
);
$currentChannelProgrammes[$channelId]['channel_name'] = $channelName;
unset($crossDayProgrammes[$channelId][$startDate]);
}
if ($channelName && !isset($processedRecords[$recordKey])) {
$programmeData = [
'start' => $startTime,
'end' => $startDate === $endDate ? $endTime : '00:00',
'title' => (string)$programme->title,
'desc' => isset($programme->desc) ? (string)$programme->desc : ''
];
$currentChannelProgrammes[$channelId]['diyp_data'][$startDate][] = $programmeData;
// 保存跨天的节目数据
if ($startDate !== $endDate && $endTime !== '00:00') {
$crossDayProgrammes[$channelId][$endDate][] = [
'start' => '00:00',
'end' => $endTime,
'title' => $programmeData['title'],
'desc' => $programmeData['desc']
];
}
$currentChannelProgrammes[$channelId]['channel_name'] = $channelName;
// 每次达到 50 时,插入数据并保留最后一条
if (count($currentChannelProgrammes) >= 50) {
$lastProgramme = array_pop($currentChannelProgrammes); // 取出最后一条
insertDataToDatabase($currentChannelProgrammes, $db, $xml_url); // 插入前 49 条
$currentChannelProgrammes = [$channelId => $lastProgramme]; // 清空并重新赋值最后一条
}
}
$processCount++;
$reader->next('programme');
}
// 插入剩余的数据
if ($currentChannelProgrammes) {
insertDataToDatabase($currentChannelProgrammes, $db, $xml_url);
}
$reader->close();
return $processCount;
}
// 从 epg_data 读取数据,生成 iconList.json 及 xmltv 文件
function processIconListAndXmltv($db, $gen_list_mapping, &$log_messages) {
global $Config, $iconList, $iconListPath;
$currentDate = date('Y-m-d'); // 获取当前日期
$dateCondition = $Config['include_future_only'] ? "WHERE date >= '$currentDate'" : '';
// 合并查询
$query = "SELECT date, channel, epg_diyp FROM epg_data $dateCondition ORDER BY channel ASC, date ASC";
$stmt = $db->query($query);
// 存储节目数据以按频道分组
$channelData = [];
while ($program = $stmt->fetch(PDO::FETCH_ASSOC)) {
$channelName = $program['channel'];
$iconUrl = iconUrlMatch($channelName, $getDefault = false);
if ($iconUrl) {
$iconList[strtoupper($channelName)] = $iconUrl;
$program['icon'] = $iconUrl;
}
// gen_list_enable 为 0 或存在映射,则处理频道数据
if (empty($Config['gen_list_enable']) || isset($gen_list_mapping[$channelName])) {
$channelData[$channelName][] = $program;
}
}
// 更新 iconList.json 文件中的数据
if (file_put_contents($iconListPath,
json_encode($iconList, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)) === false) {
logMessage($log_messages, "[台标列表] 更新 iconList.json 时发生错误!!!");
} else {
logMessage($log_messages, "[台标列表] 已更新 iconList.json");
}
logMessage($log_messages, "[XMLTV] 开始生成并写入XMLTV文件...");
// 判断是否生成 xmltv 文件
if (empty($Config['gen_xml'])) {
return;
}
// 创建 XMLWriter 实例
$xmlFilePath = __DIR__ . '/t.xml';
$xmlWriter = new XMLWriter();
$xmlWriter->openUri($xmlFilePath);
$xmlWriter->startDocument('1.0', 'UTF-8');
$xmlWriter->startElement('tv');
$xmlWriter->writeAttribute('generator-info-name', 'CrestekkEPG');
$xmlWriter->writeAttribute('generator-info-url', 'https://github.com/mxdabc/epgphp');
$xmlWriter->setIndent(true);
$xmlWriter->setIndentString(' '); // 设置缩进
// 将 $Config['channel_mappings'] 中的映射值转换为数组
$channelMappings = array_map(function($mapped) {
return strpos($mapped, 'regex:') === 0 ? [$mapped] : array_map('trim', explode(',', $mapped));
}, $Config['channel_mappings']);
// 逐个频道处理
foreach ($channelData as $channelName => $programs) {
// 写入频道信息
$xmlWriter->startElement('channel');
$xmlWriter->writeAttribute('id', htmlspecialchars($channelName, ENT_XML1, 'UTF-8'));
// 为该频道生成多个 display-name ,包括原频道名、限定频道列表、频道别名
$displayNames = array_unique(array_merge(
[$channelName],
$gen_list_mapping[$channelName] ?? [],
$channelMappings[$channelName] ?? []
));
foreach ($displayNames as $displayName) {
$xmlWriter->startElement('display-name');
$xmlWriter->writeAttribute('lang', 'zh');
$xmlWriter->text(htmlspecialchars($displayName, ENT_XML1, 'UTF-8'));
$xmlWriter->endElement(); // display-name
}
$iconUrl = $programs[0]['icon'] ?? '';
if ($iconUrl) {
$xmlWriter->startElement('icon');
$xmlWriter->writeAttribute('src', $iconUrl);
$xmlWriter->endElement(); // icon
}
$xmlWriter->endElement(); // channel
// 写入该频道的所有节目数据
foreach ($programs as $programIndex => &$program) {
$data = json_decode($program['epg_diyp'], true);
$dataCount = count($data['epg_data']);
$end_date = $program['date'];
for ($index = 0; $index < $dataCount; $index++) {
$item = $data['epg_data'][$index];
$end_time = $item['end'];
// 如果结束时间为 00:00切换到第二天的日期
if ($end_time == '00:00') {
$end_date = date('Ymd', strtotime($end_date . ' +1 day')); // 切换日期
// 合并下一个节目
if (isset($programs[$programIndex + 1])) {
$nextData = json_decode($programs[$programIndex + 1]['epg_diyp'], true);
$nextItem = $nextData['epg_data'][0] ?? null;
if ($nextItem && $nextItem['title'] == $item['title']) {
$end_time = $nextItem['end'];
array_splice($nextData['epg_data'], 0, 1); // 删除下一个节目的第一个项目
$programs[$programIndex + 1]['epg_diyp'] = json_encode($nextData);
}
}
}
// 写入当前节目
$xmlWriter->startElement('programme');
$xmlWriter->writeAttribute('channel', htmlspecialchars($channelName, ENT_XML1, 'UTF-8'));
$xmlWriter->writeAttribute('start', formatTime($program['date'], $item['start']));
$xmlWriter->writeAttribute('stop', formatTime($end_date, $end_time));
$xmlWriter->startElement('title');
$xmlWriter->writeAttribute('lang', 'zh');
$xmlWriter->text(htmlspecialchars($item['title'], ENT_XML1, 'UTF-8'));
$xmlWriter->endElement(); // title
if (!empty($item['desc'])) {
$xmlWriter->startElement('desc');
$xmlWriter->writeAttribute('lang', 'zh');
$xmlWriter->text(htmlspecialchars($item['desc'], ENT_XML1, 'UTF-8'));
$xmlWriter->endElement(); // desc
}
$xmlWriter->endElement(); // programme
}
}
}
// 结束 XML 文档
$xmlWriter->endElement(); // tv
$xmlWriter->endDocument();
$xmlWriter->flush();
logMessage($log_messages, "[XMLTV] 开始生成GZ压缩文件...");
// 所有频道数据写入完成后,生成 t.xml.gz 文件
compressXmlFile($xmlFilePath);
logMessage($log_messages, "[XMLTV] GZ压缩文件压缩成功");
logMessage($log_messages, "[XMLTV] 已生成 t.xml 和 t.xml.gz");
}
// 生成 t.xml.gz 压缩文件
function compressXmlFile($xmlFilePath) {
$gzFilePath = $xmlFilePath . '.gz';
// 打开原文件和压缩文件
$file = fopen($xmlFilePath, 'rb');
$gzFile = gzopen($gzFilePath, 'wb9'); // 最高压缩等级
// 将文件内容写入到压缩文件中
while (!feof($file)) {
gzwrite($gzFile, fread($file, 1024 * 512));
}
// 关闭文件
fclose($file);
gzclose($gzFile);
}
// 记录开始时间
$startTime = microtime(true);
// 统计更新前数据条数
$initialCount = $db->query("SELECT COUNT(*) FROM epg_data")->fetchColumn();
// 删除过期数据
$thresholdDate = date('Y-m-d', strtotime("-{$Config['days_to_keep']} days +1 day"));
deleteOldData($db, $log_messages);
// 获取限定频道列表及映射关系
$gen_res = getGenList($db);
$gen_list = $gen_res['gen_list'];
$gen_list_mapping = $gen_res['gen_list_mapping'];
// 获取频道指定 EPG 关系
$channel_bind_epg = getChannelBindEPG();
// 全局变量,用于记录已处理的记录
$processedRecords = [];
// 更新数据
foreach ($Config['xml_urls'] as $xml_url) {
// 去掉空白字符,忽略空行和以 # 开头的 URL
$xml_url = trim($xml_url);
if (empty($xml_url) || strpos($xml_url, '#') === 0) {
continue;
} elseif (preg_match('/^(tvmao|cntv)/i', $xml_url, $matches)) {
$data_source = strtolower($matches[0]);
downloadJSONData($data_source, $xml_url, $db, $log_messages);
continue;
}
// 更新 XML 数据
list($xml_url_str, , $userAgent) = explode('#', $xml_url) + [1 => '', 2 => ''];
$userAgent = trim($userAgent);
$cleaned_url = trim(strpos($xml_url_str, '=>') !== false ? explode('=>', $xml_url_str)[1] : $xml_url_str);
logMessage($log_messages, "[地址] $cleaned_url");
// 判断是否有限定频道列表并下载数据
if (strpos($xml_url_str, '=>') !== false) {
$tmp_gen_list = array_map('trim', explode(",", explode('=>', $xml_url_str)[0]));
logMessage($log_messages, "[临时] 限定频道:" . implode(", ", $tmp_gen_list));
downloadXmlData($cleaned_url, $userAgent, $db, $log_messages, $tmp_gen_list, 1);
} else {
downloadXmlData($cleaned_url, $userAgent, $db, $log_messages, $gen_list);
}
}
// 更新 iconList.json 及生成 xmltv 文件
processIconListAndXmltv($db, $gen_list_mapping, $log_messages);
// 判断是否同步更新直播源
if (isset($Config['live_source_auto_sync']) && $Config['live_source_auto_sync'] == 1) {
$parseResult = doParseSourceInfo();
if ($parseResult !== true) {
logMessage($log_messages, "[直播文件] 部分更新异常:" . rtrim(str_replace('<br>', '、', $parseResult), '、'));
} else {
logMessage($log_messages, "[直播文件] 已同步更新");
}
}
// 统计更新后数据条数
$finalCount = $db->query("SELECT COUNT(*) FROM epg_data")->fetchColumn();
$dif = $finalCount - $initialCount;
$msg = $dif != 0 ? ($dif > 0 ? " 增加 $dif" : " 减少 " . abs($dif) . "") : "";
// 记录结束时间
$endTime = microtime(true);
// 计算运行时间(以秒为单位)
$executionTime = round($endTime - $startTime, 1);
echo "<br>";
logMessage($log_messages, "[更新完成] {$executionTime} 秒。节目天数:更新前 {$initialCount} ,更新后 {$finalCount}" . $msg);
// 将日志信息写入数据库
$log_message_str = implode("<br>", $log_messages);
$timestamp = date('Y-m-d H:i:s'); // 使用设定的时区时间
$stmt = $db->prepare('INSERT INTO update_log (timestamp, log_message) VALUES (:timestamp, :log_message)');
$stmt->bindValue(':timestamp', $timestamp, PDO::PARAM_STR);
$stmt->bindValue(':log_message', $log_message_str, PDO::PARAM_STR);
$stmt->execute();
?>