jmcomic 2.4.7__py3-none-any.whl → 2.4.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
jmcomic/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # 被依赖方 <--- 使用方
3
3
  # config <--- entity <--- toolkit <--- client <--- option <--- downloader
4
4
 
5
- __version__ = '2.4.7'
5
+ __version__ = '2.4.9'
6
6
 
7
7
  from .api import *
8
8
  from .jm_plugin import *
jmcomic/jm_client_impl.py CHANGED
@@ -309,7 +309,28 @@ class JmHtmlClient(AbstractJmClient):
309
309
  album = JmcomicText.analyse_jm_album_html(resp.text)
310
310
  return JmSearchPage.wrap_single_album(album)
311
311
  else:
312
- return JmcomicText.analyse_jm_search_html(resp.text)
312
+ return JmPageTool.parse_html_to_search_page(resp.text)
313
+
314
+ def categories_filter(self,
315
+ page: int,
316
+ time: str,
317
+ category: str,
318
+ order_by: str,
319
+ ) -> JmCategoryPage:
320
+ params = {
321
+ 'page': page,
322
+ 'o': order_by,
323
+ 't': time,
324
+ }
325
+
326
+ url = f'/albums/' + (category if category != JmMagicConstants.CATEGORY_ALL else '')
327
+
328
+ resp = self.get_jm_html(
329
+ self.append_params_to_url(url, params),
330
+ allow_redirects=True,
331
+ )
332
+
333
+ return JmPageTool.parse_html_to_category_page(resp.text)
313
334
 
314
335
  # -- 帐号管理 --
315
336
 
@@ -525,6 +546,7 @@ class JmApiClient(AbstractJmClient):
525
546
  func_to_cache = ['search', 'fetch_detail_entity']
526
547
 
527
548
  API_SEARCH = '/search'
549
+ API_CATEGORIES_FILTER = '/categories/filter'
528
550
  API_ALBUM = '/album'
529
551
  API_CHAPTER = '/chapter'
530
552
  API_SCRAMBLE = '/chapter_view_template'
@@ -561,6 +583,26 @@ class JmApiClient(AbstractJmClient):
561
583
 
562
584
  return JmPageTool.parse_api_to_search_page(data)
563
585
 
586
+ def categories_filter(self,
587
+ page: int,
588
+ time: str,
589
+ category: str,
590
+ order_by: str,
591
+ ):
592
+ # o: mv, mv_m, mv_w, mv_t
593
+ o = f'{order_by}_{time}' if time != JmMagicConstants.TIME_ALL else order_by
594
+
595
+ params = {
596
+ 'page': page,
597
+ 'order': '', # 该参数为空
598
+ 'c': category,
599
+ 'o': o,
600
+ }
601
+
602
+ resp = self.req_api(self.append_params_to_url(self.API_CATEGORIES_FILTER, params))
603
+
604
+ return JmPageTool.parse_api_to_search_page(resp.model_data)
605
+
564
606
  def get_album_detail(self, album_id) -> JmAlbumDetail:
