From 60fee6227faff6a431097fb996e7e4bce2d33c03 Mon Sep 17 00:00:00 2001 From: poka Date: Fri, 20 Mar 2020 02:44:22 +0100 Subject: [PATCH] Build ownmade yggcrawler --- crawl.py | 6 +- install.sh | 4 +- yggcrawl/__init__.py | 11 + yggcrawl/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 421 bytes .../__pycache__/categories.cpython-37.pyc | Bin 0 -> 25174 bytes yggcrawl/__pycache__/torrent.cpython-37.pyc | Bin 0 -> 2541 bytes .../yggtorrentscraper.cpython-37.pyc | Bin 0 -> 9266 bytes yggcrawl/categories.py | 3893 +++++++++++++++++ yggcrawl/tests/__init__.py | 0 yggcrawl/tests/test_change_tld.py | 26 + yggcrawl/tests/test_download.py | 65 + yggcrawl/tests/test_extract_details.py | 60 + yggcrawl/tests/test_login.py | 30 + yggcrawl/tests/test_logout.py | 27 + yggcrawl/tests/test_most_completed.py | 16 + yggcrawl/tests/test_search.py | 70 + yggcrawl/tests/test_torrent.py | 32 + yggcrawl/torrent.py | 146 + yggcrawl/yggtorrentscraper.py | 453 ++ 19 files changed, 4834 insertions(+), 5 deletions(-) create mode 100644 yggcrawl/__init__.py create mode 100644 yggcrawl/__pycache__/__init__.cpython-37.pyc create mode 100644 yggcrawl/__pycache__/categories.cpython-37.pyc create mode 100644 yggcrawl/__pycache__/torrent.cpython-37.pyc create mode 100644 yggcrawl/__pycache__/yggtorrentscraper.cpython-37.pyc create mode 100644 yggcrawl/categories.py create mode 100644 yggcrawl/tests/__init__.py create mode 100644 yggcrawl/tests/test_change_tld.py create mode 100644 yggcrawl/tests/test_download.py create mode 100644 yggcrawl/tests/test_extract_details.py create mode 100644 yggcrawl/tests/test_login.py create mode 100644 yggcrawl/tests/test_logout.py create mode 100644 yggcrawl/tests/test_most_completed.py create mode 100644 yggcrawl/tests/test_search.py create mode 100644 yggcrawl/tests/test_torrent.py create mode 100644 yggcrawl/torrent.py create mode 100644 yggcrawl/yggtorrentscraper.py diff --git a/crawl.py b/crawl.py index 5c8d4ec..f93d4ad 100755 --- a/crawl.py +++ b/crawl.py @@ -3,7 +3,7 @@ import json import sys import login -from yggtorrentscraper import YggTorrentScraper +from yggcrawl import YggTorrentScraper scraper = YggTorrentScraper(requests.session()) from yggtorrentscraper import set_yggtorrent_tld set_yggtorrent_tld("se") @@ -33,7 +33,7 @@ most_completed = scraper.most_completed() if(scraper.login(login.user, login.passwd)): print("Login success") + first_torrent = research[0] + scraper.download_from_torrent_url(first_torrent) else: print("Login failed") - -#scraper.download_from_torrent_url('') diff --git a/install.sh b/install.sh index 9ac7714..17a4ff0 100644 --- a/install.sh +++ b/install.sh @@ -15,8 +15,8 @@ sbotc() { # Install YGGTorrentScraper yggts() { echo -e "${c_yellow}Installing YGGTorrentScraper...$c_" - [[ -z $(which pip3) ]] && sudo apt install python3-pip - pip3 install yggtorrentscraper + # [[ -z $(which pip3) ]] && sudo apt install python3-pip + #pip3 install yggtorrentscraper } torrengo() { diff --git a/yggcrawl/__init__.py b/yggcrawl/__init__.py new file mode 100644 index 0000000..fa5ad71 --- /dev/null +++ b/yggcrawl/__init__.py @@ -0,0 +1,11 @@ +""" +__init__.py main +""" + +from .yggtorrentscraper import ( + YggTorrentScraper, + set_yggtorrent_tld, + get_yggtorrent_tld, +) +from .torrent import Torrent, TorrentComment, TorrentFile +from .categories import categories diff --git a/yggcrawl/__pycache__/__init__.cpython-37.pyc b/yggcrawl/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ec08ad3d5eda452ab1a0a22bb81844ac1786460 GIT binary patch literal 421 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 literal 0 HcmV?d00001 diff --git a/yggcrawl/__pycache__/torrent.cpython-37.pyc b/yggcrawl/__pycache__/torrent.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..150ffb078bd1528f45b510ea950052620ec6d3f9 GIT binary patch literal 2541 zcma)8UvC>l5Z}H3zSvIELMRYgQ)s~tZQejaC`u^`4szX9qC{AO<*UyK8+HFG=vcIIYg=loTp5i+dwcK+;_CC2_B zV!CW>wgA~@K!ORLurB+C2}{`LOxR~umxFSI3(5s$f%1e8$_Hf&zQfwVYuK_*pYU{D zp1TcB%(`5#t|d4utgZua0Up5LW8Fa5-5MYSEP+=CuK{QZU%0|M=iOytksswhNu`X3 zd2uUjVHv6g&LBV0tj_Ddu(tc;pOz1B0FMFLx`lV-r}hL=IlL}Dz@PQ+j>R5v_Rgd$m{=Pe!&WTDWbkWj!Fx zQIhsVEK0kbK~X)Wl*v-|I6WFAaSm1TuoK53mYMPQT^#rKH3^x&JxF5sdBfX92&*Hs zI>`32a)yXfS!t&HWH5}gc%u^c5EhVgK8qWp*)MbW!- zrFVfCcdUSiJhTEU>mlu=n5QU*@fg9C!$_&%&mjRHfU5eY5e4E&7gl1XQ38hRQ0x~K{rKxml z6*ntcn6^Qu?aL3KD{m9JL#Rba7x*siuC3mOknRF93NUbV%`8dW#kKkvl7+RR?`T;s zd@XgonkG^+FN(W!B{TQ&->YWBpRSs~=KohMr%$S*N9@(A(r1%6Briw%6*&TTO=WA3 z#`%6KX*AZpPct(mYfs`AxgL?|NUx_=u#?@~`H%7OD=2qHNH!St43cf7I R%_iNnj7CdfH=i}%`5VL98;Sq` literal 0 HcmV?d00001 diff --git a/yggcrawl/__pycache__/yggtorrentscraper.cpython-37.pyc b/yggcrawl/__pycache__/yggtorrentscraper.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99ee7fc41c2bb91a42cc9a3cc76599bda5a4ec81 GIT binary patch literal 9266 zcmcgyOLH7Ya_-mk^z=M1cmt$F4JiQXvX1_REE z)ios8Zg?Y>vSY(u+1&Md9pTk(48lIxdvf^TgHJx{H+1;si+T6Kp^N=xbx(5$fDt+w z)KphxRaRGJWo3Sut;@xtt>CY7N_=_tqN4mKH3ok=Dj(qIzpg3@Q<&ORocO6as%&eH zCZD>a%ctQOcxuf|%XCatVLCIK*_P#4t(=o<*^Vt~nP$F~ck-y4Zh>V*;Wx@}HMb~= zzfqWlT1nP&ztx-(S+hYaduo4_}&aaMFDSjm}WBhC~nJJW2`nPFqjEE{)D zunFfRn{=LIQ_l0>XN-K)G~RTI&A2bf)+|~TcEUNG_MKrbvXkt&uTycAA|5b)Kmk%EC*JNs_AzYE-=JxjoU??lm_$z3yX(Q(4fX>}H2^ zuPvfdQn}J;wWys>+SeLQ58QUm6<)o=8=fC&z8B2w2+{Q~E-l@^fB*IK59)Oh&vQP= zFZFznFEu;$Mmv~F8=anb-xb1Zb;YIEf{7)sjec**_gr4vdB5$pyi3vOlX?6ace@@B z3d3_d1_o4v;ym-v-{^`)r+q0f=eM!OOMyM#>oz+s^ElO$^**>1l;-{3R`p3cJKy1Q zkU8&nxVRJ;^Q=SDblp0pIWbsT-4j)s*?<+oj<3XY9JRQy=DPZ+D*XOb&Wl9beQs zt!~p39((*c-GO9sjn{NqSB|=uWzocudl3bRRncVsr0@yo&37Lz?Q~k+67EKC z%k!699B!uzEngf^p0FiXtlL~VLOb7m5RLiJ|0g~4k{^GZd9iqkL+99fS|?^S4oW z3i$*00u_EhV>&FL!3>tcGs8@l#nWWC1$bte&GL9!tiXzR=2(f1;At~hZ#D+YnrAa? zoK2usV6$wJO`%ql_Vh$F`f0tM*v5_6NUhf73b6=!(ogQ1oLZ=cN)`Sp*?W}rJ>Q4b zTF@fH_nO;$7K0AU!Kzjp?S`mUU34b94^A9;?fJp58VQ2_viMo}$=ClQDxtEg?5ch3 z02YR+Bo-2h(8;WjP?+^ic3+pH43WWNHJ1BE3w36Ht?wJc>}Od%Gdm2`$`9@s(_~Ua|epBXO;bo$nUDV1yK}sm|-KB#Z1;v3QZc#${UL09hI%I4a^JS zj0b-rO$-^Qo8&nv+`HTJd{MdI5IYsI<5m2wS8HrHJXUEiI4D%zwy3ymR_VIFe;+36 z9GFCpw?V87t5N5U*FFbJR)g$a{(#IH>)daXuSj1SoOZk2W&>UVr?a%T2)DMl-Qlgp z9&dW>T8DWon7joG-g4XPJ-i;5?5*>!;lDsXyL2|N+MUIkTifx15wH#$x1d-L8r^dh zSllLjXkg#*yzZjgY~1q}vO(cWr!BCZ#mxs@^xcN*TwJb`12&gyHLojz;uV^9k;d^( zGcrEJB7%{)b8&^122&l`=*JFe_0TP?!6JjiLVCtr;YQgVk36Fvlzrifo?oRcRW4TM z{MEFXEIxV-+jtp|oQRbf8?0K6(As)Hy!Z)&O3nNm8qin6y zxkKn6Q)|Mf%Ug~$V6nW2`6Cm6pziS~!@R9tJ<1O)BeLk?vqnus(?iB^bL~eftFVS^ zKf19JS&2UQQL)B7$PpW$_wf;$+$LKU6Be@k1V~PPNJ}DXpd$PX4aa1Dx6}4Lr+ipX zA~Ttn%v^jirESV!`HeOM(I?NX7zJHZ<9`;OmTppsXGt1FTPbsuH~H(Bo+bdyDWm()ZE2yLjk3$3`8(g!Ld{jU9i&#o9nv8#pG*d#LVfAtW4Xp?aXf4(hR))}qlw$6|C^g$;~?7P3vA>-<^K}e zY-CmmGu5Ifg%&H%D!X=ng#7J+_D}`AEa~G%=%bQ8afCh==4ckYdGbJIk`J?tgF1DD zIsxkR5$dFv>QA#7^vyoq$I1tKe+H$xpBJ;cv;7lco}D<*F#ky@zmwSEb8?4;z0I%y z`Q6+visvBTQdoq{j01Jo4olVNWeZZ1ty8k~Jmh(bc(MN%4it=ntK6+X^3t6?Qt$p5 zB(I?@FRzs73*f0F(nfTL2=JwEv;&RJ!R3y`CoWEhBh$)}Q!j_*G~>VSjVj z&p7GTBkk@5>@S0>b~boBwL2?&g1a?QX&`puE$M~*$~Nz`;H_nV`m$farAx;L<%CXm zP5QCOXzsO|2vx0Z_=g@$e5AVMjo=0y1J|<^X@c_?aCw}P%kEW^y9$@@m;{sIMKgjT zAg3_A3MV7BI_!aCZ1seQj2-T6b3(S?sg+3KI%`YmT*@~f0dh_XqilOyG;3b&3e530@x1e*Z1xT`#@ zbVPDS1}L>ks@G{dcI&}lZ%!dmkC-_>)I!E8zA`{WQe_-_Kxi<>mb;NFbmC3M3zJ)? zx2BsQijx&gzTvO~8^K}Ig{?AA00{cOhy46|D9AY*(mk7687_KEE32k~pK9vVwzU}* z|FkI;|1<*#X^i@SmTcK?Y9+O#8tQ~T2G?Fz3+OA8vj?xK*}6?AOD!4kGp>(m!RezA z;Lr+FoJCO*X@+#6yQolP)EHna;H^+4hY4gQqo+Z;uOGm@!o}))Z-g2Q={dMmBSern ztB^Z|i_L_YJ`yl6!e*%V%@6_SEKD+->6a!cjHQ;L5G9>*3s4#j2V6ONz)!QMQE&lE zNFfr%Hgt|ac`+nHbi1q5i4!D(b2Z|aSUPi@A2aV*{D&;NZ?;d!)3k7!Sz(4*mcuzC z#sz9Lp#|1nQ&4nlJ|tcE63{0ntO+=7R(Mwtxe%ZxM(xjhvkj+S8~`Q2FdOrX?dLeTOX`3j+-8Rf%d5~*^HH{5TpNhiTNEWC=PJ)iHnwNX%oe6Hd@Gx5WyKinQX2~ zy2k6o*rj2ECHvBjrY8HS4)Ti_{t77`T@EEfVMST9$kO0xkp0mJnG@B9y$a48Rl~!9 z!FR>;OC;MRX=#^Iy?iPLAvX*=quj~yGl)S@C+G%ERiU36v`GD0L)1ozBW)GI(Kg0M zW#qlZV9Q-s>@4WKK^ z@D^DEIT61>8Kgi01NlwnF=a7%2Suda-&z=naw~h3mcpnZ8$c#EPOSifGH)-^IzE{Y zu@jlzUc(oDWYG#(13|K}+o7CN2dFX1+~>Hu(tHq9@Aw{)2$a7WQc-CNO7!JOevYY1 zGsG~)DM`?RTvZbm0q+9%YZS!&B?bmA2DD>@JZ?s7q!(hAUE!WDGGgEzjX4m@?I za5cG)Nsl~B5puY+&T2KXtJPMA^#ClZQK4GB+jE<7Pb|Na;OBop1!dPI%9VGTx2Q?x zi4&~i_odcaT|AD@2+6VY0`*O1Hf6!;8eQ@Wp&!)ad8h`hZy7#8YT~!{b1nn?0oIT(jg!`kte+EYh5-%K( z#QLA(y6i{{;Mp1Crg|KC?Cnv1~^eg zDVbw3e!>(@1#d`nlE7TI5(oCk-y;u5je&teWFPx^IXsS1uR%4xQ(sNI`OxQHpL^)y zU!Xvgh!0y)Mt;qWticCf30ja}?rjYyPVq^DGSu0Qv|k8aWk%Z%tofKy#s4JGYl;T& zXpo=#!E)NrKl|cRjGrh9MasKGi};KdabhTA{p6dV1Uiw9P%}Dx{D7+~8&}qE+}gac zw)(6&=yP9m>Uj3sw{EU2UtL*$7VpN|`et9gm{{EzVVC`(=!-)ne? z7AK3%mrywRmj6Z^Xh|$X;6i3EWL`oZRs7jhI$HXk!r!8T)G*2cfFctQxE`l*=!*zH zPsJ~&_$3v8O~tRN_**LehKgTN@pn}G6%{fKGD_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "animation_serie", + "id": "2179", + "options": [ + { + "name": "episode", + "id": "34", + "values": [ + "saison_complete", + "episode_01", + "episode_02", + "episode_03", + "episode_04", + "episode_05", + "episode_06", + "episode_07", + "episode_08", + "episode_09", + "episode_10", + "episode_11", + "episode_12", + "episode_13", + "episode_14", + "episode_15", + "episode_16", + "episode_17", + "episode_18", + "episode_19", + "episode_20", + "episode_21", + "episode_22", + "episode_23", + "episode_24", + "episode_25", + "episode_26", + "episode_27", + "episode_28", + "episode_29", + "episode_30", + "episode_31", + "episode_32", + "episode_33", + "episode_34", + "episode_35", + "episode_36", + "episode_37", + "episode_38", + "episode_39", + "episode_40", + "episode_41", + "episode_42", + "episode_43", + "episode_44", + "episode_45", + "episode_46", + "episode_47", + "episode_48", + "episode_49", + "episode_50", + "episode_51", + "episode_52", + "episode_53", + "episode_54", + "episode_55", + "episode_56", + "episode_57", + "episode_58", + "episode_59", + "episode_60", + "non_communique", + ], + }, + { + "name": "saison", + "id": "35", + "values": [ + "serie_integrale", + "hors_saison", + "non_communique", + "saison_01", + "saison_02", + "saison_03", + "saison_04", + "saison_05", + "saison_06", + "saison_07", + "saison_08", + "saison_09", + "saison_10", + "saison_11", + "saison_12", + "saison_13", + "saison_14", + "saison_15", + "saison_16", + "saison_17", + "saison_18", + "saison_19", + "saison_20", + "saison_21", + "saison_22", + "saison_23", + "saison_24", + "saison_25", + "saison_26", + "saison_27", + "saison_28", + "saison_29", + "saison_30", + ], + }, + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "concert", + "id": "2180", + "options": [ + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + ], + }, + { + "name": "documentaire", + "id": "2181", + "options": [ + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "emission_tv", + "id": "2182", + "options": [ + { + "name": "episode", + "id": "34", + "values": [ + "saison_complete", + "episode_01", + "episode_02", + "episode_03", + "episode_04", + "episode_05", + "episode_06", + "episode_07", + "episode_08", + "episode_09", + "episode_10", + "episode_11", + "episode_12", + "episode_13", + "episode_14", + "episode_15", + "episode_16", + "episode_17", + "episode_18", + "episode_19", + "episode_20", + "episode_21", + "episode_22", + "episode_23", + "episode_24", + "episode_25", + "episode_26", + "episode_27", + "episode_28", + "episode_29", + "episode_30", + "episode_31", + "episode_32", + "episode_33", + "episode_34", + "episode_35", + "episode_36", + "episode_37", + "episode_38", + "episode_39", + "episode_40", + "episode_41", + "episode_42", + "episode_43", + "episode_44", + "episode_45", + "episode_46", + "episode_47", + "episode_48", + "episode_49", + "episode_50", + "episode_51", + "episode_52", + "episode_53", + "episode_54", + "episode_55", + "episode_56", + "episode_57", + "episode_58", + "episode_59", + "episode_60", + "non_communique", + ], + }, + { + "name": "saison", + "id": "35", + "values": [ + "serie_integrale", + "hors_saison", + "non_communique", + "saison_01", + "saison_02", + "saison_03", + "saison_04", + "saison_05", + "saison_06", + "saison_07", + "saison_08", + "saison_09", + "saison_10", + "saison_11", + "saison_12", + "saison_13", + "saison_14", + "saison_15", + "saison_16", + "saison_17", + "saison_18", + "saison_19", + "saison_20", + "saison_21", + "saison_22", + "saison_23", + "saison_24", + "saison_25", + "saison_26", + "saison_27", + "saison_28", + "saison_29", + "saison_30", + ], + }, + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "film", + "id": "2183", + "options": [ + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "serie_tv", + "id": "2184", + "options": [ + { + "name": "episode", + "id": "34", + "values": [ + "saison_complete", + "episode_01", + "episode_02", + "episode_03", + "episode_04", + "episode_05", + "episode_06", + "episode_07", + "episode_08", + "episode_09", + "episode_10", + "episode_11", + "episode_12", + "episode_13", + "episode_14", + "episode_15", + "episode_16", + "episode_17", + "episode_18", + "episode_19", + "episode_20", + "episode_21", + "episode_22", + "episode_23", + "episode_24", + "episode_25", + "episode_26", + "episode_27", + "episode_28", + "episode_29", + "episode_30", + "episode_31", + "episode_32", + "episode_33", + "episode_34", + "episode_35", + "episode_36", + "episode_37", + "episode_38", + "episode_39", + "episode_40", + "episode_41", + "episode_42", + "episode_43", + "episode_44", + "episode_45", + "episode_46", + "episode_47", + "episode_48", + "episode_49", + "episode_50", + "episode_51", + "episode_52", + "episode_53", + "episode_54", + "episode_55", + "episode_56", + "episode_57", + "episode_58", + "episode_59", + "episode_60", + "non_communique", + ], + }, + { + "name": "saison", + "id": "35", + "values": [ + "serie_integrale", + "hors_saison", + "non_communique", + "saison_01", + "saison_02", + "saison_03", + "saison_04", + "saison_05", + "saison_06", + "saison_07", + "saison_08", + "saison_09", + "saison_10", + "saison_11", + "saison_12", + "saison_13", + "saison_14", + "saison_15", + "saison_16", + "saison_17", + "saison_18", + "saison_19", + "saison_20", + "saison_21", + "saison_22", + "saison_23", + "saison_24", + "saison_25", + "saison_26", + "saison_27", + "saison_28", + "saison_29", + "saison_30", + ], + }, + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "spectacle", + "id": "2185", + "options": [ + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + { + "name": "genre", + "id": "33", + "multiple": "1", + "values": [ + "action", + "animalier", + "animation", + "arts", + "arts_martiaux", + "aventure", + "ballet", + "biopic", + "choregraphie", + "classique", + "comedie", + "comedie_dramatique", + "court-metrage", + "culinaire", + "danse_contemporaine", + "decouverte", + "divers", + "documentaire", + "drame", + "enquete", + "epouvante_&_horreur", + "espionnage", + "famille", + "fantastique", + "fiction", + "film_noir", + "gore", + "guerre", + "historique", + "humour", + "interactif", + "judiciaire", + "litterature", + "manga", + "musical", + "nanar", + "nature", + "opera", + "opera_rock", + "pedagogie", + "peplum", + "philosophie", + "policier", + "politique_&_geopolitique", + "religions_&_croyances", + "romance", + "sante_&_bien-etre", + "science_fiction", + "sciences_&_technologies", + "societe", + "sports_&_loisirs", + "tele-realite", + "theatre", + "thriller", + "varietes_tv", + "voyages_&_tourisme", + "western", + ], + }, + ], + }, + { + "name": "sport", + "id": "2186", + "options": [ + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + ], + }, + { + "name": "video-clips", + "id": "2187", + "options": [ + { + "name": "langue", + "id": "29", + "multiple": "1", + "values": [ + "anglais", + "francais_(vff/truefrench)", + "muet", + "multi_(francais_inclus)", + "multi_(quebecois_inclus)", + "quebecois_(vfq/french)", + "vfstfr", + "vostfr", + ], + }, + { + "name": "qualite", + "id": "30", + "values": [ + "bdrip/brrip_[rip_sd_(non_hd)_depuis_bluray_ou_hdrip]", + "bluray_4k_[full_ou_remux]", + "bluray_[full]", + "bluray_[remux]", + "dvd-r_5_[dvd_<_4.37gb]", + "dvd-r_9_[dvd_>_4.37gb]", + "dvdrip_[rip_depuis_dvd-r]", + "hdrip_1080_[rip_hd_depuis_bluray]", + "hdrip_4k_[rip_hd_4k_depuis_source_4k]", + "hdrip_720_[rip_hd_depuis_bluray]", + "tvrip_[rip_sd_(non_hd)_depuis_source_tv_hd/sd]", + "tvriphd_1080_[rip_hd_depuis_source_tv_hd]", + "tvriphd_4k_[rip_hd_4k_depuis_source_tv_4k]", + "tvriphd_720_[rip_hd_depuis_source_tv_hd]", + "vcd/svcd/vhsrip", + "web-dl", + "web-dl_1080", + "web-dl_4k", + "web-dl_720", + "webrip", + "webrip_1080", + "webrip_4k", + "webrip_720", + ], + }, + { + "name": "systeme", + "id": "31", + "multiple": "1", + "values": [ + "nintendo_ds/3ds", + "pc/platine/lecteur_multimedia/etc", + "smartphone/tablette/psp/psvita", + ], + }, + { + "name": "type", + "id": "32", + "values": [ + "2d_(standard)", + "3d_converti_(non_officiel/amateur)", + "3d_converti_(post-production)", + "3d_natif_(production)", + ], + }, + ], + }, + ], + }, + { + "name": "ebook", + "id": "2140", + "subcategories": [ + { + "name": "audio", + "id": "2151", + "options": [ + { + "name": "format", + "id": "14", + "values": [ + "aac_(m4a)", + "ac3", + "aif", + "alac_(m4a)", + "bluray_pure_audio", + "dsd", + "dts", + "flac_(16_bit)", + "flac_(24_bit)", + "monkey's_audio", + "mp3", + "mpc", + "ogg", + "samples", + "wav", + "wavpack", + "wma", + ], + }, + { + "name": "type", + "id": "15", + "values": [ + "album", + "bande_originale_de_film/jeu", + "discographie", + "ep", + "integrale/coffret", + "live/concert", + "mix/medley", + "piste_audio_de_film", + "radio", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "17", + "multiple": "1", + "values": [ + "actualites", + "animaux", + "art", + "astrologie", + "auto-moto-vehicules", + "aventure", + "beaute", + "bien-etre", + "biographie", + "bricolage", + "cinema", + "comedie", + "conte", + "cuisine_et_vin", + "decoration", + "dictionnaire", + "droit", + "economie", + "encyclopedies", + "esoterisme", + "fantastique", + "fantasy", + "guerre", + "heroic_fantasy", + "histoire", + "humour", + "informatique", + "internet", + "jardinage", + "jeunesse", + "jeux_video", + "journalisme", + "linguistique", + "litterature", + "loisir", + "manuel", + "medecine", + "musique", + "nature", + "nouvelles", + "paranormal", + "parascolaire", + "partitions", + "philosophie", + "photos", + "poesie", + "polar", + "policier", + "politique", + "professionnel", + "religion", + "roman", + "sante", + "science", + "science_humaine", + "science-fiction", + "scolaire", + "societe", + "spiritualite", + "sport", + "suspense", + "technique", + "terreur", + "theatre", + "thriller", + "tourisme", + "vie_pratique", + "voyage", + ], + }, + ], + }, + { + "name": "bds", + "id": "2152", + "options": [ + { + "name": "format", + "id": "18", + "values": [ + "azw", + "cb7", + "cba", + "cbr", + "cbt", + "cbz", + "djvu", + "doc", + "epub", + "jpg", + "mobi", + "pdf", + "png", + "prc", + ], + }, + { + "name": "langue", + "id": "19", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "20", + "multiple": "1", + "values": [ + "actualites", + "animaux", + "art", + "astrologie", + "auto-moto-vehicules", + "aventure", + "beaute", + "bien-etre", + "biographie", + "bricolage", + "cinema", + "comedie", + "conte", + "cuisine_et_vin", + "decoration", + "dictionnaire", + "droit", + "economie", + "encyclopedies", + "esoterisme", + "fantastique", + "fantasy", + "guerre", + "heroic_fantasy", + "histoire", + "humour", + "informatique", + "internet", + "jardinage", + "jeunesse", + "jeux_video", + "journalisme", + "linguistique", + "litterature", + "loisir", + "manuel", + "medecine", + "musique", + "nature", + "nouvelles", + "paranormal", + "parascolaire", + "partitions", + "philosophie", + "photos", + "poesie", + "polar", + "policier", + "politique", + "professionnel", + "religion", + "roman", + "sante", + "science", + "science_humaine", + "science-fiction", + "scolaire", + "societe", + "spiritualite", + "sport", + "suspense", + "technique", + "terreur", + "theatre", + "thriller", + "tourisme", + "vie_pratique", + "voyage", + ], + }, + ], + }, + { + "name": "comics", + "id": "2153", + "options": [ + { + "name": "format", + "id": "18", + "values": [ + "azw", + "cb7", + "cba", + "cbr", + "cbt", + "cbz", + "djvu", + "doc", + "epub", + "jpg", + "mobi", + "pdf", + "png", + "prc", + ], + }, + { + "name": "langue", + "id": "19", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "20", + "multiple": "1", + "values": [ + "actualites", + "animaux", + "art", + "astrologie", + "auto-moto-vehicules", + "aventure", + "beaute", + "bien-etre", + "biographie", + "bricolage", + "cinema", + "comedie", + "conte", + "cuisine_et_vin", + "decoration", + "dictionnaire", + "droit", + "economie", + "encyclopedies", + "esoterisme", + "fantastique", + "fantasy", + "guerre", + "heroic_fantasy", + "histoire", + "humour", + "informatique", + "internet", + "jardinage", + "jeunesse", + "jeux_video", + "journalisme", + "linguistique", + "litterature", + "loisir", + "manuel", + "medecine", + "musique", + "nature", + "nouvelles", + "paranormal", + "parascolaire", + "partitions", + "philosophie", + "photos", + "poesie", + "polar", + "policier", + "politique", + "professionnel", + "religion", + "roman", + "sante", + "science", + "science_humaine", + "science-fiction", + "scolaire", + "societe", + "spiritualite", + "sport", + "suspense", + "technique", + "terreur", + "theatre", + "thriller", + "tourisme", + "vie_pratique", + "voyage", + ], + }, + ], + }, + { + "name": "livres", + "id": "2154", + "options": [ + { + "name": "format", + "id": "18", + "values": [ + "azw", + "cb7", + "cba", + "cbr", + "cbt", + "cbz", + "djvu", + "doc", + "epub", + "jpg", + "mobi", + "pdf", + "png", + "prc", + ], + }, + { + "name": "langue", + "id": "19", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "20", + "multiple": "1", + "values": [ + "actualites", + "animaux", + "art", + "astrologie", + "auto-moto-vehicules", + "aventure", + "beaute", + "bien-etre", + "biographie", + "bricolage", + "cinema", + "comedie", + "conte", + "cuisine_et_vin", + "decoration", + "dictionnaire", + "droit", + "economie", + "encyclopedies", + "esoterisme", + "fantastique", + "fantasy", + "guerre", + "heroic_fantasy", + "histoire", + "humour", + "informatique", + "internet", + "jardinage", + "jeunesse", + "jeux_video", + "journalisme", + "linguistique", + "litterature", + "loisir", + "manuel", + "medecine", + "musique", + "nature", + "nouvelles", + "paranormal", + "parascolaire", + "partitions", + "philosophie", + "photos", + "poesie", + "polar", + "policier", + "politique", + "professionnel", + "religion", + "roman", + "sante", + "science", + "science_humaine", + "science-fiction", + "scolaire", + "societe", + "spiritualite", + "sport", + "suspense", + "technique", + "terreur", + "theatre", + "thriller", + "tourisme", + "vie_pratique", + "voyage", + ], + }, + ], + }, + { + "name": "manga", + "id": "2155", + "options": [ + { + "name": "format", + "id": "18", + "values": [ + "azw", + "cb7", + "cba", + "cbr", + "cbt", + "cbz", + "djvu", + "doc", + "epub", + "jpg", + "mobi", + "pdf", + "png", + "prc", + ], + }, + { + "name": "langue", + "id": "19", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "20", + "multiple": "1", + "values": [ + "actualites", + "animaux", + "art", + "astrologie", + "auto-moto-vehicules", + "aventure", + "beaute", + "bien-etre", + "biographie", + "bricolage", + "cinema", + "comedie", + "conte", + "cuisine_et_vin", + "decoration", + "dictionnaire", + "droit", + "economie", + "encyclopedies", + "esoterisme", + "fantastique", + "fantasy", + "guerre", + "heroic_fantasy", + "histoire", + "humour", + "informatique", + "internet", + "jardinage", + "jeunesse", + "jeux_video", + "journalisme", + "linguistique", + "litterature", + "loisir", + "manuel", + "medecine", + "musique", + "nature", + "nouvelles", + "paranormal", + "parascolaire", + "partitions", + "philosophie", + "photos", + "poesie", + "polar", + "policier", + "politique", + "professionnel", + "religion", + "roman", + "sante", + "science", + "science_humaine", + "science-fiction", + "scolaire", + "societe", + "spiritualite", + "sport", + "suspense", + "technique", + "terreur", + "theatre", + "thriller", + "tourisme", + "vie_pratique", + "voyage", + ], + }, + ], + }, + { + "name": "presse", + "id": "2156", + "options": [ + { + "name": "format", + "id": "18", + "values": [ + "azw", + "cb7", + "cba", + "cbr", + "cbt", + "cbz", + "djvu", + "doc", + "epub", + "jpg", + "mobi", + "pdf", + "png", + "prc", + ], + }, + { + "name": "langue", + "id": "19", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "20", + "multiple": "1", + "values": [ + "actualites", + "animaux", + "art", + "astrologie", + "auto-moto-vehicules", + "aventure", + "beaute", + "bien-etre", + "biographie", + "bricolage", + "cinema", + "comedie", + "conte", + "cuisine_et_vin", + "decoration", + "dictionnaire", + "droit", + "economie", + "encyclopedies", + "esoterisme", + "fantastique", + "fantasy", + "guerre", + "heroic_fantasy", + "histoire", + "humour", + "informatique", + "internet", + "jardinage", + "jeunesse", + "jeux_video", + "journalisme", + "linguistique", + "litterature", + "loisir", + "manuel", + "medecine", + "musique", + "nature", + "nouvelles", + "paranormal", + "parascolaire", + "partitions", + "philosophie", + "photos", + "poesie", + "polar", + "policier", + "politique", + "professionnel", + "religion", + "roman", + "sante", + "science", + "science_humaine", + "science-fiction", + "scolaire", + "societe", + "spiritualite", + "sport", + "suspense", + "technique", + "terreur", + "theatre", + "thriller", + "tourisme", + "vie_pratique", + "voyage", + ], + }, + ], + }, + ], + }, + { + "name": "audio", + "id": "2139", + "subcategories": [ + {"name": "karaoke", "id": "2147", "options": []}, + { + "name": "musique", + "id": "2148", + "options": [ + { + "name": "format", + "id": "6", + "values": [ + "aac_(m4a)", + "ac3", + "aif", + "alac_(m4a)", + "bluray_pure_audio", + "dsd", + "dts", + "flac_(16_bit)", + "flac_(24_bit)", + "monkey's_audio", + "mp3", + "mpc", + "ogg", + "samples", + "wav", + "wavpack", + "wma", + ], + }, + { + "name": "qualite", + "id": "7", + "values": ["bluray_audio", "cd", "sacd", "vinyle", "web"], + }, + { + "name": "type", + "id": "8", + "values": [ + "album", + "bande_originale_de_film/jeu", + "discographie", + "ep", + "integrale/coffret", + "live/concert", + "mix/medley", + "piste_audio_de_film", + "radio", + ], + }, + { + "name": "genre", + "id": "9", + "multiple": "1", + "values": [ + "acid_house", + "acid_jazz", + "africaine", + "alternative", + "ambiance", + "b.o/ost_de_film", + "b.o/ost_de_jeu_video", + "baroque", + "black_metal", + "blues", + "boogie", + "bossa_nova", + "britpop", + "celtique", + "chill_out", + "cirque", + "classique", + "comedie_musicale", + "compilation", + "concerto", + "country", + "creole", + "dance_pop", + "dark_metal", + "death_metal", + "disco", + "divers", + "doom_metal", + "drum_&_bass", + "drumstep", + "dubstep", + "east_coast", + "electro", + "electro_house", + "electronique", + "enfants", + "eurodance", + "experimental", + "flamenco", + "folk", + "folk_pop", + "free_jazz_&_avant-garde", + "funk", + "fusion", + "fusion_&_jazz", + "g-funk", + "gangsta_rap", + "garage", + "gospel", + "gothique", + "grind_core", + "grunge", + "hard_core", + "hard_rock", + "hard_rock_metal", + "heavy_metal", + "hip-hop", + "house", + "humour", + "hymnes", + "indie", + "indie_dance", + "industriel", + "instrumental", + "intelligent_dance_music", + "jazz", + "jump_up", + "jungle", + "kiosque", + "latin_jazz", + "lecture", + "liquidstep", + "medieval", + "metal", + "metal_progressif", + "moombahton", + "motown", + "musique_sacree", + "musiques_du_monde", + "musiques_militaires", + "new_age", + "new_wave", + "nu_disco", + "old_school", + "oldies", + "opera_et_voix", + "piece", + "pop", + "pop_electro", + "pop_r&b", + "pop_reggae", + "pop_rock", + "popcorn", + "post-rock", + "progressive_house", + "punk", + "r&b", + "radio", + "rag_time", + "raggamuffin", + "rap", + "reggae", + "relaxation", + "remix", + "rock", + "rock_alternatif", + "rock_gothique", + "rock_hardcore", + "rock_progressif", + "roots", + "rythm_and_blues", + "salsa", + "samba", + "shoegaze", + "ska", + "soul", + "speed_metal", + "symphonie", + "techno", + "thrash", + "trance", + "trap", + "tribal", + "trip-hop", + "underground", + "variete_francaise", + "variete_internationale", + "vocal_&_traditionnel", + "west_coast", + "zeuhl", + "zouk", + ], + }, + ], + }, + { + "name": "podcast_radio", + "id": "2150", + "options": [ + { + "name": "format", + "id": "12", + "values": [ + "aac_(m4a)", + "ac3", + "aif", + "alac_(m4a)", + "bluray_pure_audio", + "dsd", + "dts", + "flac_(16_bit)", + "flac_(24_bit)", + "monkey's_audio", + "mp3", + "mpc", + "ogg", + "samples", + "wav", + "wavpack", + "wma", + ], + }, + { + "name": "genre", + "id": "13", + "multiple": "1", + "values": [ + "humour", + "litteraire", + "loisirs", + "musical", + "politique/societe", + "radio_libre", + "sciences", + "sports", + ], + }, + ], + }, + { + "name": "samples", + "id": "2149", + "options": [ + { + "name": "format", + "id": "10", + "values": [ + "aac_(m4a)", + "ac3", + "aif", + "alac_(m4a)", + "bluray_pure_audio", + "dsd", + "dts", + "flac_(16_bit)", + "flac_(24_bit)", + "monkey's_audio", + "mp3", + "mpc", + "ogg", + "samples", + "wav", + "wavpack", + "wma", + ], + }, + { + "name": "genre", + "id": "11", + "multiple": "1", + "values": [ + "acid_house", + "acid_jazz", + "africaine", + "alternative", + "ambiance", + "b.o/ost_de_film", + "b.o/ost_de_jeu_video", + "baroque", + "black_metal", + "blues", + "boogie", + "bossa_nova", + "britpop", + "celtique", + "chill_out", + "cirque", + "classique", + "comedie_musicale", + "compilation", + "concerto", + "country", + "creole", + "dance_pop", + "dark_metal", + "death_metal", + "disco", + "divers", + "doom_metal", + "drum_&_bass", + "drumstep", + "dubstep", + "east_coast", + "electro", + "electro_house", + "electronique", + "enfants", + "eurodance", + "experimental", + "flamenco", + "folk", + "folk_pop", + "free_jazz_&_avant-garde", + "funk", + "fusion", + "fusion_&_jazz", + "g-funk", + "gangsta_rap", + "garage", + "gospel", + "gothique", + "grind_core", + "grunge", + "hard_core", + "hard_rock", + "hard_rock_metal", + "heavy_metal", + "hip-hop", + "house", + "humour", + "hymnes", + "indie", + "indie_dance", + "industriel", + "instrumental", + "intelligent_dance_music", + "jazz", + "jump_up", + "jungle", + "kiosque", + "latin_jazz", + "lecture", + "liquidstep", + "medieval", + "metal", + "metal_progressif", + "moombahton", + "motown", + "musique_sacree", + "musiques_du_monde", + "musiques_militaires", + "new_age", + "new_wave", + "nu_disco", + "old_school", + "oldies", + "opera_et_voix", + "piece", + "pop", + "pop_electro", + "pop_r&b", + "pop_reggae", + "pop_rock", + "popcorn", + "post-rock", + "progressive_house", + "punk", + "r&b", + "radio", + "rag_time", + "raggamuffin", + "rap", + "reggae", + "relaxation", + "remix", + "rock", + "rock_alternatif", + "rock_gothique", + "rock_hardcore", + "rock_progressif", + "roots", + "rythm_and_blues", + "salsa", + "samba", + "shoegaze", + "ska", + "soul", + "speed_metal", + "symphonie", + "techno", + "thrash", + "trance", + "trap", + "tribal", + "trip-hop", + "underground", + "variete_francaise", + "variete_internationale", + "vocal_&_traditionnel", + "west_coast", + "zeuhl", + "zouk", + ], + }, + ], + }, + ], + }, + { + "name": "applications", + "id": "2144", + "subcategories": [ + { + "name": "autre", + "id": "2177", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + ], + }, + { + "name": "formation", + "id": "2176", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + ], + }, + { + "name": "linux", + "id": "2171", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + ], + }, + { + "name": "macos", + "id": "2172", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + ], + }, + { + "name": "smartphone", + "id": "2174", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "systeme", + "id": "26", + "values": [ + "android", + "bada", + "ios", + "meego", + "rim", + "symbian", + "webos", + "windows_mobile", + "windows_rt", + ], + }, + ], + }, + { + "name": "tablette", + "id": "2175", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "systeme", + "id": "26", + "values": [ + "android", + "bada", + "ios", + "meego", + "rim", + "symbian", + "webos", + "windows_mobile", + "windows_rt", + ], + }, + ], + }, + { + "name": "windows", + "id": "2173", + "options": [ + { + "name": "genre", + "id": "28", + "multiple": "1", + "values": [ + "accessibilite", + "administration", + "agenda", + "album_et_visionneuse", + "animation_2d_et_3d", + "animaux", + "anonymat", + "anti-spam", + "anti-spyware", + "anti-trojan", + "antivirus", + "architecture", + "aspiration_de_site", + "astrologie_et_voyance", + "astronomie_et_espace", + "audio", + "automobile", + "bricolage", + "bureautique", + "cao_et_pao", + "client_ftp", + "codec", + "commerce_electronique", + "communaute", + "communication", + "compression", + "comptabilite", + "controle_parental", + "courrier", + "crack", + "cryptage_et_securite", + "cuisine", + "developpement", + "developpement_web", + "editeur_de_site", + "edition_multimedia", + "education_et_scolarite", + "electronique", + "firewall", + "firmware", + "genealogie", + "geographie", + "gestionnaire_de_fichiers", + "gestionnaire_de_sites", + "graphisme", + "gravure", + "lecteur_multimedia", + "loader", + "maison", + "meteo", + "musique", + "navigateur_web", + "nettoyage_et_optimisation", + "organiseur", + "partage_de_fichiers", + "permis", + "photographie", + "planification", + "reconnaisance", + "referencement", + "registre", + "reseau", + "sante", + "sauvegarde", + "science", + "serveur_ftp", + "sport", + "systeme", + "systeme_d'exploitation", + "traducteur", + "utilitaire", + "video", + "wallpaper", + "webcam", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + ], + }, + ], + }, + { + "name": "jeux_video", + "id": "2142", + "subcategories": [ + { + "name": "autre", + "id": "2167", + "options": [ + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "linux", + "id": "2159", + "options": [ + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "macos", + "id": "2160", + "options": [ + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "microsoft", + "id": "2162", + "options": [ + { + "name": "console", + "id": "23", + "values": ["xbox", "xbox_360", "xbox_one"], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "nintendo", + "id": "2163", + "options": [ + { + "name": "console", + "id": "24", + "values": ["3ds", "ds", "gamecube", "wii", "wiiu"], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "smartphone", + "id": "2165", + "options": [ + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "systeme", + "id": "26", + "values": [ + "android", + "bada", + "ios", + "meego", + "rim", + "symbian", + "webos", + "windows_mobile", + "windows_rt", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "sony", + "id": "2164", + "options": [ + { + "name": "console", + "id": "25", + "values": [ + "playstation", + "playstation2", + "playstation3", + "playstation4", + "psp", + "vita", + ], + }, + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "tablette", + "id": "2166", + "options": [ + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "systeme", + "id": "26", + "values": [ + "android", + "bada", + "ios", + "meego", + "rim", + "symbian", + "webos", + "windows_mobile", + "windows_rt", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + { + "name": "windows", + "id": "2161", + "options": [ + { + "name": "langue", + "id": "16", + "values": [ + "anglais", + "francais", + "japonais", + "multi_(francais_inclus)", + ], + }, + { + "name": "genre", + "id": "22", + "multiple": "1", + "values": [ + "action", + "aventure", + "beat'em_all", + "city_builder", + "combat", + "course", + "crack", + "dlc", + "educatif", + "flipper", + "fps", + "gestion", + "hack'n_slash", + "infiltration", + "jeu_de_role", + "ludo-educatif", + "mmo", + "objets_caches", + "party_game", + "plates-formes", + "point'n'click", + "puzzle-game", + "reflexion", + "roguelike", + "rythme", + "shoot'em_up", + "simulation", + "sport", + "strategie", + "survival-horror", + "tactique", + "tower_defense", + "tps", + "update", + "visual_novel", + "wargame", + ], + }, + ], + }, + ], + }, + { + "name": "emulation", + "id": "2141", + "subcategories": [ + {"name": "emulateur", "id": "2157", "options": []}, + {"name": "rom/iso", "id": "2158", "options": []}, + ], + }, + { + "name": "gps", + "id": "2143", + "subcategories": [ + {"name": "applications", "id": "2168", "options": []}, + {"name": "cartes", "id": "2169", "options": []}, + {"name": "divers", "id": "2170", "options": []}, + ], + }, +] diff --git a/yggcrawl/tests/__init__.py b/yggcrawl/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/yggcrawl/tests/test_change_tld.py b/yggcrawl/tests/test_change_tld.py new file mode 100644 index 0000000..b42c67b --- /dev/null +++ b/yggcrawl/tests/test_change_tld.py @@ -0,0 +1,26 @@ +import unittest + +from ..yggtorrentscraper import ( + YggTorrentScraper, + set_yggtorrent_tld, + get_yggtorrent_tld, +) + + +class TestChangeYggtorrentTLD(unittest.TestCase): + current_yggtorrent_tld = get_yggtorrent_tld() + + def test_read_tld(self): + self.current_yggtorrent_tld = get_yggtorrent_tld() + + self.assertTrue(self.current_yggtorrent_tld == "se") + + def test_set_yggtorrent_tld(self): + + set_yggtorrent_tld("newtld") + + self.assertTrue(get_yggtorrent_tld() == "newtld") + pass + + def tearDown(self): + set_yggtorrent_tld(self.current_yggtorrent_tld) diff --git a/yggcrawl/tests/test_download.py b/yggcrawl/tests/test_download.py new file mode 100644 index 0000000..61861c6 --- /dev/null +++ b/yggcrawl/tests/test_download.py @@ -0,0 +1,65 @@ +import os +import shutil +import unittest + +import requests + +from ..yggtorrentscraper import YggTorrentScraper + + +class TestDownload(unittest.TestCase): + scraper = None + destination_path = None + + def __init__(self, *args, **kwargs): + super(TestDownload, self).__init__(*args, **kwargs) + yggtorrent_identifiant = os.environ.get("YGGTORRENT_IDENTIFIANT") + yggtorrent_password = os.environ.get("YGGTORRENT_PASSWORD") + + self.destination_path = os.path.join( + ".", "yggtorrentscraper", "tests", "test_download" + ) + + self.scraper = YggTorrentScraper(requests.session()) + + self.scraper.login(yggtorrent_identifiant, yggtorrent_password) + + def test_download_from_torrent(self): + most_completed = self.scraper.most_completed() + + torrent = self.scraper.extract_details(most_completed[0]) + + self.assertTrue(torrent.url is not None) + + file_full_path = self.scraper.download_from_torrent( + torrent=torrent, destination_path=self.destination_path + ) + + self.assertTrue(os.path.getsize(file_full_path) > 1000) + + def test_download_from_torrent_url(self): + file_full_path = self.scraper.download_from_torrent_url( + torrent_url="https://www2.yggtorrent.pe/torrent/filmvideo/serie-tv/440445-game-of-thrones-s08e02-multi-1080p-amzn-web-dl-dd5-1-x264-ark01", + destination_path=self.destination_path, + ) + + self.assertTrue(os.path.getsize(file_full_path) > 1000) + + def test_download_from_torrent_download_url(self): + most_completed = self.scraper.most_completed() + + torrent = self.scraper.extract_details(most_completed[0]) + + self.assertTrue(torrent.url is not None) + + file_full_path = self.scraper.download_from_torrent_download_url( + torrent_url=torrent.url, destination_path=self.destination_path + ) + + self.assertTrue(os.path.getsize(file_full_path) > 1000) + + def tearDown(self): + if os.path.exists(self.destination_path): + shutil.rmtree(self.destination_path, ignore_errors=True) + + self.scraper.logout() diff --git a/yggcrawl/tests/test_extract_details.py b/yggcrawl/tests/test_extract_details.py new file mode 100644 index 0000000..4ac644b --- /dev/null +++ b/yggcrawl/tests/test_extract_details.py @@ -0,0 +1,60 @@ +import os +import unittest + +import requests + +from ..yggtorrentscraper import YggTorrentScraper + + +class TestExtractDetails(unittest.TestCase): + scraper = YggTorrentScraper(requests.session()) + + def test_extract_details(self): + torrent = self.scraper.extract_details( + "https://www2.yggtorrent.pe/torrent/filmvideo/serie-tv/440445-game-of-thrones-s08e02-multi-1080p-amzn-web-dl-dd5-1-x264-ark01" + ) + + self.assertTrue(torrent.name is not None) + self.assertTrue(torrent.uploaded_datetime is not None) + self.assertTrue(torrent.size is not None) + self.assertTrue(torrent.uploader is not None) + + self.assertTrue(len(torrent.keywords) > 0) + + self.assertTrue(torrent.completed > -1) + self.assertTrue(torrent.seeders > -1) + self.assertTrue(torrent.leechers > -1) + + self.assertTrue(torrent.url is None) + + self.assertTrue(len(torrent.files) > 0) + self.assertTrue(len(torrent.comments) > 0) + + def test_extract_details_logged(self): + yggtorrent_identifiant = os.environ.get("YGGTORRENT_IDENTIFIANT") + yggtorrent_password = os.environ.get("YGGTORRENT_PASSWORD") + + self.scraper.login(yggtorrent_identifiant, yggtorrent_password) + + torrent = self.scraper.extract_details( + "https://www2.yggtorrent.pe/torrent/filmvideo/serie-tv/440445-game-of-thrones-s08e02-multi-1080p-amzn-web-dl-dd5-1-x264-ark01" + ) + + self.assertTrue(torrent.name is not None) + self.assertTrue(torrent.uploaded_datetime is not None) + self.assertTrue(torrent.size is not None) + self.assertTrue(torrent.uploader is not None) + + self.assertTrue(len(torrent.keywords) > 0) + + self.assertTrue(torrent.completed > -1) + self.assertTrue(torrent.seeders > -1) + self.assertTrue(torrent.leechers > -1) + + self.assertTrue(torrent.url is not None) + + self.assertTrue(len(torrent.files) > 0) + self.assertTrue(len(torrent.comments) > 0) + + def tearDown(self): + self.scraper.logout() diff --git a/yggcrawl/tests/test_login.py b/yggcrawl/tests/test_login.py new file mode 100644 index 0000000..4e5ebd0 --- /dev/null +++ b/yggcrawl/tests/test_login.py @@ -0,0 +1,30 @@ +import os +import unittest + +import requests + +from ..yggtorrentscraper import YggTorrentScraper + + +class TestAuthentification(unittest.TestCase): + def setUp(self): + self.scraper = YggTorrentScraper(requests.session()) + + def test_login_success(self): + yggtorrent_identifiant = os.environ.get("YGGTORRENT_IDENTIFIANT") + yggtorrent_password = os.environ.get("YGGTORRENT_PASSWORD") + + self.assertTrue(yggtorrent_identifiant is not None) + self.assertTrue(yggtorrent_password is not None) + + self.assertTrue(self.scraper.login(yggtorrent_identifiant, yggtorrent_password)) + + self.scraper.logout() + + def test_login_failed(self): + self.assertFalse(self.scraper.login("myidentifiant", "mypassword")) + + self.scraper.logout() + + def tearDown(self): + self.scraper.logout() diff --git a/yggcrawl/tests/test_logout.py b/yggcrawl/tests/test_logout.py new file mode 100644 index 0000000..19607b6 --- /dev/null +++ b/yggcrawl/tests/test_logout.py @@ -0,0 +1,27 @@ +import os +import unittest + +import requests + +from ..yggtorrentscraper import YggTorrentScraper + + +class TestLogout(unittest.TestCase): + def setUp(self): + self.scraper = YggTorrentScraper(requests.session()) + + def test_logout_success(self): + yggtorrent_identifiant = os.environ.get("YGGTORRENT_IDENTIFIANT") + yggtorrent_password = os.environ.get("YGGTORRENT_PASSWORD") + + self.assertTrue(self.scraper.login(yggtorrent_identifiant, yggtorrent_password)) + + self.assertTrue(self.scraper.logout()) + + def test_logout_failed(self): + self.scraper.login("myidentifiant", "mypassword") + + self.assertFalse(self.scraper.logout()) + + def tearDown(self): + self.scraper.logout() diff --git a/yggcrawl/tests/test_most_completed.py b/yggcrawl/tests/test_most_completed.py new file mode 100644 index 0000000..e3652c1 --- /dev/null +++ b/yggcrawl/tests/test_most_completed.py @@ -0,0 +1,16 @@ +import unittest + +import requests +from ..yggtorrentscraper import YggTorrentScraper + + +class TestMostCompleted(unittest.TestCase): + scraper = YggTorrentScraper(session=requests.session()) + + def test_most_completed(self): + most_completed = self.scraper.most_completed() + + self.assertEqual(len(most_completed), 100) + + def tearDown(self): + self.scraper.logout() diff --git a/yggcrawl/tests/test_search.py b/yggcrawl/tests/test_search.py new file mode 100644 index 0000000..8a14845 --- /dev/null +++ b/yggcrawl/tests/test_search.py @@ -0,0 +1,70 @@ +import unittest + +import requests + +from ..yggtorrentscraper import YggTorrentScraper + + +class TestResearch(unittest.TestCase): + scraper = YggTorrentScraper(requests.session()) + + torrent_name = "walking dead s09" + torrent_uploader = "brandit" + + torrent_name_2 = "blue oyster cult" + + def test_search_by_name(self): + torrents_url = self.scraper.search({"name": self.torrent_name}) + + torrent = self.scraper.extract_details(torrents_url[0]) + + splited_searched_name = self.torrent_name.split(" ") + + for word in splited_searched_name: + self.assertTrue(word.lower() in torrent.name.lower()) + + def test_search_by_uploader(self): + torrents_url = self.scraper.search( + {"name": self.torrent_name, "uploader": self.torrent_uploader} + ) + + for torrent_url in torrents_url: + torrent = self.scraper.extract_details(torrent_url) + + self.assertTrue(torrent.uploader.lower() == self.torrent_uploader.lower()) + + def test_search_sort_completed_asc(self): + torrents_url = self.scraper.search( + {"name": "blue oyster cult", "sort": "completed", "order": "asc"} + ) + + torrent_old = None + + for torrent_url in torrents_url: + torrent = self.scraper.extract_details(torrent_url) + + if torrent_old is not None: + self.assertTrue(torrent_old.completed <= torrent.completed) + torrent_old = torrent + + def test_search_sort_completed_desc(self): + torrents_url = self.scraper.search( + {"name": "blue oyster cult", "sort": "completed", "order": "desc"} + ) + + torrent_old = None + + for torrent_url in torrents_url: + torrent = self.scraper.extract_details(torrent_url) + + if torrent_old is not None: + self.assertTrue(torrent_old.completed >= torrent.completed) + torrent_old = torrent + + def test_search_multiple_page(self): + torrents_url = self.scraper.search({"name": "walking dead"}) + + self.assertTrue(len(torrents_url) > 200) + + def tearDown(self): + self.scraper.logout() diff --git a/yggcrawl/tests/test_torrent.py b/yggcrawl/tests/test_torrent.py new file mode 100644 index 0000000..227bcd5 --- /dev/null +++ b/yggcrawl/tests/test_torrent.py @@ -0,0 +1,32 @@ +import os +import unittest + +import requests + +from ..yggtorrentscraper import YggTorrentScraper + + +class TestTorrent(unittest.TestCase): + scraper = YggTorrentScraper(requests.session()) + + def test_str(self): + torrent_url = self.scraper.most_completed()[0] + + torrent = self.scraper.extract_details(torrent_url) + + torrent.__str__(files=True, comments=True) + + def test_str_logged(self): + yggtorrent_identifiant = os.environ.get("YGGTORRENT_IDENTIFIANT") + yggtorrent_password = os.environ.get("YGGTORRENT_PASSWORD") + + self.scraper.login(yggtorrent_identifiant, yggtorrent_password) + + torrent_url = self.scraper.most_completed()[0] + + torrent = self.scraper.extract_details(torrent_url) + + torrent.__str__(files=True, comments=True) + + def tearDown(self): + self.scraper.logout() diff --git a/yggcrawl/torrent.py b/yggcrawl/torrent.py new file mode 100644 index 0000000..a2d2488 --- /dev/null +++ b/yggcrawl/torrent.py @@ -0,0 +1,146 @@ +import os + + +class Torrent: + """ + Torrent entity + """ + + name = None + uploaded_datetime = None + size = None + uploader = None + + keywords = [] + + completed = -1 + seeders = -1 + leechers = -1 + + url = None + + files = [] + comments = [] + + def __str__(self, comments=False, files=False): + to_string = "" + + to_string += "Name : " + to_string += self.name + to_string += os.linesep + + to_string += "Url : " + + if self.url is not None: + to_string += self.url + else: + to_string += "N/A" + + to_string += os.linesep + to_string += os.linesep + + to_string += f"Keywords ({len(self.keywords)}) : " + to_string += os.linesep + + for keyword in self.keywords: + to_string += f"- {keyword}" + to_string += os.linesep + + to_string += os.linesep + + to_string += "Uploaded : " + to_string += str(self.uploaded_datetime) + to_string += os.linesep + + to_string += "Size : " + to_string += str(self.size) + to_string += os.linesep + + to_string += "Uploader : " + to_string += self.uploader + to_string += os.linesep + + to_string += "Completed : " + to_string += str(self.completed) + to_string += os.linesep + + to_string += "Seeders : " + to_string += str(self.seeders) + to_string += os.linesep + + to_string += "Leechers : " + to_string += str(self.leechers) + to_string += os.linesep + + to_string += os.linesep + + to_string += f"Files ({len(self.files)})" + to_string += os.linesep + + if files: + for file in self.files: + to_string += str(file) + to_string += os.linesep + + to_string += os.linesep + + to_string += f"Comments ({len(self.comments)})" + to_string += os.linesep + + if comments: + for comment in self.comments: + to_string += str(comment) + to_string += os.linesep + + return to_string + + +class TorrentFile: + + """ + Torrent's file entity + """ + + size = "" + file_name = "" + + def __str__(self): + to_string = "" + + to_string += "size : " + to_string += self.size + to_string += os.linesep + + to_string += "file_name : " + to_string += self.file_name + to_string += os.linesep + + return to_string + + +class TorrentComment: + + """ + Torrent's comment entity + """ + + author = "" + posted = "" + text = "" + + def __str__(self): + to_string = "" + + to_string += "Author : " + to_string += self.author + to_string += os.linesep + + to_string += "Posted : " + to_string += str(self.posted) + to_string += os.linesep + + to_string += "Text : " + to_string += str(self.text) + to_string += os.linesep + + return to_string diff --git a/yggcrawl/yggtorrentscraper.py b/yggcrawl/yggtorrentscraper.py new file mode 100644 index 0000000..7a7cb3d --- /dev/null +++ b/yggcrawl/yggtorrentscraper.py @@ -0,0 +1,453 @@ +import datetime +import logging +import os +import re + +import requests +from bs4 import BeautifulSoup + +from .torrent import Torrent, TorrentComment, TorrentFile +from .categories import categories + +YGGTORRENT_TLD = "se" + +YGGTORRENT_BASE_URL = f"https://www2.yggtorrent.{YGGTORRENT_TLD}" + +YGGTORRENT_LOGIN_URL = f"{YGGTORRENT_BASE_URL}/user/login" +YGGTORRENT_LOGOUT_URL = f"{YGGTORRENT_BASE_URL}/user/logout?attempt=1" + +YGGTORRENT_SEARCH_URL = f"{YGGTORRENT_BASE_URL}/engine/search?name=" + +logger = logging.getLogger("yggtorrentscraper") + +YGGTORRENT_DOMAIN = f".yggtorrent.{YGGTORRENT_TLD}" +YGGTORRENT_TOKEN_COOKIE = "ygg_" + +YGGTORRENT_SEARCH_URL_DESCRIPTION = "&description=" +YGGTORRENT_SEARCH_URL_FILE = "&file=" +YGGTORRENT_SEARCH_URL_UPLOADER = "&uploader=" +YGGTORRENT_SEARCH_URL_CATEGORY = "&category=" +YGGTORRENT_SEARCH_URL_SUB_CATEGORY = "&sub_category=" +YGGTORRENT_SEARCH_URL_ORDER = "&order=" +YGGTORRENT_SEARCH_URL_SORT = "&sort=" +YGGTORRENT_SEARCH_URL_DO = "&do=" +YGGTORRENT_SEARCH_URL_PAGE = "&page=" + +YGGTORRENT_SEARCH_URL_DESCRIPTION = "&description=" +YGGTORRENT_SEARCH_URL_FILE = "&file=" +YGGTORRENT_SEARCH_URL_UPLOADER = "&uploader=" +YGGTORRENT_SEARCH_URL_CATEGORY = "&category=" +YGGTORRENT_SEARCH_URL_SUB_CATEGORY = "&sub_category=" +YGGTORRENT_SEARCH_URL_ORDER = "&order=" +YGGTORRENT_SEARCH_URL_SORT = "&sort=" +YGGTORRENT_SEARCH_URL_DO = "&do=" +YGGTORRENT_SEARCH_URL_PAGE = "&page=" + +YGGTORRENT_GET_FILES = f"{YGGTORRENT_BASE_URL}/engine/get_files?torrent=" +YGGTORRENT_GET_INFO = f"https://www2.yggtorrentchg/engine/get_nfo?torrent=" + +YGGTORRENT_MOST_COMPLETED_URL = f"{YGGTORRENT_BASE_URL}/engine/mostcompleted" + +TORRENT_PER_PAGE = 50 + +YGGTORRENT_FILES_URL = f"{YGGTORRENT_BASE_URL}/engine/get_files?torrent=" + + +def set_yggtorrent_tld(yggtorrent_tld=None): + """ + Redefine all string variable according to new TLD + """ + + global YGGTORRENT_TLD + global YGGTORRENT_BASE_URL + global YGGTORRENT_LOGIN_URL + global YGGTORRENT_SEARCH_URL + global YGGTORRENT_DOMAIN + global YGGTORRENT_GET_FILES + global YGGTORRENT_GET_INFO + global YGGTORRENT_MOST_COMPLETED_URL + global YGGTORRENT_FILES_URL + + YGGTORRENT_TLD = yggtorrent_tld + + YGGTORRENT_BASE_URL = f"https://www2.yggtorrent.{YGGTORRENT_TLD}" + + YGGTORRENT_LOGIN_URL = f"{YGGTORRENT_BASE_URL}/user/login" + YGGTORRENT_SEARCH_URL = f"{YGGTORRENT_BASE_URL}/user/logout" + + YGGTORRENT_SEARCH_URL = f"{YGGTORRENT_BASE_URL}/engine/search?name=" + + YGGTORRENT_DOMAIN = ".yggtorrent.gg" + + YGGTORRENT_GET_FILES = f"{YGGTORRENT_BASE_URL}/engine/get_files?torrent=" + YGGTORRENT_GET_INFO = f"https://www2.yggtorrentchg/engine/get_nfo?torrent=" + + YGGTORRENT_MOST_COMPLETED_URL = f"{YGGTORRENT_BASE_URL}/engine/mostcompleted" + + YGGTORRENT_FILES_URL = f"{YGGTORRENT_BASE_URL}/engine/get_files?torrent=" + + +def get_yggtorrent_tld(): + return YGGTORRENT_TLD + + +class YggTorrentScraper: + session = None + + def __init__(self, session): + self.session = session + + def login(self, identifiant, password): + """ + Login request with the specified identifiant and password, return an yggtorrent_token, necessary to download + """ + self.session.cookies.clear() + + headers = { + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": "PostmanRuntime/7.17.1", + "Accept": "*/*", + "Cache-Control": "no-cache", + "Host": f"www.yggtorrent.{YGGTORRENT_TLD}", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + } + + response = self.session.post( + YGGTORRENT_LOGIN_URL, + data={"id": identifiant, "pass": password}, + headers=headers, + ) + + logger.debug("status_code : %s", response.status_code) + + yggtorrent_token = None + + if response.status_code == 200: + logger.debug("Login successful") + yggtorrent_token = response.cookies.get_dict()[YGGTORRENT_TOKEN_COOKIE] + + cookie = requests.cookies.create_cookie( + domain=YGGTORRENT_DOMAIN, + name=YGGTORRENT_TOKEN_COOKIE, + value=yggtorrent_token, + ) + + self.session.cookies.set_cookie(cookie) + + return True + else: + logger.debug("Login failed") + + return False + + def logout(self): + """ + Logout request + """ + response = self.session.get(YGGTORRENT_LOGOUT_URL) + + self.session.cookies.clear() + + logger.debug("status_code : %s", response.status_code) + + if response.status_code == 200: + logger.debug("Logout successful") + + return True + else: + logger.debug("Logout failed") + + return False + + def search(self, parameters): + search_url = create_search_url(parameters) + + torrents_url = self.get_torrents_url(search_url, parameters) + + return torrents_url + + def extract_details(self, torrent_url): + """ + Extract informations from torrent's url + """ + logger.debug("torrent_url : %s", torrent_url) + + torrents = [] + + response = self.session.get(torrent_url) + + torrent_page = BeautifulSoup(response.content, features="lxml") + + torrent = Torrent() + + term_tags = torrent_page.find_all("a", {"class": "term"}) + + for term_tag in term_tags: + torrent.keywords.append(term_tag.text) + + connection_tags = torrent_page.find("tr", {"id": "adv_search_cat"}).find_all( + "strong" + ) + + informations_tag = ( + torrent_page.find("table", {"class": "informations"}) + .find("tbody") + .find_all("tr") + ) + + download_button = torrent_page.find("a", {"class": "butt"}) + + if download_button.has_attr("href"): + torrent.url = download_button["href"] + + torrent.seeders = int(connection_tags[0].text.replace(" ", "")) + torrent.leechers = int(connection_tags[1].text.replace(" ", "")) + torrent.completed = int(connection_tags[2].text.replace(" ", "")) + + torrent.name = informations_tag[0].find_all("td")[1].text + torrent.size = informations_tag[3].find_all("td")[1].text + torrent.uploader = informations_tag[5].find_all("td")[1].text + + mydatetime = re.search( + "([0-9]*\/[0-9]*\/[0-9]* [0-9]*:[0-9]*)", + informations_tag[6].find_all("td")[1].text, + 0, + ).group(0) + + torrent.uploaded_datetime = datetime.datetime.strptime( + mydatetime, "%d/%m/%Y %H:%M" + ) + + message_tags = torrent_page.find_all("div", {"class": "message"}) + + for message_tag in message_tags: + torrent_comment = TorrentComment() + + torrent_comment.author = message_tag.find("a").text + torrent_comment.posted = message_tag.find("strong").text + torrent_comment.text = message_tag.find( + "span", {"id": "comment_text"} + ).text.strip() + + torrent.comments.append(torrent_comment) + + torrents.append(torrent) + + torrent_id = torrent_page.find("form", {"id": "report-torrent"}).find( + "input", {"type": "hidden", "name": "target"} + )["value"] + + response = self.session.get(YGGTORRENT_GET_FILES + torrent_id) + + files_page = BeautifulSoup(response.content, features="lxml") + + file_tags = files_page.find_all("tr") + + for file_tag in file_tags: + torrent_file = TorrentFile() + + td_tags = file_tag.find_all("td") + + torrent_file.file_size = ( + td_tags[0] + .text.replace("\\r", "") + .replace("\\n", "") + .replace("\\t", "") + .strip() + ) + torrent_file.file_name = ( + td_tags[1] + .text.replace("\\r", "") + .replace("\\n", "") + .replace("\\t", "") + .replace("\\", "") + .replace(" ", "") + .strip() + ) + + torrent.files.append(torrent_file) + + return torrent + + def most_completed(self): + """ + Return the most completed torrents url (TOP 100) + """ + + header = {"Accept": "application/json, text/javascript, */*; q=0.01"} + self.session.post(YGGTORRENT_MOST_COMPLETED_URL, headers=header) + + json_response = self.session.post( + YGGTORRENT_MOST_COMPLETED_URL, headers=header + ).json() + + torrents_url = [] + + for json_item in json_response: + root = BeautifulSoup(json_item[1], features="lxml") + + a_tag = root.find("a") + + torrents_url.append(a_tag["href"]) + + return torrents_url + + def get_torrents_url(self, search_url, parameters): + """ + Return + """ + + response = self.session.get(search_url) + + search_page = BeautifulSoup(response.content, features="lxml") + + pagination = search_page.find("ul", {"class": "pagination"}) + + if pagination is None: + limit_page = 1 + else: + pagination_item = pagination.find_all("a") + + limit_page = int(pagination_item[-1]["data-ci-pagination-page"]) + + torrents = [] + + for page in range(0, limit_page): + parameters["page"] = page * TORRENT_PER_PAGE + + search_url = create_search_url(parameters) + + response = self.session.get(search_url) + + search_page = BeautifulSoup(response.content, features="lxml") + + torrents_tag = search_page.findAll("a", {"id": "torrent_name"}) + + for torrent_tag in torrents_tag: + torrents.append(torrent_tag["href"]) + + return torrents + +#kopa + def download_from_torrent_url(self, torrent_url=None, destination_path="./data/files/"): + if torrent_url is not None: + torrent = self.extract_details(torrent_url) + + return self.download_from_torrent_download_url( + torrent_url=torrent.url, destination_path=destination_path + ) + + def download_from_torrent(self, torrent=None, destination_path="./data/files/"): + if torrent is not None: + return self.download_from_torrent_download_url( + torrent_url=torrent.url, destination_path=destination_path + ) + + def download_from_torrent_download_url( + self, torrent_url=None, destination_path="./data/files/" + ): + if torrent_url is None: + raise Exception("Invalid torrent_url, make sure you are logged") + + response = self.session.get(YGGTORRENT_BASE_URL + torrent_url) + + temp_file_name = response.headers.get("content-disposition") + + file_name = temp_file_name[temp_file_name.index("filename=") + 10 : -1] + + if not os.path.exists(destination_path): + os.makedirs(destination_path) + + file_full_path = os.path.join(destination_path, file_name) + + file = open(file_full_path, "wb") + + file.write(response.content) + + file.close() + + return file_full_path + + +def create_search_url(parameters): + """ + Return a formated URL for torrent's search + """ + + formated_search_url = YGGTORRENT_SEARCH_URL + + if "name" in parameters: + formated_search_url += parameters["name"].replace(" ", "+") + + if "page" in parameters: + formated_search_url += YGGTORRENT_SEARCH_URL_PAGE + formated_search_url += str(parameters["page"]) + + if "descriptions" in parameters: + formated_search_url += YGGTORRENT_SEARCH_URL_DESCRIPTION + + for description in parameters["descriptions"]: + formated_search_url += description + formated_search_url += "+" + + if "files" in parameters: + formated_search_url += YGGTORRENT_SEARCH_URL_FILE + + for file in parameters["files"]: + formated_search_url += file + formated_search_url += "+" + + if "uploader" in parameters: + formated_search_url += YGGTORRENT_SEARCH_URL_UPLOADER + formated_search_url += parameters["uploader"] + + if "sort" in parameters: + formated_search_url += YGGTORRENT_SEARCH_URL_SORT + formated_search_url += parameters["sort"] + + if "order" in parameters: + formated_search_url += YGGTORRENT_SEARCH_URL_ORDER + formated_search_url += parameters["order"] + + if "category" in parameters: + for category in categories: + if parameters["category"] == category["name"]: + formated_search_url += YGGTORRENT_SEARCH_URL_CATEGORY + formated_search_url += category["id"] + + if "subcategory" in parameters: + for subcategory in category["subcategories"]: + if parameters["subcategory"] == subcategory["name"]: + formated_search_url += YGGTORRENT_SEARCH_URL_SUB_CATEGORY + formated_search_url += subcategory["id"] + if "options" in parameters: + for key, values in parameters["options"].items(): + for option in subcategory["options"]: + if key == option["name"]: + for searched_value in values: + for index, value in enumerate( + option["values"] + ): + if searched_value == value: + formated_search_url += ( + "&option_" + ) + formated_search_url += option[ + "name" + ] + # options_index.append(index) + if "multiple" in option: + formated_search_url += ( + "%3Amultiple" + ) + + formated_search_url += "[]=" + formated_search_url += str( + index + 1 + ) + + formated_search_url += YGGTORRENT_SEARCH_URL_DO + formated_search_url += "search" + + return formated_search_url