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.
- {libgenrs-0.3.2 → libgenrs-0.3.4}/PKG-INFO +2 -2
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs/__init__.py +1 -1
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs/search.py +55 -11
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs.egg-info/PKG-INFO +2 -2
- {libgenrs-0.3.2 → libgenrs-0.3.4}/LICENSE +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/README.md +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs/download.py +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs/utils.py +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs.egg-info/SOURCES.txt +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs.egg-info/dependency_links.txt +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs.egg-info/not-zip-safe +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs.egg-info/requires.txt +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/libgenrs.egg-info/top_level.txt +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/setup.cfg +0 -0
- {libgenrs-0.3.2 → libgenrs-0.3.4}/setup.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: libgenrs
|
|
3
|
-
Version: 0.3.
|
|
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.
|
|
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
|
|
@@ -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(
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|