565
607
  return self.fetch_detail_entity(album_id,
566
608
  JmModuleConfig.album_class(),
@@ -84,6 +84,7 @@ class JmImageResp(JmResp):
84
84
 
85
85
  class JmJsonResp(JmResp):
86
86
 
87
+ @field_cache()
87
88
  def json(self) -> Dict:
88
89
  return self.resp.json()
89
90
 
@@ -128,9 +129,6 @@ class JmAlbumCommentResp(JmJsonResp):
128
129
  def is_success(self) -> bool:
129
130
  return super().is_success and self.json()['err'] is False
130
131
 
131
- def json(self) -> Dict:
132
- return self.resp.json()
133
-
134
132
 
135
133
  """
136
134
 
@@ -151,15 +149,6 @@ class JmDetailClient:
151
149
  ) -> JmPhotoDetail:
152
150
  raise NotImplementedError
153
151
 
154
- def of_api_url(self, api_path, domain):
155
- raise NotImplementedError
156
-
157
- def set_cache_dict(self, cache_dict: Optional[Dict]):
158
- raise NotImplementedError
159
-
160
- def get_cache_dict(self) -> Optional[Dict]:
161
- raise NotImplementedError
162
-
163
152
  def check_photo(self, photo: JmPhotoDetail):
164
153
  """
165
154
  photo来源有两种:
@@ -381,12 +370,78 @@ class JmSearchAlbumClient:
381
370
  return self.search(search_query, page, 4, order_by, time)
382
371
 
383
372
 
373
+ class JmCategoryClient:
374
+ """
375
+ 该接口可以看作是对全体禁漫本子的排行,热门排行的功能也派生于此
376
+
377
+ 月排行 = 分类【时间=月,排序=观看】
378
+ 周排行 = 分类【时间=周,排序=观看】
379
+ 日排行 = 分类【时间=周,排序=观看】
380
+ """
381
+
382
+ def categories_filter(self,
383
+ page: int,
384
+ time: str,
385
+ category: str,
386
+ order_by: str,
387
+ ) -> JmCategoryPage:
388
+ """
389
+ 分类
390
+
391
+ :param page: 页码
392
+ :param time: 时间范围,默认是全部时间
393
+ :param category: 类别,默认是最新,即显示最新的禁漫本子
394
+ :param order_by: 排序方式,默认是观看数
395
+ """
396
+ raise NotImplementedError
397
+
398
+ def month_ranking(self,
399
+ page: int,
400
+ category: str = JmMagicConstants.CATEGORY_ALL,
401
+ ):
402
+ """
403
+ 月排行 = 分类【时间=月,排序=观看】
404
+ """
405
+ return self.categories_filter(page,
406
+ JmMagicConstants.TIME_MONTH,
407
+ category,
408
+ JmMagicConstants.ORDER_BY_VIEW,
409
+ )
410
+
411
+ def week_ranking(self,
412
+ page: int,
413
+ category: str = JmMagicConstants.CATEGORY_ALL,
414
+ ):
415
+ """
416
+ 周排行 = 分类【时间=周,排序=观看】
417
+ """
418
+ return self.categories_filter(page,
419
+ JmMagicConstants.TIME_WEEK,
420
+ category,
421
+ JmMagicConstants.ORDER_BY_VIEW,
422
+ )
423
+
424
+ def day_ranking(self,
425
+ page: int,
426
+ category: str = JmMagicConstants.CATEGORY_ALL,
427
+ ):
428
+ """
429
+ 日排行 = 分类【时间=日,排序=观看】
430
+ """
431
+ return self.categories_filter(page,
432
+ JmMagicConstants.TIME_TODAY,
433
+ category,
434
+ JmMagicConstants.ORDER_BY_VIEW,
435
+ )
436
+
437
+
384
438
  # noinspection PyAbstractClass
385
439
  class JmcomicClient(
386
440
  JmImageClient,
387
441
  JmDetailClient,
388
442
  JmUserClient,
389
443
  JmSearchAlbumClient,
444
+ JmCategoryClient,
390
445
  Postman,
391
446
  ):
392
447
  client_key: None
@@ -403,6 +458,15 @@ class JmcomicClient(
403
458
  """
404
459
  raise NotImplementedError
405
460
 
461
+ def set_cache_dict(self, cache_dict: Optional[Dict]):
462
+ raise NotImplementedError
463
+
464
+ def get_cache_dict(self) -> Optional[Dict]:
465
+ raise NotImplementedError
466
+
467
+ def of_api_url(self, api_path, domain):
468
+ raise NotImplementedError
469
+
406
470
  def get_html_domain(self, postman=None):
407
471
  return JmModuleConfig.get_html_domain(postman or self.get_root_postman())
408
472
 
@@ -487,3 +551,20 @@ class JmcomicClient(
487
551
  }
488
552
 
489
553
  yield from self.do_page_iter(params, page, self.search)
554
+
555
+ def categories_filter_gen(self,
556
+ page: int = 1,
557
+ time: str = JmMagicConstants.TIME_ALL,
558
+ category: str = JmMagicConstants.CATEGORY_ALL,
559
+ order_by: str = JmMagicConstants.ORDER_BY_LATEST,
560
+ ) -> Generator[JmCategoryPage, Dict, None]:
561
+ """
562
+ 见 search_gen
563
+ """
564
+ params = {
565
+ 'time': time,
566
+ 'category': category,
567
+ 'order_by': order_by,
568
+ }
569
+
570
+ yield from self.do_page_iter(params, page, self.categories_filter)
jmcomic/jm_config.py CHANGED
@@ -22,12 +22,28 @@ class JmMagicConstants:
22
22
  ORDER_BY_PICTURE = 'mp'
23
23
  ORDER_BY_LIKE = 'tf'
24
24
 
25
+ ORDER_MONTH_RANKING = 'mv_m'
26
+ ORDER_WEEK_RANKING = 'mv_w'
27
+ ORDER_DAY_RANKING = 'mv_t'
28
+
25
29
  # 搜索参数-时间段
26
30
  TIME_TODAY = 't'
27
31
  TIME_WEEK = 'w'
28
32
  TIME_MONTH = 'm'
29
33
  TIME_ALL = 'a'
30
34
 
35
+ # 全部, 同人, 单本, 短篇, 其他, 韩漫, 美漫, cosplay, 3D
36
+ # category = ["0", "doujin", "single", "short", "another", "hanman", "meiman", "doujin_cosplay", "3D"]
37
+ CATEGORY_ALL = '0'
38
+ CATEGORY_DOUJIN = 'doujin'
39
+ CATEGORY_SINGLE = 'single'
40
+ CATEGORY_SHORT = 'short'
41
+ CATEGORY_ANOTHER = 'another'
42
+ CATEGORY_HANMAN = 'hanman'
43
+ CATEGORY_MEIMAN = 'meiman'
44
+ CATEGORY_DOUJIN_COSPLAY = 'doujin_cosplay'
45
+ CATEGORY_3D = '3D'
46
+
31
47
  # 分页大小
32
48
  PAGE_SIZE_SEARCH = 80
33
49
  PAGE_SIZE_FAVORITE = 20
jmcomic/jm_entity.py CHANGED
@@ -617,6 +617,9 @@ class JmSearchPage(JmPageContent):
617
617
  return page
618
618
 
619
619
 
620
+ JmCategoryPage = JmSearchPage
621
+
622
+
620
623
  class JmFavoritePage(JmPageContent):
621
624
 
622
625
  def __init__(self, content, folder_list, total):
jmcomic/jm_option.py CHANGED
@@ -220,6 +220,7 @@ class JmOption:
220
220
  break
221
221
 
222
222
  from os.path import join
223
+ # noinspection PyTypeChecker
223
224
  return join(*dir_layer)
224
225
 
225
226
  # noinspection PyMethodMayBeStatic
@@ -293,6 +294,7 @@ class JmOption:
293
294
 
294
295
  # version
295
296
  version = dic.pop('version', None)
297
+ # noinspection PyTypeChecker
296
298
  if version is not None and float(version) >= float(JmModuleConfig.JM_OPTION_VER):
297
299
  # 版本号更高,跳过兼容代码
298
300
  return cls(**dic)
jmcomic/jm_toolkit.py CHANGED
@@ -116,10 +116,6 @@ class JmcomicText:
116
116
  JmModuleConfig.album_class()
117
117
  )
118
118
 
119
- @classmethod
120
- def analyse_jm_search_html(cls, html: str) -> JmSearchPage:
121
- return JmPageTool.parse_html_to_search_page(html)
122
-
123
119
  @classmethod
124
120
  def reflect_new_instance(cls, html: str, cls_field_prefix: str, clazz: type):
125
121
 
@@ -347,6 +343,15 @@ class JmPageTool:
347
343
  r'(<a[\s\S]*?) </div>'
348
344
  )
349
345
 
346
+ # 用来提取分类页面的的album的信息
347
+ pattern_html_category_album_info_list = compile(
348
+ r'<a href="/album/(\d+)/[^>]*>[\s\S]*?title="(.*?)"[^>]*>'
349
+ r'\n</a>\n'
350
+ r'<div class="label-loveicon">'
351
+ r'([\s\S]*?)'
352
+ r'<div class="clearfix">'
353
+ )
354
+
350
355
  # 用来查找tag列表
351
356
  pattern_html_search_tag_list = compile(r'<a[^>]*?>(.*?)</a>')
352
357
 
@@ -405,6 +410,26 @@ class JmPageTool:
405
410
 
406
411
  return JmSearchPage(content, total)
407
412
 
413
+ @classmethod
414
+ def parse_html_to_category_page(cls, html: str) -> JmSearchPage:
415
+ # 3. 提取结果
416
+ content = []
417
+ total = int(PatternTool.match_or_default(html, *cls.pattern_html_search_total))
418
+
419
+ album_info_list = cls.pattern_html_category_album_info_list.findall(html)
420
+
421
+ for (album_id, title, tag_text) in album_info_list:
422
+ tag_list = cls.pattern_html_search_tag_list.findall(tag_text)
423
+ content.append((
424
+ album_id, {
425
+ 'name': title, # 改成name是为了兼容 parse_api_resp_to_page
426
+ 'tag_list': tag_list
427
+ }
428
+ ))
429
+
430
+ return JmSearchPage(content, total)
431
+
432
+
408
433
  @classmethod
409
434
  def parse_html_to_favorite_page(cls, html: str) -> JmFavoritePage:
410
435
  total = int(PatternTool.require_match(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jmcomic
3
- Version: 2.4.7
3
+ Version: 2.4.9
4
4
  Summary: Python API For JMComic (禁漫天堂)
5
5
  Home-page: https://github.com/hect0x7/JMComic-Crawler-Python
6
6
  Author: hect0x7
@@ -37,7 +37,7 @@ Requires-Dist: pycryptodome
37
37
 
38
38
  本项目的核心功能是下载本子,基于此,设计了一套方便使用、便于扩展,能满足一些特殊下载需求的框架。
39
39
 
40
- 除了下载功能以外,也实现了其他的一些禁漫接口,例如登录、搜索、收藏夹等等,按需实现。
40
+ 除了下载功能以外,也实现了其他的一些禁漫接口,例如登录、搜索、收藏夹、分类、排行榜等等,按需实现。
41
41
 
42
42
  目前核心功能实现较为稳定,项目也处于维护阶段(因为禁漫接口经常变动,需要经常维护)。
43
43
 
@@ -0,0 +1,17 @@
1
+ jmcomic/__init__.py,sha256=lU1wXRbpzgrJ3bBjL0IUiK-cPIqLEutUVaIRdd2EMfg,878
2
+ jmcomic/api.py,sha256=yukYd5NCYYxP8K2Gj72iXu7vg9PHgaOvakQzQxEOcO8,2518
3
+ jmcomic/cl.py,sha256=PBSh0JndNFZw3B7WJPj5Y8SeFdKzHE00jIwYo9An-K0,3475
4
+ jmcomic/jm_client_impl.py,sha256=SDezH8AM9HzxqmE87zskGCB1Ms6khCUeWrA1G2xBsSw,35431
5
+ jmcomic/jm_client_interface.py,sha256=GpH-laoRYT6xn7MWgS0hgDZfF2-7t9AMzC5jGwuEqis,17083
6
+ jmcomic/jm_config.py,sha256=IZEK8o2AN2_NZW4SkofiRIUT6X7ZIH6StGcjZZV-rTQ,13668
7
+ jmcomic/jm_downloader.py,sha256=E1M9CS9bYEHWe8SEsdaq_0c3zxQghpkN_4QLZiZ-o1g,7324
8
+ jmcomic/jm_entity.py,sha256=CkzYIB_fUxwsAFax6xrZio3qun5l-4bcUuWcWd9mbZE,18703
9
+ jmcomic/jm_option.py,sha256=htnAAk8zkpXQQDMpFvShvpE-V4VPVrHu9qgUYgbluKk,20019
10
+ jmcomic/jm_plugin.py,sha256=ftL0iZbc1GWk75n6ZuP1j-7MaOTqK1mQA04E-rkNEPs,16198
11
+ jmcomic/jm_toolkit.py,sha256=8zjK4ciTCds4R6yshxF8PLmp9c31qNUFJv-wVUa24_Y,29750
12
+ jmcomic-2.4.9.dist-info/LICENSE,sha256=kz4coTxZxuGxisK3W00tjK57Zh3RcMGq-EnbXrK7-xA,1064
13
+ jmcomic-2.4.9.dist-info/METADATA,sha256=VyhiTq5e4-6U8DlI__eQzYT18bv0fLDqtH-17oYBPIo,5491
14
+ jmcomic-2.4.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
15
+ jmcomic-2.4.9.dist-info/entry_points.txt,sha256=tRbQltaGSBjejI0c9jYt-4SXQMd5nSDHcMvHmuTy4ow,44
16
+ jmcomic-2.4.9.dist-info/top_level.txt,sha256=puvVMFYJqIbd6NOTMEvOyugMTT8woBfSQyxEBan3zY4,8
17
+ jmcomic-2.4.9.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- jmcomic/__init__.py,sha256=BYuf4ruBex9ljlTlGN0xXdUcus_eKTXS7ZLOqkgKJXM,878
2
- jmcomic/api.py,sha256=yukYd5NCYYxP8K2Gj72iXu7vg9PHgaOvakQzQxEOcO8,2518
3
- jmcomic/cl.py,sha256=PBSh0JndNFZw3B7WJPj5Y8SeFdKzHE00jIwYo9An-K0,3475
4
- jmcomic/jm_client_impl.py,sha256=uG4LIZZdz6zAePkgTq80n5pNV-G069cXiSgBRg_dAO8,34106
5
- jmcomic/jm_client_interface.py,sha256=xaPtHxdzGYmzsnRfq-fkH__hiARNUtxtjtEzD-SwbPg,14120
6
- jmcomic/jm_config.py,sha256=88YEZyzxBWJcKmbS6sYhfQ4ZoO6kb7ghMYOgUYBfuWg,13110
7
- jmcomic/jm_downloader.py,sha256=E1M9CS9bYEHWe8SEsdaq_0c3zxQghpkN_4QLZiZ-o1g,7324
8
- jmcomic/jm_entity.py,sha256=u5aJhIt2Q21re6moXfS0drVBmIJKjNQnRI2lVvbZ-nY,18671
9
- jmcomic/jm_option.py,sha256=-_Obz2m_roZOAkb1hw62TKDeKIy_iow99z65fXdvX7I,19945
10
- jmcomic/jm_plugin.py,sha256=ftL0iZbc1GWk75n6ZuP1j-7MaOTqK1mQA04E-rkNEPs,16198
11
- jmcomic/jm_toolkit.py,sha256=I67hbdHBLVsmi8RFanKy2sOIaMDU5GlOzi7AxfK_8vA,28892
12
- jmcomic-2.4.7.dist-info/LICENSE,sha256=kz4coTxZxuGxisK3W00tjK57Zh3RcMGq-EnbXrK7-xA,1064
13
- jmcomic-2.4.7.dist-info/METADATA,sha256=fqfirQgCGD85-12Vhf5hSo71eG3A3DSSSOjzzbi96Nc,5470
14
- jmcomic-2.4.7.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
15
- jmcomic-2.4.7.dist-info/entry_points.txt,sha256=tRbQltaGSBjejI0c9jYt-4SXQMd5nSDHcMvHmuTy4ow,44
16
- jmcomic-2.4.7.dist-info/top_level.txt,sha256=puvVMFYJqIbd6NOTMEvOyugMTT8woBfSQyxEBan3zY4,8
17
- jmcomic-2.4.7.dist-info/RECORD,,