libgenrs 0.3.2__tar.gz → 0.3.4__tar.gz

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.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libgenrs
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Asynchronous python lib for Libgen.rs
5
5
  Home-page: https://github.com/ramanveerji/libgenrs
6
- Download-URL: https://github.com/ramanveerji/libgenrs/archive/v0.3.2.tar.gz
6
+ Download-URL: https://github.com/ramanveerji/libgenrs/archive/v0.3.4.tar.gz
7
7
  License: MIT License
8
8
  Classifier: Intended Audience :: Developers
9
9
  Classifier: Operating System :: OS Independent
@@ -2,7 +2,7 @@ import logging
2
2
  from .search import Libgen
3
3
  from .download import LibgenDownload
4
4
 
5
- __version__ = '0.3.2'
5
+ __version__ = '0.3.4'
6
6
  __all__ = ['Libgen', 'LibgenDownload']
7
7
 
8
8
  logging.basicConfig(
@@ -28,11 +28,11 @@ class Libgen:
28
28
  a dictionary of search results using the result ID as the dictionary key.
29
29
  """
30
30
 
31
- if sort.lower() in ['def', 'id', 'author', 'title', 'publisher', 'year', 'pages', 'language', 'size', 'extension']:
31
+ if sort.lower() in ['def', 'id', 'author', 'title', 'publisher', 'year', 'pages', 'language', 'size', 'extension', 'md5']:
32
32
  self.sort = sort.lower()
33
33
  else:
34
34
  raise ValueError(
35
- 'sort parameter invalid. Allowed values: (def, id, author, title, publisher, year, pages, language, size, extension)'
35
+ 'sort parameter invalid. Allowed values: (def, id, author, title, publisher, year, pages, language, size, extension, md5)'
36
36
  )
37
37
  if sort_mode.upper() in ['ASC', 'DESC']:
38
38
  self.sort_mode = sort_mode.upper()
@@ -71,10 +71,17 @@ class Libgen:
71
71
  if not query or len(query.strip()) < 2:
72
72
  raise ValueError(f'The query "{query}" is invalid or less than 2 characters.')
73
73
 
74
+ clean_q = query.strip()
75
+ # Handle MD5 query directly
76
+ if search_field.lower() == 'md5' or (len(clean_q) == 32 and all(c in '0123456789abcdefABCDEF' for c in clean_q)):
77
+ md5_res = await self.__get_md5_detail(clean_q)
78
+ if md5_res:
79
+ return md5_res
80
+
74
81
  if search_field.lower() not in self.__fields:
75
82
  raise ValueError(f'search_field invalid. Allowed fields: {",".join(self.__fields)}')
76
83
 
77
- req = 'req=' + '+'.join(query.strip().split(' '))
84
+ req = 'req=' + '+'.join(clean_q.split(' '))
78
85
  column = 'column=' + search_field.lower()
79
86
  sort = 'sort=' + self.sort
80
87
  sort_mode = 'sortmode=' + self.sort_mode
@@ -103,6 +110,45 @@ class Libgen:
103
110
  logg.warning(f'All Libgen mirrors failed. Last error: {last_exception}')
104
111
  return {}
105
112
 
113
+ async def __get_md5_detail(self, md5: str) -> dict:
114
+ async with aiohttp.ClientSession(headers=self.headers) as session:
115
+ for mirror in self.mirrors:
116
+ base_url = mirror.rstrip('/')
117
+ url = f'{base_url}/ads.php?md5={md5}'
118
+ try:
119
+ async with session.get(url, timeout=aiohttp.ClientTimeout(total=4), ssl=False) as resp:
120
+ if resp.status == 200:
121
+ text = await resp.text()
122
+ detail = {'md5': md5}
123
+ m_title = re.search(r'title\s*=\s*\{([^}]+)\}', text)
124
+ if m_title:
125
+ detail['title'] = m_title.group(1).strip()
126
+ m_author = re.search(r'author\s*=\s*\{([^}]+)\}', text)
127
+ if m_author:
128
+ detail['author'] = m_author.group(1).strip()
129
+ m_pub = re.search(r'publisher\s*=\s*\{([^}]+)\}', text)
130
+ if m_pub:
131
+ detail['publisher'] = m_pub.group(1).strip()
132
+ m_year = re.search(r'year\s*=\s*\{([^}]+)\}', text)
133
+ if m_year:
134
+ detail['year'] = m_year.group(1).strip()
135
+
136
+ soup = bsoup(text, 'html.parser')
137
+ img = soup.find('img', src=re.compile(r'covers/'))
138
+ if img:
139
+ detail['coverurl'] = f'{base_url}/' + img['src'].lstrip('/')
140
+ else:
141
+ detail['coverurl'] = None
142
+
143
+ detail['mirrors'] = {'main': url}
144
+ detail['extension'] = 'pdf'
145
+ detail['filesize'] = '0'
146
+ if detail.get('title'):
147
+ return {md5: detail}
148
+ except Exception:
149
+ continue
150
+ return {}
151
+
106
152
  async def __get_ids(self, session: aiohttp.ClientSession, url: str) -> tuple:
107
153
  try:
108
154
  async with session.get(url, timeout=aiohttp.ClientTimeout(total=3.5), ssl=False) as resp:
@@ -272,15 +318,13 @@ class Libgen:
272
318
  meta = table_meta.get(str(res_id), {}) if table_meta else {}
273
319
 
274
320
  # Fill missing essential metadata fields using HTML table fallback
275
- if not item.get('title') or item.get('title') == 'Unknown Title':
276
- if meta.get('title') and meta.get('title') != 'Unknown Title':
277
- item['title'] = meta['title']
321
+ raw_t = item.get('title', '')
322
+ if not raw_t or raw_t == 'Unknown Title' or raw_t.lower().startswith(('z:\\', 'z:/')) or '\\scimag_' in raw_t.lower():
323
+ meta_t = meta.get('title', '')
324
+ if meta_t and meta_t != 'Unknown Title' and not meta_t.lower().startswith(('z:\\', 'z:/')) and '\\scimag_' not in meta_t.lower():
325
+ item['title'] = meta_t
278
326
  else:
279
- loc = item.get('locator', '')
280
- if loc:
281
- item['title'] = loc.rsplit('.', 1)[0]
282
- else:
283
- item['title'] = 'Unknown Title'
327
+ item['title'] = 'Unknown Title'
284
328
 
285
329
  if not item.get('author') or item.get('author') == 'Unknown Author':
286
330
  if meta.get('author') and meta.get('author') != 'Unknown Author':
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libgenrs
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Asynchronous python lib for Libgen.rs
5
5
  Home-page: https://github.com/ramanveerji/libgenrs
6
- Download-URL: https://github.com/ramanveerji/libgenrs/archive/v0.3.2.tar.gz
6
+ Download-URL: https://github.com/ramanveerji/libgenrs/archive/v0.3.4.tar.gz
7
7
  License: MIT License
8
8
  Classifier: Intended Audience :: Developers
9
9
  Classifier: Operating System :: OS Independent
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes