46
46
import settings as settings_file
47
47
48
48
# Version of the script
49
- script_version = (2 , 5 , 13 )
49
+ script_version = (2 , 5 , 14 )
50
50
script_version_text = "v{}.{}.{}" .format (* script_version )
51
51
52
52
# Paths = existing library
@@ -224,6 +224,7 @@ def __str__(self):
224
224
[r"\(Digital\b" ], # must_contain
225
225
[
226
226
r"Webtoon" ,
227
+ r"^(?=.*Digital)((?=.*Compilation)|(?=.*danke-repack))" ,
227
228
], # must_not_contain
228
229
),
229
230
LibraryType (
@@ -234,6 +235,12 @@ def __str__(self):
234
235
], # must_contain
235
236
[], # must_not_contain
236
237
),
238
+ LibraryType (
239
+ "digital_comps" , # name
240
+ manga_extensions , # extensions
241
+ [r"^(?=.*Digital)((?=.*Compilation)|(?=.*danke-repack))" ], # must_contain
242
+ [], # must_not_contain
243
+ ),
237
244
]
238
245
239
246
@@ -306,6 +313,7 @@ def __str__(self):
306
313
r"\bBonus(\s)" ,
307
314
r"(\]|\}|\)) -" ,
308
315
r"\bZom(\s)" ,
316
+ r"Tail -" ,
309
317
]
310
318
311
319
subtitle_exclusion_keywords = [r"-(\s)" , r"-" , r"-\s[A-Za-z]+\s" ]
@@ -687,6 +695,39 @@ def send_message(
687
695
write_to_file (changes_file_name , message )
688
696
689
697
698
+ # Determines the files library type
699
+ # must apply to all files
700
+ def get_library_type (files , required_match_percentage = 90 ):
701
+ results = []
702
+ result = None
703
+
704
+ for file in files :
705
+ extension = get_file_extension (file )
706
+ for library_type in library_types :
707
+ if (
708
+ extension in library_type .extensions
709
+ and all (
710
+ re .search (regex , file , re .IGNORECASE )
711
+ for regex in library_type .must_contain
712
+ )
713
+ and all (
714
+ not re .search (regex , file , re .IGNORECASE )
715
+ for regex in library_type .must_not_contain
716
+ )
717
+ ):
718
+ results .append (library_type )
719
+
720
+ if results :
721
+ result_counts = {
722
+ library_type : results .count (library_type ) for library_type in library_types
723
+ }
724
+ max_count = max (result_counts .values ())
725
+ if max_count / len (results ) * 100 >= required_match_percentage :
726
+ result = max (result_counts , key = result_counts .get )
727
+
728
+ return result
729
+
730
+
690
731
# Checks if the file is fully transferred by checking the file size
691
732
def is_file_transferred (file_path ):
692
733
# Check if the file path exists and is a file
@@ -2188,7 +2229,8 @@ def upgrade_to_file_class(
2188
2229
get_series_name_from_chapter (file , root , chapter_number )
2189
2230
if file_type == "chapter"
2190
2231
else get_series_name_from_volume (file , root , test_mode = test_mode )
2191
- ),
2232
+ )
2233
+ or get_series_name_from_contents (os .path .basename (root ), [file ]),
2192
2234
get_file_extension (file ),
2193
2235
root ,
2194
2236
os .path .join (root , file ),
@@ -2477,6 +2519,47 @@ def move_images(
2477
2519
remove_file (cover_image_file_path , silent = True )
2478
2520
2479
2521
2522
+ # Retrives the series name from matching the folder name and the file names
2523
+ def get_series_name_from_contents (
2524
+ folder_name , file_names , required_matching_percent = 100
2525
+ ):
2526
+ # Check if there are fewer than 2 items in the file names array
2527
+ if len (file_names ) <= 1 :
2528
+ return ""
2529
+
2530
+ min_matching_count = (
2531
+ required_matching_percent * len (file_names ) / 100
2532
+ ) # Minimum number of file names to match
2533
+ series_name = ""
2534
+
2535
+ for i , char in enumerate (folder_name ):
2536
+ # Loop through characters of the folder name
2537
+ matching_count = sum (
2538
+ 1
2539
+ for file_name in file_names
2540
+ if i < len (file_name ) and file_name [i ].lower () == char .lower ()
2541
+ )
2542
+ if matching_count >= min_matching_count :
2543
+ series_name += char
2544
+ else :
2545
+ break
2546
+
2547
+ # Check if series_name is at least three characters
2548
+ if len (series_name ) < 3 :
2549
+ series_name = ""
2550
+
2551
+ return series_name .strip ()
2552
+
2553
+
2554
+ # Checks if the file string contains a chapter/volume keyword
2555
+ def contains_keyword (file_string , chapter = False ):
2556
+ return re .search (
2557
+ rf"(\b({ chapter_regex_keywords if chapter else volume_regex_keywords } )([-_.]|)(([0-9]+)((([-_.]|)([0-9]+))+|))(\s|{ file_extensions_regex } ))" ,
2558
+ file_string ,
2559
+ re .IGNORECASE ,
2560
+ )
2561
+
2562
+
2480
2563
# Retrieves the series name through various regexes
2481
2564
# Removes the volume number and anything to the right of it, and strips it.
2482
2565
@lru_cache (maxsize = None )
@@ -2704,7 +2787,7 @@ def get_series_name_from_chapter(name, root, chapter_number="", second=False):
2704
2787
and not second
2705
2788
and root
2706
2789
and os .path .basename (root ) not in str (download_folders + paths )
2707
- and not contains_keyword (os .path .basename (root ))
2790
+ and not contains_keyword (os .path .basename (root ), chapter = True )
2708
2791
):
2709
2792
root_number = get_release_number_cache (os .path .basename (root ))
2710
2793
@@ -10163,16 +10246,16 @@ def sort_and_log_releases(released, pre_orders):
10163
10246
dirs = folder ["dirs" ]
10164
10247
files = clean_and_sort (root , folder ["files" ], chapters = False , sort = True )[0 ]
10165
10248
10166
- if not files :
10167
- continue
10168
-
10169
- base_name = os .path .basename (root )
10170
-
10171
10249
print (
10172
10250
f"\n \t [Folder { dir_index } of { len (folders )} - Path { path_index } of { len (paths_clean )} ]"
10173
10251
)
10174
10252
print (f"\t Path: { root } " )
10175
10253
10254
+ if not files :
10255
+ continue
10256
+
10257
+ base_name = os .path .basename (root )
10258
+
10176
10259
series = normalize_str (
10177
10260
base_name ,
10178
10261
skip_common_words = True ,
@@ -10295,13 +10378,6 @@ def scan_komga_library(library_id):
10295
10378
)
10296
10379
return
10297
10380
10298
- if not komga_port :
10299
- send_message (
10300
- "Komga Port is not set in settings.py. Please set it and try again." ,
10301
- error = True ,
10302
- )
10303
- return
10304
-
10305
10381
if not komga_login_email :
10306
10382
send_message (
10307
10383
"Komga Login Email is not set in settings.py. Please set it and try again." ,
@@ -10316,7 +10392,7 @@ def scan_komga_library(library_id):
10316
10392
)
10317
10393
return
10318
10394
10319
- komga_url = f"{ komga_ip } :{ komga_port } "
10395
+ komga_url = f"{ komga_ip } :{ komga_port } " if komga_port else komga_ip
10320
10396
10321
10397
print ("\n Sending Komga Scan Request:" )
10322
10398
try :
@@ -10361,13 +10437,6 @@ def get_komga_libraries(first_run=True):
10361
10437
)
10362
10438
return
10363
10439
10364
- if not komga_port :
10365
- send_message (
10366
- "Komga Port is not set in settings.py. Please set it and try again." ,
10367
- error = True ,
10368
- )
10369
- return
10370
-
10371
10440
if not komga_login_email :
10372
10441
send_message (
10373
10442
"Komga Login Email is not set in settings.py. Please set it and try again." ,
@@ -10382,7 +10451,7 @@ def get_komga_libraries(first_run=True):
10382
10451
)
10383
10452
return
10384
10453
10385
- komga_url = f"{ komga_ip } :{ komga_port } "
10454
+ komga_url = f"{ komga_ip } :{ komga_port } " if komga_port else komga_ip
10386
10455
10387
10456
try :
10388
10457
request = requests .get (
@@ -11212,15 +11281,6 @@ def correct_file_extensions():
11212
11281
print ("\t \t \t Skipped" )
11213
11282
11214
11283
11215
- # Checks if the file string contains a chapter/volume keyword
11216
- def contains_keyword (file_string , chapter = False ):
11217
- return re .search (
11218
- rf"(\b({ chapter_regex_keywords if chapter else volume_regex_keywords } )([-_.]|)(([0-9]+)((([-_.]|)([0-9]+))+|))(\s|{ file_extensions_regex } ))" ,
11219
- file_string ,
11220
- re .IGNORECASE ,
11221
- )
11222
-
11223
-
11224
11284
# Optional features below, use at your own risk.
11225
11285
# Activate them in settings.py
11226
11286
def main ():
0 commit comments