plugins.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. __package__ = 'archivebox.plugantic'
  2. from typing import List
  3. from typing_extensions import Self
  4. from pydantic import (
  5. BaseModel,
  6. ConfigDict,
  7. Field,
  8. model_validator,
  9. validate_call,
  10. SerializeAsAny,
  11. )
  12. from .binaries import (
  13. Binary,
  14. PythonBinary,
  15. SqliteBinary,
  16. DjangoBinary,
  17. WgetBinary,
  18. YtdlpBinary,
  19. )
  20. from .extractors import (
  21. Extractor,
  22. YtdlpExtractor,
  23. WgetExtractor,
  24. WarcExtractor,
  25. )
  26. from .replayers import (
  27. Replayer,
  28. GENERIC_REPLAYER,
  29. MEDIA_REPLAYER,
  30. )
  31. from .configs import (
  32. ConfigSet,
  33. WGET_CONFIG,
  34. )
  35. class Plugin(BaseModel):
  36. model_config = ConfigDict(arbitrary_types_allowed=True, extra='ignore', populate_by_name=True)
  37. name: str = Field(default='baseplugin') # e.g. media
  38. description: str = Field(default='') # e.g. get media using yt-dlp
  39. configs: List[SerializeAsAny[ConfigSet]] = Field(default=[])
  40. binaries: List[SerializeAsAny[Binary]] = Field(default=[]) # e.g. [Binary(name='yt-dlp')]
  41. extractors: List[SerializeAsAny[Extractor]] = Field(default=[])
  42. replayers: List[SerializeAsAny[Replayer]] = Field(default=[])
  43. @model_validator(mode='after')
  44. def validate(self):
  45. self.description = self.description or self.name
  46. @validate_call
  47. def install(self) -> Self:
  48. new_binaries = []
  49. for idx, binary in enumerate(self.binaries):
  50. new_binaries.append(binary.install() or binary)
  51. return self.model_copy(update={
  52. 'binaries': new_binaries,
  53. })
  54. @validate_call
  55. def load(self, cache=True) -> Self:
  56. new_binaries = []
  57. for idx, binary in enumerate(self.binaries):
  58. new_binaries.append(binary.load(cache=cache) or binary)
  59. return self.model_copy(update={
  60. 'binaries': new_binaries,
  61. })
  62. @validate_call
  63. def load_or_install(self, cache=True) -> Self:
  64. new_binaries = []
  65. for idx, binary in enumerate(self.binaries):
  66. new_binaries.append(binary.load_or_install(cache=cache) or binary)
  67. return self.model_copy(update={
  68. 'binaries': new_binaries,
  69. })
  70. class CorePlugin(Plugin):
  71. name: str = 'core'
  72. configs: List[SerializeAsAny[ConfigSet]] = []
  73. binaries: List[SerializeAsAny[Binary]] = [PythonBinary(), SqliteBinary(), DjangoBinary()]
  74. extractors: List[SerializeAsAny[Extractor]] = []
  75. replayers: List[SerializeAsAny[Replayer]] = [GENERIC_REPLAYER]
  76. class YtdlpPlugin(Plugin):
  77. name: str = 'ytdlp'
  78. configs: List[SerializeAsAny[ConfigSet]] = []
  79. binaries: List[SerializeAsAny[Binary]] = [YtdlpBinary()]
  80. extractors: List[SerializeAsAny[Extractor]] = [YtdlpExtractor()]
  81. replayers: List[SerializeAsAny[Replayer]] = [MEDIA_REPLAYER]
  82. class WgetPlugin(Plugin):
  83. name: str = 'wget'
  84. configs: List[SerializeAsAny[ConfigSet]] = [*WGET_CONFIG]
  85. binaries: List[SerializeAsAny[Binary]] = [WgetBinary()]
  86. extractors: List[SerializeAsAny[Extractor]] = [WgetExtractor(), WarcExtractor()]
  87. CORE_PLUGIN = CorePlugin()
  88. YTDLP_PLUGIN = YtdlpPlugin()
  89. WGET_PLUGIN = WgetPlugin()
  90. PLUGINS = [
  91. CORE_PLUGIN,
  92. YTDLP_PLUGIN,
  93. WGET_PLUGIN,
  94. ]
  95. LOADED_PLUGINS = PLUGINS
  96. import json
  97. for plugin in PLUGINS:
  98. try:
  99. json.dumps(plugin.model_json_schema(), indent=4)
  100. # print(json.dumps(plugin.model_json_schema(), indent=4))
  101. except Exception as err:
  102. print(f'Failed to generate JSON schema for {plugin.name}')
  103. raise
  104. # print('-------------------------------------BEFORE INSTALL---------------------------------')
  105. # for plugin in PLUGINS:
  106. # print(plugin.model_dump_json(indent=4))
  107. # print('-------------------------------------DURING LOAD/INSTALL---------------------------------')
  108. # for plugin in PLUGINS:
  109. # LOADED_PLUGINS.append(plugin.install())
  110. # print('-------------------------------------AFTER INSTALL---------------------------------')
  111. # for plugin in LOADED_PLUGINS:
  112. # print(plugin.model_dump_json(indent=4))