11import bs4
22import requests
3+ import warnings
34from typing import Union , List
45from .Infopage import info , InfoPage
6+ from datetime import datetime
7+ from .enums import *
58
69
710class SearchResult :
@@ -49,7 +52,7 @@ def get_all(self, limit: int = 20) -> List[InfoPage]:
4952 except TypeError :
5053 limit = 20
5154 for item in list (self .urls .keys ())[:limit ]:
52- print ('Getting:' , item )
55+ print ('Getting:' , item ) # noqa: 201
5356 lst .append (info (self .urls [item ]))
5457 return lst
5558
@@ -58,7 +61,7 @@ def search(name: str, page: int = 1, style: str = None, year=None, eps: int = No
5861 match_all : bool = True , max_results : int = 20 ) -> Union [SearchResult , None ]:
5962 urls = {}
6063 if max_results > 20 :
61- print ("Cannot have more than 20 Results!" )
64+ warnings . warn ("Cannot have more than 20 Results! Setting it to 20 and continuing... " )
6265 max_results = 20
6366 filters_given = any ([style , year , eps , score ])
6467 url = f"https://mydramalist.com/search?q={ name .replace (' ' , '+' )} &page={ page } "
@@ -136,7 +139,131 @@ def search(name: str, page: int = 1, style: str = None, year=None, eps: int = No
136139 filter_check |= 0b1000
137140
138141 # Add it to list if checks pass
139- if match_all and filter_check == 15 :
142+ elif match_all and filter_check == 15 :
143+ urls [curr_title ] = curr_url
144+ elif (not match_all ) and filter_check != 0 :
145+ urls [curr_title ] = curr_url
146+
147+ else : # Directly add if no filters are given
148+ urls [curr_title ] = curr_url
149+ if len (urls ) >= max_results :
150+ break
151+ if len (urls ) > 0 :
152+ return SearchResult (urls )
153+ else :
154+ return None
155+
156+
157+ def adv_search (name : str = None , page : int = 1 ,
158+ search_type : SearchType = SearchType .TITLE ,
159+ release_date_initial : int = 1890 ,
160+ release_date_final : int = datetime .now ().strftime ('%Y' ),
161+ title_types : List [TitleType ] = None ,
162+ title_status : TitleStatus = None ,
163+ title_sorted_by : TitleSortedByType = TitleSortedByType .MOST_POPULAR ,
164+ style : str = None ,
165+ year = None ,
166+ eps : int = None ,
167+ score : str = None ,
168+ match_all : bool = True ,
169+ max_results : int = 20 ) -> Union [SearchResult , None ]:
170+
171+ urls = {}
172+ if max_results > 20 :
173+ warnings .warn ("Cannot have more than 20 Results! Setting it to 20 and continuing..." )
174+ max_results = 20
175+
176+ title_type_encoded = ""
177+ if title_types is not None :
178+ title_type_encoded = f"&ty={ ',' .join (map (lambda t : str (t ), title_types ))} "
179+
180+ title_status_encoded = ""
181+ if title_status is not None :
182+ title_status_encoded = f'&st={ title_status } '
183+
184+ release_date_encoded = ""
185+ if release_date_initial != 1890 or release_date_final != datetime .now ().strftime ('%Y' ):
186+ release_date_encoded = f"&re={ release_date_initial } ,{ release_date_final } "
187+
188+ sorted_encoded = f"&so={ title_sorted_by } "
189+
190+ filters_given = any ([style , year , eps , score ])
191+ url = f"https://mydramalist.com/search?adv={ search_type } { title_type_encoded } { title_status_encoded } { release_date_encoded } { sorted_encoded } &page={ page } "
192+ base = requests .get (url )
193+ soup = bs4 .BeautifulSoup (base .text , 'lxml' )
194+ results_box = soup .find ('div' , class_ = 'col-lg-8 col-md-8' ).find_all ('div' , class_ = 'box' )
195+ for item in results_box :
196+ # Get Title
197+ try :
198+ curr_title = item .find ("h6" ).find ('a' ).text
199+ except AttributeError :
200+ return None
201+
202+ # Get Category
203+ curr_cateory = item .find ('span' , class_ = 'text-muted' )
204+
205+ # Check if Ctegory Exists
206+ if curr_cateory :
207+ curr_cateory = curr_cateory .text
208+ else :
209+ continue
210+
211+ # Get URL
212+ curr_url = item .find ("h6" ).find ('a' )['href' ]
213+
214+ # Apply filters
215+ if filters_given :
216+ if match_all :
217+ filter_check = 15 # Has to match all filters given
218+ else :
219+ filter_check = 0 # Has to match atleast one of the filters given
220+ # In Binary from MSB [0] is style, [1] is year, [2] is eps, [3] is score
221+
222+ # Check for Score
223+ curr_score = item .find ('span' , class_ = 'score' ).text
224+ if score :
225+ if curr_score :
226+ if score .endswith ('+' ):
227+ if not float (curr_score ) >= float (score .rstrip ('+' )):
228+ filter_check &= 0b1110
229+ else :
230+ filter_check |= 0b0001
231+ elif score .endswith ('-' ):
232+ if not float (curr_score ) <= float (score .rstrip ('-' )):
233+ filter_check &= 0b1110
234+ else :
235+ filter_check |= 0b0001
236+ else :
237+ if not curr_score == score :
238+ filter_check &= 0b1110
239+ else :
240+ filter_check |= 0b0001
241+ else :
242+ filter_check &= 0b1110
243+
244+ # Check for Episodes Filter
245+ if eps :
246+ if not ((curr_cateory .split (',' )[- 1 ]).startswith (f" { eps } episode" )):
247+ filter_check &= 0b1101
248+ else :
249+ filter_check |= 0b0010
250+
251+ # Check for Year Filter
252+ if year :
253+ if not curr_cateory .split (',' )[0 ].split ('-' )[- 1 ].strip () == str (year ):
254+ filter_check &= 0b1011
255+ else :
256+ filter_check |= 0b0100
257+
258+ # Check for Style Filter
259+ if style :
260+ if curr_cateory .find (style ) == - 1 :
261+ filter_check &= 0b0111
262+ else :
263+ filter_check |= 0b1000
264+
265+ # Add it to list if checks pass
266+ elif match_all and filter_check == 15 :
140267 urls [curr_title ] = curr_url
141268 elif (not match_all ) and filter_check != 0 :
142269 urls [curr_title ] = curr_url
0 commit comments