diff --git a/master/404.html b/master/404.html index 09e13e8..fd12f0d 100644 --- a/master/404.html +++ b/master/404.html @@ -14,7 +14,7 @@ - + @@ -22,7 +22,7 @@ - + @@ -240,7 +240,7 @@
- +
Ljzd-PRO/KToolBox @@ -425,7 +425,7 @@
- +
Ljzd-PRO/KToolBox @@ -883,10 +883,10 @@

404 - Not found

- + - + diff --git a/master/about-kemono/index.html b/master/about-kemono/index.html index 56c66e0..1385230 100644 --- a/master/about-kemono/index.html +++ b/master/about-kemono/index.html @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -249,7 +249,7 @@
- +
Ljzd-PRO/KToolBox @@ -436,7 +436,7 @@
- +
Ljzd-PRO/KToolBox @@ -1031,10 +1031,10 @@

About Kemono - + - + diff --git a/master/api/index.html b/master/api/index.html index 2161d4d..b88d233 100644 --- a/master/api/index.html +++ b/master/api/index.html @@ -18,7 +18,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -247,7 +247,7 @@
- +
Ljzd-PRO/KToolBox @@ -434,7 +434,7 @@
- +
Ljzd-PRO/KToolBox @@ -3159,6 +3159,15 @@ + + +
  • + + + reverse_proxy + + +
  • @@ -3357,6 +3366,15 @@ +
  • + +
  • + + + content + + +
  • @@ -3366,6 +3384,24 @@ +
  • + +
  • + + + file + + + +
  • + +
  • + + + content_filepath_validator + + +
  • @@ -7240,6 +7276,15 @@ + + +
  • + + + reverse_proxy + + +
  • @@ -7438,6 +7483,15 @@ +
  • + +
  • + + + content + + +
  • @@ -7447,6 +7501,24 @@ +
  • + +
  • + + + file + + + +
  • + +
  • + + + content_filepath_validator + + +
  • @@ -9063,7 +9135,7 @@

    - __version__ = 'v0.12.0' + __version__ = 'v0.13.0' module-attribute @@ -9487,8 +9559,7 @@

    Source code in ktoolbox/action/job.py -
    120
    -121
    +              
    121
     122
     123
     124
    @@ -9574,7 +9645,8 @@ 

    204 205 206 -207

    async def create_job_from_creator(
    +207
    +208
    async def create_job_from_creator(
             service: str,
             creator_id: str,
             path: Path,
    @@ -9853,7 +9925,8 @@ 

    114 115 116 -117

    async def create_job_from_post(
    +117
    +118
    async def create_job_from_post(
             post: Post,
             post_path: Path,
             *,
    @@ -9877,7 +9950,7 @@ 

    if post_structure: attachments_path = post_path / post_structure.attachments # attachments attachments_path.mkdir(exist_ok=True) - content_path = post_path / post_structure.content_filepath # content + content_path = post_path / post_structure.content # content content_path.parent.mkdir(exist_ok=True) else: attachments_path = post_path @@ -9903,7 +9976,7 @@

    ) ): basic_filename = f"{i + 1}{file_path_obj.suffix}" if config.job.sequential_filename else file_path_obj.name - alt_filename = generate_filename(post, basic_filename) + alt_filename = generate_filename(post, basic_filename, config.job.filename_format) jobs.append( Job( path=attachments_path, @@ -9918,6 +9991,7 @@

    post_file_name = Path(post.file.name) if is_valid_filename(post.file.name) else Path( urlparse(post.file.path).path ) + post_file_name = Path(generate_filename(post, post_file_name.name, config.job.post_structure.file)) if (not config.job.allow_list or any( map( lambda x: fnmatch(post_file_name.name, x), @@ -9932,7 +10006,7 @@

    jobs.append( Job( path=post_path, - alt_filename=f"{post.id}_{post_file_name.name}", + alt_filename=post_file_name.name, server_path=post.file.path, type=PostFileTypeEnum.File ) @@ -10194,8 +10268,7 @@

    Source code in ktoolbox/action/utils.py -
    82
    -83
    +              
    83
     84
     85
     86
    @@ -10207,7 +10280,8 @@ 

    92 93 94 -95

    def filter_posts_by_date(
    +95
    +96
    def filter_posts_by_date(
             post_list: List[Post],
             start_date: Optional[datetime],
             end_date: Optional[datetime]
    @@ -10309,8 +10383,7 @@ 

    Source code in ktoolbox/action/utils.py -
     98
    - 99
    +              
     99
     100
     101
     102
    @@ -10327,7 +10400,8 @@ 

    113 114 115 -116

    def filter_posts_by_indices(posts: List[Post], indices: CreatorIndices) -> Tuple[List[Post], CreatorIndices]:
    +116
    +117
    def filter_posts_by_indices(posts: List[Post], indices: CreatorIndices) -> Tuple[List[Post], CreatorIndices]:
         """
         Compare and filter posts by ``CreatorIndices`` data
     
    @@ -10356,7 +10430,7 @@ 

    - generate_filename(post, basic_name) + generate_filename(post, basic_name, filename_format)

    @@ -10386,13 +10460,14 @@

    55 56 57 -58

    def generate_filename(post: Post, basic_name: str) -> str:
    +58
    +59
    def generate_filename(post: Post, basic_name: str, filename_format: str) -> str:
         """Generate download filename"""
    -    basic_name_suffix = Path(basic_name).suffix
    -    basic_name_filename = basic_name.split(basic_name_suffix)[0] if basic_name_suffix else basic_name
    +    basic_name_path = Path(basic_name)
    +    basic_name_filename = basic_name.replace(basic_name_path.suffix, "")
         try:
             return sanitize_filename(
    -            config.job.filename_format.format(
    +            filename_format.format(
                     basic_name_filename,
                     id=post.id,
                     user=post.user,
    @@ -10401,10 +10476,11 @@ 

    added=post.added.strftime(TIME_FORMAT) if post.added else "", published=post.published.strftime(TIME_FORMAT) if post.published else "", edited=post.edited.strftime(TIME_FORMAT) if post.edited else "" - ) + basic_name_suffix + ) + basic_name_path.suffix ) except KeyError as e: - logger.error(f"`JobConfiguration.filename_format` contains invalid key: {e}") + logger.error( + f"`JobConfiguration.filename_format` or `PostStructureConfiguration.file` contains invalid key: {e}") exit(1)

    @@ -11452,8 +11528,7 @@

    Source code in ktoolbox/action/job.py -
    120
    -121
    +              
    121
     122
     123
     124
    @@ -11539,7 +11614,8 @@ 

    204 205 206 -207

    async def create_job_from_creator(
    +207
    +208
    async def create_job_from_creator(
             service: str,
             creator_id: str,
             path: Path,
    @@ -11818,7 +11894,8 @@ 

    114 115 116 -117

    async def create_job_from_post(
    +117
    +118
    async def create_job_from_post(
             post: Post,
             post_path: Path,
             *,
    @@ -11842,7 +11919,7 @@ 

    if post_structure: attachments_path = post_path / post_structure.attachments # attachments attachments_path.mkdir(exist_ok=True) - content_path = post_path / post_structure.content_filepath # content + content_path = post_path / post_structure.content # content content_path.parent.mkdir(exist_ok=True) else: attachments_path = post_path @@ -11868,7 +11945,7 @@

    ) ): basic_filename = f"{i + 1}{file_path_obj.suffix}" if config.job.sequential_filename else file_path_obj.name - alt_filename = generate_filename(post, basic_filename) + alt_filename = generate_filename(post, basic_filename, config.job.filename_format) jobs.append( Job( path=attachments_path, @@ -11883,6 +11960,7 @@

    post_file_name = Path(post.file.name) if is_valid_filename(post.file.name) else Path( urlparse(post.file.path).path ) + post_file_name = Path(generate_filename(post, post_file_name.name, config.job.post_structure.file)) if (not config.job.allow_list or any( map( lambda x: fnmatch(post_file_name.name, x), @@ -11897,7 +11975,7 @@

    jobs.append( Job( path=post_path, - alt_filename=f"{post.id}_{post_file_name.name}", + alt_filename=post_file_name.name, server_path=post.file.path, type=PostFileTypeEnum.File ) @@ -12461,8 +12539,7 @@

    Source code in ktoolbox/action/utils.py -
    82
    -83
    +              
    83
     84
     85
     86
    @@ -12474,7 +12551,8 @@ 

    92 93 94 -95

    def filter_posts_by_date(
    +95
    +96
    def filter_posts_by_date(
             post_list: List[Post],
             start_date: Optional[datetime],
             end_date: Optional[datetime]
    @@ -12576,8 +12654,7 @@ 

    Source code in ktoolbox/action/utils.py -
     98
    - 99
    +              
     99
     100
     101
     102
    @@ -12594,7 +12671,8 @@ 

    113 114 115 -116

    def filter_posts_by_indices(posts: List[Post], indices: CreatorIndices) -> Tuple[List[Post], CreatorIndices]:
    +116
    +117
    def filter_posts_by_indices(posts: List[Post], indices: CreatorIndices) -> Tuple[List[Post], CreatorIndices]:
         """
         Compare and filter posts by ``CreatorIndices`` data
     
    @@ -12623,7 +12701,7 @@ 

    - generate_filename(post, basic_name) + generate_filename(post, basic_name, filename_format)

    @@ -12653,13 +12731,14 @@

    55 56 57 -58

    def generate_filename(post: Post, basic_name: str) -> str:
    +58
    +59
    def generate_filename(post: Post, basic_name: str, filename_format: str) -> str:
         """Generate download filename"""
    -    basic_name_suffix = Path(basic_name).suffix
    -    basic_name_filename = basic_name.split(basic_name_suffix)[0] if basic_name_suffix else basic_name
    +    basic_name_path = Path(basic_name)
    +    basic_name_filename = basic_name.replace(basic_name_path.suffix, "")
         try:
             return sanitize_filename(
    -            config.job.filename_format.format(
    +            filename_format.format(
                     basic_name_filename,
                     id=post.id,
                     user=post.user,
    @@ -12668,10 +12747,11 @@ 

    added=post.added.strftime(TIME_FORMAT) if post.added else "", published=post.published.strftime(TIME_FORMAT) if post.published else "", edited=post.edited.strftime(TIME_FORMAT) if post.edited else "" - ) + basic_name_suffix + ) + basic_name_path.suffix ) except KeyError as e: - logger.error(f"`JobConfiguration.filename_format` contains invalid key: {e}") + logger.error( + f"`JobConfiguration.filename_format` or `PostStructureConfiguration.file` contains invalid key: {e}") exit(1)

    @@ -19654,7 +19734,7 @@

    - config = Configuration(_env_file=['.env', 'prod.env']) + config = Configuration() module-attribute @@ -19791,8 +19871,7 @@

    Source code in ktoolbox/configuration.py -
    24
    -25
    +                
    25
     26
     27
     28
    @@ -19811,7 +19890,8 @@ 

    41 42 43 -44

    class APIConfiguration(BaseModel):
    +44
    +45
    class APIConfiguration(BaseModel):
         """
         Kemono API Configuration
     
    @@ -20126,38 +20206,38 @@ 

    Source code in ktoolbox/configuration.py -
    173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -183
    -184
    -185
    -186
    -187
    -188
    -189
    -190
    -191
    -192
    -193
    -194
    -195
    -196
    -197
    -198
    -199
    -200
    -201
    -202
    -203
    -204
    class Configuration(BaseSettings):
    +                
    + + + + +
    211
    +212
    +213
    +214
    +215
    +216
    +217
    +218
    +219
    +220
    +221
    +222
    +223
    +224
    +225
    +226
    +227
    +228
    +229
    +230
    +231
    +232
    +233
    +234
    +235
    +236
    +237
    +238
    +239
    +240
    +241
    +242
    class Configuration(BaseSettings):
         # noinspection SpellCheckingInspection,GrazieInspection
         """
         KToolBox Configuration
    @@ -20182,10 +20262,10 @@ 

    use_uvloop: bool = True # noinspection SpellCheckingInspection - model_config = SettingsConfigDict( + model_config: ClassVar[SettingsConfigDict] = SettingsConfigDict( env_prefix='ktoolbox_', env_nested_delimiter='__', - env_file='.env', + env_file=['.env', 'prod.env'], env_file_encoding='utf-8', extra='ignore' ) @@ -20307,11 +20387,10 @@

    - model_config = SettingsConfigDict(env_prefix='ktoolbox_', env_nested_delimiter='__', env_file='.env', env_file_encoding='utf-8', extra='ignore') + model_config: SettingsConfigDict = SettingsConfigDict(env_prefix='ktoolbox_', env_nested_delimiter='__', env_file=['.env', 'prod.env'], env_file_encoding='utf-8', extra='ignore') class-attribute - instance-attribute

    @@ -20522,13 +20601,23 @@

    reverse_proxy + str + +
    +

    Reverse proxy format for download URL. Customize the filename format by inserting an empty {} to represent the original URL. For example: https://example.com/{} will be https://example.com/https://n1.kemono.su/data/66/83/xxxxx.jpg; https://example.com/?url={} will be https://example.com/?url=https://n1.kemono.su/data/66/83/xxxxx.jpg

    +
    +
    Source code in ktoolbox/configuration.py -
    47
    -48
    +                
    48
     49
     50
     51
    @@ -20571,7 +20660,13 @@ 

    88 89 90 -91

    class DownloaderConfiguration(BaseModel):
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    class DownloaderConfiguration(BaseModel):
         """
         File Downloader Configuration
     
    @@ -20587,6 +20682,10 @@ 

    :ivar retry_interval: Seconds of downloader retry interval :ivar use_bucket: Enable local storage bucket mode :ivar bucket_path: Path of local storage bucket + :ivar reverse_proxy: Reverse proxy format for download URL. \ + Customize the filename format by inserting an empty ``{}`` to represent the original URL. \ + For example: ``https://example.com/{}`` will be ``https://example.com/https://n1.kemono.su/data/66/83/xxxxx.jpg``; \ + ``https://example.com/?url={}`` will be ``https://example.com/?url=https://n1.kemono.su/data/66/83/xxxxx.jpg`` """ scheme: Literal["http", "https"] = "https" timeout: float = 30.0 @@ -20599,6 +20698,7 @@

    retry_interval: float = 3.0 use_bucket: bool = False bucket_path: Path = Path("./.ktoolbox/bucket_storage") + reverse_proxy: str = "{}" @model_validator(mode="after") def check_bucket_path(self) -> "DownloaderConfiguration": @@ -20773,6 +20873,26 @@

    + reverse_proxy: str = '{}' + + + class-attribute + instance-attribute + + +

    + + +
    +
    + +
    + +
    + + +

    scheme: Literal['http', 'https'] = 'https' @@ -20864,13 +20984,7 @@

    Source code in ktoolbox/configuration.py -
    76
    -77
    -78
    -79
    -80
    -81
    -82
    +              
    82
     83
     84
     85
    @@ -20879,7 +20993,13 @@ 

    88 89 90 -91

    @model_validator(mode="after")
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    @model_validator(mode="after")
     def check_bucket_path(self) -> "DownloaderConfiguration":
         if self.use_bucket:
             # noinspection PyBroadException
    @@ -20928,7 +21048,7 @@ 

    Download jobs Configuration