summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorGravatar lazlev <lazlev@yopmail.com> 2015-08-09 00:50:54 +0200
committerGravatar lazlev <lazlev@yopmail.com> 2015-08-09 00:50:54 +0200
commitb0ef3f1673e1930916604bb1264ca3a38414bc8d (patch)
treec97936e4d2a4cd6eb1072c65c8a08a7d18816b18 /module
parent[XFileSharingPro][XFileSharingProFolder] Added default __pattern__ (diff)
parentFix https://github.com/pyload/pyload/issues/1707 (diff)
downloadpyload-b0ef3f1673e1930916604bb1264ca3a38414bc8d.tar.xz
Merge pull request #1 from pyload/stable
sync with stable
Diffstat (limited to 'module')
-rw-r--r--module/plugins/Account.py292
-rw-r--r--module/plugins/AccountManager.py8
-rw-r--r--module/plugins/Container.py75
-rw-r--r--module/plugins/Crypter.py72
-rw-r--r--module/plugins/Hook.py161
-rw-r--r--module/plugins/Hoster.py33
-rw-r--r--module/plugins/accounts/AlldebridCom.py49
-rw-r--r--module/plugins/accounts/AniStreamCom.py17
-rw-r--r--module/plugins/accounts/BackinNet.py3
-rw-r--r--module/plugins/accounts/BitshareCom.py26
-rw-r--r--module/plugins/accounts/CatShareNet.py30
-rw-r--r--module/plugins/accounts/CloudsixMe.py17
-rw-r--r--module/plugins/accounts/CloudzillaTo.py22
-rw-r--r--module/plugins/accounts/CramitIn.py3
-rw-r--r--module/plugins/accounts/CzshareCom.py26
-rw-r--r--module/plugins/accounts/DebridItaliaCom.py25
-rw-r--r--module/plugins/accounts/DepositfilesCom.py22
-rw-r--r--module/plugins/accounts/EasybytezCom.py3
-rw-r--r--module/plugins/accounts/EuroshareEu.py27
-rw-r--r--module/plugins/accounts/ExashareCom.py3
-rw-r--r--module/plugins/accounts/FastixRu.py27
-rw-r--r--module/plugins/accounts/FastshareCz.py26
-rw-r--r--module/plugins/accounts/File4SafeCom.py3
-rw-r--r--module/plugins/accounts/FileParadoxIn.py3
-rw-r--r--module/plugins/accounts/FilecloudIo.py49
-rw-r--r--module/plugins/accounts/FilefactoryCom.py23
-rw-r--r--module/plugins/accounts/FilejungleCom.py31
-rw-r--r--module/plugins/accounts/FileomCom.py3
-rw-r--r--module/plugins/accounts/FilerNet.py42
-rw-r--r--module/plugins/accounts/FilerioCom.py3
-rw-r--r--module/plugins/accounts/FilesMailRu.py24
-rw-r--r--module/plugins/accounts/FileserveCom.py41
-rw-r--r--module/plugins/accounts/FourSharedCom.py31
-rw-r--r--module/plugins/accounts/FreakshareCom.py26
-rw-r--r--module/plugins/accounts/FreeWayMe.py39
-rw-r--r--module/plugins/accounts/FshareVn.py39
-rw-r--r--module/plugins/accounts/Ftp.py5
-rw-r--r--module/plugins/accounts/HellshareCz.py51
-rw-r--r--module/plugins/accounts/HighWayMe.py50
-rw-r--r--module/plugins/accounts/Http.py5
-rw-r--r--module/plugins/accounts/HugefilesNet.py3
-rw-r--r--module/plugins/accounts/HundredEightyUploadCom.py3
-rw-r--r--module/plugins/accounts/JunkyvideoCom.py3
-rw-r--r--module/plugins/accounts/JunocloudMe.py3
-rw-r--r--module/plugins/accounts/Keep2ShareCc.py35
-rw-r--r--module/plugins/accounts/LetitbitNet.py27
-rw-r--r--module/plugins/accounts/LinestorageCom.py3
-rw-r--r--module/plugins/accounts/LinksnappyCom.py47
-rw-r--r--module/plugins/accounts/MegaDebridEu.py35
-rw-r--r--module/plugins/accounts/MegaRapidCz.py33
-rw-r--r--module/plugins/accounts/MegaRapidoNet.py27
-rw-r--r--module/plugins/accounts/MegasharesCom.py32
-rw-r--r--module/plugins/accounts/MovReelCom.py3
-rw-r--r--module/plugins/accounts/MultihostersCom.py3
-rw-r--r--module/plugins/accounts/MultishareCz.py30
-rw-r--r--module/plugins/accounts/MyfastfileCom.py26
-rw-r--r--module/plugins/accounts/NitroflareCom.py82
-rw-r--r--module/plugins/accounts/NoPremiumPl.py80
-rw-r--r--module/plugins/accounts/NosuploadCom.py3
-rw-r--r--module/plugins/accounts/NovafileCom.py3
-rw-r--r--module/plugins/accounts/NowVideoSx.py25
-rw-r--r--module/plugins/accounts/OboomCom.py29
-rw-r--r--module/plugins/accounts/OneFichierCom.py30
-rw-r--r--module/plugins/accounts/OverLoadMe.py31
-rw-r--r--module/plugins/accounts/PremiumTo.py24
-rw-r--r--module/plugins/accounts/PremiumizeMe.py44
-rw-r--r--module/plugins/accounts/PutdriveCom.py3
-rw-r--r--module/plugins/accounts/QuickshareCz.py26
-rw-r--r--module/plugins/accounts/RPNetBiz.py45
-rw-r--r--module/plugins/accounts/RapideoPl.py81
-rw-r--r--module/plugins/accounts/RapidfileshareNet.py3
-rw-r--r--module/plugins/accounts/RapidgatorNet.py36
-rw-r--r--module/plugins/accounts/RapiduNet.py37
-rw-r--r--module/plugins/accounts/RarefileNet.py3
-rw-r--r--module/plugins/accounts/RealdebridCom.py35
-rw-r--r--module/plugins/accounts/RehostTo.py36
-rw-r--r--module/plugins/accounts/RyushareCom.py3
-rw-r--r--module/plugins/accounts/SafesharingEu.py3
-rw-r--r--module/plugins/accounts/SecureUploadEu.py3
-rw-r--r--module/plugins/accounts/SendmywayCom.py3
-rw-r--r--module/plugins/accounts/SharebeastCom.py17
-rw-r--r--module/plugins/accounts/ShareonlineBiz.py63
-rw-r--r--module/plugins/accounts/SimplyPremiumCom.py25
-rw-r--r--module/plugins/accounts/SimplydebridCom.py30
-rw-r--r--module/plugins/accounts/SmoozedCom.py42
-rw-r--r--module/plugins/accounts/StahnuTo.py35
-rw-r--r--module/plugins/accounts/StreamcloudEu.py3
-rw-r--r--module/plugins/accounts/TurbobitNet.py27
-rw-r--r--module/plugins/accounts/TusfilesNet.py5
-rw-r--r--module/plugins/accounts/UlozTo.py30
-rw-r--r--module/plugins/accounts/UploadableCh.py24
-rw-r--r--module/plugins/accounts/UploadcCom.py3
-rw-r--r--module/plugins/accounts/UploadedTo.py32
-rw-r--r--module/plugins/accounts/UploadheroCom.py25
-rw-r--r--module/plugins/accounts/UploadingCom.py25
-rw-r--r--module/plugins/accounts/UptoboxCom.py3
-rw-r--r--module/plugins/accounts/VidPlayNet.py3
-rw-r--r--module/plugins/accounts/WebshareCz.py48
-rw-r--r--module/plugins/accounts/WorldbytezCom.py17
-rw-r--r--module/plugins/accounts/XFileSharingPro.py24
-rw-r--r--module/plugins/accounts/YibaishiwuCom.py28
-rw-r--r--module/plugins/accounts/ZeveraCom.py24
-rw-r--r--module/plugins/captcha/AdYouLike.py (renamed from module/plugins/internal/AdYouLike.py)49
-rw-r--r--module/plugins/captcha/AdsCaptcha.py (renamed from module/plugins/internal/AdsCaptcha.py)35
-rw-r--r--module/plugins/captcha/CircleCaptcha.py707
-rw-r--r--module/plugins/captcha/GigasizeCom.py11
-rw-r--r--module/plugins/captcha/LinksaveIn.py29
-rw-r--r--module/plugins/captcha/NetloadIn.py11
-rw-r--r--module/plugins/captcha/ReCaptcha.py (renamed from module/plugins/internal/ReCaptcha.py)110
-rw-r--r--module/plugins/captcha/ShareonlineBiz.py17
-rw-r--r--module/plugins/captcha/SolveMedia.py (renamed from module/plugins/internal/SolveMedia.py)47
-rw-r--r--module/plugins/container/CCF.py11
-rw-r--r--module/plugins/container/DLC.py17
-rw-r--r--module/plugins/container/RSDF.py5
-rw-r--r--module/plugins/container/TXT.py19
-rw-r--r--module/plugins/crypter/BitshareComFolder.py5
-rw-r--r--module/plugins/crypter/C1NeonCom.py3
-rw-r--r--module/plugins/crypter/ChipDe.py7
-rw-r--r--module/plugins/crypter/CloudzillaToFolder.py7
-rw-r--r--module/plugins/crypter/CrockoComFolder.py3
-rw-r--r--module/plugins/crypter/CryptItCom.py3
-rw-r--r--module/plugins/crypter/CzshareComFolder.py5
-rw-r--r--module/plugins/crypter/DailymotionComFolder.py65
-rw-r--r--module/plugins/crypter/DataHuFolder.py15
-rw-r--r--module/plugins/crypter/DdlstorageComFolder.py3
-rw-r--r--module/plugins/crypter/DepositfilesComFolder.py3
-rw-r--r--module/plugins/crypter/Dereferer.py25
-rw-r--r--module/plugins/crypter/DevhostStFolder.py17
-rw-r--r--module/plugins/crypter/DlProtectCom.py20
-rw-r--r--module/plugins/crypter/DuckCryptInfo.py27
-rw-r--r--module/plugins/crypter/DuploadOrgFolder.py3
-rw-r--r--module/plugins/crypter/EasybytezComFolder.py3
-rw-r--r--module/plugins/crypter/EmbeduploadCom.py21
-rw-r--r--module/plugins/crypter/FilebeerInfoFolder.py3
-rw-r--r--module/plugins/crypter/FilecloudIoFolder.py3
-rw-r--r--module/plugins/crypter/FilecryptCc.py103
-rw-r--r--module/plugins/crypter/FilefactoryComFolder.py5
-rw-r--r--module/plugins/crypter/FilerNetFolder.py3
-rw-r--r--module/plugins/crypter/FileserveComFolder.py5
-rw-r--r--module/plugins/crypter/FilesonicComFolder.py3
-rw-r--r--module/plugins/crypter/FilestubeCom.py5
-rw-r--r--module/plugins/crypter/FiletramCom.py3
-rw-r--r--module/plugins/crypter/FiredriveComFolder.py3
-rw-r--r--module/plugins/crypter/FourChanOrg.py5
-rw-r--r--module/plugins/crypter/FreakhareComFolder.py7
-rw-r--r--module/plugins/crypter/FreetexthostCom.py5
-rw-r--r--module/plugins/crypter/FshareVnFolder.py3
-rw-r--r--module/plugins/crypter/FurLy.py25
-rw-r--r--module/plugins/crypter/Go4UpCom.py5
-rw-r--r--module/plugins/crypter/GooGl.py13
-rw-r--r--module/plugins/crypter/GoogledriveComFolder.py5
-rw-r--r--module/plugins/crypter/HoerbuchIn.py21
-rw-r--r--module/plugins/crypter/HotfileComFolder.py3
-rw-r--r--module/plugins/crypter/ILoadTo.py3
-rw-r--r--module/plugins/crypter/ImgurComAlbum.py5
-rw-r--r--module/plugins/crypter/LetitbitNetFolder.py5
-rw-r--r--module/plugins/crypter/LinkCryptWs.py159
-rw-r--r--module/plugins/crypter/LinkSaveIn.py7
-rw-r--r--module/plugins/crypter/LinkdecrypterCom.py25
-rw-r--r--module/plugins/crypter/LixIn.py23
-rw-r--r--module/plugins/crypter/LofCc.py3
-rw-r--r--module/plugins/crypter/MBLinkInfo.py3
-rw-r--r--module/plugins/crypter/MediafireComFolder.py17
-rw-r--r--module/plugins/crypter/MegaCoNzFolder.py12
-rw-r--r--module/plugins/crypter/MegaRapidCzFolder.py3
-rw-r--r--module/plugins/crypter/MegauploadComFolder.py3
-rw-r--r--module/plugins/crypter/Movie2KTo.py3
-rw-r--r--module/plugins/crypter/MultiUpOrg.py5
-rw-r--r--module/plugins/crypter/MultiloadCz.py11
-rw-r--r--module/plugins/crypter/MultiuploadCom.py5
-rw-r--r--module/plugins/crypter/NCryptIn.py203
-rw-r--r--module/plugins/crypter/NetfolderIn.py3
-rw-r--r--module/plugins/crypter/NitroflareComFolder.py36
-rw-r--r--module/plugins/crypter/NosvideoCom.py3
-rw-r--r--module/plugins/crypter/OneKhDe.py13
-rw-r--r--module/plugins/crypter/OronComFolder.py3
-rw-r--r--module/plugins/crypter/PastebinCom.py11
-rw-r--r--module/plugins/crypter/PastedCo.py44
-rw-r--r--module/plugins/crypter/QuickshareCzFolder.py5
-rw-r--r--module/plugins/crypter/RSLayerCom.py3
-rw-r--r--module/plugins/crypter/RelinkUs.py172
-rw-r--r--module/plugins/crypter/SafelinkingNet.py13
-rw-r--r--module/plugins/crypter/SecuredIn.py3
-rw-r--r--module/plugins/crypter/SexuriaCom.py75
-rw-r--r--module/plugins/crypter/ShSt.py31
-rw-r--r--module/plugins/crypter/ShareLinksBiz.py203
-rw-r--r--module/plugins/crypter/SharingmatrixComFolder.py3
-rw-r--r--module/plugins/crypter/SpeedLoadOrgFolder.py3
-rw-r--r--module/plugins/crypter/StealthTo.py3
-rw-r--r--module/plugins/crypter/TNTVillageScambioeticoOrg.py32
-rw-r--r--module/plugins/crypter/TinyurlCom.py7
-rw-r--r--module/plugins/crypter/TnyCz.py13
-rw-r--r--module/plugins/crypter/TrailerzoneInfo.py3
-rw-r--r--module/plugins/crypter/TurbobitNetFolder.py15
-rw-r--r--module/plugins/crypter/TusfilesNetFolder.py13
-rw-r--r--module/plugins/crypter/UlozToFolder.py9
-rw-r--r--module/plugins/crypter/UploadableChFolder.py5
-rw-r--r--module/plugins/crypter/UploadedToFolder.py22
-rw-r--r--module/plugins/crypter/WiiReloadedOrg.py3
-rw-r--r--module/plugins/crypter/WuploadComFolder.py3
-rw-r--r--module/plugins/crypter/XFileSharingProFolder.py57
-rw-r--r--module/plugins/crypter/XupPl.py5
-rw-r--r--module/plugins/crypter/YoutubeComFolder.py87
-rw-r--r--module/plugins/hooks/AlldebridComHook.py20
-rw-r--r--module/plugins/hooks/AndroidPhoneNotify.py52
-rw-r--r--module/plugins/hooks/AntiStandby.py175
-rw-r--r--module/plugins/hooks/AntiVirus.py63
-rw-r--r--module/plugins/hooks/BypassCaptcha.py71
-rw-r--r--module/plugins/hooks/Captcha9Kw.py127
-rw-r--r--module/plugins/hooks/CaptchaBrotherhood.py66
-rw-r--r--module/plugins/hooks/Checksum.py105
-rw-r--r--module/plugins/hooks/ClickAndLoad.py44
-rw-r--r--module/plugins/hooks/DeathByCaptcha.py87
-rw-r--r--module/plugins/hooks/DebridItaliaComHook.py16
-rw-r--r--module/plugins/hooks/DeleteFinished.py54
-rw-r--r--module/plugins/hooks/DownloadScheduler.py64
-rw-r--r--module/plugins/hooks/EasybytezComHook.py20
-rw-r--r--module/plugins/hooks/ExpertDecoders.py64
-rw-r--r--module/plugins/hooks/ExternalScripts.py205
-rw-r--r--module/plugins/hooks/ExtractArchive.py321
-rw-r--r--module/plugins/hooks/FastixRuHook.py16
-rw-r--r--module/plugins/hooks/FreeWayMeHook.py28
-rw-r--r--module/plugins/hooks/HighWayMeHook.py26
-rw-r--r--module/plugins/hooks/HotFolder.py30
-rw-r--r--module/plugins/hooks/IRCInterface.py137
-rw-r--r--module/plugins/hooks/ImageTyperz.py78
-rw-r--r--module/plugins/hooks/JustPremium.py33
-rw-r--r--module/plugins/hooks/LinkdecrypterComHook.py7
-rw-r--r--module/plugins/hooks/LinksnappyComHook.py16
-rw-r--r--module/plugins/hooks/MegaDebridEuHook.py20
-rw-r--r--module/plugins/hooks/MegaRapidoNetHook.py17
-rw-r--r--module/plugins/hooks/MergeFiles.py41
-rw-r--r--module/plugins/hooks/MultiHome.py43
-rw-r--r--module/plugins/hooks/MultihostersComHook.py11
-rw-r--r--module/plugins/hooks/MultishareCzHook.py16
-rw-r--r--module/plugins/hooks/MyfastfileComHook.py18
-rw-r--r--module/plugins/hooks/NoPremiumPlHook.py20
-rw-r--r--module/plugins/hooks/OverLoadMeHook.py22
-rw-r--r--module/plugins/hooks/PremiumToHook.py20
-rw-r--r--module/plugins/hooks/PremiumizeMeHook.py32
-rw-r--r--module/plugins/hooks/PutdriveComHook.py11
-rw-r--r--module/plugins/hooks/RPNetBizHook.py28
-rw-r--r--module/plugins/hooks/RapideoPlHook.py20
-rw-r--r--module/plugins/hooks/RealdebridComHook.py19
-rw-r--r--module/plugins/hooks/RehostToHook.py20
-rw-r--r--module/plugins/hooks/RestartFailed.py32
-rw-r--r--module/plugins/hooks/SimplyPremiumComHook.py16
-rw-r--r--module/plugins/hooks/SimplydebridComHook.py16
-rw-r--r--module/plugins/hooks/SkipRev.py58
-rw-r--r--module/plugins/hooks/SmoozedComHook.py18
-rw-r--r--module/plugins/hooks/UnSkipOnFail.py65
-rw-r--r--module/plugins/hooks/UpdateManager.py201
-rw-r--r--module/plugins/hooks/UserAgentSwitcher.py32
-rw-r--r--module/plugins/hooks/WindowsPhoneNotify.py53
-rw-r--r--module/plugins/hooks/XFileSharingPro.py74
-rw-r--r--module/plugins/hooks/XMPPInterface.py126
-rw-r--r--module/plugins/hooks/ZeveraComHook.py14
-rw-r--r--module/plugins/hoster/AlldebridCom.py27
-rw-r--r--module/plugins/hoster/AndroidfilehostCom.py21
-rw-r--r--module/plugins/hoster/BasePlugin.py42
-rw-r--r--module/plugins/hoster/BasketbuildCom.py17
-rw-r--r--module/plugins/hoster/BayfilesCom.py3
-rw-r--r--module/plugins/hoster/BezvadataCz.py46
-rw-r--r--module/plugins/hoster/BillionuploadsCom.py3
-rw-r--r--module/plugins/hoster/BitshareCom.py87
-rw-r--r--module/plugins/hoster/BoltsharingCom.py3
-rw-r--r--module/plugins/hoster/CatShareNet.py11
-rw-r--r--module/plugins/hoster/CloudzerNet.py3
-rw-r--r--module/plugins/hoster/CloudzillaTo.py19
-rw-r--r--module/plugins/hoster/CramitIn.py3
-rw-r--r--module/plugins/hoster/CrockoCom.py11
-rw-r--r--module/plugins/hoster/CyberlockerCh.py3
-rw-r--r--module/plugins/hoster/CzshareCom.py85
-rw-r--r--module/plugins/hoster/DailymotionCom.py41
-rw-r--r--module/plugins/hoster/DataHu.py5
-rw-r--r--module/plugins/hoster/DataportCz.py19
-rw-r--r--module/plugins/hoster/DateiTo.py19
-rw-r--r--module/plugins/hoster/DdlstorageCom.py3
-rw-r--r--module/plugins/hoster/DebridItaliaCom.py12
-rw-r--r--module/plugins/hoster/DepositfilesCom.py17
-rw-r--r--module/plugins/hoster/DevhostSt.py7
-rw-r--r--module/plugins/hoster/DlFreeFr.py50
-rw-r--r--module/plugins/hoster/DodanePl.py3
-rw-r--r--module/plugins/hoster/DropboxCom.py9
-rw-r--r--module/plugins/hoster/DuploadOrg.py3
-rw-r--r--module/plugins/hoster/EasybytezCom.py3
-rw-r--r--module/plugins/hoster/EdiskCz.py11
-rw-r--r--module/plugins/hoster/EgoFilesCom.py3
-rw-r--r--module/plugins/hoster/EnteruploadCom.py3
-rw-r--r--module/plugins/hoster/EpicShareNet.py3
-rw-r--r--module/plugins/hoster/EuroshareEu.py32
-rw-r--r--module/plugins/hoster/ExashareCom.py9
-rw-r--r--module/plugins/hoster/ExtabitCom.py21
-rw-r--r--module/plugins/hoster/FastixRu.py14
-rw-r--r--module/plugins/hoster/FastshareCz.py21
-rw-r--r--module/plugins/hoster/FileApeCom.py3
-rw-r--r--module/plugins/hoster/FileSharkPl.py30
-rw-r--r--module/plugins/hoster/FileStoreTo.py7
-rw-r--r--module/plugins/hoster/FilebeerInfo.py3
-rw-r--r--module/plugins/hoster/FileboomMe.py17
-rw-r--r--module/plugins/hoster/FilecloudIo.py43
-rw-r--r--module/plugins/hoster/FiledropperCom.py47
-rw-r--r--module/plugins/hoster/FilefactoryCom.py27
-rw-r--r--module/plugins/hoster/FilejungleCom.py11
-rw-r--r--module/plugins/hoster/FileomCom.py7
-rw-r--r--module/plugins/hoster/FilepostCom.py45
-rw-r--r--module/plugins/hoster/FilepupNet.py7
-rw-r--r--module/plugins/hoster/FilerNet.py17
-rw-r--r--module/plugins/hoster/FilerioCom.py3
-rw-r--r--module/plugins/hoster/FilesMailRu.py76
-rw-r--r--module/plugins/hoster/FileserveCom.py144
-rw-r--r--module/plugins/hoster/FileshareInUa.py3
-rw-r--r--module/plugins/hoster/FilesonicCom.py3
-rw-r--r--module/plugins/hoster/FileuploadNet.py33
-rw-r--r--module/plugins/hoster/FilezyNet.py3
-rw-r--r--module/plugins/hoster/FiredriveCom.py3
-rw-r--r--module/plugins/hoster/FlyFilesNet.py14
-rw-r--r--module/plugins/hoster/FourSharedCom.py7
-rw-r--r--module/plugins/hoster/FreakshareCom.py46
-rw-r--r--module/plugins/hoster/FreeWayMe.py32
-rw-r--r--module/plugins/hoster/FreevideoCz.py3
-rw-r--r--module/plugins/hoster/FshareVn.py50
-rw-r--r--module/plugins/hoster/Ftp.py27
-rw-r--r--module/plugins/hoster/GamefrontCom.py87
-rw-r--r--module/plugins/hoster/GigapetaCom.py17
-rw-r--r--module/plugins/hoster/GooIm.py7
-rw-r--r--module/plugins/hoster/GoogledriveCom.py15
-rw-r--r--module/plugins/hoster/HellshareCz.py7
-rw-r--r--module/plugins/hoster/HellspyCz.py3
-rw-r--r--module/plugins/hoster/HighWayMe.py78
-rw-r--r--module/plugins/hoster/HostujeNet.py9
-rw-r--r--module/plugins/hoster/HotfileCom.py3
-rw-r--r--module/plugins/hoster/HugefilesNet.py3
-rw-r--r--module/plugins/hoster/HundredEightyUploadCom.py3
-rw-r--r--module/plugins/hoster/IFileWs.py3
-rw-r--r--module/plugins/hoster/IcyFilesCom.py3
-rw-r--r--module/plugins/hoster/IfileIt.py5
-rw-r--r--module/plugins/hoster/IfolderRu.py23
-rw-r--r--module/plugins/hoster/JumbofilesCom.py11
-rw-r--r--module/plugins/hoster/JunocloudMe.py3
-rw-r--r--module/plugins/hoster/Keep2ShareCc.py35
-rw-r--r--module/plugins/hoster/KickloadCom.py3
-rw-r--r--module/plugins/hoster/KingfilesNet.py19
-rw-r--r--module/plugins/hoster/LemUploadsCom.py3
-rw-r--r--module/plugins/hoster/LetitbitNet.py61
-rw-r--r--module/plugins/hoster/LinksnappyCom.py22
-rw-r--r--module/plugins/hoster/LoadTo.py19
-rw-r--r--module/plugins/hoster/LolabitsEs.py18
-rw-r--r--module/plugins/hoster/LomafileCom.py3
-rw-r--r--module/plugins/hoster/LuckyShareNet.py36
-rw-r--r--module/plugins/hoster/MediafireCom.py27
-rw-r--r--module/plugins/hoster/MegaCoNz.py75
-rw-r--r--module/plugins/hoster/MegaDebridEu.py14
-rw-r--r--module/plugins/hoster/MegaFilesSe.py3
-rw-r--r--module/plugins/hoster/MegaRapidCz.py19
-rw-r--r--module/plugins/hoster/MegaRapidoNet.py16
-rw-r--r--module/plugins/hoster/MegacrypterCom.py25
-rw-r--r--module/plugins/hoster/MegareleaseOrg.py3
-rw-r--r--module/plugins/hoster/MegasharesCom.py35
-rw-r--r--module/plugins/hoster/MegauploadCom.py3
-rw-r--r--module/plugins/hoster/MegavideoCom.py3
-rw-r--r--module/plugins/hoster/MovReelCom.py3
-rw-r--r--module/plugins/hoster/MultihostersCom.py3
-rw-r--r--module/plugins/hoster/MultishareCz.py17
-rw-r--r--module/plugins/hoster/MyfastfileCom.py14
-rw-r--r--module/plugins/hoster/MystoreTo.py9
-rw-r--r--module/plugins/hoster/MyvideoDe.py9
-rw-r--r--module/plugins/hoster/NahrajCz.py3
-rw-r--r--module/plugins/hoster/NarodRu.py15
-rw-r--r--module/plugins/hoster/NetloadIn.py3
-rw-r--r--module/plugins/hoster/NitroflareCom.py31
-rw-r--r--module/plugins/hoster/NoPremiumPl.py58
-rw-r--r--module/plugins/hoster/NosuploadCom.py21
-rw-r--r--module/plugins/hoster/NovafileCom.py3
-rw-r--r--module/plugins/hoster/NowDownloadSx.py13
-rw-r--r--module/plugins/hoster/NowVideoSx.py7
-rw-r--r--module/plugins/hoster/OboomCom.py116
-rw-r--r--module/plugins/hoster/OneFichierCom.py14
-rw-r--r--module/plugins/hoster/OpenloadIo.py17
-rw-r--r--module/plugins/hoster/OronCom.py3
-rw-r--r--module/plugins/hoster/OverLoadMe.py29
-rw-r--r--module/plugins/hoster/PandaplaNet.py3
-rw-r--r--module/plugins/hoster/PornhostCom.py15
-rw-r--r--module/plugins/hoster/PornhubCom.py13
-rw-r--r--module/plugins/hoster/PotloadCom.py3
-rw-r--r--module/plugins/hoster/PremiumTo.py24
-rw-r--r--module/plugins/hoster/PremiumizeMe.py32
-rw-r--r--module/plugins/hoster/PromptfileCom.py25
-rw-r--r--module/plugins/hoster/PrzeklejPl.py3
-rw-r--r--module/plugins/hoster/PutdriveCom.py3
-rw-r--r--module/plugins/hoster/QuickshareCz.py41
-rw-r--r--module/plugins/hoster/RPNetBiz.py60
-rw-r--r--module/plugins/hoster/RapideoPl.py58
-rw-r--r--module/plugins/hoster/RapidfileshareNet.py3
-rw-r--r--module/plugins/hoster/RapidgatorNet.py45
-rw-r--r--module/plugins/hoster/RapiduNet.py29
-rw-r--r--module/plugins/hoster/RarefileNet.py3
-rw-r--r--module/plugins/hoster/RealdebridCom.py27
-rw-r--r--module/plugins/hoster/RedtubeCom.py17
-rw-r--r--module/plugins/hoster/RehostTo.py10
-rw-r--r--module/plugins/hoster/RemixshareCom.py7
-rw-r--r--module/plugins/hoster/RgHostNet.py3
-rw-r--r--module/plugins/hoster/SafesharingEu.py3
-rw-r--r--module/plugins/hoster/SecureUploadEu.py3
-rw-r--r--module/plugins/hoster/SendspaceCom.py13
-rw-r--r--module/plugins/hoster/Share4WebCom.py3
-rw-r--r--module/plugins/hoster/Share76Com.py3
-rw-r--r--module/plugins/hoster/ShareFilesCo.py3
-rw-r--r--module/plugins/hoster/SharebeesCom.py3
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py95
-rw-r--r--module/plugins/hoster/ShareplaceCom.py21
-rw-r--r--module/plugins/hoster/SharingmatrixCom.py3
-rw-r--r--module/plugins/hoster/ShragleCom.py3
-rw-r--r--module/plugins/hoster/SimplyPremiumCom.py28
-rw-r--r--module/plugins/hoster/SimplydebridCom.py16
-rw-r--r--module/plugins/hoster/SizedriveCom.py9
-rw-r--r--module/plugins/hoster/SmoozedCom.py52
-rw-r--r--module/plugins/hoster/SockshareCom.py3
-rw-r--r--module/plugins/hoster/SolidfilesCom.py7
-rw-r--r--module/plugins/hoster/SoundcloudCom.py13
-rw-r--r--module/plugins/hoster/SpeedLoadOrg.py3
-rw-r--r--module/plugins/hoster/SpeedfileCz.py3
-rw-r--r--module/plugins/hoster/SpeedyshareCom.py7
-rw-r--r--module/plugins/hoster/StorageTo.py3
-rw-r--r--module/plugins/hoster/StreamCz.py21
-rw-r--r--module/plugins/hoster/StreamcloudEu.py7
-rw-r--r--module/plugins/hoster/TurbobitNet.py73
-rw-r--r--module/plugins/hoster/TurbouploadCom.py3
-rw-r--r--module/plugins/hoster/TusfilesNet.py15
-rw-r--r--module/plugins/hoster/TwoSharedCom.py5
-rw-r--r--module/plugins/hoster/UlozTo.py76
-rw-r--r--module/plugins/hoster/UloziskoSk.py25
-rw-r--r--module/plugins/hoster/UnibytesCom.py21
-rw-r--r--module/plugins/hoster/UnrestrictLi.py3
-rw-r--r--module/plugins/hoster/UpleaCom.py13
-rw-r--r--module/plugins/hoster/UploadStationCom.py3
-rw-r--r--module/plugins/hoster/UploadableCh.py38
-rw-r--r--module/plugins/hoster/UploadboxCom.py3
-rw-r--r--module/plugins/hoster/UploadedTo.py85
-rw-r--r--module/plugins/hoster/UploadhereCom.py3
-rw-r--r--module/plugins/hoster/UploadheroCom.py13
-rw-r--r--module/plugins/hoster/UploadingCom.py24
-rw-r--r--module/plugins/hoster/UploadkingCom.py3
-rw-r--r--module/plugins/hoster/UpstoreNet.py29
-rw-r--r--module/plugins/hoster/UptoboxCom.py7
-rw-r--r--module/plugins/hoster/VeehdCom.py16
-rw-r--r--module/plugins/hoster/VeohCom.py13
-rw-r--r--module/plugins/hoster/VidPlayNet.py3
-rw-r--r--module/plugins/hoster/VimeoCom.py23
-rw-r--r--module/plugins/hoster/Vipleech4UCom.py3
-rw-r--r--module/plugins/hoster/VkCom.py35
-rw-r--r--module/plugins/hoster/WarserverCz.py3
-rw-r--r--module/plugins/hoster/WebshareCz.py50
-rw-r--r--module/plugins/hoster/WrzucTo.py9
-rw-r--r--module/plugins/hoster/WuploadCom.py3
-rw-r--r--module/plugins/hoster/X7To.py3
-rw-r--r--module/plugins/hoster/XFileSharingPro.py61
-rw-r--r--module/plugins/hoster/XHamsterCom.py23
-rw-r--r--module/plugins/hoster/XVideosCom.py5
-rw-r--r--module/plugins/hoster/XdadevelopersCom.py9
-rw-r--r--module/plugins/hoster/Xdcc.py93
-rw-r--r--module/plugins/hoster/YadiSk.py13
-rw-r--r--module/plugins/hoster/YibaishiwuCom.py9
-rw-r--r--module/plugins/hoster/YoupornCom.py13
-rw-r--r--module/plugins/hoster/YourfilesTo.py20
-rw-r--r--module/plugins/hoster/YoutubeCom.py75
-rw-r--r--module/plugins/hoster/ZDF.py12
-rw-r--r--module/plugins/hoster/ZShareNet.py3
-rw-r--r--module/plugins/hoster/ZahikiNet.py33
-rw-r--r--module/plugins/hoster/ZeveraCom.py16
-rw-r--r--module/plugins/hoster/ZippyshareCom.py41
-rw-r--r--module/plugins/internal/Account.py397
-rw-r--r--module/plugins/internal/Addon.py245
-rw-r--r--module/plugins/internal/Captcha.py149
-rw-r--r--module/plugins/internal/CaptchaService.py46
-rw-r--r--module/plugins/internal/Container.py91
-rw-r--r--module/plugins/internal/Crypter.py102
-rw-r--r--module/plugins/internal/DeadCrypter.py21
-rw-r--r--module/plugins/internal/DeadHoster.py21
-rw-r--r--module/plugins/internal/Extractor.py75
-rw-r--r--module/plugins/internal/Hook.py28
-rw-r--r--module/plugins/internal/Hoster.py648
-rw-r--r--module/plugins/internal/MultiCrypter.py29
-rw-r--r--module/plugins/internal/MultiHook.py160
-rw-r--r--module/plugins/internal/MultiHoster.py113
-rw-r--r--module/plugins/internal/OCR.py (renamed from module/plugins/captcha/OCR.py)117
-rw-r--r--module/plugins/internal/Plugin.py399
-rw-r--r--module/plugins/internal/SevenZip.py51
-rw-r--r--module/plugins/internal/SimpleCrypter.py137
-rw-r--r--module/plugins/internal/SimpleDereferer.py107
-rw-r--r--module/plugins/internal/SimpleHoster.py715
-rw-r--r--module/plugins/internal/UnRar.py104
-rw-r--r--module/plugins/internal/UnZip.py7
-rw-r--r--module/plugins/internal/XFSAccount.py85
-rw-r--r--module/plugins/internal/XFSCrypter.py17
-rw-r--r--module/plugins/internal/XFSHoster.py109
496 files changed, 9622 insertions, 7506 deletions
diff --git a/module/plugins/Account.py b/module/plugins/Account.py
deleted file mode 100644
index c147404e0..000000000
--- a/module/plugins/Account.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay
-"""
-
-from random import choice
-from time import time
-from traceback import print_exc
-from threading import RLock
-
-from Plugin import Base
-from module.utils import compare_time, parseFileSize, lock
-
-class WrongPassword(Exception):
- pass
-
-
-class Account(Base):
- """
- Base class for every Account plugin.
- Just overwrite `login` and cookies will be stored and account becomes accessible in\
- associated hoster plugin. Plugin should also provide `loadAccountInfo`
- """
- __name__ = "Account"
- __version__ = "0.2"
- __type__ = "account"
- __description__ = """Account Plugin"""
- __author_name__ = ("mkaay")
- __author_mail__ = ("mkaay@mkaay.de")
-
- #: after that time [in minutes] pyload will relogin the account
- login_timeout = 600
- #: account data will be reloaded after this time
- info_threshold = 600
-
-
- def __init__(self, manager, accounts):
- Base.__init__(self, manager.core)
-
- self.manager = manager
- self.accounts = {}
- self.infos = {} # cache for account information
- self.lock = RLock()
-
- self.timestamps = {}
- self.setAccounts(accounts)
- self.init()
-
- def init(self):
- pass
-
- def login(self, user, data, req):
- """login into account, the cookies will be saved so user can be recognized
-
- :param user: loginname
- :param data: data dictionary
- :param req: `Request` instance
- """
- pass
-
- @lock
- def _login(self, user, data):
- # set timestamp for login
- self.timestamps[user] = time()
-
- req = self.getAccountRequest(user)
- try:
- self.login(user, data, req)
- except WrongPassword:
- self.logWarning(
- _("Could not login with account %(user)s | %(msg)s") % {"user": user
- , "msg": _("Wrong Password")})
- data["valid"] = False
-
- except Exception, e:
- self.logWarning(
- _("Could not login with account %(user)s | %(msg)s") % {"user": user
- , "msg": e})
- data["valid"] = False
- if self.core.debug:
- print_exc()
- finally:
- if req: req.close()
-
- def relogin(self, user):
- req = self.getAccountRequest(user)
- if req:
- req.cj.clear()
- req.close()
- if user in self.infos:
- del self.infos[user] #delete old information
-
- self._login(user, self.accounts[user])
-
- def setAccounts(self, accounts):
- self.accounts = accounts
- for user, data in self.accounts.iteritems():
- self._login(user, data)
- self.infos[user] = {}
-
- def updateAccounts(self, user, password=None, options={}):
- """ updates account and return true if anything changed """
-
- if user in self.accounts:
- self.accounts[user]["valid"] = True #do not remove or accounts will not login
- if password:
- self.accounts[user]["password"] = password
- self.relogin(user)
- return True
- if options:
- before = self.accounts[user]["options"]
- self.accounts[user]["options"].update(options)
- return self.accounts[user]["options"] != before
- else:
- self.accounts[user] = {"password": password, "options": options, "valid": True}
- self._login(user, self.accounts[user])
- return True
-
- def removeAccount(self, user):
- if user in self.accounts:
- del self.accounts[user]
- if user in self.infos:
- del self.infos[user]
- if user in self.timestamps:
- del self.timestamps[user]
-
- @lock
- def getAccountInfo(self, name, force=False):
- """retrieve account infos for an user, do **not** overwrite this method!\\
- just use it to retrieve infos in hoster plugins. see `loadAccountInfo`
-
- :param name: username
- :param force: reloads cached account information
- :return: dictionary with information
- """
- data = Account.loadAccountInfo(self, name)
-
- if force or name not in self.infos:
- self.logDebug("Get Account Info for %s" % name)
- req = self.getAccountRequest(name)
-
- try:
- infos = self.loadAccountInfo(name, req)
- if not type(infos) == dict:
- raise Exception("Wrong return format")
- except Exception, e:
- infos = {"error": str(e)}
-
- if req: req.close()
-
- self.logDebug("Account Info: %s" % str(infos))
-
- infos["timestamp"] = time()
- self.infos[name] = infos
- elif "timestamp" in self.infos[name] and self.infos[name][
- "timestamp"] + self.info_threshold * 60 < time():
- self.logDebug("Reached timeout for account data")
- self.scheduleRefresh(name)
-
- data.update(self.infos[name])
- return data
-
- def isPremium(self, user):
- info = self.getAccountInfo(user)
- return info["premium"]
-
- def loadAccountInfo(self, name, req=None):
- """this should be overwritten in account plugin,\
- and retrieving account information for user
-
- :param name:
- :param req: `Request` instance
- :return:
- """
- return {
- "validuntil": None, # -1 for unlimited
- "login": name,
- #"password": self.accounts[name]["password"], #@XXX: security
- "options": self.accounts[name]["options"],
- "valid": self.accounts[name]["valid"],
- "trafficleft": None, # in kb, -1 for unlimited
- "maxtraffic": None,
- "premium": True, #useful for free accounts
- "timestamp": 0, #time this info was retrieved
- "type": self.__name__,
- }
-
- def getAllAccounts(self, force=False):
- return [self.getAccountInfo(user, force) for user, data in self.accounts.iteritems()]
-
- def getAccountRequest(self, user=None):
- if not user:
- user, data = self.selectAccount()
- if not user:
- return None
-
- req = self.core.requestFactory.getRequest(self.__name__, user)
- return req
-
- def getAccountCookies(self, user=None):
- if not user:
- user, data = self.selectAccount()
- if not user:
- return None
-
- cj = self.core.requestFactory.getCookieJar(self.__name__, user)
- return cj
-
- def getAccountData(self, user):
- return self.accounts[user]
-
- def selectAccount(self):
- """ returns an valid account name and data"""
- usable = []
- for user, data in self.accounts.iteritems():
- if not data["valid"]: continue
-
- if "time" in data["options"] and data["options"]["time"]:
- time_data = ""
- try:
- time_data = data["options"]["time"][0]
- start, end = time_data.split("-")
- if not compare_time(start.split(":"), end.split(":")):
- continue
- except:
- self.logWarning(_("Your Time %s has wrong format, use: 1:22-3:44") % time_data)
-
- if user in self.infos:
- if "validuntil" in self.infos[user]:
- if self.infos[user]["validuntil"] > 0 and time() > self.infos[user]["validuntil"]:
- continue
- if "trafficleft" in self.infos[user]:
- if self.infos[user]["trafficleft"] == 0:
- continue
-
- usable.append((user, data))
-
- if not usable: return None, None
- return choice(usable)
-
- def canUse(self):
- return False if self.selectAccount() == (None, None) else True
-
- def parseTraffic(self, string): #returns kbyte
- return parseFileSize(string) / 1024
-
- def wrongPassword(self):
- raise WrongPassword
-
- def empty(self, user):
- if user in self.infos:
- self.logWarning(_("Account %s has not enough traffic, checking again in 30min") % user)
-
- self.infos[user].update({"trafficleft": 0})
- self.scheduleRefresh(user, 30 * 60)
-
- def expired(self, user):
- if user in self.infos:
- self.logWarning(_("Account %s is expired, checking again in 1h") % user)
-
- self.infos[user].update({"validuntil": time() - 1})
- self.scheduleRefresh(user, 60 * 60)
-
- def scheduleRefresh(self, user, time=0, force=True):
- """ add task to refresh account info to sheduler """
- self.logDebug("Scheduled Account refresh for %s in %s seconds." % (user, time))
- self.core.scheduler.addJob(time, self.getAccountInfo, [user, force])
-
- @lock
- def checkLogin(self, user):
- """ checks if user is still logged in """
- if user in self.timestamps:
- if self.timestamps[user] + self.login_timeout * 60 < time():
- self.logDebug("Reached login timeout for %s" % user)
- self.relogin(user)
- return False
-
- return True
diff --git a/module/plugins/AccountManager.py b/module/plugins/AccountManager.py
index fc521d36c..094641c76 100644
--- a/module/plugins/AccountManager.py
+++ b/module/plugins/AccountManager.py
@@ -125,10 +125,10 @@ class AccountManager():
f.write("\n")
f.write(plugin+":\n")
- for name,data in accounts.iteritems():
- f.write("\n\t%s:%s\n" % (name,data["password"]) )
- if data["options"]:
- for option, values in data["options"].iteritems():
+ for name, data in accounts.iteritems():
+ f.write("\n\t%s:%s\n" % (name, data['password']) )
+ if data['options']:
+ for option, values in data['options'].iteritems():
f.write("\t@%s %s\n" % (option, " ".join(values)))
f.close()
diff --git a/module/plugins/Container.py b/module/plugins/Container.py
deleted file mode 100644
index c233d3710..000000000
--- a/module/plugins/Container.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay
-"""
-
-from module.plugins.Crypter import Crypter
-
-from os.path import join, exists, basename
-from os import remove
-import re
-
-class Container(Crypter):
- __name__ = "Container"
- __version__ = "0.1"
- __pattern__ = None
- __type__ = "container"
- __description__ = """Base container plugin"""
- __author_name__ = ("mkaay")
- __author_mail__ = ("mkaay@mkaay.de")
-
-
- def preprocessing(self, thread):
- """prepare"""
-
- self.setup()
- self.thread = thread
-
- self.loadToDisk()
-
- self.decrypt(self.pyfile)
- self.deleteTmp()
-
- self.createPackages()
-
-
- def loadToDisk(self):
- """loads container to disk if its stored remotely and overwrite url,
- or check existent on several places at disk"""
-
- if self.pyfile.url.startswith("http"):
- self.pyfile.name = re.findall("([^\/=]+)", self.pyfile.url)[-1]
- content = self.load(self.pyfile.url)
- self.pyfile.url = join(self.config["general"]["download_folder"], self.pyfile.name)
- f = open(self.pyfile.url, "wb" )
- f.write(content)
- f.close()
-
- else:
- self.pyfile.name = basename(self.pyfile.url)
- if not exists(self.pyfile.url):
- if exists(join(pypath, self.pyfile.url)):
- self.pyfile.url = join(pypath, self.pyfile.url)
- else:
- self.fail(_("File not exists."))
-
-
- def deleteTmp(self):
- if self.pyfile.name.startswith("tmp_"):
- remove(self.pyfile.url)
-
-
diff --git a/module/plugins/Crypter.py b/module/plugins/Crypter.py
deleted file mode 100644
index d1549fe80..000000000
--- a/module/plugins/Crypter.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay
-"""
-
-from module.plugins.Plugin import Plugin
-
-class Crypter(Plugin):
- __name__ = "Crypter"
- __version__ = "0.1"
- __pattern__ = None
- __type__ = "container"
- __description__ = """Base crypter plugin"""
- __author_name__ = ("mkaay")
- __author_mail__ = ("mkaay@mkaay.de")
-
- def __init__(self, pyfile):
- Plugin.__init__(self, pyfile)
-
- #: Put all packages here. It's a list of tuples like: ( name, [list of links], folder )
- self.packages = []
-
- #: List of urls, pyLoad will generate packagenames
- self.urls = []
-
- self.multiDL = True
- self.limitDL = 0
-
-
- def preprocessing(self, thread):
- """prepare"""
- self.setup()
- self.thread = thread
-
- self.decrypt(self.pyfile)
-
- self.createPackages()
-
-
- def decrypt(self, pyfile):
- raise NotImplementedError
-
- def createPackages(self):
- """ create new packages from self.packages """
- for pack in self.packages:
-
- self.log.debug("Parsed package %(name)s with %(len)d links" % { "name" : pack[0], "len" : len(pack[1]) } )
-
- links = [x.decode("utf-8") for x in pack[1]]
-
- pid = self.core.api.addPackage(pack[0], links, self.pyfile.package().queue)
-
- if self.pyfile.package().password:
- self.core.api.setPackageData(pid, {"password": self.pyfile.package().password})
-
- if self.urls:
- self.core.api.generateAndAddPackages(self.urls)
-
diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py
deleted file mode 100644
index 5efd08bae..000000000
--- a/module/plugins/Hook.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay
- @interface-version: 0.2
-"""
-
-from traceback import print_exc
-
-from Plugin import Base
-
-class Expose(object):
- """ used for decoration to declare rpc services """
-
- def __new__(cls, f, *args, **kwargs):
- hookManager.addRPC(f.__module__, f.func_name, f.func_doc)
- return f
-
-def threaded(f):
- def run(*args,**kwargs):
- hookManager.startThread(f, *args, **kwargs)
- return run
-
-class Hook(Base):
- """
- Base class for hook plugins.
- """
- __name__ = "Hook"
- __version__ = "0.2"
- __type__ = "hook"
- __threaded__ = []
- __config__ = [ ("name", "type", "desc" , "default") ]
- __description__ = """interface for hook"""
- __author_name__ = ("mkaay", "RaNaN")
- __author_mail__ = ("mkaay@mkaay.de", "RaNaN@pyload.org")
-
- #: automatically register event listeners for functions, attribute will be deleted dont use it yourself
- event_map = None
-
- # Alternative to event_map
- #: List of events the plugin can handle, name the functions exactly like eventname.
- event_list = None # dont make duplicate entries in event_map
-
-
- #: periodic call interval in secondc
- interval = 60
-
- def __init__(self, core, manager):
- Base.__init__(self, core)
-
- #: Provide information in dict here, usable by API `getInfo`
- self.info = None
-
- #: Callback of periodical job task, used by hookmanager
- self.cb = None
-
- #: `HookManager`
- self.manager = manager
-
- #register events
- if self.event_map:
- for event, funcs in self.event_map.iteritems():
- if type(funcs) in (list, tuple):
- for f in funcs:
- self.manager.addEvent(event, getattr(self,f))
- else:
- self.manager.addEvent(event, getattr(self,funcs))
-
- #delete for various reasons
- self.event_map = None
-
- if self.event_list:
- for f in self.event_list:
- self.manager.addEvent(f, getattr(self,f))
-
- self.event_list = None
-
- self.initPeriodical()
- self.setup()
-
- def initPeriodical(self):
- if self.interval >=1:
- self.cb = self.core.scheduler.addJob(0, self._periodical, threaded=False)
-
- def _periodical(self):
- try:
- if self.isActivated(): self.periodical()
- except Exception, e:
- self.core.log.error(_("Error executing hooks: %s") % str(e))
- if self.core.debug:
- print_exc()
-
- self.cb = self.core.scheduler.addJob(self.interval, self._periodical, threaded=False)
-
-
- def __repr__(self):
- return "<Hook %s>" % self.__name__
-
- def setup(self):
- """ more init stuff if needed """
- pass
-
- def unload(self):
- """ called when hook was deactivated """
- pass
-
- def isActivated(self):
- """ checks if hook is activated"""
- return self.config.getPlugin(self.__name__, "activated")
-
-
- #event methods - overwrite these if needed
- def coreReady(self):
- pass
-
- def coreExiting(self):
- pass
-
- def downloadPreparing(self, pyfile):
- pass
-
- def downloadFinished(self, pyfile):
- pass
-
- def downloadFailed(self, pyfile):
- pass
-
- def packageFinished(self, pypack):
- pass
-
- def beforeReconnecting(self, ip):
- pass
-
- def afterReconnecting(self, ip):
- pass
-
- def periodical(self):
- pass
-
- def newCaptchaTask(self, task):
- """ new captcha task for the plugin, it MUST set the handler and timeout or will be ignored """
- pass
-
- def captchaCorrect(self, task):
- pass
-
- def captchaInvalid(self, task):
- pass \ No newline at end of file
diff --git a/module/plugins/Hoster.py b/module/plugins/Hoster.py
deleted file mode 100644
index 814a70949..000000000
--- a/module/plugins/Hoster.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay
-"""
-
-from module.plugins.Plugin import Plugin
-
-def getInfo(self):
- #result = [ .. (name, size, status, url) .. ]
- return
-
-class Hoster(Plugin):
- __name__ = "Hoster"
- __version__ = "0.1"
- __pattern__ = None
- __type__ = "hoster"
- __description__ = """Base hoster plugin"""
- __author_name__ = ("mkaay")
- __author_mail__ = ("mkaay@mkaay.de")
diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py
index f9c1f2ca6..6a2f09c9c 100644
--- a/module/plugins/accounts/AlldebridCom.py
+++ b/module/plugins/accounts/AlldebridCom.py
@@ -4,60 +4,63 @@ import re
import time
import xml.dom.minidom as dom
-from BeautifulSoup import BeautifulSoup
+import BeautifulSoup
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class AlldebridCom(Account):
__name__ = "AlldebridCom"
__type__ = "account"
- __version__ = "0.23"
+ __version__ = "0.26"
+ __status__ = "testing"
__description__ = """AllDebrid.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("Andy Voigt", "spamsales@online.de")]
- def loadAccountInfo(self, user, req):
- data = self.getAccountData(user)
- html = req.load("http://www.alldebrid.com/account/")
- soup = BeautifulSoup(html)
+ def parse_info(self, user, password, data, req):
+ data = self.get_data(user)
+ html = self.load("http://www.alldebrid.com/account/")
+ soup = BeautifulSoup.BeautifulSoup(html)
- #Try to parse expiration date directly from the control panel page (better accuracy)
+ #: Try to parse expiration date directly from the control panel page (better accuracy)
try:
time_text = soup.find('div', attrs={'class': 'remaining_time_text'}).strong.string
- self.logDebug("Account expires in: %s" % time_text)
+ self.log_debug("Account expires in: %s" % time_text)
p = re.compile('\d+')
exp_data = p.findall(time_text)
exp_time = time.time() + int(exp_data[0]) * 24 * 60 * 60 + int(
exp_data[1]) * 60 * 60 + (int(exp_data[2]) - 1) * 60
- #Get expiration date from API
+ #: Get expiration date from API
except Exception:
- data = self.getAccountData(user)
- html = req.load("http://www.alldebrid.com/api.php",
- get={'action': "info_user", 'login': user, 'pw': data['password']})
+ data = self.get_data(user)
+ html = self.load("https://www.alldebrid.com/api.php",
+ get={'action': "info_user",
+ 'login' : user,
+ 'pw' : password})
- self.logDebug(html)
+ self.log_debug(html)
xml = dom.parseString(html)
exp_time = time.time() + int(xml.getElementsByTagName("date")[0].childNodes[0].nodeValue) * 24 * 60 * 60
- account_info = {"validuntil": exp_time, "trafficleft": -1}
- return account_info
+ return {'validuntil' : exp_time,
+ 'trafficleft': -1 ,
+ 'premium' : True }
- def login(self, user, data, req):
- html = req.load("http://www.alldebrid.com/register/",
- get={'action' : "login",
- 'login_login' : user,
- 'login_password': data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://www.alldebrid.com/register/",
+ get={'action' : "login",
+ 'login_login' : user,
+ 'login_password': password})
if "This login doesn't exist" in html \
or "The password is not valid" in html \
or "Invalid captcha" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/AniStreamCom.py b/module/plugins/accounts/AniStreamCom.py
new file mode 100644
index 000000000..53ca1d5b8
--- /dev/null
+++ b/module/plugins/accounts/AniStreamCom.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class AniStreamCom(XFSAccount):
+ __name__ = "AniStreamCom"
+ __type__ = "account"
+ __version__ = "0.01"
+ __status__ = "testing"
+
+ __description__ = """Ani-Stream.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "ani-stream.com"
diff --git a/module/plugins/accounts/BackinNet.py b/module/plugins/accounts/BackinNet.py
index 46c8d7ac5..58939c13a 100644
--- a/module/plugins/accounts/BackinNet.py
+++ b/module/plugins/accounts/BackinNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class BackinNet(XFSAccount):
__name__ = "BackinNet"
__type__ = "account"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__description__ = """Backin.net account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/BitshareCom.py b/module/plugins/accounts/BitshareCom.py
index 00e546f6d..280f008b2 100644
--- a/module/plugins/accounts/BitshareCom.py
+++ b/module/plugins/accounts/BitshareCom.py
@@ -1,34 +1,36 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class BitshareCom(Account):
__name__ = "BitshareCom"
__type__ = "account"
- __version__ = "0.13"
+ __version__ = "0.15"
+ __status__ = "testing"
__description__ = """Bitshare account plugin"""
__license__ = "GPLv3"
__authors__ = [("Paul King", None)]
- def loadAccountInfo(self, user, req):
- html = req.load("http://bitshare.com/mysettings.html")
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://bitshare.com/mysettings.html")
if "\"http://bitshare.com/myupgrade.html\">Free" in html:
- return {"validuntil": -1, "trafficleft": -1, "premium": False}
+ return {'validuntil': -1, 'trafficleft': -1, 'premium': False}
if not '<input type="checkbox" name="directdownload" checked="checked" />' in html:
- self.logWarning(_("Activate direct Download in your Bitshare Account"))
+ self.log_warning(_("Activate direct Download in your Bitshare Account"))
- return {"validuntil": -1, "trafficleft": -1, "premium": True}
+ return {'validuntil': -1, 'trafficleft': -1, 'premium': True}
- def login(self, user, data, req):
- html = req.load("http://bitshare.com/login.html",
- post={"user": user, "password": data['password'], "submit": "Login"},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://bitshare.com/login.html",
+ post={'user' : user,
+ 'password': password,
+ 'submit' : "Login"})
if "login" in req.lastEffectiveURL:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/CatShareNet.py b/module/plugins/accounts/CatShareNet.py
index bb42f443f..92f1cb27e 100644
--- a/module/plugins/accounts/CatShareNet.py
+++ b/module/plugins/accounts/CatShareNet.py
@@ -3,15 +3,16 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class CatShareNet(Account):
__name__ = "CatShareNet"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.08"
+ __status__ = "testing"
- __description__ = """CatShareNet account plugin"""
+ __description__ = """Catshare.net account plugin"""
__license__ = "GPLv3"
__authors__ = [("prOq", None)]
@@ -21,19 +22,19 @@ class CatShareNet(Account):
TRAFFIC_LEFT_PATTERN = r'<a href="/premium">([0-9.]+ [kMG]B)'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
premium = False
validuntil = -1
trafficleft = -1
- html = req.load("http://catshare.net/", decode=True)
+ html = self.load("http://catshare.net/")
if re.search(self.PREMIUM_PATTERN, html):
premium = True
try:
expiredate = re.search(self.VALID_UNTIL_PATTERN, html).group(1)
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
validuntil = time.mktime(time.strptime(expiredate, "%Y-%m-%d %H:%M:%S"))
@@ -41,7 +42,7 @@ class CatShareNet(Account):
pass
try:
- trafficleft = self.parseTraffic(re.search(self.TRAFFIC_LEFT_PATTERN, html).group(1))
+ trafficleft = self.parse_traffic(re.search(self.TRAFFIC_LEFT_PATTERN, html).group(1))
except Exception:
pass
@@ -49,13 +50,12 @@ class CatShareNet(Account):
return {'premium': premium, 'trafficleft': trafficleft, 'validuntil': validuntil}
- def login(self, user, data, req):
- html = req.load("http://catshare.net/login",
- post={'user_email': user,
- 'user_password': data['password'],
- 'remindPassword': 0,
- 'user[submit]': "Login"},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("http://catshare.net/login", #@TODO: Revert to `https` in 0.4.10
+ post={'user_email' : user,
+ 'user_password' : password,
+ 'remindPassword': 0,
+ 'user[submit]' : "Login"})
if not '<a href="/logout">Wyloguj</a>' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/CloudsixMe.py b/module/plugins/accounts/CloudsixMe.py
new file mode 100644
index 000000000..973e37044
--- /dev/null
+++ b/module/plugins/accounts/CloudsixMe.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class CloudsixMe(XFSAccount):
+ __name__ = "CloudsixMe"
+ __type__ = "account"
+ __version__ = "0.01"
+ __status__ = "testing"
+
+ __description__ = """Cloudsix.me account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "cloudsix.me"
diff --git a/module/plugins/accounts/CloudzillaTo.py b/module/plugins/accounts/CloudzillaTo.py
index d22d5e4b3..0d473eb7d 100644
--- a/module/plugins/accounts/CloudzillaTo.py
+++ b/module/plugins/accounts/CloudzillaTo.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class CloudzillaTo(Account):
__name__ = "CloudzillaTo"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Cloudzilla.to account plugin"""
__license__ = "GPLv3"
@@ -18,20 +19,19 @@ class CloudzillaTo(Account):
PREMIUM_PATTERN = r'<h2>account type</h2>\s*Premium Account'
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.cloudzilla.to/")
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://www.cloudzilla.to/")
premium = True if re.search(self.PREMIUM_PATTERN, html) else False
return {'validuntil': -1, 'trafficleft': -1, 'premium': premium}
- def login(self, user, data, req):
- html = req.load("http://www.cloudzilla.to/",
- post={'lusername': user,
- 'lpassword': data['password'],
- 'w' : "dologin"},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://www.cloudzilla.to/",
+ post={'lusername': user,
+ 'lpassword': password,
+ 'w' : "dologin"})
if "ERROR" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/CramitIn.py b/module/plugins/accounts/CramitIn.py
index a9e2274a2..d3f2e0d77 100644
--- a/module/plugins/accounts/CramitIn.py
+++ b/module/plugins/accounts/CramitIn.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class CramitIn(XFSAccount):
__name__ = "CramitIn"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Cramit.in account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/CzshareCom.py b/module/plugins/accounts/CzshareCom.py
index 300943828..e9a34cb83 100644
--- a/module/plugins/accounts/CzshareCom.py
+++ b/module/plugins/accounts/CzshareCom.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class CzshareCom(Account):
__name__ = "CzshareCom"
__type__ = "account"
- __version__ = "0.18"
+ __version__ = "0.20"
+ __status__ = "testing"
__description__ = """Czshare.com account plugin, now Sdilej.cz"""
__license__ = "GPLv3"
@@ -20,20 +21,20 @@ class CzshareCom(Account):
CREDIT_LEFT_PATTERN = r'<tr class="active">\s*<td>([\d ,]+) (KiB|MiB|GiB)</td>\s*<td>([^<]*)</td>\s*</tr>'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
premium = False
validuntil = None
trafficleft = None
- html = req.load("http://sdilej.cz/prehled_kreditu/")
+ html = self.load("http://sdilej.cz/prehled_kreditu/")
try:
m = re.search(self.CREDIT_LEFT_PATTERN, html)
- trafficleft = self.parseTraffic(m.group(1).replace(' ', '').replace(',', '.')) + m.group(2)
+ trafficleft = self.parse_traffic(m.group(1).replace(' ', '').replace(',', '.')) + m.group(2)
validuntil = time.mktime(time.strptime(m.group(3), '%d.%m.%y %H:%M'))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
premium = True
@@ -43,12 +44,11 @@ class CzshareCom(Account):
'trafficleft': trafficleft}
- def login(self, user, data, req):
- html = req.load('https://sdilej.cz/index.php',
- post={"Prihlasit": "Prihlasit",
- "login-password": data['password'],
- "login-name": user},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load('https://sdilej.cz/index.php',
+ post={'Prihlasit' : "Prihlasit",
+ "login-password": password,
+ "login-name" : user})
if '<div class="login' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/DebridItaliaCom.py b/module/plugins/accounts/DebridItaliaCom.py
index 3df99101a..9c0956668 100644
--- a/module/plugins/accounts/DebridItaliaCom.py
+++ b/module/plugins/accounts/DebridItaliaCom.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class DebridItaliaCom(Account):
__name__ = "DebridItaliaCom"
__type__ = "account"
- __version__ = "0.13"
+ __version__ = "0.15"
+ __status__ = "testing"
__description__ = """Debriditalia.com account plugin"""
__license__ = "GPLv3"
@@ -20,25 +21,25 @@ class DebridItaliaCom(Account):
WALID_UNTIL_PATTERN = r'Premium valid till: (.+?) \|'
- def loadAccountInfo(self, user, req):
- info = {"premium": False, "validuntil": None, "trafficleft": None}
- html = req.load("http://debriditalia.com/")
+ def parse_info(self, user, password, data, req):
+ info = {'premium': False, 'validuntil': None, 'trafficleft': None}
+ html = self.load("http://debriditalia.com/")
if 'Account premium not activated' not in html:
m = re.search(self.WALID_UNTIL_PATTERN, html)
if m:
validuntil = time.mktime(time.strptime(m.group(1), "%d/%m/%Y %H:%M"))
- info = {"premium": True, "validuntil": validuntil, "trafficleft": -1}
+ info = {'premium': True, 'validuntil': validuntil, 'trafficleft': -1}
else:
- self.logError(_("Unable to retrieve account information"))
+ self.log_error(_("Unable to retrieve account information"))
return info
- def login(self, user, data, req):
- html = req.load("http://debriditalia.com/login.php",
- get={'u': user, 'p': data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://debriditalia.com/login.php",
+ get={'u': user,
+ 'p': password})
if 'NO' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/DepositfilesCom.py b/module/plugins/accounts/DepositfilesCom.py
index a0bd6a37c..848529bc3 100644
--- a/module/plugins/accounts/DepositfilesCom.py
+++ b/module/plugins/accounts/DepositfilesCom.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class DepositfilesCom(Account):
__name__ = "DepositfilesCom"
__type__ = "account"
- __version__ = "0.32"
+ __version__ = "0.34"
+ __status__ = "testing"
__description__ = """Depositfiles.com account plugin"""
__license__ = "GPLv3"
@@ -18,19 +19,20 @@ class DepositfilesCom(Account):
("Walter Purcaro", "vuolter@gmail.com")]
- def loadAccountInfo(self, user, req):
- html = req.load("https://dfiles.eu/de/gold/")
+ def parse_info(self, user, password, data, req):
+ html = self.load("https://dfiles.eu/de/gold/")
validuntil = re.search(r"Sie haben Gold Zugang bis: <b>(.*?)</b></div>", html).group(1)
validuntil = time.mktime(time.strptime(validuntil, "%Y-%m-%d %H:%M:%S"))
- return {"validuntil": validuntil, "trafficleft": -1}
+ return {'validuntil': validuntil, 'trafficleft': -1}
- def login(self, user, data, req):
- html = req.load("https://dfiles.eu/de/login.php", get={"return": "/de/gold/payment.php"},
- post={"login": user, "password": data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://dfiles.eu/de/login.php",
+ get={'return': "/de/gold/payment.php"},
+ post={'login' : user,
+ 'password': password})
if r'<div class="error_message">Sie haben eine falsche Benutzername-Passwort-Kombination verwendet.</div>' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/EasybytezCom.py b/module/plugins/accounts/EasybytezCom.py
index 93d3e2c19..5e1a4f962 100644
--- a/module/plugins/accounts/EasybytezCom.py
+++ b/module/plugins/accounts/EasybytezCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class EasybytezCom(XFSAccount):
__name__ = "EasybytezCom"
__type__ = "account"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__description__ = """EasyBytez.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/EuroshareEu.py b/module/plugins/accounts/EuroshareEu.py
index db4539e2e..bc8618250 100644
--- a/module/plugins/accounts/EuroshareEu.py
+++ b/module/plugins/accounts/EuroshareEu.py
@@ -3,39 +3,40 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class EuroshareEu(Account):
__name__ = "EuroshareEu"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Euroshare.eu account plugin"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
self.relogin(user)
- html = req.load("http://euroshare.eu/customer-zone/settings/")
+ html = self.load("http://euroshare.eu/customer-zone/settings/")
m = re.search('id="input_expire_date" value="(\d+\.\d+\.\d+ \d+:\d+)"', html)
if m is None:
- premium, validuntil = False, -1
+ premium = False
+ validuntil = -1
else:
premium = True
validuntil = time.mktime(time.strptime(m.group(1), "%d.%m.%Y %H:%M"))
- return {"validuntil": validuntil, "trafficleft": -1, "premium": premium}
+ return {'validuntil': validuntil, 'trafficleft': -1, 'premium': premium}
- def login(self, user, data, req):
- html = req.load('http://euroshare.eu/customer-zone/login/',
- post={"trvale": "1",
- "login": user,
- "password": data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load('http://euroshare.eu/customer-zone/login/',
+ post={'trvale' : "1",
+ 'login' : user,
+ 'password': password})
if u">Nesprávne prihlasovacie meno alebo heslo" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/ExashareCom.py b/module/plugins/accounts/ExashareCom.py
index 431798522..26594c702 100644
--- a/module/plugins/accounts/ExashareCom.py
+++ b/module/plugins/accounts/ExashareCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class ExashareCom(XFSAccount):
__name__ = "ExashareCom"
__type__ = "account"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__description__ = """Exashare.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/FastixRu.py b/module/plugins/accounts/FastixRu.py
index 51be3880f..13edbbb44 100644
--- a/module/plugins/accounts/FastixRu.py
+++ b/module/plugins/accounts/FastixRu.py
@@ -1,36 +1,41 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class FastixRu(Account):
__name__ = "FastixRu"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """Fastix account plugin"""
__license__ = "GPLv3"
__authors__ = [("Massimo Rosamilia", "max@spiritix.eu")]
- def loadAccountInfo(self, user, req):
- data = self.getAccountData(user)
- html = json_loads(req.load("http://fastix.ru/api_v2/", get={'apikey': data['api'], 'sub': "getaccountdetails"}))
+ def parse_info(self, user, password, data, req):
+ data = self.get_data(user)
+ html = json_loads(self.load("http://fastix.ru/api_v2/",
+ get={'apikey': data['api'],
+ 'sub' : "getaccountdetails"}))
points = html['points']
kb = float(points) * 1024 ** 2 / 1000
if points > 0:
- account_info = {"validuntil": -1, "trafficleft": kb}
+ account_info = {'validuntil': -1, 'trafficleft': kb}
else:
- account_info = {"validuntil": None, "trafficleft": None, "premium": False}
+ account_info = {'validuntil': None, 'trafficleft': None, 'premium': False}
return account_info
- def login(self, user, data, req):
- html = req.load("http://fastix.ru/api_v2/",
- get={'sub': "get_apikey", 'email': user, 'password': data['password']})
+ def login(self, user, password, data, req):
+ html = self.load("https://fastix.ru/api_v2/",
+ get={'sub' : "get_apikey",
+ 'email' : user,
+ 'password': password})
api = json_loads(html)
api = api['apikey']
@@ -38,4 +43,4 @@ class FastixRu(Account):
data['api'] = api
if "error_code" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FastshareCz.py b/module/plugins/accounts/FastshareCz.py
index b946e29ba..3a3769a1c 100644
--- a/module/plugins/accounts/FastshareCz.py
+++ b/module/plugins/accounts/FastshareCz.py
@@ -2,13 +2,15 @@
import re
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class FastshareCz(Account):
__name__ = "FastshareCz"
__type__ = "account"
- __version__ = "0.06"
+ __version__ = "0.09"
+ __status__ = "testing"
__description__ = """Fastshare.cz account plugin"""
__license__ = "GPLv3"
@@ -19,16 +21,16 @@ class FastshareCz(Account):
CREDIT_PATTERN = r'Credit\s*:\s*</td>\s*<td>(.+?)\s*<'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = -1
trafficleft = None
premium = False
- html = req.load("http://www.fastshare.cz/user", decode=True)
+ html = self.load("http://www.fastshare.cz/user")
m = re.search(self.CREDIT_PATTERN, html)
if m:
- trafficleft = self.parseTraffic(m.group(1))
+ trafficleft = self.parse_traffic(m.group(1))
premium = bool(trafficleft)
@@ -37,14 +39,14 @@ class FastshareCz(Account):
'premium' : premium}
- def login(self, user, data, req):
- req.cj.setCookie("fastshare.cz", "lang", "en")
+ def login(self, user, password, data, req):
+ set_cookie(req.cj, "fastshare.cz", "lang", "en")
- req.load('http://www.fastshare.cz/login') # Do not remove or it will not login
+ self.load('http://www.fastshare.cz/login') #@NOTE: Do not remove or it will not login
- html = req.load("http://www.fastshare.cz/sql.php",
- post={'login': user, 'heslo': data['password']},
- decode=True)
+ html = self.load("https://www.fastshare.cz/sql.php",
+ post={'login': user,
+ 'heslo': password})
if ">Wrong username or password" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/File4SafeCom.py b/module/plugins/accounts/File4SafeCom.py
index 50fe1aac8..54c3a2359 100644
--- a/module/plugins/accounts/File4SafeCom.py
+++ b/module/plugins/accounts/File4SafeCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class File4SafeCom(XFSAccount):
__name__ = "File4SafeCom"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__description__ = """File4Safe.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/FileParadoxIn.py b/module/plugins/accounts/FileParadoxIn.py
index c12d99d6a..21f43be6e 100644
--- a/module/plugins/accounts/FileParadoxIn.py
+++ b/module/plugins/accounts/FileParadoxIn.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class FileParadoxIn(XFSAccount):
__name__ = "FileParadoxIn"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """FileParadox.in account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/FilecloudIo.py b/module/plugins/accounts/FilecloudIo.py
index 8ca55b1bc..bdb13bd3d 100644
--- a/module/plugins/accounts/FilecloudIo.py
+++ b/module/plugins/accounts/FilecloudIo.py
@@ -1,13 +1,15 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
from module.common.json_layer import json_loads
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class FilecloudIo(Account):
__name__ = "FilecloudIo"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """FilecloudIo account plugin"""
__license__ = "GPLv3"
@@ -15,45 +17,44 @@ class FilecloudIo(Account):
("stickell", "l.stickell@yahoo.it")]
- def loadAccountInfo(self, user, req):
- # It looks like the first API request always fails, so we retry 5 times, it should work on the second try
+ def parse_info(self, user, password, data, req):
+ #: It looks like the first API request always fails, so we retry 5 times, it should work on the second try
for _i in xrange(5):
- rep = req.load("https://secure.filecloud.io/api-fetch_apikey.api",
- post={"username": user, "password": self.getAccountData(user)['password']})
+ rep = self.load("https://secure.filecloud.io/api-fetch_apikey.api",
+ post={'username': user, 'password': password})
rep = json_loads(rep)
- if rep['status'] == 'ok':
+ if rep['status'] == "ok":
break
- elif rep['status'] == 'error' and rep['message'] == 'no such user or wrong password':
- self.logError(_("Wrong username or password"))
- return {"valid": False, "premium": False}
+ elif rep['status'] == "error" and rep['message'] == "no such user or wrong password":
+ self.log_error(_("Wrong username or password"))
+ return {'valid': False, 'premium': False}
else:
- return {"premium": False}
+ return {'premium': False}
akey = rep['akey']
- self.accounts[user]['akey'] = akey # Saved for hoster plugin
- rep = req.load("http://api.filecloud.io/api-fetch_account_details.api",
- post={"akey": akey})
+ self.accounts[user]['akey'] = akey #: Saved for hoster plugin
+ rep = self.load("http://api.filecloud.io/api-fetch_account_details.api",
+ post={'akey': akey})
rep = json_loads(rep)
if rep['is_premium'] == 1:
- return {"validuntil": float(rep['premium_until']), "trafficleft": -1}
+ return {'validuntil': float(rep['premium_until']), 'trafficleft': -1}
else:
- return {"premium": False}
+ return {'premium': False}
- def login(self, user, data, req):
- req.cj.setCookie("secure.filecloud.io", "lang", "en")
- html = req.load('https://secure.filecloud.io/user-login.html')
+ def login(self, user, password, data, req):
+ set_cookie(req.cj, "secure.filecloud.io", "lang", "en")
+ html = self.load('https://secure.filecloud.io/user-login.html')
if not hasattr(self, "form_data"):
self.form_data = {}
self.form_data['username'] = user
- self.form_data['password'] = data['password']
+ self.form_password = password
- html = req.load('https://secure.filecloud.io/user-login_p.html',
- post=self.form_data,
- multipart=True)
+ html = self.load('https://secure.filecloud.io/user-login_p.html',
+ post=self.form_data)
if "you have successfully logged in" not in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FilefactoryCom.py b/module/plugins/accounts/FilefactoryCom.py
index 37b6f97a8..e3d0c8491 100644
--- a/module/plugins/accounts/FilefactoryCom.py
+++ b/module/plugins/accounts/FilefactoryCom.py
@@ -4,13 +4,14 @@ import pycurl
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class FilefactoryCom(Account):
__name__ = "FilefactoryCom"
__type__ = "account"
- __version__ = "0.15"
+ __version__ = "0.17"
+ __status__ = "testing"
__description__ = """Filefactory.com account plugin"""
__license__ = "GPLv3"
@@ -21,8 +22,8 @@ class FilefactoryCom(Account):
VALID_UNTIL_PATTERN = r'Premium valid until: <strong>(?P<D>\d{1,2})\w{1,2} (?P<M>\w{3}), (?P<Y>\d{4})</strong>'
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.filefactory.com/account/")
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://www.filefactory.com/account/")
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
@@ -33,16 +34,16 @@ class FilefactoryCom(Account):
premium = False
validuntil = -1
- return {"premium": premium, "trafficleft": -1, "validuntil": validuntil}
+ return {'premium': premium, 'trafficleft': -1, 'validuntil': validuntil}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
req.http.c.setopt(pycurl.REFERER, "http://www.filefactory.com/member/login.php")
- html = req.load("http://www.filefactory.com/member/signin.php",
- post={"loginEmail" : user,
- "loginPassword": data['password'],
- "Submit" : "Sign In"})
+ html = self.load("https://www.filefactory.com/member/signin.php",
+ post={'loginEmail' : user,
+ 'loginPassword': password,
+ 'Submit' : "Sign In"})
if req.lastEffectiveURL != "http://www.filefactory.com/account/":
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FilejungleCom.py b/module/plugins/accounts/FilejungleCom.py
index b92a371a5..fb251ac5f 100644
--- a/module/plugins/accounts/FilejungleCom.py
+++ b/module/plugins/accounts/FilejungleCom.py
@@ -2,14 +2,16 @@
import re
import time
+import urlparse
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class FilejungleCom(Account):
__name__ = "FilejungleCom"
__type__ = "account"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Filejungle.com account plugin"""
__license__ = "GPLv3"
@@ -23,8 +25,8 @@ class FilejungleCom(Account):
LOGIN_FAILED_PATTERN = r'<span htmlfor="loginUser(Name|Password)" generated="true" class="fail_info">'
- def loadAccountInfo(self, user, req):
- html = req.load(self.URL + "dashboard.php")
+ def parse_info(self, user, password, data, req):
+ html = self.load(self.URL + "dashboard.php")
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if m:
premium = True
@@ -33,18 +35,17 @@ class FilejungleCom(Account):
premium = False
validuntil = -1
- return {"premium": premium, "trafficleft": -1, "validuntil": validuntil}
+ return {'premium': premium, 'trafficleft': -1, 'validuntil': validuntil}
- def login(self, user, data, req):
- html = req.load(self.URL + "login.php",
- post={"loginUserName": user,
- "loginUserPassword": data['password'],
- "loginFormSubmit": "Login",
- "recaptcha_challenge_field": "",
- "recaptcha_response_field": "",
- "recaptcha_shortencode_field": ""},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load(urlparse.urljoin(self.URL, "login.php"),
+ post={'loginUserName' : user,
+ 'loginUserPassword' : password,
+ 'loginFormSubmit' : "Login",
+ 'recaptcha_challenge_field' : "",
+ 'recaptcha_response_field' : "",
+ 'recaptcha_shortencode_field': ""})
if re.search(self.LOGIN_FAILED_PATTERN, html):
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FileomCom.py b/module/plugins/accounts/FileomCom.py
index 7c743f56a..957f4ef05 100644
--- a/module/plugins/accounts/FileomCom.py
+++ b/module/plugins/accounts/FileomCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class FileomCom(XFSAccount):
__name__ = "FileomCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Fileom.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/FilerNet.py b/module/plugins/accounts/FilerNet.py
index ac5fd11da..674c7a5dd 100644
--- a/module/plugins/accounts/FilerNet.py
+++ b/module/plugins/accounts/FilerNet.py
@@ -3,57 +3,57 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class FilerNet(Account):
__name__ = "FilerNet"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """Filer.net account plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- TOKEN_PATTERN = r'_csrf_token" value="(.+?)" />'
+ TOKEN_PATTERN = r'name="_csrf_token" value="(.+?)"'
WALID_UNTIL_PATTERN = r'Der Premium-Zugang ist gÃŒltig bis (.+)\.\s*</td>'
TRAFFIC_PATTERN = r'Traffic</th>\s*<td>([^<]+)</td>'
FREE_PATTERN = r'Account Status</th>\s*<td>\s*Free'
- def loadAccountInfo(self, user, req):
- html = req.load("https://filer.net/profile")
+ def parse_info(self, user, password, data, req):
+ html = self.load("https://filer.net/profile")
- # Free user
+ #: Free user
if re.search(self.FREE_PATTERN, html):
- return {"premium": False, "validuntil": None, "trafficleft": None}
+ return {'premium': False, 'validuntil': None, 'trafficleft': None}
until = re.search(self.WALID_UNTIL_PATTERN, html)
traffic = re.search(self.TRAFFIC_PATTERN, html)
if until and traffic:
validuntil = time.mktime(time.strptime(until.group(1), "%d.%m.%Y %H:%M:%S"))
- trafficleft = self.parseTraffic(traffic.group(1))
- return {"premium": True, "validuntil": validuntil, "trafficleft": trafficleft}
+ trafficleft = self.parse_traffic(traffic.group(1))
+ return {'premium': True, 'validuntil': validuntil, 'trafficleft': trafficleft}
else:
- self.logError(_("Unable to retrieve account information"))
- return {"premium": False, "validuntil": None, "trafficleft": None}
+ self.log_error(_("Unable to retrieve account information"))
+ return {'premium': False, 'validuntil': None, 'trafficleft': None}
- def login(self, user, data, req):
- html = req.load("https://filer.net/login")
+ def login(self, user, password, data, req):
+ html = self.load("https://filer.net/login")
token = re.search(self.TOKEN_PATTERN, html).group(1)
- html = req.load("https://filer.net/login_check",
- post={"_username": user,
- "_password": data['password'],
- "_remember_me": "on",
- "_csrf_token": token,
- "_target_path": "https://filer.net/"},
- decode=True)
+ html = self.load("https://filer.net/login_check",
+ post={'_username' : user,
+ '_password' : password,
+ '_remember_me': "on",
+ '_csrf_token' : token,
+ '_target_path': "https://filer.net/"})
if 'Logout' not in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FilerioCom.py b/module/plugins/accounts/FilerioCom.py
index 4c6755293..8a4750036 100644
--- a/module/plugins/accounts/FilerioCom.py
+++ b/module/plugins/accounts/FilerioCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class FilerioCom(XFSAccount):
__name__ = "FilerioCom"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """FileRio.in account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/FilesMailRu.py b/module/plugins/accounts/FilesMailRu.py
index ee309c425..7ed09e731 100644
--- a/module/plugins/accounts/FilesMailRu.py
+++ b/module/plugins/accounts/FilesMailRu.py
@@ -1,31 +1,31 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class FilesMailRu(Account):
__name__ = "FilesMailRu"
__type__ = "account"
- __version__ = "0.11"
+ __version__ = "0.13"
+ __status__ = "testing"
__description__ = """Filesmail.ru account plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def loadAccountInfo(self, user, req):
- return {"validuntil": None, "trafficleft": None}
+ def parse_info(self, user, password, data, req):
+ return {'validuntil': None, 'trafficleft': None}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
user, domain = user.split("@")
- html = req.load("http://swa.mail.ru/cgi-bin/auth",
- post={"Domain": domain,
- "Login": user,
- "Password": data['password'],
- "Page": "http://files.mail.ru/"},
- decode=True)
+ html = self.load("https://swa.mail.ru/cgi-bin/auth",
+ post={'Domain' : domain,
+ 'Login' : user,
+ 'Password': password,
+ 'Page' : "http://files.mail.ru/"})
if "НеверМПе ОЌя пПльзПвателя ОлО парПль" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FileserveCom.py b/module/plugins/accounts/FileserveCom.py
index 5eb6b844c..dabfc1932 100644
--- a/module/plugins/accounts/FileserveCom.py
+++ b/module/plugins/accounts/FileserveCom.py
@@ -2,43 +2,50 @@
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class FileserveCom(Account):
__name__ = "FileserveCom"
__type__ = "account"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__description__ = """Fileserve.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("mkaay", "mkaay@mkaay.de")]
- def loadAccountInfo(self, user, req):
- data = self.getAccountData(user)
+ def parse_info(self, user, password, data, req):
+ data = self.get_data(user)
- html = req.load("http://app.fileserve.com/api/login/", post={"username": user, "password": data['password'],
- "submit": "Submit+Query"})
+ html = self.load("http://app.fileserve.com/api/login/",
+ post={'username': user,
+ 'password': password,
+ 'submit': "Submit+Query"})
res = json_loads(html)
if res['type'] == "premium":
validuntil = time.mktime(time.strptime(res['expireTime'], "%Y-%m-%d %H:%M:%S"))
- return {"trafficleft": res['traffic'], "validuntil": validuntil}
+ return {'trafficleft': res['traffic'], 'validuntil': validuntil}
else:
- return {"premium": False, "trafficleft": None, "validuntil": None}
+ return {'premium': False, 'trafficleft': None, 'validuntil': None}
- def login(self, user, data, req):
- html = req.load("http://app.fileserve.com/api/login/", post={"username": user, "password": data['password'],
- "submit": "Submit+Query"})
+ def login(self, user, password, data, req):
+ html = self.load("http://app.fileserve.com/api/login/",
+ post={'username': user,
+ 'password': password,
+ 'submit' : "Submit+Query"})
res = json_loads(html)
if not res['type']:
- self.wrongPassword()
-
- #login at fileserv html
- req.load("http://www.fileserve.com/login.php",
- post={"loginUserName": user, "loginUserPassword": data['password'], "autoLogin": "checked",
- "loginFormSubmit": "Login"})
+ self.login_fail()
+
+ #: Login at fileserv html
+ self.load("http://www.fileserve.com/login.php",
+ post={'loginUserName' : user,
+ 'loginUserPassword': password,
+ 'autoLogin' : "checked",
+ 'loginFormSubmit' : "Login"})
diff --git a/module/plugins/accounts/FourSharedCom.py b/module/plugins/accounts/FourSharedCom.py
index 2777a142a..a7ec8e2c5 100644
--- a/module/plugins/accounts/FourSharedCom.py
+++ b/module/plugins/accounts/FourSharedCom.py
@@ -1,12 +1,14 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class FourSharedCom(Account):
__name__ = "FourSharedCom"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """FourShared.com account plugin"""
__license__ = "GPLv3"
@@ -14,21 +16,20 @@ class FourSharedCom(Account):
("stickell", "l.stickell@yahoo.it")]
- def loadAccountInfo(self, user, req):
- # Free mode only for now
- return {"premium": False}
+ def parse_info(self, user, password, data, req):
+ #: Free mode only for now
+ return {'premium': False}
- def login(self, user, data, req):
- req.cj.setCookie("4shared.com", "4langcookie", "en")
+ def login(self, user, password, data, req):
+ set_cookie(req.cj, "4shared.com", "4langcookie", "en")
- res = req.load("http://www.4shared.com/web/login",
- post={'login' : user,
- 'password' : data['password'],
- 'remember' : "on",
- '_remember': "on",
- 'returnTo' : "http://www.4shared.com/account/home.jsp"},
- decode=True)
+ res = self.load("https://www.4shared.com/web/login",
+ post={'login' : user,
+ 'password' : password,
+ 'remember' : "on",
+ '_remember': "on",
+ 'returnTo' : "http://www.4shared.com/account/home.jsp"})
if 'Please log in to access your 4shared account' in res:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FreakshareCom.py b/module/plugins/accounts/FreakshareCom.py
index ca3602a2c..a2f66f3b3 100644
--- a/module/plugins/accounts/FreakshareCom.py
+++ b/module/plugins/accounts/FreakshareCom.py
@@ -3,25 +3,26 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class FreakshareCom(Account):
__name__ = "FreakshareCom"
__type__ = "account"
- __version__ = "0.13"
+ __version__ = "0.15"
+ __status__ = "testing"
__description__ = """Freakshare.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
premium = False
validuntil = None
trafficleft = None
- html = req.load("http://freakshare.com/")
+ html = self.load("http://freakshare.com/")
try:
m = re.search(r'ltig bis:</td>\s*<td><b>([\d.:-]+)</b></td>', html, re.M)
@@ -32,20 +33,21 @@ class FreakshareCom(Account):
try:
m = re.search(r'Traffic verbleibend:</td>\s*<td>([^<]+)', html, re.M)
- trafficleft = self.parseTraffic(m.group(1))
+ trafficleft = self.parse_traffic(m.group(1))
except Exception:
pass
- return {"premium": premium, "validuntil": validuntil, "trafficleft": trafficleft}
+ return {'premium': premium, 'validuntil': validuntil, 'trafficleft': trafficleft}
- def login(self, user, data, req):
- req.load("http://freakshare.com/index.php?language=EN")
+ def login(self, user, password, data, req):
+ self.load("http://freakshare.com/index.php?language=EN")
- html = req.load("http://freakshare.com/login.html",
- post={"submit": "Login", "user": user, "pass": data['password']},
- decode=True)
+ html = self.load("https://freakshare.com/login.html",
+ post={'submit': "Login",
+ 'user' : user,
+ 'pass' : password})
if ">Wrong Username or Password" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/FreeWayMe.py b/module/plugins/accounts/FreeWayMe.py
index 14b9f1e9a..0c315873f 100644
--- a/module/plugins/accounts/FreeWayMe.py
+++ b/module/plugins/accounts/FreeWayMe.py
@@ -1,52 +1,53 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class FreeWayMe(Account):
__name__ = "FreeWayMe"
__type__ = "account"
- __version__ = "0.13"
+ __version__ = "0.16"
+ __status__ = "testing"
__description__ = """FreeWayMe account plugin"""
__license__ = "GPLv3"
__authors__ = [("Nicolas Giese", "james@free-way.me")]
- def loadAccountInfo(self, user, req):
- status = self.getAccountStatus(user, req)
+ def parse_info(self, user, password, data, req):
+ status = self.get_account_status(user, password, req)
- self.logDebug(status)
+ self.log_debug(status)
- account_info = {"validuntil": -1, "premium": False}
+ account_info = {'validuntil': -1, 'premium': False}
if status['premium'] == "Free":
- account_info['trafficleft'] = self.parseTraffic(status['guthaben'] + "MB")
+ account_info['trafficleft'] = self.parse_traffic(status['guthaben'] + "MB")
elif status['premium'] == "Spender":
account_info['trafficleft'] = -1
elif status['premium'] == "Flatrate":
- account_info = {"validuntil": float(status['Flatrate']),
- "trafficleft": -1,
- "premium": True}
+ account_info = {'validuntil' : float(status['Flatrate']),
+ 'trafficleft': -1,
+ 'premium' : True}
return account_info
- def login(self, user, data, req):
- status = self.getAccountStatus(user, req)
+ def login(self, user, password, data, req):
+ status = self.get_account_status(user, password, req)
- # Check if user and password are valid
+ #: Check if user and password are valid
if not status:
- self.wrongPassword()
+ self.login_fail()
- def getAccountStatus(self, user, req):
- answer = req.load("https://www.free-way.me/ajax/jd.php",
- get={"id": 4, "user": user, "pass": self.getAccountData(user)['password']})
+ def get_account_status(self, user, password, req):
+ answer = self.load("http://www.free-way.bz/ajax/jd.php", #@TODO: Revert to `https` in 0.4.10
+ get={'id': 4, 'user': user, 'pass': password})
- self.logDebug("Login: %s" % answer)
+ self.log_debug("Login: %s" % answer)
if answer == "Invalid login":
- self.wrongPassword()
+ self.login_fail()
return json_loads(answer)
diff --git a/module/plugins/accounts/FshareVn.py b/module/plugins/accounts/FshareVn.py
index 7fcf88f20..bc8ced5e2 100644
--- a/module/plugins/accounts/FshareVn.py
+++ b/module/plugins/accounts/FshareVn.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class FshareVn(Account):
__name__ = "FshareVn"
__type__ = "account"
- __version__ = "0.09"
+ __version__ = "0.11"
+ __status__ = "testing"
__description__ = """Fshare.vn account plugin"""
__license__ = "GPLv3"
@@ -23,40 +24,38 @@ class FshareVn(Account):
DIRECT_DOWNLOAD_PATTERN = ur'<input type="checkbox"\s*([^=>]*)[^>]*/>Kích hoạt download trực tiếp</dt>'
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.fshare.vn/account_info.php", decode=True)
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://www.fshare.vn/account_info.php")
if re.search(self.LIFETIME_PATTERN, html):
- self.logDebug("Lifetime membership detected")
- trafficleft = self.getTrafficLeft()
- return {"validuntil": -1, "trafficleft": trafficleft, "premium": True}
+ self.log_debug("Lifetime membership detected")
+ trafficleft = self.get_traffic_left()
+ return {'validuntil': -1, 'trafficleft': trafficleft, 'premium': True}
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
premium = True
validuntil = time.mktime(time.strptime(m.group(1), '%I:%M:%S %p %d-%m-%Y'))
- trafficleft = self.getTrafficLeft()
+ trafficleft = self.get_traffic_left()
else:
premium = False
validuntil = None
trafficleft = None
- return {"validuntil": validuntil, "trafficleft": trafficleft, "premium": premium}
+ return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- html = req.load("https://www.fshare.vn/login.php",
- post={'LoginForm[email]' : user,
- 'LoginForm[password]' : data['password'],
- 'LoginForm[rememberMe]': 1,
- 'yt0' : "Login"},
- referer=True,
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://www.fshare.vn/login.php",
+ post={'LoginForm[email]' : user,
+ 'LoginForm[password]' : password,
+ 'LoginForm[rememberMe]': 1,
+ 'yt0' : "Login"})
if not re.search(r'<img\s+alt="VIP"', html):
- self.wrongPassword()
+ self.login_fail()
- def getTrafficLeft(self):
+ def get_traffic_left(self):
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
- return self.parseTraffic(m.group(1) + m.group(2)) if m else 0
+ return self.parse_traffic(m.group(1) + m.group(2)) if m else 0
diff --git a/module/plugins/accounts/Ftp.py b/module/plugins/accounts/Ftp.py
index f978d2fa0..2d35ab7bb 100644
--- a/module/plugins/accounts/Ftp.py
+++ b/module/plugins/accounts/Ftp.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class Ftp(Account):
__name__ = "Ftp"
__type__ = "account"
- __version__ = "0.01"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Ftp dummy account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/HellshareCz.py b/module/plugins/accounts/HellshareCz.py
index e559b28e1..55daa8c2d 100644
--- a/module/plugins/accounts/HellshareCz.py
+++ b/module/plugins/accounts/HellshareCz.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class HellshareCz(Account):
__name__ = "HellshareCz"
__type__ = "account"
- __version__ = "0.16"
+ __version__ = "0.18"
+ __status__ = "testing"
__description__ = """Hellshare.cz account plugin"""
__license__ = "GPLv3"
@@ -19,9 +20,9 @@ class HellshareCz(Account):
CREDIT_LEFT_PATTERN = r'<div class="credit-link">\s*<table>\s*<tr>\s*<th>(\d+|\d\d\.\d\d\.)</th>'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
self.relogin(user)
- html = req.load("http://www.hellshare.com/")
+ html = self.load("http://www.hellshare.com/")
m = re.search(self.CREDIT_LEFT_PATTERN, html)
if m is None:
@@ -33,47 +34,47 @@ class HellshareCz(Account):
premium = True
try:
if "." in credit:
- #Time-based account
+ #: Time-based account
vt = [int(x) for x in credit.split('.')[:2]]
lt = time.localtime()
- year = lt.tm_year + int(vt[1] < lt.tm_mon or (vt[1] == lt.tm_mon and vt[0] < lt.tm_mday))
+ year = lt.tm_year + int(vt[1] < lt.tm_mon or (vt[1] is lt.tm_mon and vt[0] < lt.tm_mday))
validuntil = time.mktime(time.strptime("%s%d 23:59:59" % (credit, year), "%d.%m.%Y %H:%M:%S"))
trafficleft = -1
else:
- #Traffic-based account
- trafficleft = self.parseTraffic(credit + "MB")
+ #: Traffic-based account
+ trafficleft = self.parse_traffic(credit + "MB")
validuntil = -1
except Exception, e:
- self.logError(_("Unable to parse credit info"), e)
+ self.log_error(_("Unable to parse credit info"), e)
validuntil = -1
trafficleft = -1
- return {"validuntil": validuntil, "trafficleft": trafficleft, "premium": premium}
+ return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- html = req.load('http://www.hellshare.com/', decode=True)
+ def login(self, user, password, data, req):
+ html = self.load('http://www.hellshare.com/')
if req.lastEffectiveURL != 'http://www.hellshare.com/':
- #Switch to English
- self.logDebug("Switch lang - URL: %s" % req.lastEffectiveURL)
+ #: Switch to English
+ self.log_debug("Switch lang - URL: %s" % req.lastEffectiveURL)
- json = req.load("%s?do=locRouter-show" % req.lastEffectiveURL)
+ json = self.load("%s?do=locRouter-show" % req.lastEffectiveURL)
hash = re.search(r"(\-\-[0-9a-f]+\-)", json).group(1)
- self.logDebug("Switch lang - HASH: %s" % hash)
+ self.log_debug("Switch lang - HASH: %s" % hash)
- html = req.load('http://www.hellshare.com/%s/' % hash, decode=True)
+ html = self.load('http://www.hellshare.com/%s/' % hash)
if re.search(self.CREDIT_LEFT_PATTERN, html):
- self.logDebug("Already logged in")
+ self.log_debug("Already logged in")
return
- html = req.load('http://www.hellshare.com/login?do=loginForm-submit',
- post={"login": "Log in",
- "password": data['password'],
- "username": user,
- "perm_login": "on"},
- decode=True)
+ html = self.load("https://www.hellshare.com/login",
+ get={'do': "loginForm-submit"},
+ post={'login' : "Log in",
+ 'password' : password,
+ 'username' : user,
+ 'perm_login': "on"})
if "<p>You input a wrong user name or wrong password</p>" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/HighWayMe.py b/module/plugins/accounts/HighWayMe.py
new file mode 100644
index 000000000..ff90ec2d2
--- /dev/null
+++ b/module/plugins/accounts/HighWayMe.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+from module.common.json_layer import json_loads
+from module.plugins.internal.Account import Account
+
+
+class HighWayMe(Account):
+ __name__ = "HighWayMe.py"
+ __type__ = "account"
+ __version__ = "0.04"
+ __status__ = "testing"
+
+ __description__ = """High-Way.me account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("EvolutionClip", "evolutionclip@live.de")]
+
+
+ def parse_info(self, user, password, data, req):
+ premium = False
+ validuntil = -1
+ trafficleft = None
+
+ json_data = self.load('https://high-way.me/api.php?user')
+
+ self.log_debug("JSON data: %s" % json_data)
+
+ json_data = json_loads(json_data)
+
+ if 'premium' in json_data['user'] and json_data['user']['premium']:
+ premium = True
+
+ if 'premium_bis' in json_data['user'] and json_data['user']['premium_bis']:
+ validuntil = float(json_data['user']['premium_bis'])
+
+ if 'premium_traffic' in json_data['user'] and json_data['user']['premium_traffic']:
+ trafficleft = float(json_data['user']['premium_traffic']) / 1024 #@TODO: Remove `/ 1024` in 0.4.10
+
+ return {'premium' : premium,
+ 'validuntil' : validuntil,
+ 'trafficleft': trafficleft}
+
+
+ def login(self, user, password, data, req):
+ html = self.load("https://high-way.me/api.php?login",
+ post={'login': '1',
+ 'user': user,
+ 'pass': password})
+
+ if 'UserOrPassInvalid' in html:
+ self.login_fail()
diff --git a/module/plugins/accounts/Http.py b/module/plugins/accounts/Http.py
index 07e46eb07..dcab156ee 100644
--- a/module/plugins/accounts/Http.py
+++ b/module/plugins/accounts/Http.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class Http(Account):
__name__ = "Http"
__type__ = "account"
- __version__ = "0.01"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Http dummy account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/HugefilesNet.py b/module/plugins/accounts/HugefilesNet.py
index 5da3bbc37..fa64945a3 100644
--- a/module/plugins/accounts/HugefilesNet.py
+++ b/module/plugins/accounts/HugefilesNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class HugefilesNet(XFSAccount):
__name__ = "HugefilesNet"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Hugefiles.net account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/HundredEightyUploadCom.py b/module/plugins/accounts/HundredEightyUploadCom.py
index 319a3feee..a8527d62c 100644
--- a/module/plugins/accounts/HundredEightyUploadCom.py
+++ b/module/plugins/accounts/HundredEightyUploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class HundredEightyUploadCom(XFSAccount):
__name__ = "HundredEightyUploadCom"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """180upload.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/JunkyvideoCom.py b/module/plugins/accounts/JunkyvideoCom.py
index 8275ff176..5fcefda36 100644
--- a/module/plugins/accounts/JunkyvideoCom.py
+++ b/module/plugins/accounts/JunkyvideoCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class JunkyvideoCom(XFSAccount):
__name__ = "JunkyvideoCom"
__type__ = "account"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__description__ = """Junkyvideo.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/JunocloudMe.py b/module/plugins/accounts/JunocloudMe.py
index b0fc160f3..791835dfe 100644
--- a/module/plugins/accounts/JunocloudMe.py
+++ b/module/plugins/accounts/JunocloudMe.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class JunocloudMe(XFSAccount):
__name__ = "JunocloudMe"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Junocloud.me account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/Keep2ShareCc.py b/module/plugins/accounts/Keep2ShareCc.py
index d2ba1d237..014d43a69 100644
--- a/module/plugins/accounts/Keep2ShareCc.py
+++ b/module/plugins/accounts/Keep2ShareCc.py
@@ -3,13 +3,15 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class Keep2ShareCc(Account):
__name__ = "Keep2ShareCc"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.08"
+ __status__ = "testing"
__description__ = """Keep2Share.cc account plugin"""
__license__ = "GPLv3"
@@ -23,17 +25,17 @@ class Keep2ShareCc(Account):
LOGIN_FAIL_PATTERN = r'Please fix the following input errors'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = -1
premium = False
- html = req.load("http://keep2share.cc/site/profile.html", decode=True)
+ html = self.load("http://keep2share.cc/site/profile.html")
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
expiredate = m.group(1).strip()
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
if expiredate == "LifeTime":
premium = True
@@ -43,7 +45,7 @@ class Keep2ShareCc(Account):
validuntil = time.mktime(time.strptime(expiredate, "%Y.%m.%d"))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
premium = True if validuntil > time.mktime(time.gmtime()) else False
@@ -51,23 +53,22 @@ class Keep2ShareCc(Account):
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if m:
try:
- trafficleft = self.parseTraffic(m.group(1))
+ trafficleft = self.parse_traffic(m.group(1))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- req.cj.setCookie("keep2share.cc", "lang", "en")
+ def login(self, user, password, data, req):
+ set_cookie(req.cj, "keep2share.cc", "lang", "en")
- html = req.load("http://keep2share.cc/login.html",
- post={'LoginForm[username]' : user,
- 'LoginForm[password]' : data['password'],
- 'LoginForm[rememberMe]': 1,
- 'yt0' : ""},
- decode=True)
+ html = self.load("https://keep2share.cc/login.html",
+ post={'LoginForm[username]' : user,
+ 'LoginForm[password]' : password,
+ 'LoginForm[rememberMe]': 1,
+ 'yt0' : ""})
if re.search(self.LOGIN_FAIL_PATTERN, html):
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/LetitbitNet.py b/module/plugins/accounts/LetitbitNet.py
index 7f973d2d3..1fc9b76ba 100644
--- a/module/plugins/accounts/LetitbitNet.py
+++ b/module/plugins/accounts/LetitbitNet.py
@@ -1,34 +1,35 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
# from module.common.json_layer import json_loads, json_dumps
class LetitbitNet(Account):
__name__ = "LetitbitNet"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Letitbit.net account plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
## DISABLED BECAUSE IT GET 'key exausted' EVEN IF VALID ##
- # api_key = self.getAccountData(user)['password']
- # json_data = [api_key, ['key/info']]
- # api_rep = req.load('http://api.letitbit.net/json', post={'r': json_dumps(json_data)})
- # self.logDebug("API Key Info: " + api_rep)
+ # json_data = [password, ['key/info']]
+ # api_rep = self.load("http://api.letitbit.net/json",
+ # post={'r': json_dumps(json_data)})
+ # self.log_debug("API Key Info: " + api_rep)
# api_rep = json_loads(api_rep)
#
- # if api_rep['status'] == 'FAIL':
- # self.logWarning(api_rep['data'])
+ # if api_rep['status'] == "FAIL":
+ # self.log_warning(api_rep['data'])
# return {'valid': False, 'premium': False}
- return {"premium": True}
+ return {'premium': True}
- def login(self, user, data, req):
- # API_KEY is the username and the PREMIUM_KEY is the password
- self.logInfo(_("You must use your API KEY as username and the PREMIUM KEY as password"))
+ def login(self, user, password, data, req):
+ #: API_KEY is the username and the PREMIUM_KEY is the password
+ self.log_info(_("You must use your API KEY as username and the PREMIUM KEY as password"))
diff --git a/module/plugins/accounts/LinestorageCom.py b/module/plugins/accounts/LinestorageCom.py
index a48d5beb9..87dd2a1d3 100644
--- a/module/plugins/accounts/LinestorageCom.py
+++ b/module/plugins/accounts/LinestorageCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class LinestorageCom(XFSAccount):
__name__ = "LinestorageCom"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Linestorage.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/LinksnappyCom.py b/module/plugins/accounts/LinksnappyCom.py
index 34571d374..00ae64b44 100644
--- a/module/plugins/accounts/LinksnappyCom.py
+++ b/module/plugins/accounts/LinksnappyCom.py
@@ -2,38 +2,42 @@
import hashlib
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class LinksnappyCom(Account):
__name__ = "LinksnappyCom"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.07"
+ __status__ = "testing"
+
__description__ = """Linksnappy.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- def loadAccountInfo(self, user, req):
- data = self.getAccountData(user)
- r = req.load('http://gen.linksnappy.com/lseAPI.php',
- get={'act': 'USERDETAILS', 'username': user, 'password': hashlib.md5(data['password']).hexdigest()})
+ def parse_info(self, user, password, data, req):
+ data = self.get_data(user)
+ r = self.load('http://gen.linksnappy.com/lseAPI.php',
+ get={'act' : 'USERDETAILS',
+ 'username': user,
+ 'password': hashlib.md5(password).hexdigest()})
- self.logDebug("JSON data: " + r)
+ self.log_debug("JSON data: " + r)
j = json_loads(r)
if j['error']:
- return {"premium": False}
+ return {'premium': False}
validuntil = j['return']['expire']
- if validuntil == 'lifetime':
+ if validuntil == "lifetime":
validuntil = -1
- elif validuntil == 'expired':
- return {"premium": False}
+ elif validuntil == "expired":
+ return {'premium': False}
else:
validuntil = float(validuntil)
@@ -41,17 +45,18 @@ class LinksnappyCom(Account):
if 'trafficleft' not in j['return'] or isinstance(j['return']['trafficleft'], str):
trafficleft = -1
else:
- trafficleft = self.parseTraffic("%d MB" % j['return']['trafficleft'])
+ trafficleft = self.parse_traffic("%d MB" % j['return']['trafficleft'])
- return {"premium": True, "validuntil": validuntil, "trafficleft": trafficleft}
+ return {'premium' : True ,
+ 'validuntil' : validuntil ,
+ 'trafficleft': trafficleft}
- def login(self, user, data, req):
- r = req.load("http://gen.linksnappy.com/lseAPI.php",
- get={'act' : 'USERDETAILS',
- 'username': user,
- 'password': hashlib.md5(data['password']).hexdigest()},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://gen.linksnappy.com/lseAPI.php",
+ get={'act' : 'USERDETAILS',
+ 'username': user,
+ 'password': hashlib.md5(password).hexdigest()})
- if 'Invalid Account Details' in r:
- self.wrongPassword()
+ if "Invalid Account Details" in html:
+ self.login_fail()
diff --git a/module/plugins/accounts/MegaDebridEu.py b/module/plugins/accounts/MegaDebridEu.py
index a082b97af..d7a04491d 100644
--- a/module/plugins/accounts/MegaDebridEu.py
+++ b/module/plugins/accounts/MegaDebridEu.py
@@ -1,39 +1,44 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class MegaDebridEu(Account):
__name__ = "MegaDebridEu"
__type__ = "account"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
- __description__ = """mega-debrid.eu account plugin"""
+ __description__ = """Mega-debrid.eu account plugin"""
__license__ = "GPLv3"
__authors__ = [("D.Ducatel", "dducatel@je-geek.fr")]
- # Define the base URL of MegaDebrid api
+ #: Define the base URL of MegaDebrid api
API_URL = "https://www.mega-debrid.eu/api.php"
- def loadAccountInfo(self, user, req):
- data = self.getAccountData(user)
- jsonResponse = req.load(self.API_URL,
- get={'action': 'connectUser', 'login': user, 'password': data['password']})
+ def parse_info(self, user, password, data, req):
+ data = self.get_data(user)
+ jsonResponse = self.load(self.API_URL,
+ get={'action' : 'connectUser',
+ 'login' : user,
+ 'password': password})
res = json_loads(jsonResponse)
if res['response_code'] == "ok":
- return {"premium": True, "validuntil": float(res['vip_end']), "status": True}
+ return {'premium': True, 'validuntil': float(res['vip_end']), 'status': True}
else:
- self.logError(res)
- return {"status": False, "premium": False}
+ self.log_error(res)
+ return {'status': False, 'premium': False}
- def login(self, user, data, req):
- jsonResponse = req.load(self.API_URL,
- get={'action': 'connectUser', 'login': user, 'password': data['password']})
+ def login(self, user, password, data, req):
+ jsonResponse = self.load(self.API_URL,
+ get={'action' : 'connectUser',
+ 'login' : user,
+ 'password': password})
res = json_loads(jsonResponse)
if res['response_code'] != "ok":
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/MegaRapidCz.py b/module/plugins/accounts/MegaRapidCz.py
index 262d5a818..ce2d78994 100644
--- a/module/plugins/accounts/MegaRapidCz.py
+++ b/module/plugins/accounts/MegaRapidCz.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class MegaRapidCz(Account):
__name__ = "MegaRapidCz"
__type__ = "account"
- __version__ = "0.35"
+ __version__ = "0.37"
+ __status__ = "testing"
__description__ = """MegaRapid.cz account plugin"""
__license__ = "GPLv3"
@@ -24,37 +25,37 @@ class MegaRapidCz(Account):
TRAFFIC_LEFT_PATTERN = r'<tr><td>Kredit</td><td>(.*?) GiB'
- def loadAccountInfo(self, user, req):
- htmll = req.load("http://megarapid.cz/mujucet/", decode=True)
+ def parse_info(self, user, password, data, req):
+ htmll = self.load("http://megarapid.cz/mujucet/")
m = re.search(self.LIMITDL_PATTERN, htmll)
if m:
- data = self.getAccountData(user)
+ data = self.get_data(user)
data['options']['limitDL'] = [int(m.group(1))]
m = re.search(self.VALID_UNTIL_PATTERN, htmll)
if m:
validuntil = time.mktime(time.strptime(m.group(1), "%d.%m.%Y - %H:%M"))
- return {"premium": True, "trafficleft": -1, "validuntil": validuntil}
+ return {'premium': True, 'trafficleft': -1, 'validuntil': validuntil}
m = re.search(self.TRAFFIC_LEFT_PATTERN, htmll)
if m:
trafficleft = float(m.group(1)) * (1 << 20)
- return {"premium": True, "trafficleft": trafficleft, "validuntil": -1}
+ return {'premium': True, 'trafficleft': trafficleft, 'validuntil': -1}
- return {"premium": False, "trafficleft": None, "validuntil": None}
+ return {'premium': False, 'trafficleft': None, 'validuntil': None}
- def login(self, user, data, req):
- html = req.load("http://megarapid.cz/prihlaseni/", decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("http://megarapid.cz/prihlaseni/")
if "Heslo:" in html:
start = html.index('id="inp_hash" name="hash" value="')
html = html[start + 33:]
hashes = html[0:32]
- html = req.load("http://megarapid.cz/prihlaseni/",
- post={"hash": hashes,
- "login": user,
- "pass1": data['password'],
- "remember": 0,
- "sbmt": u"Přihlásit"})
+ html = self.load("https://megarapid.cz/prihlaseni/",
+ post={'hash' : hashes,
+ 'login' : user,
+ 'pass1' : password,
+ 'remember': 1,
+ 'sbmt' : u"Přihlásit"})
diff --git a/module/plugins/accounts/MegaRapidoNet.py b/module/plugins/accounts/MegaRapidoNet.py
index d061d02bc..08cf1f535 100644
--- a/module/plugins/accounts/MegaRapidoNet.py
+++ b/module/plugins/accounts/MegaRapidoNet.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class MegaRapidoNet(Account):
__name__ = "MegaRapidoNet"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """MegaRapido.net account plugin"""
__license__ = "GPLv3"
@@ -20,16 +21,16 @@ class MegaRapidoNet(Account):
USER_ID_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']checkbox_compartilhar["\'].*?>.*?<\s*?input[^>]*?name\s*?=\s*?["\']usar["\'].*?>.*?<\s*?input[^>]*?name\s*?=\s*?["\']user["\'][^>]*?value\s*?=\s*?["\'](.*?)\s*?["\']'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = None
premium = False
- html = req.load("http://megarapido.net/gerador", decode=True)
+ html = self.load("http://megarapido.net/gerador")
validuntil = re.search(self.VALID_UNTIL_PATTERN, html)
if validuntil:
- #hier weitermachen!!! (mÌssen umbedingt die zeit richtig machen damit! (sollte aber möglich))
+ #: Hier weitermachen!!! (mÌssen umbedingt die zeit richtig machen damit! (sollte aber möglich))
validuntil = time.time() + int(validuntil.group(1)) * 24 * 3600 + int(validuntil.group(2)) * 3600 + int(validuntil.group(3)) * 60 + int(validuntil.group(4))
trafficleft = -1
premium = True
@@ -39,19 +40,19 @@ class MegaRapidoNet(Account):
'premium' : premium}
- def login(self, user, data, req):
- req.load("http://megarapido.net/login")
- req.load("http://megarapido.net/painel_user/ajax/logar.php",
- post={'login': user, 'senha': data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ self.load("http://megarapido.net/login")
+ self.load("http://megarapido.net/painel_user/ajax/logar.php",
+ post={'login': user,
+ 'senha': password})
- html = req.load("http://megarapido.net/gerador")
+ html = self.load("http://megarapido.net/gerador")
if "sair" not in html.lower():
- self.wrongPassword()
+ self.login_fail()
else:
m = re.search(self.USER_ID_PATTERN, html)
if m:
data['uid'] = m.group(1)
else:
- self.fail("Couldn't find the user ID")
+ self.login_fail("Couldn't find the user ID")
diff --git a/module/plugins/accounts/MegasharesCom.py b/module/plugins/accounts/MegasharesCom.py
index 3d7ddbe46..ec43b7fc0 100644
--- a/module/plugins/accounts/MegasharesCom.py
+++ b/module/plugins/accounts/MegasharesCom.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class MegasharesCom(Account):
__name__ = "MegasharesCom"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """Megashares.com account plugin"""
__license__ = "GPLv3"
@@ -19,30 +20,29 @@ class MegasharesCom(Account):
VALID_UNTIL_PATTERN = r'<p class="premium_info_box">Period Ends: (\w{3} \d{1,2}, \d{4})</p>'
- def loadAccountInfo(self, user, req):
- #self.relogin(user)
- html = req.load("http://d01.megashares.com/myms.php", decode=True)
+ def parse_info(self, user, password, data, req):
+ # self.relogin(user)
+ html = self.load("http://d01.megashares.com/myms.php")
premium = False if '>Premium Upgrade<' in html else True
validuntil = trafficleft = -1
try:
timestr = re.search(self.VALID_UNTIL_PATTERN, html).group(1)
- self.logDebug(timestr)
+ self.log_debug(timestr)
validuntil = time.mktime(time.strptime(timestr, "%b %d, %Y"))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
- return {"validuntil": validuntil, "trafficleft": -1, "premium": premium}
+ return {'validuntil': validuntil, 'trafficleft': -1, 'premium': premium}
- def login(self, user, data, req):
- html = req.load('http://d01.megashares.com/myms_login.php',
- post={"httpref" : "",
- "myms_login" : "Login",
- "mymslogin_name": user,
- "mymspassword" : data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load('http://d01.megashares.com/myms_login.php',
+ post={'httpref' : "",
+ 'myms_login' : "Login",
+ 'mymslogin_name': user,
+ 'mymspassword' : password})
if not '<span class="b ml">%s</span>' % user in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/MovReelCom.py b/module/plugins/accounts/MovReelCom.py
index 6128cddc8..090950bf2 100644
--- a/module/plugins/accounts/MovReelCom.py
+++ b/module/plugins/accounts/MovReelCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class MovReelCom(XFSAccount):
__name__ = "MovReelCom"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Movreel.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/MultihostersCom.py b/module/plugins/accounts/MultihostersCom.py
index e98f17b2d..ed04ad3c2 100644
--- a/module/plugins/accounts/MultihostersCom.py
+++ b/module/plugins/accounts/MultihostersCom.py
@@ -6,7 +6,8 @@ from module.plugins.accounts.ZeveraCom import ZeveraCom
class MultihostersCom(ZeveraCom):
__name__ = "MultihostersCom"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """Multihosters.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/MultishareCz.py b/module/plugins/accounts/MultishareCz.py
index 3488e3288..c9e30a93f 100644
--- a/module/plugins/accounts/MultishareCz.py
+++ b/module/plugins/accounts/MultishareCz.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class MultishareCz(Account):
__name__ = "MultishareCz"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """Multishare.cz account plugin"""
__license__ = "GPLv3"
@@ -19,26 +20,25 @@ class MultishareCz(Account):
ACCOUNT_INFO_PATTERN = r'<input type="hidden" id="(u_ID|u_hash)" name=".+?" value="(.+?)">'
- def loadAccountInfo(self, user, req):
- #self.relogin(user)
- html = req.load("http://www.multishare.cz/profil/", decode=True)
+ def parse_info(self, user, password, data, req):
+ # self.relogin(user)
+ html = self.load("http://www.multishare.cz/profil/")
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
- trafficleft = self.parseTraffic(m.group('S') + m.group('U')) if m else 0
+ trafficleft = self.parse_traffic(m.group('S') + m.group('U')) if m else 0
self.premium = True if trafficleft else False
- html = req.load("http://www.multishare.cz/", decode=True)
+ html = self.load("http://www.multishare.cz/")
mms_info = dict(re.findall(self.ACCOUNT_INFO_PATTERN, html))
- return dict(mms_info, **{"validuntil": -1, "trafficleft": trafficleft})
+ return dict(mms_info, **{'validuntil': -1, 'trafficleft': trafficleft})
- def login(self, user, data, req):
- html = req.load('http://www.multishare.cz/html/prihlaseni_process.php',
- post={"akce" : "Přihlásit",
- "heslo": data['password'],
- "jmeno": user},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load('https://www.multishare.cz/html/prihlaseni_process.php',
+ post={'akce' : "Přihlásit",
+ 'heslo': password,
+ 'jmeno': user})
if '<div class="akce-chyba akce">' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/MyfastfileCom.py b/module/plugins/accounts/MyfastfileCom.py
index 9a13e2e42..008b62cc6 100644
--- a/module/plugins/accounts/MyfastfileCom.py
+++ b/module/plugins/accounts/MyfastfileCom.py
@@ -3,35 +3,37 @@
import time
from module.common.json_layer import json_loads
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class MyfastfileCom(Account):
__name__ = "MyfastfileCom"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.06"
+ __status__ = "testing"
__description__ = """Myfastfile.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
if 'days_left' in self.json_data:
validuntil = time.time() + self.json_data['days_left'] * 24 * 60 * 60
- return {"premium": True, "validuntil": validuntil, "trafficleft": -1}
+ return {'premium': True, 'validuntil': validuntil, 'trafficleft': -1}
else:
- self.logError(_("Unable to get account information"))
+ self.log_error(_("Unable to get account information"))
- def login(self, user, data, req):
- # Password to use is the API-Password written in http://myfastfile.com/myaccount
- html = req.load("http://myfastfile.com/api.php",
- get={"user": user, "pass": data['password']})
+ def login(self, user, password, data, req):
+ #: Password to use is the API-Password written in http://myfastfile.com/myaccount
+ html = self.load("https://myfastfile.com/api.php",
+ get={'user': user,
+ 'pass': password})
- self.logDebug("JSON data: " + html)
+ self.log_debug("JSON data: " + html)
self.json_data = json_loads(html)
if self.json_data['status'] != 'ok':
- self.logError(_('Invalid login. The password to use is the API-Password you find in your "My Account" page'))
- self.wrongPassword()
+ self.log_error(_('Invalid login. The password to use is the API-Password you find in your "My Account" page'))
+ self.login_fail()
diff --git a/module/plugins/accounts/NitroflareCom.py b/module/plugins/accounts/NitroflareCom.py
new file mode 100644
index 000000000..b7edcca32
--- /dev/null
+++ b/module/plugins/accounts/NitroflareCom.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+import re
+import time
+
+from module.plugins.internal.Account import Account
+
+
+class NitroflareCom(Account):
+ __name__ = "NitroflareCom"
+ __type__ = "account"
+ __version__ = "0.06"
+ __status__ = "testing"
+
+ __description__ = """Nitroflare.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com" )]
+
+
+ VALID_UNTIL_PATTERN = r'>Time Left</label><strong>(.+?)</'
+ TRAFFIC_LEFT_PATTERN = r'>Daily Limit</label><strong>([\d.,]+)'
+ LOGIN_FAIL_PATTERN = r'<ul class="errors">\s*<li>'
+
+ TOKEN_PATTERN = r'name="token" value="(.+?)"'
+
+
+ def parse_info(self, user, password, data, req):
+ validuntil = -1
+ trafficleft = None
+ premium = False
+
+ html = self.load("https://nitroflare.com/member",
+ get={'s': "premium"})
+
+ m = re.search(self.VALID_UNTIL_PATTERN, html)
+ if m:
+ expiredate = m.group(1).strip()
+ self.log_debug("Time Left: " + expiredate)
+
+ try:
+ validuntil = sum(int(v) * {'day': 24 * 3600, 'hour': 3600, 'minute': 60}[u.lower()] for v, u in
+ re.findall(r'(\d+)\s*(day|hour|minute)', expiredate, re.I))
+ except Exception, e:
+ self.log_error(e)
+
+ else:
+ self.log_debug("Valid until: %s" % validuntil)
+
+ if validuntil:
+ validuntil += time.time()
+ premium = True
+ else:
+ validuntil = -1
+
+ m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
+ if m:
+ try:
+ trafficleft = self.parse_traffic(str(max(0, 50 - float(m.group(1)))) + " GB")
+
+ except Exception, e:
+ self.log_error(e)
+ else:
+ self.log_debug("TRAFFIC_LEFT_PATTERN not found")
+
+ return {'validuntil' : validuntil,
+ 'trafficleft': trafficleft,
+ 'premium' : premium}
+
+
+ def login(self, user, password, data, req):
+ html = self.load("https://nitroflare.com/login")
+
+ token = re.search(self.TOKEN_PATTERN, html).group(1)
+
+ html = self.load("https://nitroflare.com/login",
+ post={'login' : "",
+ 'email' : user,
+ 'password': password,
+ 'token' : token})
+
+ if re.search(self.LOGIN_FAIL_PATTERN, html):
+ self.login_fail()
diff --git a/module/plugins/accounts/NoPremiumPl.py b/module/plugins/accounts/NoPremiumPl.py
index 7e3f757d3..e9dad7647 100644
--- a/module/plugins/accounts/NoPremiumPl.py
+++ b/module/plugins/accounts/NoPremiumPl.py
@@ -4,78 +4,80 @@ import datetime
import hashlib
import time
-from module.plugins.Account import Account
-from module.common.json_layer import json_loads as loads
+from module.common.json_layer import json_loads
+from module.plugins.internal.Account import Account
class NoPremiumPl(Account):
- __name__ = "NoPremiumPl"
- __version__ = "0.01"
- __type__ = "account"
+ __name__ = "NoPremiumPl"
+ __type__ = "account"
+ __version__ = "0.03"
+ __status__ = "testing"
+
__description__ = "NoPremium.pl account plugin"
- __license__ = "GPLv3"
- __authors__ = [("goddie", "dev@nopremium.pl")]
+ __license__ = "GPLv3"
+ __authors__ = [("goddie", "dev@nopremium.pl")]
- _api_url = "http://crypt.nopremium.pl"
- _api_query = {
- "site": "nopremium",
- "username": "",
- "password": "",
- "output": "json",
- "loc": "1",
- "info": "1"
- }
+ API_URL = "http://crypt.nopremium.pl"
+ API_QUERY = {'site' : "nopremium",
+ 'username': "" ,
+ 'password': "" ,
+ 'output' : "json" ,
+ 'loc' : "1" ,
+ 'info' : "1" }
_req = None
_usr = None
_pwd = None
- def loadAccountInfo(self, name, req):
+
+ def parse_info(self, name, req):
self._req = req
try:
- result = loads(self.runAuthQuery())
+ result = json_loads(self.run_auth_query())
except Exception:
- # todo: return or let it be thrown?
+ #@TODO: return or let it be thrown?
return
premium = False
valid_untill = -1
- if "expire" in result.keys() and result["expire"]:
+ if "expire" in result.keys() and result['expire']:
premium = True
- valid_untill = time.mktime(datetime.datetime.fromtimestamp(int(result["expire"])).timetuple())
- traffic_left = result["balance"] * 1024
+ valid_untill = time.mktime(datetime.datetime.fromtimestamp(int(result['expire'])).timetuple())
+
+ traffic_left = result['balance'] * 1024
- return ({
- "validuntil": valid_untill,
- "trafficleft": traffic_left,
- "premium": premium
- })
+ return {'validuntil' : valid_untill,
+ 'trafficleft': traffic_left,
+ 'premium' : premium }
- def login(self, user, data, req):
+
+ def login(self, user, password, data, req):
self._usr = user
- self._pwd = hashlib.sha1(hashlib.md5(data["password"]).hexdigest()).hexdigest()
+ self._pwd = hashlib.sha1(hashlib.md5(password).hexdigest()).hexdigest()
self._req = req
try:
- response = loads(self.runAuthQuery())
+ response = json_loads(self.run_auth_query())
except Exception:
- self.wrongPassword()
+ self.login_fail()
if "errno" in response.keys():
- self.wrongPassword()
+ self.login_fail()
+
data['usr'] = self._usr
data['pwd'] = self._pwd
- def createAuthQuery(self):
- query = self._api_query
- query["username"] = self._usr
- query["password"] = self._pwd
+ def create_auth_query(self):
+ query = self.API_QUERY
+ query['username'] = self._usr
+ query['password'] = self._pwd
return query
- def runAuthQuery(self):
- data = self._req.load(self._api_url, post=self.createAuthQuery())
- return data \ No newline at end of file
+ def run_auth_query(self):
+ return self.load(self.API_URL,
+ post=self.create_auth_query())
diff --git a/module/plugins/accounts/NosuploadCom.py b/module/plugins/accounts/NosuploadCom.py
index e523ee2f4..5febc8d66 100644
--- a/module/plugins/accounts/NosuploadCom.py
+++ b/module/plugins/accounts/NosuploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class NosuploadCom(XFSAccount):
__name__ = "NosuploadCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Nosupload.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/NovafileCom.py b/module/plugins/accounts/NovafileCom.py
index ab61bf0fc..524c01087 100644
--- a/module/plugins/accounts/NovafileCom.py
+++ b/module/plugins/accounts/NovafileCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class NovafileCom(XFSAccount):
__name__ = "NovafileCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Novafile.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/NowVideoSx.py b/module/plugins/accounts/NowVideoSx.py
index 2f7b033bd..73bb383be 100644
--- a/module/plugins/accounts/NowVideoSx.py
+++ b/module/plugins/accounts/NowVideoSx.py
@@ -3,13 +3,14 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class NowVideoSx(Account):
__name__ = "NowVideoSx"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """NowVideo.at account plugin"""
__license__ = "GPLv3"
@@ -19,23 +20,23 @@ class NowVideoSx(Account):
VALID_UNTIL_PATTERN = r'>Your premium membership expires on: (.+?)<'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = -1
premium = None
- html = req.load("http://www.nowvideo.sx/premium.php")
+ html = self.load("http://www.nowvideo.sx/premium.php")
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
expiredate = m.group(1).strip()
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
try:
validuntil = time.mktime(time.strptime(expiredate, "%Y-%b-%d"))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
if validuntil > time.mktime(time.gmtime()):
@@ -44,13 +45,13 @@ class NowVideoSx(Account):
premium = False
validuntil = -1
- return {"validuntil": validuntil, "trafficleft": trafficleft, "premium": premium}
+ return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- html = req.load("http://www.nowvideo.sx/login.php",
- post={'user': user, 'pass': data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("http://www.nowvideo.sx/login.php",
+ post={'user': user,
+ 'pass': password})
if re.search(r'>Log In<', html):
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/OboomCom.py b/module/plugins/accounts/OboomCom.py
index 020a45ba7..380368b70 100644
--- a/module/plugins/accounts/OboomCom.py
+++ b/module/plugins/accounts/OboomCom.py
@@ -17,37 +17,40 @@ except ImportError:
return b2a_hex(pbkdf2(self.passphrase, self.salt, self.iterations, octets))
from module.common.json_layer import json_loads
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class OboomCom(Account):
__name__ = "OboomCom"
__type__ = "account"
- __version__ = "0.24"
+ __version__ = "0.27"
+ __status__ = "testing"
__description__ = """Oboom.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("stanley", "stanley.foerster@gmail.com")]
- def loadAccountData(self, user, req):
- passwd = self.getAccountData(user)['password']
+ def load_account_data(self, user, req):
+ passwd = self.get_info(user)['login']['password']
salt = passwd[::-1]
pbkdf2 = PBKDF2(passwd, salt, 1000).hexread(16)
- result = json_loads(req.load("https://www.oboom.com/1/login", get={"auth": user, "pass": pbkdf2}))
+ result = json_loads(self.load("http://www.oboom.com/1/login", #@TODO: Revert to `https` in 0.4.10
+ get={'auth': user,
+ 'pass': pbkdf2}))
if not result[0] == 200:
- self.logWarning(_("Failed to log in: %s") % result[1])
- self.wrongPassword()
+ self.log_warning(_("Failed to log in: %s") % result[1])
+ self.login_fail()
return result[1]
- def loadAccountInfo(self, name, req):
- accountData = self.loadAccountData(name, req)
+ def parse_info(self, name, req):
+ account_data = self.load_account_data(name, req)
- userData = accountData['user']
+ userData = account_data['user']
if userData['premium'] == "null":
premium = False
@@ -64,7 +67,7 @@ class OboomCom(Account):
trafficLeft = traffic['current'] / 1024 #@TODO: Remove `/ 1024` in 0.4.10
maxTraffic = traffic['max'] / 1024 #@TODO: Remove `/ 1024` in 0.4.10
- session = accountData['session']
+ session = account_data['session']
return {'premium' : premium,
'validuntil' : validUntil,
@@ -73,5 +76,5 @@ class OboomCom(Account):
'session' : session}
- def login(self, user, data, req):
- self.loadAccountData(user, req)
+ def login(self, user, password, data, req):
+ self.load_account_data(user, req)
diff --git a/module/plugins/accounts/OneFichierCom.py b/module/plugins/accounts/OneFichierCom.py
index b19e2bc69..3a0131a3f 100644
--- a/module/plugins/accounts/OneFichierCom.py
+++ b/module/plugins/accounts/OneFichierCom.py
@@ -4,13 +4,14 @@ import pycurl
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class OneFichierCom(Account):
__name__ = "OneFichierCom"
__type__ = "account"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """1fichier.com account plugin"""
__license__ = "GPLv3"
@@ -21,38 +22,37 @@ class OneFichierCom(Account):
VALID_UNTIL_PATTERN = r'Your Premium Status will end the (\d+/\d+/\d+)'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = -1
premium = None
- html = req.load("https://1fichier.com/console/abo.pl")
+ html = self.load("https://1fichier.com/console/abo.pl")
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
expiredate = m.group(1)
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
try:
validuntil = time.mktime(time.strptime(expiredate, "%d/%m/%Y"))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
premium = True
return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium or False}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
req.http.c.setopt(pycurl.REFERER, "https://1fichier.com/login.pl?lg=en")
- html = req.load("https://1fichier.com/login.pl?lg=en",
- post={'mail' : user,
- 'pass' : data['password'],
- 'It' : "on",
- 'purge' : "off",
- 'valider': "Send"},
- decode=True)
+ html = self.load("https://1fichier.com/login.pl?lg=en",
+ post={'mail' : user,
+ 'pass' : password,
+ 'It' : "on",
+ 'purge' : "off",
+ 'valider': "Send"})
if '>Invalid email address' in html or '>Invalid password' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/OverLoadMe.py b/module/plugins/accounts/OverLoadMe.py
index 64d04aded..6741b674f 100644
--- a/module/plugins/accounts/OverLoadMe.py
+++ b/module/plugins/accounts/OverLoadMe.py
@@ -1,43 +1,42 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class OverLoadMe(Account):
__name__ = "OverLoadMe"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.06"
+ __status__ = "testing"
__description__ = """Over-Load.me account plugin"""
__license__ = "GPLv3"
__authors__ = [("marley", "marley@over-load.me")]
- def loadAccountInfo(self, user, req):
- https = "https" if self.getConfig('ssl') else "http"
- data = self.getAccountData(user)
- html = req.load(https + "://api.over-load.me/account.php",
- get={'user': user,
- 'auth': data['password']}).strip()
+ def parse_info(self, user, password, data, req):
+ data = self.get_data(user)
+ html = self.load("https://api.over-load.me/account.php",
+ get={'user': user,
+ 'auth': password}).strip()
data = json_loads(html)
- self.logDebug(data)
+ self.log_debug(data)
- # Check for premium
+ #: Check for premium
if data['membership'] == "Free":
return {'premium': False, 'validuntil': None, 'trafficleft': None}
else:
return {'premium': True, 'validuntil': data['expirationunix'], 'trafficleft': -1}
- def login(self, user, data, req):
- https = "https" if self.getConfig('ssl') else "http"
- jsondata = req.load(https + "://api.over-load.me/account.php",
- get={'user': user,
- 'auth': data['password']}).strip()
+ def login(self, user, password, data, req):
+ jsondata = self.load("https://api.over-load.me/account.php",
+ get={'user': user,
+ 'auth': password}).strip()
data = json_loads(jsondata)
if data['err'] == 1:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/PremiumTo.py b/module/plugins/accounts/PremiumTo.py
index c8ea2fa26..ba8f24c6d 100644
--- a/module/plugins/accounts/PremiumTo.py
+++ b/module/plugins/accounts/PremiumTo.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class PremiumTo(Account):
__name__ = "PremiumTo"
__type__ = "account"
- __version__ = "0.08"
+ __version__ = "0.11"
+ __status__ = "testing"
__description__ = """Premium.to account plugin"""
__license__ = "GPLv3"
@@ -15,9 +16,10 @@ class PremiumTo(Account):
("stickell", "l.stickell@yahoo.it")]
- def loadAccountInfo(self, user, req):
- traffic = req.load("http://premium.to/api/straffic.php",
- get={'username': self.username, 'password': self.password})
+ def parse_info(self, user, password, data, req):
+ traffic = self.load("http://premium.to/api/straffic.php", #@TODO: Revert to `https` in 0.4.10
+ get={'username': self.username,
+ 'password': self.password})
if "wrong username" not in traffic:
trafficleft = sum(map(float, traffic.split(';'))) / 1024 #@TODO: Remove `/ 1024` in 0.4.10
@@ -26,12 +28,12 @@ class PremiumTo(Account):
return {'premium': False, 'trafficleft': None, 'validuntil': None}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
self.username = user
- self.password = data['password']
- authcode = req.load("http://premium.to/api/getauthcode.php",
- get={'username': user, 'password': self.password},
- decode=True)
+ self.password = password
+ authcode = self.load("http://premium.to/api/getauthcode.php", #@TODO: Revert to `https` in 0.4.10
+ get={'username': user,
+ 'password': self.password})
if "wrong username" in authcode:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/PremiumizeMe.py b/module/plugins/accounts/PremiumizeMe.py
index 7d061ec2d..df3b5db51 100644
--- a/module/plugins/accounts/PremiumizeMe.py
+++ b/module/plugins/accounts/PremiumizeMe.py
@@ -1,49 +1,49 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
-
from module.common.json_layer import json_loads
+from module.plugins.internal.Account import Account
class PremiumizeMe(Account):
__name__ = "PremiumizeMe"
__type__ = "account"
- __version__ = "0.13"
+ __version__ = "0.19"
+ __status__ = "testing"
__description__ = """Premiumize.me account plugin"""
__license__ = "GPLv3"
__authors__ = [("Florian Franzen", "FlorianFranzen@gmail.com")]
- def loadAccountInfo(self, user, req):
- # Get user data from premiumize.me
- status = self.getAccountStatus(user, req)
- self.logDebug(status)
+ def parse_info(self, user, password, data, req):
+ #: Get user data from premiumize.me
+ status = self.get_account_status(user, password)
+ self.log_debug(status)
- # Parse account info
- account_info = {"validuntil": float(status['result']['expires']),
- "trafficleft": max(0, status['result']['trafficleft_bytes'] / 1024)} #@TODO: Remove `/ 1024` in 0.4.10
+ #: Parse account info
+ account_info = {'validuntil': float(status['result']['expires']),
+ 'trafficleft': max(0, status['result']['trafficleft_bytes'] / 1024)} #@TODO: Remove `/ 1024` in 0.4.10
- if status['result']['type'] == 'free':
- account_info['premium'] = False
+ if status['result']['type'] != 'free':
+ account_info['premium'] = True
return account_info
- def login(self, user, data, req):
- # Get user data from premiumize.me
- status = self.getAccountStatus(user, req)
+ def login(self, user, password, data, req):
+ #: Get user data from premiumize.me
+ status = self.get_account_status(user, password)
- # Check if user and password are valid
+ #: Check if user and password are valid
if status['status'] != 200:
- self.wrongPassword()
+ self.login_fail()
- def getAccountStatus(self, user, req):
- # Use premiumize.me API v1 (see https://secure.premiumize.me/?show=api)
- # to retrieve account info and return the parsed json answer
- answer = req.load("https://api.premiumize.me/pm-api/v1.php",
+ def get_account_status(self, user, password):
+ #: Use premiumize.me API v1 (see https://secure.premiumize.me/?show=api)
+ #: To retrieve account info and return the parsed json answer
+ answer = self.load("http://api.premiumize.me/pm-api/v1.php", #@TODO: Revert to `https` in 0.4.10
get={'method' : "accountstatus",
'params[login]': user,
- 'params[pass]' : self.getAccountData(user)['password']})
+ 'params[pass]' : password})
return json_loads(answer)
diff --git a/module/plugins/accounts/PutdriveCom.py b/module/plugins/accounts/PutdriveCom.py
index 4f2fadbcc..5356c4d1a 100644
--- a/module/plugins/accounts/PutdriveCom.py
+++ b/module/plugins/accounts/PutdriveCom.py
@@ -6,7 +6,8 @@ from module.plugins.accounts.ZeveraCom import ZeveraCom
class PutdriveCom(ZeveraCom):
__name__ = "PutdriveCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Putdrive.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/QuickshareCz.py b/module/plugins/accounts/QuickshareCz.py
index 16141d63e..42022ec82 100644
--- a/module/plugins/accounts/QuickshareCz.py
+++ b/module/plugins/accounts/QuickshareCz.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class QuickshareCz(Account):
__name__ = "QuickshareCz"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """Quickshare.cz account plugin"""
__license__ = "GPLv3"
@@ -18,26 +19,25 @@ class QuickshareCz(Account):
TRAFFIC_LEFT_PATTERN = r'Stav kreditu: <strong>(.+?)</strong>'
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.quickshare.cz/premium", decode=True)
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://www.quickshare.cz/premium")
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if m:
- trafficleft = self.parseTraffic(m.group(1))
+ trafficleft = self.parse_traffic(m.group(1))
premium = True if trafficleft else False
else:
trafficleft = None
premium = False
- return {"validuntil": -1, "trafficleft": trafficleft, "premium": premium}
+ return {'validuntil': -1, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- html = req.load('http://www.quickshare.cz/html/prihlaseni_process.php',
- post={"akce": u'Přihlásit',
- "heslo": data['password'],
- "jmeno": user},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load('http://www.quickshare.cz/html/prihlaseni_process.php',
+ post={'akce' : u'Přihlásit',
+ 'heslo': password,
+ 'jmeno': user})
if u'>TakovÜ uşivatel neexistuje.<' in html or u'>Špatné heslo.<' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/RPNetBiz.py b/module/plugins/accounts/RPNetBiz.py
index 829e54a46..d713cedca 100644
--- a/module/plugins/accounts/RPNetBiz.py
+++ b/module/plugins/accounts/RPNetBiz.py
@@ -1,51 +1,52 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class RPNetBiz(Account):
__name__ = "RPNetBiz"
__type__ = "account"
- __version__ = "0.12"
+ __version__ = "0.15"
+ __status__ = "testing"
__description__ = """RPNet.biz account plugin"""
__license__ = "GPLv3"
__authors__ = [("Dman", "dmanugm@gmail.com")]
- def loadAccountInfo(self, user, req):
- # Get account information from rpnet.biz
- res = self.getAccountStatus(user, req)
+ def parse_info(self, user, password, data, req):
+ #: Get account information from rpnet.biz
+ res = self.get_account_status(user, password, req)
try:
if res['accountInfo']['isPremium']:
- # Parse account info. Change the trafficleft later to support per host info.
- account_info = {"validuntil": float(res['accountInfo']['premiumExpiry']),
- "trafficleft": -1, "premium": True}
+ #: Parse account info. Change the trafficleft later to support per host info.
+ account_info = {'validuntil': float(res['accountInfo']['premiumExpiry']),
+ 'trafficleft': -1, 'premium': True}
else:
- account_info = {"validuntil": None, "trafficleft": None, "premium": False}
+ account_info = {'validuntil': None, 'trafficleft': None, 'premium': False}
except KeyError:
- #handle wrong password exception
- account_info = {"validuntil": None, "trafficleft": None, "premium": False}
+ #: Handle wrong password exception
+ account_info = {'validuntil': None, 'trafficleft': None, 'premium': False}
return account_info
- def login(self, user, data, req):
- # Get account information from rpnet.biz
- res = self.getAccountStatus(user, req)
+ def login(self, user, password, data, req):
+ #: Get account information from rpnet.biz
+ res = self.get_account_status(user, password, req)
- # If we have an error in the res, we have wrong login information
+ #: If we have an error in the res, we have wrong login information
if 'error' in res:
- self.wrongPassword()
+ self.login_fail()
- def getAccountStatus(self, user, req):
- # Using the rpnet API, check if valid premium account
- res = req.load("https://premium.rpnet.biz/client_api.php",
- get={"username": user, "password": self.getAccountData(user)['password'],
- "action": "showAccountInformation"})
- self.logDebug("JSON data: %s" % res)
+ def get_account_status(self, user, password, req):
+ #: Using the rpnet API, check if valid premium account
+ res = self.load("https://premium.rpnet.biz/client_api.php",
+ get={'username': user, 'password': password,
+ 'action': "showAccountInformation"})
+ self.log_debug("JSON data: %s" % res)
return json_loads(res)
diff --git a/module/plugins/accounts/RapideoPl.py b/module/plugins/accounts/RapideoPl.py
index 3e9d52fe8..42d084bdb 100644
--- a/module/plugins/accounts/RapideoPl.py
+++ b/module/plugins/accounts/RapideoPl.py
@@ -4,77 +4,80 @@ import datetime
import hashlib
import time
-from module.plugins.Account import Account
-from module.common.json_layer import json_loads as loads
+from module.common.json_layer import json_loads
+from module.plugins.internal.Account import Account
class RapideoPl(Account):
- __name__ = "RapideoPl"
- __version__ = "0.01"
- __type__ = "account"
+ __name__ = "RapideoPl"
+ __type__ = "account"
+ __version__ = "0.03"
+ __status__ = "testing"
+
__description__ = "Rapideo.pl account plugin"
- __license__ = "GPLv3"
- __authors__ = [("goddie", "dev@rapideo.pl")]
+ __license__ = "GPLv3"
+ __authors__ = [("goddie", "dev@rapideo.pl")]
- _api_url = "http://enc.rapideo.pl"
- _api_query = {
- "site": "newrd",
- "username": "",
- "password": "",
- "output": "json",
- "loc": "1",
- "info": "1"
- }
+ API_URL = "http://enc.rapideo.pl"
+ API_QUERY = {'site' : "newrd",
+ 'username': "" ,
+ 'password': "" ,
+ 'output' : "json" ,
+ 'loc' : "1" ,
+ 'info' : "1" }
_req = None
_usr = None
_pwd = None
- def loadAccountInfo(self, name, req):
+
+ def parse_info(self, name, req):
self._req = req
try:
- result = loads(self.runAuthQuery())
+ result = json_loads(self.run_auth_query())
except Exception:
- # todo: return or let it be thrown?
+ #@TODO: return or let it be thrown?
return
premium = False
valid_untill = -1
- if "expire" in result.keys() and result["expire"]:
+
+ if "expire" in result.keys() and result['expire']:
premium = True
- valid_untill = time.mktime(datetime.datetime.fromtimestamp(int(result["expire"])).timetuple())
+ valid_untill = time.mktime(datetime.datetime.fromtimestamp(int(result['expire'])).timetuple())
- traffic_left = result["balance"]
+ traffic_left = result['balance']
- return ({
- "validuntil": valid_untill,
- "trafficleft": traffic_left,
- "premium": premium
- })
+ return {'validuntil' : valid_untill,
+ 'trafficleft': traffic_left,
+ 'premium' : premium }
- def login(self, user, data, req):
+
+ def login(self, user, password, data, req):
self._usr = user
- self._pwd = hashlib.md5(data["password"]).hexdigest()
+ self._pwd = hashlib.md5(password).hexdigest()
self._req = req
+
try:
- response = loads(self.runAuthQuery())
+ response = json_loads(self.run_auth_query())
except Exception:
- self.wrongPassword()
+ self.login_fail()
if "errno" in response.keys():
- self.wrongPassword()
+ self.login_fail()
+
data['usr'] = self._usr
data['pwd'] = self._pwd
- def createAuthQuery(self):
- query = self._api_query
- query["username"] = self._usr
- query["password"] = self._pwd
+ def create_auth_query(self):
+ query = self.API_QUERY
+ query['username'] = self._usr
+ query['password'] = self._pwd
return query
- def runAuthQuery(self):
- data = self._req.load(self._api_url, post=self.createAuthQuery())
- return data \ No newline at end of file
+ def run_auth_query(self):
+ return self.load(self.API_URL,
+ post=self.create_auth_query())
diff --git a/module/plugins/accounts/RapidfileshareNet.py b/module/plugins/accounts/RapidfileshareNet.py
index c0dd7eaee..069b30900 100644
--- a/module/plugins/accounts/RapidfileshareNet.py
+++ b/module/plugins/accounts/RapidfileshareNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class RapidfileshareNet(XFSAccount):
__name__ = "RapidfileshareNet"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__description__ = """Rapidfileshare.net account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/RapidgatorNet.py b/module/plugins/accounts/RapidgatorNet.py
index 23d7aff53..5ce51a1ec 100644
--- a/module/plugins/accounts/RapidgatorNet.py
+++ b/module/plugins/accounts/RapidgatorNet.py
@@ -1,13 +1,16 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+import urlparse
+
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class RapidgatorNet(Account):
__name__ = "RapidgatorNet"
__type__ = "account"
- __version__ = "0.09"
+ __version__ = "0.11"
+ __status__ = "testing"
__description__ = """Rapidgator.net account plugin"""
__license__ = "GPLv3"
@@ -17,34 +20,35 @@ class RapidgatorNet(Account):
API_URL = "http://rapidgator.net/api/user"
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = None
premium = False
sid = None
try:
- sid = self.getAccountData(user).get('sid')
+ sid = self.get_data(user).get('sid', None)
assert sid
- html = req.load("%s/info" % self.API_URL, get={'sid': sid})
+ html = self.load(urlparse.urljoin(self.API_URL, "info"),
+ get={'sid': sid})
- self.logDebug("API:USERINFO", html)
+ self.log_debug("API:USERINFO", html)
json = json_loads(html)
if json['response_status'] == 200:
if "reset_in" in json['response']:
- self.scheduleRefresh(user, json['response']['reset_in'])
+ self.schedule_refresh(user, json['response']['reset_in'])
validuntil = json['response']['expire_date']
trafficleft = float(json['response']['traffic_left']) / 1024 #@TODO: Remove `/ 1024` in 0.4.10
premium = True
else:
- self.logError(json['response_details'])
+ self.log_error(json['response_details'])
except Exception, e:
- self.logError(e)
+ self.log_error(e)
return {'validuntil' : validuntil,
'trafficleft': trafficleft,
@@ -52,11 +56,13 @@ class RapidgatorNet(Account):
'sid' : sid}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
try:
- html = req.load('%s/login' % self.API_URL, post={"username": user, "password": data['password']})
+ html = self.load(urlparse.urljoin(self.API_URL, "login"),
+ post={'username': user,
+ 'password': password})
- self.logDebug("API:LOGIN", html)
+ self.log_debug("API:LOGIN", html)
json = json_loads(html)
@@ -64,9 +70,9 @@ class RapidgatorNet(Account):
data['sid'] = str(json['response']['session_id'])
return
else:
- self.logError(json['response_details'])
+ self.log_error(json['response_details'])
except Exception, e:
- self.logError(e)
+ self.log_error(e)
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/RapiduNet.py b/module/plugins/accounts/RapiduNet.py
index 70f47b673..1ec29bd77 100644
--- a/module/plugins/accounts/RapiduNet.py
+++ b/module/plugins/accounts/RapiduNet.py
@@ -3,14 +3,15 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
from module.common.json_layer import json_loads
class RapiduNet(Account):
__name__ = "RapiduNet"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """Rapidu.net account plugin"""
__license__ = "GPLv3"
@@ -25,12 +26,12 @@ class RapiduNet(Account):
TRAFFIC_LEFT_PATTERN = r'class="tipsyS"><b>(.+?)<'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = -1
premium = False
- html = req.load("https://rapidu.net/", decode=True)
+ html = self.load("https://rapidu.net/")
if re.search(self.PREMIUM_PATTERN, html):
premium = True
@@ -41,25 +42,25 @@ class RapiduNet(Account):
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if m:
- trafficleft = self.parseTraffic(m.group(1))
+ trafficleft = self.parse_traffic(m.group(1))
return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- req.load("https://rapidu.net/ajax.php",
- get={'a': "getChangeLang"},
- post={'_go' : "",
- 'lang': "en"})
+ def login(self, user, password, data, req):
+ self.load("https://rapidu.net/ajax.php",
+ get={'a': "getChangeLang"},
+ post={'_go' : "",
+ 'lang': "en"})
- json = json_loads(req.load("https://rapidu.net/ajax.php",
- get={'a': "getUserLogin"},
- post={'_go' : "",
- 'login' : user,
- 'pass' : data['password'],
- 'remember': "1"}))
+ json = json_loads(self.load("https://rapidu.net/ajax.php",
+ get={'a': "getUserLogin"},
+ post={'_go' : "",
+ 'login' : user,
+ 'pass' : password,
+ 'remember': "1"}))
- self.logDebug(json)
+ self.log_debug(json)
if not json['message'] == "success":
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/RarefileNet.py b/module/plugins/accounts/RarefileNet.py
index 577a6c8f6..5f52ba147 100644
--- a/module/plugins/accounts/RarefileNet.py
+++ b/module/plugins/accounts/RarefileNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class RarefileNet(XFSAccount):
__name__ = "RarefileNet"
__type__ = "account"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """RareFile.net account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/RealdebridCom.py b/module/plugins/accounts/RealdebridCom.py
index 41d8a0975..718850c1a 100644
--- a/module/plugins/accounts/RealdebridCom.py
+++ b/module/plugins/accounts/RealdebridCom.py
@@ -2,39 +2,44 @@
import xml.dom.minidom as dom
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class RealdebridCom(Account):
__name__ = "RealdebridCom"
__type__ = "account"
- __version__ = "0.45"
+ __version__ = "0.48"
+ __status__ = "testing"
__description__ = """Real-Debrid.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("Devirex Hazzard", "naibaf_11@yahoo.de")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
if self.pin_code:
- return {"premium": False}
- html = req.load("https://real-debrid.com/api/account.php")
- xml = dom.parseString(html)
- account_info = {"validuntil": float(xml.getElementsByTagName("expiration")[0].childNodes[0].nodeValue),
- "trafficleft": -1}
+ return
- return account_info
+ html = self.load("https://real-debrid.com/api/account.php")
+ xml = dom.parseString(html)
+ validuntil = float(xml.getElementsByTagName("expiration")[0].childNodes[0].nodeValue)
- def login(self, user, data, req):
+ return {'validuntil' : validuntil,
+ 'trafficleft': -1 ,
+ 'premium' : True }
+
+
+ def login(self, user, password, data, req):
self.pin_code = False
- html = req.load("https://real-debrid.com/ajax/login.php",
- get={"user": user, "pass": data['password']},
- decode=True)
+
+ html = self.load("https://real-debrid.com/ajax/login.php",
+ get={'user': user,
+ 'pass': password})
if "Your login informations are incorrect" in html:
- self.wrongPassword()
+ self.login_fail()
elif "PIN Code required" in html:
- self.logWarning(_("PIN code required. Please login to https://real-debrid.com using the PIN or disable the double authentication in your control panel on https://real-debrid.com"))
+ self.log_warning(_("PIN code required. Please login to https://real-debrid.com using the PIN or disable the double authentication in your control panel on https://real-debrid.com"))
self.pin_code = True
diff --git a/module/plugins/accounts/RehostTo.py b/module/plugins/accounts/RehostTo.py
index 04e71c9ad..36e5e33eb 100644
--- a/module/plugins/accounts/RehostTo.py
+++ b/module/plugins/accounts/RehostTo.py
@@ -1,40 +1,43 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class RehostTo(Account):
__name__ = "RehostTo"
__type__ = "account"
- __version__ = "0.16"
+ __version__ = "0.18"
+ __status__ = "testing"
__description__ = """Rehost.to account plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
premium = False
trafficleft = None
validuntil = -1
session = ""
- html = req.load("http://rehost.to/api.php",
- get={'cmd' : "login", 'user': user,
- 'pass': self.getAccountData(user)['password']})
+ html = self.load("https://rehost.to/api.php",
+ get={'cmd' : "login",
+ 'user': user,
+ 'pass': password})
try:
session = html.split(",")[1].split("=")[1]
- html = req.load("http://rehost.to/api.php",
- get={'cmd': "get_premium_credits", 'long_ses': session})
+ html = self.load("http://rehost.to/api.php",
+ get={'cmd' : "get_premium_credits",
+ 'long_ses': session})
if html.strip() == "0,0" or "ERROR" in html:
- self.logDebug(html)
+ self.log_debug(html)
else:
traffic, valid = html.split(",")
premium = True
- trafficleft = self.parseTraffic(traffic + "MB")
+ trafficleft = self.parse_traffic(traffic + "MB")
validuntil = float(valid)
finally:
@@ -44,11 +47,12 @@ class RehostTo(Account):
'session' : session}
- def login(self, user, data, req):
- html = req.load("http://rehost.to/api.php",
- get={'cmd': "login", 'user': user, 'pass': data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://rehost.to/api.php",
+ get={'cmd': "login",
+ 'user': user,
+ 'pass': password})
if "ERROR" in html:
- self.logDebug(html)
- self.wrongPassword()
+ self.log_debug(html)
+ self.login_fail()
diff --git a/module/plugins/accounts/RyushareCom.py b/module/plugins/accounts/RyushareCom.py
index 8c56ff20f..3ab907a76 100644
--- a/module/plugins/accounts/RyushareCom.py
+++ b/module/plugins/accounts/RyushareCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class RyushareCom(XFSAccount):
__name__ = "RyushareCom"
__type__ = "account"
- __version__ = "0.06"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """Ryushare.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/SafesharingEu.py b/module/plugins/accounts/SafesharingEu.py
index 2e58d33b3..eb84d502f 100644
--- a/module/plugins/accounts/SafesharingEu.py
+++ b/module/plugins/accounts/SafesharingEu.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class SafesharingEu(XFSAccount):
__name__ = "SafesharingEu"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Safesharing.eu account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/SecureUploadEu.py b/module/plugins/accounts/SecureUploadEu.py
index b335c94da..a81030b67 100644
--- a/module/plugins/accounts/SecureUploadEu.py
+++ b/module/plugins/accounts/SecureUploadEu.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class SecureUploadEu(XFSAccount):
__name__ = "SecureUploadEu"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """SecureUpload.eu account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/SendmywayCom.py b/module/plugins/accounts/SendmywayCom.py
index 4fcbe0b7a..2875e0d46 100644
--- a/module/plugins/accounts/SendmywayCom.py
+++ b/module/plugins/accounts/SendmywayCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class SendmywayCom(XFSAccount):
__name__ = "SendmywayCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Sendmyway.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/SharebeastCom.py b/module/plugins/accounts/SharebeastCom.py
new file mode 100644
index 000000000..a104a4a46
--- /dev/null
+++ b/module/plugins/accounts/SharebeastCom.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class SharebeastCom(XFSAccount):
+ __name__ = "SharebeastCom"
+ __type__ = "account"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __description__ = """Sharebeast.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "sharebeast.com"
diff --git a/module/plugins/accounts/ShareonlineBiz.py b/module/plugins/accounts/ShareonlineBiz.py
index 4214b4401..87bbc4632 100644
--- a/module/plugins/accounts/ShareonlineBiz.py
+++ b/module/plugins/accounts/ShareonlineBiz.py
@@ -2,54 +2,58 @@
import re
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class ShareonlineBiz(Account):
__name__ = "ShareonlineBiz"
__type__ = "account"
- __version__ = "0.33"
+ __version__ = "0.39"
+ __status__ = "testing"
__description__ = """Share-online.biz account plugin"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- def api_response(self, user, req):
- return req.load("http://api.share-online.biz/cgi-bin",
+ def api_response(self, user, password, req):
+ res = self.load("https://api.share-online.biz/cgi-bin",
get={'q' : "userdetails",
'aux' : "traffic",
'username': user,
- 'password': self.getAccountData(user)['password']})
+ 'password': password},
+ decode=False)
+ self.log_debug(res)
- def loadAccountInfo(self, user, req):
- premium = False
- validuntil = None
- trafficleft = -1
- maxtraffic = 100 * 1024 * 1024 * 1024 #: 100 GB
+ api = dict(line.split("=") for line in res.splitlines() if "=" in line)
+
+ if not 'a' in api:
+ self.login_fail(res.strip('*').strip())
- api = {}
- for line in self.api_response(user, req).splitlines():
- if "=" in line:
- key, value = line.split("=")
- api[key] = value
+ if api['a'].lower() == "not_available":
+ self.login_fail(_("No info available"))
- self.logDebug(api)
+ return api
- if api['a'].lower() != "not_available":
- req.cj.setCookie("share-online.biz", 'a', api['a'])
- premium = api['group'] in ("PrePaid", "Premium", "Penalty-Premium")
+ def parse_info(self, user, password, data, req):
+ premium = False
+ validuntil = None
+ trafficleft = -1
+ maxtraffic = 100 * 1024 * 1024 * 1024 #: 100 GB
- validuntil = float(api['expire_date'])
+ api = self.api_response(user, password, req)
- traffic = float(api['traffic_1d'].split(";")[0])
+ premium = api['group'] in ("PrePaid", "Premium", "Penalty-Premium")
+ validuntil = float(api['expire_date'])
+ traffic = float(api['traffic_1d'].split(";")[0])
- if maxtraffic > traffic:
- trafficleft = maxtraffic - traffic
- else:
- trafficleft = -1
+ if maxtraffic > traffic:
+ trafficleft = maxtraffic - traffic
+ else:
+ trafficleft = -1
maxtraffic /= 1024 #@TODO: Remove `/ 1024` in 0.4.10
trafficleft /= 1024 #@TODO: Remove `/ 1024` in 0.4.10
@@ -60,9 +64,6 @@ class ShareonlineBiz(Account):
'maxtraffic' : maxtraffic}
- def login(self, user, data, req):
- html = self.api_response(user, req)
- err = re.search(r'\*\*(.+?)\*\*', html)
- if err:
- self.logError(err.group(1))
- self.wrongPassword()
+ def login(self, user, password, data, req):
+ api = self.api_response(user, password, req)
+ set_cookie(req.cj, "share-online.biz", 'a', api['a'])
diff --git a/module/plugins/accounts/SimplyPremiumCom.py b/module/plugins/accounts/SimplyPremiumCom.py
index 8caf600f9..a5c69f51c 100644
--- a/module/plugins/accounts/SimplyPremiumCom.py
+++ b/module/plugins/accounts/SimplyPremiumCom.py
@@ -1,27 +1,29 @@
# -*- coding: utf-8 -*-
from module.common.json_layer import json_loads
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class SimplyPremiumCom(Account):
__name__ = "SimplyPremiumCom"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.08"
+ __status__ = "testing"
__description__ = """Simply-Premium.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("EvolutionClip", "evolutionclip@live.de")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
premium = False
validuntil = -1
trafficleft = None
- json_data = req.load('http://www.simply-premium.com/api/user.php?format=json')
+ json_data = self.load('http://www.simply-premium.com/api/user.php?format=json')
- self.logDebug("JSON data: %s" % json_data)
+ self.log_debug("JSON data: %s" % json_data)
json_data = json_loads(json_data)
@@ -34,15 +36,14 @@ class SimplyPremiumCom(Account):
if 'remain_traffic' in json_data['result'] and json_data['result']['remain_traffic']:
trafficleft = float(json_data['result']['remain_traffic']) / 1024 #@TODO: Remove `/ 1024` in 0.4.10
- return {"premium": premium, "validuntil": validuntil, "trafficleft": trafficleft}
+ return {'premium': premium, 'validuntil': validuntil, 'trafficleft': trafficleft}
- def login(self, user, data, req):
- req.cj.setCookie("simply-premium.com", "lang", "EN")
+ def login(self, user, password, data, req):
+ set_cookie(req.cj, "simply-premium.com", "lang", "EN")
- html = req.load("http://www.simply-premium.com/login.php",
- post={'key': user} if not data['password'] else {'login_name': user, 'login_pass': data['password']},
- decode=True)
+ html = self.load("https://www.simply-premium.com/login.php",
+ post={'key': user} if not password else {'login_name': user, 'login_pass': password})
if 'logout' not in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/SimplydebridCom.py b/module/plugins/accounts/SimplydebridCom.py
index 24108eb0b..84c38227e 100644
--- a/module/plugins/accounts/SimplydebridCom.py
+++ b/module/plugins/accounts/SimplydebridCom.py
@@ -2,34 +2,36 @@
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class SimplydebridCom(Account):
__name__ = "SimplydebridCom"
__type__ = "account"
- __version__ = "0.11"
+ __version__ = "0.13"
+ __status__ = "testing"
__description__ = """Simply-Debrid.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")]
- def loadAccountInfo(self, user, req):
- get_data = {'login': 2, 'u': self.loginname, 'p': self.password}
- res = req.load("http://simply-debrid.com/api.php", get=get_data, decode=True)
+ def parse_info(self, user, password, data, req):
+ res = self.load("http://simply-debrid.com/api.php",
+ get={'login': 2,
+ 'u' : user,
+ 'p' : password})
data = [x.strip() for x in res.split(";")]
if str(data[0]) != "1":
- return {"premium": False}
+ return {'premium': False}
else:
- return {"trafficleft": -1, "validuntil": time.mktime(time.strptime(str(data[2]), "%d/%m/%Y"))}
+ return {'trafficleft': -1, 'validuntil': time.mktime(time.strptime(str(data[2]), "%d/%m/%Y"))}
- def login(self, user, data, req):
- self.loginname = user
- self.password = data['password']
- get_data = {'login': 1, 'u': self.loginname, 'p': self.password}
-
- res = req.load("http://simply-debrid.com/api.php", get=get_data, decode=True)
+ def login(self, user, password, data, req):
+ res = self.load("https://simply-debrid.com/api.php",
+ get={'login': 1,
+ 'u' : user,
+ 'p' : password})
if res != "02: loggin success":
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/SmoozedCom.py b/module/plugins/accounts/SmoozedCom.py
index 1c303331b..9c2451794 100644
--- a/module/plugins/accounts/SmoozedCom.py
+++ b/module/plugins/accounts/SmoozedCom.py
@@ -20,37 +20,38 @@ except ImportError:
return b2a_hex(pbkdf2(self.passphrase, self.salt, self.iterations, octets))
from module.common.json_layer import json_loads
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class SmoozedCom(Account):
__name__ = "SmoozedCom"
__type__ = "account"
- __version__ = "0.05"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """Smoozed.com account plugin"""
__license__ = "GPLv3"
__authors__ = [("", "")]
- def loadAccountInfo(self, user, req):
- status = self.getAccountStatus(user, req)
+ def parse_info(self, user, password, data, req):
+ status = self.get_account_status(user, password, req)
- self.logDebug(status)
+ self.log_debug(status)
if status['state'] != 'ok':
info = {'validuntil' : None,
'trafficleft': None,
'premium' : False}
else:
- # Parse account info
- info = {'validuntil' : float(status["data"]["user"]["user_premium"]),
- 'trafficleft': max(0, status["data"]["traffic"][1] - status["data"]["traffic"][0]),
- 'session' : status["data"]["session_key"],
- 'hosters' : [hoster["name"] for hoster in status["data"]["hoster"]]}
+ #: Parse account info
+ info = {'validuntil' : float(status['data']['user']['user_premium']),
+ 'trafficleft': max(0, status['data']['traffic'][1] - status['data']['traffic'][0]),
+ 'session' : status['data']['session_key'],
+ 'hosters' : [hoster['name'] for hoster in status['data']['hoster']]}
if info['validuntil'] < time.time():
- if float(status["data"]["user"].get("user_trial", 0)) > time.time():
+ if float(status['data']['user'].get("user_trial", 0)) > time.time():
info['premium'] = True
else:
info['premium'] = False
@@ -60,19 +61,20 @@ class SmoozedCom(Account):
return info
- def login(self, user, data, req):
- # Get user data from premiumize.me
- status = self.getAccountStatus(user, req)
+ def login(self, user, password, data, req):
+ #: Get user data from premiumize.me
+ status = self.get_account_status(user, password, req)
- # Check if user and password are valid
+ #: Check if user and password are valid
if status['state'] != 'ok':
- self.wrongPassword()
+ self.login_fail()
- def getAccountStatus(self, user, req):
- password = self.getAccountData(user)['password']
+ def get_account_status(self, user, password, req):
+ password = password
salt = hashlib.sha256(password).hexdigest()
encrypted = PBKDF2(password, salt, iterations=1000).hexread(32)
- return json_loads(req.load("http://www2.smoozed.com/api/login",
- get={'auth': user, 'password': encrypted}))
+ return json_loads(self.load("http://www2.smoozed.com/api/login",
+ get={'auth': user,
+ 'password': encrypted}))
diff --git a/module/plugins/accounts/StahnuTo.py b/module/plugins/accounts/StahnuTo.py
deleted file mode 100644
index 882dbd2c3..000000000
--- a/module/plugins/accounts/StahnuTo.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import re
-
-from module.plugins.Account import Account
-
-
-class StahnuTo(Account):
- __name__ = "StahnuTo"
- __type__ = "account"
- __version__ = "0.05"
-
- __description__ = """StahnuTo account plugin"""
- __license__ = "GPLv3"
- __authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
-
-
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.stahnu.to/")
-
- m = re.search(r'>VIP: (\d+.*)<', html)
- trafficleft = self.parseTraffic(m.group(1)) if m else 0
-
- return {"premium": trafficleft > 512, "trafficleft": trafficleft, "validuntil": -1}
-
-
- def login(self, user, data, req):
- html = req.load("http://www.stahnu.to/login.php",
- post={"username": user,
- "password": data['password'],
- "submit": "Login"},
- decode=True)
-
- if not '<a href="logout.php">' in html:
- self.wrongPassword()
diff --git a/module/plugins/accounts/StreamcloudEu.py b/module/plugins/accounts/StreamcloudEu.py
index aa1eafcbd..9549896cc 100644
--- a/module/plugins/accounts/StreamcloudEu.py
+++ b/module/plugins/accounts/StreamcloudEu.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class StreamcloudEu(XFSAccount):
__name__ = "StreamcloudEu"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Streamcloud.eu account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/TurbobitNet.py b/module/plugins/accounts/TurbobitNet.py
index 010fbc270..206e7874f 100644
--- a/module/plugins/accounts/TurbobitNet.py
+++ b/module/plugins/accounts/TurbobitNet.py
@@ -3,21 +3,23 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookie
class TurbobitNet(Account):
__name__ = "TurbobitNet"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """TurbobitNet account plugin"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- def loadAccountInfo(self, user, req):
- html = req.load("http://turbobit.net")
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://turbobit.net")
m = re.search(r'<u>Turbo Access</u> to ([\d.]+)', html)
if m:
@@ -27,17 +29,16 @@ class TurbobitNet(Account):
premium = False
validuntil = -1
- return {"premium": premium, "trafficleft": -1, "validuntil": validuntil}
+ return {'premium': premium, 'trafficleft': -1, 'validuntil': validuntil}
- def login(self, user, data, req):
- req.cj.setCookie("turbobit.net", "user_lang", "en")
+ def login(self, user, password, data, req):
+ set_cookie(req.cj, "turbobit.net", "user_lang", "en")
- html = req.load("http://turbobit.net/user/login",
- post={"user[login]": user,
- "user[pass]": data['password'],
- "user[submit]": "Login"},
- decode=True)
+ html = self.load("http://turbobit.net/user/login",
+ post={"user[login]" : user,
+ "user[pass]" : password,
+ "user[submit]": "Login"})
if not '<div class="menu-item user-name">' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/TusfilesNet.py b/module/plugins/accounts/TusfilesNet.py
index d06ba0583..c549bbaf7 100644
--- a/module/plugins/accounts/TusfilesNet.py
+++ b/module/plugins/accounts/TusfilesNet.py
@@ -9,9 +9,10 @@ from module.plugins.internal.XFSAccount import XFSAccount
class TusfilesNet(XFSAccount):
__name__ = "TusfilesNet"
__type__ = "account"
- __version__ = "0.06"
+ __version__ = "0.07"
+ __status__ = "testing"
- __description__ = """ Tusfile.net account plugin """
+ __description__ = """Tusfile.net account plugin"""
__license__ = "GPLv3"
__authors__ = [("guidobelix", "guidobelix@hotmail.it")]
diff --git a/module/plugins/accounts/UlozTo.py b/module/plugins/accounts/UlozTo.py
index f95c8834b..00e125dbc 100644
--- a/module/plugins/accounts/UlozTo.py
+++ b/module/plugins/accounts/UlozTo.py
@@ -3,13 +3,14 @@
import re
import urlparse
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class UlozTo(Account):
__name__ = "UlozTo"
__type__ = "account"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__description__ = """Uloz.to account plugin"""
__license__ = "GPLv3"
@@ -20,8 +21,8 @@ class UlozTo(Account):
TRAFFIC_LEFT_PATTERN = r'<li class="menu-kredit"><a .*?title=".+?GB = ([\d.]+) MB"'
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.ulozto.net/", decode=True)
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://www.ulozto.net/")
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
@@ -31,19 +32,18 @@ class UlozTo(Account):
return {'validuntil': -1, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
- login_page = req.load('http://www.ulozto.net/?do=web-login', decode=True)
+ def login(self, user, password, data, req):
+ login_page = self.load('http://www.ulozto.net/?do=web-login')
action = re.findall('<form action="(.+?)"', login_page)[1].replace('&amp;', '&')
token = re.search('_token_" value="(.+?)"', login_page).group(1)
- html = req.load(urlparse.urljoin("http://www.ulozto.net/", action),
- post={'_token_' : token,
- 'do' : "loginForm-submit",
- 'login' : u"Přihlásit",
- 'password': data['password'],
- 'username': user,
- 'remember': "on"},
- decode=True)
+ html = self.load(urlparse.urljoin("https://www.ulozto.net/", action),
+ post={'_token_' : token,
+ 'do' : "loginForm-submit",
+ 'login' : u"Přihlásit",
+ 'password': password,
+ 'username': user,
+ 'remember': "on"})
if '<div class="flash error">' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/UploadableCh.py b/module/plugins/accounts/UploadableCh.py
index 86ae5dd17..9c2649e51 100644
--- a/module/plugins/accounts/UploadableCh.py
+++ b/module/plugins/accounts/UploadableCh.py
@@ -1,20 +1,21 @@
# -*- coding: utf-8 -*-
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class UploadableCh(Account):
__name__ = "UploadableCh"
__type__ = "account"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__description__ = """Uploadable.ch account plugin"""
__license__ = "GPLv3"
__authors__ = [("Sasch", "gsasch@gmail.com")]
- def loadAccountInfo(self, user, req):
- html = req.load("http://www.uploadable.ch/login.php")
+ def parse_info(self, user, password, data, req):
+ html = self.load("http://www.uploadable.ch/login.php")
premium = '<a href="/logout.php"' in html
trafficleft = -1 if premium else None
@@ -22,13 +23,12 @@ class UploadableCh(Account):
return {'validuntil': None, 'trafficleft': trafficleft, 'premium': premium} #@TODO: validuntil
- def login(self, user, data, req):
- html = req.load("http://www.uploadable.ch/login.php",
- post={'userName' : user,
- 'userPassword' : data["password"],
- 'autoLogin' : "1",
- 'action__login': "normalLogin"},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("http://www.uploadable.ch/login.php",
+ post={'userName' : user,
+ 'userPassword' : password,
+ 'autoLogin' : "1",
+ 'action__login': "normalLogin"})
if "Login failed" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/UploadcCom.py b/module/plugins/accounts/UploadcCom.py
index d1e1a2ead..5b834ac3b 100644
--- a/module/plugins/accounts/UploadcCom.py
+++ b/module/plugins/accounts/UploadcCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class UploadcCom(XFSAccount):
__name__ = "UploadcCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """Uploadc.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py
index d1556b6db..59d3fcff9 100644
--- a/module/plugins/accounts/UploadedTo.py
+++ b/module/plugins/accounts/UploadedTo.py
@@ -3,30 +3,33 @@
import re
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class UploadedTo(Account):
__name__ = "UploadedTo"
__type__ = "account"
- __version__ = "0.30"
+ __version__ = "0.35"
+ __status__ = "testing"
__description__ = """Uploaded.to account plugin"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- PREMIUM_PATTERN = r'<em>Premium</em>'
- VALID_UNTIL_PATTERN = r'<td>Duration:</td>\s*<th>(.+?)<'
+ COOKIES = False
+
+ PREMIUM_PATTERN = r'<em>Premium</em>'
+ VALID_UNTIL_PATTERN = r'<td>Duration:</td>\s*<th>(.+?)<'
TRAFFIC_LEFT_PATTERN = r'<b class="cB">(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = None
premium = None
- html = req.load("http://uploaded.net/me")
+ html = self.load("http://uploaded.net/me")
premium = True if re.search(self.PREMIUM_PATTERN, html) else False
@@ -53,19 +56,20 @@ class UploadedTo(Account):
trafficleft = float(size.replace(',', '.')) / 1024
trafficleft *= 1 << 40
else:
- trafficleft = self.parseTraffic(size + unit)
+ trafficleft = self.parse_traffic(size + unit)
return {'validuntil' : validuntil,
'trafficleft': trafficleft,
'premium' : premium}
- def login(self, user, data, req):
- # req.cj.setCookie("uploaded.net", "lang", "en")
+ def login(self, user, password, data, req):
+ self.load("http://uploaded.net/language/en")
- html = req.load("http://uploaded.net/io/login",
- post={'id': user, 'pw': data['password'], '_': ""},
- decode=True)
+ html = self.load("http://uploaded.net/io/login",
+ post={'id': user,
+ 'pw': password})
- if '"err"' in html:
- self.wrongPassword()
+ m = re.search(r'"err":"(.+?)"', html)
+ if m is not None:
+ self.login_fail(m.group(1))
diff --git a/module/plugins/accounts/UploadheroCom.py b/module/plugins/accounts/UploadheroCom.py
index 714f5b0a6..f31b01d03 100644
--- a/module/plugins/accounts/UploadheroCom.py
+++ b/module/plugins/accounts/UploadheroCom.py
@@ -4,39 +4,40 @@ import re
import datetime
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class UploadheroCom(Account):
__name__ = "UploadheroCom"
__type__ = "account"
- __version__ = "0.21"
+ __version__ = "0.23"
+ __status__ = "testing"
__description__ = """Uploadhero.co account plugin"""
__license__ = "GPLv3"
__authors__ = [("mcmyst", "mcmyst@hotmail.fr")]
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
premium_pattern = re.compile('Il vous reste <span class="bleu">(\d+)</span> jours premium')
- data = self.getAccountData(user)
- html = req.load("http://uploadhero.co/my-account")
+ data = self.get_data(user)
+ html = self.load("http://uploadhero.co/my-account")
if premium_pattern.search(html):
end_date = datetime.date.today() + datetime.timedelta(days=int(premium_pattern.search(html).group(1)))
end_date = time.mktime(future.timetuple())
- account_info = {"validuntil": end_date, "trafficleft": -1, "premium": True}
+ account_info = {'validuntil': end_date, 'trafficleft': -1, 'premium': True}
else:
- account_info = {"validuntil": -1, "trafficleft": -1, "premium": False}
+ account_info = {'validuntil': -1, 'trafficleft': -1, 'premium': False}
return account_info
- def login(self, user, data, req):
- html = req.load("http://uploadhero.co/lib/connexion.php",
- post={"pseudo_login": user, "password_login": data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("http://uploadhero.co/lib/connexion.php",
+ post={'pseudo_login': user,
+ 'password_login': password})
if "mot de passe invalide" in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/UploadingCom.py b/module/plugins/accounts/UploadingCom.py
index a20c44535..d269abde7 100644
--- a/module/plugins/accounts/UploadingCom.py
+++ b/module/plugins/accounts/UploadingCom.py
@@ -3,14 +3,15 @@
import re
import time
-from module.plugins.Account import Account
-from module.plugins.internal.SimpleHoster import set_cookies
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import set_cookies
class UploadingCom(Account):
__name__ = "UploadingCom"
__type__ = "account"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Uploading.com account plugin"""
__license__ = "GPLv3"
@@ -21,25 +22,25 @@ class UploadingCom(Account):
VALID_UNTIL_PATTERN = r'Valid Until:(.+?)<'
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = None
premium = None
- html = req.load("http://uploading.com/")
+ html = self.load("http://uploading.com/")
premium = False if re.search(self.PREMIUM_PATTERN, html) else True
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
expiredate = m.group(1).strip()
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
try:
validuntil = time.mktime(time.strptime(expiredate, "%b %d, %Y"))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
if validuntil > time.mktime(time.gmtime()):
@@ -53,13 +54,15 @@ class UploadingCom(Account):
'premium' : premium}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
set_cookies(req.cj,
[("uploading.com", "lang" , "1" ),
("uploading.com", "language", "1" ),
("uploading.com", "setlang" , "en"),
("uploading.com", "_lang" , "en")])
- req.load("http://uploading.com/")
- req.load("http://uploading.com/general/login_form/?JsHttpRequest=%s-xml" % long(time.time() * 1000),
- post={'email': user, 'password': data['password'], 'remember': "on"})
+ self.load("http://uploading.com/")
+ self.load("https://uploading.com/general/login_form/?JsHttpRequest=%s-xml" % long(time.time() * 1000),
+ post={'email' : user,
+ 'password': password,
+ 'remember': "on"})
diff --git a/module/plugins/accounts/UptoboxCom.py b/module/plugins/accounts/UptoboxCom.py
index c40dbd6e6..68aaecc47 100644
--- a/module/plugins/accounts/UptoboxCom.py
+++ b/module/plugins/accounts/UptoboxCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class UptoboxCom(XFSAccount):
__name__ = "UptoboxCom"
__type__ = "account"
- __version__ = "0.08"
+ __version__ = "0.09"
+ __status__ = "testing"
__description__ = """DDLStorage.com account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/VidPlayNet.py b/module/plugins/accounts/VidPlayNet.py
index 5bfc24963..d543c5671 100644
--- a/module/plugins/accounts/VidPlayNet.py
+++ b/module/plugins/accounts/VidPlayNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class VidPlayNet(XFSAccount):
__name__ = "VidPlayNet"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__description__ = """VidPlay.net account plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/accounts/WebshareCz.py b/module/plugins/accounts/WebshareCz.py
index f032e2317..bbfb90a92 100644
--- a/module/plugins/accounts/WebshareCz.py
+++ b/module/plugins/accounts/WebshareCz.py
@@ -6,13 +6,14 @@ import time
from passlib.hash import md5_crypt
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class WebshareCz(Account):
__name__ = "WebshareCz"
__type__ = "account"
- __version__ = "0.07"
+ __version__ = "0.10"
+ __status__ = "testing"
__description__ = """Webshare.cz account plugin"""
__license__ = "GPLv3"
@@ -24,45 +25,42 @@ class WebshareCz(Account):
TRAFFIC_LEFT_PATTERN = r'<bytes>(.+)</bytes>'
- def loadAccountInfo(self, user, req):
- html = req.load("https://webshare.cz/api/user_data/",
- post={'wst': self.infos['wst']},
- decode=True)
+ def parse_info(self, user, password, data, req):
+ html = self.load("https://webshare.cz/api/user_data/",
+ post={'wst': self.get_data(user).get('wst', None)})
- self.logDebug("Response: " + html)
+ self.log_debug("Response: " + html)
expiredate = re.search(self.VALID_UNTIL_PATTERN, html).group(1)
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
validuntil = time.mktime(time.strptime(expiredate, "%Y-%m-%d %H:%M:%S"))
- trafficleft = self.parseTraffic(re.search(self.TRAFFIC_LEFT_PATTERN, html).group(1))
+ trafficleft = self.parse_traffic(re.search(self.TRAFFIC_LEFT_PATTERN, html).group(1))
premium = validuntil > time.time()
return {'validuntil': validuntil, 'trafficleft': -1, 'premium': premium}
- def login(self, user, data, req):
- salt = req.load("https://webshare.cz/api/salt/",
- post={'username_or_email': user,
- 'wst' : ""},
- decode=True)
+ def login(self, user, password, data, req):
+ salt = self.load("https://webshare.cz/api/salt/",
+ post={'username_or_email': user,
+ 'wst' : ""})
if "<status>OK</status>" not in salt:
- self.wrongPassword()
+ self.login_fail()
salt = re.search('<salt>(.+)</salt>', salt).group(1)
- password = hashlib.sha1(md5_crypt.encrypt(data["password"], salt=salt)).hexdigest()
+ password = hashlib.sha1(md5_crypt.encrypt(password, salt=salt)).hexdigest()
digest = hashlib.md5(user + ":Webshare:" + password).hexdigest()
- login = req.load("https://webshare.cz/api/login/",
- post={'digest' : digest,
- 'keep_logged_in' : 1,
- 'password' : password,
- 'username_or_email': user,
- 'wst' : ""},
- decode=True)
+ login = self.load("https://webshare.cz/api/login/",
+ post={'digest' : digest,
+ 'keep_logged_in' : 1,
+ 'password' : password,
+ 'username_or_email': user,
+ 'wst' : ""})
if "<status>OK</status>" not in login:
- self.wrongPassword()
+ self.login_fail()
- self.infos['wst'] = re.search('<token>(.+)</token>', login).group(1)
+ data['wst'] = re.search('<token>(.+)</token>', login).group(1)
diff --git a/module/plugins/accounts/WorldbytezCom.py b/module/plugins/accounts/WorldbytezCom.py
new file mode 100644
index 000000000..ea409fd58
--- /dev/null
+++ b/module/plugins/accounts/WorldbytezCom.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.XFSAccount import XFSAccount
+
+
+class WorldbytezCom(XFSAccount):
+ __name__ = "WorldbytezCom"
+ __type__ = "account"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __description__ = """Worldbytez.com account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ HOSTER_DOMAIN = "worldbytez.com"
diff --git a/module/plugins/accounts/XFileSharingPro.py b/module/plugins/accounts/XFileSharingPro.py
index 8dc7f3a30..f21247cf4 100644
--- a/module/plugins/accounts/XFileSharingPro.py
+++ b/module/plugins/accounts/XFileSharingPro.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSAccount import XFSAccount
class XFileSharingPro(XFSAccount):
__name__ = "XFileSharingPro"
__type__ = "account"
- __version__ = "0.06"
+ __version__ = "0.09"
+ __status__ = "testing"
__description__ = """XFileSharingPro multi-purpose account plugin"""
__license__ = "GPLv3"
@@ -16,19 +17,10 @@ class XFileSharingPro(XFSAccount):
HOSTER_DOMAIN = None
- def init(self):
- if self.HOSTER_DOMAIN:
- return super(XFileSharingPro, self).init()
+ def login(self, user, password, data, req):
+ try:
+ return super(XFileSharingPro, self).login(user, data, req)
-
- def loadAccountInfo(self, user, req):
- return super(XFileSharingPro if self.HOSTER_DOMAIN else XFSAccount, self).loadAccountInfo(user, req)
-
-
- def login(self, user, data, req):
- if self.HOSTER_DOMAIN:
- try:
- return super(XFileSharingPro, self).login(user, data, req)
- except Exception:
- self.HOSTER_URL = self.HOSTER_URL.replace("www.", "")
- return super(XFileSharingPro, self).login(user, data, req)
+ except Fail:
+ self.HOSTER_URL = self.HOSTER_URL.replace("www.", "")
+ return super(XFileSharingPro, self).login(user, data, req)
diff --git a/module/plugins/accounts/YibaishiwuCom.py b/module/plugins/accounts/YibaishiwuCom.py
index 33602a2fe..c5dda0921 100644
--- a/module/plugins/accounts/YibaishiwuCom.py
+++ b/module/plugins/accounts/YibaishiwuCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class YibaishiwuCom(Account):
__name__ = "YibaishiwuCom"
__type__ = "account"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__description__ = """115.com account plugin"""
__license__ = "GPLv3"
@@ -18,23 +19,22 @@ class YibaishiwuCom(Account):
ACCOUNT_INFO_PATTERN = r'var USER_PERMISSION = {(.*?)}'
- def loadAccountInfo(self, user, req):
- #self.relogin(user)
- html = req.load("http://115.com/", decode=True)
+ def parse_info(self, user, password, data, req):
+ # self.relogin(user)
+ html = self.load("http://115.com/")
m = re.search(self.ACCOUNT_INFO_PATTERN, html, re.S)
premium = True if m and 'is_vip: 1' in m.group(1) else False
validuntil = trafficleft = (-1 if m else 0)
- return dict({"validuntil": validuntil, "trafficleft": trafficleft, "premium": premium})
+ return dict({'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium})
- def login(self, user, data, req):
- html = req.load("http://passport.115.com/?ac=login",
- post={"back": "http://www.115.com/",
- "goto": "http://115.com/",
- "login[account]": user,
- "login[passwd]": data['password']},
- decode=True)
+ def login(self, user, password, data, req):
+ html = self.load("https://passport.115.com/?ac=login",
+ post={'back' : "http://www.115.com/",
+ 'goto' : "http://115.com/",
+ "login[account]": user,
+ "login[passwd]" : password})
if not 'var USER_PERMISSION = {' in html:
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/accounts/ZeveraCom.py b/module/plugins/accounts/ZeveraCom.py
index 9bc6d0487..4138ba3cc 100644
--- a/module/plugins/accounts/ZeveraCom.py
+++ b/module/plugins/accounts/ZeveraCom.py
@@ -2,13 +2,14 @@
import time
-from module.plugins.Account import Account
+from module.plugins.internal.Account import Account
class ZeveraCom(Account):
__name__ = "ZeveraCom"
__type__ = "account"
- __version__ = "0.26"
+ __version__ = "0.28"
+ __status__ = "testing"
__description__ = """Zevera.com account plugin"""
__license__ = "GPLv3"
@@ -26,13 +27,13 @@ class ZeveraCom(Account):
def init(self):
if not self.HOSTER_DOMAIN:
- self.logError(_("Missing HOSTER_DOMAIN"))
+ self.log_error(_("Missing HOSTER_DOMAIN"))
if not hasattr(self, "API_URL"):
self.API_URL = "http://api.%s/jDownloader.ashx" % (self.HOSTER_DOMAIN or "")
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = None
premium = False
@@ -47,12 +48,12 @@ class ZeveraCom(Account):
return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium}
- def login(self, user, data, req):
+ def login(self, user, password, data, req):
self.user = user
- self.password = data['password']
+ self.password = password
if self.api_response(req) == "No trafic":
- self.wrongPassword()
+ self.login_fail()
def api_response(self, req, just_header=False, **kwargs):
@@ -62,12 +63,11 @@ class ZeveraCom(Account):
get_data.update(kwargs)
- res = req.load(self.API_URL,
- get=get_data,
- just_header=just_header,
- decode=True)
+ res = self.load(self.API_URL,
+ get=get_data,
+ just_header=just_header)
- self.logDebug(res)
+ self.log_debug(res)
if ':' in res:
if not just_header:
diff --git a/module/plugins/internal/AdYouLike.py b/module/plugins/captcha/AdYouLike.py
index a9c194dda..f91b5805c 100644
--- a/module/plugins/internal/AdYouLike.py
+++ b/module/plugins/captcha/AdYouLike.py
@@ -3,13 +3,14 @@
import re
from module.common.json_layer import json_loads
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class AdYouLike(Captcha):
+class AdYouLike(CaptchaService):
__name__ = "AdYouLike"
__type__ = "captcha"
- __version__ = "0.06"
+ __version__ = "0.07"
+ __status__ = "testing"
__description__ = """AdYouLike captcha service plugin"""
__license__ = "GPLv3"
@@ -20,28 +21,28 @@ class AdYouLike(Captcha):
CALLBACK_PATTERN = r'(Adyoulike\.g\._jsonp_\d+)'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.AYL_PATTERN, html)
n = re.search(self.CALLBACK_PATTERN, html)
if m and n:
self.key = (m.group(1).strip(), n.group(1).strip())
- self.logDebug("Ayl: %s | Callback: %s" % self.key)
- return self.key #: key is the tuple(ayl, callback)
+ self.log_debug("Ayl: %s | Callback: %s" % self.key)
+ return self.key #: Key is the tuple(ayl, callback)
else:
- self.logWarning("Ayl or callback pattern not found")
+ self.log_warning(_("Ayl or callback pattern not found"))
return None
- def challenge(self, key=None, html=None):
- ayl, callback = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None):
+ ayl, callback = key or self.retrieve_key(data)
- # {"adyoulike":{"key":"P~zQ~O0zV0WTiAzC-iw0navWQpCLoYEP"},
- # "all":{"element_id":"ayl_private_cap_92300","lang":"fr","env":"prod"}}
+ #: {'adyoulike':{'key':"P~zQ~O0zV0WTiAzC-iw0navWQpCLoYEP"},
+ #: 'all':{'element_id':"ayl_private_cap_92300",'lang':"fr",'env':"prod"}}
ayl = json_loads(ayl)
- html = self.plugin.req.load("http://api-ayl.appspot.com/challenge",
+ html = self.plugin.load("http://api-ayl.appspot.com/challenge",
get={'key' : ayl['adyoulike']['key'],
'env' : ayl['all']['env'],
'callback': callback})
@@ -51,21 +52,21 @@ class AdYouLike(Captcha):
except AttributeError:
self.fail(_("AdYouLike challenge pattern not found"))
- self.logDebug("Challenge: %s" % challenge)
+ self.log_debug("Challenge: %s" % challenge)
return self.result(ayl, challenge), challenge
def result(self, server, challenge):
- # Adyoulike.g._jsonp_5579316662423138
- # ({"translations":{"fr":{"instructions_visual":"Recopiez « Soonnight » ci-dessous :"}},
- # "site_under":true,"clickable":true,"pixels":{"VIDEO_050":[],"DISPLAY":[],"VIDEO_000":[],"VIDEO_100":[],
- # "VIDEO_025":[],"VIDEO_075":[]},"medium_type":"image/adyoulike",
- # "iframes":{"big":"<iframe src=\"http://www.soonnight.com/campagn.html\" scrolling=\"no\"
- # height=\"250\" width=\"300\" frameborder=\"0\"></iframe>"},"shares":{},"id":256,
- # "token":"e6QuI4aRSnbIZJg02IsV6cp4JQ9~MjA1","formats":{"small":{"y":300,"x":0,"w":300,"h":60},
- # "big":{"y":0,"x":0,"w":300,"h":250},"hover":{"y":440,"x":0,"w":300,"h":60}},
- # "tid":"SqwuAdxT1EZoi4B5q0T63LN2AkiCJBg5"})
+ #: Adyoulike.g._jsonp_5579316662423138
+ #: ({'translations':{'fr':{'instructions_visual':"Recopiez « Soonnight » ci-dessous :"}},
+ #: 'site_under':true,'clickable':true,'pixels':{'VIDEO_050':[],'DISPLAY':[],'VIDEO_000':[],'VIDEO_100':[],
+ #: 'VIDEO_025':[],'VIDEO_075':[]},'medium_type':"image/adyoulike",
+ #: 'iframes':{'big':"<iframe src=\"http://www.soonnight.com/campagn.html\" scrolling=\"no\"
+ #: height=\"250\" width=\"300\" frameborder=\"0\"></iframe>"},'shares':{},'id':256,
+ #: 'token':"e6QuI4aRSnbIZJg02IsV6cp4JQ9~MjA1",'formats':{'small':{'y':300,'x':0,'w':300,'h':60},
+ #: 'big':{'y':0,'x':0,'w':300,'h':250},'hover':{'y':440,'x':0,'w':300,'h':60}},
+ #: 'tid':"SqwuAdxT1EZoi4B5q0T63LN2AkiCJBg5"})
if isinstance(server, basestring):
server = json_loads(server)
@@ -86,6 +87,6 @@ class AdYouLike(Captcha):
'_ayl_token_challenge': challenge['token'],
'_ayl_response' : response}
- self.logDebug("Result: %s" % result)
+ self.log_debug("Result: %s" % result)
return result
diff --git a/module/plugins/internal/AdsCaptcha.py b/module/plugins/captcha/AdsCaptcha.py
index 9cab99151..613283e53 100644
--- a/module/plugins/internal/AdsCaptcha.py
+++ b/module/plugins/captcha/AdsCaptcha.py
@@ -3,13 +3,14 @@
import random
import re
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class AdsCaptcha(Captcha):
+class AdsCaptcha(CaptchaService):
__name__ = "AdsCaptcha"
__type__ = "captcha"
- __version__ = "0.09"
+ __version__ = "0.10"
+ __status__ = "testing"
__description__ = """AdsCaptcha captcha service plugin"""
__license__ = "GPLv3"
@@ -20,24 +21,24 @@ class AdsCaptcha(Captcha):
PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?PublicKey=([\w-]+)'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.PUBLICKEY_PATTERN, html)
n = re.search(self.CAPTCHAID_PATTERN, html)
if m and n:
- self.key = (m.group(1).strip(), n.group(1).strip()) #: key is the tuple(PublicKey, CaptchaId)
- self.logDebug("Key: %s | ID: %s" % self.key)
+ self.key = (m.group(1).strip(), n.group(1).strip()) #: Key is the tuple(PublicKey, CaptchaId)
+ self.log_debug("Key: %s | ID: %s" % self.key)
return self.key
else:
- self.logWarning("Key or id pattern not found")
+ self.log_warning(_("Key or id pattern not found"))
return None
- def challenge(self, key=None, html=None):
- PublicKey, CaptchaId = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None):
+ PublicKey, CaptchaId = key or self.retrieve_key(data)
- html = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx",
+ html = self.plugin.load("http://api.adscaptcha.com/Get.aspx",
get={'CaptchaId': CaptchaId,
'PublicKey': PublicKey})
try:
@@ -47,17 +48,17 @@ class AdsCaptcha(Captcha):
except AttributeError:
self.fail(_("AdsCaptcha challenge pattern not found"))
- self.logDebug("Challenge: %s" % challenge)
+ self.log_debug("Challenge: %s" % challenge)
return self.result(server, challenge), challenge
def result(self, server, challenge):
- result = self.plugin.decryptCaptcha("%sChallenge.aspx" % server,
- get={'cid': challenge, 'dummy': random.random()},
- cookies=True,
- imgtype="jpg")
+ result = self.decrypt("%sChallenge.aspx" % server,
+ get={'cid': challenge, 'dummy': random.random()},
+ cookies=True,
+ input_type="jpg")
- self.logDebug("Result: %s" % result)
+ self.log_debug("Result: %s" % result)
return result
diff --git a/module/plugins/captcha/CircleCaptcha.py b/module/plugins/captcha/CircleCaptcha.py
index d4f08018d..dc04a04c8 100644
--- a/module/plugins/captcha/CircleCaptcha.py
+++ b/module/plugins/captcha/CircleCaptcha.py
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
+#
+#@TODO: Recheck all
from __future__ import division
@@ -9,7 +11,7 @@ import math
import operator
import urllib
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class ImageSequence:
@@ -29,7 +31,8 @@ class ImageSequence:
class CircleCaptcha(OCR):
__name__ = "CircleCaptcha"
__type__ = "ocr"
- __version__ = "1.00"
+ __version__ = "1.04"
+ __status__ = "testing"
__description__ = """Circle captcha ocr plugin"""
__license__ = "GPLv3"
@@ -43,11 +46,11 @@ class CircleCaptcha(OCR):
BLACKCOLOR = 5
- def cleanImage(self, im, pix):
+ def clean_image(self, im, pix):
cleandeep = 1
- imageheight = range(1,int(im.size[1]))
- imagewidth = range(1,int(im.size[0]))
+ imageheight = xrange(1, int(im.size[1]))
+ imagewidth = xrange(1, int(im.size[0]))
howmany = 0
curcolor = self.BACKGROUND
@@ -55,184 +58,184 @@ class CircleCaptcha(OCR):
jump = True
howmany = 0
for x in imagewidth:
- curpix = pix[x,y]
+ curpix = pix[x, y]
if curpix > self.BACKGROUND:
if howmany <= cleandeep and howmany > 0:
- # clean pixel
- for ic in range(1,cleandeep+1):
+ #: Clean pixel
+ for ic in xrange(1, cleandeep+1):
if x -ic > 0:
- pix[x-ic,y] = self.BACKGROUND
+ pix[x-ic, y] = self.BACKGROUND
jump = False
howmany = 0
curcolor = curpix
- # print (x, y), jump,2
+ # self.log_debug(x, y, jump, 2)
else:
if howmany == 0:
- # found pixel
+ #: Found pixel
jump = True
howmany = howmany + 1
curcolor = curpix
- # print (x, y), jump,2
+ # self.log_debug(x, y, jump, 2)
else:
howmany = howmany + 1
if howmany == 1:
- # clean pixel
- pix[x-1,y] = self.BACKGROUND
+ #: Clean pixel
+ pix[x-1, y] = self.BACKGROUND
curcolor = self.BACKGROUND
for x in imagewidth:
jump = True
howmany = 0
for y in imageheight:
- curpix = pix[x,y]
- # if jump == True:
+ curpix = pix[x, y]
+ # if jump is True:
if curpix > self.BACKGROUND:
if howmany <= cleandeep and howmany > 0:
- # clean pixel
- for ic in range(1,cleandeep+1):
- # raw_input('2'+str(ic))
+ #: Clean pixel
+ for ic in xrange(1, cleandeep+1):
+ #: raw_input('2'+str(ic))
if y-ic > 0:
- pix[x,y-ic] = self.BACKGROUND
+ pix[x, y-ic] = self.BACKGROUND
jump = False
howmany = 0
curcolor = curpix
- # print (x, y), jump
+ # self.log_debug(x, y, jump)
else:
if howmany == 0:
- # found pixel
+ #: Found pixel
jump = True
howmany = howmany + 1
curcolor = curpix
- # print (x, y), jump
+ # self.log_debug(x, y, jump)
else:
howmany = howmany + 1
if howmany == 1:
- # clean pixel
- pix[x-1,y] = self.BACKGROUND
+ #: Clean pixel
+ pix[x-1, y] = self.BACKGROUND
- # return -1
+ #: return -1
- def findFirstPixelX(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
- imageheight = range(1,int(im.size[1]))
- imagewidth = range(curx+1,int(im.size[0]))
+ def find_first_pixel_x(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
+ imageheight = xrange(1, int(im.size[1]))
+ imagewidth = xrange(curx+1, int(im.size[0]))
jump = True
- newx = (-1,-1)
+ newx = (-1, -1)
blackfound = 0
for x in imagewidth:
- curpix = pix[x,cury]
+ curpix = pix[x, cury]
if curpix < self.BLACKCOLOR:
blackfound = blackfound + 1
- if ExitWithBlack == True and blackfound >= 3:
- break; #exit if found black
+ if ExitWithBlack is True and blackfound >= 3:
+ break #: Exit if found black
else:
- continue;
+ continue
if curpix >= self.BACKGROUND:
- # found first pixel white
+ #: Found first pixel white
jump = False
- continue;
+ continue
- if (curpix < self.BACKGROUND and color == -1) or (curpix == color and color > -1):
- if jump == False:
- # found pixel
+ if (curpix < self.BACKGROUND and color == -1) or (curpix is color and color > -1):
+ if jump is False:
+ #: Found pixel
curcolor = curpix
newx = x, curcolor
- break;
+ break
return newx
- def findLastPixelX(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
- imageheight = range(1,int(im.size[1]))
- imagewidth = range(curx+1,int(im.size[0]))
- newx = (-1,-1)
+ def find_last_pixel_x(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
+ imageheight = xrange(1, int(im.size[1]))
+ imagewidth = xrange(curx+1, int(im.size[0]))
+ newx = (-1, -1)
blackfound = 0
for x in imagewidth:
- curpix = pix[x,cury]
+ curpix = pix[x, cury]
if curpix < self.BLACKCOLOR:
blackfound = blackfound + 1
- if ExitWithBlack == True and blackfound >= 3:
- break; #exit if found black
+ if ExitWithBlack is True and blackfound >= 3:
+ break #: Exit if found black
else:
- continue;
+ continue
if curpix >= self.BACKGROUND:
- if newx != (-1,-1):
- # found last pixel and the first white
- break;
+ if newx != (-1, -1):
+ #: Found last pixel and the first white
+ break
- if (curpix < self.BACKGROUND and color == -1) or (curpix == color and color > -1):
- # found pixel
+ if (curpix < self.BACKGROUND and color == -1) or (curpix is color and color > -1):
+ #: Found pixel
curcolor = curpix
newx = x, curcolor
return newx
- def findLastPixelY(self, im, pix, curx, cury, DownToUp, color = -1, ExitWithBlack = False):
- if DownToUp == False:
- imageheight = range(int(cury)+1,int(im.size[1])-1)
+ def find_last_pixel_y(self, im, pix, curx, cury, DownToUp, color = -1, ExitWithBlack = False):
+ if DownToUp is False:
+ imageheight = xrange(int(cury)+1, int(im.size[1])-1)
else:
- imageheight = range(int(cury)-1,1,-1)
- imagewidth = range(int(curx),int(im.size[0]))
- newy = (-1,-1)
+ imageheight = xrange(int(cury)-1, 1, -1)
+ imagewidth = xrange(int(curx), int(im.size[0]))
+ newy = (-1, -1)
blackfound = 0
for y in imageheight:
- curpix = pix[curx,y]
+ curpix = pix[curx, y]
if curpix < self.BLACKCOLOR:
blackfound = blackfound + 1
- if ExitWithBlack == True and blackfound >= 3:
- break; #exit if found black
+ if ExitWithBlack is True and blackfound >= 3:
+ break #: Exit if found black
else:
- continue;
+ continue
if curpix >= self.BACKGROUND:
- if newy != (-1,-1):
- # found last pixel and the first white
- break;
+ if newy != (-1, -1):
+ #: Found last pixel and the first white
+ break
- if (curpix < self.BACKGROUND and color == -1) or (curpix == color and color > -1):
- # found pixel
+ if (curpix < self.BACKGROUND and color == -1) or (curpix is color and color > -1):
+ #: Found pixel
curcolor = curpix
newy = y, color
return newy
- def findCircle(self, pix, x1, y1, x2, y2, x3, y3):
- # trasposizione coordinate
- # A(0,0) B(x2-x1,y2-y1) C(x3-x1,y3-y1)
- # x**2+y**2+ax+bx+c=0
- p1 = (0,0)
- p2 = (x2-x1,y2-y1)
- p3 = (x3-x1,y3-y1)
+ def find_circle(self, pix, x1, y1, x2, y2, x3, y3):
+ #: Trasposizione coordinate
+ #: A(0, 0) B(x2-x1, y2-y1) C(x3-x1, y3-y1)
+ #: x**2+y**2+ax+bx+c=0
+ p1 = (0, 0)
+ p2 = (x2-x1, y2-y1)
+ p3 = (x3-x1, y3-y1)
- # 1
+ #: 1
c=0
- # 2
- # p2[0]**2+a*p2[0]+c=0
- # a*p2[0]=-1*(p2[0]**2-c)
- # a=(-1*(p2[0]**2-c))/p2[0]
+ #: 2
+ #: p2[0]**2+a*p2[0]+c=0
+ #: a*p2[0]=-1*(p2[0]**2-c)
+ #: a=(-1*(p2[0]**2-c))/p2[0]
a=(-1*(p2[0]**2-c))/p2[0]
- # 3
- # p3[0]**2+p3[1]**2+a*p3[0]+b*p3[1]+c=0
- # b*p3[1]=-(p3[0]**2+p3[1]**2+a*p3[0]+c)
- # b=(-1 * (p3[0]**2+p3[1]**2+a*p3[0]+c)) / p3[1]
+ #: 3
+ #: p3[0]**2+p3[1]**2+a*p3[0]+b*p3[1]+c=0
+ #: b*p3[1]=-(p3[0]**2+p3[1]**2+a*p3[0]+c)
+ #: b=(-1 * (p3[0]**2+p3[1]**2+a*p3[0]+c)) / p3[1]
b=(-1 * (p3[0]**2+p3[1]**2+a*p3[0]+c)) / p3[1]
r=math.floor(math.sqrt((-1*(a/2))**2+(-1*(b/2))**2))
cx=math.floor((-1*(a/2))+x1)
cy=math.floor((-1*(b/2))+y1)
- return cx,cy,r
+ return cx, cy, r
- def verifyCircleNew(self, im, pix, c):
+ def verify_circle_new(self, im, pix, c):
"""
This is the MAIN function to recognize the circle
returns:
@@ -241,9 +244,8 @@ class CircleCaptcha(OCR):
-1 -> Not found circle
-2 -> Found black position then leave position
"""
-
- imageheight = range(int(c[1]-c[2]),int(c[1]+c[2]))
- imagewidth = range(int(c[0]-c[2]),int(c[0]+c[2]))
+ imageheight = xrange(int(c[1]-c[2]), int(c[1]+c[2]))
+ imagewidth = xrange(int(c[0]-c[2]), int(c[0]+c[2]))
min_ray = 15
max_ray = 30
@@ -253,68 +255,73 @@ class CircleCaptcha(OCR):
missing = 0
missingconsecutive = 0
missinglist = []
- minX = 0; maxX = 0; minY = 0; maxY = 0
+
+ minX = 0
+ maxX = 0
+ minY = 0
+ maxY = 0
+
pointsofcircle = []
if (c[2] < min_ray) or (c[2] > max_ray):
return -1
- # check cardinal points (at least 3) (if found i have to leave this position)
- if pix[c[0] + c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0] - c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] + c[2]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] - c[2]] < self.BLACKCOLOR:
- return -2;
+ #: Check cardinal points (at least 3) (if found i have to leave this position)
+ if pix[c[0] + c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0] - c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] + c[2]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] - c[2]] < self.BLACKCOLOR:
+ return -2
cardinalpoints = 0
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0] - c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],True) == 1:
+ if self.verify_point(im, pix, c[0] - c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] + c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],True) == 1:
+ if self.verify_point(im, pix, c[0], c[1] + c[2], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] - c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],False) == -1:
- return -2;
+ if self.verify_point(im, pix, c[0], c[1] - c[2], False) == -1:
+ return -2
if cardinalpoints < 3:
- return -1;
+ return -1
for x in imagewidth:
- # Pitagora
+ #: Pitagora
y = int(round(c[1]- math.sqrt(c[2]**2-(c[0]-x)**2)))
y2= int(round(c[1]+ math.sqrt(c[2]**2-(c[0]-x)**2)))
howmany = howmany + 2
- if self.verifyPoint(im, pix, x,y,exactfind) == 0:
+ if self.verify_point(im, pix, x, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y))
+ missinglist.append((x, y))
else:
- pointsofcircle.append((x,y))
+ pointsofcircle.append((x, y))
- if self.verifyPoint(im, pix, x,y,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y, False) == -1:
+ return -2
- if self.verifyPoint(im, pix, x,y2,exactfind) == 0:
+ if self.verify_point(im, pix, x, y2, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y2))
+ missinglist.append((x, y2))
else:
- pointsofcircle.append((x,y2))
+ pointsofcircle.append((x, y2))
- if self.verifyPoint(im, pix, x,y2,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y2, False) == -1:
+ return -2
- def verifyCircle(self, im, pix, c):
+ def verify_circle(self, im, pix, c):
"""
This is the MAIN function to recognize the circle
returns:
@@ -323,9 +330,8 @@ class CircleCaptcha(OCR):
-1 -> Not found circle
-2 -> Found black position then leave position
"""
-
- imageheight = range(int(c[1]-c[2]),int(c[1]+c[2]))
- imagewidth = range(int(c[0]-c[2]),int(c[0]+c[2]))
+ imageheight = xrange(int(c[1]-c[2]), int(c[1]+c[2]))
+ imagewidth = xrange(int(c[0]-c[2]), int(c[0]+c[2]))
min_ray = 15
max_ray = 30
@@ -335,119 +341,124 @@ class CircleCaptcha(OCR):
missing = 0
missingconsecutive = 0
missinglist = []
- minX = 0; maxX = 0; minY = 0; maxY = 0
+
+ minX = 0
+ maxX = 0
+ minY = 0
+ maxY = 0
+
pointsofcircle = []
if (c[2] < min_ray) or (c[2] > max_ray):
return -1
- # check cardinal points (at least 3) (if found i have to leave this position)
- if pix[c[0] + c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0] - c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] + c[2]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] - c[2]] < self.BLACKCOLOR:
- return -2;
+ #: Check cardinal points (at least 3) (if found i have to leave this position)
+ if pix[c[0] + c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0] - c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] + c[2]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] - c[2]] < self.BLACKCOLOR:
+ return -2
cardinalpoints = 0
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0] - c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],True) == 1:
+ if self.verify_point(im, pix, c[0] - c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] + c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],True) == 1:
+ if self.verify_point(im, pix, c[0], c[1] + c[2], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] - c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],False) == -1:
- return -2;
+ if self.verify_point(im, pix, c[0], c[1] - c[2], False) == -1:
+ return -2
if cardinalpoints < 3:
- return -1;
+ return -1
for x in imagewidth:
- # Pitagora
+ #: Pitagora
y = int(round(c[1]- math.sqrt(c[2]**2-(c[0]-x)**2)))
y2= int(round(c[1]+ math.sqrt(c[2]**2-(c[0]-x)**2)))
howmany = howmany + 2
- if self.verifyPoint(im, pix, x,y,exactfind) == 0:
+ if self.verify_point(im, pix, x, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y))
+ missinglist.append((x, y))
else:
- pointsofcircle.append((x,y))
+ pointsofcircle.append((x, y))
- if self.verifyPoint(im, pix, x,y,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y, False) == -1:
+ return -2
- if self.verifyPoint(im, pix, x,y2,exactfind) == 0:
+ if self.verify_point(im, pix, x, y2, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y2))
+ missinglist.append((x, y2))
else:
- pointsofcircle.append((x,y2))
+ pointsofcircle.append((x, y2))
- if self.verifyPoint(im, pix, x,y2,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y2, False) == -1:
+ return -2
for y in imageheight:
- # Pitagora
+ #: Pitagora
x = int(round(c[0]- math.sqrt(c[2]**2-(c[1]-y)**2)))
x2= int(round(c[0]+ math.sqrt(c[2]**2-(c[1]-y)**2)))
howmany = howmany + 2
- if self.verifyPoint(im, pix, x,y,exactfind) == 0:
+ if self.verify_point(im, pix, x, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y))
+ missinglist.append((x, y))
else:
- pointsofcircle.append((x,y))
+ pointsofcircle.append((x, y))
- if self.verifyPoint(im, pix, x,y,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y, False) == -1:
+ return -2
- if self.verifyPoint(im, pix, x2,y,exactfind) == 0:
+ if self.verify_point(im, pix, x2, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x2,y))
+ missinglist.append((x2, y))
else:
- pointsofcircle.append((x2,y))
+ pointsofcircle.append((x2, y))
- if self.verifyPoint(im, pix, x2,y,exactfind) == -1:
- return -2;
+ if self.verify_point(im, pix, x2, y, exactfind) == -1:
+ return -2
for p in missinglist:
- # left and bottom
- if (self.verifyPoint(im, pix, p[0]-1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]+1,exactfind) == 1):
+ #: Left and bottom
+ if (self.verify_point(im, pix, p[0]-1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]+1, exactfind) == 1):
missing = missing - 1
- elif (self.verifyPoint(im, pix, p[0]-1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]-1,exactfind) == 1):
+ elif (self.verify_point(im, pix, p[0]-1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]-1, exactfind) == 1):
missing = missing - 1
- # right and bottom
- elif (self.verifyPoint(im, pix, p[0]+1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]+1,exactfind) == 1):
+ #: Right and bottom
+ elif (self.verify_point(im, pix, p[0]+1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]+1, exactfind) == 1):
missing = missing - 1
- # right and up
- elif (self.verifyPoint(im, pix, p[0]+1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]-1,exactfind) == 1):
+ #: Right and up
+ elif (self.verify_point(im, pix, p[0]+1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]-1, exactfind) == 1):
missing = missing - 1
- if (p[0], p[1]+1) in missinglist or \
- (p[0], p[1]-1) in missinglist or \
- (p[0]+1, p[1]) in missinglist or \
- (p[0]-1, p[1]) in missinglist or \
- (p[0]+1, p[1]+1) in missinglist or \
- (p[0]-1, p[1]+1) in missinglist or \
- (p[0]+1, p[1]-1) in missinglist or \
- (p[0]-1, p[1]-1) in missinglist or \
- self.verifyPoint(im, pix, p[0], p[1],False) == 1:
+ if ((p[0], p[1]+1) in missinglist
+ or (p[0], p[1]-1) in missinglist
+ or (p[0]+1, p[1]) in missinglist
+ or (p[0]-1, p[1]) in missinglist
+ or (p[0]+1, p[1]+1) in missinglist
+ or (p[0]-1, p[1]+1) in missinglist
+ or (p[0]+1, p[1]-1) in missinglist
+ or (p[0]-1, p[1]-1) in missinglist
+ or self.verify_point(im, pix, p[0], p[1], False) == 1):
missingconsecutive = missingconsecutive + 1
# else:
- # pix[p[0], p[1]] = 0
+ # pix[p[0], p[1]] = 0
if missing / howmany > 0:
indice = c[2] * (missing / howmany)
@@ -461,80 +472,79 @@ class CircleCaptcha(OCR):
minY = min(missinglist, key=operator.itemgetter(1))[1]
maxY = max(missinglist, key=operator.itemgetter(1))[1]
- # Assial Simmetric
- if self._DEBUG == True:
- print "Center: " + str(c)
- print "Missing: " + str(missing)
- print "Howmany: " + str(howmany)
- print "Ratio: " + str(missing / howmany)
- print "Missing consecutives: " + str(missingconsecutive)
- print "Missing X lenght: " + str(minX) + ":" + str(maxX)
- print "Missing Y lenght: " + str(minY) + ":" + str(maxY)
- print "Ratio without consecutives: " + str((missing - missingconsecutive) / howmany)
- print "List missing: " + str(missinglist)
+ #: Assial Simmetric
+ if self.pyload.debug:
+ self.log_debug("Center: " + str(c),
+ "Missing: " + str(missing),
+ "Howmany: " + str(howmany),
+ "Ratio: " + str(missing / howmany),
+ "Missing consecutives: " + str(missingconsecutive),
+ "Missing X lenght: " + str(minX) + ":" + str(maxX),
+ "Missing Y lenght: " + str(minY) + ":" + str(maxY),
+ "Ratio without consecutives: " + str((missing - missingconsecutive) / howmany),
+ "List missing: " + str(missinglist))
- # Lenght of missing cannot be over 75% of diameter
+ #: Lenght of missing cannot be over 75% of diameter
if maxX - minX >= c[2] * 2 * 0.75:
- return -1;
+ return -1
if maxY - minY >= c[2] * 2 * 0.75:
- # raw_input('tro')
- return -1;
+ #: raw_input('tro')
+ return -1
"""
- # Lenght of missing cannot be less 10% of diameter
+ #: Lenght of missing cannot be less 10% of diameter
if maxX - minX < c[2] * 2 * 0.10 and maxY - minY < c[2] * 2 * 0.10:
- return -1;
+ return -1
"""
-
if missing / howmany > 0.25 or \
missingconsecutive >= (howmany / 4) * 2 or \
howmany < 80:
- return -1;
+ return -1
# elif missing / howmany < 0.10:
elif missing == 0:
self.pointsofcirclefound.extend(pointsofcircle)
- return 1;
+ return 1
elif (missing - missingconsecutive) / howmany < 0.20:
- return 0;
+ return 0
else:
self.pointsofcirclefound.extend(pointsofcircle)
- return 1;
+ return 1
- def verifyPoint(self, im, pix, x,y,exact,color = -1):
- # Verify point
+ def verify_point(self, im, pix, x, y, exact, color = -1):
+ #: Verify point
result = 0
if x < 0 or x >= im.size[0]:
- return result;
+ return result
if y < 0 or y >= im.size[1]:
- return result;
+ return result
- curpix = pix[x,y]
- if (curpix == color and color > -1) or (curpix < self.BACKGROUND and color == -1):
+ curpix = pix[x, y]
+ if (curpix is color and color > -1) or (curpix < self.BACKGROUND and color == -1):
if curpix > self.BLACKCOLOR:
result = 1
else:
result = -1
- # Verify around
- if (exact == False):
+ #: Verify around
+ if exact is False:
if x + 1 < im.size[0]:
- curpix = pix[x+1,y]
- if (curpix == color and color > -1) or (curpix < self.BACKGROUND and color == -1):
+ curpix = pix[x+1, y]
+ if (curpix is color and color > -1) or (curpix < self.BACKGROUND and color == -1):
if curpix > self.BLACKCOLOR:
result = 1
if curpix <= self.BLACKCOLOR:
result = -1
if x > 0:
- curpix = pix[x-1,y]
- if (curpix == color and color > -1) or (curpix < self.BACKGROUND and color == -1):
+ curpix = pix[x-1, y]
+ if (curpix is color and color > -1) or (curpix < self.BACKGROUND and color == -1):
if curpix > self.BLACKCOLOR:
result = 1
if curpix <= self.BLACKCOLOR:
result = -1
- # print str((x,y)) + " = " + str(result);
+ # self.log_debug(str((x, y)) + " = " + str(result))
return result
@@ -543,22 +553,23 @@ class CircleCaptcha(OCR):
mypalette = None
for im in ImageSequence(img):
im.save("orig.png", "png")
- if mypalette != None:
+ if mypalette is not None:
im.putpalette(mypalette)
mypalette = im.getpalette()
im = im.convert('L')
- if self._DEBUG == True:
+ if self.pyload.debug:
iDebugSaveFile = iDebugSaveFile + 1
- # if iDebugSaveFile < 7: continue;
+ # if iDebugSaveFile < 7:
+ # continue
im.save("output" + str(iDebugSaveFile) + ".png", "png")
raw_input('frame: '+ str(im))
pix = im.load()
- stepheight = range(1,im.size[1],2)
- # stepheight = range(45,47)
- imagewidth = range(1,im.size[0])
+ stepheight = xrange(1, im.size[1], 2)
+ #: stepheight = xrange(45, 47)
+ imagewidth = xrange(1, im.size[0])
lstPoints = [] # Declares an empty list for the points
lstX = [] # CoordinateX
lstY = [] # CoordinateY
@@ -566,209 +577,211 @@ class CircleCaptcha(OCR):
min_distance = 10
max_diameter = 70
- if self._DEBUG == True:
+ if self.pyload.debug:
imdebug = im.copy()
draw = ImageDraw.Draw(imdebug)
pixcopy = imdebug.load()
- # Clean image for powerfull search
- self.cleanImage(im, pix)
+ #: Clean image for powerfull search
+ self.clean_image(im, pix)
im.save("cleaned" + str(iDebugSaveFile) + ".png", "png")
found = set()
findnewcircle = True
- # finding all the circles
+ #: Finding all the circles
for y1 in stepheight:
x1 = 1
curcolor = -1
- for k in range(1,100):
+ for k in xrange(1, 100):
findnewcircle = False
- retval = self.findFirstPixelX(im, pix, x1, y1, -1, False)
+ retval = self.find_first_pixel_x(im, pix, x1, y1, -1, False)
x1 = retval[0]
curcolor = retval[1]
if x1 == -2:
- break;
+ break
if x1 == -1:
- break;
- if self._DEBUG == True: print "x1, y1 -> " + str((x1,y1)) + ": " + str(pix[x1,y1])
-
- if (x1,y1) in self.pointsofcirclefound:
- if self._DEBUG == True: print 'found ' + str((x1,y1))
- continue;
-
- if self._DEBUG == True: pixcopy[x1,y1] = 45 #(255,0,0,255)
- # found 1 pixel, seeking x2,y2
+ break
+ if self.pyload.debug:
+ self.log_debug("x1, y1 -> " + str((x1, y1)) + ": " + str(pix[x1, y1]))
+
+ if (x1, y1) in self.pointsofcirclefound:
+ if self.pyload.debug:
+ self.log_debug("Found " + str((x1, y1)))
+ continue
+
+ if self.pyload.debug:
+ pixcopy[x1, y1] = 45 #(255, 0, 0, 255)
+ #: found 1 pixel, seeking x2, y2
x2 = x1
y2 = y1
- for i in range(1,100):
- retval = self.findLastPixelX(im, pix, x2, y2, -1, True)
+ for i in xrange(1, 100):
+ retval = self.find_last_pixel_x(im, pix, x2, y2, -1, True)
x2 = retval[0]
if x1 == -2:
findnewcircle = True
- break;
+ break
if x2 == -1:
- break;
- if self._DEBUG == True: print "x2, y2 -> " + str((x2,y1)) + ": " + str(pix[x2,y1])
+ break
+ if self.pyload.debug:
+ self.log_debug("x2, y2 -> " + str((x2, y1)) + ": " + str(pix[x2, y1]))
if abs(x2 - x1) < min_distance:
- continue;
+ continue
if abs(x2 - x1) > (im.size[1] * 2 / 3):
- break;
+ break
if abs(x2 - x1) > max_diameter:
- break;
+ break
- if self._DEBUG == True: pixcopy[x2,y2] = 65 #(0,255,0,255)
- # found 2 pixel, seeking x3,y3
- # verify cord
+ if self.pyload.debug:
+ pixcopy[x2, y2] = 65 #(0, 255, 0, 255)
+ #: found 2 pixel, seeking x3, y3
+ #: Verify cord
- for invert in range(0,2):
+ for invert in xrange(0, 2):
x3 = math.floor(x2 - ((x2 - x1) / 2))
y3 = y1
- for j in range(1,50):
- retval = self.findLastPixelY(im, pix, x3, y3, True if invert == 1 else False, -1, True)
- # print (x3, y3,retval[0],invert)
+ for j in xrange(1, 50):
+ retval = self.find_last_pixel_y(im, pix, x3, y3, True if invert == 1 else False, -1, True)
+ # self.log_debug(x3, y3, retval[0], invert)
y3 = retval[0]
if y3 == -2:
findnewcircle = True
- break;
+ break
if y3 == -1:
- break;
+ break
- if self._DEBUG == True: print "x3, y3 -> " + str((x3,y3)) + ": " + str(pix[x3,y3])
- # verify cord
+ if self.pyload.debug:
+ self.log_debug("x3, y3 -> " + str((x3, y3)) + ": " + str(pix[x3, y3]))
+ #: Verify cord
if abs(y3 - y2) < min_distance:
- continue;
+ continue
if abs(y3 - y2) > (im.size[1] * 2 / 3):
- break;
+ break
if abs(y3 - y2) > max_diameter:
- break;
+ break
- if self._DEBUG == True: pixcopy[x3,y3] = 85
- # found 3 pixel. try circle
- c = self.findCircle(pix, x1,y1,x2,y2,x3,y3)
+ if self.pyload.debug:
+ pixcopy[x3, y3] = 85
+ #: found 3 pixel. try circle
+ c = self.find_circle(pix, x1, y1, x2, y2, x3, y3)
if c[0] + c[2] >= im.size[0] or c[1] + c[2] >= im.size[1] or c[0] - c[2] <= 0 or c[1] - c[2] <= 0:
- continue;
+ continue
- if self._DEBUG == True: pixcopy[c[0],c[1]] = 0
- # (x-r, y-r, x+r, y+r)
- verified = self.verifyCircle(im, pix, c)
+ if self.pyload.debug:
+ pixcopy[c[0], c[1]] = 0
+ #: (x-r, y-r, x+r, y+r)
+ verified = self.verify_circle(im, pix, c)
if verified == -1:
verified = -1
elif verified == 0:
- found.add(((c[0],c[1],c[2]),verified))
+ found.add(((c[0], c[1], c[2]), verified))
findnewcircle = True
elif verified == 1:
- found.add(((c[0],c[1],c[2]),verified))
+ found.add(((c[0], c[1], c[2]), verified))
findnewcircle = True
- if self._DEBUG == True:
+ if self.pyload.debug:
_pause = ""
# if verified == -1:
- # draw.ellipse((c[0]-c[2],c[1]-c[2],c[0]+c[2],c[1]+c[2]),outline=0)
+ # draw.ellipse((c[0]-c[2], c[1]-c[2], c[0]+c[2], c[1]+c[2]), outline=0)
# _pause = "NOTDOUND"
# imdebug.save("debug.png", "png")
if verified == 0:
- draw.ellipse((c[0]-c[2],c[1]-c[2],c[0]+c[2],c[1]+c[2]),outline=120)
+ draw.ellipse((c[0]-c[2], c[1]-c[2], c[0]+c[2], c[1]+c[2]), outline=120)
_pause = "OPENED"
if verified == 1:
- draw.ellipse((c[0]-c[2],c[1]-c[2],c[0]+c[2],c[1]+c[2]),outline=65)
+ draw.ellipse((c[0]-c[2], c[1]-c[2], c[0]+c[2], c[1]+c[2]), outline=65)
_pause = "CLOSED"
imdebug.save("debug.png", "png")
if _pause != "":
valore = raw_input('Found ' + _pause + ' CIRCLE circle press [Enter] = continue / [q] for Quit: ' + str(verified))
- if valore == 'q':
- sys.exit();
+ if valore == "q":
+ sys.exit()
- if findnewcircle == True:
- break;
- if findnewcircle == True:
- break;
- if findnewcircle == True:
- break;
+ if findnewcircle is True:
+ break
+ if findnewcircle is True:
+ break
+ if findnewcircle is True:
+ break
- if self._DEBUG == True:
- print 'Howmany opened circle? ' + str(len(found)) + ' ' + str(found)
+ if self.pyload.debug:
+ self.log_debug('Howmany opened circle? ' + str(len(found)) + ' ' + str(found))
- # clean results
+ #: Clean results
for c in found:
verify = c[1]
if verify == 0:
p = c[0]
- if (
- ((p[0], p[1]+1,p[2]),1) in found or \
- ((p[0], p[1]-1,p[2]),1) in found or \
- ((p[0]+1, p[1],p[2]),1) in found or \
- ((p[0]-1, p[1],p[2]),1) in found or \
- ((p[0]+1, p[1]+1,p[2]),1) in found or \
- ((p[0]-1, p[1]+1,p[2]),1) in found or \
- ((p[0]+1, p[1]-1,p[2]),1) in found or \
- ((p[0]-1, p[1]-1,p[2]),1) in found \
- ):
-
- # delete nearly circle
+ if (((p[0], p[1]+1, p[2]), 1) in found
+ or ((p[0], p[1]-1, p[2]), 1) in found
+ or ((p[0]+1, p[1], p[2]), 1) in found
+ or ((p[0]-1, p[1], p[2]), 1) in found
+ or ((p[0]+1, p[1]+1, p[2]), 1) in found
+ or ((p[0]-1, p[1]+1, p[2]), 1) in found
+ or ((p[0]+1, p[1]-1, p[2]), 1) in found
+ or ((p[0]-1, p[1]-1, p[2]), 1) in found):
+
+ #: Delete nearly circle
verify = -1
- if (
- ((p[0], p[1]+1,p[2]+1),1) in found or \
- ((p[0], p[1]-1,p[2]+1),1) in found or \
- ((p[0]+1, p[1],p[2]+1),1) in found or \
- ((p[0]-1, p[1],p[2]+1),1) in found or \
- ((p[0]+1, p[1]+1,p[2]+1),1) in found or \
- ((p[0]-1, p[1]+1,p[2]+1),1) in found or \
- ((p[0]+1, p[1]-1,p[2]+1),1) in found or \
- ((p[0]-1, p[1]-1,p[2]+1),1) in found \
- ):
-
- # delete nearly circle
+ if (((p[0], p[1]+1, p[2]+1), 1) in found
+ or ((p[0], p[1]-1, p[2]+1), 1) in found
+ or ((p[0]+1, p[1], p[2]+1), 1) in found
+ or ((p[0]-1, p[1], p[2]+1), 1) in found
+ or ((p[0]+1, p[1]+1, p[2]+1), 1) in found
+ or ((p[0]-1, p[1]+1, p[2]+1), 1) in found
+ or ((p[0]+1, p[1]-1, p[2]+1), 1) in found
+ or ((p[0]-1, p[1]-1, p[2]+1), 1) in found):
+
+ #: Delete nearly circle
verify = -1
- if (
- ((p[0], p[1]+1,p[2]-1),1) in found or \
- ((p[0], p[1]-1,p[2]-1),1) in found or \
- ((p[0]+1, p[1],p[2]-1),1) in found or \
- ((p[0]-1, p[1],p[2]-1),1) in found or \
- ((p[0]+1, p[1]+1,p[2]-1),1) in found or \
- ((p[0]-1, p[1]+1,p[2]-1),1) in found or \
- ((p[0]+1, p[1]-1,p[2]-1),1) in found or \
- ((p[0]-1, p[1]-1,p[2]-1),1) in found \
- ):
-
- # delete nearly circle
+ if (((p[0], p[1]+1, p[2]-1), 1) in found
+ or ((p[0], p[1]-1, p[2]-1), 1) in found
+ or ((p[0]+1, p[1], p[2]-1), 1) in found
+ or ((p[0]-1, p[1], p[2]-1), 1) in found
+ or ((p[0]+1, p[1]+1, p[2]-1), 1) in found
+ or ((p[0]-1, p[1]+1, p[2]-1), 1) in found
+ or ((p[0]+1, p[1]-1, p[2]-1), 1) in found
+ or ((p[0]-1, p[1]-1, p[2]-1), 1) in found):
+
+ #: Delete nearly circle
verify = -1
# if verify == 0:
- # if self._DEBUG == True:
- # pix[c[0][0],c[0][1]] = 90 #(255,255,0)
+ # if self.pyload.debug:
+ # pix[c[0][0], c[0][1]] = 90 #(255, 255, 0)
# im.save("output.png", "png")
- # return c[0][0],c[0][1]
+ # return c[0][0], c[0][1]
# elif verify == 1:
- # if self._DEBUG == True:
- # pix[c[0][0],c[0][1]] = 40 #(255,0,0)
+ # if self.pyload.debug:
+ # pix[c[0][0], c[0][1]] = 40 #(255, 0, 0)
# im.save("output.png", "png")
# else:
- # if self._DEBUG == True:
- # pix[c[0][0],c[0][1]] = 180 #(0,0,255)
+ # if self.pyload.debug:
+ # pix[c[0][0], c[0][1]] = 180 #(0, 0, 255)
# im.save("output.png", "png")
- if self._DEBUG == True:
+ if self.pyload.debug:
im.save("output.png", "png")
- # Return coordinates of opened circle (eg (x,y))
+ #: Return coordinates of opened circle (eg (x, y))
def decrypt_from_web(self, url):
file = cStringIO.StringIO(urllib.urlopen(url).read())
img = Image.open(file)
- coords = self.decrypt(img);
- print "Coords: " + str(coords)
+ coords = self.decrypt(img)
+ self.log_info(_("Coords: %s") % coords)
- # Return coordinates of opened circle (eg (x,y))
+ #: Return coordinates of opened circle (eg (x, y))
def decrypt_from_file(self, filename):
- coords = self.decrypt(Image.open(filename)); #Can be many different formats.
- print "Coords: " + str(coords)
+ coords = self.decrypt(Image.open(filename)) #: Can be many different formats.
+ self.log_info(_("Coords: %s") % coords)
##DEBUG
@@ -778,4 +791,4 @@ class CircleCaptcha(OCR):
# coords = x.decrypt_from_file("decripter/captx.html2.gif")
# coords = x.decrypt_from_web("http://ncrypt.in/classes/captcha/circlecaptcha.php")
# b = datetime.datetime.now()
-# print 'Elapsed time: ' + str((b-a).seconds) + ' seconds'
+# self.log_debug("Elapsed time: %s seconds" % (b-a).seconds)
diff --git a/module/plugins/captcha/GigasizeCom.py b/module/plugins/captcha/GigasizeCom.py
index 52c41729b..12f123c41 100644
--- a/module/plugins/captcha/GigasizeCom.py
+++ b/module/plugins/captcha/GigasizeCom.py
@@ -1,23 +1,20 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class GigasizeCom(OCR):
__name__ = "GigasizeCom"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Gigasize.com ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
-
-
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
self.threshold(2.8)
self.run_tesser(True, False, False, True)
diff --git a/module/plugins/captcha/LinksaveIn.py b/module/plugins/captcha/LinksaveIn.py
index 95b107977..4d2e2bc34 100644
--- a/module/plugins/captcha/LinksaveIn.py
+++ b/module/plugins/captcha/LinksaveIn.py
@@ -2,27 +2,28 @@
try:
from PIL import Image
+
except ImportError:
import Image
import glob
import os
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class LinksaveIn(OCR):
__name__ = "LinksaveIn"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Linksave.in ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
+ def init(self):
self.data_dir = os.path.dirname(os.path.abspath(__file__)) + os.sep + "LinksaveIn" + os.sep
@@ -31,7 +32,7 @@ class LinksaveIn(OCR):
frame_nr = 0
lut = im.resize((256, 1))
- lut.putdata(range(256))
+ lut.putdata(xrange(256))
lut = list(lut.convert("RGB").getdata())
new = Image.new("RGB", im.size)
@@ -51,7 +52,7 @@ class LinksaveIn(OCR):
new.save(self.data_dir+"unblacked.png")
self.image = new.copy()
self.pixels = self.image.load()
- self.result_captcha = ''
+ self.result_captcha = ""
def get_bg(self):
@@ -63,11 +64,11 @@ class LinksaveIn(OCR):
bg = Image.open(bgpath)
bglut = bg.resize((256, 1))
- bglut.putdata(range(256))
+ bglut.putdata(xrange(256))
bglut = list(bglut.convert("RGB").getdata())
lut = img.resize((256, 1))
- lut.putdata(range(256))
+ lut.putdata(xrange(256))
lut = list(lut.convert("RGB").getdata())
bgpix = bg.load()
@@ -80,11 +81,11 @@ class LinksaveIn(OCR):
cstat[rgb_c] += 1
except Exception:
cstat[rgb_c] = 1
- if rgb_bg == rgb_c:
+ if rgb_bg is rgb_c:
stat[bgpath] += 1
max_p = 0
bg = ""
- for bgpath, value in stat.iteritems():
+ for bgpath, value in stat.items():
if max_p < value:
bg = bgpath
max_p = value
@@ -96,11 +97,11 @@ class LinksaveIn(OCR):
img = self.image.convert("P")
bglut = bg.resize((256, 1))
- bglut.putdata(range(256))
+ bglut.putdata(xrange(256))
bglut = list(bglut.convert("RGB").getdata())
lut = img.resize((256, 1))
- lut.putdata(range(256))
+ lut.putdata(xrange(256))
lut = list(lut.convert("RGB").getdata())
bgpix = bg.load()
@@ -110,7 +111,7 @@ class LinksaveIn(OCR):
for y in xrange(bg.size[1]):
rgb_bg = bglut[bgpix[x, y]]
rgb_c = lut[pix[x, y]]
- if rgb_c == rgb_bg:
+ if rgb_c is rgb_bg:
orgpix[x, y] = (255, 255, 255)
@@ -136,7 +137,7 @@ class LinksaveIn(OCR):
self.pixels = self.image.load()
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
bg = self.get_bg()
self.substract_bg(bg)
diff --git a/module/plugins/captcha/NetloadIn.py b/module/plugins/captcha/NetloadIn.py
index 1fb258c47..50174684d 100644
--- a/module/plugins/captcha/NetloadIn.py
+++ b/module/plugins/captcha/NetloadIn.py
@@ -1,23 +1,20 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class NetloadIn(OCR):
__name__ = "NetloadIn"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Netload.in ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
-
-
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
self.to_greyscale()
self.clean(3)
diff --git a/module/plugins/internal/ReCaptcha.py b/module/plugins/captcha/ReCaptcha.py
index dea714a62..5931159c5 100644
--- a/module/plugins/internal/ReCaptcha.py
+++ b/module/plugins/captcha/ReCaptcha.py
@@ -7,13 +7,14 @@ import urlparse
from base64 import b64encode
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class ReCaptcha(Captcha):
+class ReCaptcha(CaptchaService):
__name__ = "ReCaptcha"
__type__ = "captcha"
- __version__ = "0.17"
+ __version__ = "0.18"
+ __status__ = "testing"
__description__ = """ReCaptcha captcha service plugin"""
__license__ = "GPLv3"
@@ -22,36 +23,36 @@ class ReCaptcha(Captcha):
("zapp-brannigan", "fuerst.reinje@web.de")]
- KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)'
KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)'
+ KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.KEY_V2_PATTERN, html) or re.search(self.KEY_V1_PATTERN, html)
if m:
self.key = m.group(1).strip()
- self.logDebug("Key: %s" % self.key)
+ self.log_debug("Key: %s" % self.key)
return self.key
else:
- self.logWarning("Key pattern not found")
+ self.log_warning(_("Key pattern not found"))
return None
- def challenge(self, key=None, html=None, version=None):
- key = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None, version=None):
+ key = key or self.retrieve_key(data)
if version in (1, 2):
return getattr(self, "_challenge_v%s" % version)(key)
else:
return self.challenge(key,
- version=2 if re.search(self.KEY_V2_PATTERN, html or self.retrieve_html()) else 1)
+ version=2 if re.search(self.KEY_V2_PATTERN, data or self.retrieve_data()) else 1)
def _challenge_v1(self, key):
- html = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge",
+ html = self.plugin.load("http://www.google.com/recaptcha/api/challenge",
get={'k': key})
try:
challenge = re.search("challenge : '(.+?)',", html).group(1)
@@ -60,14 +61,14 @@ class ReCaptcha(Captcha):
except AttributeError:
self.fail(_("ReCaptcha challenge pattern not found"))
- self.logDebug("Challenge: %s" % challenge)
+ self.log_debug("Challenge: %s" % challenge)
return self.result(server, challenge, key)
def result(self, server, challenge, key):
- self.plugin.req.load("http://www.google.com/recaptcha/api/js/recaptcha.js")
- html = self.plugin.req.load("http://www.google.com/recaptcha/api/reload",
+ self.plugin.load("http://www.google.com/recaptcha/api/js/recaptcha.js")
+ html = self.plugin.load("http://www.google.com/recaptcha/api/reload",
get={'c' : challenge,
'k' : key,
'reason': "i",
@@ -79,50 +80,49 @@ class ReCaptcha(Captcha):
except AttributeError:
self.fail(_("ReCaptcha second challenge pattern not found"))
- self.logDebug("Second challenge: %s" % challenge)
- result = self.plugin.decryptCaptcha("%simage" % server,
- get={'c': challenge},
- cookies=True,
- forceUser=True,
- imgtype="jpg")
+ self.log_debug("Second challenge: %s" % challenge)
+ result = self.decrypt(urlparse.urljoin(server, "image"),
+ get={'c': challenge},
+ cookies=True,
+ input_type="jpg")
- self.logDebug("Result: %s" % result)
+ self.log_debug("Result: %s" % result)
return result, challenge
- def _collectApiInfo(self):
- html = self.plugin.req.load("http://www.google.com/recaptcha/api.js")
+ def _collect_api_info(self):
+ html = self.plugin.load("http://www.google.com/recaptcha/api.js")
a = re.search(r'po.src = \'(.*?)\';', html).group(1)
vers = a.split("/")[5]
- self.logDebug("API version: %s" % vers)
+ self.log_debug("API version: %s" % vers)
language = a.split("__")[1].split(".")[0]
- self.logDebug("API language: %s" % language)
+ self.log_debug("API language: %s" % language)
- html = self.plugin.req.load("https://apis.google.com/js/api.js")
+ html = self.plugin.load("https://apis.google.com/js/api.js")
b = re.search(r'"h":"(.*?)","', html).group(1)
jsh = b.decode('unicode-escape')
- self.logDebug("API jsh-string: %s" % jsh)
+ self.log_debug("API jsh-string: %s" % jsh)
return vers, language, jsh
- def _prepareTimeAndRpc(self):
- self.plugin.req.load("http://www.google.com/recaptcha/api2/demo")
+ def _prepare_time_and_rpc(self):
+ self.plugin.load("http://www.google.com/recaptcha/api2/demo")
millis = int(round(time.time() * 1000))
- self.logDebug("Time: %s" % millis)
+ self.log_debug("Time: %s" % millis)
rand = random.randint(1, 99999999)
a = "0.%s" % str(rand * 2147483647)
rpc = int(100000000 * float(a))
- self.logDebug("Rpc-token: %s" % rpc)
+ self.log_debug("Rpc-token: %s" % rpc)
return millis, rpc
@@ -136,10 +136,10 @@ class ReCaptcha(Captcha):
parent = ""
botguardstring = "!A"
- vers, language, jsh = self._collectApiInfo()
- millis, rpc = self._prepareTimeAndRpc()
+ vers, language, jsh = self._collect_api_info()
+ millis, rpc = self._prepare_time_and_rpc()
- html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor",
+ html = self.plugin.load("https://www.google.com/recaptcha/api2/anchor",
get={'k' : key,
'hl' : language,
'v' : vers,
@@ -150,36 +150,38 @@ class ReCaptcha(Captcha):
'rpctoken': rpc})
token1 = re.search(r'id="recaptcha-token" value="(.*?)">', html)
- self.logDebug("Token #1: %s" % token1.group(1))
-
- html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame",
- get={'c' : token1.group(1),
- 'hl' : language,
- 'v' : vers,
- 'bg' : botguardstring,
- 'k' : key,
- 'usegapi': "1",
- 'jsh' : jsh}).decode('unicode-escape')
+ self.log_debug("Token #1: %s" % token1.group(1))
+
+ html = self.plugin.load("https://www.google.com/recaptcha/api2/frame",
+ get={'c' : token1.group(1),
+ 'hl' : language,
+ 'v' : vers,
+ 'bg' : botguardstring,
+ 'k' : key,
+ 'usegapi': "1",
+ 'jsh' : jsh},
+ decode="unicode-escape")
token2 = re.search(r'"finput","(.*?)",', html)
- self.logDebug("Token #2: %s" % token2.group(1))
+ self.log_debug("Token #2: %s" % token2.group(1))
token3 = re.search(r'"rresp","(.*?)",', html)
- self.logDebug("Token #3: %s" % token3.group(1))
+ self.log_debug("Token #3: %s" % token3.group(1))
millis_captcha_loading = int(round(time.time() * 1000))
- captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload",
- get={'c':token3.group(1), 'k':key},
- cookies=True,
- forceUser=True)
+ captcha_response = self.decrypt("https://www.google.com/recaptcha/api2/payload",
+ get={'c':token3.group(1), 'k':key},
+ cookies=True,
+ ocr=False,
+ timeout=30)
response = b64encode('{"response":"%s"}' % captcha_response)
- self.logDebug("Result: %s" % response)
+ self.log_debug("Result: %s" % response)
timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading
timeToSolveMore = timeToSolve + int(float("0." + str(random.randint(1, 99999999))) * 500)
- html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify",
+ html = self.plugin.load("https://www.google.com/recaptcha/api2/userverify",
post={'k' : key,
'c' : token3.group(1),
'response': response,
@@ -188,7 +190,7 @@ class ReCaptcha(Captcha):
'bg' : botguardstring})
token4 = re.search(r'"uvresp","(.*?)",', html)
- self.logDebug("Token #4: %s" % token4.group(1))
+ self.log_debug("Token #4: %s" % token4.group(1))
result = token4.group(1)
diff --git a/module/plugins/captcha/ShareonlineBiz.py b/module/plugins/captcha/ShareonlineBiz.py
index 6fad66600..edf14df87 100644
--- a/module/plugins/captcha/ShareonlineBiz.py
+++ b/module/plugins/captcha/ShareonlineBiz.py
@@ -1,30 +1,27 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class ShareonlineBiz(OCR):
__name__ = "ShareonlineBiz"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Shareonline.biz ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
-
-
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
self.to_greyscale()
self.image = self.image.resize((160, 50))
self.pixels = self.image.load()
self.threshold(1.85)
- #self.eval_black_white(240)
- #self.derotate_by_average()
+ # self.eval_black_white(240)
+ # self.derotate_by_average()
letters = self.split_captcha_letters()
@@ -36,4 +33,4 @@ class ShareonlineBiz(OCR):
return final
- #tesseract at 60%
+ #: Tesseract at 60%
diff --git a/module/plugins/internal/SolveMedia.py b/module/plugins/captcha/SolveMedia.py
index 7f5de51e1..870b5fc10 100644
--- a/module/plugins/internal/SolveMedia.py
+++ b/module/plugins/captcha/SolveMedia.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.Plugin import Fail
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.Plugin import Fail
+from module.plugins.internal.CaptchaService import CaptchaService
-class SolveMedia(Captcha):
+class SolveMedia(CaptchaService):
__name__ = "SolveMedia"
__type__ = "captcha"
- __version__ = "0.13"
+ __version__ = "0.15"
+ __status__ = "testing"
__description__ = """SolveMedia captcha service plugin"""
__license__ = "GPLv3"
@@ -19,23 +20,23 @@ class SolveMedia(Captcha):
KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.KEY_PATTERN, html)
if m:
self.key = m.group(1).strip()
- self.logDebug("Key: %s" % self.key)
+ self.log_debug("Key: %s" % self.key)
return self.key
else:
- self.logWarning("Key pattern not found")
+ self.log_warning(_("Key pattern not found"))
return None
- def challenge(self, key=None, html=None):
- key = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None):
+ key = key or self.retrieve_key(data)
- html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript",
+ html = self.plugin.load("http://api.solvemedia.com/papi/challenge.noscript",
get={'k': key})
for i in xrange(1, 11):
@@ -43,7 +44,7 @@ class SolveMedia(Captcha):
magic = re.search(r'name="magic" value="(.+?)"', html).group(1)
except AttributeError:
- self.logWarning("Magic pattern not found")
+ self.log_warning(_("Magic pattern not found"))
magic = None
try:
@@ -54,17 +55,17 @@ class SolveMedia(Captcha):
self.fail(_("SolveMedia challenge pattern not found"))
else:
- self.logDebug("Challenge: %s" % challenge)
+ self.log_debug("Challenge: %s" % challenge)
try:
result = self.result("http://api.solvemedia.com/papi/media", challenge)
except Fail, e:
- self.logWarning(e)
+ self.log_warning(e)
self.plugin.invalidCaptcha()
result = None
- html = self.plugin.req.load("http://api.solvemedia.com/papi/verify.noscript",
+ html = self.plugin.load("http://api.solvemedia.com/papi/verify.noscript",
post={'adcopy_response' : result,
'k' : key,
'l' : "en",
@@ -81,9 +82,9 @@ class SolveMedia(Captcha):
else:
if "error" in html:
- self.logWarning("Captcha code was invalid")
- self.logDebug("Retry #%d" % i)
- html = self.plugin.req.load(redirect)
+ self.log_warning(_("Captcha code was invalid"))
+ self.log_debug("Retry #%d" % i)
+ html = self.plugin.load(redirect)
else:
break
@@ -94,11 +95,11 @@ class SolveMedia(Captcha):
def result(self, server, challenge):
- result = self.plugin.decryptCaptcha(server,
- get={'c': challenge},
- cookies=True,
- imgtype="gif")
+ result = self.decrypt(server,
+ get={'c': challenge},
+ cookies=True,
+ input_type="gif")
- self.logDebug("Result: %s" % result)
+ self.log_debug("Result: %s" % result)
return result
diff --git a/module/plugins/container/CCF.py b/module/plugins/container/CCF.py
index 235d5dc1d..3126d69a5 100644
--- a/module/plugins/container/CCF.py
+++ b/module/plugins/container/CCF.py
@@ -6,14 +6,15 @@ import MultipartPostHandler
import re
import urllib2
-from module.plugins.Container import Container
-from module.utils import fs_encode, save_join
+from module.plugins.internal.Container import Container
+from module.utils import fs_encode, save_join as fs_join
class CCF(Container):
__name__ = "CCF"
__type__ = "container"
- __version__ = "0.23"
+ __version__ = "0.25"
+ __status__ = "testing"
__pattern__ = r'.+\.ccf$'
@@ -32,8 +33,8 @@ class CCF(Container):
'filename': "test.ccf",
'upload' : open(fs_filename, "rb")}).read()
- download_folder = self.config['general']['download_folder']
- dlc_file = save_join(download_folder, "tmp_%s.dlc" % pyfile.name)
+ download_folder = self.pyload.config.get("general", "download_folder")
+ dlc_file = fs_join(download_folder, "tmp_%s.dlc" % pyfile.name)
try:
dlc = re.search(r'<dlc>(.+)</dlc>', dlc_content, re.S).group(1).decode('base64')
diff --git a/module/plugins/container/DLC.py b/module/plugins/container/DLC.py
index ff2f0104a..145322942 100644
--- a/module/plugins/container/DLC.py
+++ b/module/plugins/container/DLC.py
@@ -7,14 +7,15 @@ import xml.dom.minidom
from Crypto.Cipher import AES
-from module.plugins.Container import Container
+from module.plugins.internal.Container import Container
from module.utils import decode, fs_encode
class DLC(Container):
__name__ = "DLC"
__type__ = "container"
- __version__ = "0.24"
+ __version__ = "0.26"
+ __status__ = "testing"
__pattern__ = r'.+\.dlc$'
@@ -53,20 +54,20 @@ class DLC(Container):
self.data = AES.new(key, AES.MODE_CBC, iv).decrypt(dlc_data).decode('base64')
self.packages = [(name or pyfile.name, links, name or pyfile.name) \
- for name, links in self.getPackages()]
+ for name, links in self.get_packages()]
- def getPackages(self):
+ def get_packages(self):
root = xml.dom.minidom.parseString(self.data).documentElement
content = root.getElementsByTagName("content")[0]
- return self.parsePackages(content)
+ return self.parse_packages(content)
- def parsePackages(self, startNode):
- return [(decode(node.getAttribute("name")).decode('base64'), self.parseLinks(node)) \
+ def parse_packages(self, startNode):
+ return [(decode(node.getAttribute("name")).decode('base64'), self.parse_links(node)) \
for node in startNode.getElementsByTagName("package")]
- def parseLinks(self, startNode):
+ def parse_links(self, startNode):
return [node.getElementsByTagName("url")[0].firstChild.data.decode('base64') \
for node in startNode.getElementsByTagName("file")]
diff --git a/module/plugins/container/RSDF.py b/module/plugins/container/RSDF.py
index dd2d14cf7..cedb2b605 100644
--- a/module/plugins/container/RSDF.py
+++ b/module/plugins/container/RSDF.py
@@ -7,14 +7,15 @@ import re
from Crypto.Cipher import AES
-from module.plugins.Container import Container
+from module.plugins.internal.Container import Container
from module.utils import fs_encode
class RSDF(Container):
__name__ = "RSDF"
__type__ = "container"
- __version__ = "0.29"
+ __version__ = "0.31"
+ __status__ = "testing"
__pattern__ = r'.+\.rsdf$'
diff --git a/module/plugins/container/TXT.py b/module/plugins/container/TXT.py
index d419ee060..8c9f99c27 100644
--- a/module/plugins/container/TXT.py
+++ b/module/plugins/container/TXT.py
@@ -2,14 +2,15 @@
import codecs
-from module.plugins.Container import Container
+from module.plugins.internal.Container import Container
from module.utils import fs_encode
class TXT(Container):
__name__ = "TXT"
__type__ = "container"
- __version__ = "0.15"
+ __version__ = "0.17"
+ __status__ = "testing"
__pattern__ = r'.+\.(txt|text)$'
__config__ = [("flush" , "bool" , "Flush list after adding", False ),
@@ -23,7 +24,7 @@ class TXT(Container):
def decrypt(self, pyfile):
try:
- encoding = codecs.lookup(self.getConfig('encoding')).name
+ encoding = codecs.lookup(self.get_config('encoding')).name
except Exception:
encoding = "utf-8"
@@ -43,7 +44,7 @@ class TXT(Container):
continue
if link.startswith("[") and link.endswith("]"):
- # new package
+ #: New package
curPack = link[1:-1]
packages[curPack] = []
continue
@@ -52,18 +53,18 @@ class TXT(Container):
txt.close()
- # empty packages fix
- for key, value in packages.iteritems():
+ #: Empty packages fix
+ for key, value in packages.items():
if not value:
packages.pop(key, None)
- if self.getConfig('flush'):
+ if self.get_config('flush'):
try:
txt = open(fs_filename, 'wb')
txt.close()
except IOError:
- self.logWarning(_("Failed to flush list"))
+ self.log_warning(_("Failed to flush list"))
- for name, links in packages.iteritems():
+ for name, links in packages.items():
self.packages.append((name, links, name))
diff --git a/module/plugins/crypter/BitshareComFolder.py b/module/plugins/crypter/BitshareComFolder.py
index 256c5b5aa..d7a51cb1c 100644
--- a/module/plugins/crypter/BitshareComFolder.py
+++ b/module/plugins/crypter/BitshareComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class BitshareComFolder(SimpleCrypter):
__name__ = "BitshareComFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?bitshare\.com/\?d=\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -19,7 +20,7 @@ class BitshareComFolder(SimpleCrypter):
LINK_PATTERN = r'<a href="(http://bitshare\.com/files/.+)">.+</a></td>'
- NAME_PATTERN = r'View public folder "(?P<N>.+)"</h1>'
+ NAME_PATTERN = r'View public folder "(?P<N>.+?)"</h1>'
getInfo = create_getInfo(BitshareComFolder)
diff --git a/module/plugins/crypter/C1NeonCom.py b/module/plugins/crypter/C1NeonCom.py
index 9b6093081..09acace63 100644
--- a/module/plugins/crypter/C1NeonCom.py
+++ b/module/plugins/crypter/C1NeonCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class C1NeonCom(DeadCrypter):
__name__ = "C1NeonCom"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?c1neon\.com/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/ChipDe.py b/module/plugins/crypter/ChipDe.py
index f535da48d..3604635e5 100644
--- a/module/plugins/crypter/ChipDe.py
+++ b/module/plugins/crypter/ChipDe.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class ChipDe(Crypter):
__name__ = "ChipDe"
__type__ = "crypter"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?chip\.de/video/.+\.html'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -26,4 +27,4 @@ class ChipDe(Crypter):
self.fail(_("Failed to find the URL"))
else:
self.urls = [f.group(1)]
- self.logDebug("The file URL is %s" % self.urls[0])
+ self.log_debug("The file URL is %s" % self.urls[0])
diff --git a/module/plugins/crypter/CloudzillaToFolder.py b/module/plugins/crypter/CloudzillaToFolder.py
index 96d7245f1..09b4d4c08 100644
--- a/module/plugins/crypter/CloudzillaToFolder.py
+++ b/module/plugins/crypter/CloudzillaToFolder.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class CloudzillaToFolder(SimpleHoster):
__name__ = "CloudzillaToFolder"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?cloudzilla\.to/share/folder/(?P<ID>[\w^_]+)'
@@ -26,10 +27,10 @@ class CloudzillaToFolder(SimpleHoster):
PASSWORD_PATTERN = r'<div id="pwd_protected">'
- def checkErrors(self):
+ def check_errors(self):
m = re.search(self.PASSWORD_PATTERN, self.html)
if m:
- self.html = self.load(self.pyfile.url, get={'key': self.getPassword()})
+ self.html = self.load(self.pyfile.url, get={'key': self.get_password()})
if re.search(self.PASSWORD_PATTERN, self.html):
self.retry(reason="Wrong password")
diff --git a/module/plugins/crypter/CrockoComFolder.py b/module/plugins/crypter/CrockoComFolder.py
index f56cc449a..81dfcd525 100644
--- a/module/plugins/crypter/CrockoComFolder.py
+++ b/module/plugins/crypter/CrockoComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class CrockoComFolder(SimpleCrypter):
__name__ = "CrockoComFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?crocko\.com/f/.+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/CryptItCom.py b/module/plugins/crypter/CryptItCom.py
index 1c9e841b7..be0094747 100644
--- a/module/plugins/crypter/CryptItCom.py
+++ b/module/plugins/crypter/CryptItCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class CryptItCom(DeadCrypter):
__name__ = "CryptItCom"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?crypt-it\.com/(s|e|d|c)/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/CzshareComFolder.py b/module/plugins/crypter/CzshareComFolder.py
index c317b1b49..cb41426d7 100644
--- a/module/plugins/crypter/CzshareComFolder.py
+++ b/module/plugins/crypter/CzshareComFolder.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class CzshareComFolder(Crypter):
__name__ = "CzshareComFolder"
__type__ = "crypter"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(czshare|sdilej)\.(com|cz)/folders/.+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/DailymotionComFolder.py b/module/plugins/crypter/DailymotionComFolder.py
index 01caa0bb8..8a4a0f258 100644
--- a/module/plugins/crypter/DailymotionComFolder.py
+++ b/module/plugins/crypter/DailymotionComFolder.py
@@ -4,14 +4,15 @@ import re
import urlparse
from module.common.json_layer import json_loads
-from module.plugins.Crypter import Crypter
-from module.utils import save_join
+from module.plugins.internal.Crypter import Crypter
+from module.utils import save_join as fs_join
class DailymotionComFolder(Crypter):
__name__ = "DailymotionComFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?dailymotion\.com/((playlists/)?(?P<TYPE>playlist|user)/)?(?P<ID>[\w^_]+)(?(TYPE)|#)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -22,16 +23,16 @@ class DailymotionComFolder(Crypter):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- def api_response(self, ref, req=None):
+ def api_response(self, ref, data=None):
url = urlparse.urljoin("https://api.dailymotion.com/", ref)
- html = self.load(url, get=req)
+ html = self.load(url, get=data)
return json_loads(html)
- def getPlaylistInfo(self, id):
- ref = "playlist/" + id
- req = {"fields": "name,owner.screenname"}
- playlist = self.api_response(ref, req)
+ def get_playlist_info(self, id):
+ ref = "playlist/" + id
+ data = {'fields': "name,owner.screenname"}
+ playlist = self.api_response(ref, data)
if "error" in playlist:
return
@@ -41,10 +42,10 @@ class DailymotionComFolder(Crypter):
return name, owner
- def _getPlaylists(self, user_id, page=1):
- ref = "user/%s/playlists" % user_id
- req = {"fields": "id", "page": page, "limit": 100}
- user = self.api_response(ref, req)
+ def _get_playlists(self, user_id, page=1):
+ ref = "user/%s/playlists" % user_id
+ data = {'fields': "id", 'page': page, 'limit': 100}
+ user = self.api_response(ref, data)
if "error" in user:
return
@@ -53,18 +54,18 @@ class DailymotionComFolder(Crypter):
yield playlist['id']
if user['has_more']:
- for item in self._getPlaylists(user_id, page + 1):
+ for item in self._get_playlists(user_id, page + 1):
yield item
- def getPlaylists(self, user_id):
- return [(id,) + self.getPlaylistInfo(id) for id in self._getPlaylists(user_id)]
+ def get_playlists(self, user_id):
+ return [(id,) + self.get_playlist_info(id) for id in self._get_playlists(user_id)]
- def _getVideos(self, id, page=1):
- ref = "playlist/%s/videos" % id
- req = {"fields": "url", "page": page, "limit": 100}
- playlist = self.api_response(ref, req)
+ def _get_videos(self, id, page=1):
+ ref = "playlist/%s/videos" % id
+ data = {'fields': "url", 'page': page, 'limit': 100}
+ playlist = self.api_response(ref, data)
if "error" in playlist:
return
@@ -73,12 +74,12 @@ class DailymotionComFolder(Crypter):
yield video['url']
if playlist['has_more']:
- for item in self._getVideos(id, page + 1):
+ for item in self._get_videos(id, page + 1):
yield item
- def getVideos(self, playlist_id):
- return list(self._getVideos(playlist_id))[::-1]
+ def get_videos(self, playlist_id):
+ return list(self._get_videos(playlist_id))[::-1]
def decrypt(self, pyfile):
@@ -87,19 +88,19 @@ class DailymotionComFolder(Crypter):
m_type = m.group('TYPE')
if m_type == "playlist":
- self.logDebug("Url recognized as Playlist")
- p_info = self.getPlaylistInfo(m_id)
+ self.log_debug("Url recognized as Playlist")
+ p_info = self.get_playlist_info(m_id)
playlists = [(m_id,) + p_info] if p_info else None
else:
- self.logDebug("Url recognized as Channel")
- playlists = self.getPlaylists(m_id)
- self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), m_id))
+ self.log_debug("Url recognized as Channel")
+ playlists = self.get_playlists(m_id)
+ self.log_debug("%s playlist\s found on channel \"%s\"" % (len(playlists), m_id))
if not playlists:
self.fail(_("No playlist available"))
for p_id, p_name, p_owner in playlists:
- p_videos = self.getVideos(p_id)
- p_folder = save_join(self.config['general']['download_folder'], p_owner, p_name)
- self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name))
- self.packages.append((p_name, p_videos, p_folder)) #: folder is NOT recognized by pyload 0.4.9!
+ p_videos = self.get_videos(p_id)
+ p_folder = fs_join(self.pyload.config.get("general", "download_folder"), p_owner, p_name)
+ self.log_debug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name))
+ self.packages.append((p_name, p_videos, p_folder)) #: Folder is NOT recognized by pyload 0.4.9!
diff --git a/module/plugins/crypter/DataHuFolder.py b/module/plugins/crypter/DataHuFolder.py
index 67f5e788f..e6e3c70a5 100644
--- a/module/plugins/crypter/DataHuFolder.py
+++ b/module/plugins/crypter/DataHuFolder.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class DataHuFolder(SimpleCrypter):
__name__ = "DataHuFolder"
__type__ = "crypter"
- __version__ = "0.06"
+ __version__ = "0.08"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?data\.hu/dir/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -22,22 +23,22 @@ class DataHuFolder(SimpleCrypter):
LINK_PATTERN = r'<a href=\'(http://data\.hu/get/.+)\' target=\'_blank\'>\1</a>'
- NAME_PATTERN = ur'<title>(?P<N>.+) Let\xf6lt\xe9se</title>'
+ NAME_PATTERN = ur'<title>(?P<N>.+?) Let\xf6lt\xe9se</title>'
def prepare(self):
super(DataHuFolder, self).prepare()
- if u'K\xe9rlek add meg a jelsz\xf3t' in self.html: # Password protected
- password = self.getPassword()
+ if u'K\xe9rlek add meg a jelsz\xf3t' in self.html: #: Password protected
+ password = self.get_password()
if not password:
self.fail(_("Password required"))
- self.logDebug("The folder is password protected', 'Using password: " + password)
+ self.log_debug("The folder is password protected', 'Using password: " + password)
- self.html = self.load(self.pyfile.url, post={'mappa_pass': password}, decode=True)
+ self.html = self.load(self.pyfile.url, post={'mappa_pass': password})
- if u'Hib\xe1s jelsz\xf3' in self.html: # Wrong password
+ if u'Hib\xe1s jelsz\xf3' in self.html: #: Wrong password
self.fail(_("Wrong password"))
diff --git a/module/plugins/crypter/DdlstorageComFolder.py b/module/plugins/crypter/DdlstorageComFolder.py
index dc6ec1da5..ffc9f1d01 100644
--- a/module/plugins/crypter/DdlstorageComFolder.py
+++ b/module/plugins/crypter/DdlstorageComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class DdlstorageComFolder(DeadCrypter):
__name__ = "DdlstorageComFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?ddlstorage\.com/folder/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/DepositfilesComFolder.py b/module/plugins/crypter/DepositfilesComFolder.py
index 46ec265c3..0c795279e 100644
--- a/module/plugins/crypter/DepositfilesComFolder.py
+++ b/module/plugins/crypter/DepositfilesComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class DepositfilesComFolder(SimpleCrypter):
__name__ = "DepositfilesComFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?depositfiles\.com/folders/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/Dereferer.py b/module/plugins/crypter/Dereferer.py
index 8e56a7bfc..9051abcc2 100644
--- a/module/plugins/crypter/Dereferer.py
+++ b/module/plugins/crypter/Dereferer.py
@@ -1,12 +1,15 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer
+import re
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
-class Dereferer(SimpleDereferer):
+
+class Dereferer(SimpleCrypter):
__name__ = "Dereferer"
__type__ = "crypter"
- __version__ = "0.12"
+ __version__ = "0.18"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/.*?(?P<LINK>(?:ht|f)tps?://.+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -21,24 +24,18 @@ class Dereferer(SimpleDereferer):
HOSTER_NAME = None
- def _log(self, type, args):
- msg = " | ".join(str(a).strip() for a in args if a)
- logger = getattr(self.log, type)
- logger("%s: %s: %s" % (self.__name__, self.HOSTER_NAME, msg or _("%s MARK" % type.upper())))
+ def _log(self, level, plugintype, pluginname, messages):
+ return super(Dereferer, self)._log(level, plugintype, pluginname, (self.HOSTER_NAME,) + messages)
def init(self):
super(Dereferer, self).init()
- self.__pattern__ = self.core.pluginManager.crypterPlugins[self.__name__]['pattern'] #@TODO: Recheck in 0.4.10
+ self.__pattern__ = self.pyload.pluginManager.crypterPlugins[self.__name__]['pattern'] #@TODO: Recheck in 0.4.10
self.HOSTER_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group("DOMAIN").lower()
self.HOSTER_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+)', self.HOSTER_DOMAIN) if part != '.')
- def getLink(self):
- try:
- return re.match(self.__pattern__, pyfile.url).group('LINK').strip()
-
- except Exception, e:
- self.logWarning(e)
+ def get_links(self):
+ return [re.match(self.__pattern__, self.pyfile.url).group('LINK').strip()]
diff --git a/module/plugins/crypter/DevhostStFolder.py b/module/plugins/crypter/DevhostStFolder.py
index 4d15e2058..8340adeb8 100644
--- a/module/plugins/crypter/DevhostStFolder.py
+++ b/module/plugins/crypter/DevhostStFolder.py
@@ -12,14 +12,15 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class DevhostStFolder(SimpleCrypter):
__name__ = "DevhostStFolder"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?d-h\.st/users/(?P<USER>\w+)(/\?fld_id=(?P<ID>\d+))?'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
("use_subfolder" , "bool", "Save package to subfolder" , True),
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
- __description__ = """d-h.st folder decrypter plugin"""
+ __description__ = """D-h.st folder decrypter plugin"""
__license__ = "GPLv3"
__authors__ = [("zapp-brannigan", "fuerst.reinje@web.de"),
("Walter Purcaro", "vuolter@gmail.com")]
@@ -29,11 +30,11 @@ class DevhostStFolder(SimpleCrypter):
OFFLINE_PATTERN = r'"/cHP">test\.png<'
- def checkNameSize(self, getinfo=True):
+ def check_name_size(self, getinfo=True):
if not self.info or getinfo:
- self.logDebug("File info (BEFORE): %s" % self.info)
- self.info.update(self.getInfo(self.pyfile.url, self.html))
- self.logDebug("File info (AFTER): %s" % self.info)
+ self.log_debug("File info (BEFORE): %s" % self.info)
+ self.info.update(self.get_info(self.pyfile.url, self.html))
+ self.log_debug("File info (AFTER): %s" % self.info)
try:
if self.info['pattern']['ID'] == "0":
@@ -49,7 +50,7 @@ class DevhostStFolder(SimpleCrypter):
self.pyfile.name = m.group(1)
except Exception, e:
- self.logDebug(e)
+ self.log_debug(e)
self.pyfile.name = self.info['pattern']['USER']
try:
@@ -58,7 +59,7 @@ class DevhostStFolder(SimpleCrypter):
except Exception:
pass
- self.logDebug("File name: %s" % self.pyfile.name,
+ self.log_debug("File name: %s" % self.pyfile.name,
"File folder: %s" % self.pyfile.name)
diff --git a/module/plugins/crypter/DlProtectCom.py b/module/plugins/crypter/DlProtectCom.py
index a9f39c6f3..0c776ac61 100644
--- a/module/plugins/crypter/DlProtectCom.py
+++ b/module/plugins/crypter/DlProtectCom.py
@@ -11,7 +11,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class DlProtectCom(SimpleCrypter):
__name__ = "DlProtectCom"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?dl-protect\.com/((en|fr)/)?\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -28,15 +29,15 @@ class DlProtectCom(SimpleCrypter):
OFFLINE_PATTERN = r'Unfortunately, the link you are looking for is not found'
- def getLinks(self):
- # Direct link with redirect
+ def get_links(self):
+ #: Direct link with redirect
if not re.match(r"https?://(?:www\.)?dl-protect\.com/.+", self.req.http.lastEffectiveURL):
return [self.req.http.lastEffectiveURL]
post_req = {'key' : re.search(r'name="key" value="(.+?)"', self.html).group(1),
'submitform': ""}
- if "Please click on continue to see the content" in self.html:
+ if "Please click on continue to see the links" in self.html:
post_req['submitform'] = "Continue"
self.wait(2)
@@ -48,14 +49,13 @@ class DlProtectCom(SimpleCrypter):
'submitform': "Decrypt+link"})
if "Password :" in self.html:
- post_req['pwd'] = self.getPassword()
+ post_req['pwd'] = self.get_password()
if "Security Code" in self.html:
- captcha_id = re.search(r'/captcha\.php\?uid=(.+?)"', self.html).group(1)
- captcha_url = "http://www.dl-protect.com/captcha.php?uid=" + captcha_id
- captcha_code = self.decryptCaptcha(captcha_url, imgtype="gif")
-
- post_req['secure'] = captcha_code
+ m = re.search(r'/captcha\.php\?key=(.+?)"', self.html)
+ if m:
+ captcha_code = self.captcha.decrypt("http://www.dl-protect.com/captcha.php?key=" + m.group(1), input_type="gif")
+ post_req['secure'] = captcha_code
self.html = self.load(self.pyfile.url, post=post_req)
diff --git a/module/plugins/crypter/DuckCryptInfo.py b/module/plugins/crypter/DuckCryptInfo.py
index cc108d101..c9269b05e 100644
--- a/module/plugins/crypter/DuckCryptInfo.py
+++ b/module/plugins/crypter/DuckCryptInfo.py
@@ -2,15 +2,16 @@
import re
-from BeautifulSoup import BeautifulSoup
+import BeautifulSoup
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class DuckCryptInfo(Crypter):
__name__ = "DuckCryptInfo"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?duckcrypt\.info/(folder|wait|link)/(\w+)/?(\w*)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -31,29 +32,29 @@ class DuckCryptInfo(Crypter):
if m is None:
self.fail(_("Weird error in link"))
if str(m.group(1)) == "link":
- self.handleLink(url)
+ self.handle_link(url)
else:
- self.handleFolder(m)
+ self.handle_folder(m)
- def handleFolder(self, m):
+ def handle_folder(self, m):
html = self.load("http://duckcrypt.info/ajax/auth.php?hash=" + str(m.group(2)))
m = re.match(self.__pattern__, html)
- self.logDebug("Redirectet to " + str(m.group(0)))
+ self.log_debug("Redirectet to " + str(m.group(0)))
html = self.load(str(m.group(0)))
- soup = BeautifulSoup(html)
- cryptlinks = soup.findAll("div", attrs={"class": "folderbox"})
- self.logDebug("Redirectet to " + str(cryptlinks))
+ soup = BeautifulSoup.BeautifulSoup(html)
+ cryptlinks = soup.findAll("div", attrs={'class': "folderbox"})
+ self.log_debug("Redirectet to " + str(cryptlinks))
if not cryptlinks:
self.error(_("No link found"))
for clink in cryptlinks:
if clink.find("a"):
- self.handleLink(clink.find("a")['href'])
+ self.handle_link(clink.find("a")['href'])
- def handleLink(self, url):
+ def handle_link(self, url):
html = self.load(url)
soup = BeautifulSoup(html)
self.urls = [soup.find("iframe")['src']]
if not self.urls:
- self.logInfo(_("No link found"))
+ self.log_info(_("No link found"))
diff --git a/module/plugins/crypter/DuploadOrgFolder.py b/module/plugins/crypter/DuploadOrgFolder.py
index d505806b7..f0e9b8c96 100644
--- a/module/plugins/crypter/DuploadOrgFolder.py
+++ b/module/plugins/crypter/DuploadOrgFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class DuploadOrgFolder(DeadCrypter):
__name__ = "DuploadOrgFolder"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?dupload\.org/folder/\d+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/EasybytezComFolder.py b/module/plugins/crypter/EasybytezComFolder.py
index fdd3d4ff4..0c070b6f1 100644
--- a/module/plugins/crypter/EasybytezComFolder.py
+++ b/module/plugins/crypter/EasybytezComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSCrypter import XFSCrypter, create_getInfo
class EasybytezComFolder(XFSCrypter):
__name__ = "EasybytezComFolder"
__type__ = "crypter"
- __version__ = "0.10"
+ __version__ = "0.11"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?easybytez\.com/users/\d+/\d+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/EmbeduploadCom.py b/module/plugins/crypter/EmbeduploadCom.py
index 28633f634..341b3e315 100644
--- a/module/plugins/crypter/EmbeduploadCom.py
+++ b/module/plugins/crypter/EmbeduploadCom.py
@@ -1,14 +1,15 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
from module.network.HTTPRequest import BadHeader
class EmbeduploadCom(Crypter):
__name__ = "EmbeduploadCom"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?embedupload\.com/\?d=.+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True ),
@@ -25,30 +26,30 @@ class EmbeduploadCom(Crypter):
def decrypt(self, pyfile):
- self.html = self.load(pyfile.url, decode=True)
+ self.html = self.load(pyfile.url)
tmp_links = []
m = re.findall(self.LINK_PATTERN, self.html)
if m:
- prefered_set = set(self.getConfig('preferedHoster').split('|'))
+ prefered_set = set(self.get_config('preferedHoster').split('|'))
prefered_set = map(lambda s: s.lower().split('.')[0], prefered_set)
- self.logDebug("PF: %s" % prefered_set)
+ self.log_debug("PF: %s" % prefered_set)
tmp_links.extend(x[1] for x in m if x[0] in prefered_set)
- self.urls = self.getLocation(tmp_links)
+ self.urls = self.get_location(tmp_links)
if not self.urls:
- ignored_set = set(self.getConfig('ignoredHoster').split('|'))
+ ignored_set = set(self.get_config('ignoredHoster').split('|'))
ignored_set = map(lambda s: s.lower().split('.')[0], ignored_set)
- self.logDebug("IG: %s" % ignored_set)
+ self.log_debug("IG: %s" % ignored_set)
tmp_links.extend(x[1] for x in m if x[0] not in ignored_set)
- self.urls = self.getLocation(tmp_links)
+ self.urls = self.get_location(tmp_links)
- def getLocation(self, tmp_links):
+ def get_location(self, tmp_links):
new_links = []
for link in tmp_links:
try:
diff --git a/module/plugins/crypter/FilebeerInfoFolder.py b/module/plugins/crypter/FilebeerInfoFolder.py
index 5b401c555..5d0e26329 100644
--- a/module/plugins/crypter/FilebeerInfoFolder.py
+++ b/module/plugins/crypter/FilebeerInfoFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class FilebeerInfoFolder(DeadCrypter):
__name__ = "FilebeerInfoFolder"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filebeer\.info/\d*~f\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/FilecloudIoFolder.py b/module/plugins/crypter/FilecloudIoFolder.py
index f900f4910..6c7b5be15 100644
--- a/module/plugins/crypter/FilecloudIoFolder.py
+++ b/module/plugins/crypter/FilecloudIoFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FilecloudIoFolder(SimpleCrypter):
__name__ = "FilecloudIoFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(filecloud\.io|ifile\.it)/_\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/FilecryptCc.py b/module/plugins/crypter/FilecryptCc.py
index 4d2b42f90..9f4ad69aa 100644
--- a/module/plugins/crypter/FilecryptCc.py
+++ b/module/plugins/crypter/FilecryptCc.py
@@ -9,14 +9,15 @@ import urlparse
from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.internal.Crypter import Crypter
+from module.plugins.captcha.ReCaptcha import ReCaptcha
class FilecryptCc(Crypter):
__name__ = "FilecryptCc"
__type__ = "crypter"
- __version__ = "0.15"
+ __version__ = "0.18"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?filecrypt\.cc/Container/\w+'
@@ -47,66 +48,63 @@ class FilecryptCc(Crypter):
if "content notfound" in self.html: #@NOTE: "content notfound" is NOT a typo
self.offline()
- self.handlePasswordProtection()
- self.handleCaptcha()
- self.handleMirrorPages()
+ self.handle_password_protection()
+ self.handle_captcha()
+ self.handle_mirror_pages()
- for handle in (self.handleCNL, self.handleWeblinks, self.handleDlcContainer):
+ for handle in (self.handle_CNL, self.handle_weblinks, self.handle_dlc_container):
handle()
if self.links:
self.packages = [(pyfile.package().name, self.links, pyfile.package().name)]
return
- def handleMirrorPages(self):
- if "mirror=" not in self.siteWithLinks:
+ def handle_mirror_pages(self):
+ if "mirror=" not in self.site_with_links:
return
- mirror = re.findall(self.MIRROR_PAGE_PATTERN, self.siteWithLinks)
+ mirror = re.findall(self.MIRROR_PAGE_PATTERN, self.site_with_links)
- self.logInfo(_("Found %d mirrors") % len(mirror))
+ self.log_info(_("Found %d mirrors") % len(mirror))
for i in mirror[1:]:
- self.siteWithLinks = self.siteWithLinks + self.load(i).decode("utf-8", "replace")
+ self.site_with_links = self.site_with_links + self.load(i)
- def handlePasswordProtection(self):
+ def handle_password_protection(self):
if '<input type="text" name="password"' not in self.html:
return
- self.logInfo(_("Folder is password protected"))
+ self.log_info(_("Folder is password protected"))
- password = self.getPassword()
+ password = self.get_password()
if not password:
self.fail(_("Please enter the password in package section and try again"))
- self.html = self.load(self.pyfile.url, post={"password": password})
+ self.html = self.load(self.pyfile.url, post={'password': password})
- def handleCaptcha(self):
+ def handle_captcha(self):
m = re.search(self.CAPTCHA_PATTERN, self.html)
m2 = re.search(self.CIRCLE_CAPTCHA_PATTERN, self.html)
- if m: #: normal captcha
- self.logDebug("Captcha-URL: %s" % m.group(1))
+ if m: #: Normal captcha
+ self.log_debug("Captcha-URL: %s" % m.group(1))
- captcha_code = self.decryptCaptcha(urlparse.urljoin(self.base_url, m.group(1)),
- forceUser=True,
- imgtype="gif")
+ captcha_code = self.captcha.decrypt(urlparse.urljoin(self.base_url, m.group(1)),
+ input_type="gif")
- self.siteWithLinks = self.load(self.pyfile.url,
- post={'recaptcha_response_field': captcha_code},
- decode=True)
- elif m2: #: circle captcha
- self.logDebug("Captcha-URL: %s" % m2.group(1))
+ self.site_with_links = self.load(self.pyfile.url,
+ post={'recaptcha_response_field': captcha_code})
+ elif m2: #: Circle captcha
+ self.log_debug("Captcha-URL: %s" % m2.group(1))
- captcha_code = self.decryptCaptcha('%s%s?c=abc' %(self.base_url, m2.group(1)),
- result_type='positional')
+ captcha_code = self.captcha.decrypt('%s%s?c=abc' %(self.base_url, m2.group(1)),
+ output_type='positional')
- self.siteWithLinks = self.load(self.pyfile.url,
- post={'button.x': captcha_code[0], 'button.y': captcha_code[1]},
- decode=True)
+ self.site_with_links = self.load(self.pyfile.url,
+ post={'button.x': captcha_code[0], 'button.y': captcha_code[1]})
else:
recaptcha = ReCaptcha(self)
@@ -114,20 +112,19 @@ class FilecryptCc(Crypter):
if captcha_key:
response, challenge = recaptcha.challenge(captcha_key)
- self.siteWithLinks = self.load(self.pyfile.url,
- post={'g-recaptcha-response': response},
- decode=True)
+ self.site_with_links = self.load(self.pyfile.url,
+ post={'g-recaptcha-response': response})
else:
- self.logInfo(_("No captcha found"))
- self.siteWithLinks = self.html
+ self.log_info(_("No captcha found"))
+ self.site_with_links = self.html
- if "recaptcha_image" in self.siteWithLinks or "data-sitekey" in self.siteWithLinks:
- self.invalidCaptcha()
+ if "recaptcha_image" in self.site_with_links or "data-sitekey" in self.site_with_links:
+ self.captcha.invalid()
self.retry()
- def handleDlcContainer(self):
- dlc = re.findall(self.DLC_LINK_PATTERN, self.siteWithLinks)
+ def handle_dlc_container(self):
+ dlc = re.findall(self.DLC_LINK_PATTERN, self.site_with_links)
if not dlc:
return
@@ -136,9 +133,9 @@ class FilecryptCc(Crypter):
self.links.append("%s/DLC/%s.dlc" % (self.base_url, i))
- def handleWeblinks(self):
+ def handle_weblinks(self):
try:
- weblinks = re.findall(self.WEBLINK_PATTERN, self.siteWithLinks)
+ weblinks = re.findall(self.WEBLINK_PATTERN, self.site_with_links)
for link in weblinks:
res = self.load("%s/Link/%s.html" % (self.base_url, link))
@@ -147,32 +144,32 @@ class FilecryptCc(Crypter):
self.links.append(res2['location'])
except Exception, e:
- self.logDebug("Error decrypting weblinks: %s" % e)
+ self.log_debug("Error decrypting weblinks: %s" % e)
- def handleCNL(self):
+ def handle_CNL(self):
try:
- vjk = re.findall('<input type="hidden" name="jk" value="function f\(\){ return \'(.*)\';}">', self.siteWithLinks)
- vcrypted = re.findall('<input type="hidden" name="crypted" value="(.*)">', self.siteWithLinks)
+ vjk = re.findall('<input type="hidden" name="jk" value="function f\(\){ return \'(.*)\';}">', self.site_with_links)
+ vcrypted = re.findall('<input type="hidden" name="crypted" value="(.*)">', self.site_with_links)
for i in xrange(len(vcrypted)):
- self.links.extend(self._getLinks(vcrypted[i], vjk[i]))
+ self.links.extend(self._get_links(vcrypted[i], vjk[i]))
except Exception, e:
- self.logDebug("Error decrypting CNL: %s" % e)
+ self.log_debug("Error decrypting CNL: %s" % e)
- def _getLinks(self, crypted, jk):
- # Get key
+ def _get_links(self, crypted, jk):
+ #: Get key
key = binascii.unhexlify(str(jk))
- # Decrypt
+ #: Decrypt
Key = key
IV = key
obj = AES.new(Key, AES.MODE_CBC, IV)
text = obj.decrypt(crypted.decode('base64'))
- # Extract links
+ #: Extract links
text = text.replace("\x00", "").replace("\r", "")
links = filter(bool, text.split('\n'))
diff --git a/module/plugins/crypter/FilefactoryComFolder.py b/module/plugins/crypter/FilefactoryComFolder.py
index c0cd028cc..aec73f33c 100644
--- a/module/plugins/crypter/FilefactoryComFolder.py
+++ b/module/plugins/crypter/FilefactoryComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FilefactoryComFolder(SimpleCrypter):
__name__ = "FilefactoryComFolder"
__type__ = "crypter"
- __version__ = "0.32"
+ __version__ = "0.33"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?filefactory\.com/(?:f|folder)/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -25,7 +26,7 @@ class FilefactoryComFolder(SimpleCrypter):
PAGES_PATTERN = r'data-paginator-totalPages="(\d+)'
- def loadPage(self, page_n):
+ def load_page(self, page_n):
return self.load(self.pyfile.url, get={'page': page_n, 'show': 100})
diff --git a/module/plugins/crypter/FilerNetFolder.py b/module/plugins/crypter/FilerNetFolder.py
index e2b44e868..4814c5933 100644
--- a/module/plugins/crypter/FilerNetFolder.py
+++ b/module/plugins/crypter/FilerNetFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FilerNetFolder(SimpleCrypter):
__name__ = "FilerNetFolder"
__type__ = "crypter"
- __version__ = "0.42"
+ __version__ = "0.43"
+ __status__ = "testing"
__pattern__ = r'https?://filer\.net/folder/\w{16}'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/FileserveComFolder.py b/module/plugins/crypter/FileserveComFolder.py
index 1363e2d45..44de55581 100644
--- a/module/plugins/crypter/FileserveComFolder.py
+++ b/module/plugins/crypter/FileserveComFolder.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class FileserveComFolder(Crypter):
__name__ = "FileserveComFolder"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fileserve\.com/list/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/FilesonicComFolder.py b/module/plugins/crypter/FilesonicComFolder.py
index 6cd4d8b8c..7ebba702a 100644
--- a/module/plugins/crypter/FilesonicComFolder.py
+++ b/module/plugins/crypter/FilesonicComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class FilesonicComFolder(DeadCrypter):
__name__ = "FilesonicComFolder"
__type__ = "crypter"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filesonic\.com/folder/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/FilestubeCom.py b/module/plugins/crypter/FilestubeCom.py
index 133f4a53f..5fcd72c64 100644
--- a/module/plugins/crypter/FilestubeCom.py
+++ b/module/plugins/crypter/FilestubeCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FilestubeCom(SimpleCrypter):
__name__ = "FilestubeCom"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.07"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filestube\.(?:com|to)/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -19,7 +20,7 @@ class FilestubeCom(SimpleCrypter):
LINK_PATTERN = r'<a class=\"file-link-main(?: noref)?\" [^>]* href=\"(http://[^\"]+)'
- NAME_PATTERN = r'<h1\s*> (?P<N>.+) download\s*</h1>'
+ NAME_PATTERN = r'<h1\s*> (?P<N>.+?) download\s*</h1>'
getInfo = create_getInfo(FilestubeCom)
diff --git a/module/plugins/crypter/FiletramCom.py b/module/plugins/crypter/FiletramCom.py
index b012d35bc..6603a3542 100644
--- a/module/plugins/crypter/FiletramCom.py
+++ b/module/plugins/crypter/FiletramCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FiletramCom(SimpleCrypter):
__name__ = "FiletramCom"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filetram\.com/[^/]+/.+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/FiredriveComFolder.py b/module/plugins/crypter/FiredriveComFolder.py
index 792f3198b..84b6cf34a 100644
--- a/module/plugins/crypter/FiredriveComFolder.py
+++ b/module/plugins/crypter/FiredriveComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class FiredriveComFolder(DeadCrypter):
__name__ = "FiredriveComFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(firedrive|putlocker)\.com/share/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/FourChanOrg.py b/module/plugins/crypter/FourChanOrg.py
index 366adef14..65a2ac788 100644
--- a/module/plugins/crypter/FourChanOrg.py
+++ b/module/plugins/crypter/FourChanOrg.py
@@ -5,13 +5,14 @@
import re
import urlparse
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class FourChanOrg(Crypter):
__name__ = "FourChanOrg"
__type__ = "crypter"
- __version__ = "0.31"
+ __version__ = "0.33"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?boards\.4chan\.org/\w+/res/(\d+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/FreakhareComFolder.py b/module/plugins/crypter/FreakhareComFolder.py
index 173660668..f7f1946f4 100644
--- a/module/plugins/crypter/FreakhareComFolder.py
+++ b/module/plugins/crypter/FreakhareComFolder.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FreakhareComFolder(SimpleCrypter):
__name__ = "FreakhareComFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?freakshare\.com/folder/.+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -25,7 +26,7 @@ class FreakhareComFolder(SimpleCrypter):
PAGES_PATTERN = r'Pages: +(\d+)'
- def loadPage(self, page_n):
+ def load_page(self, page_n):
if not hasattr(self, 'f_id') and not hasattr(self, 'f_md5'):
m = re.search(r'http://freakshare.com/\?x=folder&f_id=(\d+)&f_md5=(\w+)', self.html)
if m:
@@ -36,7 +37,7 @@ class FreakhareComFolder(SimpleCrypter):
'f_md5': self.f_md5,
'entrys': '20',
'page': page_n - 1,
- 'order': ''}, decode=True)
+ 'order': ''})
getInfo = create_getInfo(FreakhareComFolder)
diff --git a/module/plugins/crypter/FreetexthostCom.py b/module/plugins/crypter/FreetexthostCom.py
index cf6fbb8a4..350f89202 100644
--- a/module/plugins/crypter/FreetexthostCom.py
+++ b/module/plugins/crypter/FreetexthostCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FreetexthostCom(SimpleCrypter):
__name__ = "FreetexthostCom"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?freetexthost\.com/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -20,7 +21,7 @@ class FreetexthostCom(SimpleCrypter):
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- def getLinks(self):
+ def get_links(self):
m = re.search(r'<div id="contentsinner">\s*(.+)<div class="viewcount">', self.html, re.S)
if m is None:
self.error(_("Unable to extract links"))
diff --git a/module/plugins/crypter/FshareVnFolder.py b/module/plugins/crypter/FshareVnFolder.py
index bbee53337..f4941007a 100644
--- a/module/plugins/crypter/FshareVnFolder.py
+++ b/module/plugins/crypter/FshareVnFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class FshareVnFolder(SimpleCrypter):
__name__ = "FshareVnFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fshare\.vn/folder/.+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/FurLy.py b/module/plugins/crypter/FurLy.py
new file mode 100644
index 000000000..595fcb34d
--- /dev/null
+++ b/module/plugins/crypter/FurLy.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
+
+
+class FurLy(SimpleCrypter):
+ __name__ = "FurLy"
+ __type__ = "crypter"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'http://(?:www\.)?fur\.ly/(\d/)?\w+'
+
+ __description__ = """Fur.ly decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ URL_REPLACEMENTS = [(r'fur\.ly/', r'fur\.ly/bar/')]
+
+ LINK_PATTERN = r'urls\[\d+\] = "(.+?)"'
+ OFFLINE_PATTERN = r'var output;\s*var total'
+
+
+getInfo = create_getInfo(FurLy)
diff --git a/module/plugins/crypter/Go4UpCom.py b/module/plugins/crypter/Go4UpCom.py
index 22f31f6f6..026982014 100644
--- a/module/plugins/crypter/Go4UpCom.py
+++ b/module/plugins/crypter/Go4UpCom.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class Go4UpCom(SimpleCrypter):
__name__ = "Go4UpCom"
__type__ = "crypter"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://go4up\.com/(dl/\w{12}|rd/\w{12}/\d+)'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -29,7 +30,7 @@ class Go4UpCom(SimpleCrypter):
OFFLINE_PATTERN = r'>\s*(404 Page Not Found|File not Found|Mirror does not exist)'
- def getLinks(self):
+ def get_links(self):
links = []
m = re.search(r'(/download/gethosts/.+?)"', self.html)
diff --git a/module/plugins/crypter/GooGl.py b/module/plugins/crypter/GooGl.py
index 30e193b9d..76a542408 100644
--- a/module/plugins/crypter/GooGl.py
+++ b/module/plugins/crypter/GooGl.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer, create_getInfo
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
from module.common.json_layer import json_loads
-class GooGl(SimpleDereferer):
+class GooGl(SimpleCrypter):
__name__ = "GooGl"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?goo\.gl/([a-zA-Z]+/)?\w+'
@@ -22,11 +23,11 @@ class GooGl(SimpleDereferer):
OFFLINE_PATTERN = r'has been disabled|does not exist'
- def getLink(self):
+ def get_links(self):
rep = self.load(self.API_URL, get={'shortUrl': self.pyfile.url})
- self.logDebug("JSON data: " + rep)
+ self.log_debug("JSON data: " + rep)
rep = json_loads(rep)
- return rep['longUrl'] if "longUrl" in rep else None
+ return [rep['longUrl']] if "longUrl" in rep else None
getInfo = create_getInfo(GooGl)
diff --git a/module/plugins/crypter/GoogledriveComFolder.py b/module/plugins/crypter/GoogledriveComFolder.py
index 70898b313..88c7ebab2 100644
--- a/module/plugins/crypter/GoogledriveComFolder.py
+++ b/module/plugins/crypter/GoogledriveComFolder.py
@@ -6,10 +6,11 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class GoogledriveComFolder(SimpleCrypter):
__name__ = "GoogledriveCom"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?drive\.google\.com/folderview\?.*id=\w+'
- __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides core.config['general']['folder_per_package']
+ __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config['general']['folder_per_package']
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
__description__ = """Drive.google.com folder decrypter plugin"""
diff --git a/module/plugins/crypter/HoerbuchIn.py b/module/plugins/crypter/HoerbuchIn.py
index ccc3ab664..27075324d 100644
--- a/module/plugins/crypter/HoerbuchIn.py
+++ b/module/plugins/crypter/HoerbuchIn.py
@@ -2,15 +2,16 @@
import re
-from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
+import BeautifulSoup
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class HoerbuchIn(Crypter):
__name__ = "HoerbuchIn"
__type__ = "crypter"
- __version__ = "0.60"
+ __version__ = "0.62"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?hoerbuch\.in/(wp/horbucher/\d+/.+/|tp/out\.php\?.+|protection/folder_\d+\.html)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -31,26 +32,26 @@ class HoerbuchIn(Crypter):
if self.article.match(pyfile.url):
html = self.load(pyfile.url)
- soup = BeautifulSoup(html, convertEntities=BeautifulStoneSoup.HTML_ENTITIES)
+ soup = BeautifulSoup.BeautifulSoup(html, convertEntities=BeautifulSoup.BeautifulStoneSoup.HTML_ENTITIES)
- abookname = soup.find("a", attrs={"rel": "bookmark"}).text
- for a in soup.findAll("a", attrs={"href": self.protection}):
+ abookname = soup.find("a", attrs={'rel': "bookmark"}).text
+ for a in soup.findAll("a", attrs={'href': self.protection}):
package = "%s (%s)" % (abookname, a.previousSibling.previousSibling.text[:-1])
- links = self.decryptFolder(a['href'])
+ links = self.decrypt_folder(a['href'])
self.packages.append((package, links, package))
else:
- self.urls = self.decryptFolder(pyfile.url)
+ self.urls = self.decrypt_folder(pyfile.url)
- def decryptFolder(self, url):
+ def decrypt_folder(self, url):
m = self.protection.search(url)
if m is None:
self.fail(_("Bad URL"))
url = m.group(0)
self.pyfile.url = url
- html = self.load(url, post={"viewed": "adpg"})
+ html = self.load(url, post={'viewed': "adpg"})
links = []
pattern = re.compile("http://www\.hoerbuch\.in/protection/(\w+)/(.*?)\"")
diff --git a/module/plugins/crypter/HotfileComFolder.py b/module/plugins/crypter/HotfileComFolder.py
index f1dd56228..1b2429f4a 100644
--- a/module/plugins/crypter/HotfileComFolder.py
+++ b/module/plugins/crypter/HotfileComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class HotfileComFolder(DeadCrypter):
__name__ = "HotfileComFolder"
__type__ = "crypter"
- __version__ = "0.30"
+ __version__ = "0.31"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?hotfile\.com/list/\w+/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/ILoadTo.py b/module/plugins/crypter/ILoadTo.py
index 4c7387739..03826cc5a 100644
--- a/module/plugins/crypter/ILoadTo.py
+++ b/module/plugins/crypter/ILoadTo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class ILoadTo(DeadCrypter):
__name__ = "ILoadTo"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?iload\.to/go/\d+-[\w.-]+/'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/ImgurComAlbum.py b/module/plugins/crypter/ImgurComAlbum.py
index 9ef7797af..488979b48 100644
--- a/module/plugins/crypter/ImgurComAlbum.py
+++ b/module/plugins/crypter/ImgurComAlbum.py
@@ -7,7 +7,8 @@ from module.utils import uniqify
class ImgurComAlbum(SimpleCrypter):
__name__ = "ImgurComAlbum"
__type__ = "crypter"
- __version__ = "0.51"
+ __version__ = "0.52"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.|m\.)?imgur\.com/(a|gallery|)/?\w{5,7}'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -23,7 +24,7 @@ class ImgurComAlbum(SimpleCrypter):
LINK_PATTERN = r'i\.imgur\.com/\w{7}s?\.(?:jpeg|jpg|png|gif|apng)'
- def getLinks(self):
+ def get_links(self):
f = lambda url: "http://" + re.sub(r'(\w{7})s\.', r'\1.', url)
return uniqify(map(f, re.findall(self.LINK_PATTERN, self.html)))
diff --git a/module/plugins/crypter/LetitbitNetFolder.py b/module/plugins/crypter/LetitbitNetFolder.py
index b60d754a7..e560306f5 100644
--- a/module/plugins/crypter/LetitbitNetFolder.py
+++ b/module/plugins/crypter/LetitbitNetFolder.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class LetitbitNetFolder(Crypter):
__name__ = "LetitbitNetFolder"
__type__ = "crypter"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?letitbit\.net/folder/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/LinkCryptWs.py b/module/plugins/crypter/LinkCryptWs.py
index 5c65e726d..af13f55f6 100644
--- a/module/plugins/crypter/LinkCryptWs.py
+++ b/module/plugins/crypter/LinkCryptWs.py
@@ -7,14 +7,15 @@ import pycurl
from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
from module.utils import html_unescape
class LinkCryptWs(Crypter):
__name__ = "LinkCryptWs"
__type__ = "crypter"
- __version__ = "0.08"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?linkcrypt\.ws/(dir|container)/(?P<ID>\w+)'
@@ -36,13 +37,13 @@ class LinkCryptWs(Crypter):
def prepare(self):
- # Init
+ #: Init
self.fileid = re.match(self.__pattern__, self.pyfile.url).group('ID')
self.req.cj.setCookie("linkcrypt.ws", "language", "en")
- # Request package
- self.req.http.c.setopt(pycurl.USERAGENT, "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko") #: better chance to not get those key-captchas
+ #: Request package
+ self.req.http.c.setopt(pycurl.USERAGENT, "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko") #: Better chance to not get those key-captchas
self.html = self.load(self.pyfile.url)
@@ -52,34 +53,34 @@ class LinkCryptWs(Crypter):
self.prepare()
- if not self.isOnline():
+ if not self.is_online():
self.offline()
- if self.isKeyCaptchaProtected():
+ if self.is_key_captcha_protected():
self.retry(8, 15, _("Can't handle Key-Captcha"))
- if self.isCaptchaProtected():
+ if self.is_captcha_protected():
self.captcha = True
- self.unlockCaptchaProtection()
- self.handleCaptchaErrors()
+ self.unlock_captcha_protection()
+ self.handle_captcha_errors()
- # Check for protection
- if self.isPasswordProtected():
- self.unlockPasswordProtection()
- self.handleErrors()
+ #: Check for protection
+ if self.is_password_protected():
+ self.unlock_password_protection()
+ self.handle_errors()
- # get unrar password
+ #: Get unrar password
self.getunrarpw()
- # Get package name and folder
- package_name, folder_name = self.getPackageInfo()
+ #: Get package name and folder
+ package_name, folder_name = self.get_package_info()
- #get the container definitions from script section
+ #: Get the container definitions from script section
self.get_container_html()
- # Extract package links
+ #: Extract package links
for type in self.sources:
- links = self.handleLinkSource(type)
+ links = self.handle_link_source(type)
if links:
self.links.extend(links)
@@ -89,59 +90,59 @@ class LinkCryptWs(Crypter):
self.packages = [(package_name, self.links, folder_name)]
- def isOnline(self):
+ def is_online(self):
if "<title>Linkcrypt.ws // Error 404</title>" in self.html:
- self.logDebug("Folder doesn't exist anymore")
+ self.log_debug("Folder doesn't exist anymore")
return False
else:
return True
- def isPasswordProtected(self):
+ def is_password_protected(self):
if "Authorizing" in self.html:
- self.logDebug("Links are password protected")
+ self.log_debug("Links are password protected")
return True
else:
return False
- def isCaptchaProtected(self):
+ def is_captcha_protected(self):
if 'id="captcha">' in self.html:
- self.logDebug("Links are captcha protected")
+ self.log_debug("Links are captcha protected")
return True
else:
return False
- def isKeyCaptchaProtected(self):
+ def is_key_captcha_protected(self):
if re.search(r'>If the folder does not open after klick on <', self.html, re.I):
return True
else:
return False
- def unlockPasswordProtection(self):
- password = self.getPassword()
+ def unlock_password_protection(self):
+ password = self.get_password()
if password:
- self.logDebug("Submitting password [%s] for protected links" % password)
- self.html = self.load(self.pyfile.url, post={"password": password, 'x': "0", 'y': "0"})
+ self.log_debug("Submitting password [%s] for protected links" % password)
+ self.html = self.load(self.pyfile.url, post={'password': password, 'x': "0", 'y': "0"})
else:
self.fail(_("Folder is password protected"))
- def unlockCaptchaProtection(self):
+ def unlock_captcha_protection(self):
captcha_url = re.search(r'<form.*?id\s*?=\s*?"captcha"[^>]*?>.*?<\s*?input.*?src="(.+?)"', self.html, re.I | re.S).group(1)
- captcha_code = self.decryptCaptcha(captcha_url, forceUser=True, imgtype="gif", result_type='positional')
+ captcha_code = self.captcha.decrypt(captcha_url, input_type="gif", output_type='positional')
- self.html = self.load(self.pyfile.url, post={"x": captcha_code[0], "y": captcha_code[1]})
+ self.html = self.load(self.pyfile.url, post={'x': captcha_code[0], 'y': captcha_code[1]})
- def getPackageInfo(self):
+ def get_package_info(self):
name = self.pyfile.package().name
folder = self.pyfile.package().folder
- self.logDebug("Defaulting to pyfile name [%s] and folder [%s] for package" % (name, folder))
+ self.log_debug("Defaulting to pyfile name [%s] and folder [%s] for package" % (name, folder))
return name, folder
@@ -149,51 +150,51 @@ class LinkCryptWs(Crypter):
def getunrarpw(self):
sitein = self.html
indexi = sitein.find("|source|") + 8
- indexe = sitein.find("|",indexi)
+ indexe = sitein.find("|", indexi)
unrarpw = sitein[indexi:indexe]
if not (unrarpw == "Password" or "Dateipasswort") :
- self.logDebug("File password set to: [%s]"% unrarpw)
+ self.log_debug("File password set to: [%s]"% unrarpw)
self.pyfile.package().password = unrarpw
- def handleErrors(self):
- if self.isPasswordProtected():
+ def handle_errors(self):
+ if self.is_password_protected():
self.fail(_("Incorrect password"))
- def handleCaptchaErrors(self):
+ def handle_captcha_errors(self):
if self.captcha:
if "Your choice was wrong!" in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry()
else:
- self.correctCaptcha()
+ self.captcha.correct()
- def handleLinkSource(self, type):
- if type == 'cnl':
- return self.handleCNL2()
+ def handle_link_source(self, type):
+ if type == "cnl":
+ return self.handle_CNL2()
- elif type == 'web':
- return self.handleWebLinks()
+ elif type == "web":
+ return self.handle_web_links()
elif type in ('rsdf', 'ccf', 'dlc'):
- return self.handleContainer(type)
+ return self.handle_container(type)
else:
self.fail(_("Unknown source type: %s") % type) #@TODO: Replace with self.error in 0.4.10
- def handleWebLinks(self):
- self.logDebug("Search for Web links ")
+ def handle_web_links(self):
+ self.log_debug("Search for Web links ")
package_links = []
pattern = r'<form action="http://linkcrypt.ws/out.html"[^>]*?>.*?<input[^>]*?value="(.+?)"[^>]*?name="file"'
ids = re.findall(pattern, self.html, re.I | re.S)
- self.logDebug("Decrypting %d Web links" % len(ids))
+ self.log_debug("Decrypting %d Web links" % len(ids))
for idx, weblink_id in enumerate(ids):
try:
@@ -208,7 +209,7 @@ class LinkCryptWs(Crypter):
package_links.append(link2)
except Exception, detail:
- self.logDebug("Error decrypting Web link %s, %s" % (weblink_id, detail))
+ self.log_debug("Error decrypting Web link %s, %s" % (weblink_id, detail))
return package_links
@@ -228,13 +229,13 @@ class LinkCryptWs(Crypter):
return self.js.eval(line.replace('{}))',"{}).replace('document.open();document.write','').replace(';document.close();',''))"))
- def handleContainer(self, type):
+ def handle_container(self, type):
package_links = []
type = type.lower()
- self.logDebug('Search for %s Container links' % type.upper())
+ self.log_debug('Search for %s Container links' % type.upper())
- if not type.isalnum(): # check to prevent broken re-pattern (cnl2,rsdf,ccf,dlc,web are all alpha-numeric)
+ if not type.isalnum(): #: Check to prevent broken re-pattern (cnl2, rsdf, ccf, dlc, web are all alpha-numeric)
self.fail(_("Unknown container type: %s") % type) #@TODO: Replace with self.error in 0.4.10
for line in self.container_html:
@@ -245,18 +246,18 @@ class LinkCryptWs(Crypter):
if not clink:
continue
- self.logDebug("clink avaible")
+ self.log_debug("clink avaible")
- package_name, folder_name = self.getPackageInfo()
- self.logDebug("Added package with name %s.%s and container link %s" %( package_name, type, clink.group(1)))
- self.core.api.uploadContainer( "%s.%s" %(package_name, type), self.load(clink.group(1)))
+ package_name, folder_name = self.get_package_info()
+ self.log_debug("Added package with name %s.%s and container link %s" %( package_name, type, clink.group(1)))
+ self.pyload.api.uploadContainer('.'.join([package_name, type]), self.load(clink.group(1)))
return "Found it"
return package_links
- def handleCNL2(self):
- self.logDebug("Search for CNL links")
+ def handle_CNL2(self):
+ self.log_debug("Search for CNL links")
package_links = []
cnl_line = None
@@ -267,52 +268,52 @@ class LinkCryptWs(Crypter):
break
if cnl_line:
- self.logDebug("cnl_line gefunden")
+ self.log_debug("cnl_line gefunden")
try:
cnl_section = self.handle_javascript(cnl_line)
- (vcrypted, vjk) = self._getCipherParams(cnl_section)
+ (vcrypted, vjk) = self._get_cipher_params(cnl_section)
for (crypted, jk) in zip(vcrypted, vjk):
- package_links.extend(self._getLinks(crypted, jk))
+ package_links.extend(self._get_links(crypted, jk))
except Exception:
- self.logError(_("Unable to decrypt CNL links (JS Error) try to get over links"))
- return self.handleWebLinks()
+ self.log_error(_("Unable to decrypt CNL links (JS Error) try to get over links"))
+ return self.handle_web_links()
return package_links
- def _getCipherParams(self, cnl_section):
- # Get jk
+ def _get_cipher_params(self, cnl_section):
+ #: Get jk
jk_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkCryptWs.JK_KEY
vjk = re.findall(jk_re, cnl_section)
- # Get crypted
+ #: Get crypted
crypted_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkCryptWs.CRYPTED_KEY
vcrypted = re.findall(crypted_re, cnl_section)
- # Log and return
- self.logDebug("Detected %d crypted blocks" % len(vcrypted))
+ #: Log and return
+ self.log_debug("Detected %d crypted blocks" % len(vcrypted))
return vcrypted, vjk
- def _getLinks(self, crypted, jk):
- # Get key
+ def _get_links(self, crypted, jk):
+ #: Get key
jreturn = self.js.eval("%s f()" % jk)
key = binascii.unhexlify(jreturn)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
+ self.log_debug("JsEngine returns value [%s]" % jreturn)
- # Decrypt
+ #: Decrypt
Key = key
IV = key
obj = AES.new(Key, AES.MODE_CBC, IV)
text = obj.decrypt(crypted.decode('base64'))
- # Extract links
+ #: Extract links
text = text.replace("\x00", "").replace("\r", "")
links = filter(bool, text.split('\n'))
- # Log and return
- self.logDebug("Package has %d links" % len(links))
+ #: Log and return
+ self.log_debug("Package has %d links" % len(links))
return links
diff --git a/module/plugins/crypter/LinkSaveIn.py b/module/plugins/crypter/LinkSaveIn.py
index 95652096d..36b545de8 100644
--- a/module/plugins/crypter/LinkSaveIn.py
+++ b/module/plugins/crypter/LinkSaveIn.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer, create_getInfo
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
-class LinkSaveIn(SimpleDereferer):
+class LinkSaveIn(SimpleCrypter):
__name__ = "LinkSaveIn"
__type__ = "crypter"
- __version__ = "2.04"
+ __version__ = "2.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?linksave\.in/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/LinkdecrypterCom.py b/module/plugins/crypter/LinkdecrypterCom.py
index 0704214d0..d8812dbd5 100644
--- a/module/plugins/crypter/LinkdecrypterCom.py
+++ b/module/plugins/crypter/LinkdecrypterCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.MultiCrypter import MultiCrypter
-class LinkdecrypterCom(Crypter):
+class LinkdecrypterCom(MultiCrypter):
__name__ = "LinkdecrypterCom"
__type__ = "crypter"
- __version__ = "0.29"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -27,15 +28,15 @@ class LinkdecrypterCom(Crypter):
def setup(self):
- self.password = self.getPassword()
+ self.password = self.get_password()
self.req.setOption("timeout", 300)
def decrypt(self, pyfile):
retries = 5
- post_dict = {"link_cache": "on", "pro_links": pyfile.url, "modo_links": "text"}
- self.html = self.load('http://linkdecrypter.com/', post=post_dict, decode=True)
+ post_dict = {'link_cache': "on", 'pro_links': pyfile.url, 'modo_links': "text"}
+ self.html = self.load('http://linkdecrypter.com/', post=post_dict)
while retries:
m = re.search(self.TEXTAREA_PATTERN, self.html, re.S)
@@ -49,21 +50,21 @@ class LinkdecrypterCom(Crypter):
m = re.search(r"<p><i><b>([^<]+)</b></i></p>", self.html)
msg = m.group(1) if m else ""
- self.logInfo(_("Captcha protected link"), result_type, msg)
+ self.log_info(_("Captcha protected link"), result_type, msg)
- captcha = self.decryptCaptcha(captcha_url, result_type=result_type)
+ captcha = self.captcha.decrypt(captcha_url, output_type=result_type)
if result_type == "positional":
captcha = "%d|%d" % captcha
- self.html = self.load('http://linkdecrypter.com/', post={"captcha": captcha}, decode=True)
+ self.html = self.load('http://linkdecrypter.com/', post={'captcha': captcha})
retries -= 1
elif self.PASSWORD_PATTERN in self.html:
if self.password:
- self.logInfo(_("Password protected link"))
- self.html = self.load('http://linkdecrypter.com/', post={'password': self.password}, decode=True)
+ self.log_info(_("Password protected link"))
+ self.html = self.load('http://linkdecrypter.com/', post={'password': self.password})
else:
self.fail(_("Missing password"))
else:
retries -= 1
- self.html = self.load('http://linkdecrypter.com/', decode=True)
+ self.html = self.load('http://linkdecrypter.com/')
diff --git a/module/plugins/crypter/LixIn.py b/module/plugins/crypter/LixIn.py
index 5c77eae5e..2d26564e8 100644
--- a/module/plugins/crypter/LixIn.py
+++ b/module/plugins/crypter/LixIn.py
@@ -3,13 +3,14 @@
import re
import urlparse
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class LixIn(Crypter):
__name__ = "LixIn"
__type__ = "crypter"
- __version__ = "0.22"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?lix\.in/(?P<ID>.+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -33,9 +34,9 @@ class LixIn(Crypter):
self.error(_("Unable to identify file ID"))
id = m.group('ID')
- self.logDebug("File id is %s" % id)
+ self.log_debug("File id is %s" % id)
- self.html = self.load(url, decode=True)
+ self.html = self.load(url)
m = re.search(self.SUBMIT_PATTERN, self.html)
if m is None:
@@ -46,18 +47,18 @@ class LixIn(Crypter):
for _i in xrange(5):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
- self.logDebug("Trying captcha")
- captcharesult = self.decryptCaptcha(urlparse.urljoin("http://lix.in/", m.group(1)))
- self.html = self.load(url, decode=True,
- post={"capt": captcharesult, "submit": "submit", "tiny": id})
+ self.log_debug("Trying captcha")
+ captcharesult = self.captcha.decrypt(urlparse.urljoin("http://lix.in/", m.group(1)))
+ self.html = self.load(url,
+ post={'capt': captcharesult, 'submit': "submit", 'tiny': id})
else:
- self.logDebug("No captcha/captcha solved")
+ self.log_debug("No captcha/captcha solved")
else:
- self.html = self.load(url, decode=True, post={"submit": "submit", "tiny": id})
+ self.html = self.load(url, post={'submit': "submit", 'tiny': id})
m = re.search(self.LINK_PATTERN, self.html)
if m is None:
self.error(_("Unable to find destination url"))
else:
self.urls = [m.group(1)]
- self.logDebug("Found link %s, adding to package" % self.urls[0])
+ self.log_debug("Found link %s, adding to package" % self.urls[0])
diff --git a/module/plugins/crypter/LofCc.py b/module/plugins/crypter/LofCc.py
index 62e05f299..b25c9485a 100644
--- a/module/plugins/crypter/LofCc.py
+++ b/module/plugins/crypter/LofCc.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class LofCc(DeadCrypter):
__name__ = "LofCc"
__type__ = "crypter"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?lof\.cc/(.+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/MBLinkInfo.py b/module/plugins/crypter/MBLinkInfo.py
index 7ff400f7e..98c63b9d4 100644
--- a/module/plugins/crypter/MBLinkInfo.py
+++ b/module/plugins/crypter/MBLinkInfo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class MBLinkInfo(DeadCrypter):
__name__ = "MBLinkInfo"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?mblink\.info/?\?id=(\d+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/MediafireComFolder.py b/module/plugins/crypter/MediafireComFolder.py
index c1612bb6a..81d880725 100644
--- a/module/plugins/crypter/MediafireComFolder.py
+++ b/module/plugins/crypter/MediafireComFolder.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
from module.plugins.hoster.MediafireCom import checkHTMLHeader
from module.common.json_layer import json_loads
@@ -9,7 +9,8 @@ from module.common.json_layer import json_loads
class MediafireComFolder(Crypter):
__name__ = "MediafireComFolder"
__type__ = "crypter"
- __version__ = "0.14"
+ __version__ = "0.16"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?mediafire\.com/(folder/|\?sharekey=|\?\w{13}($|[/#]))'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -26,27 +27,27 @@ class MediafireComFolder(Crypter):
def decrypt(self, pyfile):
url, result = checkHTMLHeader(pyfile.url)
- self.logDebug("Location (%d): %s" % (result, url))
+ self.log_debug("Location (%d): %s" % (result, url))
if result == 0:
- # load and parse html
+ #: Load and parse html
html = self.load(pyfile.url)
m = re.search(self.LINK_PATTERN, html)
if m:
- # file page
+ #: File page
self.urls.append("http://www.mediafire.com/file/%s" % m.group(1))
else:
- # folder page
+ #: Folder page
m = re.search(self.FOLDER_KEY_PATTERN, html)
if m:
folder_key = m.group(1)
- self.logDebug("FOLDER KEY: %s" % folder_key)
+ self.log_debug("FOLDER KEY: %s" % folder_key)
json_resp = json_loads(self.load("http://www.mediafire.com/api/folder/get_info.php",
get={'folder_key' : folder_key,
'response_format': "json",
'version' : 1}))
- #self.logInfo(json_resp)
+ # self.log_info(json_resp)
if json_resp['response']['result'] == "Success":
for link in json_resp['response']['folder_info']['files']:
self.urls.append("http://www.mediafire.com/file/%s" % link['quickkey'])
diff --git a/module/plugins/crypter/MegaCoNzFolder.py b/module/plugins/crypter/MegaCoNzFolder.py
index bd135ac5f..107746819 100644
--- a/module/plugins/crypter/MegaCoNzFolder.py
+++ b/module/plugins/crypter/MegaCoNzFolder.py
@@ -2,15 +2,16 @@
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class MegaCoNzFolder(Crypter):
__name__ = "MegaCoNzFolder"
__type__ = "crypter"
- __version__ = "0.04"
+ __version__ = "0.06"
+ __status__ = "testing"
- __pattern__ = r'(?:https?://(?:www\.)?mega\.co\.nz/|mega:|chrome:.+?)#F!(?P<ID>[\w^_]+)!(?P<KEY>[\w,\\-]+)'
+ __pattern__ = r'(https?://(?:www\.)?mega(\.co)?\.nz/|mega:|chrome:.+?)#F!(?P<ID>[\w^_]+)!(?P<KEY>[\w,\\-]+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
@@ -26,7 +27,4 @@ class MegaCoNzFolder(Crypter):
def decrypt(self, pyfile):
url = "https://mega.co.nz/#F!%s!%s" % re.match(self.__pattern__, pyfile.url).groups()
self.html = self.load("http://rapidgen.org/linkfinder", post={'linklisturl': url})
- self.urls = re.findall(r'(https://mega.co.nz/#N!.+?)<', self.html)
-
- if not self.urls: #@TODO: Remove in 0.4.10
- self.fail(_("No link grabbed"))
+ self.urls = re.findall(r'(https://mega(\.co)?\.nz/#N!.+?)<', self.html)
diff --git a/module/plugins/crypter/MegaRapidCzFolder.py b/module/plugins/crypter/MegaRapidCzFolder.py
index fadd6dbed..8e7bcdf6b 100644
--- a/module/plugins/crypter/MegaRapidCzFolder.py
+++ b/module/plugins/crypter/MegaRapidCzFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class MegaRapidCzFolder(SimpleCrypter):
__name__ = "MegaRapidCzFolder"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(share|mega)rapid\.cz/slozka/\d+/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/MegauploadComFolder.py b/module/plugins/crypter/MegauploadComFolder.py
index 60e4af57e..c0ae6d16a 100644
--- a/module/plugins/crypter/MegauploadComFolder.py
+++ b/module/plugins/crypter/MegauploadComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class MegauploadComFolder(DeadCrypter):
__name__ = "MegauploadComFolder"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?megaupload\.com/(\?f|xml/folderfiles\.php\?.*&?folderid)=\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/Movie2KTo.py b/module/plugins/crypter/Movie2KTo.py
index 919d77c86..53636cda3 100644
--- a/module/plugins/crypter/Movie2KTo.py
+++ b/module/plugins/crypter/Movie2KTo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class Movie2KTo(DeadCrypter):
__name__ = "Movie2KTo"
__type__ = "crypter"
- __version__ = "0.51"
+ __version__ = "0.52"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?movie2k\.to/(.+)\.html'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/MultiUpOrg.py b/module/plugins/crypter/MultiUpOrg.py
index b676c3029..b4326b679 100644
--- a/module/plugins/crypter/MultiUpOrg.py
+++ b/module/plugins/crypter/MultiUpOrg.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class MultiUpOrg(SimpleCrypter):
__name__ = "MultiUpOrg"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?multiup\.org/(en|fr)/(?P<TYPE>project|download|miror)/\w+(/\w+)?'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -24,7 +25,7 @@ class MultiUpOrg(SimpleCrypter):
NAME_PATTERN = r'<title>.*(?:Project|Projet|ownload|élécharger) (?P<N>.+?) (\(|- )'
- def getLinks(self):
+ def get_links(self):
m_type = re.match(self.__pattern__, self.pyfile.url).group('TYPE')
if m_type == "project":
diff --git a/module/plugins/crypter/MultiloadCz.py b/module/plugins/crypter/MultiloadCz.py
index eea689a09..d9b6236be 100644
--- a/module/plugins/crypter/MultiloadCz.py
+++ b/module/plugins/crypter/MultiloadCz.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class MultiloadCz(Crypter):
__name__ = "MultiloadCz"
__type__ = "crypter"
- __version__ = "0.40"
+ __version__ = "0.42"
+ __status__ = "testing"
__pattern__ = r'http://(?:[^/]*\.)?multiload\.cz/(stahnout|slozka)/.+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -25,7 +26,7 @@ class MultiloadCz(Crypter):
def decrypt(self, pyfile):
- self.html = self.load(pyfile.url, decode=True)
+ self.html = self.load(pyfile.url)
if re.match(self.__pattern__, pyfile.url).group(1) == "slozka":
m = re.search(self.FOLDER_PATTERN, self.html)
@@ -34,9 +35,9 @@ class MultiloadCz(Crypter):
else:
m = re.findall(self.LINK_PATTERN, self.html)
if m:
- prefered_set = set(self.getConfig('usedHoster').split('|'))
+ prefered_set = set(self.get_config('usedHoster').split('|'))
self.urls.extend(x[1] for x in m if x[0] in prefered_set)
if not self.urls:
- ignored_set = set(self.getConfig('ignoredHoster').split('|'))
+ ignored_set = set(self.get_config('ignoredHoster').split('|'))
self.urls.extend(x[1] for x in m if x[0] not in ignored_set)
diff --git a/module/plugins/crypter/MultiuploadCom.py b/module/plugins/crypter/MultiuploadCom.py
index 41794445a..358758b7a 100644
--- a/module/plugins/crypter/MultiuploadCom.py
+++ b/module/plugins/crypter/MultiuploadCom.py
@@ -6,12 +6,13 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class MultiuploadCom(DeadCrypter):
__name__ = "MultiuploadCom"
__type__ = "crypter"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?multiupload\.(com|nl)/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
- __description__ = """ MultiUpload.com decrypter plugin """
+ __description__ = """MultiUpload.com decrypter plugin"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index 593e9b506..d483be323 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -5,14 +5,15 @@ import re
from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.internal.Crypter import Crypter
+from module.plugins.captcha.ReCaptcha import ReCaptcha
class NCryptIn(Crypter):
__name__ = "NCryptIn"
__type__ = "crypter"
- __version__ = "1.35"
+ __version__ = "1.37"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?ncrypt\.in/(?P<TYPE>folder|link|frame)-([^/\?]+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -32,62 +33,62 @@ class NCryptIn(Crypter):
def setup(self):
self.package = None
- self.cleanedHtml = None
+ self.cleaned_html = None
self.links_source_order = ["cnl2", "rsdf", "ccf", "dlc", "web"]
self.protection_type = None
def decrypt(self, pyfile):
- # Init
+ #: Init
self.package = pyfile.package()
package_links = []
package_name = self.package.name
folder_name = self.package.folder
- # Deal with single links
- if self.isSingleLink():
- package_links.extend(self.handleSingleLink())
+ #: Deal with single links
+ if self.is_single_link():
+ package_links.extend(self.handle_single_link())
- # Deal with folders
+ #: Deal with folders
else:
- # Request folder home
- self.html = self.requestFolderHome()
- self.cleanedHtml = self.removeHtmlCrap(self.html)
- if not self.isOnline():
+ #: Request folder home
+ self.html = self.request_folder_home()
+ self.cleaned_html = self.remove_html_crap(self.html)
+ if not self.is_online():
self.offline()
- # Check for folder protection
- if self.isProtected():
- self.html = self.unlockProtection()
- self.cleanedHtml = self.removeHtmlCrap(self.html)
- self.handleErrors()
+ #: Check for folder protection
+ if self.is_protected():
+ self.html = self.unlock_protection()
+ self.cleaned_html = self.remove_html_crap(self.html)
+ self.handle_errors()
- # Prepare package name and folder
- (package_name, folder_name) = self.getPackageInfo()
+ #: Prepare package name and folder
+ (package_name, folder_name) = self.get_package_info()
- # Extract package links
+ #: Extract package links
for link_source_type in self.links_source_order:
- package_links.extend(self.handleLinkSource(link_source_type))
- if package_links: # use only first source which provides links
+ package_links.extend(self.handle_link_source(link_source_type))
+ if package_links: #: Use only first source which provides links
break
package_links = set(package_links)
- # Pack and return links
+ #: Pack and return links
if package_links:
self.packages = [(package_name, package_links, folder_name)]
- def isSingleLink(self):
+ def is_single_link(self):
link_type = re.match(self.__pattern__, self.pyfile.url).group('TYPE')
return link_type in ("link", "frame")
- def requestFolderHome(self):
- return self.load(self.pyfile.url, decode=True)
+ def request_folder_home(self):
+ return self.load(self.pyfile.url)
- def removeHtmlCrap(self, content):
+ def remove_html_crap(self, content):
patterns = (r'(type="hidden".*?(name=".*?")?.*?value=".*?")',
r'display:none;">(.*?)</(div|span)>',
r'<div\s+class="jdownloader"(.*?)</div>',
@@ -99,148 +100,148 @@ class NCryptIn(Crypter):
return content
- def isOnline(self):
- if "Your folder does not exist" in self.cleanedHtml:
- self.logDebug("File not m")
+ def is_online(self):
+ if "Your folder does not exist" in self.cleaned_html:
+ self.log_debug("File not m")
return False
return True
- def isProtected(self):
- form = re.search(r'<form.*?name.*?protected.*?>(.*?)</form>', self.cleanedHtml, re.S)
+ def is_protected(self):
+ form = re.search(r'<form.*?name.*?protected.*?>(.*?)</form>', self.cleaned_html, re.S)
if form:
content = form.group(1)
for keyword in ("password", "captcha"):
if keyword in content:
self.protection_type = keyword
- self.logDebug("Links are %s protected" % self.protection_type)
+ self.log_debug("Links are %s protected" % self.protection_type)
return True
return False
- def getPackageInfo(self):
+ def get_package_info(self):
m = re.search(self.NAME_PATTERN, self.html)
if m:
name = folder = m.group('N').strip()
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
+ self.log_debug("Found name [%s] and folder [%s] in package info" % (name, folder))
else:
name = self.package.name
folder = self.package.folder
- self.logDebug("Package info not m, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
+ self.log_debug("Package info not m, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
return name, folder
- def unlockProtection(self):
+ def unlock_protection(self):
postData = {}
- form = re.search(r'<form name="protected"(.*?)</form>', self.cleanedHtml, re.S).group(1)
+ form = re.search(r'<form name="protected"(.*?)</form>', self.cleaned_html, re.S).group(1)
- # Submit package password
+ #: Submit package password
if "password" in form:
- password = self.getPassword()
- self.logDebug("Submitting password [%s] for protected links" % password)
+ password = self.get_password()
+ self.log_debug("Submitting password [%s] for protected links" % password)
postData['password'] = password
- # Resolve anicaptcha
+ #: Resolve anicaptcha
if "anicaptcha" in form:
- self.logDebug("Captcha protected")
+ self.log_debug("Captcha protected")
captchaUri = re.search(r'src="(/temp/anicaptcha/.+?)"', form).group(1)
- captcha = self.decryptCaptcha("http://ncrypt.in" + captchaUri)
- self.logDebug("Captcha resolved [%s]" % captcha)
+ captcha = self.captcha.decrypt("http://ncrypt.in" + captchaUri)
+ self.log_debug("Captcha resolved [%s]" % captcha)
postData['captcha'] = captcha
- # Resolve recaptcha
+ #: Resolve recaptcha
if "recaptcha" in form:
- self.logDebug("ReCaptcha protected")
+ self.log_debug("ReCaptcha protected")
captcha_key = re.search(r'\?k=(.*?)"', form).group(1)
- self.logDebug("Resolving ReCaptcha with key [%s]" % captcha_key)
+ self.log_debug("Resolving ReCaptcha with key [%s]" % captcha_key)
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge(captcha_key)
postData['recaptcha_challenge_field'] = challenge
postData['recaptcha_response_field'] = response
- # Resolve circlecaptcha
+ #: Resolve circlecaptcha
if "circlecaptcha" in form:
- self.logDebug("CircleCaptcha protected")
+ self.log_debug("CircleCaptcha protected")
captcha_img_url = "http://ncrypt.in/classes/captcha/circlecaptcha.php"
- coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional')
- self.logDebug("Captcha resolved, coords [%s]" % str(coords))
+ coords = self.captcha.decrypt(captcha_img_url, input_type="png", output_type='positional', ocr="CircleCaptcha")
+ self.log_debug("Captcha resolved, coords [%s]" % str(coords))
postData['circle.x'] = coords[0]
postData['circle.y'] = coords[1]
- # Unlock protection
+ #: Unlock protection
postData['submit_protected'] = 'Continue to folder'
- return self.load(self.pyfile.url, post=postData, decode=True)
+ return self.load(self.pyfile.url, post=postData)
- def handleErrors(self):
+ def handle_errors(self):
if self.protection_type == "password":
- if "This password is invalid!" in self.cleanedHtml:
- self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry")
+ if "This password is invalid!" in self.cleaned_html:
+ self.log_debug("Incorrect password, please set right password on 'Edit package' form and retry")
self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry"))
if self.protection_type == "captcha":
- if "The securitycheck was wrong!" in self.cleanedHtml:
- self.invalidCaptcha()
+ if "The securitycheck was wrong!" in self.cleaned_html:
+ self.captcha.invalid()
self.retry()
else:
- self.correctCaptcha()
+ self.captcha.correct()
- def handleLinkSource(self, link_source_type):
- # Check for JS engine
+ def handle_link_source(self, link_source_type):
+ #: Check for JS engine
require_js_engine = link_source_type in ("cnl2", "rsdf", "ccf", "dlc")
if require_js_engine and not self.js:
- self.logDebug("No JS engine available, skip %s links" % link_source_type)
+ self.log_debug("No JS engine available, skip %s links" % link_source_type)
return []
- # Select suitable handler
- if link_source_type == 'single':
- return self.handleSingleLink()
- if link_source_type == 'cnl2':
- return self.handleCNL2()
+ #: Select suitable handler
+ if link_source_type == "single":
+ return self.handle_single_link()
+ if link_source_type == "cnl2":
+ return self.handle_CNL2()
elif link_source_type in ("rsdf", "ccf", "dlc"):
- return self.handleContainer(link_source_type)
+ return self.handle_container(link_source_type)
elif link_source_type == "web":
- return self.handleWebLinks()
+ return self.handle_web_links()
else:
self.error(_('Unknown source type "%s"') % link_source_type)
- def handleSingleLink(self):
- self.logDebug("Handling Single link")
+ def handle_single_link(self):
+ self.log_debug("Handling Single link")
package_links = []
- # Decrypt single link
- decrypted_link = self.decryptLink(self.pyfile.url)
+ #: Decrypt single link
+ decrypted_link = self.decrypt_link(self.pyfile.url)
if decrypted_link:
package_links.append(decrypted_link)
return package_links
- def handleCNL2(self):
- self.logDebug("Handling CNL2 links")
+ def handle_CNL2(self):
+ self.log_debug("Handling CNL2 links")
package_links = []
- if 'cnl2_output' in self.cleanedHtml:
+ if 'cnl2_output' in self.cleaned_html:
try:
- (vcrypted, vjk) = self._getCipherParams()
+ (vcrypted, vjk) = self._get_cipher_params()
for (crypted, jk) in zip(vcrypted, vjk):
- package_links.extend(self._getLinks(crypted, jk))
+ package_links.extend(self._get_links(crypted, jk))
except Exception:
self.fail(_("Unable to decrypt CNL2 links"))
return package_links
- def handleContainers(self):
- self.logDebug("Handling Container links")
+ def handle_containers(self):
+ self.log_debug("Handling Container links")
package_links = []
pattern = r'/container/(rsdf|dlc|ccf)/(\w+)'
containersLinks = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Container links" % len(containersLinks))
+ self.log_debug("Decrypting %d Container links" % len(containersLinks))
for containerLink in containersLinks:
link = "http://ncrypt.in/container/%s/%s.%s" % (containerLink[0], containerLink[1], containerLink[0])
package_links.append(link)
@@ -248,15 +249,15 @@ class NCryptIn(Crypter):
return package_links
- def handleWebLinks(self):
- self.logDebug("Handling Web links")
+ def handle_web_links(self):
+ self.log_debug("Handling Web links")
pattern = r'(http://ncrypt\.in/link-.*?=)'
links = re.findall(pattern, self.html)
package_links = []
- self.logDebug("Decrypting %d Web links" % len(links))
+ self.log_debug("Decrypting %d Web links" % len(links))
for i, link in enumerate(links):
- self.logDebug("Decrypting Web link %d, %s" % (i + 1, link))
+ self.log_debug("Decrypting Web link %d, %s" % (i + 1, link))
decrypted_link = self.decrypt(link)
if decrypted_link:
package_links.append(decrypted_link)
@@ -264,47 +265,47 @@ class NCryptIn(Crypter):
return package_links
- def decryptLink(self, link):
+ def decrypt_link(self, link):
try:
url = link.replace("link-", "frame-")
link = self.load(url, just_header=True)['location']
return link
except Exception, detail:
- self.logDebug("Error decrypting link %s, %s" % (link, detail))
+ self.log_debug("Error decrypting link %s, %s" % (link, detail))
- def _getCipherParams(self):
+ def _get_cipher_params(self):
pattern = r'<input.*?name="%s".*?value="(.*?)"'
- # Get jk
+ #: Get jk
jk_re = pattern % NCryptIn.JK_KEY
vjk = re.findall(jk_re, self.html)
- # Get crypted
+ #: Get crypted
crypted_re = pattern % NCryptIn.CRYPTED_KEY
vcrypted = re.findall(crypted_re, self.html)
- # Log and return
- self.logDebug("Detected %d crypted blocks" % len(vcrypted))
+ #: Log and return
+ self.log_debug("Detected %d crypted blocks" % len(vcrypted))
return vcrypted, vjk
- def _getLinks(self, crypted, jk):
- # Get key
+ def _get_links(self, crypted, jk):
+ #: Get key
jreturn = self.js.eval("%s f()" % jk)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
+ self.log_debug("JsEngine returns value [%s]" % jreturn)
key = binascii.unhexlify(jreturn)
- # Decrypt
+ #: Decrypt
Key = key
IV = key
obj = AES.new(Key, AES.MODE_CBC, IV)
text = obj.decrypt(crypted.decode('base64'))
- # Extract links
+ #: Extract links
text = text.replace("\x00", "").replace("\r", "")
links = filter(bool, text.split('\n'))
- # Log and return
- self.logDebug("Block has %d links" % len(links))
+ #: Log and return
+ self.log_debug("Block has %d links" % len(links))
return links
diff --git a/module/plugins/crypter/NetfolderIn.py b/module/plugins/crypter/NetfolderIn.py
index 32d59af03..5b992bf58 100644
--- a/module/plugins/crypter/NetfolderIn.py
+++ b/module/plugins/crypter/NetfolderIn.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class NetfolderIn(DeadCrypter):
__name__ = "NetfolderIn"
__type__ = "crypter"
- __version__ = "0.73"
+ __version__ = "0.74"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?netfolder\.(in|me)/(folder\.php\?folder_id=)?(?P<ID>\w+)(?(1)|/\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/NitroflareComFolder.py b/module/plugins/crypter/NitroflareComFolder.py
new file mode 100644
index 000000000..0f0443355
--- /dev/null
+++ b/module/plugins/crypter/NitroflareComFolder.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+from module.common.json_layer import json_loads
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
+
+
+class NitroflareComFolder(SimpleCrypter):
+ __name__ = "NitroflareComFolder"
+ __type__ = "crypter"
+ __version__ = "0.03"
+ __status__ = "testing"
+
+ __pattern__ = r'https?://(?:www\.)?nitroflare\.com/folder/(?P<USER>\d+)/(?P<ID>[\w=]+)'
+ __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
+ ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
+
+ __description__ = """Nitroflare.com folder decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def get_links(self):
+ res = json_loads(self.load("http://nitroflare.com/ajax/folder.php",
+ post={'userId' : self.info['pattern']['USER'],
+ 'folder' : self.info['pattern']['ID'],
+ 'page' : 1,
+ 'perPage': 10000}))
+ if res['name']:
+ self.pyfile.name = res['name']
+ else:
+ self.offline()
+
+ return [link['url'] for link in res['files']] if 'files' in res else None
+
+
+getInfo = create_getInfo(NitroflareComFolder)
diff --git a/module/plugins/crypter/NosvideoCom.py b/module/plugins/crypter/NosvideoCom.py
index 9808837c4..4513440d6 100644
--- a/module/plugins/crypter/NosvideoCom.py
+++ b/module/plugins/crypter/NosvideoCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class NosvideoCom(SimpleCrypter):
__name__ = "NosvideoCom"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?nosvideo\.com/\?v=\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
diff --git a/module/plugins/crypter/OneKhDe.py b/module/plugins/crypter/OneKhDe.py
index 4dcb416f5..341359c5a 100644
--- a/module/plugins/crypter/OneKhDe.py
+++ b/module/plugins/crypter/OneKhDe.py
@@ -2,15 +2,15 @@
import re
-from module.unescape import unescape
-
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
+from module.utils import html_unescape
class OneKhDe(Crypter):
__name__ = "OneKhDe"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?1kh\.de/f/'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -27,7 +27,8 @@ class OneKhDe(Crypter):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
return True
@@ -37,6 +38,6 @@ class OneKhDe(Crypter):
self.html = self.load(url)
link_ids = re.findall(r"<a id=\"DownloadLink_(\d*)\" href=\"http://1kh.de/", self.html)
for id in link_ids:
- new_link = unescape(
+ new_link = html_unescape(
re.search("width=\"100%\" src=\"(.*)\"></iframe>", self.load("http://1kh.de/l/" + id)).group(1))
self.urls.append(new_link)
diff --git a/module/plugins/crypter/OronComFolder.py b/module/plugins/crypter/OronComFolder.py
index 048af7d82..563c984fc 100644
--- a/module/plugins/crypter/OronComFolder.py
+++ b/module/plugins/crypter/OronComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class OronComFolder(DeadCrypter):
__name__ = "OronComFolder"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?oron\.com/folder/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/PastebinCom.py b/module/plugins/crypter/PastebinCom.py
index 751b47cc9..c8a7473f1 100644
--- a/module/plugins/crypter/PastebinCom.py
+++ b/module/plugins/crypter/PastebinCom.py
@@ -6,9 +6,10 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class PastebinCom(SimpleCrypter):
__name__ = "PastebinCom"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
- __pattern__ = r'http://(?:www\.)?pastebin\.com/\w+'
+ __pattern__ = r'https://(?:www\.)?pastebin\.com/(.+i=)?(?P<ID>\w{8})'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
("use_subfolder" , "bool", "Save package to subfolder" , True),
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
@@ -18,8 +19,10 @@ class PastebinCom(SimpleCrypter):
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- LINK_PATTERN = r'<div class="de\d+">(https?://[^ <]+)(?:[^<]*)</div>'
- NAME_PATTERN = r'<div class="paste_box_line1" title="(?P<N>.+?)">'
+ URL_REPLACEMENTS = [(__pattern__ + '.*', r'http://www.pastebin.com/\g<ID>')]
+
+ NAME_PATTERN = r'<div class="paste_box_line1" title="(?P<N>.+?)"'
+ LINK_PATTERN = r'<div class="de\d+">(.+?)<'
getInfo = create_getInfo(PastebinCom)
diff --git a/module/plugins/crypter/PastedCo.py b/module/plugins/crypter/PastedCo.py
new file mode 100644
index 000000000..0804f56d4
--- /dev/null
+++ b/module/plugins/crypter/PastedCo.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.Crypter import Crypter
+
+import re
+
+
+class PastedCo(Crypter):
+ __name__ = "PastedCo"
+ __type__ = "crypter"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'http://pasted\.co/\w+'
+
+ __description__ = """Pasted.co decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Frederik Möllers", "fred-public@posteo.de")]
+
+
+ NAME_PATTERN = r'<title>(?P<N>.+?) - .+</title>'
+ NAME_PATTERN = r"'save_paste' href=\"(http://pasted.co/[0-9a-f]+)/info"
+
+ FS_URL_PREFIX = '<pre id=\'thepaste\' class="prettyprint">'
+ FS_URL_SUFFIX = '</pre>'
+
+ def decrypt(self, pyfile):
+ package = pyfile.package()
+ package_name = package.name
+ package_folder = package.folder
+ html = self.load(pyfile.url, decode = True).splitlines()
+ fs_url = None
+ FS_URL_RE = re.compile('%s/fullscreen\.php\?hash=[0-9a-f]*' % pyfile.url)
+ for line in html:
+ match = FS_URL_RE.search(line)
+ if match:
+ fs_url = match.group()
+ break
+ if not fs_url:
+ raise Exception("Could not find pasted.co fullscreen URL!")
+ urls = self.load(fs_url, decode = True)
+ urls = urls[urls.find(PastedCo.FS_URL_PREFIX) + len(PastedCo.FS_URL_PREFIX):]
+ urls = urls[:urls.find(PastedCo.FS_URL_SUFFIX)].splitlines()
+ self.packages.append((package_name, urls, package_folder))
diff --git a/module/plugins/crypter/QuickshareCzFolder.py b/module/plugins/crypter/QuickshareCzFolder.py
index 3e38d36b4..10b6073e4 100644
--- a/module/plugins/crypter/QuickshareCzFolder.py
+++ b/module/plugins/crypter/QuickshareCzFolder.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class QuickshareCzFolder(Crypter):
__name__ = "QuickshareCzFolder"
__type__ = "crypter"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?quickshare\.cz/slozka-\d+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/RSLayerCom.py b/module/plugins/crypter/RSLayerCom.py
index 6f078e9e4..c8637279b 100644
--- a/module/plugins/crypter/RSLayerCom.py
+++ b/module/plugins/crypter/RSLayerCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class RSLayerCom(DeadCrypter):
__name__ = "RSLayerCom"
__type__ = "crypter"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?rs-layer\.com/directory-'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/RelinkUs.py b/module/plugins/crypter/RelinkUs.py
index ed3da1f9b..b3c13db5d 100644
--- a/module/plugins/crypter/RelinkUs.py
+++ b/module/plugins/crypter/RelinkUs.py
@@ -7,14 +7,15 @@ import re
import os
from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
-from module.utils import save_join
+from module.plugins.internal.Crypter import Crypter
+from module.utils import save_join as fs_join
class RelinkUs(Crypter):
__name__ = "RelinkUs"
__type__ = "crypter"
- __version__ = "3.12"
+ __version__ = "3.14"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?relink\.us/(f/|((view|go)\.php\?id=))(?P<ID>.+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -62,164 +63,164 @@ class RelinkUs(Crypter):
def decrypt(self, pyfile):
- # Init
- self.initPackage(pyfile)
+ #: Init
+ self.init_package(pyfile)
- # Request package
- self.requestPackage()
+ #: Request package
+ self.request_package()
- # Check for online
- if not self.isOnline():
+ #: Check for online
+ if not self.is_online():
self.offline()
- # Check for protection
- if self.isPasswordProtected():
- self.unlockPasswordProtection()
- self.handleErrors()
+ #: Check for protection
+ if self.is_password_protected():
+ self.unlock_password_protection()
+ self.handle_errors()
- if self.isCaptchaProtected():
+ if self.is_captcha_protected():
self.captcha = True
- self.unlockCaptchaProtection()
- self.handleErrors()
+ self.unlock_captcha_protection()
+ self.handle_errors()
- # Get package name and folder
- (package_name, folder_name) = self.getPackageInfo()
+ #: Get package name and folder
+ (package_name, folder_name) = self.get_package_info()
- # Extract package links
+ #: Extract package links
package_links = []
for sources in self.PREFERRED_LINK_SOURCES:
- package_links.extend(self.handleLinkSource(sources))
- if package_links: # use only first source which provides links
+ package_links.extend(self.handle_link_source(sources))
+ if package_links: #: Use only first source which provides links
break
package_links = set(package_links)
- # Pack
+ #: Pack
if package_links:
self.packages = [(package_name, package_links, folder_name)]
- def initPackage(self, pyfile):
+ def init_package(self, pyfile):
self.fileid = re.match(self.__pattern__, pyfile.url).group('ID')
self.package = pyfile.package()
- def requestPackage(self):
- self.html = self.load(self.pyfile.url, decode=True)
+ def request_package(self):
+ self.html = self.load(self.pyfile.url)
- def isOnline(self):
+ def is_online(self):
if self.OFFLINE_TOKEN in self.html:
- self.logDebug("File not found")
+ self.log_debug("File not found")
return False
return True
- def isPasswordProtected(self):
+ def is_password_protected(self):
if self.PASSWORD_TOKEN in self.html:
- self.logDebug("Links are password protected")
+ self.log_debug("Links are password protected")
return True
- def isCaptchaProtected(self):
+ def is_captcha_protected(self):
if self.CAPTCHA_TOKEN in self.html:
- self.logDebug("Links are captcha protected")
+ self.log_debug("Links are captcha protected")
return True
return False
- def unlockPasswordProtection(self):
- password = self.getPassword()
+ def unlock_password_protection(self):
+ password = self.get_password()
- self.logDebug("Submitting password [%s] for protected links" % password)
+ self.log_debug("Submitting password [%s] for protected links" % password)
if password:
passwd_url = self.PASSWORD_SUBMIT_URL + "?id=%s" % self.fileid
passwd_data = {'id': self.fileid, 'password': password, 'pw': 'submit'}
- self.html = self.load(passwd_url, post=passwd_data, decode=True)
+ self.html = self.load(passwd_url, post=passwd_data)
- def unlockCaptchaProtection(self):
- self.logDebug("Request user positional captcha resolving")
+ def unlock_captcha_protection(self):
+ self.log_debug("Request user positional captcha resolving")
captcha_img_url = self.CAPTCHA_IMG_URL + "?id=%s" % self.fileid
- coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional')
- self.logDebug("Captcha resolved, coords [%s]" % str(coords))
+ coords = self.captcha.decrypt(captcha_img_url, input_type="png", output_type='positional', ocr="CircleCaptcha")
+ self.log_debug("Captcha resolved, coords [%s]" % str(coords))
captcha_post_url = self.CAPTCHA_SUBMIT_URL + "?id=%s" % self.fileid
captcha_post_data = {'button.x': coords[0], 'button.y': coords[1], 'captcha': 'submit'}
- self.html = self.load(captcha_post_url, post=captcha_post_data, decode=True)
+ self.html = self.load(captcha_post_url, post=captcha_post_data)
- def getPackageInfo(self):
+ def get_package_info(self):
name = folder = None
- # Try to get info from web
+ #: Try to get info from web
m = re.search(self.FILE_TITLE_REGEX, self.html)
if m:
title = m.group(1).strip()
if not self.FILE_NOTITLE in title:
name = folder = title
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
+ self.log_debug("Found name [%s] and folder [%s] in package info" % (name, folder))
- # Fallback to defaults
+ #: Fallback to defaults
if not name or not folder:
name = self.package.name
folder = self.package.folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
+ self.log_debug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
- # Return package info
+ #: Return package info
return name, folder
- def handleErrors(self):
+ def handle_errors(self):
if self.PASSWORD_ERROR_ROKEN in self.html:
msg = "Incorrect password, please set right password on 'Edit package' form and retry"
- self.logDebug(msg)
+ self.log_debug(msg)
self.fail(_(msg))
if self.captcha:
if self.CAPTCHA_ERROR_ROKEN in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry()
else:
- self.correctCaptcha()
+ self.captcha.correct()
- def handleLinkSource(self, source):
- if source == 'cnl2':
- return self.handleCNL2Links()
- elif source == 'dlc':
- return self.handleDLCLinks()
- elif source == 'web':
- return self.handleWEBLinks()
+ def handle_link_source(self, source):
+ if source == "cnl2":
+ return self.handle_CNL2Links()
+ elif source == "dlc":
+ return self.handle_DLC_links()
+ elif source == "web":
+ return self.handle_WEB_links()
else:
self.error(_('Unknown source type "%s"') % source)
- def handleCNL2Links(self):
- self.logDebug("Search for CNL2 links")
+ def handle_CNL2Links(self):
+ self.log_debug("Search for CNL2 links")
package_links = []
m = re.search(self.CNL2_FORM_REGEX, self.html, re.S)
if m:
cnl2_form = m.group(1)
try:
- (vcrypted, vjk) = self._getCipherParams(cnl2_form)
+ (vcrypted, vjk) = self._get_cipher_params(cnl2_form)
for (crypted, jk) in zip(vcrypted, vjk):
- package_links.extend(self._getLinks(crypted, jk))
+ package_links.extend(self._get_links(crypted, jk))
except Exception:
- self.logDebug("Unable to decrypt CNL2 links")
+ self.log_debug("Unable to decrypt CNL2 links")
return package_links
- def handleDLCLinks(self):
- self.logDebug("Search for DLC links")
+ def handle_DLC_links(self):
+ self.log_debug("Search for DLC links")
package_links = []
m = re.search(self.DLC_LINK_REGEX, self.html)
if m:
container_url = self.DLC_DOWNLOAD_URL + "?id=%s&dlc=1" % self.fileid
- self.logDebug("Downloading DLC container link [%s]" % container_url)
+ self.log_debug("Downloading DLC container link [%s]" % container_url)
try:
dlc = self.load(container_url)
dlc_filename = self.fileid + ".dlc"
- dlc_filepath = save_join(self.config['general']['download_folder'], dlc_filename)
+ dlc_filepath = fs_join(self.pyload.config.get("general", "download_folder"), dlc_filename)
with open(dlc_filepath, "wb") as f:
f.write(dlc)
package_links.append(dlc_filepath)
@@ -230,64 +231,63 @@ class RelinkUs(Crypter):
return package_links
- def handleWEBLinks(self):
- self.logDebug("Search for WEB links")
+ def handle_WEB_links(self):
+ self.log_debug("Search for WEB links")
package_links = []
params = re.findall(self.WEB_FORWARD_REGEX, self.html)
- self.logDebug("Decrypting %d Web links" % len(params))
+ self.log_debug("Decrypting %d Web links" % len(params))
for index, param in enumerate(params):
try:
url = self.WEB_FORWARD_URL + "?%s" % param
- self.logDebug("Decrypting Web link %d, %s" % (index + 1, url))
+ self.log_debug("Decrypting Web link %d, %s" % (index + 1, url))
- res = self.load(url, decode=True)
+ res = self.load(url)
link = re.search(self.WEB_LINK_REGEX, res).group(1)
package_links.append(link)
except Exception, detail:
- self.logDebug("Error decrypting Web link %s, %s" % (index, detail))
+ self.log_debug("Error decrypting Web link %s, %s" % (index, detail))
- self.setWait(4)
- self.wait()
+ self.wait(4)
return package_links
- def _getCipherParams(self, cnl2_form):
- # Get jk
+ def _get_cipher_params(self, cnl2_form):
+ #: Get jk
jk_re = self.CNL2_FORMINPUT_REGEX % self.CNL2_JK_KEY
vjk = re.findall(jk_re, cnl2_form, re.I)
- # Get crypted
+ #: Get crypted
crypted_re = self.CNL2_FORMINPUT_REGEX % RelinkUs.CNL2_CRYPTED_KEY
vcrypted = re.findall(crypted_re, cnl2_form, re.I)
- # Log and return
- self.logDebug("Detected %d crypted blocks" % len(vcrypted))
+ #: Log and return
+ self.log_debug("Detected %d crypted blocks" % len(vcrypted))
return vcrypted, vjk
- def _getLinks(self, crypted, jk):
- # Get key
+ def _get_links(self, crypted, jk):
+ #: Get key
jreturn = self.js.eval("%s f()" % jk)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
+ self.log_debug("JsEngine returns value [%s]" % jreturn)
key = binascii.unhexlify(jreturn)
- # Decrypt
+ #: Decrypt
Key = key
IV = key
obj = AES.new(Key, AES.MODE_CBC, IV)
text = obj.decrypt(crypted.decode('base64'))
- # Extract links
+ #: Extract links
text = text.replace("\x00", "").replace("\r", "")
links = filter(bool, text.split('\n'))
- # Log and return
- self.logDebug("Package has %d links" % len(links))
+ #: Log and return
+ self.log_debug("Package has %d links" % len(links))
return links
diff --git a/module/plugins/crypter/SafelinkingNet.py b/module/plugins/crypter/SafelinkingNet.py
index 5d822af11..e2b8471ab 100644
--- a/module/plugins/crypter/SafelinkingNet.py
+++ b/module/plugins/crypter/SafelinkingNet.py
@@ -2,17 +2,18 @@
import re
-from BeautifulSoup import BeautifulSoup
+import BeautifulSoup
from module.common.json_layer import json_loads
-from module.plugins.Crypter import Crypter
-from module.plugins.internal.SolveMedia import SolveMedia
+from module.plugins.internal.Crypter import Crypter
+from module.plugins.captcha.SolveMedia import SolveMedia
class SafelinkingNet(Crypter):
__name__ = "SafelinkingNet"
__type__ = "crypter"
- __version__ = "0.15"
+ __version__ = "0.17"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?safelinking\.net/([pd])/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -43,7 +44,7 @@ class SafelinkingNet(Crypter):
self.html = self.load(url)
if "link-password" in self.html:
- postData['link-password'] = self.getPassword()
+ postData['link-password'] = self.get_password()
if "altcaptcha" in self.html:
for _i in xrange(5):
@@ -66,7 +67,7 @@ class SafelinkingNet(Crypter):
break
pyfile.package().password = ""
- soup = BeautifulSoup(self.html)
+ soup = BeautifulSoup.BeautifulSoup(self.html)
scripts = soup.findAll("script")
for s in scripts:
if "d_links" in s.text:
diff --git a/module/plugins/crypter/SecuredIn.py b/module/plugins/crypter/SecuredIn.py
index a2eac4f13..95416585a 100644
--- a/module/plugins/crypter/SecuredIn.py
+++ b/module/plugins/crypter/SecuredIn.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class SecuredIn(DeadCrypter):
__name__ = "SecuredIn"
__type__ = "crypter"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?secured\.in/download-[\d]+-\w{8}\.html'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/SexuriaCom.py b/module/plugins/crypter/SexuriaCom.py
index 06dcf547e..7942d5e42 100644
--- a/module/plugins/crypter/SexuriaCom.py
+++ b/module/plugins/crypter/SexuriaCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class SexuriaCom(Crypter):
__name__ = "SexuriaCom"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sexuria\.com/(v1/)?(Pornos_Kostenlos_.+?_(\d+)\.html|dl_links_\d+_\d+\.html|id=\d+\&part=\d+\&link=\d+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -19,76 +20,76 @@ class SexuriaCom(Crypter):
__authors__ = [("NETHead", "NETHead.AT.gmx.DOT.net")]
- PATTERN_SUPPORTED_MAIN = re.compile(r'http://(www\.)?sexuria\.com/(v1/)?Pornos_Kostenlos_.+?_(\d+)\.html', re.I)
- PATTERN_SUPPORTED_CRYPT = re.compile(r'http://(www\.)?sexuria\.com/(v1/)?dl_links_\d+_(?P<ID>\d+)\.html', re.I)
- PATTERN_SUPPORTED_REDIRECT = re.compile(r'http://(www\.)?sexuria\.com/out\.php\?id=(?P<ID>\d+)\&part=\d+\&link=\d+', re.I)
- PATTERN_TITLE = re.compile(r'<title> - (?P<TITLE>.*) Sexuria - Kostenlose Pornos - Rapidshare XXX Porn</title>', re.I)
- PATTERN_PASSWORD = re.compile(r'<strong>Passwort: </strong></div></td>.*?bgcolor="#EFEFEF">(?P<PWD>.*?)</td>', re.I | re.S)
- PATTERN_DL_LINK_PAGE = re.compile(r'"(dl_links_\d+_\d+\.html)"', re.I)
- PATTERN_REDIRECT_LINKS = re.compile(r'value="(http://sexuria\.com/out\.php\?id=\d+\&part=\d+\&link=\d+)" readonly', re.I)
+ PATTERN_SUPPORTED_MAIN = r'http://(www\.)?sexuria\.com/(v1/)?Pornos_Kostenlos_.+?_(\d+)\.html'
+ PATTERN_SUPPORTED_CRYPT = r'http://(www\.)?sexuria\.com/(v1/)?dl_links_\d+_(?P<ID>\d+)\.html'
+ PATTERN_SUPPORTED_REDIRECT = r'http://(www\.)?sexuria\.com/out\.php\?id=(?P<ID>\d+)\&part=\d+\&link=\d+'
+ PATTERN_TITLE = r'<title> - (?P<TITLE>.*) Sexuria - Kostenlose Pornos - Rapidshare XXX Porn</title>'
+ PATTERN_PASSWORD = r'<strong>Passwort: </strong></div></td>.*?bgcolor="#EFEFEF">(?P<PWD>.*?)</td>'
+ PATTERN_DL_LINK_PAGE = r'"(dl_links_\d+_\d+\.html)"'
+ PATTERN_REDIRECT_LINKS = r'value="(http://sexuria\.com/out\.php\?id=\d+\&part=\d+\&link=\d+)" readonly'
def decrypt(self, pyfile):
- # Init
+ #: Init
self.pyfile = pyfile
self.package = pyfile.package()
- # Get package links
- package_name, self.links, folder_name, package_pwd = self.decryptLinks(self.pyfile.url)
+ #: Get package links
+ package_name, self.links, folder_name, package_pwd = self.decrypt_links(self.pyfile.url)
self.packages = [(package_name, self.links, folder_name)]
- def decryptLinks(self, url):
+ def decrypt_links(self, url):
linklist = []
- name = self.package.name
- folder = self.package.folder
+ name = self.package.name
+ folder = self.package.folder
password = None
- if re.match(self.PATTERN_SUPPORTED_MAIN, url):
- # Processing main page
+ if re.match(self.PATTERN_SUPPORTED_MAIN, url, re.I):
+ #: Processing main page
html = self.load(url)
- links = re.findall(self.PATTERN_DL_LINK_PAGE, html)
+ links = re.findall(self.PATTERN_DL_LINK_PAGE, html, re.I)
for link in links:
linklist.append("http://sexuria.com/v1/" + link)
- elif re.match(self.PATTERN_SUPPORTED_REDIRECT, url):
- # Processing direct redirect link (out.php), redirecting to main page
- id = re.search(self.PATTERN_SUPPORTED_REDIRECT, url).group('ID')
+ elif re.match(self.PATTERN_SUPPORTED_REDIRECT, url, re.I):
+ #: Processing direct redirect link (out.php), redirecting to main page
+ id = re.search(self.PATTERN_SUPPORTED_REDIRECT, url, re.I).group('ID')
if id:
linklist.append("http://sexuria.com/v1/Pornos_Kostenlos_liebe_%s.html" % id)
- elif re.match(self.PATTERN_SUPPORTED_CRYPT, url):
- # Extract info from main file
- id = re.search(self.PATTERN_SUPPORTED_CRYPT, url).group('ID')
- html = self.load("http://sexuria.com/v1/Pornos_Kostenlos_info_%s.html" % id, decode=True)
+ elif re.match(self.PATTERN_SUPPORTED_CRYPT, url, re.I):
+ #: Extract info from main file
+ id = re.search(self.PATTERN_SUPPORTED_CRYPT, url, re.I).group('ID')
+ html = self.load("http://sexuria.com/v1/Pornos_Kostenlos_info_%s.html" % id)
- title = re.search(self.PATTERN_TITLE, html).group('TITLE').strip()
+ title = re.search(self.PATTERN_TITLE, html, re.I).group('TITLE').strip()
if title:
name = folder = title
- self.logDebug("Package info found, name [%s] and folder [%s]" % (name, folder))
+ self.log_debug("Package info found, name [%s] and folder [%s]" % (name, folder))
- pwd = re.search(self.PATTERN_PASSWORD, html).group('PWD')
- if pwd:
+ pwd = re.search(self.PATTERN_PASSWORD, html, re.I | re.S).group('PWD')
+ if pwd and pwd not in ("Kein Passwort", "-"):
password = pwd.strip()
- self.logDebug("Password info [%s] found" % password)
+ self.log_debug("Password info [%s] found" % password)
- # Process link (dl_link)
+ #: Process link (dl_link)
html = self.load(url)
- links = re.findall(self.PATTERN_REDIRECT_LINKS, html)
+ links = re.findall(self.PATTERN_REDIRECT_LINKS, html, re.I)
if len(links) == 0:
- self.LogError("Broken for link %s" % link)
+ self.log_error(_("Broken for link: %s") % link)
else:
for link in links:
link = link.replace("http://sexuria.com/", "http://www.sexuria.com/")
finallink = self.load(link, just_header=True)['location']
if not finallink or "sexuria.com/" in finallink:
- self.LogError("Broken for link %s" % link)
+ self.log_error(_("Broken for link: %s") % link)
else:
linklist.append(finallink)
- # Debug log
- self.logDebug("%d supported links" % len(linklist))
+ #: Debug log
+ self.log_debug("%d supported links" % len(linklist))
for i, link in enumerate(linklist):
- self.logDebug("Supported link %d, %s" % (i + 1, link))
+ self.log_debug("Supported link %d, %s" % (i + 1, link))
return name, linklist, folder, password
diff --git a/module/plugins/crypter/ShSt.py b/module/plugins/crypter/ShSt.py
new file mode 100644
index 000000000..754bc542c
--- /dev/null
+++ b/module/plugins/crypter/ShSt.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.Crypter import Crypter
+
+import pycurl
+import re
+
+
+class ShSt(Crypter):
+ __name__ = "ShSt"
+ __type__ = "crypter"
+ __version__ = "0.04"
+ __status__ = "testing"
+
+ __pattern__ = r'http://sh\.st/\w+'
+
+ __description__ = """Sh.St decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Frederik Möllers", "fred-public@posteo.de")]
+
+
+ NAME_PATTERN = r'<title>(?P<N>.+?) - .+</title>'
+
+
+ def decrypt(self, pyfile):
+ #: If we use curl as a user agent, we will get a straight redirect (no waiting!)
+ self.req.http.c.setopt(pycurl.USERAGENT, "curl/7.42.1")
+ #: Fetch the target URL
+ header = self.load(self.pyfile.url, just_header = True, decode = False)
+ target_url = header['location']
+ self.urls.append(target_url)
diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py
index f17ba54d7..6fbe59b38 100644
--- a/module/plugins/crypter/ShareLinksBiz.py
+++ b/module/plugins/crypter/ShareLinksBiz.py
@@ -4,13 +4,14 @@ import binascii
import re
from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class ShareLinksBiz(Crypter):
__name__ = "ShareLinksBiz"
__type__ = "crypter"
- __version__ = "1.14"
+ __version__ = "1.16"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(share-links|s2l)\.biz/(?P<ID>_?\w+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -22,113 +23,113 @@ class ShareLinksBiz(Crypter):
def setup(self):
- self.baseUrl = None
- self.fileId = None
+ self.base_url = None
+ self.file_id = None
self.package = None
self.captcha = False
def decrypt(self, pyfile):
- # Init
- self.initFile(pyfile)
+ #: Init
+ self.init_file(pyfile)
- # Request package
- url = self.baseUrl + '/' + self.fileId
- self.html = self.load(url, decode=True)
+ #: Request package
+ url = self.base_url + '/' + self.file_id
+ self.html = self.load(url)
- # Unblock server (load all images)
- self.unblockServer()
+ #: Unblock server (load all images)
+ self.unblock_server()
- # Check for protection
- if self.isPasswordProtected():
- self.unlockPasswordProtection()
- self.handleErrors()
+ #: Check for protection
+ if self.is_password_protected():
+ self.unlock_password_protection()
+ self.handle_errors()
- if self.isCaptchaProtected():
+ if self.is_captcha_protected():
self.captcha = True
- self.unlockCaptchaProtection()
- self.handleErrors()
+ self.unlock_captcha_protection()
+ self.handle_errors()
- # Extract package links
+ #: Extract package links
package_links = []
- package_links.extend(self.handleWebLinks())
- package_links.extend(self.handleContainers())
- package_links.extend(self.handleCNL2())
+ package_links.extend(self.handle_web_links())
+ package_links.extend(self.handle_containers())
+ package_links.extend(self.handle_CNL2())
package_links = set(package_links)
- # Get package info
- package_name, package_folder = self.getPackageInfo()
+ #: Get package info
+ package_name, package_folder = self.get_package_info()
- # Pack
+ #: Pack
self.packages = [(package_name, package_links, package_folder)]
- def initFile(self, pyfile):
+ def init_file(self, pyfile):
url = pyfile.url
if 's2l.biz' in url:
url = self.load(url, just_header=True)['location']
- self.baseUrl = "http://www.%s.biz" % re.match(self.__pattern__, url).group(1)
- self.fileId = re.match(self.__pattern__, url).group('ID')
+ self.base_url = "http://www.%s.biz" % re.match(self.__pattern__, url).group(1)
+ self.file_id = re.match(self.__pattern__, url).group('ID')
self.package = pyfile.package()
- def isOnline(self):
+ def is_online(self):
if "No usable content was found" in self.html:
- self.logDebug("File not found")
+ self.log_debug("File not found")
return False
return True
- def isPasswordProtected(self):
- if re.search(r'''<form.*?id="passwordForm".*?>''', self.html):
- self.logDebug("Links are protected")
+ def is_password_protected(self):
+ if re.search(r'<form.*?id="passwordForm".*?>', self.html):
+ self.log_debug("Links are protected")
return True
return False
- def isCaptchaProtected(self):
+ def is_captcha_protected(self):
if '<map id="captchamap"' in self.html:
- self.logDebug("Links are captcha protected")
+ self.log_debug("Links are captcha protected")
return True
return False
- def unblockServer(self):
+ def unblock_server(self):
imgs = re.findall(r"(/template/images/.*?\.gif)", self.html)
for img in imgs:
- self.load(self.baseUrl + img)
+ self.load(self.base_url + img)
- def unlockPasswordProtection(self):
- password = self.getPassword()
- self.logDebug("Submitting password [%s] for protected links" % password)
- post = {"password": password, 'login': 'Submit form'}
- url = self.baseUrl + '/' + self.fileId
- self.html = self.load(url, post=post, decode=True)
+ def unlock_password_protection(self):
+ password = self.get_password()
+ self.log_debug("Submitting password [%s] for protected links" % password)
+ post = {'password': password, 'login': 'Submit form'}
+ url = self.base_url + '/' + self.file_id
+ self.html = self.load(url, post=post)
- def unlockCaptchaProtection(self):
- # Get captcha map
- captchaMap = self._getCaptchaMap()
- self.logDebug("Captcha map with [%d] positions" % len(captchaMap.keys()))
+ def unlock_captcha_protection(self):
+ #: Get captcha map
+ captchaMap = self._get_captcha_map()
+ self.log_debug("Captcha map with [%d] positions" % len(captchaMap.keys()))
- # Request user for captcha coords
+ #: Request user for captcha coords
m = re.search(r'<img src="/captcha.gif\?d=(.*?)&amp;PHPSESSID=(.*?)&amp;legend=1"', self.html)
- captchaUrl = self.baseUrl + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2))
- self.logDebug("Waiting user for correct position")
- coords = self.decryptCaptcha(captchaUrl, forceUser=True, imgtype="gif", result_type='positional')
- self.logDebug("Captcha resolved, coords [%s]" % str(coords))
+ captchaUrl = self.base_url + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2))
+ self.log_debug("Waiting user for correct position")
+ coords = self.captcha.decrypt(captchaUrl, input_type="gif", output_type='positional')
+ self.log_debug("Captcha resolved, coords [%s]" % str(coords))
- # Resolve captcha
- href = self._resolveCoords(coords, captchaMap)
+ #: Resolve captcha
+ href = self._resolve_coords(coords, captchaMap)
if href is None:
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry(wait_time=5)
- url = self.baseUrl + href
- self.html = self.load(url, decode=True)
+ url = self.base_url + href
+ self.html = self.load(url)
- def _getCaptchaMap(self):
+ def _get_captcha_map(self):
mapp = {}
for m in re.finditer(r'<area shape="rect" coords="(.*?)" href="(.*?)"', self.html):
rect = eval('(' + m.group(1) + ')')
@@ -137,66 +138,66 @@ class ShareLinksBiz(Crypter):
return mapp
- def _resolveCoords(self, coords, captchaMap):
+ def _resolve_coords(self, coords, captchaMap):
x, y = coords
- for rect, href in captchaMap.iteritems():
+ for rect, href in captchaMap.items():
x1, y1, x2, y2 = rect
if (x >= x1 and x <= x2) and (y >= y1 and y <= y2):
return href
- def handleErrors(self):
+ def handle_errors(self):
if "The inserted password was wrong" in self.html:
- self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry")
+ self.log_debug("Incorrect password, please set right password on 'Edit package' form and retry")
self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry"))
if self.captcha:
if "Your choice was wrong" in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry(wait_time=5)
else:
- self.correctCaptcha()
+ self.captcha.correct()
- def getPackageInfo(self):
+ def get_package_info(self):
name = folder = None
- # Extract from web package header
+ #: Extract from web package header
title_re = r'<h2><img.*?/>(.*)</h2>'
m = re.search(title_re, self.html, re.S)
if m:
title = m.group(1).strip()
if 'unnamed' not in title:
name = folder = title
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
+ self.log_debug("Found name [%s] and folder [%s] in package info" % (name, folder))
- # Fallback to defaults
+ #: Fallback to defaults
if not name or not folder:
name = self.package.name
folder = self.package.folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
+ self.log_debug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
- # Return package info
+ #: Return package info
return name, folder
- def handleWebLinks(self):
+ def handle_web_links(self):
package_links = []
- self.logDebug("Handling Web links")
+ self.log_debug("Handling Web links")
#@TODO: Gather paginated web links
pattern = r'javascript:_get\(\'(.*?)\', \d+, \'\'\)'
ids = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Web links" % len(ids))
+ self.log_debug("Decrypting %d Web links" % len(ids))
for i, ID in enumerate(ids):
try:
- self.logDebug("Decrypting Web link %d, [%s]" % (i + 1, ID))
+ self.log_debug("Decrypting Web link %d, [%s]" % (i + 1, ID))
- dwLink = self.baseUrl + "/get/lnk/" + ID
+ dwLink = self.base_url + "/get/lnk/" + ID
res = self.load(dwLink)
code = re.search(r'frm/(\d+)', res).group(1)
- fwLink = self.baseUrl + "/get/frm/" + code
+ fwLink = self.base_url + "/get/frm/" + code
res = self.load(fwLink)
jscode = re.search(r'<script language="javascript">\s*eval\((.*)\)\s*</script>', res, re.S).group(1)
@@ -205,75 +206,75 @@ class ShareLinksBiz(Crypter):
dlLink = self.js.eval(jslauncher % jscode)
- self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink)
+ self.log_debug("JsEngine returns value [%s] for redirection link" % dlLink)
package_links.append(dlLink)
except Exception, detail:
- self.logDebug("Error decrypting Web link [%s], %s" % (ID, detail))
+ self.log_debug("Error decrypting Web link [%s], %s" % (ID, detail))
return package_links
- def handleContainers(self):
+ def handle_containers(self):
package_links = []
- self.logDebug("Handling Container links")
+ self.log_debug("Handling Container links")
pattern = r'javascript:_get\(\'(.*?)\', 0, \'(rsdf|ccf|dlc)\'\)'
containersLinks = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Container links" % len(containersLinks))
+ self.log_debug("Decrypting %d Container links" % len(containersLinks))
for containerLink in containersLinks:
- link = "%s/get/%s/%s" % (self.baseUrl, containerLink[1], containerLink[0])
+ link = "%s/get/%s/%s" % (self.base_url, containerLink[1], containerLink[0])
package_links.append(link)
return package_links
- def handleCNL2(self):
+ def handle_CNL2(self):
package_links = []
- self.logDebug("Handling CNL2 links")
+ self.log_debug("Handling CNL2 links")
if '/lib/cnl2/ClicknLoad.swf' in self.html:
try:
- (crypted, jk) = self._getCipherParams()
- package_links.extend(self._getLinks(crypted, jk))
+ (crypted, jk) = self._get_cipher_params()
+ package_links.extend(self._get_links(crypted, jk))
except Exception:
self.fail(_("Unable to decrypt CNL2 links"))
return package_links
- def _getCipherParams(self):
- # Request CNL2
+ def _get_cipher_params(self):
+ #: Request CNL2
code = re.search(r'ClicknLoad.swf\?code=(.*?)"', self.html).group(1)
- url = "%s/get/cnl2/%s" % (self.baseUrl, code)
+ url = "%s/get/cnl2/%s" % (self.base_url, code)
res = self.load(url)
params = res.split(";;")
- # Get jk
+ #: Get jk
strlist = list(params[1].decode('base64'))
- jk = ''.join(strlist[::-1])
+ jk = "".join(strlist[::-1])
- # Get crypted
+ #: Get crypted
strlist = list(params[2].decode('base64'))
- crypted = ''.join(strlist[::-1])
+ crypted = "".join(strlist[::-1])
- # Log and return
+ #: Log and return
return crypted, jk
- def _getLinks(self, crypted, jk):
- # Get key
+ def _get_links(self, crypted, jk):
+ #: Get key
jreturn = self.js.eval("%s f()" % jk)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
+ self.log_debug("JsEngine returns value [%s]" % jreturn)
key = binascii.unhexlify(jreturn)
- # Decrypt
+ #: Decrypt
Key = key
IV = key
obj = AES.new(Key, AES.MODE_CBC, IV)
text = obj.decrypt(crypted.decode('base64'))
- # Extract links
+ #: Extract links
text = text.replace("\x00", "").replace("\r", "")
links = filter(bool, text.split('\n'))
- # Log and return
- self.logDebug("Block has %d links" % len(links))
+ #: Log and return
+ self.log_debug("Block has %d links" % len(links))
return links
diff --git a/module/plugins/crypter/SharingmatrixComFolder.py b/module/plugins/crypter/SharingmatrixComFolder.py
index eb1b4d8a6..bd35cfd8e 100644
--- a/module/plugins/crypter/SharingmatrixComFolder.py
+++ b/module/plugins/crypter/SharingmatrixComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class SharingmatrixComFolder(DeadCrypter):
__name__ = "SharingmatrixComFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sharingmatrix\.com/folder/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/SpeedLoadOrgFolder.py b/module/plugins/crypter/SpeedLoadOrgFolder.py
index af768ef7b..736d59720 100644
--- a/module/plugins/crypter/SpeedLoadOrgFolder.py
+++ b/module/plugins/crypter/SpeedLoadOrgFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class SpeedLoadOrgFolder(DeadCrypter):
__name__ = "SpeedLoadOrgFolder"
__type__ = "crypter"
- __version__ = "0.30"
+ __version__ = "0.31"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?speedload\.org/(\d+~f$|folder/\d+/)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/StealthTo.py b/module/plugins/crypter/StealthTo.py
index 551468980..3a175cd87 100644
--- a/module/plugins/crypter/StealthTo.py
+++ b/module/plugins/crypter/StealthTo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class StealthTo(DeadCrypter):
__name__ = "StealthTo"
__type__ = "crypter"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?stealth\.to/folder/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/TNTVillageScambioeticoOrg.py b/module/plugins/crypter/TNTVillageScambioeticoOrg.py
new file mode 100644
index 000000000..6ba1ee19b
--- /dev/null
+++ b/module/plugins/crypter/TNTVillageScambioeticoOrg.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
+
+
+class TNTVillageScambioeticoOrg(SimpleCrypter):
+ __name__ = "TNTVillageScambioeticoOrg"
+ __type__ = "crypter"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'http://(?:www\.)?forum\.tntvillage\.scambioetico\.org/index\.php\?.*showtopic=\d+'
+ __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config['general']['folder_per_package']
+ ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
+
+ __description__ = """TNTVillage.scambioetico.org decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ LINK_PATTERNS = [r'<th class="titlemedium"><a href=\'(.+?)\'', r"<a href='(\./index\.php\?act.+?)'"]
+
+
+ def get_links(self):
+ for p in self.LINK_PATTERNS:
+ self.LINK_PATTERN = p
+ links = super(TNTVillageScambioeticoOrg, self).getLinks()
+ if links:
+ return links
+
+
+getInfo = create_getInfo(TNTVillageScambioeticoOrg)
diff --git a/module/plugins/crypter/TinyurlCom.py b/module/plugins/crypter/TinyurlCom.py
index 4b5b35457..bff1efa12 100644
--- a/module/plugins/crypter/TinyurlCom.py
+++ b/module/plugins/crypter/TinyurlCom.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleDereferer import SimpleDereferer, create_getInfo
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
-class TinyurlCom(SimpleDereferer):
+class TinyurlCom(SimpleCrypter):
__name__ = "TinyurlCom"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(preview\.)?tinyurl\.com/[\w-]+'
diff --git a/module/plugins/crypter/TnyCz.py b/module/plugins/crypter/TnyCz.py
index 719c26449..f3fb19cb3 100644
--- a/module/plugins/crypter/TnyCz.py
+++ b/module/plugins/crypter/TnyCz.py
@@ -1,14 +1,15 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
-
import re
+from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
+
class TnyCz(SimpleCrypter):
__name__ = "TnyCz"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?tny\.cz/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -20,12 +21,12 @@ class TnyCz(SimpleCrypter):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- NAME_PATTERN = r'<title>(?P<N>.+) - .+</title>'
+ NAME_PATTERN = r'<title>(?P<N>.+?) - .+</title>'
- def getLinks(self):
+ def get_links(self):
m = re.search(r'<a id=\'save_paste\' href="(.+save\.php\?hash=.+)">', self.html)
- return re.findall(".+", self.load(m.group(1), decode=True)) if m else None
+ return re.findall(".+", self.load(m.group(1))) if m else None
getInfo = create_getInfo(TnyCz)
diff --git a/module/plugins/crypter/TrailerzoneInfo.py b/module/plugins/crypter/TrailerzoneInfo.py
index 6f1c90612..03ab004a3 100644
--- a/module/plugins/crypter/TrailerzoneInfo.py
+++ b/module/plugins/crypter/TrailerzoneInfo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class TrailerzoneInfo(DeadCrypter):
__name__ = "TrailerzoneInfo"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?trailerzone\.info/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/TurbobitNetFolder.py b/module/plugins/crypter/TurbobitNetFolder.py
index dcbd6a5d7..3a36f5032 100644
--- a/module/plugins/crypter/TurbobitNetFolder.py
+++ b/module/plugins/crypter/TurbobitNetFolder.py
@@ -9,7 +9,8 @@ from module.common.json_layer import json_loads
class TurbobitNetFolder(SimpleCrypter):
__name__ = "TurbobitNetFolder"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?turbobit\.net/download/folder/(?P<ID>\w+)'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -25,24 +26,22 @@ class TurbobitNetFolder(SimpleCrypter):
NAME_PATTERN = r'src=\'/js/lib/grid/icon/folder.png\'> <span>(?P<N>.+?)</span>'
- def _getLinks(self, id, page=1):
+ def _get_links(self, id, page=1):
gridFile = self.load("http://turbobit.net/downloadfolder/gridFile",
- get={"rootId": id, "rows": 200, "page": page}, decode=True)
+ get={'rootId': id, 'rows': 200, 'page': page})
grid = json_loads(gridFile)
if grid['rows']:
for i in grid['rows']:
yield i['id']
- for id in self._getLinks(id, page + 1):
+ for id in self._get_links(id, page + 1):
yield id
else:
return
- def getLinks(self):
- id = re.match(self.__pattern__, self.pyfile.url).group('ID')
- fixurl = lambda id: "http://turbobit.net/%s.html" % id
- return map(fixurl, self._getLinks(id))
+ def get_links(self):
+ return ["http://turbobit.net/%s.html" % id for id in self._get_links(self.info['pattern']['ID'])]
getInfo = create_getInfo(TurbobitNetFolder)
diff --git a/module/plugins/crypter/TusfilesNetFolder.py b/module/plugins/crypter/TusfilesNetFolder.py
index 1cc505b81..684fb1e46 100644
--- a/module/plugins/crypter/TusfilesNetFolder.py
+++ b/module/plugins/crypter/TusfilesNetFolder.py
@@ -10,7 +10,8 @@ from module.plugins.internal.XFSCrypter import XFSCrypter, create_getInfo
class TusfilesNetFolder(XFSCrypter):
__name__ = "TusfilesNetFolder"
__type__ = "crypter"
- __version__ = "0.08"
+ __version__ = "0.09"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?tusfiles\.net/go/(?P<ID>\w+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -27,11 +28,11 @@ class TusfilesNetFolder(XFSCrypter):
URL_REPLACEMENTS = [(__pattern__ + ".*", r'https://www.tusfiles.net/go/\g<ID>/')]
- def loadPage(self, page_n):
- return self.load(urlparse.urljoin(self.pyfile.url, str(page_n)), decode=True)
+ def load_page(self, page_n):
+ return self.load(urlparse.urljoin(self.pyfile.url, str(page_n)))
- def handlePages(self, pyfile):
+ def handle_pages(self, pyfile):
pages = re.search(self.PAGES_PATTERN, self.html)
if pages:
pages = int(math.ceil(int(pages.group('pages')) / 25.0))
@@ -39,8 +40,8 @@ class TusfilesNetFolder(XFSCrypter):
return
for p in xrange(2, pages + 1):
- self.html = self.loadPage(p)
- self.links += self.getLinks()
+ self.html = self.load_page(p)
+ self.links += self.get_links()
getInfo = create_getInfo(TusfilesNetFolder)
diff --git a/module/plugins/crypter/UlozToFolder.py b/module/plugins/crypter/UlozToFolder.py
index 3f2a60cf7..19569ef31 100644
--- a/module/plugins/crypter/UlozToFolder.py
+++ b/module/plugins/crypter/UlozToFolder.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import re
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class UlozToFolder(Crypter):
__name__ = "UlozToFolder"
__type__ = "crypter"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj\.cz|zachowajto\.pl)/(m|soubory)/.+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -28,7 +29,7 @@ class UlozToFolder(Crypter):
new_links = []
for i in xrange(1, 100):
- self.logInfo(_("Fetching links from page %i") % i)
+ self.log_info(_("Fetching links from page %i") % i)
m = re.search(self.FOLDER_PATTERN, html, re.S)
if m is None:
self.error(_("FOLDER_PATTERN not found"))
@@ -40,7 +41,7 @@ class UlozToFolder(Crypter):
else:
break
else:
- self.logInfo(_("Limit of 99 pages reached, aborting"))
+ self.log_info(_("Limit of 99 pages reached, aborting"))
if new_links:
self.urls = [map(lambda s: "http://ulozto.net/%s" % s, new_links)]
diff --git a/module/plugins/crypter/UploadableChFolder.py b/module/plugins/crypter/UploadableChFolder.py
index f1eb93323..767e989d5 100644
--- a/module/plugins/crypter/UploadableChFolder.py
+++ b/module/plugins/crypter/UploadableChFolder.py
@@ -6,14 +6,15 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class UploadableChFolder(SimpleCrypter):
__name__ = "UploadableChFolder"
__type__ = "crypter"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadable\.ch/list/\w+'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
("use_subfolder" , "bool", "Save package to subfolder" , True),
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
- __description__ = """ Uploadable.ch folder decrypter plugin """
+ __description__ = """Uploadable.ch folder decrypter plugin"""
__license__ = "GPLv3"
__authors__ = [("guidobelix", "guidobelix@hotmail.it"),
("Walter Purcaro", "vuolter@gmail.com")]
diff --git a/module/plugins/crypter/UploadedToFolder.py b/module/plugins/crypter/UploadedToFolder.py
index d54ed47eb..381d744fe 100644
--- a/module/plugins/crypter/UploadedToFolder.py
+++ b/module/plugins/crypter/UploadedToFolder.py
@@ -9,11 +9,11 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class UploadedToFolder(SimpleCrypter):
__name__ = "UploadedToFolder"
__type__ = "crypter"
- __version__ = "0.42"
+ __version__ = "0.44"
+ __status__ = "testing"
- __pattern__ = r'http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/(?P<ID>\w+)'
- __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
- ("use_subfolder" , "bool", "Save package to subfolder" , True),
+ __pattern__ = r'https?://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/\w+'
+ __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
__description__ = """UploadedTo decrypter plugin"""
@@ -21,17 +21,11 @@ class UploadedToFolder(SimpleCrypter):
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- PLAIN_PATTERN = r'<small class="date"><a href="([\w/]+)" onclick='
- NAME_PATTERN = r'<title>(?P<N>.+?)<'
+ NAME_PATTERN = r'<title>(?P<N>.+?)<'
+ OFFLINE_PATTERN = r'>Page not found'
+ TEMP_OFFLINE_PATTERN = r'<title>uploaded\.net - Maintenance'
-
- def getLinks(self):
- m = re.search(self.PLAIN_PATTERN, self.html)
- if m is None:
- self.error(_("PLAIN_PATTERN not found"))
-
- plain_link = urlparse.urljoin("http://uploaded.net/", m.group(1))
- return self.load(plain_link).split('\n')[:-1]
+ LINK_PATTERN = r'<h2><a href="(.+?)"'
getInfo = create_getInfo(UploadedToFolder)
diff --git a/module/plugins/crypter/WiiReloadedOrg.py b/module/plugins/crypter/WiiReloadedOrg.py
index eddc0e5d1..7679836d2 100644
--- a/module/plugins/crypter/WiiReloadedOrg.py
+++ b/module/plugins/crypter/WiiReloadedOrg.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class WiiReloadedOrg(DeadCrypter):
__name__ = "WiiReloadedOrg"
__type__ = "crypter"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?wii-reloaded\.org/protect/get\.php\?i=.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/WuploadComFolder.py b/module/plugins/crypter/WuploadComFolder.py
index dece467a2..da1fa9bac 100644
--- a/module/plugins/crypter/WuploadComFolder.py
+++ b/module/plugins/crypter/WuploadComFolder.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo
class WuploadComFolder(DeadCrypter):
__name__ = "WuploadComFolder"
__type__ = "crypter"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?wupload\.com/folder/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/crypter/XFileSharingProFolder.py b/module/plugins/crypter/XFileSharingProFolder.py
index 2e1a2f022..584cc7668 100644
--- a/module/plugins/crypter/XFileSharingProFolder.py
+++ b/module/plugins/crypter/XFileSharingProFolder.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSCrypter import XFSCrypter, create_getInfo
class XFileSharingProFolder(XFSCrypter):
__name__ = "XFileSharingProFolder"
__type__ = "crypter"
- __version__ = "0.06"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:user|folder)s?/\w+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
@@ -19,34 +20,56 @@ class XFileSharingProFolder(XFSCrypter):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- def _log(self, type, args):
- msg = " | ".join(str(a).strip() for a in args if a)
- logger = getattr(self.log, type)
- logger("%s: %s: %s" % (self.__name__, self.HOSTER_NAME, msg or _("%s MARK" % type.upper())))
+ def _log(self, level, plugintype, pluginname, messages):
+ return super(XFileSharingProFolder, self)._log(level,
+ plugintype,
+ "%s: %s" % (pluginname, self.HOSTER_NAME),
+ messages)
def init(self):
super(XFileSharingProFolder, self).init()
- self.__pattern__ = self.core.pluginManager.crypterPlugins[self.__name__]['pattern']
+ self.__pattern__ = self.pyload.pluginManager.crypterPlugins[self.__name__]['pattern']
self.HOSTER_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group("DOMAIN").lower()
- self.HOSTER_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+)', self.HOSTER_DOMAIN) if part != '.')
+ self.HOSTER_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+|\-)', self.HOSTER_DOMAIN) if part != '.')
- account = self.core.accountManager.getAccountPlugin(self.HOSTER_NAME)
- if account and account.canUse():
- self.account = account
-
- elif self.account:
- self.account.HOSTER_DOMAIN = self.HOSTER_DOMAIN
+ def _setup(self):
+ account_name = self.__name__ if self.account.HOSTER_DOMAIN is None else self.HOSTER_NAME
+ self.chunk_limit = 1
+ self.multiDL = True
+ if self.account:
+ self.req = self.pyload.requestFactory.getRequest(accountname, self.user)
+ self.premium = self.account.is_premium(self.user)
+ self.resume_download = self.premium
else:
- return
+ self.req = self.pyload.requestFactory.getRequest(account_name)
+ self.premium = False
+ self.resume_download = False
+
+
+ def load_account(self):
+ if self.req:
+ self.req.close()
+
+ if not self.account:
+ self.account = self.pyload.accountManager.getAccountPlugin(self.HOSTER_NAME)
+
+ if not self.account:
+ self.account = self.pyload.accountManager.getAccountPlugin(self.__name__)
+
+ if self.account:
+ if not self.account.HOSTER_DOMAIN:
+ self.account.HOSTER_DOMAIN = self.HOSTER_DOMAIN
+
+ if not self.user:
+ self.user = self.account.select()[0]
- self.user, data = self.account.selectAccount()
- self.req = self.account.getAccountRequest(self.user)
- self.premium = self.account.isPremium(self.user)
+ if not self.user or not self.account.is_logged(self.user, True):
+ self.account = False
getInfo = create_getInfo(XFileSharingProFolder)
diff --git a/module/plugins/crypter/XupPl.py b/module/plugins/crypter/XupPl.py
index 5ab6750c4..ac918a6de 100644
--- a/module/plugins/crypter/XupPl.py
+++ b/module/plugins/crypter/XupPl.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.Crypter import Crypter
+from module.plugins.internal.Crypter import Crypter
class XupPl(Crypter):
__name__ = "XupPl"
__type__ = "crypter"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'https?://(?:[^/]*\.)?xup\.pl/.+'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
diff --git a/module/plugins/crypter/YoutubeComFolder.py b/module/plugins/crypter/YoutubeComFolder.py
index a2b02b2f1..ea09c63f9 100644
--- a/module/plugins/crypter/YoutubeComFolder.py
+++ b/module/plugins/crypter/YoutubeComFolder.py
@@ -4,14 +4,15 @@ import re
import urlparse
from module.common.json_layer import json_loads
-from module.plugins.Crypter import Crypter
-from module.utils import save_join
+from module.plugins.internal.Crypter import Crypter
+from module.utils import save_join as fs_join
class YoutubeComFolder(Crypter):
__name__ = "YoutubeComFolder"
__type__ = "crypter"
- __version__ = "1.01"
+ __version__ = "1.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.|m\.)?youtube\.com/(?P<TYPE>user|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P<ID>[\w-]+)'
__config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True ),
@@ -29,36 +30,36 @@ class YoutubeComFolder(Crypter):
def api_response(self, ref, req):
- req.update({"key": self.API_KEY})
+ req.update({'key': self.API_KEY})
url = urlparse.urljoin("https://www.googleapis.com/youtube/v3/", ref)
html = self.load(url, get=req)
return json_loads(html)
- def getChannel(self, user):
- channels = self.api_response("channels", {"part": "id,snippet,contentDetails", "forUsername": user, "maxResults": "50"})
+ def get_channel(self, user):
+ channels = self.api_response("channels", {'part': "id,snippet,contentDetails", 'forUsername': user, 'maxResults': "50"})
if channels['items']:
channel = channels['items'][0]
- return {"id": channel['id'],
- "title": channel['snippet']['title'],
- "relatedPlaylists": channel['contentDetails']['relatedPlaylists'],
- "user": user} # One lone channel for user?
+ return {'id': channel['id'],
+ 'title': channel['snippet']['title'],
+ 'relatedPlaylists': channel['contentDetails']['relatedPlaylists'],
+ 'user': user} #: One lone channel for user?
- def getPlaylist(self, p_id):
- playlists = self.api_response("playlists", {"part": "snippet", "id": p_id})
+ def get_playlist(self, p_id):
+ playlists = self.api_response("playlists", {'part': "snippet", 'id': p_id})
if playlists['items']:
playlist = playlists['items'][0]
- return {"id": p_id,
- "title": playlist['snippet']['title'],
- "channelId": playlist['snippet']['channelId'],
- "channelTitle": playlist['snippet']['channelTitle']}
+ return {'id': p_id,
+ 'title': playlist['snippet']['title'],
+ 'channelId': playlist['snippet']['channelId'],
+ 'channelTitle': playlist['snippet']['channelTitle']}
- def _getPlaylists(self, id, token=None):
- req = {"part": "id", "maxResults": "50", "channelId": id}
+ def _get_playlists(self, id, token=None):
+ req = {'part': "id", 'maxResults': "50", 'channelId': id}
if token:
- req.update({"pageToken": token})
+ req.update({'pageToken': token})
playlists = self.api_response("playlists", req)
@@ -66,18 +67,18 @@ class YoutubeComFolder(Crypter):
yield playlist['id']
if "nextPageToken" in playlists:
- for item in self._getPlaylists(id, playlists['nextPageToken']):
+ for item in self._get_playlists(id, playlists['nextPageToken']):
yield item
- def getPlaylists(self, ch_id):
- return map(self.getPlaylist, self._getPlaylists(ch_id))
+ def get_playlists(self, ch_id):
+ return map(self.get_playlist, self._get_playlists(ch_id))
- def _getVideosId(self, id, token=None):
- req = {"part": "contentDetails", "maxResults": "50", "playlistId": id}
+ def _get_videos_id(self, id, token=None):
+ req = {'part': "contentDetails", 'maxResults': "50", 'playlistId': id}
if token:
- req.update({"pageToken": token})
+ req.update({'pageToken': token})
playlist = self.api_response("playlistItems", req)
@@ -85,12 +86,12 @@ class YoutubeComFolder(Crypter):
yield item['contentDetails']['videoId']
if "nextPageToken" in playlist:
- for item in self._getVideosId(id, playlist['nextPageToken']):
+ for item in self._get_videos_id(id, playlist['nextPageToken']):
yield item
- def getVideosId(self, p_id):
- return list(self._getVideosId(p_id))
+ def get_videos_id(self, p_id):
+ return list(self._get_videos_id(p_id))
def decrypt(self, pyfile):
@@ -99,29 +100,29 @@ class YoutubeComFolder(Crypter):
m_type = m.group('TYPE')
if m_type == "user":
- self.logDebug("Url recognized as Channel")
+ self.log_debug("Url recognized as Channel")
user = m_id
- channel = self.getChannel(user)
+ channel = self.get_channel(user)
if channel:
- playlists = self.getPlaylists(channel['id'])
- self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), channel['title']))
+ playlists = self.get_playlists(channel['id'])
+ self.log_debug("%s playlist\s found on channel \"%s\"" % (len(playlists), channel['title']))
- relatedplaylist = {p_name: self.getPlaylist(p_id) for p_name, p_id in channel['relatedPlaylists'].iteritems()}
- self.logDebug("Channel's related playlists found = %s" % relatedplaylist.keys())
+ relatedplaylist = {p_name: self.get_playlist(p_id) for p_name, p_id in channel['relatedPlaylists'].items()}
+ self.log_debug("Channel's related playlists found = %s" % relatedplaylist.keys())
relatedplaylist['uploads']['title'] = "Unplaylisted videos"
relatedplaylist['uploads']['checkDups'] = True #: checkDups flag
- for p_name, p_data in relatedplaylist.iteritems():
- if self.getConfig(p_name):
+ for p_name, p_data in relatedplaylist.items():
+ if self.get_config(p_name):
p_data['title'] += " of " + user
playlists.append(p_data)
else:
playlists = []
else:
- self.logDebug("Url recognized as Playlist")
- playlists = [self.getPlaylist(m_id)]
+ self.log_debug("Url recognized as Playlist")
+ playlists = [self.get_playlist(m_id)]
if not playlists:
self.fail(_("No playlist available"))
@@ -130,18 +131,18 @@ class YoutubeComFolder(Crypter):
urlize = lambda x: "https://www.youtube.com/watch?v=" + x
for p in playlists:
p_name = p['title']
- p_videos = self.getVideosId(p['id'])
- p_folder = save_join(self.config['general']['download_folder'], p['channelTitle'], p_name)
- self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name))
+ p_videos = self.get_videos_id(p['id'])
+ p_folder = fs_join(self.pyload.config.get("general", "download_folder"), p['channelTitle'], p_name)
+ self.log_debug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name))
if not p_videos:
continue
elif "checkDups" in p:
p_urls = [urlize(v_id) for v_id in p_videos if v_id not in addedvideos]
- self.logDebug("%s video\s available on playlist \"%s\" after duplicates cleanup" % (len(p_urls), p_name))
+ self.log_debug("%s video\s available on playlist \"%s\" after duplicates cleanup" % (len(p_urls), p_name))
else:
p_urls = map(urlize, p_videos)
- self.packages.append((p_name, p_urls, p_folder)) #: folder is NOT recognized by pyload 0.4.9!
+ self.packages.append((p_name, p_urls, p_folder)) #: Folder is NOT recognized by pyload 0.4.9!
addedvideos.extend(p_videos)
diff --git a/module/plugins/hooks/AlldebridComHook.py b/module/plugins/hooks/AlldebridComHook.py
index 092921134..402850d87 100644
--- a/module/plugins/hooks/AlldebridComHook.py
+++ b/module/plugins/hooks/AlldebridComHook.py
@@ -6,22 +6,20 @@ from module.plugins.internal.MultiHook import MultiHook
class AlldebridComHook(MultiHook):
__name__ = "AlldebridComHook"
__type__ = "hook"
- __version__ = "0.16"
+ __version__ = "0.17"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 ),
- ("ssl" , "bool" , "Use HTTPS" , True )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Alldebrid.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Andy Voigt", "spamsales@online.de")]
- def getHosters(self):
- https = "https" if self.getConfig('ssl') else "http"
- html = self.getURL(https + "://www.alldebrid.com/api.php", get={'action': "get_host"}).replace("\"", "").strip()
-
+ def get_hosters(self):
+ html = self.load("https://www.alldebrid.com/api.php",
+ get={'action': "get_host"}).replace("\"", "").strip()
return [x.strip() for x in html.split(",") if x.strip()]
diff --git a/module/plugins/hooks/AndroidPhoneNotify.py b/module/plugins/hooks/AndroidPhoneNotify.py
index a8a1cff72..f79f226e4 100644
--- a/module/plugins/hooks/AndroidPhoneNotify.py
+++ b/module/plugins/hooks/AndroidPhoneNotify.py
@@ -2,14 +2,14 @@
import time
-from module.network.RequestFactory import getURL
-from module.plugins.Hook import Hook, Expose
+from module.plugins.internal.Addon import Addon, Expose
-class AndroidPhoneNotify(Hook):
+class AndroidPhoneNotify(Addon):
__name__ = "AndroidPhoneNotify"
__type__ = "hook"
- __version__ = "0.08"
+ __version__ = "0.10"
+ __status__ = "testing"
__config__ = [("apikey" , "str" , "API key" , "" ),
("notifycaptcha" , "bool", "Notify captcha request" , True ),
@@ -27,56 +27,52 @@ class AndroidPhoneNotify(Hook):
("Walter Purcaro", "vuolter@gmail.com" )]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
- self.event_list = ["allDownloadsProcessed", "plugin_updated"]
+ def init(self):
+ self.event_list = ["plugin_updated"]
+ self.event_map = {'allDownloadsProcessed': "all_downloads_processed"}
self.last_notify = 0
self.notifications = 0
def plugin_updated(self, type_plugins):
- if not self.getConfig('notifyupdate'):
+ if not self.get_config('notifyupdate'):
return
self.notify(_("Plugins updated"), str(type_plugins))
- def coreReady(self):
- self.key = self.getConfig('apikey')
+ def activate(self):
+ self.key = self.get_config('apikey')
- def coreExiting(self):
- if not self.getConfig('notifyexit'):
+ def exit(self):
+ if not self.get_config('notifyexit'):
return
- if self.core.do_restart:
+ if self.pyload.do_restart:
self.notify(_("Restarting pyLoad"))
else:
self.notify(_("Exiting pyLoad"))
- def newCaptchaTask(self, task):
- if not self.getConfig('notifycaptcha'):
+ def captcha_task(self, task):
+ if not self.get_config('notifycaptcha'):
return
self.notify(_("Captcha"), _("New request waiting user input"))
- def packageFinished(self, pypack):
- if self.getConfig('notifypackage'):
+ def package_finished(self, pypack):
+ if self.get_config('notifypackage'):
self.notify(_("Package finished"), pypack.name)
- def allDownloadsProcessed(self):
- if not self.getConfig('notifyprocessed'):
+ def all_downloads_processed(self):
+ if not self.get_config('notifyprocessed'):
return
- if any(True for pdata in self.core.api.getQueue() if pdata.linksdone < pdata.linkstotal):
+ if any(True for pdata in self.pyload.api.getQueue() if pdata.linksdone < pdata.linkstotal):
self.notify(_("Package failed"), _("One or more packages was not completed successfully"))
else:
self.notify(_("All packages finished"))
@@ -92,21 +88,21 @@ class AndroidPhoneNotify(Hook):
if not key:
return
- if self.core.isClientConnected() and not self.getConfig('ignoreclient'):
+ if self.pyload.isClientConnected() and not self.get_config('ignoreclient'):
return
elapsed_time = time.time() - self.last_notify
- if elapsed_time < self.getConf("sendtimewait"):
+ if elapsed_time < self.get_config("sendtimewait"):
return
if elapsed_time > 60:
self.notifications = 0
- elif self.notifications >= self.getConf("sendpermin"):
+ elif self.notifications >= self.get_config("sendpermin"):
return
- getURL("http://www.notifymyandroid.com/publicapi/notify",
+ self.load("http://www.notifymyandroid.com/publicapi/notify",
get={'apikey' : key,
'application': "pyLoad",
'event' : event,
diff --git a/module/plugins/hooks/AntiStandby.py b/module/plugins/hooks/AntiStandby.py
new file mode 100644
index 000000000..48b86fa55
--- /dev/null
+++ b/module/plugins/hooks/AntiStandby.py
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import os
+import time
+import subprocess
+import sys
+
+try:
+ import caffeine
+except ImportError:
+ pass
+
+from module.plugins.internal.Addon import Addon, Expose
+from module.utils import fs_encode, save_join as fs_join
+
+
+class Kernel32(object):
+ ES_AWAYMODE_REQUIRED = 0x00000040
+ ES_CONTINUOUS = 0x80000000
+ ES_DISPLAY_REQUIRED = 0x00000002
+ ES_SYSTEM_REQUIRED = 0x00000001
+ ES_USER_PRESENT = 0x00000004
+
+
+class AntiStandby(Addon):
+ __name__ = "AntiStandby"
+ __type__ = "hook"
+ __version__ = "0.11"
+ __status__ = "testing"
+
+ __config__ = [("activated", "bool", "Activated" , True ),
+ ("hdd" , "bool", "Prevent HDD standby" , True ),
+ ("system" , "bool", "Prevent OS standby" , True ),
+ ("display" , "bool", "Prevent display standby" , False),
+ ("interval" , "int" , "HDD touching interval in seconds", 25 )]
+
+ __description__ = """Prevent OS, HDD and display standby"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ TMP_FILE = ".antistandby"
+ MIN_INTERVAL = 5
+
+
+ def init(self):
+ self.pid = None
+ self.mtime = 0
+
+
+ def activate(self):
+ hdd = self.get_config('hdd')
+ system = not self.get_config('system')
+ display = not self.get_config('display')
+
+ if hdd:
+ self.interval = max(self.get_config('interval'), self.MIN_INTERVAL)
+ self.init_periodical(threaded=True)
+
+ if os.name == "nt":
+ self.win_standby(system, display)
+
+ elif sys.platform == "darwin":
+ self.osx_standby(system, display)
+
+ else:
+ self.linux_standby(system, display)
+
+
+ def deactivate(self):
+ try:
+ os.remove(self.TMP_FILE)
+
+ except OSError:
+ pass
+
+ if os.name == "nt":
+ self.win_standby(True)
+
+ elif sys.platform == "darwin":
+ self.osx_standby(True)
+
+ else:
+ self.linux_standby(True)
+
+
+ @Expose
+ def win_standby(self, system=True, display=True):
+ import ctypes
+
+ set = ctypes.windll.kernel32.SetThreadExecutionState
+
+ if system:
+ if display:
+ set(Kernel32.ES_CONTINUOUS)
+ else:
+ set(Kernel32.ES_CONTINUOUS | Kernel32.ES_DISPLAY_REQUIRED)
+ else:
+ if display:
+ set(Kernel32.ES_CONTINUOUS | Kernel32.ES_SYSTEM_REQUIRED)
+ else:
+ set(Kernel32.ES_CONTINUOUS | Kernel32.ES_SYSTEM_REQUIRED | Kernel32.ES_DISPLAY_REQUIRED)
+
+
+ @Expose
+ def osx_standby(self, system=True, display=True):
+ try:
+ if system:
+ caffeine.off()
+ else:
+ caffeine.on(display)
+
+ except NameError:
+ self.log_warning(_("Unable to change power state"),
+ _("caffeine lib not found"))
+
+ except Exception, e:
+ self.log_warning(_("Unable to change power state"), e)
+
+
+ @Expose
+ def linux_standby(self, system=True, display=True):
+ try:
+ if system:
+ if self.pid:
+ self.pid.kill()
+
+ elif not self.pid:
+ self.pid = subprocess.Popen(["caffeine"])
+
+ except Exception, e:
+ self.log_warning(_("Unable to change system power state"), e)
+
+ try:
+ if display:
+ subprocess.call(["xset", "+dpms", "s", "default"])
+ else:
+ subprocess.call(["xset", "-dpms", "s", "off"])
+
+ except Exception, e:
+ self.log_warning(_("Unable to change display power state"), e)
+
+
+ @Expose
+ def touch(self, path):
+ with open(path, 'w'):
+ os.utime(path, None)
+
+ self.mtime = time.time()
+
+
+ @Expose
+ def max_mtime(self, path):
+ return max(0, 0,
+ *(os.path.getmtime(fs_join(root, file))
+ for root, dirs, files in os.walk(fs_encode(path), topdown=False)
+ for file in files))
+
+
+ def periodical(self):
+ if self.get_config('hdd') is False:
+ return
+
+ if (self.pyload.threadManager.pause or
+ not self.pyload.api.isTimeDownload() or
+ not self.pyload.threadManager.getActiveFiles()):
+ return
+
+ download_folder = self.pyload.config.get("general", "download_folder")
+ if (self.max_mtime(download_folder) - self.mtime) < self.interval:
+ return
+
+ self.touch(self.TMP_FILE)
diff --git a/module/plugins/hooks/AntiVirus.py b/module/plugins/hooks/AntiVirus.py
index c620f556d..b58d0b61d 100644
--- a/module/plugins/hooks/AntiVirus.py
+++ b/module/plugins/hooks/AntiVirus.py
@@ -9,14 +9,15 @@ try:
except ImportError:
pass
-from module.plugins.Hook import Hook, Expose, threaded
-from module.utils import fs_encode, save_join
+from module.plugins.internal.Addon import Addon, Expose, threaded
+from module.utils import fs_encode, save_join as fs_join
-class AntiVirus(Hook):
+class AntiVirus(Addon):
__name__ = "AntiVirus"
__type__ = "hook"
- __version__ = "0.09"
+ __version__ = "0.12"
+ __status__ = "testing"
#@TODO: add trash option (use Send2Trash lib)
__config__ = [("action" , "Antivirus default;Delete;Quarantine", "Manage infected files" , "Antivirus default"),
@@ -32,20 +33,13 @@ class AntiVirus(Hook):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
@Expose
@threaded
def scan(self, pyfile, thread):
- file = fs_encode(pyfile.plugin.lastDownload)
- filename = os.path.basename(pyfile.plugin.lastDownload)
- cmdfile = fs_encode(self.getConfig('cmdfile'))
- cmdargs = fs_encode(self.getConfig('cmdargs').strip())
+ file = fs_encode(pyfile.plugin.last_download)
+ filename = os.path.basename(pyfile.plugin.last_download)
+ cmdfile = fs_encode(self.get_config('cmdfile'))
+ cmdargs = fs_encode(self.get_config('cmdargs').strip())
if not os.path.isfile(file) or not os.path.isfile(cmdfile):
return
@@ -60,20 +54,20 @@ class AntiVirus(Hook):
out, err = map(str.strip, p.communicate())
if out:
- self.logInfo(filename, out)
+ self.log_info(filename, out)
if err:
- self.logWarning(filename, err)
- if not self.getConfig('ignore-err'):
- self.logDebug("Delete/Quarantine task is aborted")
+ self.log_warning(filename, err)
+ if not self.get_config('ignore-err'):
+ self.log_debug("Delete/Quarantine task is aborted")
return
if p.returncode:
- pyfile.error = _("infected file")
- action = self.getConfig('action')
+ pyfile.error = _("Infected file")
+ action = self.get_config('action')
try:
if action == "Delete":
- if not self.getConfig('deltotrash'):
+ if not self.get_config('deltotrash'):
os.remove(file)
else:
@@ -81,39 +75,38 @@ class AntiVirus(Hook):
send2trash.send2trash(file)
except NameError:
- self.logWarning(_("Send2Trash lib not found, moving to quarantine instead"))
+ self.log_warning(_("Send2Trash lib not found, moving to quarantine instead"))
pyfile.setCustomStatus(_("file moving"))
- shutil.move(file, self.getConfig('quardir'))
+ shutil.move(file, self.get_config('quardir'))
except Exception, e:
- self.logWarning(_("Unable to move file to trash: %s, moving to quarantine instead") % e.message)
+ self.log_warning(_("Unable to move file to trash: %s, moving to quarantine instead") % e.message)
pyfile.setCustomStatus(_("file moving"))
- shutil.move(file, self.getConfig('quardir'))
+ shutil.move(file, self.get_config('quardir'))
else:
- self.logDebug(_("Successfully moved file to trash"))
+ self.log_debug("Successfully moved file to trash")
elif action == "Quarantine":
pyfile.setCustomStatus(_("file moving"))
- shutil.move(file, self.getConfig('quardir'))
+ shutil.move(file, self.get_config('quardir'))
except (IOError, shutil.Error), e:
- self.logError(filename, action + " action failed!", e)
+ self.log_error(filename, action + " action failed!", e)
elif not out and not err:
- self.logDebug(filename, "No infected file found")
+ self.log_debug(filename, "No infected file found")
finally:
pyfile.setProgress(100)
thread.finishFile(pyfile)
- def downloadFinished(self, pyfile):
+ def download_finished(self, pyfile):
return self.scan(pyfile)
- def downloadFailed(self, pyfile):
- #: Check if pyfile is still "failed",
- # maybe might has been restarted in meantime
- if pyfile.status == 8 and self.getConfig('scanfailed'):
+ def download_failed(self, pyfile):
+ #: Check if pyfile is still "failed", maybe might has been restarted in meantime
+ if pyfile.status == 8 and self.get_config('scanfailed'):
return self.scan(pyfile)
diff --git a/module/plugins/hooks/BypassCaptcha.py b/module/plugins/hooks/BypassCaptcha.py
index 9e01edfa2..4b155a67e 100644
--- a/module/plugins/hooks/BypassCaptcha.py
+++ b/module/plugins/hooks/BypassCaptcha.py
@@ -3,8 +3,8 @@
import pycurl
from module.network.HTTPRequest import BadHeader
-from module.network.RequestFactory import getURL, getRequest
-from module.plugins.Hook import Hook, threaded
+from module.network.RequestFactory import getRequest as get_request
+from module.plugins.internal.Hook import Hook, threaded
class BypassCaptchaException(Exception):
@@ -13,7 +13,7 @@ class BypassCaptchaException(Exception):
self.err = err
- def getCode(self):
+ def get_code(self):
return self.err
@@ -28,10 +28,11 @@ class BypassCaptchaException(Exception):
class BypassCaptcha(Hook):
__name__ = "BypassCaptcha"
__type__ = "hook"
- __version__ = "0.06"
+ __version__ = "0.08"
+ __status__ = "testing"
- __config__ = [("force", "bool", "Force BC even if client is connected", False),
- ("passkey", "password", "Passkey", "")]
+ __config__ = [("passkey" , "password", "Access key" , "" ),
+ ("check_client", "bool" , "Don't use if client is connected", True)]
__description__ = """Send captchas to BypassCaptcha.com"""
__license__ = "GPLv3"
@@ -40,8 +41,6 @@ class BypassCaptcha(Hook):
("zoidberg" , "zoidberg@mujmail.cz" )]
- interval = 0 #@TODO: Remove in 0.4.10
-
PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32"
SUBMIT_URL = "http://bypasscaptcha.com/upload.php"
@@ -49,30 +48,26 @@ class BypassCaptcha(Hook):
GETCREDITS_URL = "http://bypasscaptcha.com/ex_left.php"
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
- def getCredits(self):
- res = getURL(self.GETCREDITS_URL, post={"key": self.getConfig('passkey')})
+ def get_credits(self):
+ res = self.load(self.GETCREDITS_URL, post={'key': self.get_config('passkey')})
data = dict(x.split(' ', 1) for x in res.splitlines())
return int(data['Left'])
def submit(self, captcha, captchaType="file", match=None):
- req = getRequest()
+ req = get_request()
- #raise timeout threshold
+ #: Raise timeout threshold
req.c.setopt(pycurl.LOW_SPEED_TIME, 80)
try:
- res = req.load(self.SUBMIT_URL,
- post={'vendor_key': self.PYLOAD_KEY,
- 'key': self.getConfig('passkey'),
- 'gen_task_id': "1",
- 'file': (pycurl.FORM_FILE, captcha)},
- multipart=True)
+ res = self.load(self.SUBMIT_URL,
+ post={'vendor_key': self.PYLOAD_KEY,
+ 'key': self.get_config('passkey'),
+ 'gen_task_id': "1",
+ 'file': (pycurl.FORM_FILE, captcha)},
+ req=req)
finally:
req.close()
@@ -82,59 +77,59 @@ class BypassCaptcha(Hook):
result = data['Value']
ticket = data['TaskId']
- self.logDebug("Result %s : %s" % (ticket, result))
+ self.log_debug("Result %s : %s" % (ticket, result))
return ticket, result
def respond(self, ticket, success):
try:
- res = getURL(self.RESPOND_URL, post={"task_id": ticket, "key": self.getConfig('passkey'),
- "cv": 1 if success else 0})
+ res = self.load(self.RESPOND_URL, post={'task_id': ticket, 'key': self.get_config('passkey'),
+ 'cv': 1 if success else 0})
except BadHeader, e:
- self.logError(_("Could not send response"), e)
+ self.log_error(_("Could not send response"), e)
- def newCaptchaTask(self, task):
+ def captcha_task(self, task):
if "service" in task.data:
return False
if not task.isTextual():
return False
- if not self.getConfig('passkey'):
+ if not self.get_config('passkey'):
return False
- if self.core.isClientConnected() and not self.getConfig('force'):
+ if self.pyload.isClientConnected() and self.get_config('check_client'):
return False
- if self.getCredits() > 0:
+ if self.get_credits() > 0:
task.handler.append(self)
task.data['service'] = self.__name__
task.setWaiting(100)
- self._processCaptcha(task)
+ self._process_captcha(task)
else:
- self.logInfo(_("Your %s account has not enough credits") % self.__name__)
+ self.log_info(_("Your %s account has not enough credits") % self.__name__)
- def captchaCorrect(self, task):
- if task.data['service'] == self.__name__ and "ticket" in task.data:
+ def captcha_correct(self, task):
+ if task.data['service'] is self.__name__ and "ticket" in task.data:
self.respond(task.data['ticket'], True)
- def captchaInvalid(self, task):
- if task.data['service'] == self.__name__ and "ticket" in task.data:
+ def captcha_invalid(self, task):
+ if task.data['service'] is self.__name__ and "ticket" in task.data:
self.respond(task.data['ticket'], False)
@threaded
- def _processCaptcha(self, task):
+ def _process_captcha(self, task):
c = task.captchaFile
try:
ticket, result = self.submit(c)
except BypassCaptchaException, e:
- task.error = e.getCode()
+ task.error = e.get_code()
return
task.data['ticket'] = ticket
diff --git a/module/plugins/hooks/Captcha9Kw.py b/module/plugins/hooks/Captcha9Kw.py
index 60482b8fc..2e2685978 100644
--- a/module/plugins/hooks/Captcha9Kw.py
+++ b/module/plugins/hooks/Captcha9Kw.py
@@ -8,18 +8,16 @@ import time
from base64 import b64encode
from module.network.HTTPRequest import BadHeader
-from module.network.RequestFactory import getURL
-
-from module.plugins.Hook import Hook, threaded
+from module.plugins.internal.Hook import Hook, threaded
class Captcha9Kw(Hook):
__name__ = "Captcha9Kw"
__type__ = "hook"
- __version__ = "0.28"
+ __version__ = "0.30"
+ __status__ = "testing"
- __config__ = [("ssl" , "bool" , "Use HTTPS" , True ),
- ("force" , "bool" , "Force captcha resolving even if client is connected" , True ),
+ __config__ = [("check_client" , "bool" , "Don't use if client is connected" , True ),
("confirm" , "bool" , "Confirm Captcha (cost +6 credits)" , False ),
("captchaperhour", "int" , "Captcha per hour" , "9999" ),
("captchapermin" , "int" , "Captcha per minute" , "9999" ),
@@ -36,62 +34,54 @@ class Captcha9Kw(Hook):
("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
- API_URL = "http://www.9kw.eu/index.cgi"
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- if self.getConfig('ssl'):
- self.API_URL = self.API_URL.replace("http://", "https://")
+ API_URL = "https://www.9kw.eu/index.cgi"
- def getCredits(self):
- res = getURL(self.API_URL,
- get={'apikey': self.getConfig('passkey'),
+ def get_credits(self):
+ res = self.load(self.API_URL,
+ get={'apikey': self.get_config('passkey'),
'pyload': "1",
'source': "pyload",
'action': "usercaptchaguthaben"})
if res.isdigit():
- self.logInfo(_("%s credits left") % res)
+ self.log_info(_("%s credits left") % res)
credits = self.info['credits'] = int(res)
return credits
else:
- self.logError(res)
+ self.log_error(res)
return 0
@threaded
- def _processCaptcha(self, task):
+ def _process_captcha(self, task):
try:
with open(task.captchaFile, 'rb') as f:
data = f.read()
except IOError, e:
- self.logError(e)
+ self.log_error(e)
return
- pluginname = re.search(r'_([^_]*)_\d+.\w+', task.captchaFile).group(1)
+ pluginname = re.search(r'_(.+?)_\d+.\w+', task.captchaFile).group(1)
option = {'min' : 2,
'max' : 50,
'phrase' : 0,
'numeric' : 0,
'case_sensitive': 0,
'math' : 0,
- 'prio' : min(max(self.getConfig('prio'), 0), 10),
- 'confirm' : self.getConfig('confirm'),
- 'timeout' : min(max(self.getConfig('timeout'), 300), 3999),
- 'selfsolve' : self.getConfig('selfsolve'),
- 'cph' : self.getConfig('captchaperhour'),
- 'cpm' : self.getConfig('captchapermin')}
+ 'prio' : min(max(self.get_config('prio'), 0), 10),
+ 'confirm' : self.get_config('confirm'),
+ 'timeout' : min(max(self.get_config('timeout'), 300), 3999),
+ 'selfsolve' : self.get_config('selfsolve'),
+ 'cph' : self.get_config('captchaperhour'),
+ 'cpm' : self.get_config('captchapermin')}
- for opt in str(self.getConfig('hoster_options').split('|')):
+ for opt in str(self.get_config('hoster_options').split('|')):
details = map(str.strip, opt.split(':'))
- if not details or details[0].lower() != pluginname.lower():
+ if not details or details[0].lower() is not pluginname.lower():
continue
for d in details:
@@ -106,7 +96,7 @@ class Captcha9Kw(Hook):
break
- post_data = {'apikey' : self.getConfig('passkey'),
+ post_data = {'apikey' : self.get_config('passkey'),
'prio' : option['prio'],
'confirm' : option['confirm'],
'maxtimeout' : option['timeout'],
@@ -120,32 +110,35 @@ class Captcha9Kw(Hook):
'numeric' : option['numeric'],
'math' : option['math'],
'oldsource' : pluginname,
- 'pyload' : "1",
+ 'pyload' : 1,
'source' : "pyload",
- 'base64' : "1",
+ 'base64' : 1,
'mouse' : 1 if task.isPositional() else 0,
'file-upload-01': b64encode(data),
'action' : "usercaptchaupload"}
for _i in xrange(5):
try:
- res = getURL(self.API_URL, post=post_data)
+ res = self.load(self.API_URL, post=post_data)
+
except BadHeader, e:
time.sleep(3)
+
else:
if res and res.isdigit():
break
+
else:
- self.logError(_("Bad upload: %s") % res)
+ self.log_error(_("Bad upload: %s") % res)
return
- self.logDebug(_("NewCaptchaID ticket: %s") % res, task.captchaFile)
+ self.log_debug("NewCaptchaID ticket: %s" % res, task.captchaFile)
- task.data["ticket"] = res
+ task.data['ticket'] = res
- for _i in xrange(int(self.getConfig('timeout') / 5)):
- result = getURL(self.API_URL,
- get={'apikey': self.getConfig('passkey'),
+ for _i in xrange(int(self.get_config('timeout') / 5)):
+ result = self.load(self.API_URL,
+ get={'apikey': self.get_config('passkey'),
'id' : res,
'pyload': "1",
'info' : "1",
@@ -157,36 +150,36 @@ class Captcha9Kw(Hook):
else:
break
else:
- self.logDebug("Could not send request: %s" % res)
+ self.log_debug("Could not send request: %s" % res)
result = None
- self.logInfo(_("Captcha result for ticket %s: %s") % (res, result))
+ self.log_info(_("Captcha result for ticket %s: %s") % (res, result))
task.setResult(result)
- def newCaptchaTask(self, task):
+ def captcha_task(self, task):
if not task.isTextual() and not task.isPositional():
return
- if not self.getConfig('passkey'):
+ if not self.get_config('passkey'):
return
- if self.core.isClientConnected() and not self.getConfig('force'):
+ if self.pyload.isClientConnected() and self.get_config('check_client'):
return
- credits = self.getCredits()
+ credits = self.get_credits()
if not credits:
- self.logError(_("Your captcha 9kw.eu account has not enough credits"))
+ self.log_error(_("Your captcha 9kw.eu account has not enough credits"))
return
- queue = min(self.getConfig('queue'), 999)
- timeout = min(max(self.getConfig('timeout'), 300), 3999)
- pluginname = re.search(r'_([^_]*)_\d+.\w+', task.captchaFile).group(1)
+ queue = min(self.get_config('queue'), 999)
+ timeout = min(max(self.get_config('timeout'), 300), 3999)
+ pluginname = re.search(r'_(.+?)_\d+.\w+', task.captchaFile).group(1)
for _i in xrange(5):
- servercheck = getURL("http://www.9kw.eu/grafik/servercheck.txt")
+ servercheck = self.load("http://www.9kw.eu/grafik/servercheck.txt")
if queue < re.search(r'queue=(\d+)', servercheck).group(1):
break
@@ -194,17 +187,17 @@ class Captcha9Kw(Hook):
else:
self.fail(_("Too many captchas in queue"))
- for opt in str(self.getConfig('hoster_options').split('|')):
+ for opt in str(self.get_config('hoster_options').split('|')):
details = map(str.strip, opt.split(':'))
- if not details or details[0].lower() != pluginname.lower():
+ if not details or details[0].lower() is not pluginname.lower():
continue
for d in details:
hosteroption = d.split("=")
if len(hosteroption) > 1 \
- and hosteroption[0].lower() == 'timeout' \
+ and hosteroption[0].lower() == "timeout" \
and hosteroption[1].isdigit():
timeout = int(hosteroption[1])
@@ -214,41 +207,41 @@ class Captcha9Kw(Hook):
task.setWaiting(timeout)
- self._processCaptcha(task)
+ self._process_captcha(task)
- def _captchaResponse(self, task, correct):
+ def _captcha_response(self, task, correct):
type = "correct" if correct else "refund"
if 'ticket' not in task.data:
- self.logDebug("No CaptchaID for %s request (task: %s)" % (type, task))
+ self.log_debug("No CaptchaID for %s request (task: %s)" % (type, task))
return
- passkey = self.getConfig('passkey')
+ passkey = self.get_config('passkey')
for _i in xrange(3):
- res = getURL(self.API_URL,
+ res = self.load(self.API_URL,
get={'action' : "usercaptchacorrectback",
'apikey' : passkey,
'api_key': passkey,
'correct': "1" if correct else "2",
'pyload' : "1",
'source' : "pyload",
- 'id' : task.data["ticket"]})
+ 'id' : task.data['ticket']})
- self.logDebug("Request %s: %s" % (type, res))
+ self.log_debug("Request %s: %s" % (type, res))
if res == "OK":
break
time.sleep(5)
else:
- self.logDebug("Could not send %s request: %s" % (type, res))
+ self.log_debug("Could not send %s request: %s" % (type, res))
- def captchaCorrect(self, task):
- self._captchaResponse(task, True)
+ def captcha_correct(self, task):
+ self._captcha_response(task, True)
- def captchaInvalid(self, task):
- self._captchaResponse(task, False)
+ def captcha_invalid(self, task):
+ self._captcha_response(task, False)
diff --git a/module/plugins/hooks/CaptchaBrotherhood.py b/module/plugins/hooks/CaptchaBrotherhood.py
index bda080037..0df1ab8a9 100644
--- a/module/plugins/hooks/CaptchaBrotherhood.py
+++ b/module/plugins/hooks/CaptchaBrotherhood.py
@@ -9,11 +9,12 @@ import urllib
try:
from PIL import Image
+
except ImportError:
import Image
-from module.network.RequestFactory import getURL, getRequest
-from module.plugins.Hook import Hook, threaded
+from module.network.RequestFactory import getRequest as get_request
+from module.plugins.internal.Hook import Hook, threaded
class CaptchaBrotherhoodException(Exception):
@@ -22,7 +23,7 @@ class CaptchaBrotherhoodException(Exception):
self.err = err
- def getCode(self):
+ def get_code(self):
return self.err
@@ -37,11 +38,12 @@ class CaptchaBrotherhoodException(Exception):
class CaptchaBrotherhood(Hook):
__name__ = "CaptchaBrotherhood"
__type__ = "hook"
- __version__ = "0.08"
+ __version__ = "0.10"
+ __status__ = "testing"
- __config__ = [("username", "str", "Username", ""),
- ("force", "bool", "Force CT even if client is connected", False),
- ("passkey", "password", "Password", "")]
+ __config__ = [("username" , "str" , "Username" , "" ),
+ ("password" , "password", "Password" , "" ),
+ ("check_client", "bool" , "Don't use if client is connected", True)]
__description__ = """Send captchas to CaptchaBrotherhood.com"""
__license__ = "GPLv3"
@@ -49,23 +51,17 @@ class CaptchaBrotherhood(Hook):
("zoidberg", "zoidberg@mujmail.cz")]
- interval = 0 #@TODO: Remove in 0.4.10
-
API_URL = "http://www.captchabrotherhood.com/"
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
- def getCredits(self):
- res = getURL(self.API_URL + "askCredits.aspx",
- get={"username": self.getConfig('username'), "password": self.getConfig('passkey')})
+ def get_credits(self):
+ res = self.load(self.API_URL + "askCredits.aspx",
+ get={'username': self.get_config('username'), 'password': self.get_config('password')})
if not res.startswith("OK"):
raise CaptchaBrotherhoodException(res)
else:
credits = int(res[3:])
- self.logInfo(_("%d credits left") % credits)
+ self.log_info(_("%d credits left") % credits)
self.info['credits'] = credits
return credits
@@ -74,7 +70,7 @@ class CaptchaBrotherhood(Hook):
try:
img = Image.open(captcha)
output = StringIO.StringIO()
- self.logDebug("CAPTCHA IMAGE", img, img.format, img.mode)
+ self.log_debug("CAPTCHA IMAGE", img, img.format, img.mode)
if img.format in ("GIF", "JPEG"):
img.save(output, img.format)
else:
@@ -86,11 +82,11 @@ class CaptchaBrotherhood(Hook):
except Exception, e:
raise CaptchaBrotherhoodException("Reading or converting captcha image failed: %s" % e)
- req = getRequest()
+ req = get_request()
url = "%ssendNewCaptcha.aspx?%s" % (self.API_URL,
- urllib.urlencode({'username' : self.getConfig('username'),
- 'password' : self.getConfig('passkey'),
+ urllib.urlencode({'username' : self.get_config('username'),
+ 'password' : self.get_config('password'),
'captchaSource': "pyLoad",
'timeout' : "80"}))
@@ -122,50 +118,50 @@ class CaptchaBrotherhood(Hook):
def api_response(self, api, ticket):
- res = getURL("%s%s.aspx" % (self.API_URL, api),
- get={"username": self.getConfig('username'),
- "password": self.getConfig('passkey'),
- "captchaID": ticket})
+ res = self.load("%s%s.aspx" % (self.API_URL, api),
+ get={'username': self.get_config('username'),
+ 'password': self.get_config('password'),
+ 'captchaID': ticket})
if not res.startswith("OK"):
raise CaptchaBrotherhoodException("Unknown response: %s" % res)
return res
- def newCaptchaTask(self, task):
+ def captcha_task(self, task):
if "service" in task.data:
return False
if not task.isTextual():
return False
- if not self.getConfig('username') or not self.getConfig('passkey'):
+ if not self.get_config('username') or not self.get_config('password'):
return False
- if self.core.isClientConnected() and not self.getConfig('force'):
+ if self.pyload.isClientConnected() and self.get_config('check_client'):
return False
- if self.getCredits() > 10:
+ if self.get_credits() > 10:
task.handler.append(self)
task.data['service'] = self.__name__
task.setWaiting(100)
- self._processCaptcha(task)
+ self._process_captcha(task)
else:
- self.logInfo(_("Your CaptchaBrotherhood Account has not enough credits"))
+ self.log_info(_("Your CaptchaBrotherhood Account has not enough credits"))
- def captchaInvalid(self, task):
- if task.data['service'] == self.__name__ and "ticket" in task.data:
+ def captcha_invalid(self, task):
+ if task.data['service'] is self.__name__ and "ticket" in task.data:
res = self.api_response("complainCaptcha", task.data['ticket'])
@threaded
- def _processCaptcha(self, task):
+ def _process_captcha(self, task):
c = task.captchaFile
try:
ticket, result = self.submit(c)
except CaptchaBrotherhoodException, e:
- task.error = e.getCode()
+ task.error = e.get_code()
return
task.data['ticket'] = ticket
diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py
index ab7daf701..6ecbfcda2 100644
--- a/module/plugins/hooks/Checksum.py
+++ b/module/plugins/hooks/Checksum.py
@@ -7,11 +7,11 @@ import os
import re
import zlib
-from module.plugins.Hook import Hook
-from module.utils import save_join, fs_encode
+from module.plugins.internal.Addon import Addon
+from module.utils import save_join as fs_join, fs_encode
-def computeChecksum(local_file, algorithm):
+def compute_checksum(local_file, algorithm):
if algorithm in getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")):
h = getattr(hashlib, algorithm)()
@@ -35,16 +35,17 @@ def computeChecksum(local_file, algorithm):
return None
-class Checksum(Hook):
+class Checksum(Addon):
__name__ = "Checksum"
__type__ = "hook"
- __version__ = "0.16"
+ __version__ = "0.19"
+ __status__ = "testing"
- __config__ = [("check_checksum", "bool", "Check checksum? (If False only size will be verified)", True),
- ("check_action", "fail;retry;nothing", "What to do if check fails?", "retry"),
- ("max_tries", "int", "Number of retries", 2),
- ("retry_action", "fail;nothing", "What to do if all retries fail?", "fail"),
- ("wait_time", "int", "Time to wait before each retry (seconds)", 1)]
+ __config__ = [("check_checksum", "bool" , "Check checksum? (If False only size will be verified)", True ),
+ ("check_action" , "fail;retry;nothing", "What to do if check fails?" , "retry"),
+ ("max_tries" , "int" , "Number of retries" , 2 ),
+ ("retry_action" , "fail;nothing" , "What to do if all retries fail?" , "fail" ),
+ ("wait_time" , "int" , "Time to wait before each retry (seconds)" , 1 )]
__description__ = """Verify downloaded file size and checksum"""
__license__ = "GPLv3"
@@ -53,7 +54,6 @@ class Checksum(Hook):
("stickell" , "l.stickell@yahoo.it")]
- interval = 0 #@TODO: Remove in 0.4.10
methods = {'sfv' : 'crc32',
'crc' : 'crc32',
'hash': 'md5'}
@@ -63,13 +63,12 @@ class Checksum(Hook):
'default': r'^(?P<HASH>[0-9A-Fa-f]+)\s+\*?(?P<NAME>.+)$'}
- def coreReady(self):
- if not self.getConfig('check_checksum'):
- self.logInfo(_("Checksum validation is disabled in plugin configuration"))
+ def activate(self):
+ if not self.get_config('check_checksum'):
+ self.log_info(_("Checksum validation is disabled in plugin configuration"))
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
+ def init(self):
self.algorithms = sorted(
getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True)
@@ -78,12 +77,12 @@ class Checksum(Hook):
self.formats = self.algorithms + ["sfv", "crc", "hash"]
- def downloadFinished(self, pyfile):
+ def download_finished(self, pyfile):
"""
Compute checksum for the downloaded file and compare it with the hash provided by the hoster.
pyfile.plugin.check_data should be a dictionary which can contain:
- a) if known, the exact filesize in bytes (e.g. "size": 123456789)
- b) hexadecimal hash string with algorithm name as key (e.g. "md5": "d76505d0869f9f928a17d42d66326307")
+ a) if known, the exact filesize in bytes (e.g. 'size': 123456789)
+ b) hexadecimal hash string with algorithm name as key (e.g. 'md5': "d76505d0869f9f928a17d42d66326307")
"""
if hasattr(pyfile.plugin, "check_data") and isinstance(pyfile.plugin.check_data, dict):
data = pyfile.plugin.check_data.copy()
@@ -98,31 +97,31 @@ class Checksum(Hook):
else:
return
- self.logDebug(data)
+ self.log_debug(data)
- if not pyfile.plugin.lastDownload:
- self.checkFailed(pyfile, None, "No file downloaded")
+ if not pyfile.plugin.last_download:
+ self.check_failed(pyfile, None, "No file downloaded")
- local_file = fs_encode(pyfile.plugin.lastDownload)
- #download_folder = self.config['general']['download_folder']
- #local_file = fs_encode(save_join(download_folder, pyfile.package().folder, pyfile.name))
+ local_file = fs_encode(pyfile.plugin.last_download)
+ # download_folder = self.pyload.config.get("general", "download_folder")
+ # local_file = fs_encode(fs_join(download_folder, pyfile.package().folder, pyfile.name))
if not os.path.isfile(local_file):
- self.checkFailed(pyfile, None, "File does not exist")
+ self.check_failed(pyfile, None, "File does not exist")
- # validate file size
+ #: Validate file size
if "size" in data:
api_size = int(data['size'])
file_size = os.path.getsize(local_file)
- if api_size != file_size:
- self.logWarning(_("File %s has incorrect size: %d B (%d expected)") % (pyfile.name, file_size, api_size))
- self.checkFailed(pyfile, local_file, "Incorrect file size")
+ if api_size is not file_size:
+ self.log_warning(_("File %s has incorrect size: %d B (%d expected)") % (pyfile.name, file_size, api_size))
+ self.check_failed(pyfile, local_file, "Incorrect file size")
data.pop('size', None)
- # validate checksum
- if data and self.getConfig('check_checksum'):
+ #: Validate checksum
+ if data and self.get_config('check_checksum'):
if not 'md5' in data:
for type in ("checksum", "hashsum", "hash"):
@@ -134,29 +133,29 @@ class Checksum(Hook):
if key in data:
checksum = computeChecksum(local_file, key.replace("-", "").lower())
if checksum:
- if checksum == data[key].lower():
- self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') %
+ if checksum is data[key].lower():
+ self.log_info(_('File integrity of "%s" verified by %s checksum (%s)') %
(pyfile.name, key.upper(), checksum))
break
else:
- self.logWarning(_("%s checksum for file %s does not match (%s != %s)") %
+ self.log_warning(_("%s checksum for file %s does not match (%s != %s)") %
(key.upper(), pyfile.name, checksum, data[key]))
- self.checkFailed(pyfile, local_file, "Checksums do not match")
+ self.check_failed(pyfile, local_file, "Checksums do not match")
else:
- self.logWarning(_("Unsupported hashing algorithm"), key.upper())
+ self.log_warning(_("Unsupported hashing algorithm"), key.upper())
else:
- self.logWarning(_("Unable to validate checksum for file: ") + pyfile.name)
+ self.log_warning(_("Unable to validate checksum for file: ") + pyfile.name)
- def checkFailed(self, pyfile, local_file, msg):
- check_action = self.getConfig('check_action')
+ def check_failed(self, pyfile, local_file, msg):
+ check_action = self.get_config('check_action')
if check_action == "retry":
- max_tries = self.getConfig('max_tries')
- retry_action = self.getConfig('retry_action')
+ max_tries = self.get_config('max_tries')
+ retry_action = self.get_config('retry_action')
if pyfile.plugin.retries < max_tries:
if local_file:
os.remove(local_file)
- pyfile.plugin.retry(max_tries, self.getConfig('wait_time'), msg)
+ pyfile.plugin.retry(max_tries, self.get_config('wait_time'), msg)
elif retry_action == "nothing":
return
elif check_action == "nothing":
@@ -164,18 +163,18 @@ class Checksum(Hook):
pyfile.plugin.fail(reason=msg)
- def packageFinished(self, pypack):
- download_folder = save_join(self.config['general']['download_folder'], pypack.folder, "")
+ def package_finished(self, pypack):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder, "")
- for link in pypack.getChildren().itervalues():
+ for link in pypack.getChildren().values():
file_type = os.path.splitext(link['name'])[1][1:].lower()
if file_type not in self.formats:
continue
- hash_file = fs_encode(save_join(download_folder, link['name']))
+ hash_file = fs_encode(fs_join(download_folder, link['name']))
if not os.path.isfile(hash_file):
- self.logWarning(_("File not found"), link['name'])
+ self.log_warning(_("File not found"), link['name'])
continue
with open(hash_file) as f:
@@ -183,14 +182,14 @@ class Checksum(Hook):
for m in re.finditer(self.regexps.get(file_type, self.regexps['default']), text):
data = m.groupdict()
- self.logDebug(link['name'], data)
+ self.log_debug(link['name'], data)
- local_file = fs_encode(save_join(download_folder, data['NAME']))
+ local_file = fs_encode(fs_join(download_folder, data['NAME']))
algorithm = self.methods.get(file_type, file_type)
checksum = computeChecksum(local_file, algorithm)
- if checksum == data['HASH']:
- self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') %
+ if checksum is data['HASH']:
+ self.log_info(_('File integrity of "%s" verified by %s checksum (%s)') %
(data['NAME'], algorithm, checksum))
else:
- self.logWarning(_("%s checksum for file %s does not match (%s != %s)") %
+ self.log_warning(_("%s checksum for file %s does not match (%s != %s)") %
(algorithm, data['NAME'], checksum, data['HASH']))
diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py
index a7862045e..ba03129e6 100644
--- a/module/plugins/hooks/ClickAndLoad.py
+++ b/module/plugins/hooks/ClickAndLoad.py
@@ -10,7 +10,7 @@ except ImportError:
from threading import Lock
-from module.plugins.Hook import Hook, threaded
+from module.plugins.internal.Addon import Addon, threaded
def forward(source, destination):
@@ -22,14 +22,15 @@ def forward(source, destination):
bufdata = source.recv(bufsize)
finally:
destination.shutdown(socket.SHUT_WR)
- # destination.close()
+ #: destination.close()
#@TODO: IPv6 support
-class ClickAndLoad(Hook):
+class ClickAndLoad(Addon):
__name__ = "ClickAndLoad"
__type__ = "hook"
- __version__ = "0.43"
+ __version__ = "0.45"
+ __status__ = "testing"
__config__ = [("activated", "bool", "Activated" , True),
("port" , "int" , "Port" , 9666),
@@ -41,20 +42,13 @@ class ClickAndLoad(Hook):
("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
- def coreReady(self):
- if not self.config['webinterface']['activated']:
+ def activate(self):
+ if not self.pyload.config.get("webinterface", "activated"):
return
- ip = "" if self.getConfig('extern') else "127.0.0.1"
- webport = self.config['webinterface']['port']
- cnlport = self.getConfig('port')
+ ip = "" if self.get_config('extern') else "127.0.0.1"
+ webport = self.pyload.config.get("webinterface", "port")
+ cnlport = self.get_config('port')
self.proxy(ip, webport, cnlport)
@@ -63,7 +57,7 @@ class ClickAndLoad(Hook):
def proxy(self, ip, webport, cnlport):
time.sleep(10) #@TODO: Remove in 0.4.10 (implement addon delay on startup)
- self.logInfo(_("Proxy listening on %s:%s") % (ip or "0.0.0.0", cnlport))
+ self.log_info(_("Proxy listening on %s:%s") % (ip or "0.0.0.0", cnlport))
self._server(ip, webport, cnlport)
@@ -81,22 +75,22 @@ class ClickAndLoad(Hook):
while True:
client_socket, client_addr = dock_socket.accept()
- self.logDebug("Connection from %s:%s" % client_addr)
+ self.log_debug("Connection from %s:%s" % client_addr)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- if self.config['webinterface']['https']:
+ if self.pyload.config.get("webinterface", "https"):
try:
server_socket = ssl.wrap_socket(server_socket)
except NameError:
- self.logError(_("pyLoad's webinterface is configured to use HTTPS, Please install python's ssl lib or disable HTTPS"))
- client_socket.close() #: reset the connection.
+ self.log_error(_("pyLoad's webinterface is configured to use HTTPS, Please install python's ssl lib or disable HTTPS"))
+ client_socket.close() #: Reset the connection.
continue
except Exception, e:
- self.logError(_("SSL error: %s") % e.message)
- client_socket.close() #: reset the connection.
+ self.log_error(_("SSL error: %s") % e.message)
+ client_socket.close() #: Reset the connection.
continue
server_socket.connect(("127.0.0.1", webport))
@@ -105,10 +99,10 @@ class ClickAndLoad(Hook):
self.manager.startThread(forward, server_socket, client_socket)
except socket.timeout:
- self.logDebug("Connection timed out, retrying...")
+ self.log_debug("Connection timed out, retrying...")
return self._server(ip, webport, cnlport)
except socket.error, e:
- self.logError(e)
+ self.log_error(e)
time.sleep(240)
return self._server(ip, webport, cnlport)
diff --git a/module/plugins/hooks/DeathByCaptcha.py b/module/plugins/hooks/DeathByCaptcha.py
index f9618f011..98572191e 100644
--- a/module/plugins/hooks/DeathByCaptcha.py
+++ b/module/plugins/hooks/DeathByCaptcha.py
@@ -10,8 +10,8 @@ from base64 import b64encode
from module.common.json_layer import json_loads
from module.network.HTTPRequest import BadHeader
-from module.network.RequestFactory import getRequest
-from module.plugins.Hook import Hook, threaded
+from module.network.RequestFactory import getRequest as get_request
+from module.plugins.internal.Hook import Hook, threaded
class DeathByCaptchaException(Exception):
@@ -29,11 +29,11 @@ class DeathByCaptchaException(Exception):
self.err = err
- def getCode(self):
+ def get_code(self):
return self.err
- def getDesc(self):
+ def get_desc(self):
if self.err in self.DBC_ERRORS.keys():
return self.DBC_ERRORS[self.err]
else:
@@ -51,11 +51,12 @@ class DeathByCaptchaException(Exception):
class DeathByCaptcha(Hook):
__name__ = "DeathByCaptcha"
__type__ = "hook"
- __version__ = "0.06"
+ __version__ = "0.08"
+ __status__ = "testing"
- __config__ = [("username", "str", "Username", ""),
- ("passkey", "password", "Password", ""),
- ("force", "bool", "Force DBC even if client is connected", False)]
+ __config__ = [("username" , "str" , "Username" , "" ),
+ ("password" , "password", "Password" , "" ),
+ ("check_client", "bool" , "Don't use if client is connected", True)]
__description__ = """Send captchas to DeathByCaptcha.com"""
__license__ = "GPLv3"
@@ -63,31 +64,27 @@ class DeathByCaptcha(Hook):
("zoidberg", "zoidberg@mujmail.cz")]
- interval = 0 #@TODO: Remove in 0.4.10
-
API_URL = "http://api.dbcapi.me/api/"
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
def api_response(self, api="captcha", post=False, multipart=False):
- req = getRequest()
- req.c.setopt(pycurl.HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version])
+ req = get_request()
+ req.c.setopt(pycurl.HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.pyload.version])
if post:
if not isinstance(post, dict):
post = {}
- post.update({"username": self.getConfig('username'),
- "password": self.getConfig('passkey')})
+ post.update({'username': self.get_config('username'),
+ 'password': self.get_config('password')})
res = None
try:
- json = req.load("%s%s" % (self.API_URL, api),
- post=post,
- multipart=multipart)
- self.logDebug(json)
+ json = self.load("%s%s" % (self.API_URL, api),
+ post=post,
+ multipart=multipart,
+ req=req)
+
+ self.log_debug(json)
res = json_loads(json)
if "error" in res:
@@ -96,11 +93,11 @@ class DeathByCaptcha(Hook):
raise DeathByCaptchaException(str(res))
except BadHeader, e:
- if 403 == e.code:
+ if 403 is e.code:
raise DeathByCaptchaException('not-logged-in')
- elif 413 == e.code:
+ elif 413 is e.code:
raise DeathByCaptchaException('invalid-captcha')
- elif 503 == e.code:
+ elif 503 is e.code:
raise DeathByCaptchaException('service-overload')
elif e.code in (400, 405):
raise DeathByCaptchaException('invalid-request')
@@ -113,7 +110,7 @@ class DeathByCaptcha(Hook):
return res
- def getCredits(self):
+ def get_credits(self):
res = self.api_response("user", True)
if 'is_banned' in res and res['is_banned']:
@@ -124,7 +121,7 @@ class DeathByCaptcha(Hook):
raise DeathByCaptchaException(res)
- def getStatus(self):
+ def get_status(self):
res = self.api_response("status", False)
if 'is_service_overloaded' in res and res['is_service_overloaded']:
@@ -133,7 +130,7 @@ class DeathByCaptcha(Hook):
def submit(self, captcha, captchaType="file", match=None):
#@NOTE: Workaround multipart-post bug in HTTPRequest.py
- if re.match("^\w*$", self.getConfig('passkey')):
+ if re.match("^\w*$", self.get_config('password')):
multipart = True
data = (pycurl.FORM_FILE, captcha)
else:
@@ -142,7 +139,7 @@ class DeathByCaptcha(Hook):
data = f.read()
data = "base64:" + b64encode(data)
- res = self.api_response("captcha", {"captchafile": data}, multipart)
+ res = self.api_response("captcha", {'captchafile': data}, multipart)
if "captcha" not in res:
raise DeathByCaptchaException(res)
@@ -157,33 +154,33 @@ class DeathByCaptcha(Hook):
raise DeathByCaptchaException('timed-out')
result = res['text']
- self.logDebug("Result %s : %s" % (ticket, result))
+ self.log_debug("Result %s : %s" % (ticket, result))
return ticket, result
- def newCaptchaTask(self, task):
+ def captcha_task(self, task):
if "service" in task.data:
return False
if not task.isTextual():
return False
- if not self.getConfig('username') or not self.getConfig('passkey'):
+ if not self.get_config('username') or not self.get_config('password'):
return False
- if self.core.isClientConnected() and not self.getConfig('force'):
+ if self.pyload.isClientConnected() and self.get_config('check_client'):
return False
try:
- self.getStatus()
- self.getCredits()
+ self.get_status()
+ self.get_credits()
except DeathByCaptchaException, e:
- self.logError(e.getDesc())
+ self.log_error(e.getDesc())
return False
balance, rate = self.info['balance'], self.info['rate']
- self.logInfo(_("Account balance"),
+ self.log_info(_("Account balance"),
_("US$%.3f (%d captchas left at %.2f cents each)") % (balance / 100,
balance // rate, rate))
@@ -191,29 +188,29 @@ class DeathByCaptcha(Hook):
task.handler.append(self)
task.data['service'] = self.__name__
task.setWaiting(180)
- self._processCaptcha(task)
+ self._process_captcha(task)
- def captchaInvalid(self, task):
- if task.data['service'] == self.__name__ and "ticket" in task.data:
+ def captcha_invalid(self, task):
+ if task.data['service'] is self.__name__ and "ticket" in task.data:
try:
res = self.api_response("captcha/%d/report" % task.data['ticket'], True)
except DeathByCaptchaException, e:
- self.logError(e.getDesc())
+ self.log_error(e.getDesc())
except Exception, e:
- self.logError(e)
+ self.log_error(e)
@threaded
- def _processCaptcha(self, task):
+ def _process_captcha(self, task):
c = task.captchaFile
try:
ticket, result = self.submit(c)
except DeathByCaptchaException, e:
- task.error = e.getCode()
- self.logError(e.getDesc())
+ task.error = e.get_code()
+ self.log_error(e.getDesc())
return
task.data['ticket'] = ticket
diff --git a/module/plugins/hooks/DebridItaliaComHook.py b/module/plugins/hooks/DebridItaliaComHook.py
index 36b307696..1b000c665 100644
--- a/module/plugins/hooks/DebridItaliaComHook.py
+++ b/module/plugins/hooks/DebridItaliaComHook.py
@@ -8,13 +8,13 @@ from module.plugins.internal.MultiHook import MultiHook
class DebridItaliaComHook(MultiHook):
__name__ = "DebridItaliaComHook"
__type__ = "hook"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Debriditalia.com hook plugin"""
__license__ = "GPLv3"
@@ -22,5 +22,5 @@ class DebridItaliaComHook(MultiHook):
("Walter Purcaro", "vuolter@gmail.com" )]
- def getHosters(self):
- return self.getURL("http://debriditalia.com/api.php", get={'hosts': ""}).replace('"', '').split(',')
+ def get_hosters(self):
+ return self.load("http://debriditalia.com/api.php", get={'hosts': ""}).replace('"', '').split(',')
diff --git a/module/plugins/hooks/DeleteFinished.py b/module/plugins/hooks/DeleteFinished.py
index be17c3c0f..75a282808 100644
--- a/module/plugins/hooks/DeleteFinished.py
+++ b/module/plugins/hooks/DeleteFinished.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
from module.database import style
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
-class DeleteFinished(Hook):
+class DeleteFinished(Addon):
__name__ = "DeleteFinished"
__type__ = "hook"
- __version__ = "1.12"
+ __version__ = "1.14"
+ __status__ = "testing"
__config__ = [("interval" , "int" , "Check interval in hours" , 72 ),
("deloffline", "bool", "Delete package with offline links", False)]
@@ -21,59 +22,60 @@ class DeleteFinished(Hook):
## overwritten methods ##
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- # self.event_list = ["pluginConfigChanged"]
+ def init(self):
+ # self.event_map = {'pluginConfigChanged': "plugin_config_changed"}
self.interval = self.MIN_CHECK_INTERVAL
def periodical(self):
if not self.info['sleep']:
- deloffline = self.getConfig('deloffline')
- mode = '0,1,4' if deloffline else '0,4'
+ deloffline = self.get_config('deloffline')
+ mode = "0,1,4" if deloffline else "0,4"
msg = _('delete all finished packages in queue list (%s packages with offline links)')
- self.logInfo(msg % (_('including') if deloffline else _('excluding')))
- self.deleteFinished(mode)
+ self.log_info(msg % (_('including') if deloffline else _('excluding')))
+ self.delete_finished(mode)
self.info['sleep'] = True
- self.addEvent('packageFinished', self.wakeup)
+ self.add_event('package_finished', self.wakeup)
- # def pluginConfigChanged(self, plugin, name, value):
- # if name == "interval" and value != self.interval:
+ # def plugin_config_changed(self, plugin, name, value):
+ # if name == "interval" and value is not self.interval:
# self.interval = value * 3600
- # self.initPeriodical()
+ # self.init_periodical()
- def unload(self):
- self.manager.removeEvent('packageFinished', self.wakeup)
+ def deactivate(self):
+ self.manager.removeEvent('package_finished', self.wakeup)
- def coreReady(self):
+ def activate(self):
self.info['sleep'] = True
- # interval = self.getConfig('interval')
- # self.pluginConfigChanged(self.__name__, 'interval', interval)
- self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60 * 60)
- self.addEvent('packageFinished', self.wakeup)
+ # interval = self.get_config('interval')
+ # self.plugin_config_changed(self.__name__, 'interval', interval)
+ self.interval = max(self.MIN_CHECK_INTERVAL, self.get_config('interval') * 60 * 60)
+ self.add_event('package_finished', self.wakeup)
## own methods ##
@style.queue
- def deleteFinished(self, mode):
+ def delete_finished(self, mode):
self.c.execute('DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE package=packages.id AND status NOT IN (%s))' % mode)
self.c.execute('DELETE FROM links WHERE NOT EXISTS(SELECT 1 FROM packages WHERE id=links.package)')
def wakeup(self, pypack):
- self.manager.removeEvent('packageFinished', self.wakeup)
+ self.manager.removeEvent('package_finished', self.wakeup)
self.info['sleep'] = False
## event managing ##
- def addEvent(self, event, func):
- """Adds an event listener for event name"""
+ def add_event(self, event, func):
+ """
+ Adds an event listener for event name
+ """
if event in self.manager.events:
if func in self.manager.events[event]:
- self.logDebug("Function already registered", func)
+ self.log_debug("Function already registered", func)
else:
self.manager.events[event].append(func)
else:
diff --git a/module/plugins/hooks/DownloadScheduler.py b/module/plugins/hooks/DownloadScheduler.py
index 9c74ac1d4..b2e804dce 100644
--- a/module/plugins/hooks/DownloadScheduler.py
+++ b/module/plugins/hooks/DownloadScheduler.py
@@ -3,17 +3,17 @@
import re
import time
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
-class DownloadScheduler(Hook):
+class DownloadScheduler(Addon):
__name__ = "DownloadScheduler"
__type__ = "hook"
- __version__ = "0.22"
+ __version__ = "0.24"
+ __status__ = "testing"
- __config__ = [("timetable", "str", "List time periods as hh:mm full or number(kB/s)",
- "0:00 full, 7:00 250, 10:00 0, 17:00 150"),
- ("abort", "bool", "Abort active downloads when start period with speed 0", False)]
+ __config__ = [("timetable", "str" , "List time periods as hh:mm full or number(kB/s)" , "0:00 full, 7:00 250, 10:00 0, 17:00 150"),
+ ("abort" , "bool", "Abort active downloads when start period with speed 0", False )]
__description__ = """Download Scheduler"""
__license__ = "GPLv3"
@@ -21,61 +21,53 @@ class DownloadScheduler(Hook):
("stickell", "l.stickell@yahoo.it")]
- interval = 0 #@TODO: Remove in 0.4.10
+ def activate(self):
+ self.update_schedule()
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded
-
-
- def coreReady(self):
- self.updateSchedule()
-
-
- def updateSchedule(self, schedule=None):
+ def update_schedule(self, schedule=None):
if schedule is None:
- schedule = self.getConfig('timetable')
+ schedule = self.get_config('timetable')
schedule = re.findall("(\d{1,2}):(\d{2})[\s]*(-?\d+)",
schedule.lower().replace("full", "-1").replace("none", "0"))
if not schedule:
- self.logError(_("Invalid schedule"))
+ self.log_error(_("Invalid schedule"))
return
t0 = time.localtime()
now = (t0.tm_hour, t0.tm_min, t0.tm_sec, "X")
schedule = sorted([(int(x[0]), int(x[1]), 0, int(x[2])) for x in schedule] + [now])
- self.logDebug("Schedule", schedule)
+ self.log_debug("Schedule", schedule)
for i, v in enumerate(schedule):
if v[3] == "X":
last, next = schedule[i - 1], schedule[(i + 1) % len(schedule)]
- self.logDebug("Now/Last/Next", now, last, next)
+ self.log_debug("Now/Last/Next", now, last, next)
- self.setDownloadSpeed(last[3])
+ self.set_download_speed(last[3])
next_time = (((24 + next[0] - now[0]) * 60 + next[1] - now[1]) * 60 + next[2] - now[2]) % 86400
- self.core.scheduler.removeJob(self.cb)
- self.cb = self.core.scheduler.addJob(next_time, self.updateSchedule, threaded=False)
+ self.pyload.scheduler.removeJob(self.cb)
+ self.cb = self.pyload.scheduler.addJob(next_time, self.update_schedule, threaded=False)
- def setDownloadSpeed(self, speed):
+ def set_download_speed(self, speed):
if speed == 0:
- abort = self.getConfig('abort')
- self.logInfo(_("Stopping download server. (Running downloads will %sbe aborted.)") % '' if abort else _('not '))
- self.core.api.pauseServer()
+ abort = self.get_config('abort')
+ self.log_info(_("Stopping download server. (Running downloads will %sbe aborted.)") % '' if abort else _('not '))
+ self.pyload.api.pauseServer()
if abort:
- self.core.api.stopAllDownloads()
+ self.pyload.api.stopAllDownloads()
else:
- self.core.api.unpauseServer()
+ self.pyload.api.unpauseServer()
if speed > 0:
- self.logInfo(_("Setting download speed to %d kB/s") % speed)
- self.core.api.setConfigValue("download", "limit_speed", 1)
- self.core.api.setConfigValue("download", "max_speed", speed)
+ self.log_info(_("Setting download speed to %d kB/s") % speed)
+ self.pyload.config.set("download", "limit_speed", 1)
+ self.pyload.config.set("download", "max_speed", speed)
else:
- self.logInfo(_("Setting download speed to FULL"))
- self.core.api.setConfigValue("download", "limit_speed", 0)
- self.core.api.setConfigValue("download", "max_speed", -1)
+ self.log_info(_("Setting download speed to FULL"))
+ self.pyload.config.set("download", "limit_speed", 0)
+ self.pyload.config.set("download", "max_speed", -1)
diff --git a/module/plugins/hooks/EasybytezComHook.py b/module/plugins/hooks/EasybytezComHook.py
index 43efb5048..6f53619ac 100644
--- a/module/plugins/hooks/EasybytezComHook.py
+++ b/module/plugins/hooks/EasybytezComHook.py
@@ -8,23 +8,23 @@ from module.plugins.internal.MultiHook import MultiHook
class EasybytezComHook(MultiHook):
__name__ = "EasybytezComHook"
__type__ = "hook"
- __version__ = "0.07"
+ __version__ = "0.08"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """EasyBytez.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
- def getHosters(self):
- user, data = self.account.selectAccount()
+ def get_hosters(self):
+ user, info = self.account.select()
- req = self.account.getAccountRequest(user)
- html = req.load("http://www.easybytez.com")
+ html = self.load("http://www.easybytez.com",
+ req=self.account.get_request(user))
return re.search(r'</textarea>\s*Supported sites:(.*)', html).group(1).split(',')
diff --git a/module/plugins/hooks/ExpertDecoders.py b/module/plugins/hooks/ExpertDecoders.py
index ccd48f664..630382f2d 100644
--- a/module/plugins/hooks/ExpertDecoders.py
+++ b/module/plugins/hooks/ExpertDecoders.py
@@ -8,17 +8,18 @@ import uuid
from base64 import b64encode
from module.network.HTTPRequest import BadHeader
-from module.network.RequestFactory import getURL, getRequest
-from module.plugins.Hook import Hook, threaded
+from module.network.RequestFactory import getRequest as get_request
+from module.plugins.internal.Hook import Hook, threaded
class ExpertDecoders(Hook):
__name__ = "ExpertDecoders"
__type__ = "hook"
- __version__ = "0.04"
+ __version__ = "0.06"
+ __status__ = "testing"
- __config__ = [("force", "bool", "Force CT even if client is connected", False),
- ("passkey", "password", "Access key", "")]
+ __config__ = [("passkey" , "password", "Access key" , "" ),
+ ("check_client", "bool" , "Don't use if client is connected", True)]
__description__ = """Send captchas to expertdecoders.com"""
__license__ = "GPLv3"
@@ -26,78 +27,73 @@ class ExpertDecoders(Hook):
("zoidberg", "zoidberg@mujmail.cz")]
- interval = 0 #@TODO: Remove in 0.4.10
-
API_URL = "http://www.fasttypers.org/imagepost.ashx"
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
- def getCredits(self):
- res = getURL(self.API_URL, post={"key": self.getConfig('passkey'), "action": "balance"})
+ def get_credits(self):
+ res = self.load(self.API_URL, post={'key': self.get_config('passkey'), 'action': "balance"})
if res.isdigit():
- self.logInfo(_("%s credits left") % res)
+ self.log_info(_("%s credits left") % res)
self.info['credits'] = credits = int(res)
return credits
else:
- self.logError(res)
+ self.log_error(res)
return 0
@threaded
- def _processCaptcha(self, task):
+ def _process_captcha(self, task):
task.data['ticket'] = ticket = uuid.uuid4()
result = None
with open(task.captchaFile, 'rb') as f:
data = f.read()
- req = getRequest()
- #raise timeout threshold
+ req = get_request()
+ #: Raise timeout threshold
req.c.setopt(pycurl.LOW_SPEED_TIME, 80)
try:
- result = req.load(self.API_URL,
- post={'action' : "upload",
- 'key' : self.getConfig('passkey'),
+ result = self.load(self.API_URL,
+ post={'action' : "upload",
+ 'key' : self.get_config('passkey'),
'file' : b64encode(data),
- 'gen_task_id': ticket})
+ 'gen_task_id': ticket},
+ req=req)
finally:
req.close()
- self.logDebug("Result %s : %s" % (ticket, result))
+ self.log_debug("Result %s : %s" % (ticket, result))
task.setResult(result)
- def newCaptchaTask(self, task):
+ def captcha_task(self, task):
if not task.isTextual():
return False
- if not self.getConfig('passkey'):
+ if not self.get_config('passkey'):
return False
- if self.core.isClientConnected() and not self.getConfig('force'):
+ if self.pyload.isClientConnected() and self.get_config('check_client'):
return False
- if self.getCredits() > 0:
+ if self.get_credits() > 0:
task.handler.append(self)
task.setWaiting(100)
- self._processCaptcha(task)
+ self._process_captcha(task)
else:
- self.logInfo(_("Your ExpertDecoders Account has not enough credits"))
+ self.log_info(_("Your ExpertDecoders Account has not enough credits"))
- def captchaInvalid(self, task):
+ def captcha_invalid(self, task):
if "ticket" in task.data:
try:
- res = getURL(self.API_URL,
- post={'action': "refund", 'key': self.getConfig('passkey'), 'gen_task_id': task.data['ticket']})
- self.logInfo(_("Request refund"), res)
+ res = self.load(self.API_URL,
+ post={'action': "refund", 'key': self.get_config('passkey'), 'gen_task_id': task.data['ticket']})
+ self.log_info(_("Request refund"), res)
except BadHeader, e:
- self.logError(_("Could not send refund request"), e)
+ self.log_error(_("Could not send refund request"), e)
diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py
index a0815499b..b7495136a 100644
--- a/module/plugins/hooks/ExternalScripts.py
+++ b/module/plugins/hooks/ExternalScripts.py
@@ -3,17 +3,18 @@
import os
import subprocess
-from module.plugins.Hook import Hook
-from module.utils import fs_encode, save_join
+from module.plugins.internal.Addon import Addon, Expose
+from module.utils import fs_encode, save_join as fs_join
-class ExternalScripts(Hook):
+class ExternalScripts(Addon):
__name__ = "ExternalScripts"
__type__ = "hook"
- __version__ = "0.39"
+ __version__ = "0.46"
+ __status__ = "testing"
__config__ = [("activated", "bool", "Activated" , True ),
- ("waitend" , "bool", "Wait script ending", False)]
+ ("lock" , "bool", "Wait script ending", False)]
__description__ = """Run external scripts"""
__license__ = "GPLv3"
@@ -23,18 +24,16 @@ class ExternalScripts(Hook):
("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {'oldip': None}
+ def init(self):
+ self.info['oldip'] = None
self.scripts = {}
self.event_list = ["archive_extract_failed", "archive_extracted" ,
"package_extract_failed", "package_extracted" ,
- "all_archives_extracted", "all_archives_processed",
- "allDownloadsFinished" , "allDownloadsProcessed" ,
- "packageDeleted"]
+ "all_archives_extracted", "all_archives_processed"]
+ self.event_map = {'allDownloadsFinished' : "all_downloads_finished" ,
+ 'allDownloadsProcessed': "all_downloads_processed",
+ 'packageDeleted' : "package_deleted" }
folders = ["pyload_start", "pyload_restart", "pyload_stop",
"before_reconnect", "after_reconnect",
@@ -45,174 +44,204 @@ class ExternalScripts(Hook):
"all_archives_extracted", "all_archives_processed"]
for folder in folders:
- self.scripts[folder] = []
- for dir in (pypath, ''):
- self.initPluginType(folder, os.path.join(dir, 'scripts', folder))
+ path = os.path.join("scripts", folder)
+ self.init_folder(folder, path)
- for script_type, names in self.scripts.iteritems():
- if names:
- self.logInfo(_("Installed scripts for: ") + script_type, ", ".join(map(os.path.basename, names)))
+ for folder, scripts in self.scripts.items():
+ if scripts:
+ self.log_info(_("Installed scripts in folder `%s`: %s")
+ % (folder, ", ".join(scripts)))
self.pyload_start()
- def initPluginType(self, name, dir):
- if not os.path.isdir(dir):
+ def init_folder(self, name, path):
+ self.scripts[name] = []
+
+ if not os.path.isdir(path):
try:
- os.makedirs(dir)
+ os.makedirs(path)
except OSError, e:
- self.logDebug(e)
+ self.log_debug(e)
return
- for filename in os.listdir(dir):
- file = save_join(dir, filename)
-
+ for file in os.listdir(path):
if not os.path.isfile(file):
continue
- if filename[0] in ("#", "_") or filename.endswith("~") or filename.endswith(".swp"):
+ if file[0] in ("#", "_") or file.endswith("~") or file.endswith(".swp"):
continue
if not os.access(file, os.X_OK):
- self.logWarning(_("Script not executable:") + " %s/%s" % (name, filename))
+ self.log_warning(_("Script not executable: [%s] %s") % (name, file))
self.scripts[name].append(file)
- def callScript(self, script, *args):
+ @Expose
+ def call(self, script, args=[], lock=False):
try:
- cmd_args = [fs_encode(str(x) if not isinstance(x, basestring) else x) for x in args]
- cmd = [script] + cmd_args
-
- self.logDebug("Executing: %s" % os.path.abspath(script), "Args: " + ' '.join(cmd_args))
+ script = os.path.abspath(script)
+ args = [script] + map(encode, args)
- p = subprocess.Popen(cmd, bufsize=-1) #@NOTE: output goes to pyload
- if self.getConfig('waitend'):
+ self.log_info(_("EXECUTE [%s] %s") % (os.path.dirname(script), args))
+ p = subprocess.Popen(args, bufsize=-1) #@NOTE: output goes to pyload
+ if lock:
p.communicate()
except Exception, e:
- try:
- self.logError(_("Runtime error: %s") % os.path.abspath(script), e)
- except Exception:
- self.logError(_("Runtime error: %s") % os.path.abspath(script), _("Unknown error"))
+ self.log_error(_("Runtime error: %s") % script, e or _("Unknown error"))
def pyload_start(self):
+ lock = self.get_config('lock')
for script in self.scripts['pyload_start']:
- self.callScript(script)
+ self.call(script, lock=lock)
- def coreExiting(self):
- for script in self.scripts['pyload_restart' if self.core.do_restart else 'pyload_stop']:
- self.callScript(script)
+ def exit(self):
+ lock = self.get_config('lock')
+ for script in self.scripts['pyload_restart' if self.pyload.do_restart else 'pyload_stop']:
+ self.call(script, lock=True)
- def beforeReconnecting(self, ip):
+ def before_reconnect(self, ip):
+ lock = self.get_config('lock')
for script in self.scripts['before_reconnect']:
- self.callScript(script, ip)
+ args = [ip]
+ self.call(script, args, lock)
self.info['oldip'] = ip
- def afterReconnecting(self, ip):
+ def after_reconnect(self, ip):
+ lock = self.get_config('lock')
for script in self.scripts['after_reconnect']:
- self.callScript(script, ip, self.info['oldip']) #@TODO: Use built-in oldip in 0.4.10
+ args = [ip, self.info['oldip']] #@TODO: Use built-in oldip in 0.4.10
+ self.call(script, args, lock)
- def downloadPreparing(self, pyfile):
+ def download_preparing(self, pyfile):
+ lock = self.get_config('lock')
for script in self.scripts['download_preparing']:
- self.callScript(script, pyfile.id, pyfile.name, None, pyfile.pluginname, pyfile.url)
+ args = [pyfile.id, pyfile.name, None, pyfile.pluginname, pyfile.url]
+ self.call(script, args, lock)
- def downloadFailed(self, pyfile):
- if self.config['general']['folder_per_package']:
- download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder)
+ def download_failed(self, pyfile):
+ lock = self.get_config('lock')
+
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pyfile.package().folder)
else:
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
for script in self.scripts['download_failed']:
- file = save_join(download_folder, pyfile.name)
- self.callScript(script, pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url)
+ file = fs_join(download_folder, pyfile.name)
+ args = [script, pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url]
+ self.call(script, args, lock)
+
+ def download_finished(self, pyfile):
+ lock = self.get_config('lock')
- def downloadFinished(self, pyfile):
- if self.config['general']['folder_per_package']:
- download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder)
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pyfile.package().folder)
else:
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
for script in self.scripts['download_finished']:
- file = save_join(download_folder, pyfile.name)
- self.callScript(script, pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url)
+ file = fs_join(download_folder, pyfile.name)
+ args = [pyfile.id, pyfile.name, file, pyfile.pluginname, pyfile.url]
+ self.call(script, args, lock)
def archive_extract_failed(self, pyfile, archive):
+ lock = self.get_config('lock')
for script in self.scripts['archive_extract_failed']:
- self.callScript(script, pyfile.id, pyfile.name, archive.filename, archive.out, archive.files)
+ args = [pyfile.id, pyfile.name, archive.filename, archive.out, archive.files]
+ self.call(script, args, lock)
def archive_extracted(self, pyfile, archive):
+ lock = self.get_config('lock')
for script in self.scripts['archive_extracted']:
- self.callScript(script, pyfile.id, pyfile.name, archive.filename, archive.out, archive.files)
+ args = [script, pyfile.id, pyfile.name, archive.filename, archive.out, archive.files]
+ self.call(script, args, lock)
+
+ def package_finished(self, pypack):
+ lock = self.get_config('lock')
- def packageFinished(self, pypack):
- if self.config['general']['folder_per_package']:
- download_folder = save_join(self.config['general']['download_folder'], pypack.folder)
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder)
else:
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
for script in self.scripts['package_finished']:
- self.callScript(script, pypack.id, pypack.name, download_folder, pypack.password)
+ args = [pypack.id, pypack.name, download_folder, pypack.password]
+ self.call(script, args, lock)
- def packageDeleted(self, pid):
- pack = self.core.api.getPackageInfo(pid)
+ def package_deleted(self, pid):
+ lock = self.get_config('lock')
+ pack = self.pyload.api.getPackageInfo(pid)
- if self.config['general']['folder_per_package']:
- download_folder = save_join(self.config['general']['download_folder'], pack.folder)
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pack.folder)
else:
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
for script in self.scripts['package_deleted']:
- self.callScript(script, pack.id, pack.name, download_folder, pack.password)
+ args = [pack.id, pack.name, download_folder, pack.password]
+ self.call(script, args, lock)
def package_extract_failed(self, pypack):
- if self.config['general']['folder_per_package']:
- download_folder = save_join(self.config['general']['download_folder'], pypack.folder)
+ lock = self.get_config('lock')
+
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder)
else:
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
for script in self.scripts['package_extract_failed']:
- self.callScript(script, pypack.id, pypack.name, download_folder, pypack.password)
+ args = [pypack.id, pypack.name, download_folder, pypack.password]
+ self.call(script, args, lock)
def package_extracted(self, pypack):
- if self.config['general']['folder_per_package']:
- download_folder = save_join(self.config['general']['download_folder'], pypack.folder)
+ lock = self.get_config('lock')
+
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(self.pyload.config.get("general", "download_folder"), pypack.folder)
else:
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
for script in self.scripts['package_extracted']:
- self.callScript(script, pypack.id, pypack.name, download_folder)
+ args = [pypack.id, pypack.name, download_folder]
+ self.call(script, args, lock)
- def allDownloadsFinished(self):
+ def all_downloads_finished(self):
+ lock = self.get_config('lock')
for script in self.scripts['all_downloads_finished']:
- self.callScript(script)
+ self.call(script, lock=lock)
- def allDownloadsProcessed(self):
+ def all_downloads_processed(self):
+ lock = self.get_config('lock')
for script in self.scripts['all_downloads_processed']:
- self.callScript(script)
+ self.call(script, lock=lock)
def all_archives_extracted(self):
+ lock = self.get_config('lock')
for script in self.scripts['all_archives_extracted']:
- self.callScript(script)
+ self.call(script, lock=lock)
def all_archives_processed(self):
+ lock = self.get_config('lock')
for script in self.scripts['all_archives_processed']:
- self.callScript(script)
+ self.call(script, lock=lock)
diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py
index 3e371ec2b..eab196160 100644
--- a/module/plugins/hooks/ExtractArchive.py
+++ b/module/plugins/hooks/ExtractArchive.py
@@ -23,10 +23,12 @@ if sys.version_info < (2, 7) and os.name != "nt":
raise
- # unsued timeout option for older python version
+ #: Unsued timeout option for older python version
def wait(self, timeout=0):
- """Wait for child process to terminate. Returns returncode
- attribute."""
+ """
+ Wait for child process to terminate. Returns returncode
+ attribute.
+ """
if self.returncode is None:
try:
pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
@@ -34,9 +36,9 @@ if sys.version_info < (2, 7) and os.name != "nt":
except OSError, e:
if e.errno != errno.ECHILD:
raise
- # This happens if SIGCLD is set to be ignored or waiting
- # for child processes has otherwise been disabled for our
- # process. This child is dead, we can't get the status.
+ #: This happens if SIGCLD is set to be ignored or waiting
+ #: For child processes has otherwise been disabled for our
+ #: process. This child is dead, we can't get the status.
sts = 0
self._handle_exitstatus(sts)
return self.returncode
@@ -48,15 +50,10 @@ try:
except ImportError:
pass
-from copy import copy
-if os.name != "nt":
- from grp import getgrnam
- from pwd import getpwnam
-
-from module.plugins.Hook import Hook, Expose, threaded
+from module.plugins.internal.Addon import Addon, Expose, threaded
+from module.plugins.internal.Plugin import replace_patterns
from module.plugins.internal.Extractor import ArchiveError, CRCError, PasswordError
-from module.plugins.internal.SimpleHoster import replace_patterns
-from module.utils import fs_encode, save_join, uniqify
+from module.utils import fs_encode, save_join as fs_join, uniqify
class ArchiveQueue(object):
@@ -68,7 +65,7 @@ class ArchiveQueue(object):
def get(self):
try:
- return [int(pid) for pid in self.plugin.getStorage("ExtractArchive:%s" % self.storage, "").decode('base64').split()]
+ return [int(pid) for pid in self.plugin.retrieve("ExtractArchive:%s" % self.storage, "").decode('base64').split()]
except Exception:
return []
@@ -78,11 +75,11 @@ class ArchiveQueue(object):
item = str(value)[1:-1].replace(' ', '').replace(',', ' ')
else:
item = str(value).strip()
- return self.plugin.setStorage("ExtractArchive:%s" % self.storage, item.encode('base64')[:-1])
+ return self.plugin.store("ExtractArchive:%s" % self.storage, item.encode('base64')[:-1])
def delete(self):
- return self.plugin.delStorage("ExtractArchive:%s" % self.storage)
+ return self.plugin.delete("ExtractArchive:%s" % self.storage)
def add(self, item):
@@ -101,16 +98,17 @@ class ArchiveQueue(object):
except ValueError:
pass
- if queue == []:
+ if queue is []:
return self.delete()
return self.set(queue)
-class ExtractArchive(Hook):
+class ExtractArchive(Addon):
__name__ = "ExtractArchive"
__type__ = "hook"
- __version__ = "1.44"
+ __version__ = "1.49"
+ __status__ = "testing"
__config__ = [("activated" , "bool" , "Activated" , True ),
("fullpath" , "bool" , "Extract with full paths" , True ),
@@ -119,7 +117,7 @@ class ExtractArchive(Hook):
("repair" , "bool" , "Repair broken archives (RAR required)" , False ),
("test" , "bool" , "Test archive before extracting" , False ),
("usepasswordfile", "bool" , "Use password file" , True ),
- ("passwordfile" , "file" , "Password file" , "archive_password.txt" ),
+ ("passwordfile" , "file" , "Password file" , "passwords.txt" ),
("delete" , "bool" , "Delete archive after extraction" , True ),
("deltotrash" , "bool" , "Move to trash (recycle bin) instead delete", True ),
("subfolder" , "bool" , "Create subfolder for each package" , False ),
@@ -139,53 +137,53 @@ class ExtractArchive(Hook):
NAME_REPLACEMENTS = [(r'\.part\d+\.rar$', ".part.rar")]
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- self.event_list = ["allDownloadsProcessed","packageDeleted"]
+ def init(self):
+ self.event_map = {'allDownloadsProcessed': "all_downloads_processed",
+ 'packageDeleted' : "package_deleted" }
self.queue = ArchiveQueue(self, "Queue")
self.failed = ArchiveQueue(self, "Failed")
self.interval = 60
self.extracting = False
- self.lastPackage = False
+ self.last_package = False
self.extractors = []
self.passwords = []
self.repair = False
- def coreReady(self):
+ def activate(self):
for p in ("UnRar", "SevenZip", "UnZip"):
try:
- module = self.core.pluginManager.loadModule("internal", p)
+ module = self.pyload.pluginManager.loadModule("internal", p)
klass = getattr(module, p)
- if klass.isUsable():
+ if klass.find():
self.extractors.append(klass)
if klass.REPAIR:
- self.repair = self.getConfig('repair')
+ self.repair = self.get_config('repair')
except OSError, e:
if e.errno == 2:
- self.logWarning(_("No %s installed") % p)
+ self.log_warning(_("No %s installed") % p)
else:
- self.logWarning(_("Could not activate: %s") % p, e)
- if self.core.debug:
+ self.log_warning(_("Could not activate: %s") % p, e)
+ if self.pyload.debug:
traceback.print_exc()
except Exception, e:
- self.logWarning(_("Could not activate: %s") % p, e)
- if self.core.debug:
+ self.log_warning(_("Could not activate: %s") % p, e)
+ if self.pyload.debug:
traceback.print_exc()
if self.extractors:
- self.logDebug(*["Found %s %s" % (Extractor.__name__, Extractor.VERSION) for Extractor in self.extractors])
- self.extractQueued() #: Resume unfinished extractions
+ self.log_debug(*["Found %s %s" % (Extractor.__name__, Extractor.VERSION) for Extractor in self.extractors])
+ self.extract_queued() #: Resume unfinished extractions
else:
- self.logInfo(_("No Extract plugins activated"))
+ self.log_info(_("No Extract plugins activated"))
@threaded
- def extractQueued(self, thread):
+ def extract_queued(self, thread):
if self.extracting: #@NOTE: doing the check here for safty (called by coreReady)
return
@@ -193,8 +191,8 @@ class ExtractArchive(Hook):
packages = self.queue.get()
while packages:
- if self.lastPackage: #: called from allDownloadsProcessed
- self.lastPackage = False
+ if self.last_package: #: Called from allDownloadsProcessed
+ self.last_package = False
if self.extract(packages, thread): #@NOTE: check only if all gone fine, no failed reporting for now
self.manager.dispatchEvent("all_archives_extracted")
self.manager.dispatchEvent("all_archives_processed")
@@ -202,34 +200,45 @@ class ExtractArchive(Hook):
if self.extract(packages, thread): #@NOTE: check only if all gone fine, no failed reporting for now
pass
- packages = self.queue.get() #: check for packages added during extraction
+ packages = self.queue.get() #: Check for packages added during extraction
self.extracting = False
+ #: Deprecated method, use `extract_package` instead
@Expose
- def extractPackage(self, *ids):
- """ Extract packages with given id"""
+ def extractPackage(self, *args, **kwargs):
+ """
+ See `extract_package`
+ """
+ return self.extract_package(*args, **kwargs)
+
+
+ @Expose
+ def extract_package(self, *ids):
+ """
+ Extract packages with given id
+ """
for id in ids:
self.queue.add(id)
- if not self.getConfig('waitall') and not self.extracting:
- self.extractQueued()
+ if not self.get_config('waitall') and not self.extracting:
+ self.extract_queued()
- def packageDeleted(self, pid):
+ def package_deleted(self, pid):
self.queue.remove(pid)
- def packageFinished(self, pypack):
+ def package_finished(self, pypack):
self.queue.add(pypack.id)
- if not self.getConfig('waitall') and not self.extracting:
- self.extractQueued()
+ if not self.get_config('waitall') and not self.extracting:
+ self.extract_queued()
- def allDownloadsProcessed(self):
- self.lastPackage = True
- if self.getConfig('waitall') and not self.extracting:
- self.extractQueued()
+ def all_downloads_processed(self):
+ self.last_package = True
+ if self.get_config('waitall') and not self.extracting:
+ self.extract_queued()
@Expose
@@ -243,51 +252,51 @@ class ExtractArchive(Hook):
toList = lambda string: string.replace(' ', '').replace(',', '|').replace(';', '|').split('|')
- destination = self.getConfig('destination')
- subfolder = self.getConfig('subfolder')
- fullpath = self.getConfig('fullpath')
- overwrite = self.getConfig('overwrite')
- renice = self.getConfig('renice')
- recursive = self.getConfig('recursive')
- delete = self.getConfig('delete')
- keepbroken = self.getConfig('keepbroken')
+ destination = self.get_config('destination')
+ subfolder = self.get_config('subfolder')
+ fullpath = self.get_config('fullpath')
+ overwrite = self.get_config('overwrite')
+ renice = self.get_config('renice')
+ recursive = self.get_config('recursive')
+ delete = self.get_config('delete')
+ keepbroken = self.get_config('keepbroken')
- extensions = [x.lstrip('.').lower() for x in toList(self.getConfig('extensions'))]
- excludefiles = toList(self.getConfig('excludefiles'))
+ extensions = [x.lstrip('.').lower() for x in toList(self.get_config('extensions'))]
+ excludefiles = toList(self.get_config('excludefiles'))
if extensions:
- self.logDebug("Use for extensions: %s" % "|.".join(extensions))
+ self.log_debug("Use for extensions: %s" % "|.".join(extensions))
- # reload from txt file
- self.reloadPasswords()
+ #: Reload from txt file
+ self.reload_passwords()
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
- # iterate packages -> extractors -> targets
+ #: Iterate packages -> extractors -> targets
for pid in ids:
- pypack = self.core.files.getPackage(pid)
+ pypack = self.pyload.files.getPackage(pid)
if not pypack:
self.queue.remove(pid)
continue
- self.logInfo(_("Check package: %s") % pypack.name)
+ self.log_info(_("Check package: %s") % pypack.name)
- # determine output folder
- out = save_join(download_folder, pypack.folder, destination, "") #: force trailing slash
+ #: Determine output folder
+ out = fs_join(download_folder, pypack.folder, destination, "") #: Force trailing slash
if subfolder:
- out = save_join(out, pypack.folder)
+ out = fs_join(out, pypack.folder)
if not os.path.exists(out):
os.makedirs(out)
matched = False
success = True
- files_ids = dict((pylink['name'],((save_join(download_folder, pypack.folder, pylink['name'])), pylink['id'], out)) for pylink \
- in sorted(pypack.getChildren().itervalues(), key=lambda k: k['name'])).values() #: remove duplicates
+ files_ids = dict((pylink['name'], ((fs_join(download_folder, pypack.folder, pylink['name'])), pylink['id'], out)) for pylink \
+ in sorted(pypack.getChildren().values(), key=lambda k: k['name'])).values() #: Remove duplicates
- # check as long there are unseen files
+ #: Check as long there are unseen files
while files_ids:
new_files_ids = []
@@ -296,21 +305,21 @@ class ExtractArchive(Hook):
if filter(lambda ext: fname.lower().endswith(ext), extensions)]
for Extractor in self.extractors:
- targets = Extractor.getTargets(files_ids)
+ targets = Extractor.get_targets(files_ids)
if targets:
- self.logDebug("Targets for %s: %s" % (Extractor.__name__, targets))
+ self.log_debug("Targets for %s: %s" % (Extractor.__name__, targets))
matched = True
for fname, fid, fout in targets:
name = os.path.basename(fname)
if not os.path.exists(fname):
- self.logDebug(name, "File not found")
+ self.log_debug(name, "File not found")
continue
- self.logInfo(name, _("Extract to: %s") % fout)
+ self.log_info(name, _("Extract to: %s") % fout)
try:
- pyfile = self.core.files.getFile(fid)
+ pyfile = self.pyload.files.getFile(fid)
archive = Extractor(self,
fname,
fout,
@@ -333,28 +342,30 @@ class ExtractArchive(Hook):
thread.finishFile(pyfile)
except Exception, e:
- self.logError(name, e)
+ self.log_error(name, e)
success = False
continue
- # remove processed file and related multiparts from list
+ #: Remove processed file and related multiparts from list
files_ids = [(fname, fid, fout) for fname, fid, fout in files_ids \
- if fname not in archive.getDeleteFiles()]
- self.logDebug("Extracted files: %s" % new_files)
- self.setPermissions(new_files)
+ if fname not in archive.get_delete_files()]
+ self.log_debug("Extracted files: %s" % new_files)
+
+ for file in new_files:
+ self.set_permissions(file)
for filename in new_files:
- file = fs_encode(save_join(os.path.dirname(archive.filename), filename))
+ file = fs_encode(fs_join(os.path.dirname(archive.filename), filename))
if not os.path.exists(file):
- self.logDebug("New file %s does not exists" % filename)
+ self.log_debug("New file %s does not exists" % filename)
continue
if recursive and os.path.isfile(file):
- new_files_ids.append((filename, fid, os.path.dirname(filename))) #: append as new target
+ new_files_ids.append((filename, fid, os.path.dirname(filename))) #: Append as new target
self.manager.dispatchEvent("archive_extracted", pyfile, archive)
- files_ids = new_files_ids #: also check extracted files
+ files_ids = new_files_ids #: Also check extracted files
if matched:
if success:
@@ -367,7 +378,7 @@ class ExtractArchive(Hook):
self.failed.add(pid)
else:
- self.logInfo(_("No files found to extract"))
+ self.log_info(_("No files found to extract"))
if not matched or not success and subfolder:
try:
@@ -388,44 +399,44 @@ class ExtractArchive(Hook):
encrypted = False
try:
- self.logDebug("Password: %s" % (password or "None provided"))
- passwords = uniqify([password] + self.getPasswords(False)) if self.getConfig('usepasswordfile') else [password]
+ self.log_debug("Password: %s" % (password or "None provided"))
+ passwords = uniqify([password] + self.get_passwords(False)) if self.get_config('usepasswordfile') else [password]
for pw in passwords:
try:
- if self.getConfig('test') or self.repair:
+ if self.get_config('test') or self.repair:
pyfile.setCustomStatus(_("archive testing"))
if pw:
- self.logDebug("Testing with password: %s" % pw)
+ self.log_debug("Testing with password: %s" % pw)
pyfile.setProgress(0)
archive.verify(pw)
pyfile.setProgress(100)
else:
archive.check(pw)
- self.addPassword(pw)
+ self.add_password(pw)
break
except PasswordError:
if not encrypted:
- self.logInfo(name, _("Password protected"))
+ self.log_info(name, _("Password protected"))
encrypted = True
except CRCError, e:
- self.logDebug(name, e)
- self.logInfo(name, _("CRC Error"))
+ self.log_debug(name, e)
+ self.log_info(name, _("CRC Error"))
if self.repair:
- self.logWarning(name, _("Repairing..."))
+ self.log_warning(name, _("Repairing..."))
pyfile.setCustomStatus(_("archive repairing"))
pyfile.setProgress(0)
repaired = archive.repair()
pyfile.setProgress(100)
- if not repaired and not self.getConfig('keepbroken'):
+ if not repaired and not self.get_config('keepbroken'):
raise CRCError("Archive damaged")
- self.addPassword(pw)
+ self.add_password(pw)
break
raise CRCError("Archive damaged")
@@ -436,33 +447,33 @@ class ExtractArchive(Hook):
pyfile.setCustomStatus(_("extracting"))
pyfile.setProgress(0)
- if not encrypted or not self.getConfig('usepasswordfile'):
- self.logDebug("Extracting using password: %s" % (password or "None"))
+ if not encrypted or not self.get_config('usepasswordfile'):
+ self.log_debug("Extracting using password: %s" % (password or "None"))
archive.extract(password)
else:
- for pw in filter(None, uniqify([password] + self.getPasswords(False))):
+ for pw in filter(None, uniqify([password] + self.get_passwords(False))):
try:
- self.logDebug("Extracting using password: %s" % pw)
+ self.log_debug("Extracting using password: %s" % pw)
archive.extract(pw)
- self.addPassword(pw)
+ self.add_password(pw)
break
except PasswordError:
- self.logDebug("Password was wrong")
+ self.log_debug("Password was wrong")
else:
raise PasswordError
pyfile.setProgress(100)
pyfile.setStatus("processing")
- delfiles = archive.getDeleteFiles()
- self.logDebug("Would delete: " + ", ".join(delfiles))
+ delfiles = archive.get_delete_files()
+ self.log_debug("Would delete: " + ", ".join(delfiles))
- if self.getConfig('delete'):
- self.logInfo(_("Deleting %s files") % len(delfiles))
+ if self.get_config('delete'):
+ self.log_info(_("Deleting %s files") % len(delfiles))
- deltotrash = self.getConfig('deltotrash')
+ deltotrash = self.get_config('deltotrash')
for f in delfiles:
file = fs_encode(f)
if not os.path.exists(file):
@@ -476,31 +487,33 @@ class ExtractArchive(Hook):
send2trash.send2trash(file)
except NameError:
- self.logWarning(_("Unable to move %s to trash: Send2Trash lib not found") % os.path.basename(f))
+ self.log_warning(_("Unable to move %s to trash") % os.path.basename(f),
+ _("Send2Trash lib not found"))
except Exception, e:
- self.logWarning(_("Unable to move %s to trash: %s") % (os.path.basename(f), e.message))
+ self.log_warning(_("Unable to move %s to trash") % os.path.basename(f),
+ e.message)
else:
- self.logDebug(_("Successfully moved %s to trash") % os.path.basename(f))
+ self.log_info(_("Moved %s to trash") % os.path.basename(f))
- self.logInfo(name, _("Extracting finished"))
+ self.log_info(name, _("Extracting finished"))
extracted_files = archive.files or archive.list()
return extracted_files
except PasswordError:
- self.logError(name, _("Wrong password" if password else "No password found"))
+ self.log_error(name, _("Wrong password" if password else "No password found"))
except CRCError, e:
- self.logError(name, _("CRC mismatch"), e)
+ self.log_error(name, _("CRC mismatch"), e)
except ArchiveError, e:
- self.logError(name, _("Archive error"), e)
+ self.log_error(name, _("Archive error"), e)
except Exception, e:
- self.logError(name, _("Unknown error"), e)
- if self.core.debug:
+ self.log_error(name, _("Unknown error"), e)
+ if self.pyload.debug:
traceback.print_exc()
self.manager.dispatchEvent("archive_extract_failed", pyfile, archive)
@@ -508,63 +521,63 @@ class ExtractArchive(Hook):
raise Exception(_("Extract failed"))
+ #: Deprecated method, use `get_passwords` instead
@Expose
- def getPasswords(self, reload=True):
- """ List of saved passwords """
+ def getPasswords(self, *args, **kwargs):
+ """
+ See `get_passwords`
+ """
+ return self.get_passwords(*args, **kwargs)
+
+
+ @Expose
+ def get_passwords(self, reload=True):
+ """
+ List of saved passwords
+ """
if reload:
- self.reloadPasswords()
+ self.reload_passwords()
return self.passwords
- def reloadPasswords(self):
+ def reload_passwords(self):
try:
passwords = []
- file = fs_encode(self.getConfig('passwordfile'))
+ file = fs_encode(self.get_config('passwordfile'))
with open(file) as f:
for pw in f.read().splitlines():
passwords.append(pw)
except IOError, e:
- self.logError(e)
+ self.log_error(e)
else:
self.passwords = passwords
+ #: Deprecated method, use `add_password` instead
+ @Expose
+ def addPassword(self, *args, **kwargs):
+ """
+ See `add_password`
+ """
+ return self.add_password(*args, **kwargs)
+
+
@Expose
- def addPassword(self, password):
- """ Adds a password to saved list"""
+ def add_password(self, password):
+ """
+ Adds a password to saved list
+ """
try:
self.passwords = uniqify([password] + self.passwords)
- file = fs_encode(self.getConfig('passwordfile'))
+ file = fs_encode(self.get_config('passwordfile'))
with open(file, "wb") as f:
for pw in self.passwords:
f.write(pw + '\n')
except IOError, e:
- self.logError(e)
-
-
- def setPermissions(self, files):
- for f in files:
- if not os.path.exists(f):
- continue
-
- try:
- if self.config['permission']['change_file']:
- if os.path.isfile(f):
- os.chmod(f, int(self.config['permission']['file'], 8))
-
- elif os.path.isdir(f):
- os.chmod(f, int(self.config['permission']['folder'], 8))
-
- if self.config['permission']['change_dl'] and os.name != "nt":
- uid = getpwnam(self.config['permission']['user'])[2]
- gid = getgrnam(self.config['permission']['group'])[2]
- os.chown(f, uid, gid)
-
- except Exception, e:
- self.logWarning(_("Setting User and Group failed"), e)
+ self.log_error(e)
diff --git a/module/plugins/hooks/FastixRuHook.py b/module/plugins/hooks/FastixRuHook.py
index 16e30e93a..3fdb29409 100644
--- a/module/plugins/hooks/FastixRuHook.py
+++ b/module/plugins/hooks/FastixRuHook.py
@@ -7,21 +7,21 @@ from module.plugins.internal.MultiHook import MultiHook
class FastixRuHook(MultiHook):
__name__ = "FastixRuHook"
__type__ = "hook"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Fastix.ru hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Massimo Rosamilia", "max@spiritix.eu")]
- def getHosters(self):
- html = self.getURL("http://fastix.ru/api_v2",
+ def get_hosters(self):
+ html = self.load("http://fastix.ru/api_v2",
get={'apikey': "5182964c3f8f9a7f0b00000a_kelmFB4n1IrnCDYuIFn2y",
'sub' : "allowed_sources"})
host_list = json_loads(html)
diff --git a/module/plugins/hooks/FreeWayMeHook.py b/module/plugins/hooks/FreeWayMeHook.py
index baea44540..1380433bf 100644
--- a/module/plugins/hooks/FreeWayMeHook.py
+++ b/module/plugins/hooks/FreeWayMeHook.py
@@ -6,27 +6,23 @@ from module.plugins.internal.MultiHook import MultiHook
class FreeWayMeHook(MultiHook):
__name__ = "FreeWayMeHook"
__type__ = "hook"
- __version__ = "0.15"
+ __version__ = "0.18"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """FreeWay.me hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Nicolas Giese", "james@free-way.me")]
- def getHosters(self):
- # Get account data
- if not self.account or not self.account.canUse():
- hostis = self.getURL("https://www.free-way.me/ajax/jd.php", get={"id": 3}).replace("\"", "").strip()
- else:
- self.logDebug("AccountInfo available - Get HosterList with User Pass")
- (user, data) = self.account.selectAccount()
- hostis = self.getURL("https://www.free-way.me/ajax/jd.php", get={"id": 3, "user": user, "pass": data['password']}).replace("\"", "").strip()
-
- self.logDebug("hosters: %s" % hostis)
+ def get_hosters(self):
+ user, info = self.account.select()
+ hostis = self.load("http://www.free-way.bz/ajax/jd.php",
+ get={'id' : 3,
+ 'user': user,
+ 'pass': info['login']['password']}).replace("\"", "") #@TODO: Revert to `https` in 0.4.10
return [x.strip() for x in hostis.split(",") if x.strip()]
diff --git a/module/plugins/hooks/HighWayMeHook.py b/module/plugins/hooks/HighWayMeHook.py
new file mode 100644
index 000000000..e9e62525d
--- /dev/null
+++ b/module/plugins/hooks/HighWayMeHook.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+
+from module.common.json_layer import json_loads
+from module.plugins.internal.MultiHook import MultiHook
+
+
+class HighWayMeHook(MultiHook):
+ __name__ = "HighWayMeHook"
+ __type__ = "hook"
+ __version__ = "0.04"
+ __status__ = "testing"
+
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+
+ __description__ = """High-Way.me hook plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("EvolutionClip", "evolutionclip@live.de")]
+
+
+ def get_hosters(self):
+ json_data = json_loads(self.load("https://high-way.me/api.php",
+ get={'hoster': 1}))
+ return [element['name'] for element in json_data['hoster']]
diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py
index f771cf232..84db4db17 100644
--- a/module/plugins/hooks/HotFolder.py
+++ b/module/plugins/hooks/HotFolder.py
@@ -7,14 +7,15 @@ import time
from shutil import move
-from module.plugins.Hook import Hook
-from module.utils import fs_encode, save_join
+from module.plugins.internal.Addon import Addon
+from module.utils import fs_encode, save_join as fs_join
-class HotFolder(Hook):
+class HotFolder(Addon):
__name__ = "HotFolder"
__type__ = "hook"
- __version__ = "0.14"
+ __version__ = "0.16"
+ __status__ = "testing"
__config__ = [("folder" , "str" , "Folder to observe" , "container"),
("watch_file", "bool", "Observe link file" , False ),
@@ -26,20 +27,19 @@ class HotFolder(Hook):
__authors__ = [("RaNaN", "RaNaN@pyload.de")]
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
+ def init(self):
self.interval = 30
def periodical(self):
- folder = fs_encode(self.getConfig('folder'))
- file = fs_encode(self.getConfig('file'))
+ folder = fs_encode(self.get_config('folder'))
+ file = fs_encode(self.get_config('file'))
try:
if not os.path.isdir(os.path.join(folder, "finished")):
os.makedirs(os.path.join(folder, "finished"))
- if self.getConfig('watch_file'):
+ if self.get_config('watch_file'):
with open(file, "a+") as f:
f.seek(0)
content = f.read().strip()
@@ -50,10 +50,10 @@ class HotFolder(Hook):
name = "%s_%s.txt" % (file, time.strftime("%H-%M-%S_%d%b%Y"))
- with open(save_join(folder, "finished", name), "wb") as f:
+ with open(fs_join(folder, "finished", name), "wb") as f:
f.write(content)
- self.core.api.addPackage(f.name, [f.name], 1)
+ self.pyload.api.addPackage(f.name, [f.name], 1)
for f in os.listdir(folder):
path = os.path.join(folder, f)
@@ -61,11 +61,11 @@ class HotFolder(Hook):
if not os.path.isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."):
continue
- newpath = os.path.join(folder, "finished", f if self.getConfig('keep') else "tmp_" + f)
+ newpath = os.path.join(folder, "finished", f if self.get_config('keep') else "tmp_" + f)
move(path, newpath)
- self.logInfo(_("Added %s from HotFolder") % f)
- self.core.api.addPackage(f, [newpath], 1)
+ self.log_info(_("Added %s from HotFolder") % f)
+ self.pyload.api.addPackage(f, [newpath], 1)
except (IOError, OSError), e:
- self.logError(e)
+ self.log_error(e)
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index 33fde3d20..08b1bad0c 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -11,42 +11,39 @@ from select import select
from threading import Thread
from module.Api import PackageDoesNotExists, FileDoesNotExists
-from module.network.RequestFactory import getURL
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
from module.utils import formatSize
-class IRCInterface(Thread, Hook):
+class IRCInterface(Thread, Addon):
__name__ = "IRCInterface"
__type__ = "hook"
- __version__ = "0.13"
-
- __config__ = [("host", "str", "IRC-Server Address", "Enter your server here!"),
- ("port", "int", "IRC-Server Port", 6667),
- ("ident", "str", "Clients ident", "pyload-irc"),
- ("realname", "str", "Realname", "pyload-irc"),
- ("ssl", "bool", "Use SSL", False),
- ("nick", "str", "Nickname the Client will take", "pyLoad-IRC"),
- ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"),
- ("info_file", "bool", "Inform about every file finished", False),
- ("info_pack", "bool", "Inform about every package finished", True),
- ("captcha", "bool", "Send captcha requests", True)]
+ __version__ = "0.15"
+ __status__ = "testing"
+
+ __config__ = [("host" , "str" , "IRC-Server Address" , "Enter your server here!"),
+ ("port" , "int" , "IRC-Server Port" , 6667 ),
+ ("ident" , "str" , "Clients ident" , "pyload-irc" ),
+ ("realname" , "str" , "Realname" , "pyload-irc" ),
+ ("ssl" , "bool", "Use SSL" , False ),
+ ("nick" , "str" , "Nickname the Client will take" , "pyLoad-IRC" ),
+ ("owner" , "str" , "Nickname the Client will accept commands from", "Enter your nick here!" ),
+ ("info_file", "bool", "Inform about every file finished" , False ),
+ ("info_pack", "bool", "Inform about every package finished" , True ),
+ ("captcha" , "bool", "Send captcha requests" , True )]
__description__ = """Connect to irc and let owner perform different tasks"""
__license__ = "GPLv3"
__authors__ = [("Jeix", "Jeix@hasnomail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
def __init__(self, core, manager):
Thread.__init__(self)
- Hook.__init__(self, core, manager)
- self.setDaemon(True)
+ Addon.__init__(self, core, manager)
+ self.set_daemon(True)
- def coreReady(self):
+ def activate(self):
self.abort = False
self.more = []
self.new_package = {}
@@ -54,30 +51,30 @@ class IRCInterface(Thread, Hook):
self.start()
- def packageFinished(self, pypack):
+ def package_finished(self, pypack):
try:
- if self.getConfig('info_pack'):
+ if self.get_config('info_pack'):
self.response(_("Package finished: %s") % pypack.name)
except Exception:
pass
- def downloadFinished(self, pyfile):
+ def download_finished(self, pyfile):
try:
- if self.getConfig('info_file'):
+ if self.get_config('info_file'):
self.response(
- _("Download finished: %(name)s @ %(plugin)s ") % {"name": pyfile.name, "plugin": pyfile.pluginname})
+ _("Download finished: %(name)s @ %(plugin)s ") % {'name': pyfile.name, 'plugin': pyfile.pluginname})
except Exception:
pass
- def newCaptchaTask(self, task):
- if self.getConfig('captcha') and task.isTextual():
+ def captcha_task(self, task):
+ if self.get_config('captcha') and task.isTextual():
task.handler.append(self)
task.setWaiting(60)
- html = getURL("http://www.freeimagehosting.net/upload.php",
- post={"attached": (pycurl.FORM_FILE, task.captchaFile)}, multipart=True)
+ html = self.load("http://www.freeimagehosting.net/upload.php",
+ post={'attached': (pycurl.FORM_FILE, task.captchaFile)})
url = re.search(r"\[img\]([^\[]+)\[/img\]\[/url\]", html).group(1)
self.response(_("New Captcha Request: %s") % url)
@@ -85,22 +82,22 @@ class IRCInterface(Thread, Hook):
def run(self):
- # connect to IRC etc.
+ #: Connect to IRC etc.
self.sock = socket.socket()
- host = self.getConfig('host')
- self.sock.connect((host, self.getConfig('port')))
+ host = self.get_config('host')
+ self.sock.connect((host, self.get_config('port')))
- if self.getConfig('ssl'):
+ if self.get_config('ssl'):
self.sock = ssl.wrap_socket(self.sock, cert_reqs=ssl.CERT_NONE) #@TODO: support certificate
- nick = self.getConfig('nick')
+ nick = self.get_config('nick')
self.sock.send("NICK %s\r\n" % nick)
self.sock.send("USER %s %s bla :%s\r\n" % (nick, host, nick))
- for t in self.getConfig('owner').split():
+ for t in self.get_config('owner').split():
if t.strip().startswith("#"):
self.sock.send("JOIN %s\r\n" % t.strip())
- self.logInfo(_("Connected to"), host)
- self.logInfo(_("Switching to listening mode!"))
+ self.log_info(_("Connected to"), host)
+ self.log_info(_("Switching to listening mode!"))
try:
self.main_loop()
@@ -140,36 +137,36 @@ class IRCInterface(Thread, Hook):
continue
msg = {
- "origin": msg[0][1:],
- "action": msg[1],
- "target": msg[2],
- "text": msg[3][1:]
+ 'origin': msg[0][1:],
+ 'action': msg[1],
+ 'target': msg[2],
+ 'text': msg[3][1:]
}
self.handle_events(msg)
def handle_events(self, msg):
- if not msg['origin'].split("!", 1)[0] in self.getConfig('owner').split():
+ if not msg['origin'].split("!", 1)[0] in self.get_config('owner').split():
return
- if msg['target'].split("!", 1)[0] != self.getConfig('nick'):
+ if msg['target'].split("!", 1)[0] is not self.get_config('nick'):
return
if msg['action'] != "PRIVMSG":
return
- # HANDLE CTCP ANTI FLOOD/BOT PROTECTION
+ #: HANDLE CTCP ANTI FLOOD/BOT PROTECTION
if msg['text'] == "\x01VERSION\x01":
- self.logDebug("Sending CTCP VERSION")
+ self.log_debug("Sending CTCP VERSION")
self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
return
elif msg['text'] == "\x01TIME\x01":
- self.logDebug("Sending CTCP TIME")
+ self.log_debug("Sending CTCP TIME")
self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time()))
return
elif msg['text'] == "\x01LAG\x01":
- self.logDebug("Received CTCP LAG") #: don't know how to answer
+ self.log_debug("Received CTCP LAG") #: don't know how to answer
return
trigger = "pass"
@@ -189,12 +186,12 @@ class IRCInterface(Thread, Hook):
for line in res:
self.response(line, msg['origin'])
except Exception, e:
- self.logError(e)
+ self.log_error(e)
def response(self, msg, origin=""):
if origin == "":
- for t in self.getConfig('owner').split():
+ for t in self.get_config('owner').split():
self.sock.send("PRIVMSG %s :%s\r\n" % (t.strip(), msg))
else:
self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg))
@@ -207,7 +204,7 @@ class IRCInterface(Thread, Hook):
def event_status(self, args):
- downloads = self.core.api.statusDownloads()
+ downloads = self.pyload.api.statusDownloads()
if not downloads:
return ["INFO: There are no active downloads currently."]
@@ -233,7 +230,7 @@ class IRCInterface(Thread, Hook):
def event_queue(self, args):
- ps = self.core.api.getQueueData()
+ ps = self.pyload.api.getQueueData()
if not ps:
return ["INFO: There are no packages in queue."]
@@ -246,7 +243,7 @@ class IRCInterface(Thread, Hook):
def event_collector(self, args):
- ps = self.core.api.getCollectorData()
+ ps = self.pyload.api.getCollectorData()
if not ps:
return ["INFO: No packages in collector!"]
@@ -263,7 +260,7 @@ class IRCInterface(Thread, Hook):
info = None
try:
- info = self.core.api.getFileData(int(args[0]))
+ info = self.pyload.api.getFileData(int(args[0]))
except FileDoesNotExists:
return ["ERROR: Link doesn't exists."]
@@ -278,7 +275,7 @@ class IRCInterface(Thread, Hook):
lines = []
pack = None
try:
- pack = self.core.api.getPackageData(int(args[0]))
+ pack = self.pyload.api.getPackageData(int(args[0]))
except PackageDoesNotExists:
return ["ERROR: Package doesn't exists."]
@@ -315,12 +312,12 @@ class IRCInterface(Thread, Hook):
def event_start(self, args):
- self.core.api.unpauseServer()
+ self.pyload.api.unpauseServer()
return ["INFO: Starting downloads."]
def event_stop(self, args):
- self.core.api.pauseServer()
+ self.pyload.api.pauseServer()
return ["INFO: No new downloads will be started."]
@@ -336,17 +333,17 @@ class IRCInterface(Thread, Hook):
count_failed = 0
try:
id = int(pack)
- pack = self.core.api.getPackageData(id)
+ pack = self.pyload.api.getPackageData(id)
if not pack:
return ["ERROR: Package doesn't exists."]
- #TODO add links
+ #@TODO: add links
return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack['name'], id)]
except Exception:
- # create new package
- id = self.core.api.addPackage(pack, links, 1)
+ #: Create new package
+ id = self.pyload.api.addPackage(pack, links, 1)
return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))]
@@ -355,11 +352,11 @@ class IRCInterface(Thread, Hook):
return ["ERROR: Use del command like this: del -p|-l <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"]
if args[0] == "-p":
- ret = self.core.api.deletePackages(map(int, args[1:]))
+ ret = self.pyload.api.deletePackages(map(int, args[1:]))
return ["INFO: Deleted %d packages!" % len(args[1:])]
elif args[0] == "-l":
- ret = self.core.api.delLinks(map(int, args[1:]))
+ ret = self.pyload.api.delLinks(map(int, args[1:]))
return ["INFO: Deleted %d links!" % len(args[1:])]
else:
@@ -372,11 +369,11 @@ class IRCInterface(Thread, Hook):
id = int(args[0])
try:
- info = self.core.api.getPackageInfo(id)
+ info = self.pyload.api.getPackageInfo(id)
except PackageDoesNotExists:
return ["ERROR: Package #%d does not exist." % id]
- self.core.api.pushToQueue(id)
+ self.pyload.api.pushToQueue(id)
return ["INFO: Pushed package #%d to queue." % id]
@@ -385,19 +382,21 @@ class IRCInterface(Thread, Hook):
return ["ERROR: Pull package from queue like this: pull <package id>."]
id = int(args[0])
- if not self.core.api.getPackageData(id):
+ if not self.pyload.api.getPackageData(id):
return ["ERROR: Package #%d does not exist." % id]
- self.core.api.pullFromQueue(id)
+ self.pyload.api.pullFromQueue(id)
return ["INFO: Pulled package #%d from queue to collector." % id]
def event_c(self, args):
- """ captcha answer """
+ """
+ Captcha answer
+ """
if not args:
return ["ERROR: Captcha ID missing."]
- task = self.core.captchaManager.getTaskByID(args[0])
+ task = self.pyload.captchaManager.getTaskByID(args[0])
if not task:
return ["ERROR: Captcha Task with ID %s does not exists." % args[0]]
diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py
index f1fcacb71..42ab99027 100644
--- a/module/plugins/hooks/ImageTyperz.py
+++ b/module/plugins/hooks/ImageTyperz.py
@@ -7,8 +7,8 @@ import re
from base64 import b64encode
-from module.network.RequestFactory import getURL, getRequest
-from module.plugins.Hook import Hook, threaded
+from module.network.RequestFactory import getRequest as get_request
+from module.plugins.internal.Hook import Hook, threaded
class ImageTyperzException(Exception):
@@ -17,7 +17,7 @@ class ImageTyperzException(Exception):
self.err = err
- def getCode(self):
+ def get_code(self):
return self.err
@@ -32,11 +32,12 @@ class ImageTyperzException(Exception):
class ImageTyperz(Hook):
__name__ = "ImageTyperz"
__type__ = "hook"
- __version__ = "0.06"
+ __version__ = "0.08"
+ __status__ = "testing"
- __config__ = [("username", "str", "Username", ""),
- ("passkey", "password", "Password", ""),
- ("force", "bool", "Force IT even if client is connected", False)]
+ __config__ = [("username" , "str" , "Username" , "" ),
+ ("password" , "password", "Password" , "" ),
+ ("check_client", "bool" , "Don't use if client is connected", True)]
__description__ = """Send captchas to ImageTyperz.com"""
__license__ = "GPLv3"
@@ -44,22 +45,16 @@ class ImageTyperz(Hook):
("zoidberg", "zoidberg@mujmail.cz")]
- interval = 0 #@TODO: Remove in 0.4.10
-
SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx"
RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx"
GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx"
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
- def getCredits(self):
- res = getURL(self.GETCREDITS_URL,
+ def get_credits(self):
+ res = self.load(self.GETCREDITS_URL,
post={'action': "REQUESTBALANCE",
- 'username': self.getConfig('username'),
- 'password': self.getConfig('passkey')})
+ 'username': self.get_config('username'),
+ 'password': self.get_config('password')})
if res.startswith('ERROR'):
raise ImageTyperzException(res)
@@ -69,18 +64,18 @@ class ImageTyperz(Hook):
except Exception:
raise ImageTyperzException("Invalid response")
- self.logInfo(_("Account balance: $%s left") % res)
+ self.log_info(_("Account balance: $%s left") % res)
return balance
def submit(self, captcha, captchaType="file", match=None):
- req = getRequest()
- #raise timeout threshold
+ req = get_request()
+ #: Raise timeout threshold
req.c.setopt(pycurl.LOW_SPEED_TIME, 80)
try:
#@NOTE: Workaround multipart-post bug in HTTPRequest.py
- if re.match("^\w*$", self.getConfig('passkey')):
+ if re.match("^\w*$", self.get_config('password')):
multipart = True
data = (pycurl.FORM_FILE, captcha)
else:
@@ -89,11 +84,12 @@ class ImageTyperz(Hook):
data = f.read()
data = b64encode(data)
- res = req.load(self.SUBMIT_URL,
- post={'action': "UPLOADCAPTCHA",
- 'username': self.getConfig('username'),
- 'password': self.getConfig('passkey'), "file": data},
- multipart=multipart)
+ res = self.load(self.SUBMIT_URL,
+ post={'action': "UPLOADCAPTCHA",
+ 'username': self.get_config('username'),
+ 'password': self.get_config('password'), 'file': data},
+ multipart=multipart,
+ req=req)
finally:
req.close()
@@ -109,50 +105,50 @@ class ImageTyperz(Hook):
return ticket, result
- def newCaptchaTask(self, task):
+ def captcha_task(self, task):
if "service" in task.data:
return False
if not task.isTextual():
return False
- if not self.getConfig('username') or not self.getConfig('passkey'):
+ if not self.get_config('username') or not self.get_config('password'):
return False
- if self.core.isClientConnected() and not self.getConfig('force'):
+ if self.pyload.isClientConnected() and self.get_config('check_client'):
return False
- if self.getCredits() > 0:
+ if self.get_credits() > 0:
task.handler.append(self)
task.data['service'] = self.__name__
task.setWaiting(100)
- self._processCaptcha(task)
+ self._process_captcha(task)
else:
- self.logInfo(_("Your %s account has not enough credits") % self.__name__)
+ self.log_info(_("Your %s account has not enough credits") % self.__name__)
- def captchaInvalid(self, task):
- if task.data['service'] == self.__name__ and "ticket" in task.data:
- res = getURL(self.RESPOND_URL,
+ def captcha_invalid(self, task):
+ if task.data['service'] is self.__name__ and "ticket" in task.data:
+ res = self.load(self.RESPOND_URL,
post={'action': "SETBADIMAGE",
- 'username': self.getConfig('username'),
- 'password': self.getConfig('passkey'),
+ 'username': self.get_config('username'),
+ 'password': self.get_config('password'),
'imageid': task.data['ticket']})
if res == "SUCCESS":
- self.logInfo(_("Bad captcha solution received, requested refund"))
+ self.log_info(_("Bad captcha solution received, requested refund"))
else:
- self.logError(_("Bad captcha solution received, refund request failed"), res)
+ self.log_error(_("Bad captcha solution received, refund request failed"), res)
@threaded
- def _processCaptcha(self, task):
+ def _process_captcha(self, task):
c = task.captchaFile
try:
ticket, result = self.submit(c)
except ImageTyperzException, e:
- task.error = e.getCode()
+ task.error = e.get_code()
return
task.data['ticket'] = ticket
diff --git a/module/plugins/hooks/JustPremium.py b/module/plugins/hooks/JustPremium.py
index f66747f82..69a6a851b 100644
--- a/module/plugins/hooks/JustPremium.py
+++ b/module/plugins/hooks/JustPremium.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
-class JustPremium(Hook):
+class JustPremium(Addon):
__name__ = "JustPremium"
__type__ = "hook"
- __version__ = "0.22"
+ __version__ = "0.24"
+ __status__ = "testing"
__config__ = [("excluded", "str", "Exclude hosters (comma separated)", ""),
("included", "str", "Include hosters (comma separated)", "")]
@@ -20,28 +21,24 @@ class JustPremium(Hook):
("immenz" , "immenz@gmx.net" )]
- interval = 0 #@TODO: Remove in 0.4.10
+ def init(self):
+ self.event_map = {'linksAdded': "links_added"}
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- self.event_list = ["linksAdded"]
+ def links_added(self, links, pid):
+ hosterdict = self.pyload.pluginManager.hosterPlugins
+ linkdict = self.pyload.api.checkURLs(links)
-
- def linksAdded(self, links, pid):
- hosterdict = self.core.pluginManager.hosterPlugins
- linkdict = self.core.api.checkURLs(links)
-
- premiumplugins = set(account.type for account in self.core.api.getAccounts(False) \
+ premiumplugins = set(account.type for account in self.pyload.api.getAccounts(False) \
if account.valid and account.premium)
- multihosters = set(hoster for hoster in self.core.pluginManager.hosterPlugins \
+ multihosters = set(hoster for hoster in self.pyload.pluginManager.hosterPlugins \
if 'new_name' in hosterdict[hoster] \
and hosterdict[hoster]['new_name'] in premiumplugins)
excluded = map(lambda domain: "".join(part.capitalize() for part in re.split(r'(\.|\d+)', domain) if part != '.'),
- self.getConfig('excluded').replace(' ', '').replace(',', '|').replace(';', '|').split('|'))
+ self.get_config('excluded').replace(' ', '').replace(',', '|').replace(';', '|').split('|'))
included = map(lambda domain: "".join(part.capitalize() for part in re.split(r'(\.|\d+)', domain) if part != '.'),
- self.getConfig('included').replace(' ', '').replace(',', '|').replace(';', '|').split('|'))
+ self.get_config('included').replace(' ', '').replace(',', '|').replace(';', '|').split('|'))
hosterlist = (premiumplugins | multihosters).union(excluded).difference(included)
@@ -50,7 +47,7 @@ class JustPremium(Hook):
return
for pluginname in set(linkdict.keys()) - hosterlist:
- self.logInfo(_("Remove links of plugin: %s") % pluginname)
+ self.log_info(_("Remove links of plugin: %s") % pluginname)
for link in linkdict[pluginname]:
- self.logDebug("Remove link: %s" % link)
+ self.log_debug("Remove link: %s" % link)
links.remove(link)
diff --git a/module/plugins/hooks/LinkdecrypterComHook.py b/module/plugins/hooks/LinkdecrypterComHook.py
index b2eaece62..6930afdb5 100644
--- a/module/plugins/hooks/LinkdecrypterComHook.py
+++ b/module/plugins/hooks/LinkdecrypterComHook.py
@@ -8,7 +8,8 @@ from module.plugins.internal.MultiHook import MultiHook
class LinkdecrypterComHook(MultiHook):
__name__ = "LinkdecrypterComHook"
__type__ = "hook"
- __version__ = "1.06"
+ __version__ = "1.07"
+ __status__ = "testing"
__config__ = [("activated" , "bool" , "Activated" , True ),
("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
@@ -21,9 +22,9 @@ class LinkdecrypterComHook(MultiHook):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- def getHosters(self):
+ def get_hosters(self):
list = re.search(r'>Supported\(\d+\)</b>: <i>(.[\w.\-, ]+)',
- self.getURL("http://linkdecrypter.com/", decode=True).replace("(g)", "")).group(1).split(', ')
+ self.load("http://linkdecrypter.com/").replace("(g)", "")).group(1).split(', ')
try:
list.remove("download.serienjunkies.org")
except ValueError:
diff --git a/module/plugins/hooks/LinksnappyComHook.py b/module/plugins/hooks/LinksnappyComHook.py
index 72282575b..e46e480d6 100644
--- a/module/plugins/hooks/LinksnappyComHook.py
+++ b/module/plugins/hooks/LinksnappyComHook.py
@@ -7,21 +7,21 @@ from module.plugins.internal.MultiHook import MultiHook
class LinksnappyComHook(MultiHook):
__name__ = "LinksnappyComHook"
__type__ = "hook"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Linksnappy.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- def getHosters(self):
- json_data = self.getURL("http://gen.linksnappy.com/lseAPI.php", get={'act': "FILEHOSTS"})
+ def get_hosters(self):
+ json_data = self.load("http://gen.linksnappy.com/lseAPI.php", get={'act': "FILEHOSTS"})
json_data = json_loads(json_data)
return json_data['return'].keys()
diff --git a/module/plugins/hooks/MegaDebridEuHook.py b/module/plugins/hooks/MegaDebridEuHook.py
index 0de7b4dcf..04f0be86f 100644
--- a/module/plugins/hooks/MegaDebridEuHook.py
+++ b/module/plugins/hooks/MegaDebridEuHook.py
@@ -7,27 +7,27 @@ from module.plugins.internal.MultiHook import MultiHook
class MegaDebridEuHook(MultiHook):
__name__ = "MegaDebridEuHook"
__type__ = "hook"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Mega-debrid.eu hook plugin"""
__license__ = "GPLv3"
__authors__ = [("D.Ducatel", "dducatel@je-geek.fr")]
- def getHosters(self):
- reponse = self.getURL("http://www.mega-debrid.eu/api.php", get={'action': "getHosters"})
+ def get_hosters(self):
+ reponse = self.load("http://www.mega-debrid.eu/api.php", get={'action': "getHosters"})
json_data = json_loads(reponse)
if json_data['response_code'] == "ok":
host_list = [element[0] for element in json_data['hosters']]
else:
- self.logError(_("Unable to retrieve hoster list"))
- host_list = list()
+ self.log_error(_("Unable to retrieve hoster list"))
+ host_list = []
return host_list
diff --git a/module/plugins/hooks/MegaRapidoNetHook.py b/module/plugins/hooks/MegaRapidoNetHook.py
index e113b305e..4956427ff 100644
--- a/module/plugins/hooks/MegaRapidoNetHook.py
+++ b/module/plugins/hooks/MegaRapidoNetHook.py
@@ -8,7 +8,8 @@ from module.plugins.internal.MultiHook import MultiHook
class MegaRapidoNetHook(MultiHook):
__name__ = "MegaRapidoNetHook"
__type__ = "hook"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
@@ -20,15 +21,15 @@ class MegaRapidoNetHook(MultiHook):
__authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")]
- def getHosters(self):
- hosters = {'1fichier' : [],#leave it there are so many possible addresses?
+ def get_hosters(self):
+ hosters = {'1fichier' : [], # leave it there are so many possible addresses?
'1st-files' : ['1st-files.com'],
'2shared' : ['2shared.com'],
'4shared' : ['4shared.com', '4shared-china.com'],
'asfile' : ['http://asfile.com/'],
'bitshare' : ['bitshare.com'],
'brupload' : ['brupload.net'],
- 'crocko' : ['crocko.com','easy-share.com'],
+ 'crocko' : ['crocko.com', 'easy-share.com'],
'dailymotion' : ['dailymotion.com'],
'depfile' : ['depfile.com'],
'depositfiles': ['depositfiles.com', 'dfiles.eu'],
@@ -38,12 +39,12 @@ class MegaRapidoNetHook(MultiHook):
'extmatrix' : ['extmatrix.com'],
'facebook' : [],
'file4go' : ['file4go.com'],
- 'filecloud' : ['filecloud.io','ifile.it','mihd.net'],
+ 'filecloud' : ['filecloud.io', 'ifile.it', 'mihd.net'],
'filefactory' : ['filefactory.com'],
'fileom' : ['fileom.com'],
'fileparadox' : ['fileparadox.in'],
'filepost' : ['filepost.com', 'fp.io'],
- 'filerio' : ['filerio.in','filerio.com','filekeen.com'],
+ 'filerio' : ['filerio.in', 'filerio.com', 'filekeen.com'],
'filesflash' : ['filesflash.com'],
'firedrive' : ['firedrive.com', 'putlocker.com'],
'flashx' : [],
@@ -51,7 +52,7 @@ class MegaRapidoNetHook(MultiHook):
'gigasize' : ['gigasize.com'],
'hipfile' : ['hipfile.com'],
'junocloud' : ['junocloud.me'],
- 'letitbit' : ['letitbit.net','shareflare.net'],
+ 'letitbit' : ['letitbit.net', 'shareflare.net'],
'mediafire' : ['mediafire.com'],
'mega' : ['mega.co.nz'],
'megashares' : ['megashares.com'],
@@ -75,7 +76,7 @@ class MegaRapidoNetHook(MultiHook):
hoster_list = []
- for item in hosters.itervalues():
+ for item in hosters.values():
hoster_list.extend(item)
return hoster_list
diff --git a/module/plugins/hooks/MergeFiles.py b/module/plugins/hooks/MergeFiles.py
index 941938920..a76a578bf 100644
--- a/module/plugins/hooks/MergeFiles.py
+++ b/module/plugins/hooks/MergeFiles.py
@@ -6,14 +6,15 @@ import os
import re
import traceback
-from module.plugins.Hook import Hook, threaded
-from module.utils import save_join
+from module.plugins.internal.Addon import Addon, threaded
+from module.utils import save_join as fs_join
-class MergeFiles(Hook):
+class MergeFiles(Addon):
__name__ = "MergeFiles"
__type__ = "hook"
- __version__ = "0.14"
+ __version__ = "0.16"
+ __status__ = "testing"
__config__ = [("activated", "bool", "Activated", True)]
@@ -22,20 +23,14 @@ class MergeFiles(Hook):
__authors__ = [("and9000", "me@has-no-mail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
BUFFER_SIZE = 4096
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
@threaded
- def packageFinished(self, pack):
+ def package_finished(self, pack):
files = {}
fid_dict = {}
- for fid, data in pack.getChildren().iteritems():
+ for fid, data in pack.getChildren().items():
if re.search("\.\d{3}$", data['name']):
if data['name'][:-4] not in files:
files[data['name'][:-4]] = []
@@ -43,24 +38,24 @@ class MergeFiles(Hook):
files[data['name'][:-4]].sort()
fid_dict[data['name']] = fid
- download_folder = self.config['general']['download_folder']
+ download_folder = self.pyload.config.get("general", "download_folder")
- if self.config['general']['folder_per_package']:
- download_folder = save_join(download_folder, pack.folder)
+ if self.pyload.config.get("general", "folder_per_package"):
+ download_folder = fs_join(download_folder, pack.folder)
- for name, file_list in files.iteritems():
- self.logInfo(_("Starting merging of"), name)
+ for name, file_list in files.items():
+ self.log_info(_("Starting merging of"), name)
- with open(save_join(download_folder, name), "wb") as final_file:
+ with open(fs_join(download_folder, name), "wb") as final_file:
for splitted_file in file_list:
- self.logDebug("Merging part", splitted_file)
+ self.log_debug("Merging part", splitted_file)
- pyfile = self.core.files.getFile(fid_dict[splitted_file])
+ pyfile = self.pyload.files.getFile(fid_dict[splitted_file])
pyfile.setStatus("processing")
try:
- with open(save_join(download_folder, splitted_file), "rb") as s_file:
+ with open(fs_join(download_folder, splitted_file), "rb") as s_file:
size_written = 0
s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file)))
while True:
@@ -71,7 +66,7 @@ class MergeFiles(Hook):
pyfile.setProgress((size_written * 100) / s_file_size)
else:
break
- self.logDebug("Finished merging part", splitted_file)
+ self.log_debug("Finished merging part", splitted_file)
except Exception, e:
traceback.print_exc()
@@ -81,4 +76,4 @@ class MergeFiles(Hook):
pyfile.setStatus("finished")
pyfile.release()
- self.logInfo(_("Finished merging of"), name)
+ self.log_info(_("Finished merging of"), name)
diff --git a/module/plugins/hooks/MultiHome.py b/module/plugins/hooks/MultiHome.py
index a26d139c0..929ab9a25 100644
--- a/module/plugins/hooks/MultiHome.py
+++ b/module/plugins/hooks/MultiHome.py
@@ -2,64 +2,61 @@
import time
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
-class MultiHome(Hook):
+class MultiHome(Addon):
__name__ = "MultiHome"
__type__ = "hook"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__config__ = [("interfaces", "str", "Interfaces", "None")]
- __description__ = """Ip address changer"""
+ __description__ = """IP address changer"""
__license__ = "GPLv3"
__authors__ = [("mkaay", "mkaay@mkaay.de")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
+ def init(self):
self.register = {}
self.interfaces = []
- self.parseInterfaces(self.getConfig('interfaces').split(";"))
+ self.parse_interfaces(self.get_config('interfaces').split(";"))
if not self.interfaces:
- self.parseInterfaces([self.config['download']['interface']])
- self.setConfig("interfaces", self.toConfig())
+ self.parse_interfaces([self.pyload.config.get("download", "interface")])
+ self.set_config("interfaces", self.to_config())
- def toConfig(self):
+ def to_config(self):
return ";".join(i.adress for i in self.interfaces)
- def parseInterfaces(self, interfaces):
+ def parse_interfaces(self, interfaces):
for interface in interfaces:
if not interface or str(interface).lower() == "none":
continue
self.interfaces.append(Interface(interface))
- def coreReady(self):
- requestFactory = self.core.requestFactory
+ def activate(self):
+ requestFactory = self.pyload.requestFactory
oldGetRequest = requestFactory.getRequest
- def getRequest(pluginName, account=None):
- iface = self.bestInterface(pluginName, account)
+ def get_request(pluginName, account=None):
+ iface = self.best_interface(pluginName, account)
if iface:
iface.useFor(pluginName, account)
requestFactory.iface = lambda: iface.adress
- self.logDebug("Using address", iface.adress)
+ self.log_debug("Using address", iface.adress)
return oldGetRequest(pluginName, account)
- requestFactory.getRequest = getRequest
+ requestFactory.getRequest = get_request
- def bestInterface(self, pluginName, account):
+ def best_interface(self, pluginName, account):
best = None
for interface in self.interfaces:
if not best or interface.lastPluginAccess(pluginName, account) < best.lastPluginAccess(pluginName, account):
@@ -74,13 +71,13 @@ class Interface(object):
self.history = {}
- def lastPluginAccess(self, pluginName, account):
+ def last_plugin_access(self, pluginName, account):
if (pluginName, account) in self.history:
return self.history[(pluginName, account)]
return 0
- def useFor(self, pluginName, account):
+ def use_for(self, pluginName, account):
self.history[(pluginName, account)] = time.time()
diff --git a/module/plugins/hooks/MultihostersComHook.py b/module/plugins/hooks/MultihostersComHook.py
index 7b5e49c49..ec1cf9c85 100644
--- a/module/plugins/hooks/MultihostersComHook.py
+++ b/module/plugins/hooks/MultihostersComHook.py
@@ -6,12 +6,13 @@ from module.plugins.hooks.ZeveraComHook import ZeveraComHook
class MultihostersComHook(ZeveraComHook):
__name__ = "MultihostersComHook"
__type__ = "hook"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
- __config__ = [("mode" , "all;listed;unlisted", "Use for plugins (if supported)" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed", "bool" , "Revert to standard download if download fails", False),
- ("interval" , "int" , "Reload interval in hours (0 to disable)" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Multihosters.com hook plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/hooks/MultishareCzHook.py b/module/plugins/hooks/MultishareCzHook.py
index 6052b7673..30f1e21b5 100644
--- a/module/plugins/hooks/MultishareCzHook.py
+++ b/module/plugins/hooks/MultishareCzHook.py
@@ -8,13 +8,13 @@ from module.plugins.internal.MultiHook import MultiHook
class MultishareCzHook(MultiHook):
__name__ = "MultishareCzHook"
__type__ = "hook"
- __version__ = "0.07"
+ __version__ = "0.08"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """MultiShare.cz hook plugin"""
__license__ = "GPLv3"
@@ -24,6 +24,6 @@ class MultishareCzHook(MultiHook):
HOSTER_PATTERN = r'<img class="logo-shareserveru"[^>]*?alt="(.+?)"></td>\s*<td class="stav">[^>]*?alt="OK"'
- def getHosters(self):
- html = self.getURL("http://www.multishare.cz/monitoring/")
+ def get_hosters(self):
+ html = self.load("http://www.multishare.cz/monitoring/")
return re.findall(self.HOSTER_PATTERN, html)
diff --git a/module/plugins/hooks/MyfastfileComHook.py b/module/plugins/hooks/MyfastfileComHook.py
index 20a1cfac2..1eedd9238 100644
--- a/module/plugins/hooks/MyfastfileComHook.py
+++ b/module/plugins/hooks/MyfastfileComHook.py
@@ -7,22 +7,22 @@ from module.plugins.internal.MultiHook import MultiHook
class MyfastfileComHook(MultiHook):
__name__ = "MyfastfileComHook"
__type__ = "hook"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Myfastfile.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- def getHosters(self):
- json_data = self.getURL("http://myfastfile.com/api.php", get={'hosts': ""}, decode=True)
- self.logDebug("JSON data", json_data)
+ def get_hosters(self):
+ json_data = self.load("http://myfastfile.com/api.php", get={'hosts': ""})
+ self.log_debug("JSON data", json_data)
json_data = json_loads(json_data)
return json_data['hosts']
diff --git a/module/plugins/hooks/NoPremiumPlHook.py b/module/plugins/hooks/NoPremiumPlHook.py
index b5a007ff9..7dbdf6a68 100644
--- a/module/plugins/hooks/NoPremiumPlHook.py
+++ b/module/plugins/hooks/NoPremiumPlHook.py
@@ -7,23 +7,23 @@ from module.plugins.internal.MultiHook import MultiHook
class NoPremiumPlHook(MultiHook):
__name__ = "NoPremiumPlHook"
__type__ = "hook"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """NoPremium.pl hook plugin"""
__license__ = "GPLv3"
__authors__ = [("goddie", "dev@nopremium.pl")]
- def getHosters(self):
- hostings = json_loads(self.getURL("https://www.nopremium.pl/clipboard.php?json=3").strip())
- hostings_domains = [domain for row in hostings for domain in row["domains"] if row["sdownload"] == "0"]
+ def get_hosters(self):
+ hostings = json_loads(self.load("https://www.nopremium.pl/clipboard.php?json=3").strip())
+ hostings_domains = [domain for row in hostings for domain in row['domains'] if row['sdownload'] == "0"]
- self.logDebug(hostings_domains)
+ self.log_debug(hostings_domains)
return hostings_domains
diff --git a/module/plugins/hooks/OverLoadMeHook.py b/module/plugins/hooks/OverLoadMeHook.py
index d608a2ecd..5398fc17d 100644
--- a/module/plugins/hooks/OverLoadMeHook.py
+++ b/module/plugins/hooks/OverLoadMeHook.py
@@ -6,24 +6,20 @@ from module.plugins.internal.MultiHook import MultiHook
class OverLoadMeHook(MultiHook):
__name__ = "OverLoadMeHook"
__type__ = "hook"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 ),
- ("ssl" , "bool" , "Use HTTPS" , True )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Over-Load.me hook plugin"""
__license__ = "GPLv3"
__authors__ = [("marley", "marley@over-load.me")]
- def getHosters(self):
- https = "https" if self.getConfig('ssl') else "http"
- html = self.getURL(https + "://api.over-load.me/hoster.php",
- get={'auth': "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}).replace("\"", "").strip()
- self.logDebug("Hosterlist", html)
-
+ def get_hosters(self):
+ html = self.load("https://api.over-load.me/hoster.php",
+ get={'auth': "0001-cb1f24dadb3aa487bda5afd3b76298935329be7700cd7-5329be77-00cf-1ca0135f"}).replace("\"", "").strip()
return [x.strip() for x in html.split(",") if x.strip()]
diff --git a/module/plugins/hooks/PremiumToHook.py b/module/plugins/hooks/PremiumToHook.py
index ef2a84223..bcd7a7aab 100644
--- a/module/plugins/hooks/PremiumToHook.py
+++ b/module/plugins/hooks/PremiumToHook.py
@@ -6,13 +6,13 @@ from module.plugins.internal.MultiHook import MultiHook
class PremiumToHook(MultiHook):
__name__ = "PremiumToHook"
__type__ = "hook"
- __version__ = "0.08"
+ __version__ = "0.11"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Premium.to hook plugin"""
__license__ = "GPLv3"
@@ -21,7 +21,9 @@ class PremiumToHook(MultiHook):
("stickell", "l.stickell@yahoo.it")]
- def getHosters(self):
- html = self.getURL("http://premium.to/api/hosters.php",
- get={'username': self.account.username, 'password': self.account.password})
+ def get_hosters(self):
+ user, info = self.account.select()
+ html = self.load("http://premium.to/api/hosters.php",
+ get={'username': user,
+ 'password': info['login']['password']})
return [x.strip() for x in html.replace("\"", "").split(";")]
diff --git a/module/plugins/hooks/PremiumizeMeHook.py b/module/plugins/hooks/PremiumizeMeHook.py
index e081fb389..9a9a380af 100644
--- a/module/plugins/hooks/PremiumizeMeHook.py
+++ b/module/plugins/hooks/PremiumizeMeHook.py
@@ -7,32 +7,34 @@ from module.plugins.internal.MultiHook import MultiHook
class PremiumizeMeHook(MultiHook):
__name__ = "PremiumizeMeHook"
__type__ = "hook"
- __version__ = "0.17"
+ __version__ = "0.20"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Premiumize.me hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Florian Franzen", "FlorianFranzen@gmail.com")]
- def getHosters(self):
- # Get account data
- user, data = self.account.selectAccount()
+ def get_hosters(self):
+ #: Get account data
+ user, info = self.account.select()
- # Get supported hosters list from premiumize.me using the
- # json API v1 (see https://secure.premiumize.me/?show=api)
- answer = self.getURL("https://api.premiumize.me/pm-api/v1.php",
- get={'method': "hosterlist", 'params[login]': user, 'params[pass]': data['password']})
+ #: Get supported hosters list from premiumize.me using the
+ #: json API v1 (see https://secure.premiumize.me/?show=api)
+ answer = self.load("http://api.premiumize.me/pm-api/v1.php", #@TODO: Revert to `https` in 0.4.10
+ get={'method' : "hosterlist",
+ 'params[login]': user,
+ 'params[pass]' : info['login']['password']})
data = json_loads(answer)
- # If account is not valid thera are no hosters available
+ #: If account is not valid thera are no hosters available
if data['status'] != 200:
return []
- # Extract hosters from json file
+ #: Extract hosters from json file
return data['result']['hosterlist']
diff --git a/module/plugins/hooks/PutdriveComHook.py b/module/plugins/hooks/PutdriveComHook.py
index c3ebf4ff3..d206aaf88 100644
--- a/module/plugins/hooks/PutdriveComHook.py
+++ b/module/plugins/hooks/PutdriveComHook.py
@@ -6,12 +6,13 @@ from module.plugins.hooks.ZeveraComHook import ZeveraComHook
class PutdriveComHook(ZeveraComHook):
__name__ = "PutdriveComHook"
__type__ = "hook"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
- __config__ = [("mode" , "all;listed;unlisted", "Use for plugins (if supported)" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed", "bool" , "Revert to standard download if download fails", False),
- ("interval" , "int" , "Reload interval in hours (0 to disable)" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Putdrive.com hook plugin"""
__license__ = "GPLv3"
diff --git a/module/plugins/hooks/RPNetBizHook.py b/module/plugins/hooks/RPNetBizHook.py
index 10332948d..5d26b7f09 100644
--- a/module/plugins/hooks/RPNetBizHook.py
+++ b/module/plugins/hooks/RPNetBizHook.py
@@ -7,30 +7,32 @@ from module.plugins.internal.MultiHook import MultiHook
class RPNetBizHook(MultiHook):
__name__ = "RPNetBizHook"
__type__ = "hook"
- __version__ = "0.14"
+ __version__ = "0.16"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """RPNet.biz hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Dman", "dmanugm@gmail.com")]
- def getHosters(self):
- # Get account data
- user, data = self.account.selectAccount()
+ def get_hosters(self):
+ #: Get account data
+ user, info = self.account.select()
- res = self.getURL("https://premium.rpnet.biz/client_api.php",
- get={'username': user, 'password': data['password'], 'action': "showHosterList"})
+ res = self.load("https://premium.rpnet.biz/client_api.php",
+ get={'username': user,
+ 'password': info['login']['password'],
+ 'action' : "showHosterList"})
hoster_list = json_loads(res)
- # If account is not valid thera are no hosters available
+ #: If account is not valid thera are no hosters available
if 'error' in hoster_list:
return []
- # Extract hosters from json file
+ #: Extract hosters from json file
return hoster_list['hosters']
diff --git a/module/plugins/hooks/RapideoPlHook.py b/module/plugins/hooks/RapideoPlHook.py
index 0400f07ba..130f73851 100644
--- a/module/plugins/hooks/RapideoPlHook.py
+++ b/module/plugins/hooks/RapideoPlHook.py
@@ -7,23 +7,23 @@ from module.plugins.internal.MultiHook import MultiHook
class RapideoPlHook(MultiHook):
__name__ = "RapideoPlHook"
__type__ = "hook"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Rapideo.pl hook plugin"""
__license__ = "GPLv3"
__authors__ = [("goddie", "dev@rapideo.pl")]
- def getHosters(self):
- hostings = json_loads(self.getURL("https://www.rapideo.pl/clipboard.php?json=3").strip())
- hostings_domains = [domain for row in hostings for domain in row["domains"] if row["sdownload"] == "0"]
+ def get_hosters(self):
+ hostings = json_loads(self.load("https://www.rapideo.pl/clipboard.php?json=3").strip())
+ hostings_domains = [domain for row in hostings for domain in row['domains'] if row['sdownload'] == "0"]
- self.logDebug(hostings_domains)
+ self.log_debug(hostings_domains)
return hostings_domains
diff --git a/module/plugins/hooks/RealdebridComHook.py b/module/plugins/hooks/RealdebridComHook.py
index aa0c9f640..01b9d165e 100644
--- a/module/plugins/hooks/RealdebridComHook.py
+++ b/module/plugins/hooks/RealdebridComHook.py
@@ -6,22 +6,19 @@ from module.plugins.internal.MultiHook import MultiHook
class RealdebridComHook(MultiHook):
__name__ = "RealdebridComHook"
__type__ = "hook"
- __version__ = "0.46"
+ __version__ = "0.47"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 ),
- ("ssl" , "bool" , "Use HTTPS" , True )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Real-Debrid.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Devirex Hazzard", "naibaf_11@yahoo.de")]
- def getHosters(self):
- https = "https" if self.getConfig('ssl') else "http"
- html = self.getURL(https + "://real-debrid.com/api/hosters.php").replace("\"", "").strip()
-
+ def get_hosters(self):
+ html = self.load("https://real-debrid.com/api/hosters.php").replace("\"", "").strip()
return [x.strip() for x in html.split(",") if x.strip()]
diff --git a/module/plugins/hooks/RehostToHook.py b/module/plugins/hooks/RehostToHook.py
index a2415129a..7bb27e820 100644
--- a/module/plugins/hooks/RehostToHook.py
+++ b/module/plugins/hooks/RehostToHook.py
@@ -6,22 +6,22 @@ from module.plugins.internal.MultiHook import MultiHook
class RehostToHook(MultiHook):
__name__ = "RehostToHook"
__type__ = "hook"
- __version__ = "0.50"
+ __version__ = "0.51"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Rehost.to hook plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def getHosters(self):
- user, data = self.account.selectAccount()
- html = self.getURL("http://rehost.to/api.php",
+ def get_hosters(self):
+ user, info = self.account.select()
+ html = self.load("http://rehost.to/api.php",
get={'cmd' : "get_supported_och_dl",
- 'long_ses': self.account.getAccountInfo(user)['session']})
+ 'long_ses': self.account.get_data(user)['session']})
return [x.strip() for x in html.replace("\"", "").split(",")]
diff --git a/module/plugins/hooks/RestartFailed.py b/module/plugins/hooks/RestartFailed.py
index 865af2a6b..6c3388e3a 100644
--- a/module/plugins/hooks/RestartFailed.py
+++ b/module/plugins/hooks/RestartFailed.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
-class RestartFailed(Hook):
+class RestartFailed(Addon):
__name__ = "RestartFailed"
__type__ = "hook"
- __version__ = "1.58"
+ __version__ = "1.60"
+ __status__ = "testing"
__config__ = [("interval", "int", "Check interval in minutes", 90)]
@@ -18,28 +19,27 @@ class RestartFailed(Hook):
MIN_CHECK_INTERVAL = 15 * 60 #: 15 minutes
- # def pluginConfigChanged(self, plugin, name, value):
+ # def plugin_config_changed(self, plugin, name, value):
# if name == "interval":
# interval = value * 60
- # if self.MIN_CHECK_INTERVAL <= interval != self.interval:
- # self.core.scheduler.removeJob(self.cb)
+ # if self.MIN_CHECK_INTERVAL <= interval is not self.interval:
+ # self.pyload.scheduler.removeJob(self.cb)
# self.interval = interval
- # self.initPeriodical()
+ # self.init_periodical()
# else:
- # self.logDebug("Invalid interval value, kept current")
+ # self.log_debug("Invalid interval value, kept current")
def periodical(self):
- self.logDebug(_("Restart failed downloads"))
- self.core.api.restartFailed()
+ self.log_debug("Restart failed downloads")
+ self.pyload.api.restartFailed()
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- # self.event_list = ["pluginConfigChanged"]
+ def init(self):
+ # self.event_map = {'pluginConfigChanged': "plugin_config_changed"}
self.interval = self.MIN_CHECK_INTERVAL
- def coreReady(self):
- # self.pluginConfigChanged(self.__name__, "interval", self.getConfig('interval'))
- self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60)
+ def activate(self):
+ # self.plugin_config_changed(self.__name__, "interval", self.get_config('interval'))
+ self.interval = max(self.MIN_CHECK_INTERVAL, self.get_config('interval') * 60)
diff --git a/module/plugins/hooks/SimplyPremiumComHook.py b/module/plugins/hooks/SimplyPremiumComHook.py
index 116e3a76e..6fbd75c8a 100644
--- a/module/plugins/hooks/SimplyPremiumComHook.py
+++ b/module/plugins/hooks/SimplyPremiumComHook.py
@@ -7,21 +7,21 @@ from module.plugins.internal.MultiHook import MultiHook
class SimplyPremiumComHook(MultiHook):
__name__ = "SimplyPremiumComHook"
__type__ = "hook"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Simply-Premium.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("EvolutionClip", "evolutionclip@live.de")]
- def getHosters(self):
- json_data = self.getURL("http://www.simply-premium.com/api/hosts.php", get={'format': "json", 'online': 1})
+ def get_hosters(self):
+ json_data = self.load("http://www.simply-premium.com/api/hosts.php", get={'format': "json", 'online': 1})
json_data = json_loads(json_data)
host_list = [element['regex'] for element in json_data['result']]
diff --git a/module/plugins/hooks/SimplydebridComHook.py b/module/plugins/hooks/SimplydebridComHook.py
index 01629df99..0da7ec719 100644
--- a/module/plugins/hooks/SimplydebridComHook.py
+++ b/module/plugins/hooks/SimplydebridComHook.py
@@ -6,19 +6,19 @@ from module.plugins.internal.MultiHook import MultiHook
class SimplydebridComHook(MultiHook):
__name__ = "SimplydebridComHook"
__type__ = "hook"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Simply-Debrid.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")]
- def getHosters(self):
- html = self.getURL("http://simply-debrid.com/api.php", get={'list': 1})
+ def get_hosters(self):
+ html = self.load("http://simply-debrid.com/api.php", get={'list': 1})
return [x.strip() for x in html.rstrip(';').replace("\"", "").split(";")]
diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py
index 7901ca540..a1ddc3094 100644
--- a/module/plugins/hooks/SkipRev.py
+++ b/module/plugins/hooks/SkipRev.py
@@ -7,14 +7,14 @@ import urlparse
from types import MethodType
from module.PyFile import PyFile
-from module.plugins.Hook import Hook
-from module.plugins.Plugin import SkipDownload
+from module.plugins.internal.Addon import Addon
-class SkipRev(Hook):
+class SkipRev(Addon):
__name__ = "SkipRev"
__type__ = "hook"
- __version__ = "0.29"
+ __version__ = "0.33"
+ __status__ = "testing"
__config__ = [("mode" , "Auto;Manual", "Choose recovery archives to skip" , "Auto"),
("revtokeep", "int" , "Number of recovery archives to keep for package", 0 )]
@@ -24,30 +24,19 @@ class SkipRev(Hook):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
@staticmethod
- def _setup(self):
- self.pyfile.plugin._setup()
+ def _init(self):
+ self.pyfile.plugin._init()
if self.pyfile.hasStatus("skipped"):
- raise SkipDownload(self.pyfile.statusname or self.pyfile.pluginname)
+ self.skip(self.pyfile.statusname or self.pyfile.pluginname)
def _name(self, pyfile):
- if hasattr(pyfile.pluginmodule, "getInfo"): #@NOTE: getInfo is deprecated in 0.4.10
- return pyfile.pluginmodule.getInfo([pyfile.url]).next()[0]
- else:
- self.logWarning("Unable to grab file name")
- return urlparse.urlparse(urllib.unquote(pyfile.url)).path.split('/')[-1]
+ return pyfile.pluginclass.get_info(pyfile.url)['name']
def _pyfile(self, link):
- return PyFile(self.core.files,
+ return PyFile(self.pyload.files,
link.fid,
link.url,
link.name,
@@ -59,47 +48,46 @@ class SkipRev(Hook):
link.order)
- def downloadPreparing(self, pyfile):
+ def download_preparing(self, pyfile):
name = self._name(pyfile)
if pyfile.statusname is _("unskipped") or not name.endswith(".rev") or not ".part" in name:
return
- revtokeep = -1 if self.getConfig('mode') == "Auto" else self.getConfig('revtokeep')
+ revtokeep = -1 if self.get_config('mode') == "Auto" else self.get_config('revtokeep')
if revtokeep:
status_list = (1, 4, 8, 9, 14) if revtokeep < 0 else (1, 3, 4, 8, 9, 14)
pyname = re.compile(r'%s\.part\d+\.rev$' % name.rsplit('.', 2)[0].replace('.', '\.'))
- queued = [True for link in self.core.api.getPackageData(pyfile.package().id).links \
+ queued = [True for link in self.pyload.api.getPackageData(pyfile.package().id).links \
if link.status not in status_list and pyname.match(link.name)].count(True)
- if not queued or queued < revtokeep: #: keep one rev at least in auto mode
+ if not queued or queued < revtokeep: #: Keep one rev at least in auto mode
return
pyfile.setCustomStatus("SkipRev", "skipped")
- if not hasattr(pyfile.plugin, "_setup"):
- # Work-around: inject status checker inside the preprocessing routine of the plugin
- pyfile.plugin._setup = pyfile.plugin.setup
- pyfile.plugin.setup = MethodType(self._setup, pyfile.plugin)
+ if not hasattr(pyfile.plugin, "_init"):
+ #: Work-around: inject status checker inside the preprocessing routine of the plugin
+ pyfile.plugin._init = pyfile.plugin.init
+ pyfile.plugin.init = MethodType(self._init, pyfile.plugin)
- def downloadFailed(self, pyfile):
- #: Check if pyfile is still "failed",
- # maybe might has been restarted in meantime
+ def download_failed(self, pyfile):
+ #: Check if pyfile is still "failed", maybe might has been restarted in meantime
if pyfile.status != 8 or pyfile.name.rsplit('.', 1)[-1].strip() not in ("rar", "rev"):
return
- revtokeep = -1 if self.getConfig('mode') == "Auto" else self.getConfig('revtokeep')
+ revtokeep = -1 if self.get_config('mode') == "Auto" else self.get_config('revtokeep')
if not revtokeep:
return
pyname = re.compile(r'%s\.part\d+\.rev$' % pyfile.name.rsplit('.', 2)[0].replace('.', '\.'))
- for link in self.core.api.getPackageData(pyfile.package().id).links:
- if link.status is 4 and pyname.match(link.name):
+ for link in self.pyload.api.getPackageData(pyfile.package().id).links:
+ if link.status == 4 and pyname.match(link.name):
pylink = self._pyfile(link)
if revtokeep > -1 or pyfile.name.endswith(".rev"):
@@ -107,6 +95,6 @@ class SkipRev(Hook):
else:
pylink.setCustomStatus(_("unskipped"), "queued")
- self.core.files.save()
+ self.pyload.files.save()
pylink.release()
return
diff --git a/module/plugins/hooks/SmoozedComHook.py b/module/plugins/hooks/SmoozedComHook.py
index 24b7c8df0..b9825b223 100644
--- a/module/plugins/hooks/SmoozedComHook.py
+++ b/module/plugins/hooks/SmoozedComHook.py
@@ -6,19 +6,19 @@ from module.plugins.internal.MultiHook import MultiHook
class SmoozedComHook(MultiHook):
__name__ = "SmoozedComHook"
__type__ = "hook"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Smoozed.com hook plugin"""
__license__ = "GPLv3"
__authors__ = [("", "")]
- def getHosters(self):
- user, data = self.account.selectAccount()
- return self.account.getAccountInfo(user)["hosters"]
+ def get_hosters(self):
+ user, info = self.account.select()
+ return self.account.get_data(user)['hosters']
diff --git a/module/plugins/hooks/UnSkipOnFail.py b/module/plugins/hooks/UnSkipOnFail.py
index 9059d0350..d467b8a01 100644
--- a/module/plugins/hooks/UnSkipOnFail.py
+++ b/module/plugins/hooks/UnSkipOnFail.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
from module.PyFile import PyFile
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
-class UnSkipOnFail(Hook):
+class UnSkipOnFail(Addon):
__name__ = "UnSkipOnFail"
__type__ = "hook"
- __version__ = "0.07"
+ __version__ = "0.09"
+ __status__ = "testing"
__config__ = [("activated", "bool", "Activated", True)]
@@ -16,46 +17,38 @@ class UnSkipOnFail(Hook):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
-
- def downloadFailed(self, pyfile):
- #: Check if pyfile is still "failed",
- # maybe might has been restarted in meantime
+ def download_failed(self, pyfile):
+ #: Check if pyfile is still "failed", maybe might has been restarted in meantime
if pyfile.status != 8:
return
msg = _("Looking for skipped duplicates of: %s (pid:%s)")
- self.logInfo(msg % (pyfile.name, pyfile.package().id))
+ self.log_info(msg % (pyfile.name, pyfile.package().id))
- link = self.findDuplicate(pyfile)
+ link = self.find_duplicate(pyfile)
if link:
- self.logInfo(_("Queue found duplicate: %s (pid:%s)") % (link.name, link.packageID))
+ self.log_info(_("Queue found duplicate: %s (pid:%s)") % (link.name, link.packageID))
#: Change status of "link" to "new_status".
- # "link" has to be a valid FileData object,
- # "new_status" has to be a valid status name
- # (i.e. "queued" for this Plugin)
- # It creates a temporary PyFile object using
- # "link" data, changes its status, and tells
- # the core.files-manager to save its data.
+ #: "link" has to be a valid FileData object,
+ #: "new_status" has to be a valid status name
+ #: (i.e. "queued" for this Plugin)
+ #: It creates a temporary PyFile object using
+ #: "link" data, changes its status, and tells
+ #: The pyload.files-manager to save its data.
pylink = self._pyfile(link)
pylink.setCustomStatus(_("unskipped"), "queued")
- self.core.files.save()
+ self.pyload.files.save()
pylink.release()
else:
- self.logInfo(_("No duplicates found"))
+ self.log_info(_("No duplicates found"))
- def findDuplicate(self, pyfile):
- """ Search all packages for duplicate links to "pyfile".
+ def find_duplicate(self, pyfile):
+ """Search all packages for duplicate links to "pyfile".
Duplicates are links that would overwrite "pyfile".
To test on duplicity the package-folder and link-name
of twolinks are compared (link.name).
@@ -64,28 +57,28 @@ class UnSkipOnFail(Hook):
the data for "pyfile" iotselöf.
It does MOT check the link's status.
"""
- queue = self.core.api.getQueue() #: get packages (w/o files, as most file data is useless here)
+ queue = self.pyload.api.getQueue() #: Get packages (w/o files, as most file data is useless here)
for package in queue:
- #: check if package-folder equals pyfile's package folder
- if package.folder != pyfile.package().folder:
+ #: Check if package-folder equals pyfile's package folder
+ if package.folder is not pyfile.package().folder:
continue
- #: now get packaged data w/ files/links
- pdata = self.core.api.getPackageData(package.pid)
+ #: Now get packaged data w/ files/links
+ pdata = self.pyload.api.getPackageData(package.pid)
for link in pdata.links:
- #: check if link is "skipped"
+ #: Check if link == "skipped"
if link.status != 4:
continue
- #: check if link name collides with pdata's name
- #: AND at last check if it is not pyfile itself
- if link.name == pyfile.name and link.fid != pyfile.id:
+ #: Check if link name collides with pdata's name
+ #: and at last check if it is not pyfile itself
+ if link.name is pyfile.name and link.fid is not pyfile.id:
return link
def _pyfile(self, link):
- return PyFile(self.core.files,
+ return PyFile(self.pyload.files,
link.fid,
link.url,
link.name,
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py
index 98d602226..117da0633 100644
--- a/module/plugins/hooks/UpdateManager.py
+++ b/module/plugins/hooks/UpdateManager.py
@@ -2,34 +2,23 @@
from __future__ import with_statement
+import operator
import os
import re
import sys
import time
+import traceback
-from operator import itemgetter
+from module.plugins.internal.Addon import Expose, Addon, threaded
+from module.plugins.internal.Plugin import exists
+from module.utils import fs_encode, save_join as fs_join
-from module.network.RequestFactory import getURL
-from module.plugins.Hook import Expose, Hook, threaded
-from module.utils import save_join
-
-# Case-sensitive os.path.exists
-def exists(path):
- if os.path.exists(path):
- if os.name == 'nt':
- dir, name = os.path.split(path)
- return name in os.listdir(dir)
- else:
- return True
- else:
- return False
-
-
-class UpdateManager(Hook):
+class UpdateManager(Addon):
__name__ = "UpdateManager"
__type__ = "hook"
- __version__ = "0.52"
+ __version__ = "0.55"
+ __status__ = "testing"
__config__ = [("activated" , "bool", "Activated" , True ),
("checkinterval", "int" , "Check interval in hours" , 8 ),
@@ -39,7 +28,7 @@ class UpdateManager(Hook):
("reloadplugins", "bool", "Monitor plugin code changes in debug mode", True ),
("nodebugupdate", "bool", "Don't update plugins in debug mode" , False)]
- __description__ = """ Check for updates """
+ __description__ = """Check for updates"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
@@ -50,26 +39,26 @@ class UpdateManager(Hook):
MIN_CHECK_INTERVAL = 3 * 60 * 60 #: 3 hours
- def coreReady(self):
+ def activate(self):
if self.checkonstart:
- self.core.api.pauseServer()
+ self.pyload.api.pauseServer()
self.update()
if self.do_restart is False:
- self.core.api.unpauseServer()
+ self.pyload.api.unpauseServer()
- self.initPeriodical()
+ self.init_periodical()
- def setup(self):
+ def init(self):
self.info = {'pyload': False, 'version': None, 'plugins': False, 'last_check': time.time()}
- self.mtimes = {} #: store modification time for each plugin
+ self.mtimes = {} #: Store modification time for each plugin
- self.event_list = ["allDownloadsProcessed"]
+ self.event_map = {'allDownloadsProcessed': "all_downloads_processed"}
self.interval = 10
- if self.getConfig('checkonstart'):
- self.core.api.pauseServer()
+ if self.get_config('checkonstart'):
+ self.pyload.api.pauseServer()
self.checkonstart = True
else:
self.checkonstart = False
@@ -77,32 +66,43 @@ class UpdateManager(Hook):
self.do_restart = False
- def allDownloadsProcessed(self):
+ def all_downloads_processed(self):
if self.do_restart is True:
- self.logWarning(_("Downloads are done, restarting pyLoad to reload the updated plugins"))
- self.core.api.restart()
+ self.log_warning(_("Downloads are done, restarting pyLoad to reload the updated plugins"))
+ self.pyload.api.restart()
def periodical(self):
- if self.core.debug:
- if self.getConfig('reloadplugins'):
- self.autoreloadPlugins()
+ if self.pyload.debug:
+ if self.get_config('reloadplugins'):
+ self.autoreload_plugins()
- if self.getConfig('nodebugupdate'):
+ if self.get_config('nodebugupdate'):
return
- if self.getConfig('checkperiod') \
- and time.time() - max(self.MIN_CHECK_INTERVAL, self.getConfig('checkinterval') * 60 * 60) > self.info['last_check']:
+ if self.get_config('checkperiod') \
+ and time.time() - max(self.MIN_CHECK_INTERVAL, self.get_config('checkinterval') * 60 * 60) > self.info['last_check']:
self.update()
+ #: Deprecated method, use `autoreload_plugins` instead
@Expose
- def autoreloadPlugins(self):
- """ reload and reindex all modified plugins """
+ def autoreloadPlugins(self, *args, **kwargs):
+ """
+ See `autoreload_plugins`
+ """
+ return self.autoreload_plugins(*args, **kwargs)
+
+
+ @Expose
+ def autoreload_plugins(self):
+ """
+ Reload and reindex all modified plugins
+ """
modules = filter(
lambda m: m and (m.__name__.startswith("module.plugins.") or
m.__name__.startswith("userplugins.")) and
- m.__name__.count(".") >= 2, sys.modules.itervalues()
+ m.__name__.count(".") >= 2, sys.modules.values()
)
reloads = []
@@ -110,12 +110,12 @@ class UpdateManager(Hook):
for m in modules:
root, type, name = m.__name__.rsplit(".", 2)
id = (type, name)
- if type in self.core.pluginManager.plugins:
+ if type in self.pyload.pluginManager.plugins:
f = m.__file__.replace(".pyc", ".py")
if not os.path.isfile(f):
continue
- mtime = os.stat(f).st_mtime
+ mtime = os.path.getmtime(f)
if id not in self.mtimes:
self.mtimes[id] = mtime
@@ -123,29 +123,31 @@ class UpdateManager(Hook):
reloads.append(id)
self.mtimes[id] = mtime
- return True if self.core.pluginManager.reloadPlugins(reloads) else False
+ return True if self.pyload.pluginManager.reloadPlugins(reloads) else False
def server_response(self):
try:
- return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines()
+ return self.load(self.SERVER_URL,
+ get={'v': self.pyload.api.getServerVersion()}).splitlines()
except Exception:
- self.logWarning(_("Unable to retrieve server to get updates"))
+ self.log_warning(_("Unable to retrieve server to get updates"))
@Expose
@threaded
def update(self):
- """ check for updates """
-
- if self._update() is 2 and self.getConfig('autorestart'):
- if not self.core.api.statusDownloads():
- self.core.api.restart()
+ """
+ Check for updates
+ """
+ if self._update() == 2 and self.get_config('autorestart'):
+ if not self.pyload.api.statusDownloads():
+ self.pyload.api.restart()
else:
self.do_restart = True
- self.logWarning(_("Downloads are active, will restart once the download is done"))
- self.core.api.pauseServer()
+ self.log_warning(_("Downloads are active, will restart once the download is done"))
+ self.pyload.api.pauseServer()
def _update(self):
@@ -157,30 +159,31 @@ class UpdateManager(Hook):
exitcode = 0
elif data[0] == "None":
- self.logInfo(_("No new pyLoad version available"))
- exitcode = self._updatePlugins(data[1:])
+ self.log_info(_("No new pyLoad version available"))
+ exitcode = self._update_plugins(data[1:])
elif onlyplugin:
exitcode = 0
else:
- self.logInfo(_("*** New pyLoad Version %s available ***") % data[0])
- self.logInfo(_("*** Get it here: https://github.com/pyload/pyload/releases ***"))
+ self.log_info(_("*** New pyLoad Version %s available ***") % data[0])
+ self.log_info(_("*** Get it here: https://github.com/pyload/pyload/releases ***"))
self.info['pyload'] = True
self.info['version'] = data[0]
exitcode = 3
- # Exit codes:
- # -1 = No plugin updated, new pyLoad version available
- # 0 = No plugin updated
- # 1 = Plugins updated
- # 2 = Plugins updated, but restart required
+ #: Exit codes:
+ #: -1 = No plugin updated, new pyLoad version available
+ #: 0 = No plugin updated
+ #: 1 = Plugins updated
+ #: 2 = Plugins updated, but restart required
return exitcode
- def _updatePlugins(self, data):
- """ check for plugin updates """
-
+ def _update_plugins(self, data):
+ """
+ Check for plugin updates
+ """
exitcode = 0
updated = []
@@ -202,7 +205,7 @@ class UpdateManager(Hook):
if blacklist:
type_plugins = [(plugin['type'], plugin['name'].rsplit('.', 1)[0]) for plugin in blacklist]
- # Protect UpdateManager from self-removing
+ #: Protect UpdateManager from self-removing
try:
type_plugins.remove(("hook", "UpdateManager"))
except ValueError:
@@ -210,17 +213,17 @@ class UpdateManager(Hook):
for t, n in type_plugins:
for idx, plugin in enumerate(updatelist):
- if n == plugin['name'] and t == plugin['type']:
+ if n is plugin['name'] and t is plugin['type']:
updatelist.pop(idx)
break
- for t, n in self.removePlugins(sorted(type_plugins)):
- self.logInfo(_("Removed blacklisted plugin: [%(type)s] %(name)s") % {
+ for t, n in self.remove_plugins(sorted(type_plugins)):
+ self.log_info(_("Removed blacklisted plugin: [%(type)s] %(name)s") % {
'type': t,
'name': n,
})
- for plugin in sorted(updatelist, key=itemgetter("type", "name")):
+ for plugin in sorted(updatelist, key=operator.itemgetter("type", "name")):
filename = plugin['name']
prefix = plugin['type']
version = plugin['version']
@@ -236,7 +239,7 @@ class UpdateManager(Hook):
else:
type = prefix
- plugins = getattr(self.core.pluginManager, "%sPlugins" % type)
+ plugins = getattr(self.pyload.pluginManager, "%sPlugins" % type)
oldver = float(plugins[name]['v']) if name in plugins else None
newver = float(version)
@@ -248,62 +251,74 @@ class UpdateManager(Hook):
else:
continue
- self.logInfo(_(msg) % {'type' : type,
+ self.log_info(_(msg) % {'type' : type,
'name' : name,
'oldver': oldver,
'newver': newver})
try:
- content = getURL(url % plugin)
+ content = self.load(url % plugin, decode=False)
m = VERSION.search(content)
if m and m.group(2) == version:
- with open(save_join("userplugins", prefix, filename), "wb") as f:
- f.write(content)
+ with open(fs_join("userplugins", prefix, filename), "wb") as f:
+ f.write(fs_encode(content))
updated.append((prefix, name))
else:
- raise Exception, _("Version mismatch")
+ raise Exception(_("Version mismatch"))
except Exception, e:
- self.logError(_("Error updating plugin: %s") % filename, e)
+ self.log_error(_("Error updating plugin: %s") % filename, e)
+ if self.pyload.debug:
+ traceback.print_exc()
if updated:
- self.logInfo(_("*** Plugins updated ***"))
+ self.log_info(_("*** Plugins updated ***"))
- if self.core.pluginManager.reloadPlugins(updated):
+ if self.pyload.pluginManager.reloadPlugins(updated):
exitcode = 1
else:
- self.logWarning(_("pyLoad restart required to reload the updated plugins"))
+ self.log_warning(_("pyLoad restart required to reload the updated plugins"))
self.info['plugins'] = True
exitcode = 2
self.manager.dispatchEvent("plugin_updated", updated)
else:
- self.logInfo(_("No plugin updates available"))
+ self.log_info(_("No plugin updates available"))
- # Exit codes:
- # 0 = No plugin updated
- # 1 = Plugins updated
- # 2 = Plugins updated, but restart required
+ #: Exit codes:
+ #: 0 = No plugin updated
+ #: 1 = Plugins updated
+ #: 2 = Plugins updated, but restart required
return exitcode
+ #: Deprecated method, use `remove_plugins` instead
@Expose
- def removePlugins(self, type_plugins):
- """ delete plugins from disk """
+ def removePlugins(self, *args, **kwargs):
+ """
+ See `remove_plugins`
+ """
+ return self.remove_plugins(*args, **kwargs)
+
+ @Expose
+ def remove_plugins(self, type_plugins):
+ """
+ Delete plugins from disk
+ """
if not type_plugins:
return
removed = set()
- self.logDebug("Requested deletion of plugins: %s" % type_plugins)
+ self.log_debug("Requested deletion of plugins: %s" % type_plugins)
for type, name in type_plugins:
rootplugins = os.path.join(pypath, "module", "plugins")
for dir in ("userplugins", rootplugins):
- py_filename = save_join(dir, type, name + ".py")
+ py_filename = fs_join(dir, type, name + ".py")
pyc_filename = py_filename + "c"
if type == "hook":
@@ -311,7 +326,7 @@ class UpdateManager(Hook):
self.manager.deactivateHook(name)
except Exception, e:
- self.logDebug(e)
+ self.log_debug(e)
for filename in (py_filename, pyc_filename):
if not exists(filename):
@@ -321,10 +336,12 @@ class UpdateManager(Hook):
os.remove(filename)
except OSError, e:
- self.logError(_("Error removing: %s") % filename, e)
+ self.log_warning(_("Error removing: %s") % filename, e)
+ if self.pyload.debug:
+ traceback.print_exc()
else:
id = (type, name)
removed.add(id)
- return list(removed) #: return a list of the plugins successfully removed
+ return list(removed) #: Return a list of the plugins successfully removed
diff --git a/module/plugins/hooks/UserAgentSwitcher.py b/module/plugins/hooks/UserAgentSwitcher.py
index 5f9fd5212..52f542268 100644
--- a/module/plugins/hooks/UserAgentSwitcher.py
+++ b/module/plugins/hooks/UserAgentSwitcher.py
@@ -2,31 +2,37 @@
import pycurl
-from module.plugins.Hook import Hook
+from module.plugins.internal.Addon import Addon
+from module.plugins.internal.Plugin import encode
-class UserAgentSwitcher(Hook):
+class UserAgentSwitcher(Addon):
__name__ = "UserAgentSwitcher"
__type__ = "hook"
- __version__ = "0.07"
+ __version__ = "0.11"
+ __status__ = "testing"
- __config__ = [("activated", "bool", "Activated" , True ),
- ("useragent", "str" , "Custom user-agent string" , "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0")]
+ __config__ = [("activated" , "bool", "Activated" , True ),
+ ("connecttimeout", "int" , "Connection timeout in seconds" , 60 ),
+ ("maxredirs" , "int" , "Maximum number of redirects to follow" , 10 ),
+ ("useragent" , "str" , "Custom user-agent string" , "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0")]
__description__ = """Custom user-agent"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
+ def download_preparing(self, pyfile):
+ connecttimeout = self.get_config('connecttimeout')
+ maxredirs = self.get_config('maxredirs')
+ useragent = self.get_config('useragent')
+ if connecttimeout:
+ pyfile.plugin.req.http.c.setopt(pycurl.CONNECTTIMEOUT, connecttimeout)
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
+ if maxredirs:
+ pyfile.plugin.req.http.c.setopt(pycurl.MAXREDIRS, maxredirs)
-
- def downloadPreparing(self, pyfile):
- useragent = self.getConfig('useragent').encode("utf8", "replace") #@TODO: Remove `encode` in 0.4.10
if useragent:
- self.logDebug("Use custom user-agent string: " + useragent)
- pyfile.plugin.req.http.c.setopt(pycurl.USERAGENT, useragent)
+ self.log_debug("Use custom user-agent string: " + useragent)
+ pyfile.plugin.req.http.c.setopt(pycurl.USERAGENT, encode(useragent))
diff --git a/module/plugins/hooks/WindowsPhoneNotify.py b/module/plugins/hooks/WindowsPhoneNotify.py
index 8f66761f6..900d94a04 100644
--- a/module/plugins/hooks/WindowsPhoneNotify.py
+++ b/module/plugins/hooks/WindowsPhoneNotify.py
@@ -3,13 +3,14 @@
import httplib
import time
-from module.plugins.Hook import Hook, Expose
+from module.plugins.internal.Addon import Addon, Expose
-class WindowsPhoneNotify(Hook):
+class WindowsPhoneNotify(Addon):
__name__ = "WindowsPhoneNotify"
__type__ = "hook"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__config__ = [("push-id" , "str" , "Push ID" , "" ),
("push-url" , "str" , "Push url" , "" ),
@@ -28,62 +29,58 @@ class WindowsPhoneNotify(Hook):
("Walter Purcaro", "vuolter@gmail.com" )]
- interval = 0 #@TODO: Remove in 0.4.10
-
-
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
- self.event_list = ["allDownloadsProcessed", "plugin_updated"]
+ def init(self):
+ self.event_list = ["plugin_updated"]
+ self.event_map = {'allDownloadsProcessed': "all_downloads_processed"}
self.last_notify = 0
self.notifications = 0
def plugin_updated(self, type_plugins):
- if not self.getConfig('notifyupdate'):
+ if not self.get_config('notifyupdate'):
return
self.notify(_("Plugins updated"), str(type_plugins))
- def coreReady(self):
- self.key = (self.getConfig('push-id'), self.getConfig('push-url'))
+ def activate(self):
+ self.key = (self.get_config('push-id'), self.get_config('push-url'))
- def coreExiting(self):
- if not self.getConfig('notifyexit'):
+ def exit(self):
+ if not self.get_config('notifyexit'):
return
- if self.core.do_restart:
+ if self.pyload.do_restart:
self.notify(_("Restarting pyLoad"))
else:
self.notify(_("Exiting pyLoad"))
- def newCaptchaTask(self, task):
- if not self.getConfig('notifycaptcha'):
+ def captcha_task(self, task):
+ if not self.get_config('notifycaptcha'):
return
self.notify(_("Captcha"), _("New request waiting user input"))
- def packageFinished(self, pypack):
- if self.getConfig('notifypackage'):
+ def package_finished(self, pypack):
+ if self.get_config('notifypackage'):
self.notify(_("Package finished"), pypack.name)
- def allDownloadsProcessed(self):
- if not self.getConfig('notifyprocessed'):
+ def all_downloads_processed(self):
+ if not self.get_config('notifyprocessed'):
return
- if any(True for pdata in self.core.api.getQueue() if pdata.linksdone < pdata.linkstotal):
+ if any(True for pdata in self.pyload.api.getQueue() if pdata.linksdone < pdata.linkstotal):
self.notify(_("Package failed"), _("One or more packages was not completed successfully"))
else:
self.notify(_("All packages finished"))
- def getXmlData(self, msg):
+ def get_xml_data(self, msg):
return ("<?xml version='1.0' encoding='utf-8'?> <wp:Notification xmlns:wp='WPNotification'> "
"<wp:Toast> <wp:Text1>pyLoad</wp:Text1> <wp:Text2>%s</wp:Text2> "
"</wp:Toast> </wp:Notification>" % msg)
@@ -99,21 +96,21 @@ class WindowsPhoneNotify(Hook):
if not id or not url:
return
- if self.core.isClientConnected() and not self.getConfig('ignoreclient'):
+ if self.pyload.isClientConnected() and not self.get_config('ignoreclient'):
return
elapsed_time = time.time() - self.last_notify
- if elapsed_time < self.getConf("sendtimewait"):
+ if elapsed_time < self.get_config("sendtimewait"):
return
if elapsed_time > 60:
self.notifications = 0
- elif self.notifications >= self.getConf("sendpermin"):
+ elif self.notifications >= self.get_config("sendpermin"):
return
- request = self.getXmlData("%s: %s" % (event, msg) if msg else event)
+ request = self.get_xml_data("%s: %s" % (event, msg) if msg else event)
webservice = httplib.HTTP(url)
webservice.putrequest("POST", id)
diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py
index 92d89dc01..7567a31a3 100644
--- a/module/plugins/hooks/XFileSharingPro.py
+++ b/module/plugins/hooks/XFileSharingPro.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Hook import Hook
+from module.plugins.internal.Hook import Hook
class XFileSharingPro(Hook):
__name__ = "XFileSharingPro"
__type__ = "hook"
- __version__ = "0.38"
+ __version__ = "0.42"
+ __status__ = "testing"
__config__ = [("activated" , "bool", "Activated" , True ),
("use_hoster_list" , "bool", "Load listed hosters only" , False),
@@ -22,50 +23,51 @@ class XFileSharingPro(Hook):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- interval = 0 #@TODO: Remove in 0.4.10
regexp = {'hoster' : (r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)',
r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:embed-)?\w+'),
'crypter': (r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:user|folder)s?/\w+',
r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:user|folder)s?/\w+')}
HOSTER_BUILTIN = [#WORKING HOSTERS:
- "backin.net", "eyesfile.ca", "file4safe.com", "fileband.com", "filedwon.com", "fileparadox.in",
- "filevice.com", "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com", "ryushare.com",
- "salefiles.com", "sendmyway.com", "sharesix.com", "thefile.me", "verzend.be", "xvidstage.com",
- #NOT TESTED:
- "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com", "linkzhost.com", "mightyupload.com",
- "rockdizfile.com", "sharebeast.com", "sharerepo.com", "shareswift.com", "uploadbaz.com", "uploadc.com",
- "vidbull.com", "worldbytez.com", "zalaa.com", "zomgupload.com",
- #NOT WORKING:
+ "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", "file4safe.com",
+ "fileband.com", "filedwon.com", "fileparadox.in", "filevice.com",
+ "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com",
+ "ryushare.com", "salefiles.com", "sendmyway.com", "sharebeast.com",
+ "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", "xvidstage.com",
+ #: NOT TESTED:
+ "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com",
+ "linkzhost.com", "mightyupload.com", "rockdizfile.com", "sharerepo.com",
+ "shareswift.com", "uploadbaz.com", "uploadc.com", "vidbull.com",
+ "zalaa.com", "zomgupload.com",
+ #: NOT WORKING:
"amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"]
CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"]
- # def pluginConfigChanged(self, plugin, name, value):
- # self.loadPattern()
+ # def plugin_config_changed(self, plugin, name, value):
+ # self.load_pattern()
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
- # self.event_list = ["pluginConfigChanged"]
+ # def init(self):
+ # self.event_map = {'pluginConfigChanged': "plugin_config_changed"}
- def coreReady(self):
- self.loadPattern()
+ def activate(self):
+ self.load_pattern()
- def loadPattern(self):
- use_builtin_list = self.getConfig('use_builtin_list')
+ def load_pattern(self):
+ use_builtin_list = self.get_config('use_builtin_list')
for type, plugin in (("hoster", "XFileSharingPro"),
("crypter", "XFileSharingProFolder")):
- every_plugin = not self.getConfig("use_%s_list" % type)
+ every_plugin = not self.get_config("use_%s_list" % type)
if every_plugin:
- self.logInfo(_("Handling any %s I can!") % type)
+ self.log_info(_("Handling any %s I can!") % type)
pattern = self.regexp[type][0]
else:
- plugins = self.getConfig('%s_list' % type)
+ plugins = self.get_config('%s_list' % type)
plugin_set = set(plugins.replace(' ', '').replace('\\', '').replace('|', ',').replace(';', ',').lower().split(','))
if use_builtin_list:
@@ -74,42 +76,42 @@ class XFileSharingPro(Hook):
plugin_set -= set(('', u''))
if not plugin_set:
- self.logInfo(_("No %s to handle") % type)
+ self.log_info(_("No %s to handle") % type)
self._unload(type, plugin)
return
match_list = '|'.join(sorted(plugin_set))
len_match_list = len(plugin_set)
- self.logInfo(_("Handling %d %s%s: %s") % (len_match_list,
+ self.log_info(_("Handling %d %s%s: %s") % (len_match_list,
type,
"" if len_match_list == 1 else "s",
match_list.replace('|', ', ')))
pattern = self.regexp[type][1] % match_list.replace('.', '\.')
- dict = self.core.pluginManager.plugins[type][plugin]
+ dict = self.pyload.pluginManager.plugins[type][plugin]
dict['pattern'] = pattern
dict['re'] = re.compile(pattern)
- self.logDebug("Loaded %s pattern: %s" % (type, pattern))
+ self.log_debug("Loaded %s pattern: %s" % (type, pattern))
def _unload(self, type, plugin):
- dict = self.core.pluginManager.plugins[type][plugin]
+ dict = self.pyload.pluginManager.plugins[type][plugin]
dict['pattern'] = r'^unmatchable$'
dict['re'] = re.compile(dict['pattern'])
- def unload(self):
- # self.unloadHoster("BasePlugin")
+ def deactivate(self):
+ # self.unload_hoster("BasePlugin")
for type, plugin in (("hoster", "XFileSharingPro"),
("crypter", "XFileSharingProFolder")):
self._unload(type, plugin)
- def unloadHoster(self, hoster):
- hdict = self.core.pluginManager.hosterPlugins[hoster]
+ def unload_hoster(self, hoster):
+ hdict = self.pyload.pluginManager.hosterPlugins[hoster]
if "new_name" in hdict and hdict['new_name'] == "XFileSharingPro":
if "module" in hdict:
hdict.pop('module', None)
@@ -123,10 +125,10 @@ class XFileSharingPro(Hook):
return False
- # def downloadFailed(self, pyfile):
+ # def download_failed(self, pyfile):
# if pyfile.pluginname == "BasePlugin" \
# and pyfile.hasStatus("failed") \
- # and not self.getConfig('use_hoster_list') \
- # and self.unloadHoster("BasePlugin"):
- # self.logDebug("Unloaded XFileSharingPro from BasePlugin")
+ # and not self.get_config('use_hoster_list') \
+ # and self.unload_hoster("BasePlugin"):
+ # self.log_debug("Unloaded XFileSharingPro from BasePlugin")
# pyfile.setStatus("queued")
diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py
index b61428392..50dd40774 100644
--- a/module/plugins/hooks/XMPPInterface.py
+++ b/module/plugins/hooks/XMPPInterface.py
@@ -12,15 +12,16 @@ from module.plugins.hooks.IRCInterface import IRCInterface
class XMPPInterface(IRCInterface, JabberClient):
__name__ = "XMPPInterface"
__type__ = "hook"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
- __config__ = [("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"),
- ("pw", "str", "Password", ""),
- ("tls", "bool", "Use TLS", False),
- ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"),
- ("info_file", "bool", "Inform about every file finished", False),
- ("info_pack", "bool", "Inform about every package finished", True),
- ("captcha", "bool", "Send captcha requests", True)]
+ __config__ = [("jid" , "str" , "Jabber ID" , "user@exmaple-jabber-server.org" ),
+ ("pw" , "str" , "Password" , "" ),
+ ("tls" , "bool", "Use TLS" , False ),
+ ("owners" , "str" , "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"),
+ ("info_file", "bool", "Inform about every file finished" , False ),
+ ("info_pack", "bool", "Inform about every package finished" , True ),
+ ("captcha" , "bool", "Send captcha requests" , True )]
__description__ = """Connect to jabber and let owner perform different tasks"""
__license__ = "GPLv3"
@@ -33,22 +34,22 @@ class XMPPInterface(IRCInterface, JabberClient):
def __init__(self, core, manager):
IRCInterface.__init__(self, core, manager)
- self.jid = JID(self.getConfig('jid'))
- password = self.getConfig('pw')
+ self.jid = JID(self.get_config('jid'))
+ password = self.get_config('pw')
- # if bare JID is provided add a resource -- it is required
+ #: If bare JID is provided add a resource -- it is required
if not self.jid.resource:
self.jid = JID(self.jid.node, self.jid.domain, "pyLoad")
- if self.getConfig('tls'):
+ if self.get_config('tls'):
tls_settings = streamtls.TLSSettings(require=True, verify_peer=False)
auth = ("sasl:PLAIN", "sasl:DIGEST-MD5")
else:
tls_settings = None
auth = ("sasl:DIGEST-MD5", "digest")
- # setup client with provided connection information
- # and identity data
+ #: Setup client with provided connection information
+ #: And identity data
JabberClient.__init__(self, self.jid, password,
disco_name="pyLoad XMPP Client", disco_type="bot",
tls_settings=tls_settings, auth_methods=auth)
@@ -59,75 +60,81 @@ class XMPPInterface(IRCInterface, JabberClient):
]
- def coreReady(self):
+ def activate(self):
self.new_package = {}
self.start()
- def packageFinished(self, pypack):
+ def package_finished(self, pypack):
try:
- if self.getConfig('info_pack'):
+ if self.get_config('info_pack'):
self.announce(_("Package finished: %s") % pypack.name)
except Exception:
pass
- def downloadFinished(self, pyfile):
+ def download_finished(self, pyfile):
try:
- if self.getConfig('info_file'):
+ if self.get_config('info_file'):
self.announce(
- _("Download finished: %(name)s @ %(plugin)s") % {"name": pyfile.name, "plugin": pyfile.pluginname})
+ _("Download finished: %(name)s @ %(plugin)s") % {'name': pyfile.name, 'plugin': pyfile.pluginname})
except Exception:
pass
def run(self):
- # connect to IRC etc.
+ #: Connect to IRC etc.
self.connect()
try:
self.loop()
except Exception, ex:
- self.logError(ex)
+ self.log_error(ex)
def stream_state_changed(self, state, arg):
- """This one is called when the state of stream connecting the component
+ """
+ This one is called when the state of stream connecting the component
to a server changes. This will usually be used to let the user
- know what is going on."""
- self.logDebug("*** State changed: %s %r ***" % (state, arg))
+ know what is going on.
+ """
+ self.log_debug("*** State changed: %s %r ***" % (state, arg))
def disconnected(self):
- self.logDebug("Client was disconnected")
+ self.log_debug("Client was disconnected")
def stream_closed(self, stream):
- self.logDebug("Stream was closed", stream)
+ self.log_debug("Stream was closed", stream)
def stream_error(self, err):
- self.logDebug("Stream Error", err)
+ self.log_debug("Stream Error", err)
def get_message_handlers(self):
- """Return list of (message_type, message_handler) tuples.
+ """
+ Return list of (message_type, message_handler) tuples.
The handlers returned will be called when matching message is received
- in a client session."""
+ in a client session.
+ """
return [("normal", self.message)]
def message(self, stanza):
- """Message handler for the component."""
+ """
+ Message handler for the component.
+ """
subject = stanza.get_subject()
body = stanza.get_body()
t = stanza.get_type()
- self.logDebug("Message from %s received." % unicode(stanza.get_from()))
- self.logDebug("Body: %s Subject: %s Type: %s" % (body, subject, t))
+ self.log_debug("Message from %s received." % stanza.get_from())
+ self.log_debug("Body: %s Subject: %s Type: %s" % (body, subject, t))
if t == "headline":
- # 'headline' messages should never be replied to
+ #: 'headline' messages should never be replied to
return True
if subject:
subject = u"Re: " + subject
@@ -135,11 +142,11 @@ class XMPPInterface(IRCInterface, JabberClient):
to_jid = stanza.get_from()
from_jid = stanza.get_to()
- #j = JID()
+ # j = JID()
to_name = to_jid.as_utf8()
from_name = from_jid.as_utf8()
- names = self.getConfig('owners').split(";")
+ names = self.get_config('owners').split(";")
if to_name in names or to_jid.node + "@" + to_jid.domain in names:
messages = []
@@ -168,7 +175,7 @@ class XMPPInterface(IRCInterface, JabberClient):
messages.append(m)
except Exception, e:
- self.logError(e)
+ self.log_error(e)
return messages
@@ -181,9 +188,11 @@ class XMPPInterface(IRCInterface, JabberClient):
def announce(self, message):
- """ send message to all owners"""
- for user in self.getConfig('owners').split(";"):
- self.logDebug("Send message to", user)
+ """
+ Send message to all owners
+ """
+ for user in self.get_config('owners').split(";"):
+ self.log_debug("Send message to", user)
to_jid = JID(user)
@@ -200,51 +209,62 @@ class XMPPInterface(IRCInterface, JabberClient):
stream.send(m)
- def beforeReconnecting(self, ip):
+ def before_reconnect(self, ip):
self.disconnect()
- def afterReconnecting(self, ip):
+ def after_reconnect(self, ip):
self.connect()
class VersionHandler(object):
- """Provides handler for a version query.
+ """
+ Provides handler for a version query.
This class will answer version query and announce 'jabber:iq:version' namespace
- in the client's disco#info results."""
-
+ in the client's disco#info results.
+ """
implements(IIqHandlersProvider, IFeaturesProvider)
def __init__(self, client):
- """Just remember who created this."""
+ """
+ Just remember who created this.
+ """
self.client = client
def get_features(self):
- """Return namespace which should the client include in its reply to a
- disco#info query."""
+ """
+ Return namespace which should the client include in its reply to a
+ disco#info query.
+ """
return ["jabber:iq:version"]
def get_iq_get_handlers(self):
- """Return list of tuples (element_name, namespace, handler) describing
- handlers of <iq type='get'/> stanzas"""
+ """
+ Return list of tuples (element_name, namespace, handler) describing
+ handlers of <iq type='get'/> stanzas
+ """
return [("query", "jabber:iq:version", self.get_version)]
def get_iq_set_handlers(self):
- """Return empty list, as this class provides no <iq type='set'/> stanza handler."""
+ """
+ Return empty list, as this class provides no <iq type='set'/> stanza handler.
+ """
return []
def get_version(self, iq):
- """Handler for jabber:iq:version queries.
+ """
+ Handler for jabber:iq:version queries.
jabber:iq:version queries are not supported directly by PyXMPP, so the
XML node is accessed directly through the libxml2 API. This should be
- used very carefully!"""
+ used very carefully!
+ """
iq = iq.make_result_response()
q = iq.new_query("jabber:iq:version")
q.newTextChild(q.ns(), "name", "Echo component")
diff --git a/module/plugins/hooks/ZeveraComHook.py b/module/plugins/hooks/ZeveraComHook.py
index 21c1741d2..395c67802 100644
--- a/module/plugins/hooks/ZeveraComHook.py
+++ b/module/plugins/hooks/ZeveraComHook.py
@@ -6,13 +6,13 @@ from module.plugins.internal.MultiHook import MultiHook
class ZeveraComHook(MultiHook):
__name__ = "ZeveraComHook"
__type__ = "hook"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
- __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
- ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ),
- ("revertfailed" , "bool" , "Revert to standard download if fails", True ),
- ("reload" , "bool" , "Reload plugin list" , True ),
- ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
+ __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
+ ("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
+ ("reload" , "bool" , "Reload plugin list" , True ),
+ ("reloadinterval", "int" , "Reload interval in hours" , 12 )]
__description__ = """Zevera.com hook plugin"""
__license__ = "GPLv3"
@@ -20,6 +20,6 @@ class ZeveraComHook(MultiHook):
("Walter Purcaro", "vuolter@gmail.com" )]
- def getHosters(self):
+ def get_hosters(self):
html = self.account.api_response(pyreq.getHTTPRequest(timeout=120), cmd="gethosters")
return [x.strip() for x in html.split(",")]
diff --git a/module/plugins/hoster/AlldebridCom.py b/module/plugins/hoster/AlldebridCom.py
index 2ed09f58c..753712d5c 100644
--- a/module/plugins/hoster/AlldebridCom.py
+++ b/module/plugins/hoster/AlldebridCom.py
@@ -5,16 +5,18 @@ import urllib
from module.common.json_layer import json_loads
from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
-from module.utils import parseFileSize
+from module.utils import parseFileSize as parse_size
class AlldebridCom(MultiHoster):
__name__ = "AlldebridCom"
__type__ = "hoster"
- __version__ = "0.46"
+ __version__ = "0.48"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.|s\d+\.)?alldebrid\.com/dl/[\w^_]+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Alldebrid.com multi-hoster plugin"""
__license__ = "GPLv3"
@@ -22,33 +24,28 @@ class AlldebridCom(MultiHoster):
def setup(self):
- self.chunkLimit = 16
+ self.chunk_limit = 16
- def handlePremium(self, pyfile):
- password = self.getPassword()
+ def handle_premium(self, pyfile):
+ password = self.get_password()
data = json_loads(self.load("http://www.alldebrid.com/service.php",
get={'link': pyfile.url, 'json': "true", 'pw': password}))
- self.logDebug("Json data", data)
+ self.log_debug("Json data", data)
if data['error']:
if data['error'] == "This link isn't available on the hoster website.":
self.offline()
else:
- self.logWarning(data['error'])
- self.tempOffline()
+ self.log_warning(data['error'])
+ self.temp_offline()
else:
if pyfile.name and not pyfile.name.endswith('.tmp'):
pyfile.name = data['filename']
- pyfile.size = parseFileSize(data['filesize'])
+ pyfile.size = parse_size(data['filesize'])
self.link = data['link']
- if self.getConfig('ssl'):
- self.link = self.link.replace("http://", "https://")
- else:
- self.link = self.link.replace("https://", "http://")
-
getInfo = create_getInfo(AlldebridCom)
diff --git a/module/plugins/hoster/AndroidfilehostCom.py b/module/plugins/hoster/AndroidfilehostCom.py
index 08005de0f..3fb77f83e 100644
--- a/module/plugins/hoster/AndroidfilehostCom.py
+++ b/module/plugins/hoster/AndroidfilehostCom.py
@@ -11,7 +11,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class AndroidfilehostCom(SimpleHoster):
__name__ = "AndroidfilehostCom"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?androidfilehost\.com/\?fid=\d+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -32,33 +33,31 @@ class AndroidfilehostCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.resumeDownload = True
- self.chunkLimit = 1
+ self.resume_download = True
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
wait = re.search(self.WAIT_PATTERN, self.html)
- self.logDebug("Waiting time: %s seconds" % wait.group(1))
+ self.log_debug("Waiting time: %s seconds" % wait.group(1))
fid = re.search(r'id="fid" value="(\d+)" />', self.html).group(1)
- self.logDebug("fid: %s" % fid)
+ self.log_debug("fid: %s" % fid)
html = self.load("https://www.androidfilehost.com/libs/otf/mirrors.otf.php",
post={'submit': 'submit',
'action': 'getdownloadmirrors',
- 'fid' : fid},
- decode=True)
+ 'fid' : fid})
self.link = re.findall('"url":"(.*?)"', html)[0].replace("\\", "")
mirror_host = self.link.split("/")[2]
- self.logDebug("Mirror Host: %s" % mirror_host)
+ self.log_debug("Mirror Host: %s" % mirror_host)
html = self.load("https://www.androidfilehost.com/libs/otf/stats.otf.php",
get={'fid' : fid,
'w' : 'download',
- 'mirror': mirror_host},
- decode=True)
+ 'mirror': mirror_host})
getInfo = create_getInfo(AndroidfilehostCom)
diff --git a/module/plugins/hoster/BasePlugin.py b/module/plugins/hoster/BasePlugin.py
index 2228516aa..2e9ae4e48 100644
--- a/module/plugins/hoster/BasePlugin.py
+++ b/module/plugins/hoster/BasePlugin.py
@@ -5,14 +5,15 @@ import urllib
import urlparse
from module.network.HTTPRequest import BadHeader
-from module.plugins.internal.SimpleHoster import create_getInfo, getFileURL
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.SimpleHoster import create_getInfo
+from module.plugins.internal.Hoster import Hoster
class BasePlugin(Hoster):
__name__ = "BasePlugin"
__type__ = "hoster"
- __version__ = "0.43"
+ __version__ = "0.45"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
@@ -23,7 +24,7 @@ class BasePlugin(Hoster):
@classmethod
- def getInfo(cls, url="", html=""): #@TODO: Move to hoster class in 0.4.10
+ def get_info(cls, url="", html=""): #@TODO: Move to hoster class in 0.4.10
url = urllib.unquote(url)
url_p = urlparse.urlparse(url)
return {'name' : (url_p.path.split('/')[-1]
@@ -35,22 +36,23 @@ class BasePlugin(Hoster):
def setup(self):
- self.chunkLimit = -1
+ self.chunk_limit = -1
self.multiDL = True
- self.resumeDownload = True
+ self.resume_download = True
def process(self, pyfile):
- """main function"""
-
- pyfile.name = self.getInfo(pyfile.url)['name']
+ """
+ Main function
+ """
+ pyfile.name = self.get_info(pyfile.url)['name']
if not pyfile.url.startswith("http"):
self.fail(_("No plugin matched"))
for _i in xrange(5):
try:
- link = getFileURL(self, urllib.unquote(pyfile.url))
+ link = self.direct_link(urllib.unquote(pyfile.url))
if link:
self.download(link, ref=False, disposition=True)
@@ -58,21 +60,21 @@ class BasePlugin(Hoster):
self.fail(_("File not found"))
except BadHeader, e:
- if e.code is 404:
+ if e.code == 404:
self.offline()
elif e.code in (401, 403):
- self.logDebug("Auth required", "Received HTTP status code: %d" % e.code)
+ self.log_debug("Auth required", "Received HTTP status code: %d" % e.code)
- account = self.core.accountManager.getAccountPlugin('Http')
- servers = [x['login'] for x in account.getAllAccounts()]
+ account = self.pyload.accountManager.getAccountPlugin('Http')
+ servers = [x['login'] for x in account.getAllAccounts()] #@TODO: Recheck in 0.4.10
server = urlparse.urlparse(pyfile.url).netloc
if server in servers:
- self.logDebug("Logging on to %s" % server)
- self.req.addAuth(account.getAccountData(server)['password'])
+ self.log_debug("Logging on to %s" % server)
+ self.req.addAuth(account.get_info(server)['login']['password'])
else:
- pwd = self.getPassword()
+ pwd = self.get_password()
if ':' in pwd:
self.req.addAuth(pwd)
else:
@@ -84,7 +86,7 @@ class BasePlugin(Hoster):
else:
self.fail(_("No file downloaded")) #@TODO: Move to hoster class in 0.4.10
- errmsg = self.checkDownload({'Empty file' : re.compile(r'\A\s*\Z'),
+ errmsg = self.check_download({'Empty file' : re.compile(r'\A\s*\Z'),
'Html error' : re.compile(r'\A(?:\s*<.+>)?((?:[\w\s]*(?:[Ee]rror|ERROR)\s*\:?)?\s*\d{3})(?:\Z|\s+)'),
'Html file' : re.compile(r'\A\s*<!DOCTYPE html'),
'Request error': re.compile(r'([Aa]n error occured while processing your request)')})
@@ -92,11 +94,11 @@ class BasePlugin(Hoster):
return
try:
- errmsg += " | " + self.lastCheck.group(1).strip()
+ errmsg += " | " + self.last_check.group(1).strip()
except Exception:
pass
- self.logWarning("Check result: " + errmsg, "Waiting 1 minute and retry")
+ self.log_warning(_("Check result: ") + errmsg, _("Waiting 1 minute and retry"))
self.retry(3, 60, errmsg)
diff --git a/module/plugins/hoster/BasketbuildCom.py b/module/plugins/hoster/BasketbuildCom.py
index 89e4d39f9..9bbd0ea60 100644
--- a/module/plugins/hoster/BasketbuildCom.py
+++ b/module/plugins/hoster/BasketbuildCom.py
@@ -12,12 +12,13 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class BasketbuildCom(SimpleHoster):
__name__ = "BasketbuildCom"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(?:\w\.)?basketbuild\.com/filedl/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
- __description__ = """basketbuild.com hoster plugin"""
+ __description__ = """Basketbuild.com hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")]
@@ -29,11 +30,11 @@ class BasketbuildCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.resumeDownload = True
- self.chunkLimit = 1
+ self.resume_download = True
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
try:
link1 = re.search(r'href="(.+dlgate/.+)"', self.html).group(1)
self.html = self.load(link1)
@@ -42,15 +43,15 @@ class BasketbuildCom(SimpleHoster):
self.error(_("Hop #1 not found"))
else:
- self.logDebug("Next hop: %s" % link1)
+ self.log_debug("Next hop: %s" % link1)
try:
wait = re.search(r'var sec = (\d+)', self.html).group(1)
- self.logDebug("Wait %s seconds" % wait)
+ self.log_debug("Wait %s seconds" % wait)
self.wait(wait)
except AttributeError:
- self.logDebug("No wait time found")
+ self.log_debug("No wait time found")
try:
self.link = re.search(r'id="dlLink">\s*<a href="(.+?)"', self.html).group(1)
diff --git a/module/plugins/hoster/BayfilesCom.py b/module/plugins/hoster/BayfilesCom.py
index cccd4acc7..6e9397d4f 100644
--- a/module/plugins/hoster/BayfilesCom.py
+++ b/module/plugins/hoster/BayfilesCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class BayfilesCom(DeadHoster):
__name__ = "BayfilesCom"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?bayfiles\.(com|net)/file/(?P<ID>\w+/\w+/[^/]+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/BezvadataCz.py b/module/plugins/hoster/BezvadataCz.py
index b47c2902d..d2af8272a 100644
--- a/module/plugins/hoster/BezvadataCz.py
+++ b/module/plugins/hoster/BezvadataCz.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class BezvadataCz(SimpleHoster):
__name__ = "BezvadataCz"
__type__ = "hoster"
- __version__ = "0.27"
+ __version__ = "0.29"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?bezvadata\.cz/stahnout/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -24,22 +25,22 @@ class BezvadataCz(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
- #download button
+ def handle_free(self, pyfile):
+ #: Download button
m = re.search(r'<a class="stahnoutSoubor".*?href="(.*?)"', self.html)
if m is None:
self.error(_("Page 1 URL not found"))
url = "http://bezvadata.cz%s" % m.group(1)
- #captcha form
+ #: Captcha form
self.html = self.load(url)
- self.checkErrors()
+ self.check_errors()
for _i in xrange(5):
- action, inputs = self.parseHtmlForm('frm-stahnoutFreeForm')
+ action, inputs = self.parse_html_form('frm-stahnoutFreeForm')
if not inputs:
self.error(_("FreeForm"))
@@ -47,31 +48,26 @@ class BezvadataCz(SimpleHoster):
if m is None:
self.error(_("Wrong captcha image"))
- #captcha image is contained in html page as base64encoded data but decryptCaptcha() expects image url
- self.load, proper_load = self.loadcaptcha, self.load
- try:
- inputs['captcha'] = self.decryptCaptcha(m.group(1), imgtype='png')
- finally:
- self.load = proper_load
+ inputs['captcha'] = self.captcha._decrypt(m.group(1).decode('base64'), input_type='png')
if '<img src="data:image/png;base64' in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
self.fail(_("No valid captcha code entered"))
- #download url
+ #: Download url
self.html = self.load("http://bezvadata.cz%s" % action, post=inputs)
- self.checkErrors()
+ self.check_errors()
m = re.search(r'<a class="stahnoutSoubor2" href="(.*?)">', self.html)
if m is None:
self.error(_("Page 2 URL not found"))
url = "http://bezvadata.cz%s" % m.group(1)
- self.logDebug("DL URL %s" % url)
+ self.log_debug("DL URL %s" % url)
- #countdown
+ #: countdown
m = re.search(r'id="countdown">(\d\d):(\d\d)<', self.html)
wait_time = (int(m.group(1)) * 60 + int(m.group(2))) if m else 120
self.wait(wait_time, False)
@@ -79,17 +75,13 @@ class BezvadataCz(SimpleHoster):
self.link = url
- def checkErrors(self):
+ def check_errors(self):
if 'images/button-download-disable.png' in self.html:
- self.longWait(5 * 60, 24) #: parallel dl limit
+ self.wait(5 * 60, 24, _("Download limit reached")) #: Parallel dl limit
elif '<div class="infobox' in self.html:
- self.tempOffline()
+ self.temp_offline()
else:
- return super(BezvadataCz, self).checkErrors()
-
-
- def loadcaptcha(self, data, *args, **kwargs):
- return data.decode('base64')
+ return super(BezvadataCz, self).check_errors()
getInfo = create_getInfo(BezvadataCz)
diff --git a/module/plugins/hoster/BillionuploadsCom.py b/module/plugins/hoster/BillionuploadsCom.py
index d0fbd7a8b..a142f4ab3 100644
--- a/module/plugins/hoster/BillionuploadsCom.py
+++ b/module/plugins/hoster/BillionuploadsCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class BillionuploadsCom(DeadHoster):
__name__ = "BillionuploadsCom"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?billionuploads\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py
index 5c709e4f7..b975a8ab0 100644
--- a/module/plugins/hoster/BitshareCom.py
+++ b/module/plugins/hoster/BitshareCom.py
@@ -4,14 +4,15 @@ from __future__ import with_statement
import re
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class BitshareCom(SimpleHoster):
__name__ = "BitshareCom"
__type__ = "hoster"
- __version__ = "0.54"
+ __version__ = "0.55"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?bitshare\.com/(files/)?(?(1)|\?f=)(?P<ID>\w+)(?(1)/(?P<NAME>.+?)\.html)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -33,32 +34,32 @@ class BitshareCom(SimpleHoster):
def setup(self):
self.multiDL = self.premium
- self.chunkLimit = 1
+ self.chunk_limit = 1
def process(self, pyfile):
if self.premium:
self.account.relogin(self.user)
- # File id
+ #: File id
m = re.match(self.__pattern__, pyfile.url)
self.file_id = max(m.group('ID1'), m.group('ID2'))
- self.logDebug("File id is [%s]" % self.file_id)
+ self.log_debug("File id is [%s]" % self.file_id)
- # Load main page
- self.html = self.load(pyfile.url, ref=False, decode=True)
+ #: Load main page
+ self.html = self.load(pyfile.url, ref=False)
- # Check offline
+ #: Check offline
if re.search(self.OFFLINE_PATTERN, self.html):
self.offline()
- # Check Traffic used up
+ #: Check Traffic used up
if re.search(self.TRAFFIC_USED_UP, self.html):
- self.logInfo(_("Your Traffic is used up for today"))
+ self.log_info(_("Your Traffic is used up for today"))
self.wait(30 * 60, True)
self.retry()
- # File name
+ #: File name
m = re.match(self.__pattern__, pyfile.url)
name1 = m.group('NAME') if m else None
@@ -67,77 +68,77 @@ class BitshareCom(SimpleHoster):
pyfile.name = max(name1, name2)
- # Ajax file id
+ #: Ajax file id
self.ajaxid = re.search(self.AJAXID_PATTERN, self.html).group(1)
- self.logDebug("File ajax id is [%s]" % self.ajaxid)
+ self.log_debug("File ajax id is [%s]" % self.ajaxid)
- # This may either download our file or forward us to an error page
- self.link = self.getDownloadUrl()
+ #: This may either download our file or forward us to an error page
+ self.link = self.get_download_url()
- if self.checkDownload({"error": ">Error occured<"}):
+ if self.check_download({'error': ">Error occured<"}):
self.retry(5, 5 * 60, "Bitshare host : Error occured")
- def getDownloadUrl(self):
- # Return location if direct download is active
+ def get_download_url(self):
+ #: Return location if direct download is active
if self.premium:
header = self.load(self.pyfile.url, just_header=True)
if 'location' in header:
return header['location']
- # Get download info
- self.logDebug("Getting download info")
+ #: Get download info
+ self.log_debug("Getting download info")
res = self.load("http://bitshare.com/files-ajax/" + self.file_id + "/request.html",
- post={"request": "generateID", "ajaxid": self.ajaxid})
+ post={'request': "generateID", 'ajaxid': self.ajaxid})
- self.handleErrors(res, ':')
+ self.handle_errors(res, ':')
parts = res.split(":")
filetype = parts[0]
wait = int(parts[1])
captcha = int(parts[2])
- self.logDebug("Download info [type: '%s', waiting: %d, captcha: %d]" % (filetype, wait, captcha))
+ self.log_debug("Download info [type: '%s', waiting: %d, captcha: %d]" % (filetype, wait, captcha))
- # Waiting
+ #: Waiting
if wait > 0:
- self.logDebug("Waiting %d seconds." % wait)
+ self.log_debug("Waiting %d seconds." % wait)
if wait < 120:
self.wait(wait, False)
else:
self.wait(wait - 55, True)
self.retry()
- # Resolve captcha
+ #: Resolve captcha
if captcha == 1:
- self.logDebug("File is captcha protected")
+ self.log_debug("File is captcha protected")
recaptcha = ReCaptcha(self)
- # Try up to 3 times
+ #: Try up to 3 times
for i in xrange(3):
response, challenge = recaptcha.challenge()
res = self.load("http://bitshare.com/files-ajax/" + self.file_id + "/request.html",
- post={"request" : "validateCaptcha",
- "ajaxid" : self.ajaxid,
- "recaptcha_challenge_field": challenge,
- "recaptcha_response_field" : response})
- if self.handleCaptchaErrors(res):
+ post={'request' : "validateCaptcha",
+ 'ajaxid' : self.ajaxid,
+ 'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field' : response})
+ if self.handle_captcha_errors(res):
break
- # Get download URL
- self.logDebug("Getting download url")
+ #: Get download URL
+ self.log_debug("Getting download url")
res = self.load("http://bitshare.com/files-ajax/" + self.file_id + "/request.html",
- post={"request": "getDownloadURL", "ajaxid": self.ajaxid})
+ post={'request': "getDownloadURL", 'ajaxid': self.ajaxid})
- self.handleErrors(res, '#')
+ self.handle_errors(res, '#')
url = res.split("#")[-1]
return url
- def handleErrors(self, res, separator):
- self.logDebug("Checking response [%s]" % res)
+ def handle_errors(self, res, separator):
+ self.log_debug("Checking response [%s]" % res)
if "ERROR:Session timed out" in res:
self.retry()
elif "ERROR" in res:
@@ -145,15 +146,15 @@ class BitshareCom(SimpleHoster):
self.fail(msg)
- def handleCaptchaErrors(self, res):
- self.logDebug("Result of captcha resolving [%s]" % res)
+ def handle_captcha_errors(self, res):
+ self.log_debug("Result of captcha resolving [%s]" % res)
if "SUCCESS" in res:
- self.correctCaptcha()
+ self.captcha.correct()
return True
elif "ERROR:SESSION ERROR" in res:
self.retry()
- self.invalidCaptcha()
+ self.captcha.invalid()
getInfo = create_getInfo(BitshareCom)
diff --git a/module/plugins/hoster/BoltsharingCom.py b/module/plugins/hoster/BoltsharingCom.py
index db813ba2e..c33049e01 100644
--- a/module/plugins/hoster/BoltsharingCom.py
+++ b/module/plugins/hoster/BoltsharingCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class BoltsharingCom(DeadHoster):
__name__ = "BoltsharingCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?boltsharing\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/CatShareNet.py b/module/plugins/hoster/CatShareNet.py
index c966dbe1a..5b7d61e05 100644
--- a/module/plugins/hoster/CatShareNet.py
+++ b/module/plugins/hoster/CatShareNet.py
@@ -3,13 +3,14 @@
import re
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
class CatShareNet(SimpleHoster):
__name__ = "CatShareNet"
__type__ = "hoster"
- __version__ = "0.15"
+ __version__ = "0.16"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?catshare\.net/\w{16}'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -21,8 +22,6 @@ class CatShareNet(SimpleHoster):
("Walter Purcaro", "vuolter@gmail.com")]
- TEXT_ENCODING = True
-
INFO_PATTERN = r'<title>(?P<N>.+) \((?P<S>[\d.,]+) (?P<U>[\w^_]+)\)<'
OFFLINE_PATTERN = r'<div class="alert alert-error"'
@@ -35,10 +34,10 @@ class CatShareNet(SimpleHoster):
def setup(self):
self.multiDL = self.premium
- self.resumeDownload = True
+ self.resume_download = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge()
diff --git a/module/plugins/hoster/CloudzerNet.py b/module/plugins/hoster/CloudzerNet.py
index af40b8d5f..fa0bccba3 100644
--- a/module/plugins/hoster/CloudzerNet.py
+++ b/module/plugins/hoster/CloudzerNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class CloudzerNet(DeadHoster):
__name__ = "CloudzerNet"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(cloudzer\.net/file/|clz\.to/(file/)?)\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/CloudzillaTo.py b/module/plugins/hoster/CloudzillaTo.py
index 09453137d..60c66960d 100644
--- a/module/plugins/hoster/CloudzillaTo.py
+++ b/module/plugins/hoster/CloudzillaTo.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class CloudzillaTo(SimpleHoster):
__name__ = "CloudzillaTo"
__type__ = "hoster"
- __version__ = "0.07"
+ __version__ = "0.08"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?cloudzilla\.to/share/file/(?P<ID>[\w^_]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -24,9 +25,9 @@ class CloudzillaTo(SimpleHoster):
PASSWORD_PATTERN = r'<div id="pwd_protected">'
- def checkErrors(self):
+ def check_errors(self):
if re.search(self.PASSWORD_PATTERN, self.html):
- pw = self.getPassword()
+ pw = self.get_password()
if pw:
self.html = self.load(self.pyfile.url, get={'key': pw})
else:
@@ -35,16 +36,16 @@ class CloudzillaTo(SimpleHoster):
if re.search(self.PASSWORD_PATTERN, self.html):
self.retry(reason="Wrong password")
else:
- return super(CloudzillaTo, self).checkErrors()
+ return super(CloudzillaTo, self).check_errors()
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.html = self.load("http://www.cloudzilla.to/generateticket/",
- post={'file_id': self.info['pattern']['ID'], 'key': self.getPassword()})
+ post={'file_id': self.info['pattern']['ID'], 'key': self.get_password()})
ticket = dict(re.findall(r'<(.+?)>([^<>]+?)</', self.html))
- self.logDebug(ticket)
+ self.log_debug(ticket)
if 'error' in ticket:
if "File is password protected" in ticket['error']:
@@ -60,8 +61,8 @@ class CloudzillaTo(SimpleHoster):
'ticket_id': ticket['ticket_id']}
- def handlePremium(self, pyfile):
- return self.handleFree(pyfile)
+ def handle_premium(self, pyfile):
+ return self.handle_free(pyfile)
getInfo = create_getInfo(CloudzillaTo)
diff --git a/module/plugins/hoster/CramitIn.py b/module/plugins/hoster/CramitIn.py
index 44dac958d..f14ae0c71 100644
--- a/module/plugins/hoster/CramitIn.py
+++ b/module/plugins/hoster/CramitIn.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class CramitIn(XFSHoster):
__name__ = "CramitIn"
__type__ = "hoster"
- __version__ = "0.07"
+ __version__ = "0.08"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?cramit\.in/\w{12}'
diff --git a/module/plugins/hoster/CrockoCom.py b/module/plugins/hoster/CrockoCom.py
index 098ba5fab..8f092ad0c 100644
--- a/module/plugins/hoster/CrockoCom.py
+++ b/module/plugins/hoster/CrockoCom.py
@@ -3,14 +3,15 @@
import re
import urlparse
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class CrockoCom(SimpleHoster):
__name__ = "CrockoCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(crocko|easy-share)\.com/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -32,7 +33,7 @@ class CrockoCom(SimpleHoster):
NAME_REPLACEMENTS = [(r'<.*?>', '')]
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if "You need Premium membership to download this file." in self.html:
self.fail(_("You need Premium membership to download this file"))
@@ -57,8 +58,8 @@ class CrockoCom(SimpleHoster):
inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge()
self.download(action, post=inputs)
- if self.checkDownload({"captcha": recaptcha.KEY_AJAX_PATTERN}):
- self.invalidCaptcha()
+ if self.check_download({'captcha': recaptcha.KEY_AJAX_PATTERN}):
+ self.captcha.invalid()
else:
break
else:
diff --git a/module/plugins/hoster/CyberlockerCh.py b/module/plugins/hoster/CyberlockerCh.py
index 9d748bf85..8cb9f7851 100644
--- a/module/plugins/hoster/CyberlockerCh.py
+++ b/module/plugins/hoster/CyberlockerCh.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class CyberlockerCh(DeadHoster):
__name__ = "CyberlockerCh"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?cyberlocker\.ch/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py
index 8f72f2148..3d2de5f7f 100644
--- a/module/plugins/hoster/CzshareCom.py
+++ b/module/plugins/hoster/CzshareCom.py
@@ -6,13 +6,14 @@
import re
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.utils import parseFileSize
+from module.utils import parseFileSize as parse_size
class CzshareCom(SimpleHoster):
__name__ = "CzshareCom"
__type__ = "hoster"
- __version__ = "0.99"
+ __version__ = "1.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(czshare|sdilej)\.(com|cz)/(\d+/|download\.php\?).+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -39,58 +40,58 @@ class CzshareCom(SimpleHoster):
USER_CREDIT_PATTERN = r'<div class="credit">\s*kredit: <strong>([\d .,]+)(\w+)</strong>\s*</div><!-- .credit -->'
- def checkTrafficLeft(self):
- # check if user logged in
+ def check_traffic_left(self):
+ #: Check if user logged in
m = re.search(self.USER_CREDIT_PATTERN, self.html)
if m is None:
self.account.relogin(self.user)
- self.html = self.load(self.pyfile.url, decode=True)
+ self.html = self.load(self.pyfile.url)
m = re.search(self.USER_CREDIT_PATTERN, self.html)
if m is None:
return False
- # check user credit
+ #: Check user credit
try:
- credit = parseFileSize(m.group(1).replace(' ', ''), m.group(2))
- self.logInfo(_("Premium download for %i KiB of Credit") % (self.pyfile.size / 1024))
- self.logInfo(_("User %s has %i KiB left") % (self.user, credit / 1024))
+ credit = parse_size(m.group(1).replace(' ', ''), m.group(2))
+ self.log_info(_("Premium download for %i KiB of Credit") % (self.pyfile.size / 1024))
+ self.log_info(_("User %s has %i KiB left") % (self.user, credit / 1024))
if credit < self.pyfile.size:
- self.logInfo(_("Not enough credit to download file: %s") % self.pyfile.name)
+ self.log_info(_("Not enough credit to download file: %s") % self.pyfile.name)
return False
except Exception, e:
- # let's continue and see what happens...
- self.logError(e)
+ #: let's continue and see what happens...
+ self.log_error(e)
return True
- def handlePremium(self, pyfile):
- # parse download link
+ def handle_premium(self, pyfile):
+ #: Parse download link
try:
form = re.search(self.PREMIUM_FORM_PATTERN, self.html, re.S).group(1)
inputs = dict(re.findall(self.FORM_INPUT_PATTERN, form))
except Exception, e:
- self.logError(e)
- self.resetAccount()
+ self.log_error(e)
+ self.restart(nopremium=True)
- # download the file, destination is determined by pyLoad
+ #: Download the file, destination is determined by pyLoad
self.download("http://sdilej.cz/profi_down.php", post=inputs, disposition=True)
- def handleFree(self, pyfile):
- # get free url
+ def handle_free(self, pyfile):
+ #: Get free url
m = re.search(self.FREE_URL_PATTERN, self.html)
if m is None:
self.error(_("FREE_URL_PATTERN not found"))
parsed_url = "http://sdilej.cz" + m.group(1)
- self.logDebug("PARSED_URL:" + parsed_url)
+ self.log_debug("PARSED_URL:" + parsed_url)
- # get download ticket and parse html
- self.html = self.load(parsed_url, decode=True)
+ #: Get download ticket and parse html
+ self.html = self.load(parsed_url)
if re.search(self.MULTIDL_PATTERN, self.html):
- self.longWait(5 * 60, 12)
+ self.wait(5 * 60, 12, _("Download limit reached"))
try:
form = re.search(self.FREE_FORM_PATTERN, self.html, re.S).group(1)
@@ -98,32 +99,32 @@ class CzshareCom(SimpleHoster):
pyfile.size = int(inputs['size'])
except Exception, e:
- self.logError(e)
+ self.log_error(e)
self.error(_("Form"))
- # get and decrypt captcha
+ #: Get and decrypt captcha
captcha_url = 'http://sdilej.cz/captcha.php'
for _i in xrange(5):
- inputs['captchastring2'] = self.decryptCaptcha(captcha_url)
- self.html = self.load(parsed_url, post=inputs, decode=True)
+ inputs['captchastring2'] = self.captcha.decrypt(captcha_url)
+ self.html = self.load(parsed_url, post=inputs)
if u"<li>ZadanÃœ ověřovací kód nesouhlasí!</li>" in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
elif re.search(self.MULTIDL_PATTERN, self.html):
- self.longWait(5 * 60, 12)
+ self.wait(5 * 60, 12, _("Download limit reached"))
else:
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
self.fail(_("No valid captcha code entered"))
m = re.search("countdown_number = (\d+);", self.html)
- self.setWait(int(m.group(1)) if m else 50)
+ self.set_wait(int(m.group(1)) if m else 50)
- # download the file, destination is determined by pyLoad
- self.logDebug("WAIT URL", self.req.lastEffectiveURL)
+ #: Download the file, destination is determined by pyLoad
+ self.log_debug("WAIT URL", self.req.lastEffectiveURL)
m = re.search("free_wait.php\?server=(.*?)&(.*)", self.req.lastEffectiveURL)
if m is None:
@@ -134,29 +135,29 @@ class CzshareCom(SimpleHoster):
self.wait()
- def checkFile(self, rules={}):
- # check download
- check = self.checkDownload({
+ def check_file(self):
+ #: Check download
+ check = self.check_download({
"temp offline" : re.compile(r"^Soubor je do.*asn.* nedostupn.*$"),
- "credit" : re.compile(r"^Nem.*te dostate.*n.* kredit.$"),
+ 'credit' : re.compile(r"^Nem.*te dostate.*n.* kredit.$"),
"multi-dl" : re.compile(self.MULTIDL_PATTERN),
- "captcha" : "<li>ZadanÃœ ověřovací kód nesouhlasí!</li>"
+ 'captcha' : "<li>ZadanÃœ ověřovací kód nesouhlasí!</li>"
})
if check == "temp offline":
self.fail(_("File not available - try later"))
elif check == "credit":
- self.resetAccount()
+ self.restart(nopremium=True)
elif check == "multi-dl":
- self.longWait(5 * 60, 12)
+ self.wait(5 * 60, 12, _("Download limit reached"))
elif check == "captcha":
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry()
- return super(CzshareCom, self).checkFile(rules)
+ return super(CzshareCom, self).check_file()
getInfo = create_getInfo(CzshareCom)
diff --git a/module/plugins/hoster/DailymotionCom.py b/module/plugins/hoster/DailymotionCom.py
index c6939e5e5..63003dc06 100644
--- a/module/plugins/hoster/DailymotionCom.py
+++ b/module/plugins/hoster/DailymotionCom.py
@@ -4,19 +4,19 @@ import re
from module.PyFile import statusMap
from module.common.json_layer import json_loads
-from module.network.RequestFactory import getURL
-from module.plugins.Hoster import Hoster
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.Hoster import Hoster
-def getInfo(urls):
+def get_info(urls):
result = []
regex = re.compile(DailymotionCom.__pattern__)
apiurl = "https://api.dailymotion.com/video/%s"
- request = {"fields": "access_error,status,title"}
+ request = {'fields': "access_error,status,title"}
for url in urls:
id = regex.match(url).group('ID')
- html = getURL(apiurl % id, get=request)
+ html = get_url(apiurl % id, get=request)
info = json_loads(html)
name = info['title'] + ".mp4" if "title" in info else url
@@ -40,7 +40,8 @@ def getInfo(urls):
class DailymotionCom(Hoster):
__name__ = "DailymotionCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?dailymotion\.com/.*video/(?P<ID>[\w^_]+)'
__config__ = [("quality", "Lowest;LD 144p;LD 240p;SD 384p;HQ 480p;HD 720p;HD 1080p;Highest", "Quality", "Highest")]
@@ -51,11 +52,11 @@ class DailymotionCom(Hoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def getStreams(self):
+ def get_streams(self):
streams = []
for result in re.finditer(r"\"(?P<URL>http:\\/\\/www.dailymotion.com\\/cdn\\/H264-(?P<QF>.*?)\\.*?)\"",
@@ -71,8 +72,8 @@ class DailymotionCom(Hoster):
return sorted(streams, key=lambda x: x[0][::-1])
- def getQuality(self):
- q = self.getConfig('quality')
+ def get_quality(self):
+ q = self.get_config('quality')
if q == "Lowest":
quality = 0
@@ -84,7 +85,7 @@ class DailymotionCom(Hoster):
return quality
- def getLink(self, streams, quality):
+ def get_link(self, streams, quality):
if quality > 0:
for x, s in [item for item in enumerate(streams)][::-1]:
qf = s[0][1]
@@ -98,28 +99,28 @@ class DailymotionCom(Hoster):
s = streams[idx]
- self.logInfo(_("Download video quality %sx%s") % s[0])
+ self.log_info(_("Download video quality %sx%s") % s[0])
return s[1]
- def checkInfo(self, pyfile):
- pyfile.name, pyfile.size, pyfile.status, pyfile.url = getInfo([pyfile.url])[0]
+ def check_info(self, pyfile):
+ pyfile.name, pyfile.size, pyfile.status, pyfile.url = get_info([pyfile.url])[0]
if pyfile.status == 1:
self.offline()
elif pyfile.status == 6:
- self.tempOffline()
+ self.temp_offline()
def process(self, pyfile):
- self.checkInfo(pyfile)
+ self.check_info(pyfile)
id = re.match(self.__pattern__, pyfile.url).group('ID')
- self.html = self.load("http://www.dailymotion.com/embed/video/" + id, decode=True)
+ self.html = self.load("http://www.dailymotion.com/embed/video/" + id)
- streams = self.getStreams()
- quality = self.getQuality()
+ streams = self.get_streams()
+ quality = self.get_quality()
- self.download(self.getLink(streams, quality))
+ self.download(self.get_link(streams, quality))
diff --git a/module/plugins/hoster/DataHu.py b/module/plugins/hoster/DataHu.py
index 955c94437..c0f1e4aa4 100644
--- a/module/plugins/hoster/DataHu.py
+++ b/module/plugins/hoster/DataHu.py
@@ -11,7 +11,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DataHu(SimpleHoster):
__name__ = "DataHu"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?data\.hu/get/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -28,7 +29,7 @@ class DataHu(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = self.premium
diff --git a/module/plugins/hoster/DataportCz.py b/module/plugins/hoster/DataportCz.py
index ad514f5eb..15caae1f7 100644
--- a/module/plugins/hoster/DataportCz.py
+++ b/module/plugins/hoster/DataportCz.py
@@ -6,7 +6,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DataportCz(SimpleHoster):
__name__ = "DataportCz"
__type__ = "hoster"
- __version__ = "0.41"
+ __version__ = "0.42"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?dataport\.cz/file/(.+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -24,12 +25,12 @@ class DataportCz(SimpleHoster):
FREE_SLOTS_PATTERN = ur'Počet volnÜch slotů: <span class="darkblue">(\d+)</span><br />'
- def handleFree(self, pyfile):
- captchas = {"1": "jkeG", "2": "hMJQ", "3": "vmEK", "4": "ePQM", "5": "blBd"}
+ def handle_free(self, pyfile):
+ captchas = {'1': "jkeG", '2': "hMJQ", '3': "vmEK", '4': "ePQM", '5': "blBd"}
for _i in xrange(60):
- action, inputs = self.parseHtmlForm('free_download_form')
- self.logDebug(action, inputs)
+ action, inputs = self.parse_html_form('free_download_form')
+ self.log_debug(action, inputs)
if not action or not inputs:
self.error(_("free_download_form"))
@@ -40,15 +41,15 @@ class DataportCz(SimpleHoster):
self.download("http://www.dataport.cz%s" % action, post=inputs)
- check = self.checkDownload({"captcha": 'alert("\u0160patn\u011b opsan\u00fd k\u00f3d z obr\u00e1zu");',
- "slot" : 'alert("Je n\u00e1m l\u00edto, ale moment\u00e1ln\u011b nejsou'})
+ check = self.check_download({'captcha': 'alert("\u0160patn\u011b opsan\u00fd k\u00f3d z obr\u00e1zu");',
+ 'slot' : 'alert("Je n\u00e1m l\u00edto, ale moment\u00e1ln\u011b nejsou'})
if check == "captcha":
self.error(_("invalid captcha"))
elif check == "slot":
- self.logDebug("No free slots - wait 60s and retry")
+ self.log_debug("No free slots - wait 60s and retry")
self.wait(60, False)
- self.html = self.load(pyfile.url, decode=True)
+ self.html = self.load(pyfile.url)
continue
else:
diff --git a/module/plugins/hoster/DateiTo.py b/module/plugins/hoster/DateiTo.py
index 92a96b9ec..d90fc5864 100644
--- a/module/plugins/hoster/DateiTo.py
+++ b/module/plugins/hoster/DateiTo.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DateiTo(SimpleHoster):
__name__ = "DateiTo"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?datei\.to/datei/(?P<ID>\w+)\.html'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,21 +30,21 @@ class DateiTo(SimpleHoster):
DATA_PATTERN = r'url: "(.*?)", data: "(.*?)",'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
url = 'http://datei.to/ajax/download.php'
data = {'P': 'I', 'ID': self.info['pattern']['ID']}
recaptcha = ReCaptcha(self)
for _i in xrange(10):
- self.logDebug("URL", url, "POST", data)
+ self.log_debug("URL", url, "POST", data)
self.html = self.load(url, post=data)
- self.checkErrors()
+ self.check_errors()
if url.endswith('download.php') and 'P' in data:
- if data['P'] == 'I':
- self.doWait()
+ if data['P'] == "I":
+ self.do_wait()
- elif data['P'] == 'IV':
+ elif data['P'] == "IV":
break
m = re.search(self.DATA_PATTERN, self.html)
@@ -60,7 +61,7 @@ class DateiTo(SimpleHoster):
self.link = self.html
- def doWait(self):
+ def do_wait(self):
m = re.search(self.WAIT_PATTERN, self.html)
wait_time = int(m.group(1)) if m else 30
diff --git a/module/plugins/hoster/DdlstorageCom.py b/module/plugins/hoster/DdlstorageCom.py
index 976d9ccf9..5a826452b 100644
--- a/module/plugins/hoster/DdlstorageCom.py
+++ b/module/plugins/hoster/DdlstorageCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class DdlstorageCom(DeadHoster):
__name__ = "DdlstorageCom"
__type__ = "hoster"
- __version__ = "1.02"
+ __version__ = "1.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?ddlstorage\.com/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/DebridItaliaCom.py b/module/plugins/hoster/DebridItaliaCom.py
index 4f64215fa..7cf7c4663 100644
--- a/module/plugins/hoster/DebridItaliaCom.py
+++ b/module/plugins/hoster/DebridItaliaCom.py
@@ -8,10 +8,12 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class DebridItaliaCom(MultiHoster):
__name__ = "DebridItaliaCom"
__type__ = "hoster"
- __version__ = "0.17"
+ __version__ = "0.19"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.|s\d+\.)?debriditalia\.com/dl/\d+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Debriditalia.com multi-hoster plugin"""
__license__ = "GPLv3"
@@ -22,9 +24,9 @@ class DebridItaliaCom(MultiHoster):
URL_REPLACEMENTS = [("https://", "http://")]
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.html = self.load("http://www.debriditalia.com/api.php",
- get={'generate': "on", 'link': pyfile.url, 'p': self.getPassword()})
+ get={'generate': "on", 'link': pyfile.url, 'p': self.get_password()})
if "ERROR:" not in self.html:
self.link = self.html.strip()
@@ -34,7 +36,7 @@ class DebridItaliaCom(MultiHoster):
self.html = self.load("http://debriditalia.com/linkgen2.php",
post={'xjxfun' : "convertiLink",
'xjxargs[]': "S<![CDATA[%s]]>" % pyfile.url,
- 'xjxargs[]': "S%s" % self.getPassword()})
+ 'xjxargs[]': "S%s" % self.get_password()})
try:
self.link = re.search(r'<a href="(.+?)"', self.html).group(1)
except AttributeError:
diff --git a/module/plugins/hoster/DepositfilesCom.py b/module/plugins/hoster/DepositfilesCom.py
index 18f23f552..9d42935cb 100644
--- a/module/plugins/hoster/DepositfilesCom.py
+++ b/module/plugins/hoster/DepositfilesCom.py
@@ -3,14 +3,15 @@
import re
import urllib
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DepositfilesCom(SimpleHoster):
__name__ = "DepositfilesCom"
__type__ = "hoster"
- __version__ = "0.56"
+ __version__ = "0.57"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(depositfiles\.com|dfiles\.(eu|ru))(/\w{1,3})?/files/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -40,18 +41,18 @@ class DepositfilesCom(SimpleHoster):
LINK_MIRROR_PATTERN = r'class="repeat_mirror"><a href="(.+?)"'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.html = self.load(pyfile.url, post={'gateway_result': "1"})
- self.checkErrors()
+ self.check_errors()
m = re.search(r"var fid = '(\w+)';", self.html)
if m is None:
self.retry(wait_time=5)
params = {'fid': m.group(1)}
- self.logDebug("FID: %s" % params['fid'])
+ self.log_debug("FID: %s" % params['fid'])
- self.checkErrors()
+ self.check_errors()
recaptcha = ReCaptcha(self)
captcha_key = recaptcha.detect_key()
@@ -69,9 +70,9 @@ class DepositfilesCom(SimpleHoster):
self.link = urllib.unquote(m.group(1))
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
if '<span class="html_download_api-gold_traffic_limit">' in self.html:
- self.logWarning(_("Download limit reached"))
+ self.log_warning(_("Download limit reached"))
self.retry(25, 60 * 60, "Download limit reached")
elif 'onClick="show_gold_offer' in self.html:
diff --git a/module/plugins/hoster/DevhostSt.py b/module/plugins/hoster/DevhostSt.py
index e7a23f6b1..d999cdf96 100644
--- a/module/plugins/hoster/DevhostSt.py
+++ b/module/plugins/hoster/DevhostSt.py
@@ -11,12 +11,13 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DevhostSt(SimpleHoster):
__name__ = "DevhostSt"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?d-h\.st/(?!users/)\w{3}'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
- __description__ = """d-h.st hoster plugin"""
+ __description__ = """D-h.st hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")]
@@ -31,7 +32,7 @@ class DevhostSt(SimpleHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
getInfo = create_getInfo(DevhostSt)
diff --git a/module/plugins/hoster/DlFreeFr.py b/module/plugins/hoster/DlFreeFr.py
index 030f7e971..f9d427c1b 100644
--- a/module/plugins/hoster/DlFreeFr.py
+++ b/module/plugins/hoster/DlFreeFr.py
@@ -5,7 +5,6 @@ import re
from module.network.Browser import Browser
from module.network.CookieJar import CookieJar
-from module.plugins.internal.AdYouLike import AdYouLike
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns
@@ -36,7 +35,8 @@ class CustomBrowser(Browser):
class DlFreeFr(SimpleHoster):
__name__ = "DlFreeFr"
__type__ = "hoster"
- __version__ = "0.29"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?dl\.free\.fr/(\w+|getfile\.pl\?file=/\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -44,24 +44,24 @@ class DlFreeFr(SimpleHoster):
__description__ = """Dl.free.fr hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("the-razer", "daniel_ AT gmx DOT net"),
- ("zoidberg", "zoidberg@mujmail.cz"),
- ("Toilal", "toilal.dev@gmail.com")]
+ ("zoidberg" , "zoidberg@mujmail.cz" ),
+ ("Toilal" , "toilal.dev@gmail.com" )]
- NAME_PATTERN = r'Fichier:</td>\s*<td.*?>(?P<N>[^>]*)</td>'
- SIZE_PATTERN = r'Taille:</td>\s*<td.*?>(?P<S>[\d.,]+\w)o'
+ NAME_PATTERN = r'Fichier:</td>\s*<td.*?>(?P<N>[^>]*)</td>'
+ SIZE_PATTERN = r'Taille:</td>\s*<td.*?>(?P<S>[\d.,]+\w)o'
OFFLINE_PATTERN = r'Erreur 404 - Document non trouv|Fichier inexistant|Le fichier demand&eacute; n\'a pas &eacute;t&eacute; trouv&eacute;'
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
self.limitDL = 5
- self.chunkLimit = 1
+ self.chunk_limit = 1
def init(self):
- factory = self.core.requestFactory
+ factory = self.pyload.requestFactory
self.req = CustomBrowser(factory.bucket, factory.getOptions())
@@ -77,13 +77,15 @@ class DlFreeFr(SimpleHoster):
if headers.get('code') == 200:
content_type = headers.get('content-type')
if content_type and content_type.startswith("text/html"):
- # Undirect acces to requested file, with a web page providing it (captcha)
+ #: Undirect acces to requested file, with a web page providing it (captcha)
self.html = self.load(valid_url)
- self.handleFree(pyfile)
+ self.handle_free(pyfile)
else:
- # Direct access to requested file for users using free.fr as Internet Service Provider.
+ #: Direct access to requested file for users using free.fr as Internet Service Provider.
self.link = valid_url
+ self.download(self.link, disposition=True)
+
elif headers.get('code') == 404:
self.offline()
@@ -91,33 +93,27 @@ class DlFreeFr(SimpleHoster):
self.fail(_("Invalid return code: ") + str(headers.get('code')))
- def handleFree(self, pyfile):
- action, inputs = self.parseHtmlForm('action="getfile.pl"')
-
- adyoulike = AdYouLike(self)
- response, challenge = adyoulike.challenge()
- inputs.update(response)
-
+ def handle_free(self, pyfile):
+ action, inputs = self.parse_html_form('action="getfile.pl"')
self.load("http://dl.free.fr/getfile.pl", post=inputs)
- headers = self.getLastHeaders()
+ headers = self.get_last_headers()
if headers.get("code") == 302 and "set-cookie" in headers and "location" in headers:
- m = re.search("(.*?)=(.*?); path=(.*?); domain=(.*?)", headers.get("set-cookie"))
- cj = CookieJar(__name__)
+ m = re.search("(.*?)=(.*?); path=(.*?); domain=(.*)", headers.get("set-cookie"))
+ cj = CookieJar(self.__name__)
if m:
cj.setCookie(m.group(4), m.group(1), m.group(2), m.group(3))
else:
self.fail(_("Cookie error"))
self.link = headers.get("location")
-
self.req.setCookieJar(cj)
else:
self.fail(_("Invalid response"))
- def getLastHeaders(self):
- #parse header
- header = {"code": self.req.code}
+ def get_last_headers(self):
+ #: Parse header
+ header = {'code': self.req.code}
for line in self.req.http.header.splitlines():
line = line.strip()
if not line or ":" not in line:
@@ -128,7 +124,7 @@ class DlFreeFr(SimpleHoster):
value = value.strip()
if key in header:
- if type(header[key]) == list:
+ if type(header[key]) is list:
header[key].append(value)
else:
header[key] = [header[key], value]
diff --git a/module/plugins/hoster/DodanePl.py b/module/plugins/hoster/DodanePl.py
index 46f748cc4..3a2c732d8 100644
--- a/module/plugins/hoster/DodanePl.py
+++ b/module/plugins/hoster/DodanePl.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class DodanePl(DeadHoster):
__name__ = "DodanePl"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?dodane\.pl/file/\d+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/DropboxCom.py b/module/plugins/hoster/DropboxCom.py
index eec968f5a..7c4e952df 100644
--- a/module/plugins/hoster/DropboxCom.py
+++ b/module/plugins/hoster/DropboxCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class DropboxCom(SimpleHoster):
__name__ = "DropboxCom"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?dropbox\.com/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -28,11 +29,11 @@ class DropboxCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
- self.resumeDownload = True
+ self.chunk_limit = 1
+ self.resume_download = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.download(pyfile.url, get={'dl': "1"})
diff --git a/module/plugins/hoster/DuploadOrg.py b/module/plugins/hoster/DuploadOrg.py
index 076171544..124919d91 100644
--- a/module/plugins/hoster/DuploadOrg.py
+++ b/module/plugins/hoster/DuploadOrg.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class DuploadOrg(DeadHoster):
__name__ = "DuploadOrg"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?dupload\.org/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/EasybytezCom.py b/module/plugins/hoster/EasybytezCom.py
index 693910c1b..81b524a20 100644
--- a/module/plugins/hoster/EasybytezCom.py
+++ b/module/plugins/hoster/EasybytezCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class EasybytezCom(XFSHoster):
__name__ = "EasybytezCom"
__type__ = "hoster"
- __version__ = "0.23"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?easybytez\.com/\w{12}'
diff --git a/module/plugins/hoster/EdiskCz.py b/module/plugins/hoster/EdiskCz.py
index b8485001e..3204ec9ad 100644
--- a/module/plugins/hoster/EdiskCz.py
+++ b/module/plugins/hoster/EdiskCz.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class EdiskCz(SimpleHoster):
__name__ = "EdiskCz"
__type__ = "hoster"
- __version__ = "0.23"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?edisk\.(cz|sk|eu)/(stahni|sk/stahni|en/download)/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -32,20 +33,20 @@ class EdiskCz(SimpleHoster):
def process(self, pyfile):
url = re.sub("/(stahni|sk/stahni)/", "/en/download/", pyfile.url)
- self.logDebug("URL:" + url)
+ self.log_debug("URL:" + url)
m = re.search(self.ACTION_PATTERN, url)
if m is None:
self.error(_("ACTION_PATTERN not found"))
action = m.group(1)
- self.html = self.load(url, decode=True)
- self.getFileInfo()
+ self.html = self.load(url)
+ self.get_fileInfo()
self.html = self.load(re.sub("/en/download/", "/en/download-slow/", url))
url = self.load(re.sub("/en/download/", "/x-download/", url), post={
- "action": action
+ 'action': action
})
if not re.match(self.LINK_FREE_PATTERN, url):
diff --git a/module/plugins/hoster/EgoFilesCom.py b/module/plugins/hoster/EgoFilesCom.py
index 78108962f..d91c70fdc 100644
--- a/module/plugins/hoster/EgoFilesCom.py
+++ b/module/plugins/hoster/EgoFilesCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class EgoFilesCom(DeadHoster):
__name__ = "EgoFilesCom"
__type__ = "hoster"
- __version__ = "0.16"
+ __version__ = "0.17"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?egofiles\.com/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/EnteruploadCom.py b/module/plugins/hoster/EnteruploadCom.py
index 8ef994e1e..bc7d2415a 100644
--- a/module/plugins/hoster/EnteruploadCom.py
+++ b/module/plugins/hoster/EnteruploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class EnteruploadCom(DeadHoster):
__name__ = "EnteruploadCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?enterupload\.com/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/EpicShareNet.py b/module/plugins/hoster/EpicShareNet.py
index 7e3c8ba0e..498a43395 100644
--- a/module/plugins/hoster/EpicShareNet.py
+++ b/module/plugins/hoster/EpicShareNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class EpicShareNet(DeadHoster):
__name__ = "EpicShareNet"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?epicshare\.net/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/EuroshareEu.py b/module/plugins/hoster/EuroshareEu.py
index 842e0cb87..53ac9ff06 100644
--- a/module/plugins/hoster/EuroshareEu.py
+++ b/module/plugins/hoster/EuroshareEu.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class EuroshareEu(SimpleHoster):
__name__ = "EuroshareEu"
__type__ = "hoster"
- __version__ = "0.28"
+ __version__ = "0.30"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?euroshare\.(eu|sk|cz|hu|pl)/file/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -23,33 +24,33 @@ class EuroshareEu(SimpleHoster):
LINK_FREE_PATTERN = r'<a href="(/file/\d+/[^/]*/download/)"><div class="downloadButton"'
- ERR_PARDL_PATTERN = r'<h2>Prebieha s.ahovanie</h2>|<p>Naraz je z jednej IP adresy mo.n. s.ahova. iba jeden s.bor'
- ERR_NOT_LOGGED_IN_PATTERN = r'href="/customer-zone/login/"'
+ DL_LIMIT_PATTERN = r'<h2>Prebieha s.ahovanie</h2>|<p>Naraz je z jednej IP adresy mo.n. s.ahova. iba jeden s.bor'
+ ERROR_PATTERN = r'href="/customer-zone/login/"'
URL_REPLACEMENTS = [(r"(http://[^/]*\.)(sk|cz|hu|pl)/", r"\1eu/")]
- def handlePremium(self, pyfile):
- if self.ERR_NOT_LOGGED_IN_PATTERN in self.html:
+ def handle_premium(self, pyfile):
+ if self.ERROR_PATTERN in self.html:
self.account.relogin(self.user)
self.retry(reason=_("User not logged in"))
self.link = pyfile.url.rstrip('/') + "/download/"
- check = self.checkDownload({"login": re.compile(self.ERR_NOT_LOGGED_IN_PATTERN),
- "json" : re.compile(r'\{"status":"error".*?"message":"(.*?)"')})
+ check = self.check_download({'login': re.compile(self.ERROR_PATTERN),
+ 'json' : re.compile(r'\{"status":"error".*?"message":"(.*?)"')})
- if check == "login" or (check == "json" and self.lastCheck.group(1) == "Access token expired"):
+ if check == "login" or (check == "json" and self.last_check.group(1) == "Access token expired"):
self.account.relogin(self.user)
self.retry(reason=_("Access token expired"))
elif check == "json":
- self.fail(self.lastCheck.group(1))
+ self.fail(self.last_check.group(1))
- def handleFree(self, pyfile):
- if re.search(self.ERR_PARDL_PATTERN, self.html):
- self.longWait(5 * 60, 12)
+ def handle_free(self, pyfile):
+ if re.search(self.DL_LIMIT_PATTERN, self.html):
+ self.wait(5 * 60, 12, _("Download limit reached"))
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
@@ -58,11 +59,4 @@ class EuroshareEu(SimpleHoster):
self.link = "http://euroshare.eu%s" % m.group(1)
- def checkFile(self, rules={}):
- if self.checkDownload({"multi-dl": re.compile(self.ERR_PARDL_PATTERN)})
- self.longWait(5 * 60, 12)
-
- return super(EuroshareEu, self).checkFile(rules)
-
-
getInfo = create_getInfo(EuroshareEu)
diff --git a/module/plugins/hoster/ExashareCom.py b/module/plugins/hoster/ExashareCom.py
index d70ca6d3a..19cd1b46c 100644
--- a/module/plugins/hoster/ExashareCom.py
+++ b/module/plugins/hoster/ExashareCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class ExashareCom(XFSHoster):
__name__ = "ExashareCom"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?exashare\.com/\w{12}'
@@ -22,11 +23,11 @@ class ExashareCom(XFSHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
- self.resumeDownload = self.premium
+ self.chunk_limit = 1
+ self.resume_download = self.premium
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("Free download link not found"))
diff --git a/module/plugins/hoster/ExtabitCom.py b/module/plugins/hoster/ExtabitCom.py
index ead2e1e53..3442e7d27 100644
--- a/module/plugins/hoster/ExtabitCom.py
+++ b/module/plugins/hoster/ExtabitCom.py
@@ -4,14 +4,15 @@ import re
from module.common.json_layer import json_loads
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, seconds_to_midnight
class ExtabitCom(SimpleHoster):
__name__ = "ExtabitCom"
__type__ = "hoster"
- __version__ = "0.66"
+ __version__ = "0.67"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?extabit\.com/(file|go|fid)/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,7 +30,7 @@ class ExtabitCom(SimpleHoster):
LINK_FREE_PATTERN = r'[\'"](http://guest\d+\.extabit\.com/\w+/.*?)[\'"]'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if r">Only premium users can download this file" in self.html:
self.fail(_("Only premium users can download this file"))
@@ -37,10 +38,10 @@ class ExtabitCom(SimpleHoster):
if m:
self.wait(int(m.group(1)) * 60, True)
elif "The daily downloads limit from your IP is exceeded" in self.html:
- self.logWarning(_("You have reached your daily downloads limit for today"))
- self.wait(secondsToMidnight(gmt=2), True)
+ self.log_warning(_("You have reached your daily downloads limit for today"))
+ self.wait(seconds_to_midnight(gmt=2), True)
- self.logDebug("URL: " + self.req.http.lastEffectiveURL)
+ self.log_debug("URL: " + self.req.http.lastEffectiveURL)
m = re.match(self.__pattern__, self.req.http.lastEffectiveURL)
fileID = m.group('ID') if m else self.info['pattern']['ID']
@@ -50,14 +51,14 @@ class ExtabitCom(SimpleHoster):
captcha_key = m.group(1)
for _i in xrange(5):
- get_data = {"type": "recaptcha"}
+ get_data = {'type': "recaptcha"}
get_data['capture'], get_data['challenge'] = recaptcha.challenge(captcha_key)
res = json_loads(self.load("http://extabit.com/file/%s/" % fileID, get=get_data))
if "ok" in res:
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
self.fail(_("Invalid captcha"))
else:
diff --git a/module/plugins/hoster/FastixRu.py b/module/plugins/hoster/FastixRu.py
index cc50f4229..0019cf3c2 100644
--- a/module/plugins/hoster/FastixRu.py
+++ b/module/plugins/hoster/FastixRu.py
@@ -10,10 +10,12 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class FastixRu(MultiHoster):
__name__ = "FastixRu"
__type__ = "hoster"
- __version__ = "0.11"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fastix\.(ru|it)/file/\w{24}'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Fastix multi-hoster plugin"""
__license__ = "GPLv3"
@@ -21,11 +23,11 @@ class FastixRu(MultiHoster):
def setup(self):
- self.chunkLimit = 3
+ self.chunk_limit = 3
- def handlePremium(self, pyfile):
- api_key = self.account.getAccountData(self.user)
+ def handle_premium(self, pyfile):
+ api_key = self.account.get_data(self.user)
api_key = api_key['api']
self.html = self.load("http://fastix.ru/api_v2/",
@@ -33,7 +35,7 @@ class FastixRu(MultiHoster):
data = json_loads(self.html)
- self.logDebug("Json data", data)
+ self.log_debug("Json data", data)
if "error\":true" in self.html:
self.offline()
diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py
index 330a6e3b9..485d69d15 100644
--- a/module/plugins/hoster/FastshareCz.py
+++ b/module/plugins/hoster/FastshareCz.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FastshareCz(SimpleHoster):
__name__ = "FastshareCz"
__type__ = "hoster"
- __version__ = "0.29"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fastshare\.cz/\d+/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -33,20 +34,20 @@ class FastshareCz(SimpleHoster):
CREDIT_ERROR = " credit for "
- def checkErrors(self):
+ def check_errors(self):
if self.SLOT_ERROR in self.html:
errmsg = self.info['error'] = _("No free slots")
self.retry(12, 60, errmsg)
if self.CREDIT_ERROR in self.html:
errmsg = self.info['error'] = _("Not enough traffic left")
- self.logWarning(errmsg)
- self.resetAccount()
+ self.log_warning(errmsg)
+ self.restart(nopremium=True)
self.info.pop('error', None)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.FREE_URL_PATTERN, self.html)
if m:
action, captcha_src = m.groups()
@@ -54,12 +55,12 @@ class FastshareCz(SimpleHoster):
self.error(_("FREE_URL_PATTERN not found"))
baseurl = "http://www.fastshare.cz"
- captcha = self.decryptCaptcha(urlparse.urljoin(baseurl, captcha_src))
+ captcha = self.captcha.decrypt(urlparse.urljoin(baseurl, captcha_src))
self.download(urlparse.urljoin(baseurl, action), post={'code': captcha, 'btn.x': 77, 'btn.y': 18})
- def checkFile(self, rules={}):
- check = self.checkDownload({
+ def check_file(self):
+ check = self.check_download({
'paralell-dl' : re.compile(r"<title>FastShare.cz</title>|<script>alert\('Pres FREE muzete stahovat jen jeden soubor najednou.'\)"),
'wrong captcha': re.compile(r'Download for FREE'),
'credit' : re.compile(self.CREDIT_ERROR)
@@ -72,9 +73,9 @@ class FastshareCz(SimpleHoster):
self.retry(max_tries=5, reason=_("Wrong captcha"))
elif check == "credit":
- self.resetAccount()
+ self.restart(nopremium=True)
- return super(FastshareCz, self).checkFile(rules)
+ return super(FastshareCz, self).check_file()
getInfo = create_getInfo(FastshareCz)
diff --git a/module/plugins/hoster/FileApeCom.py b/module/plugins/hoster/FileApeCom.py
index 79157539b..c91024824 100644
--- a/module/plugins/hoster/FileApeCom.py
+++ b/module/plugins/hoster/FileApeCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FileApeCom(DeadHoster):
__name__ = "FileApeCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fileape\.com/(index\.php\?act=download\&id=|dl/)\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FileSharkPl.py b/module/plugins/hoster/FileSharkPl.py
index de030be9c..62a7a553f 100644
--- a/module/plugins/hoster/FileSharkPl.py
+++ b/module/plugins/hoster/FileSharkPl.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FileSharkPl(SimpleHoster):
__name__ = "FileSharkPl"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fileshark\.pl/pobierz/\d+/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -20,7 +21,7 @@ class FileSharkPl(SimpleHoster):
("Walter Purcaro", "vuolter@gmail.com")]
- NAME_PATTERN = r'<h2 class="name-file">(?P<N>.+)</h2>'
+ NAME_PATTERN = r'<h2 class="name-file">(?P<N>.+?)</h2>'
SIZE_PATTERN = r'<p class="size-file">(.*?)<strong>(?P<S>\d+\.?\d*)\s(?P<U>\w+)</strong></p>'
OFFLINE_PATTERN = r'(P|p)lik zosta. (usuni.ty|przeniesiony)'
@@ -37,7 +38,7 @@ class FileSharkPl(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
if self.premium:
self.multiDL = True
@@ -46,8 +47,8 @@ class FileSharkPl(SimpleHoster):
self.multiDL = False
- def checkErrors(self):
- # check if file is now available for download (-> file name can be found in html body)
+ def check_errors(self):
+ #: Check if file is now available for download (-> file name can be found in html body)
m = re.search(self.WAIT_PATTERN, self.html)
if m:
errmsg = self.info['error'] = _("Another download already run")
@@ -62,7 +63,7 @@ class FileSharkPl(SimpleHoster):
elif re.match(self.SLOT_ERROR_PATTERN, alert):
errmsg = self.info['error'] = _("No free download slots available")
- self.logWarning(errmsg)
+ self.log_warning(errmsg)
self.retry(10, 30 * 60, _("Still no free download slots available"))
else:
@@ -72,7 +73,7 @@ class FileSharkPl(SimpleHoster):
self.info.pop('error', None)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("Download url not found"))
@@ -84,10 +85,10 @@ class FileSharkPl(SimpleHoster):
m = re.search(self.WAIT_PATTERN, self.html)
if m:
seconds = int(m.group(1))
- self.logDebug("Wait %s seconds" % seconds)
+ self.log_debug("Wait %s seconds" % seconds)
self.wait(seconds)
- action, inputs = self.parseHtmlForm('action=""')
+ action, inputs = self.parse_html_form('action=""')
m = re.search(self.TOKEN_PATTERN, self.html)
if m is None:
@@ -99,19 +100,10 @@ class FileSharkPl(SimpleHoster):
if m is None:
self.retry(reason=_("Captcha image not found"))
- tmp_load = self.load
- self.load = self._decode64 #: work-around: injects decode64 inside decryptCaptcha
-
- inputs['form[captcha]'] = self.decryptCaptcha(m.group(1), imgtype='jpeg')
+ inputs['form[captcha]'] = self.captcha._decrypt(m.group(1).decode('base64'), input_type='jpeg')
inputs['form[start]'] = ""
- self.load = tmp_load
-
self.download(link, post=inputs, disposition=True)
- def _decode64(self, data, *args, **kwargs):
- return data.decode('base64')
-
-
getInfo = create_getInfo(FileSharkPl)
diff --git a/module/plugins/hoster/FileStoreTo.py b/module/plugins/hoster/FileStoreTo.py
index 3262b73ad..96c1456cb 100644
--- a/module/plugins/hoster/FileStoreTo.py
+++ b/module/plugins/hoster/FileStoreTo.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FileStoreTo(SimpleHoster):
__name__ = "FileStoreTo"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filestore\.to/\?d=(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -25,11 +26,11 @@ class FileStoreTo(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.wait(10)
self.link = self.load("http://filestore.to/ajax/download.php",
get={'D': re.search(r'"D=(\w+)', self.html).group(1)})
diff --git a/module/plugins/hoster/FilebeerInfo.py b/module/plugins/hoster/FilebeerInfo.py
index 244131dc7..9db53fe19 100644
--- a/module/plugins/hoster/FilebeerInfo.py
+++ b/module/plugins/hoster/FilebeerInfo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FilebeerInfo(DeadHoster):
__name__ = "FilebeerInfo"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filebeer\.info/(?!\d*~f)(?P<ID>\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FileboomMe.py b/module/plugins/hoster/FileboomMe.py
index 9cdeebe3d..2798d9eda 100644
--- a/module/plugins/hoster/FileboomMe.py
+++ b/module/plugins/hoster/FileboomMe.py
@@ -10,7 +10,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FileboomMe(SimpleHoster):
__name__ = "FileboomMe"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://f(?:ile)?boom\.me/file/(?P<ID>\w+)'
@@ -30,12 +31,12 @@ class FileboomMe(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = False
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
post_url = urljoin(pyfile.url, "/file/" + self.info['pattern']['ID'])
m = re.search(r'data-slow-id="(\w+)"', self.html)
@@ -55,7 +56,7 @@ class FileboomMe(SimpleHoster):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
- captcha = self.decryptCaptcha(urljoin(pyfile.url, m.group(1)))
+ captcha = self.captcha.decrypt(urljoin(pyfile.url, m.group(1)))
self.html = self.load(post_url,
post={'CaptchaForm[code]' : captcha,
@@ -64,10 +65,10 @@ class FileboomMe(SimpleHoster):
'uniqueId' : uniqueId})
if 'The verification code is incorrect' in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.checkErrors()
+ self.check_errors()
self.html = self.load(post_url,
post={'free' : 1,
@@ -78,7 +79,7 @@ class FileboomMe(SimpleHoster):
self.link = urljoin(pyfile.url, m.group(0))
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
break
diff --git a/module/plugins/hoster/FilecloudIo.py b/module/plugins/hoster/FilecloudIo.py
index 346e9c444..21654fee3 100644
--- a/module/plugins/hoster/FilecloudIo.py
+++ b/module/plugins/hoster/FilecloudIo.py
@@ -3,14 +3,15 @@
import re
from module.common.json_layer import json_loads
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilecloudIo(SimpleHoster):
__name__ = "FilecloudIo"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(?:filecloud\.io|ifile\.it|mihd\.net)/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,7 +30,7 @@ class FilecloudIo(SimpleHoster):
TEMP_OFFLINE_PATTERN = r'l10n\.FILES__WARNING'
UKEY_PATTERN = r'\'ukey\'\s*:\'(\w+)'
- AB1_PATTERN = r'if\( __ab1 == \'(\w+)\' \)'
+ AB1_PATTERN = r'if\( __ab1 is \'(\w+)\' \)'
ERROR_MSG_PATTERN = r'var __error_msg\s*=\s*l10n\.(.*?);'
@@ -39,13 +40,13 @@ class FilecloudIo(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
- data = {"ukey": self.info['pattern']['ID']}
+ def handle_free(self, pyfile):
+ data = {'ukey': self.info['pattern']['ID']}
m = re.search(self.AB1_PATTERN, self.html)
if m is None:
@@ -61,20 +62,20 @@ class FilecloudIo(SimpleHoster):
self.error(_("ReCaptcha key not found"))
response, challenge = recaptcha.challenge(captcha_key)
- self.account.form_data = {"recaptcha_challenge_field": challenge,
- "recaptcha_response_field" : response}
+ self.account.form_data = {'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field' : response}
self.account.relogin(self.user)
self.retry(2)
json_url = "http://filecloud.io/download-request.json"
res = self.load(json_url, post=data)
- self.logDebug(res)
+ self.log_debug(res)
res = json_loads(res)
if "error" in res and res['error']:
self.fail(res)
- self.logDebug(res)
+ self.log_debug(res)
if res['captcha']:
data['ctype'] = "recaptcha"
@@ -83,13 +84,13 @@ class FilecloudIo(SimpleHoster):
json_url = "http://filecloud.io/download-request.json"
res = self.load(json_url, post=data)
- self.logDebug(res)
+ self.log_debug(res)
res = json_loads(res)
if "retry" in res and res['retry']:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
self.fail(_("Incorrect captcha"))
@@ -102,22 +103,22 @@ class FilecloudIo(SimpleHoster):
self.error(_("LINK_FREE_PATTERN not found"))
if "size" in self.info and self.info['size']:
- self.check_data = {"size": int(self.info['size'])}
+ self.check_data = {'size': int(self.info['size'])}
self.link = m.group(1)
else:
self.fail(_("Unexpected server response"))
- def handlePremium(self, pyfile):
- akey = self.account.getAccountData(self.user)['akey']
+ def handle_premium(self, pyfile):
+ akey = self.account.get_data(self.user)['akey']
ukey = self.info['pattern']['ID']
- self.logDebug("Akey: %s | Ukey: %s" % (akey, ukey))
+ self.log_debug("Akey: %s | Ukey: %s" % (akey, ukey))
rep = self.load("http://api.filecloud.io/api-fetch_download_url.api",
- post={"akey": akey, "ukey": ukey})
- self.logDebug("FetchDownloadUrl: " + rep)
+ post={'akey': akey, 'ukey': ukey})
+ self.log_debug("FetchDownloadUrl: " + rep)
rep = json_loads(rep)
- if rep['status'] == 'ok':
+ if rep['status'] == "ok":
self.link = rep['download_url']
else:
self.fail(rep['message'])
diff --git a/module/plugins/hoster/FiledropperCom.py b/module/plugins/hoster/FiledropperCom.py
new file mode 100644
index 000000000..3f5e2b761
--- /dev/null
+++ b/module/plugins/hoster/FiledropperCom.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+import re
+import urlparse
+
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class FiledropperCom(SimpleHoster):
+ __name__ = "FiledropperCom"
+ __type__ = "hoster"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'https?://(?:www\.)?filedropper\.com/\w+'
+
+ __description__ = """Filedropper.com hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")]
+
+
+ NAME_PATTERN = r'Filename: (?P<N>.+?) <'
+ SIZE_PATTERN = r'Size: (?P<S>[\d.,]+) (?P<U>[\w^_]+),' #@NOTE: Website says always 0 KB
+ OFFLINE_PATTERN = r'value="a\.swf"'
+
+
+ def setup(self):
+ self.multiDL = False
+ self.chunk_limit = 1
+
+
+ def handle_free(self, pyfile):
+ m = re.search(r'img id="img" src="(.+?)"', self.html)
+ if m is None:
+ self.fail("Captcha not found")
+
+ captcha_code = self.captcha.decrypt("http://www.filedropper.com/%s" % m.group(1))
+
+ m = re.search(r'method="post" action="(.+?)"', self.html)
+ if m is None:
+ self.fail("Download link not found")
+
+ self.download(urlparse.urljoin("http://www.filedropper.com/", m.group(1)),
+ post={'code': captcha_code})
+
+
+getInfo = create_getInfo(FiledropperCom)
diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py
index ea1a38b7a..325b4bb27 100644
--- a/module/plugins/hoster/FilefactoryCom.py
+++ b/module/plugins/hoster/FilefactoryCom.py
@@ -3,24 +3,25 @@
import re
import urlparse
-from module.network.RequestFactory import getURL
-from module.plugins.internal.SimpleHoster import SimpleHoster, parseFileInfo
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.SimpleHoster import SimpleHoster, parse_fileInfo
-def getInfo(urls):
+def get_info(urls):
for url in urls:
- h = getURL(url, just_header=True)
+ h = get_url(url, just_header=True)
m = re.search(r'Location: (.+)\r\n', h)
if m and not re.match(m.group(1), FilefactoryCom.__pattern__): #: It's a direct link! Skipping
yield (url, 0, 3, url)
else: #: It's a standard html page
- yield parseFileInfo(FilefactoryCom, url, getURL(url))
+ yield parse_fileInfo(FilefactoryCom, url, get_url(url))
class FilefactoryCom(SimpleHoster):
__name__ = "FilefactoryCom"
__type__ = "hoster"
- __version__ = "0.55"
+ __version__ = "0.57"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?filefactory\.com/(file|trafficshare/\w+)/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -42,7 +43,7 @@ class FilefactoryCom(SimpleHoster):
COOKIES = [("filefactory.com", "locale", "en_US.utf8")]
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if "Currently only Premium Members can download files larger than" in self.html:
self.fail(_("File too large for free download"))
elif "All free download slots on this server are currently in use" in self.html:
@@ -59,22 +60,22 @@ class FilefactoryCom(SimpleHoster):
self.wait(m.group(1))
- def checkFile(self, rules={}):
- check = self.checkDownload({'multiple': "You are currently downloading too many files at once.",
+ def check_file(self):
+ check = self.check_download({'multiple': "You are currently downloading too many files at once.",
'error' : '<div id="errorMessage">'})
if check == "multiple":
- self.logDebug("Parallel downloads detected; waiting 15 minutes")
+ self.log_debug("Parallel downloads detected; waiting 15 minutes")
self.retry(wait_time=15 * 60, reason=_("Parallel downloads"))
elif check == "error":
self.error(_("Unknown error"))
- return super(FilefactoryCom, self).checkFile(rules)
+ return super(FilefactoryCom, self).check_file()
- def handlePremium(self, pyfile):
- self.link = self.directLink(self.load(pyfile.url, just_header=True))
+ def handle_premium(self, pyfile):
+ self.link = self.direct_link(self.load(pyfile.url, just_header=True))
if not self.link:
html = self.load(pyfile.url)
diff --git a/module/plugins/hoster/FilejungleCom.py b/module/plugins/hoster/FilejungleCom.py
index 236603c6e..1a2a7d344 100644
--- a/module/plugins/hoster/FilejungleCom.py
+++ b/module/plugins/hoster/FilejungleCom.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
-from module.plugins.hoster.FileserveCom import FileserveCom, checkFile
-from module.plugins.Plugin import chunks
+from module.plugins.hoster.FileserveCom import FileserveCom, check_file
+from module.plugins.internal.Plugin import chunks
class FilejungleCom(FileserveCom):
__name__ = "FilejungleCom"
__type__ = "hoster"
- __version__ = "0.51"
+ __version__ = "0.53"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filejungle\.com/f/(?P<ID>[^/]+)'
@@ -24,6 +25,6 @@ class FilejungleCom(FileserveCom):
LONG_WAIT_PATTERN = r'<h1>Please wait for (\d+) (\w+)\s*to download the next file\.</h1>'
-def getInfo(urls):
+def get_info(urls):
for chunk in chunks(urls, 100):
- yield checkFile(FilejungleCom, chunk)
+ yield check_file(FilejungleCom, chunk)
diff --git a/module/plugins/hoster/FileomCom.py b/module/plugins/hoster/FileomCom.py
index 306953b84..0d54b6b6c 100644
--- a/module/plugins/hoster/FileomCom.py
+++ b/module/plugins/hoster/FileomCom.py
@@ -9,7 +9,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class FileomCom(XFSHoster):
__name__ = "FileomCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?fileom\.com/\w{12}'
@@ -26,8 +27,8 @@ class FileomCom(XFSHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
- self.resumeDownload = self.premium
+ self.chunk_limit = 1
+ self.resume_download = self.premium
getInfo = create_getInfo(FileomCom)
diff --git a/module/plugins/hoster/FilepostCom.py b/module/plugins/hoster/FilepostCom.py
index 1f3de6717..d8c626ef2 100644
--- a/module/plugins/hoster/FilepostCom.py
+++ b/module/plugins/hoster/FilepostCom.py
@@ -4,14 +4,15 @@ import re
import time
from module.common.json_layer import json_loads
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilepostCom(SimpleHoster):
__name__ = "FilepostCom"
__type__ = "hoster"
- __version__ = "0.34"
+ __version__ = "0.35"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(?:filepost\.com/files|fp\.io)/(?P<ID>[^/]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,7 +30,7 @@ class FilepostCom(SimpleHoster):
FLP_TOKEN_PATTERN = r'set_store_options\({token: \'(.+?)\''
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.FLP_TOKEN_PATTERN, self.html)
if m is None:
self.error(_("Token"))
@@ -40,27 +41,27 @@ class FilepostCom(SimpleHoster):
self.error(_("Captcha key"))
captcha_key = m.group(1)
- # Get wait time
+ #: Get wait time
get_dict = {'SID': self.req.cj.getCookie('SID'), 'JsHttpRequest': str(int(time.time() * 10000)) + '-xml'}
post_dict = {'action': 'set_download', 'token': flp_token, 'code': self.info['pattern']['ID']}
- wait_time = int(self.getJsonResponse(get_dict, post_dict, 'wait_time'))
+ wait_time = int(self.get_json_response(get_dict, post_dict, 'wait_time'))
if wait_time > 0:
self.wait(wait_time)
- post_dict = {"token": flp_token, "code": self.info['pattern']['ID'], "file_pass": ''}
+ post_dict = {'token': flp_token, 'code': self.info['pattern']['ID'], 'file_pass': ''}
if 'var is_pass_exists = true;' in self.html:
- # Solve password
- password = self.getPassword()
+ #: Solve password
+ password = self.get_password()
if password:
- self.logInfo(_("Password protected link, trying ") + file_pass)
+ self.log_info(_("Password protected link, trying ") + file_pass)
get_dict['JsHttpRequest'] = str(int(time.time() * 10000)) + '-xml'
post_dict['file_pass'] = file_pass
- self.link = self.getJsonResponse(get_dict, post_dict, 'link')
+ self.link = self.get_json_response(get_dict, post_dict, 'link')
if not self.link:
self.fail(_("Incorrect password"))
@@ -68,7 +69,7 @@ class FilepostCom(SimpleHoster):
self.fail(_("No password found"))
else:
- # Solve recaptcha
+ #: Solve recaptcha
recaptcha = ReCaptcha(self)
for i in xrange(5):
@@ -76,32 +77,32 @@ class FilepostCom(SimpleHoster):
if i:
post_dict['recaptcha_response_field'], post_dict['recaptcha_challenge_field'] = recaptcha.challenge(
captcha_key)
- self.logDebug(u"RECAPTCHA: %s : %s : %s" % (
+ self.log_debug(u"RECAPTCHA: %s : %s : %s" % (
captcha_key, post_dict['recaptcha_challenge_field'], post_dict['recaptcha_response_field']))
- self.link = self.getJsonResponse(get_dict, post_dict, 'link')
+ self.link = self.get_json_response(get_dict, post_dict, 'link')
else:
self.fail(_("Invalid captcha"))
- def getJsonResponse(self, get_dict, post_dict, field):
+ def get_json_response(self, get_dict, post_dict, field):
res = json_loads(self.load('https://filepost.com/files/get/', get=get_dict, post=post_dict))
- self.logDebug(res)
+ self.log_debug(res)
if not 'js' in res:
self.error(_("JSON %s 1") % field)
- # i changed js_answer to res['js'] since js_answer is nowhere set.
- # i don't know the JSON-HTTP specs in detail, but the previous author
- # accessed res['js']['error'] as well as js_answer['error'].
- # see the two lines commented out with "# ~?".
+ #: I changed js_answer to res['js'] since js_answer is nowhere set.
+ #: I don't know the JSON-HTTP specs in detail, but the previous author
+ #: Accessed res['js']['error'] as well as js_answer['error'].
+ #: See the two lines commented out with "# ~?".
if 'error' in res['js']:
- if res['js']['error'] == 'download_delay':
+ if res['js']['error'] == "download_delay":
self.retry(wait_time=res['js']['params']['next_download'])
- # ~? self.retry(wait_time=js_answer['params']['next_download'])
+ #: ~? self.retry(wait_time=js_answer['params']['next_download'])
elif 'Wrong file password' in res['js']['error'] \
or 'You entered a wrong CAPTCHA code' in res['js']['error'] \
@@ -109,7 +110,7 @@ class FilepostCom(SimpleHoster):
return None
elif 'CAPTCHA' in res['js']['error']:
- self.logDebug("Error response is unknown, but mentions CAPTCHA")
+ self.log_debug("Error response is unknown, but mentions CAPTCHA")
return None
else:
diff --git a/module/plugins/hoster/FilepupNet.py b/module/plugins/hoster/FilepupNet.py
index 874fde3c8..8bb23adb1 100644
--- a/module/plugins/hoster/FilepupNet.py
+++ b/module/plugins/hoster/FilepupNet.py
@@ -12,7 +12,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilepupNet(SimpleHoster):
__name__ = "FilepupNet"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filepup\.net/files/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -33,10 +34,10 @@ class FilepupNet(SimpleHoster):
def setup(self):
self.multiDL = False
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("Download link not found"))
diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py
index 3b876ed48..f8c41f4d1 100644
--- a/module/plugins/hoster/FilerNet.py
+++ b/module/plugins/hoster/FilerNet.py
@@ -8,14 +8,15 @@ import pycurl
import re
import urlparse
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FilerNet(SimpleHoster):
__name__ = "FilerNet"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?filer\.net/get/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -34,14 +35,14 @@ class FilerNet(SimpleHoster):
LINK_FREE_PATTERN = LINK_PREMIUM_PATTERN = r'href="([^"]+)">Get download</a>'
- def handleFree(self, pyfile):
- inputs = self.parseHtmlForm(input_names={'token': re.compile(r'.+')})[1]
+ def handle_free(self, pyfile):
+ inputs = self.parse_html_form(input_names={'token': re.compile(r'.+')})[1]
if 'token' not in inputs:
self.error(_("Unable to detect token"))
- self.html = self.load(pyfile.url, post={'token': inputs['token']}, decode=True)
+ self.html = self.load(pyfile.url, post={'token': inputs['token']})
- inputs = self.parseHtmlForm(input_names={'hash': re.compile(r'.+')})[1]
+ inputs = self.parse_html_form(input_names={'hash': re.compile(r'.+')})[1]
if 'hash' not in inputs:
self.error(_("Unable to detect hash"))
@@ -58,9 +59,9 @@ class FilerNet(SimpleHoster):
if 'location' in self.req.http.header.lower():
self.link = re.search(r'location: (\S+)', self.req.http.header, re.I).group(1)
- self.correctCaptcha()
+ self.captcha.correct()
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
getInfo = create_getInfo(FilerNet)
diff --git a/module/plugins/hoster/FilerioCom.py b/module/plugins/hoster/FilerioCom.py
index c6ebbd444..c65c07a42 100644
--- a/module/plugins/hoster/FilerioCom.py
+++ b/module/plugins/hoster/FilerioCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class FilerioCom(XFSHoster):
__name__ = "FilerioCom"
__type__ = "hoster"
- __version__ = "0.07"
+ __version__ = "0.08"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(filerio\.(in|com)|filekeen\.com)/\w{12}'
diff --git a/module/plugins/hoster/FilesMailRu.py b/module/plugins/hoster/FilesMailRu.py
index 7bd099282..a6dd56152 100644
--- a/module/plugins/hoster/FilesMailRu.py
+++ b/module/plugins/hoster/FilesMailRu.py
@@ -2,16 +2,16 @@
import re
-from module.network.RequestFactory import getURL
-from module.plugins.Hoster import Hoster
-from module.plugins.Plugin import chunks
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.Hoster import Hoster
+from module.plugins.internal.Plugin import chunks
-def getInfo(urls):
+def get_info(urls):
result = []
for chunk in chunks(urls, 10):
for url in chunk:
- html = getURL(url)
+ html = get_url(url)
if r'<div class="errorMessage mb10">' in html:
result.append((url, 0, 1, url))
elif r'Page cannot be displayed' in html:
@@ -24,15 +24,16 @@ def getInfo(urls):
except Exception:
pass
- # status 1=OFFLINE, 2=OK, 3=UNKNOWN
- # result.append((#name,#size,#status,#url))
+ #: status 1=OFFLINE, 2=OK, 3=UNKNOWN
+ #: result.append((#name,#size,#status,#url))
yield result
class FilesMailRu(Hoster):
__name__ = "FilesMailRu"
__type__ = "hoster"
- __version__ = "0.32"
+ __version__ = "0.34"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?files\.mail\.ru/.+'
@@ -49,57 +50,62 @@ class FilesMailRu(Hoster):
self.html = self.load(pyfile.url)
self.url_pattern = '<a href="(.+?)" onclick="return Act\(this\, \'dlink\'\, event\)">(.+?)</a>'
- #marks the file as "offline" when the pattern was found on the html-page'''
+ #: Marks the file as "offline" when the pattern was found on the html-page'''
if r'<div class="errorMessage mb10">' in self.html:
self.offline()
elif r'Page cannot be displayed' in self.html:
self.offline()
- #the filename that will be showed in the list (e.g. test.part1.rar)'''
- pyfile.name = self.getFileName()
+ #: The filename that will be showed in the list (e.g. test.part1.rar)'''
+ pyfile.name = self.get_file_name()
- #prepare and download'''
+ #: Prepare and download'''
if not self.account:
self.prepare()
- self.download(self.getFileUrl())
- self.myPostProcess()
+ self.download(self.get_file_url())
+ self.my_post_process()
else:
- self.download(self.getFileUrl())
- self.myPostProcess()
+ self.download(self.get_file_url())
+ self.my_post_process()
def prepare(self):
- """You have to wait some seconds. Otherwise you will get a 40Byte HTML Page instead of the file you expected"""
- self.setWait(10)
- self.wait()
+ """
+ You have to wait some seconds. Otherwise you will get a 40Byte HTML Page instead of the file you expected
+ """
+ self.wait(10)
return True
- def getFileUrl(self):
- """gives you the URL to the file. Extracted from the Files.mail.ru HTML-page stored in self.html"""
+ def get_file_url(self):
+ """
+ Gives you the URL to the file. Extracted from the Files.mail.ru HTML-page stored in self.html
+ """
return re.search(self.url_pattern, self.html).group(0).split('<a href="')[1].split('" onclick="return Act')[0]
- def getFileName(self):
- """gives you the Name for each file. Also extracted from the HTML-Page"""
+ def get_file_name(self):
+ """
+ Gives you the Name for each file. Also extracted from the HTML-Page
+ """
return re.search(self.url_pattern, self.html).group(0).split(', event)">')[1].split('</a>')[0]
- def myPostProcess(self):
- # searches the file for HTMl-Code. Sometimes the Redirect
- # doesn't work (maybe a curl Problem) and you get only a small
- # HTML file and the Download is marked as "finished"
- # then the download will be restarted. It's only bad for these
- # who want download a HTML-File (it's one in a million ;-) )
+ def my_post_process(self):
+ #: Searches the file for HTMl-Code. Sometimes the Redirect
+ #: doesn't work (maybe a curl Problem) and you get only a small
+ #: HTML file and the Download is marked as "finished"
+ #: then the download will be restarted. It's only bad for these
+ #: who want download a HTML-File (it's one in a million ;-) )
#
- # The maximum UploadSize allowed on files.mail.ru at the moment is 100MB
- # so i set it to check every download because sometimes there are downloads
- # that contain the HTML-Text and 60MB ZEROs after that in a xyzfile.part1.rar file
- # (Loading 100MB in to ram is not an option)
- check = self.checkDownload({"html": "<meta name="}, read_size=50000)
+ #: The maximum UploadSize allowed on files.mail.ru at the moment == 100MB
+ #: so i set it to check every download because sometimes there are downloads
+ #: that contain the HTML-Text and 60MB ZEROs after that in a xyzfile.part1.rar file
+ #: (Loading 100MB in to ram is not an option)
+ check = self.check_download({'html': "<meta name="}, read_size=50000)
if check == "html":
- self.logInfo(_(
+ self.log_info(_(
"There was HTML Code in the Downloaded File (%s)...redirect error? The Download will be restarted." %
self.pyfile.name))
self.retry()
diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py
index f8cf652b9..a74589cff 100644
--- a/module/plugins/hoster/FileserveCom.py
+++ b/module/plugins/hoster/FileserveCom.py
@@ -3,16 +3,16 @@
import re
from module.common.json_layer import json_loads
-from module.network.RequestFactory import getURL
-from module.plugins.Hoster import Hoster
-from module.plugins.Plugin import chunks
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SimpleHoster import secondsToMidnight
-from module.utils import parseFileSize
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.Hoster import Hoster
+from module.plugins.internal.Plugin import chunks
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.internal.SimpleHoster import seconds_to_midnight
+from module.utils import parseFileSize as parse_size
-def checkFile(plugin, urls):
- html = getURL(plugin.URLS[1], post={"urls": "\n".join(urls)}, decode=True)
+def check_file(plugin, urls):
+ html = get_url(plugin.URLS[1], post={'urls': "\n".join(urls)})
file_info = []
for li in re.finditer(plugin.LINKCHECK_TR, html, re.S):
@@ -21,7 +21,7 @@ def checkFile(plugin, urls):
if cols:
file_info.append((
cols[1] if cols[1] != '--' else cols[0],
- parseFileSize(cols[2]) if cols[2] != '--' else 0,
+ parse_size(cols[2]) if cols[2] != '--' else 0,
2 if cols[3].startswith('Available') else 1,
cols[0]))
except Exception, e:
@@ -33,65 +33,67 @@ def checkFile(plugin, urls):
class FileserveCom(Hoster):
__name__ = "FileserveCom"
__type__ = "hoster"
- __version__ = "0.55"
+ __version__ = "0.58"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fileserve\.com/file/(?P<ID>[^/]+)'
__description__ = """Fileserve.com hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("jeix", "jeix@hasnomail.de"),
- ("mkaay", "mkaay@mkaay.de"),
- ("Paul King", None),
- ("zoidberg", "zoidberg@mujmail.cz")]
+ __authors__ = [("jeix" , "jeix@hasnomail.de" ),
+ ("mkaay" , "mkaay@mkaay.de" ),
+ ("Paul King", None ),
+ ("zoidberg" , "zoidberg@mujmail.cz")]
- URLS = ["http://www.fileserve.com/file/", "http://www.fileserve.com/link-checker.php",
+ URLS = ["http://www.fileserve.com/file/",
+ "http://www.fileserve.com/link-checker.php",
"http://www.fileserve.com/checkReCaptcha.php"]
+
LINKCHECK_TR = r'<tr>\s*(<td>http://www\.fileserve\.com/file/.*?)</tr>'
LINKCHECK_TD = r'<td>(?:<.*?>|&nbsp;)*([^<]*)'
- CAPTCHA_KEY_PATTERN = r'var reCAPTCHA_publickey=\'(.+?)\''
- LONG_WAIT_PATTERN = r'<li class="title">You need to wait (\d+) (\w+) to start another download\.</li>'
- LINK_EXPIRED_PATTERN = r'Your download link has expired'
- DAILY_LIMIT_PATTERN = r'Your daily download limit has been reached'
+ CAPTCHA_KEY_PATTERN = r'var reCAPTCHA_publickey=\'(.+?)\''
+ LONG_WAIT_PATTERN = r'<li class="title">You need to wait (\d+) (\w+) to start another download\.</li>'
+ LINK_EXPIRED_PATTERN = r'Your download link has expired'
+ DL_LIMIT_PATTERN = r'Your daily download limit has been reached'
NOT_LOGGED_IN_PATTERN = r'<form (name="loginDialogBoxForm"|id="login_form")|<li><a href="/login\.php">Login</a></li>'
def setup(self):
- self.resumeDownload = self.multiDL = self.premium
+ self.resume_download = self.multiDL = self.premium
self.file_id = re.match(self.__pattern__, self.pyfile.url).group('ID')
self.url = "%s%s" % (self.URLS[0], self.file_id)
- self.logDebug("File ID: %s URL: %s" % (self.file_id, self.url))
+ self.log_debug("File ID: %s URL: %s" % (self.file_id, self.url))
def process(self, pyfile):
- pyfile.name, pyfile.size, status, self.url = checkFile(self, [self.url])[0]
+ pyfile.name, pyfile.size, status, self.url = check_file(self, [self.url])[0]
if status != 2:
self.offline()
- self.logDebug("File Name: %s Size: %d" % (pyfile.name, pyfile.size))
+ self.log_debug("File Name: %s Size: %d" % (pyfile.name, pyfile.size))
if self.premium:
- self.handlePremium()
+ self.handle_premium()
else:
- self.handleFree()
+ self.handle_free()
- def handleFree(self):
+ def handle_free(self):
self.html = self.load(self.url)
- action = self.load(self.url, post={"checkDownload": "check"}, decode=True)
+ action = self.load(self.url, post={'checkDownload': "check"})
action = json_loads(action)
- self.logDebug(action)
+ self.log_debug(action)
if "fail" in action:
if action['fail'] == "timeLimit":
- self.html = self.load(self.url, post={"checkDownload": "showError", "errorType": "timeLimit"},
- decode=True)
+ self.html = self.load(self.url, post={'checkDownload': "showError", 'errorType': "timeLimit"})
- self.doLongWait(re.search(self.LONG_WAIT_PATTERN, self.html))
+ self.do_long_wait(re.search(self.LONG_WAIT_PATTERN, self.html))
elif action['fail'] == "parallelDownload":
- self.logWarning(_("Parallel download error, now waiting 60s"))
+ self.log_warning(_("Parallel download error, now waiting 60s"))
self.retry(wait_time=60, reason=_("parallelDownload"))
else:
@@ -99,47 +101,46 @@ class FileserveCom(Hoster):
elif "success" in action:
if action['success'] == "showCaptcha":
- self.doCaptcha()
- self.doTimmer()
+ self.do_captcha()
+ self.do_timmer()
elif action['success'] == "showTimmer":
- self.doTimmer()
+ self.do_timmer()
else:
self.error(_("Unknown server response"))
- # show download link
- res = self.load(self.url, post={"downloadLink": "show"}, decode=True)
- self.logDebug("Show downloadLink response: %s" % res)
+ #: Show download link
+ res = self.load(self.url, post={'downloadLink': "show"})
+ self.log_debug("Show downloadLink response: %s" % res)
if "fail" in res:
self.error(_("Couldn't retrieve download url"))
- # this may either download our file or forward us to an error page
- self.download(self.url, post={"download": "normal"})
- self.logDebug(self.req.http.lastEffectiveURL)
+ #: This may either download our file or forward us to an error page
+ self.download(self.url, post={'download': "normal"})
+ self.log_debug(self.req.http.lastEffectiveURL)
- check = self.checkDownload({"expired": self.LINK_EXPIRED_PATTERN,
- "wait" : re.compile(self.LONG_WAIT_PATTERN),
- "limit" : self.DAILY_LIMIT_PATTERN})
+ check = self.check_download({'expired': self.LINK_EXPIRED_PATTERN,
+ 'wait' : re.compile(self.LONG_WAIT_PATTERN),
+ 'limit' : self.DL_LIMIT_PATTERN})
if check == "expired":
- self.logDebug("Download link was expired")
+ self.log_debug("Download link was expired")
self.retry()
elif check == "wait":
- self.doLongWait(self.lastCheck)
+ self.do_long_wait(self.last_check)
elif check == "limit":
- self.logWarning(_("Download limited reached for today"))
- self.setWait(secondsToMidnight(gmt=2), True)
- self.wait()
+ self.log_warning(_("Download limited reached for today"))
+ self.wait(seconds_to_midnight(gmt=2), True)
self.retry()
- self.thread.m.reconnecting.wait(3) # Ease issue with later downloads appearing to be in parallel
+ self.thread.m.reconnecting.wait(3) #: Ease issue with later downloads appearing to be in parallel
- def doTimmer(self):
- res = self.load(self.url, post={"downloadLink": "wait"}, decode=True)
- self.logDebug("Wait response: %s" % res[:80])
+ def do_timmer(self):
+ res = self.load(self.url, post={'downloadLink': "wait"})
+ self.log_debug("Wait response: %s" % res[:80])
if "fail" in res:
self.fail(_("Failed getting wait time"))
@@ -152,11 +153,10 @@ class FileserveCom(Hoster):
else:
wait_time = int(res) + 3
- self.setWait(wait_time)
- self.wait()
+ self.wait(wait_time)
- def doCaptcha(self):
+ def do_captcha(self):
captcha_key = re.search(self.CAPTCHA_KEY_PATTERN, self.html).group(1)
recaptcha = ReCaptcha(self)
@@ -167,50 +167,48 @@ class FileserveCom(Hoster):
'recaptcha_response_field' : response,
'recaptcha_shortencode_field': self.file_id}))
if not res['success']:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
self.fail(_("Invalid captcha"))
- def doLongWait(self, m):
+ def do_long_wait(self, m):
wait_time = (int(m.group(1)) * {'seconds': 1, 'minutes': 60, 'hours': 3600}[m.group(2)]) if m else 12 * 60
- self.setWait(wait_time, True)
- self.wait()
+ self.wait(wait_time, True)
self.retry()
- def handlePremium(self):
+ def handle_premium(self):
premium_url = None
if self.__name__ == "FileserveCom":
- #try api download
+ #: Try api download
res = self.load("http://app.fileserve.com/api/download/premium/",
- post={"username": self.user,
- "password": self.account.getAccountData(self.user)['password'],
- "shorten": self.file_id},
- decode=True)
+ post={'username': self.user,
+ 'password': self.account.get_info(self.user)['login']['password'],
+ 'shorten': self.file_id})
if res:
res = json_loads(res)
if res['error_code'] == "302":
premium_url = res['next']
elif res['error_code'] in ["305", "500"]:
- self.tempOffline()
+ self.temp_offline()
elif res['error_code'] in ["403", "605"]:
- self.resetAccount()
+ self.restart(nopremium=True)
elif res['error_code'] in ["606", "607", "608"]:
self.offline()
else:
- self.logError(res['error_code'], res['error_message'])
+ self.log_error(res['error_code'], res['error_message'])
self.download(premium_url or self.pyfile.url)
- if not premium_url and self.checkDownload({"login": re.compile(self.NOT_LOGGED_IN_PATTERN)}):
+ if not premium_url and self.check_download({'login': re.compile(self.NOT_LOGGED_IN_PATTERN)}):
self.account.relogin(self.user)
self.retry(reason=_("Not logged in"))
-def getInfo(urls):
+def get_info(urls):
for chunk in chunks(urls, 100):
- yield checkFile(FileserveCom, chunk)
+ yield check_file(FileserveCom, chunk)
diff --git a/module/plugins/hoster/FileshareInUa.py b/module/plugins/hoster/FileshareInUa.py
index aa1785f19..3fb181348 100644
--- a/module/plugins/hoster/FileshareInUa.py
+++ b/module/plugins/hoster/FileshareInUa.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FileshareInUa(DeadHoster):
__name__ = "FileshareInUa"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?fileshare\.in\.ua/\w{7}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FilesonicCom.py b/module/plugins/hoster/FilesonicCom.py
index 5254a6f9b..59c0ea246 100644
--- a/module/plugins/hoster/FilesonicCom.py
+++ b/module/plugins/hoster/FilesonicCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FilesonicCom(DeadHoster):
__name__ = "FilesonicCom"
__type__ = "hoster"
- __version__ = "0.35"
+ __version__ = "0.36"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filesonic\.com/file/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FileuploadNet.py b/module/plugins/hoster/FileuploadNet.py
new file mode 100644
index 000000000..c7f541687
--- /dev/null
+++ b/module/plugins/hoster/FileuploadNet.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class FileuploadNet(SimpleHoster):
+ __name__ = "FileuploadNet"
+ __type__ = "hoster"
+ __version__ = "0.03"
+ __status__ = "testing"
+
+ __pattern__ = r'https?://(?:www\.)?(en\.)?file-upload\.net/download-\d+/.+'
+
+ __description__ = """File-upload.net hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")]
+
+
+ NAME_PATTERN = r'<title>File-Upload.net - (?P<N>.+?)<'
+ SIZE_PATTERN = r'</label><span>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ OFFLINE_PATTERN = r'Datei existiert nicht'
+
+ LINK_FREE_PATTERN = r"<a href='(.+?)' title='download' onclick"
+
+
+ def setup(self):
+ self.multiDL = True
+ self.chunk_limit = 1
+
+
+getInfo = create_getInfo(FileuploadNet)
diff --git a/module/plugins/hoster/FilezyNet.py b/module/plugins/hoster/FilezyNet.py
index 9f442c846..249548d13 100644
--- a/module/plugins/hoster/FilezyNet.py
+++ b/module/plugins/hoster/FilezyNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FilezyNet(DeadHoster):
__name__ = "FilezyNet"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?filezy\.net/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FiredriveCom.py b/module/plugins/hoster/FiredriveCom.py
index 8faee5b52..cc530a3c5 100644
--- a/module/plugins/hoster/FiredriveCom.py
+++ b/module/plugins/hoster/FiredriveCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FiredriveCom(DeadHoster):
__name__ = "FiredriveCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(firedrive|putlocker)\.com/(mobile/)?(file|embed)/(?P<ID>\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FlyFilesNet.py b/module/plugins/hoster/FlyFilesNet.py
index 689eb3c66..ca2f7f270 100644
--- a/module/plugins/hoster/FlyFilesNet.py
+++ b/module/plugins/hoster/FlyFilesNet.py
@@ -3,14 +3,14 @@
import re
import urllib
-from module.network.RequestFactory import getURL
from module.plugins.internal.SimpleHoster import SimpleHoster
class FlyFilesNet(SimpleHoster):
__name__ = "FlyFilesNet"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.11"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?flyfiles\.net/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -31,12 +31,12 @@ class FlyFilesNet(SimpleHoster):
url = "http://flyfiles.net"
- # get download URL
- parsed_url = getURL(url, post={"getDownLink": session})
- self.logDebug("Parsed URL: %s" % parsed_url)
+ #: Get download URL
+ parsed_url = self.load(url, post={'getDownLink': session})
+ self.log_debug("Parsed URL: %s" % parsed_url)
- if parsed_url == '#downlink|' or parsed_url == "#downlink|#":
- self.logWarning(_("Could not get the download URL. Please wait 10 minutes"))
+ if parsed_url == "#downlink|" or parsed_url == "#downlink|#":
+ self.log_warning(_("Could not get the download URL. Please wait 10 minutes"))
self.wait(10 * 60, True)
self.retry()
diff --git a/module/plugins/hoster/FourSharedCom.py b/module/plugins/hoster/FourSharedCom.py
index 79eb1fb83..e5b309dc1 100644
--- a/module/plugins/hoster/FourSharedCom.py
+++ b/module/plugins/hoster/FourSharedCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FourSharedCom(SimpleHoster):
__name__ = "FourSharedCom"
__type__ = "hoster"
- __version__ = "0.31"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?4shared(\-china)?\.com/(account/)?(download|get|file|document|photo|video|audio|mp3|office|rar|zip|archive|music)/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -35,7 +36,7 @@ class FourSharedCom(SimpleHoster):
ID_PATTERN = r'name="d3fid" value="(.*?)"'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_BTN_PATTERN, self.html)
if m:
link = m.group(1)
@@ -53,7 +54,7 @@ class FourSharedCom(SimpleHoster):
try:
m = re.search(self.ID_PATTERN, self.html)
res = self.load('http://www.4shared.com/web/d2/getFreeDownloadLimitInfo?fileId=%s' % m.group(1))
- self.logDebug(res)
+ self.log_debug(res)
except Exception:
pass
diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py
index d005443d9..4564ee03e 100644
--- a/module/plugins/hoster/FreakshareCom.py
+++ b/module/plugins/hoster/FreakshareCom.py
@@ -2,15 +2,16 @@
import re
-from module.plugins.Hoster import Hoster
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SimpleHoster import secondsToMidnight
+from module.plugins.internal.Hoster import Hoster
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.internal.SimpleHoster import seconds_to_midnight
class FreakshareCom(Hoster):
__name__ = "FreakshareCom"
__type__ = "hoster"
- __version__ = "0.41"
+ __version__ = "0.43"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?freakshare\.(net|com)/files/\S*?/'
@@ -43,25 +44,24 @@ class FreakshareCom(Hoster):
self.download(pyfile.url, post=self.req_opts)
- check = self.checkDownload({"bad" : "bad try",
- "paralell" : "> Sorry, you cant download more then 1 files at time. <",
- "empty" : "Warning: Unknown: Filename cannot be empty",
- "wrong_captcha" : "Wrong Captcha!",
- "downloadserver": "No Downloadserver. Please try again later!"})
+ check = self.check_download({'bad' : "bad try",
+ 'paralell' : "> Sorry, you cant download more then 1 files at time. <",
+ 'empty' : "Warning: Unknown: Filename cannot be empty",
+ 'wrong_captcha' : "Wrong Captcha!",
+ 'downloadserver': "No Downloadserver. Please try again later!"})
if check == "bad":
self.fail(_("Bad Try"))
elif check == "paralell":
- self.setWait(300, True)
- self.wait()
+ self.wait(300, True)
self.retry()
elif check == "empty":
self.fail(_("File not downloadable"))
elif check == "wrong_captcha":
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry()
elif check == "downloadserver":
@@ -76,7 +76,7 @@ class FreakshareCom(Hoster):
if not self.file_exists():
self.offline()
- self.setWait(self.get_waiting_time())
+ self.set_wait(self.get_waiting_time())
pyfile.name = self.get_file_name()
pyfile.size = self.get_file_size()
@@ -87,19 +87,20 @@ class FreakshareCom(Hoster):
def download_html(self):
- self.load("http://freakshare.com/index.php", {"language": "EN"}) # Set english language in server session
+ self.load("http://freakshare.com/index.php", {'language': "EN"}) #: Set english language in server session
self.html = self.load(self.pyfile.url)
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
if not self.wantReconnect:
- self.req_opts = self.get_download_options() # get the Post options for the Request
- #file_url = self.pyfile.url
- #return file_url
+ self.req_opts = self.get_download_options() #: Get the Post options for the Request
+ # file_url = self.pyfile.url
+ # return file_url
else:
self.offline()
@@ -141,7 +142,7 @@ class FreakshareCom(Hoster):
if "Your Traffic is used up for today" in self.html:
self.wantReconnect = True
- return secondsToMidnight(gmt=2)
+ return seconds_to_midnight(gmt=2)
timestring = re.search('\s*var\s(?:downloadWait|time)\s=\s(\d*)[\d.]*;', self.html)
if timestring:
@@ -151,7 +152,8 @@ class FreakshareCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
@@ -163,11 +165,11 @@ class FreakshareCom(Hoster):
def get_download_options(self):
re_envelope = re.search(r".*?value=\"Free\sDownload\".*?\n*?(.*?<.*?>\n*)*?\n*\s*?</form>",
- self.html).group(0) # get the whole request
+ self.html).group(0) #: Get the whole request
to_sort = re.findall(r"<input\stype=\"hidden\"\svalue=\"(.*?)\"\sname=\"(.*?)\"\s\/>", re_envelope)
request_options = dict((n, v) for (v, n) in to_sort)
- herewego = self.load(self.pyfile.url, None, request_options) # the actual download-Page
+ herewego = self.load(self.pyfile.url, None, request_options) #: The actual download-Page
to_sort = re.findall(r"<input\stype=\".*?\"\svalue=\"(\S*?)\".*?name=\"(\S*?)\"\s.*?\/>", herewego)
request_options = dict((n, v) for (v, n) in to_sort)
diff --git a/module/plugins/hoster/FreeWayMe.py b/module/plugins/hoster/FreeWayMe.py
index 1cca24c3b..ed7c4bf7f 100644
--- a/module/plugins/hoster/FreeWayMe.py
+++ b/module/plugins/hoster/FreeWayMe.py
@@ -6,10 +6,12 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class FreeWayMe(MultiHoster):
__name__ = "FreeWayMe"
__type__ = "hoster"
- __version__ = "0.16"
+ __version__ = "0.19"
+ __status__ = "testing"
- __pattern__ = r'https://(?:www\.)?free-way\.me/.+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __pattern__ = r'https?://(?:www\.)?free-way\.(bz|me)/.+'
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """FreeWayMe multi-hoster plugin"""
__license__ = "GPLv3"
@@ -17,36 +19,36 @@ class FreeWayMe(MultiHoster):
def setup(self):
- self.resumeDownload = False
+ self.resume_download = False
self.multiDL = self.premium
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handlePremium(self, pyfile):
- user, data = self.account.selectAccount()
+ def handle_premium(self, pyfile):
+ user, data = self.account.select()
for _i in xrange(5):
- # try it five times
- header = self.load("https://www.free-way.me/load.php",
+ #: Try it five times
+ header = self.load("http://www.free-way.bz/load.php", #@TODO: Revert to `https` in 0.4.10
get={'multiget': 7,
'url' : pyfile.url,
'user' : user,
- 'pw' : self.account.getAccountData(user)['password'],
+ 'pw' : self.account.get_info(self.user)['login']['password'],
'json' : ""},
just_header=True)
if 'location' in header:
headers = self.load(header['location'], just_header=True)
if headers['code'] == 500:
- # error on 2nd stage
- self.logError(_("Error [stage2]"))
+ #: Error on 2nd stage
+ self.log_error(_("Error [stage2]"))
else:
- # seems to work..
+ #: Seems to work..
self.download(header['location'])
break
else:
- # error page first stage
- self.logError(_("Error [stage1]"))
+ #: Error page first stage
+ self.log_error(_("Error [stage1]"))
#@TODO: handle errors
diff --git a/module/plugins/hoster/FreevideoCz.py b/module/plugins/hoster/FreevideoCz.py
index 49f02a28b..ec8734b6a 100644
--- a/module/plugins/hoster/FreevideoCz.py
+++ b/module/plugins/hoster/FreevideoCz.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class FreevideoCz(DeadHoster):
__name__ = "FreevideoCz"
__type__ = "hoster"
- __version__ = "0.30"
+ __version__ = "0.31"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?freevideo\.cz/vase-videa/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/FshareVn.py b/module/plugins/hoster/FshareVn.py
index 50128db10..a5aac222c 100644
--- a/module/plugins/hoster/FshareVn.py
+++ b/module/plugins/hoster/FshareVn.py
@@ -4,27 +4,27 @@ import re
import time
import urlparse
-from module.network.RequestFactory import getURL
-from module.plugins.internal.SimpleHoster import SimpleHoster, parseFileInfo
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.SimpleHoster import SimpleHoster, parse_fileInfo
-def getInfo(urls):
+def get_info(urls):
for url in urls:
- html = getURL("http://www.fshare.vn/check_link.php",
- post={'action': "check_link", 'arrlinks': url},
- decode=True)
+ html = get_url("http://www.fshare.vn/check_link.php",
+ post={'action': "check_link", 'arrlinks': url})
- yield parseFileInfo(FshareVn, url, html)
+ yield parse_fileInfo(FshareVn, url, html)
-def doubleDecode(m):
+def double_decode(m):
return m.group(1).decode('raw_unicode_escape')
class FshareVn(SimpleHoster):
__name__ = "FshareVn"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?fshare\.vn/file/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -45,31 +45,27 @@ class FshareVn(SimpleHoster):
def preload(self):
self.html = self.load("http://www.fshare.vn/check_link.php",
- post={'action': "check_link", 'arrlinks': pyfile.url},
- decode=True)
+ post={'action': "check_link", 'arrlinks': pyfile.url})
- if isinstance(self.TEXT_ENCODING, basestring):
- self.html = unicode(self.html, self.TEXT_ENCODING)
+ def handle_free(self, pyfile):
+ self.html = self.load(pyfile.url)
- def handleFree(self, pyfile):
- self.html = self.load(pyfile.url, decode=True)
+ self.check_errors()
- self.checkErrors()
-
- action, inputs = self.parseHtmlForm('frm_download')
+ action, inputs = self.parse_html_form('frm_download')
url = urlparse.urljoin(pyfile.url, action)
if not inputs:
self.error(_("No FORM"))
elif 'link_file_pwd_dl' in inputs:
- password = self.getPassword()
+ password = self.get_password()
if password:
- self.logInfo(_("Password protected link, trying ") + password)
+ self.log_info(_("Password protected link, trying ") + password)
inputs['link_file_pwd_dl'] = password
- self.html = self.load(url, post=inputs, decode=True)
+ self.html = self.load(url, post=inputs)
if 'name="link_file_pwd_dl"' in self.html:
self.fail(_("Incorrect password"))
@@ -77,12 +73,12 @@ class FshareVn(SimpleHoster):
self.fail(_("No password found"))
else:
- self.html = self.load(url, post=inputs, decode=True)
+ self.html = self.load(url, post=inputs)
- self.checkErrors()
+ self.check_errors()
m = re.search(r'var count = (\d+)', self.html)
- self.setWait(int(m.group(1)) if m else 30)
+ self.set_wait(int(m.group(1)) if m else 30)
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
@@ -92,19 +88,19 @@ class FshareVn(SimpleHoster):
self.wait()
- def checkErrors(self):
+ def check_errors(self):
if '/error.php?' in self.req.lastEffectiveURL or u"Liên kết bạn chọn khÃŽng tồn" in self.html:
self.offline()
m = re.search(self.WAIT_PATTERN, self.html)
if m:
- self.logInfo(_("Wait until %s ICT") % m.group(1))
+ self.log_info(_("Wait until %s ICT") % m.group(1))
wait_until = time.mktime.time(time.strptime.time(m.group(1), "%d/%m/%Y %H:%M"))
self.wait(wait_until - time.mktime.time(time.gmtime.time()) - 7 * 60 * 60, True)
self.retry()
elif '<ul class="message-error">' in self.html:
msg = "Unknown error occured or wait time not parsed"
- self.logError(msg)
+ self.log_error(msg)
self.retry(30, 2 * 60, msg)
self.info.pop('error', None)
diff --git a/module/plugins/hoster/Ftp.py b/module/plugins/hoster/Ftp.py
index 295955cbe..25eb44604 100644
--- a/module/plugins/hoster/Ftp.py
+++ b/module/plugins/hoster/Ftp.py
@@ -5,13 +5,14 @@ import re
import urllib
import urlparse
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class Ftp(Hoster):
__name__ = "Ftp"
__type__ = "hoster"
- __version__ = "0.52"
+ __version__ = "0.54"
+ __status__ = "testing"
__pattern__ = r'(?:ftps?|sftp)://([\w.-]+(:[\w.-]+)?@)?[\w.-]+(:\d+)?/.+'
@@ -23,8 +24,8 @@ class Ftp(Hoster):
def setup(self):
- self.chunkLimit = -1
- self.resumeDownload = True
+ self.chunk_limit = -1
+ self.resume_download = True
def process(self, pyfile):
@@ -41,10 +42,10 @@ class Ftp(Hoster):
servers = [x['login'] for x in self.account.getAllAccounts()] if self.account else []
if netloc in servers:
- self.logDebug("Logging on to %s" % netloc)
- self.req.addAuth(self.account.getAccountInfo(netloc)['password'])
+ self.log_debug("Logging on to %s" % netloc)
+ self.req.addAuth(self.account.get_info(netloc)['login']['password'])
else:
- pwd = self.getPassword()
+ pwd = self.get_password()
if ':' in pwd:
self.req.addAuth(pwd)
@@ -56,22 +57,22 @@ class Ftp(Hoster):
self.fail(_("Error %d: %s") % e.args)
self.req.http.c.setopt(pycurl.NOBODY, 0)
- self.logDebug(self.req.http.header)
+ self.log_debug(self.req.http.header)
m = re.search(r"Content-Length:\s*(\d+)", res)
if m:
pyfile.size = int(m.group(1))
self.download(pyfile.url)
else:
- #Naive ftp directory listing
+ #: Naive ftp directory listing
if re.search(r'^25\d.*?"', self.req.http.header, re.M):
pyfile.url = pyfile.url.rstrip('/')
pkgname = "/".join([pyfile.package().name, urlparse.urlparse(pyfile.url).path.rpartition('/')[2]])
pyfile.url += '/'
- self.req.http.c.setopt(48, 1) # CURLOPT_DIRLISTONLY
+ self.req.http.c.setopt(48, 1) #: CURLOPT_DIRLISTONLY
res = self.load(pyfile.url, decode=False)
- links = [pyfile.url + urllib.quote(x) for x in res.splitlines()]
- self.logDebug("LINKS", links)
- self.core.api.addPackage(pkgname, links)
+ links = [pyfile.url + x for x in res.splitlines()]
+ self.log_debug("LINKS", links)
+ self.pyload.api.addPackage(pkgname, links)
else:
self.fail(_("Unexpected server response"))
diff --git a/module/plugins/hoster/GamefrontCom.py b/module/plugins/hoster/GamefrontCom.py
index c68866f87..fb3b98f5e 100644
--- a/module/plugins/hoster/GamefrontCom.py
+++ b/module/plugins/hoster/GamefrontCom.py
@@ -1,90 +1,37 @@
# -*- coding: utf-8 -*-
-import re
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.network.RequestFactory import getURL
-from module.plugins.Hoster import Hoster
-from module.utils import parseFileSize
-
-class GamefrontCom(Hoster):
+class GamefrontCom(SimpleHoster):
__name__ = "GamefrontCom"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.09"
+ __status__ = "testing"
- __pattern__ = r'http://(?:www\.)?gamefront\.com/files/\w+'
+ __pattern__ = r'http://(?:www\.)?gamefront\.com/files/(?P<ID>\d+)'
__description__ = """Gamefront.com hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("fwannmacher", "felipe@warhammerproject.com")]
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+ NAME_PATTERN = r'<title>(?P<N>.+?) \| Game Front</title>'
+ SIZE_PATTERN = r'>File Size:</dt>\s*<dd>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
+ OFFLINE_PATTERN = r'<p>File not found'
- PATTERN_FILENAME = r'<title>(.*?) | Game Front'
- PATTERN_FILESIZE = r'<dt>File Size:</dt>[\n\s]*<dd>(.*?)</dd>'
- PATTERN_OFFLINE = r'This file doesn\'t exist, or has been removed.'
+ LINK_FREE_PATTERN = r"downloadUrl = '(.+?)'"
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- self.chunkLimit = -1
-
-
- def process(self, pyfile):
- self.pyfile = pyfile
- self.html = self.load(pyfile.url, decode=True)
-
- if not self._checkOnline():
- self.offline()
-
- pyfile.name = self._getName()
-
- link = self._getLink()
-
- if not link.startswith('http://'):
- link = "http://www.gamefront.com/" + link
-
- self.download(link)
-
-
- def _checkOnline(self):
- if re.search(self.PATTERN_OFFLINE, self.html):
- return False
- else:
- return True
-
-
- def _getName(self):
- name = re.search(self.PATTERN_FILENAME, self.html)
- if name is None:
- self.fail(_("Plugin broken")
-
- return name.group(1)
-
-
- def _getLink(self):
- self.html2 = self.load("http://www.gamefront.com/" + re.search("(files/service/thankyou\\?id=\w+)",
- self.html).group(1))
- return re.search("<a href=\"(http://media\d+\.gamefront.com/.*)\">click here</a>", self.html2).group(1).replace("&amp;", "&")
-
-
-def getInfo(urls):
- result = []
- for url in urls:
- html = getURL(url)
- if re.search(GamefrontCom.PATTERN_OFFLINE, html):
- result.append((url, 0, 1, url))
- else:
- name = re.search(GamefrontCom.PATTERN_FILENAME, html)
- if name is None:
- result.append((url, 0, 1, url))
- else:
- name = name.group(1)
- size = re.search(GamefrontCom.PATTERN_FILESIZE, html)
- size = parseFileSize(size.group(1))
+ def handle_free(self, pyfile):
+ self.html = self.load("http://www.gamefront.com/files/service/thankyou",
+ get={'id': self.info['pattern']['ID']})
+ return super(GamefrontCom, self).handle_free(pyfile)
- result.append((name, size, 3, url))
- yield result
+getInfo = create_getInfo(GamefrontCom)
diff --git a/module/plugins/hoster/GigapetaCom.py b/module/plugins/hoster/GigapetaCom.py
index c2feeb6f8..381c39a21 100644
--- a/module/plugins/hoster/GigapetaCom.py
+++ b/module/plugins/hoster/GigapetaCom.py
@@ -10,7 +10,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class GigapetaCom(SimpleHoster):
__name__ = "GigapetaCom"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?gigapeta\.com/dl/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,27 +30,27 @@ class GigapetaCom(SimpleHoster):
COOKIES = [("gigapeta.com", "lang", "us")]
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
captcha_key = str(random.randint(1, 100000000))
captcha_url = "http://gigapeta.com/img/captcha.gif?x=%s" % captcha_key
self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0)
for _i in xrange(5):
- self.checkErrors()
+ self.check_errors()
- captcha = self.decryptCaptcha(captcha_url)
+ captcha = self.captcha.decrypt(captcha_url)
self.html = self.load(pyfile.url, post={
- "captcha_key": captcha_key,
- "captcha": captcha,
- "download": "Download"})
+ 'captcha_key': captcha_key,
+ 'captcha': captcha,
+ 'download': "Download"})
m = re.search(r'Location\s*:\s*(.+)', self.req.http.header, re.I)
if m:
self.link = m.group(1).rstrip() #@TODO: Remove .rstrip() in 0.4.10
break
elif "Entered figures don&#96;t coincide with the picture" in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
self.fail(_("No valid captcha code entered"))
diff --git a/module/plugins/hoster/GooIm.py b/module/plugins/hoster/GooIm.py
index 4b27e6cc8..2c2f4aa9e 100644
--- a/module/plugins/hoster/GooIm.py
+++ b/module/plugins/hoster/GooIm.py
@@ -11,7 +11,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class GooIm(SimpleHoster):
__name__ = "GooIm"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?goo\.im/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -26,11 +27,11 @@ class GooIm(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.wait(10)
self.link = pyfile.url
diff --git a/module/plugins/hoster/GoogledriveCom.py b/module/plugins/hoster/GoogledriveCom.py
index 1c33a1e4e..903b5361e 100644
--- a/module/plugins/hoster/GoogledriveCom.py
+++ b/module/plugins/hoster/GoogledriveCom.py
@@ -13,7 +13,8 @@ from module.utils import html_unescape
class GoogledriveCom(SimpleHoster):
__name__ = "GoogledriveCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(drive|docs)\.google\.com/(file/d/\w+|uc\?.*id=)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -23,8 +24,6 @@ class GoogledriveCom(SimpleHoster):
__authors__ = [("zapp-brannigan", "fuerst.reinje@web.de")]
- DISPOSITION = False #: Remove in 0.4.10
-
NAME_PATTERN = r'(?:<title>|class="uc-name-size".*>)(?P<N>.+?)(?: - Google Drive</title>|</a> \()'
OFFLINE_PATTERN = r'align="center"><p class="errorMessage"'
@@ -33,11 +32,11 @@ class GoogledriveCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.resumeDownload = True
- self.chunkLimit = 1
+ self.resume_download = True
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
for _i in xrange(2):
m = re.search(self.LINK_FREE_PATTERN, self.html)
@@ -49,9 +48,9 @@ class GoogledriveCom(SimpleHoster):
if not urlparse.urlparse(link).scheme:
link = urlparse.urljoin("https://docs.google.com/", link)
- direct_link = self.directLink(link, False)
+ direct_link = self.direct_link(link, False)
if not direct_link:
- self.html = self.load(link, decode=True)
+ self.html = self.load(link)
else:
self.link = direct_link
break
diff --git a/module/plugins/hoster/HellshareCz.py b/module/plugins/hoster/HellshareCz.py
index ac0043b37..eab819ad9 100644
--- a/module/plugins/hoster/HellshareCz.py
+++ b/module/plugins/hoster/HellshareCz.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class HellshareCz(SimpleHoster):
__name__ = "HellshareCz"
__type__ = "hoster"
- __version__ = "0.85"
+ __version__ = "0.86"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?hellshare\.(?:cz|com|sk|hu|pl)/[^?]*/\d+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,8 +30,8 @@ class HellshareCz(SimpleHoster):
def setup(self):
- self.resumeDownload = self.multiDL = bool(self.account)
- self.chunkLimit = 1
+ self.resume_download = self.multiDL = bool(self.account)
+ self.chunk_limit = 1
getInfo = create_getInfo(HellshareCz)
diff --git a/module/plugins/hoster/HellspyCz.py b/module/plugins/hoster/HellspyCz.py
index 9b10760bd..499a94413 100644
--- a/module/plugins/hoster/HellspyCz.py
+++ b/module/plugins/hoster/HellspyCz.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class HellspyCz(DeadHoster):
__name__ = "HellspyCz"
__type__ = "hoster"
- __version__ = "0.28"
+ __version__ = "0.29"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(?:hellspy\.(?:cz|com|sk|hu|pl)|sciagaj\.pl)(/\S+/\d+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/HighWayMe.py b/module/plugins/hoster/HighWayMe.py
new file mode 100644
index 000000000..119ddb70e
--- /dev/null
+++ b/module/plugins/hoster/HighWayMe.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
+from module.plugins.internal.SimpleHoster import seconds_to_midnight
+
+
+class HighWayMe(MultiHoster):
+ __name__ = "HighWayMe"
+ __type__ = "hoster"
+ __version__ = "0.13"
+ __status__ = "testing"
+
+ __pattern__ = r'https?://.+high-way\.my'
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
+
+ __description__ = """High-Way.me multi-hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("EvolutionClip", "evolutionclip@live.de")]
+
+
+ def setup(self):
+ self.chunk_limit = 4
+
+
+ def check_errors(self):
+ if self.html.get('code') == 302: #@NOTE: This is not working. It should by if 302 Moved Temporarily then... But I don't now how to implement it.
+ self.account.relogin(self.user)
+ self.retry()
+
+ elif "<code>9</code>" in self.html:
+ self.offline()
+
+ elif "downloadlimit" in self.html:
+ self.log_warning(_("Reached maximum connctions"))
+ self.retry(5, 60, _("Reached maximum connctions"))
+
+ elif "trafficlimit" in self.html:
+ self.log_warning(_("Reached daily limit"))
+ self.retry(wait_time=seconds_to_midnight(gmt=2), reason="Daily limit for this host reached")
+
+ elif "<code>8</code>" in self.html:
+ self.log_warning(_("Hoster temporarily unavailable, waiting 1 minute and retry"))
+ self.retry(5, 60, _("Hoster is temporarily unavailable"))
+
+
+ def handle_premium(self, pyfile):
+ for _i in xrange(5):
+ self.html = self.load("https://high-way.me/load.php",
+ get={'link': self.pyfile.url})
+
+ if self.html:
+ self.log_debug("JSON data: " + self.html)
+ break
+ else:
+ self.log_info(_("Unable to get API data, waiting 1 minute and retry"))
+ self.retry(5, 60, _("Unable to get API data"))
+
+ self.check_errors()
+
+ try:
+ self.pyfile.name = re.search(r'<name>([^<]+)</name>', self.html).group(1)
+
+ except AttributeError:
+ self.pyfile.name = ""
+
+ try:
+ self.pyfile.size = re.search(r'<size>(\d+)</size>', self.html).group(1)
+
+ except AttributeError:
+ self.pyfile.size = 0
+
+ self.link = re.search(r'<download>([^<]+)</download>', self.html).group(1)
+
+
+getInfo = create_getInfo(HighWayMe)
diff --git a/module/plugins/hoster/HostujeNet.py b/module/plugins/hoster/HostujeNet.py
index ec91e50b9..4dbf550b3 100644
--- a/module/plugins/hoster/HostujeNet.py
+++ b/module/plugins/hoster/HostujeNet.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class HostujeNet(SimpleHoster):
__name__ = "HostujeNet"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?hostuje\.net/\w+'
@@ -24,10 +25,10 @@ class HostujeNet(SimpleHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(r'<script src="([\w^_]+.php)"></script>', self.html)
if m:
jscript = self.load("http://hostuje.net/" + m.group(1))
@@ -39,7 +40,7 @@ class HostujeNet(SimpleHoster):
else:
self.error(_("script not found"))
- action, inputs = self.parseHtmlForm(pyfile.url.replace(".", "\.").replace( "?", "\?"))
+ action, inputs = self.parse_html_form(pyfile.url.replace(".", "\.").replace( "?", "\?"))
if not action:
self.error(_("form not found"))
diff --git a/module/plugins/hoster/HotfileCom.py b/module/plugins/hoster/HotfileCom.py
index 082415c6b..032bd350e 100644
--- a/module/plugins/hoster/HotfileCom.py
+++ b/module/plugins/hoster/HotfileCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class HotfileCom(DeadHoster):
__name__ = "HotfileCom"
__type__ = "hoster"
- __version__ = "0.37"
+ __version__ = "0.38"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?hotfile\.com/dl/\d+/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/HugefilesNet.py b/module/plugins/hoster/HugefilesNet.py
index 3fdcca1ba..582d17756 100644
--- a/module/plugins/hoster/HugefilesNet.py
+++ b/module/plugins/hoster/HugefilesNet.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class HugefilesNet(XFSHoster):
__name__ = "HugefilesNet"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?hugefiles\.net/\w{12}'
diff --git a/module/plugins/hoster/HundredEightyUploadCom.py b/module/plugins/hoster/HundredEightyUploadCom.py
index 2a35a008f..9b3550922 100644
--- a/module/plugins/hoster/HundredEightyUploadCom.py
+++ b/module/plugins/hoster/HundredEightyUploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class HundredEightyUploadCom(XFSHoster):
__name__ = "HundredEightyUploadCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?180upload\.com/\w{12}'
diff --git a/module/plugins/hoster/IFileWs.py b/module/plugins/hoster/IFileWs.py
index ff263d43a..2444846d7 100644
--- a/module/plugins/hoster/IFileWs.py
+++ b/module/plugins/hoster/IFileWs.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class IFileWs(DeadHoster):
__name__ = "IFileWs"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?ifile\.ws/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/IcyFilesCom.py b/module/plugins/hoster/IcyFilesCom.py
index f81381c66..975e6bfc0 100644
--- a/module/plugins/hoster/IcyFilesCom.py
+++ b/module/plugins/hoster/IcyFilesCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class IcyFilesCom(DeadHoster):
__name__ = "IcyFilesCom"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?icyfiles\.com/(.+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/IfileIt.py b/module/plugins/hoster/IfileIt.py
index ef267b505..a0c435762 100644
--- a/module/plugins/hoster/IfileIt.py
+++ b/module/plugins/hoster/IfileIt.py
@@ -6,12 +6,13 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class IfileIt(DeadHoster):
__name__ = "IfileIt"
__type__ = "hoster"
- __version__ = "0.29"
+ __version__ = "0.30"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
__config__ = [] #@TODO: Remove in 0.4.10
- __description__ = """Ifile.it"""
+ __description__ = """Ifile.it hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
diff --git a/module/plugins/hoster/IfolderRu.py b/module/plugins/hoster/IfolderRu.py
index 0f09731e4..85d03489d 100644
--- a/module/plugins/hoster/IfolderRu.py
+++ b/module/plugins/hoster/IfolderRu.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class IfolderRu(SimpleHoster):
__name__ = "IfolderRu"
__type__ = "hoster"
- __version__ = "0.39"
+ __version__ = "0.40"
+ __status__ = "testing"
__pattern__ = r'http://(?:www)?(files\.)?(ifolder\.ru|metalarea\.org|rusfolder\.(com|net|ru))/(files/)?(?P<ID>\d+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -34,27 +35,27 @@ class IfolderRu(SimpleHoster):
def setup(self):
- self.resumeDownload = self.multiDL = bool(self.account)
- self.chunkLimit = 1
+ self.resume_download = self.multiDL = bool(self.account)
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
url = "http://rusfolder.com/%s" % self.info['pattern']['ID']
- self.html = self.load("http://rusfolder.com/%s" % self.info['pattern']['ID'], decode=True)
- self.getFileInfo()
+ self.html = self.load("http://rusfolder.com/%s" % self.info['pattern']['ID'])
+ self.get_fileInfo()
session_id = re.search(self.SESSION_ID_PATTERN, self.html).groups()
captcha_url = "http://ints.rusfolder.com/random/images/?session=%s" % session_id
for _i in xrange(5):
- action, inputs = self.parseHtmlForm('id="download-step-one-form"')
- inputs['confirmed_number'] = self.decryptCaptcha(captcha_url, cookies=True)
+ action, inputs = self.parse_html_form('id="download-step-one-form"')
+ inputs['confirmed_number'] = self.captcha.decrypt(captcha_url, cookies=True)
inputs['action'] = '1'
- self.logDebug(inputs)
+ self.log_debug(inputs)
- self.html = self.load(url, decode=True, post=inputs)
+ self.html = self.load(url, post=inputs)
if self.WRONG_CAPTCHA_PATTERN in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
break
else:
diff --git a/module/plugins/hoster/JumbofilesCom.py b/module/plugins/hoster/JumbofilesCom.py
index a9bf14c6d..e9c084c95 100644
--- a/module/plugins/hoster/JumbofilesCom.py
+++ b/module/plugins/hoster/JumbofilesCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class JumbofilesCom(SimpleHoster):
__name__ = "JumbofilesCom"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?jumbofiles\.com/(?P<ID>\w{12})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -24,13 +25,13 @@ class JumbofilesCom(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
- post_data = {"id": self.info['pattern']['ID'], "op": "download3", "rand": ""}
- html = self.load(self.pyfile.url, post=post_data, decode=True)
+ def handle_free(self, pyfile):
+ post_data = {'id': self.info['pattern']['ID'], 'op': "download3", 'rand': ""}
+ html = self.load(self.pyfile.url, post=post_data)
self.link = re.search(self.LINK_FREE_PATTERN, html).group(1)
diff --git a/module/plugins/hoster/JunocloudMe.py b/module/plugins/hoster/JunocloudMe.py
index 415d5e2d0..4483ccd5d 100644
--- a/module/plugins/hoster/JunocloudMe.py
+++ b/module/plugins/hoster/JunocloudMe.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class JunocloudMe(XFSHoster):
__name__ = "JunocloudMe"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:\w+\.)?junocloud\.me/\w{12}'
diff --git a/module/plugins/hoster/Keep2ShareCc.py b/module/plugins/hoster/Keep2ShareCc.py
index fb94d12c4..bf4b157cb 100644
--- a/module/plugins/hoster/Keep2ShareCc.py
+++ b/module/plugins/hoster/Keep2ShareCc.py
@@ -3,14 +3,15 @@
import re
import urlparse
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class Keep2ShareCc(SimpleHoster):
__name__ = "Keep2ShareCc"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(keep2share|k2s|keep2s)\.cc/file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -23,7 +24,7 @@ class Keep2ShareCc(SimpleHoster):
URL_REPLACEMENTS = [(__pattern__ + ".*", "http://keep2s.cc/file/\g<ID>")]
- NAME_PATTERN = r'File: <span>(?P<N>.+)</span>'
+ NAME_PATTERN = r'File: <span>(?P<N>.+?)</span>'
SIZE_PATTERN = r'Size: (?P<S>[^<]+)</div>'
OFFLINE_PATTERN = r'File not found or deleted|Sorry, this file is blocked or deleted|Error 404'
@@ -39,7 +40,7 @@ class Keep2ShareCc(SimpleHoster):
ERROR_PATTERN = r'>\s*(Free user can\'t download large files|You no can access to this file|This download available only for premium users|This is private file)'
- def checkErrors(self):
+ def check_errors(self):
m = re.search(self.TEMP_ERROR_PATTERN, self.html)
if m:
self.info['error'] = m.group(1)
@@ -53,9 +54,9 @@ class Keep2ShareCc(SimpleHoster):
m = re.search(self.WAIT_PATTERN, self.html)
if m:
- self.logDebug("Hoster told us to wait for %s" % m.group(1))
+ self.log_debug("Hoster told us to wait for %s" % m.group(1))
- # string to time convert courtesy of https://stackoverflow.com/questions/10663720
+ #: String to time convert courtesy of https://stackoverflow.com/questions/10663720
ftr = [3600, 60, 1]
wait_time = sum(a * b for a, b in zip(ftr, map(int, m.group(1).split(':'))))
@@ -65,18 +66,18 @@ class Keep2ShareCc(SimpleHoster):
self.info.pop('error', None)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.fid = re.search(r'<input type="hidden" name="slow_id" value="(.+?)">', self.html).group(1)
self.html = self.load(pyfile.url, post={'yt0': '', 'slow_id': self.fid})
- # self.logDebug(self.fid)
- # self.logDebug(pyfile.url)
+ # self.log_debug(self.fid)
+ # self.log_debug(pyfile.url)
- self.checkErrors()
+ self.check_errors()
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
- self.handleCaptcha()
+ self.handle_captcha()
self.wait(31)
self.html = self.load(pyfile.url)
@@ -87,20 +88,20 @@ class Keep2ShareCc(SimpleHoster):
self.link = m.group(1)
- def handleCaptcha(self):
+ def handle_captcha(self):
post_data = {'free' : 1,
'freeDownloadRequest': 1,
'uniqueId' : self.fid,
'yt0' : ''}
m = re.search(r'id="(captcha\-form)"', self.html)
- self.logDebug("captcha-form found %s" % m)
+ self.log_debug("captcha-form found %s" % m)
m = re.search(self.CAPTCHA_PATTERN, self.html)
- self.logDebug("CAPTCHA_PATTERN found %s" % m)
+ self.log_debug("CAPTCHA_PATTERN found %s" % m)
if m:
captcha_url = urlparse.urljoin("http://keep2s.cc/", m.group(1))
- post_data['CaptchaForm[code]'] = self.decryptCaptcha(captcha_url)
+ post_data['CaptchaForm[code]'] = self.captcha.decrypt(captcha_url)
else:
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge()
@@ -110,9 +111,9 @@ class Keep2ShareCc(SimpleHoster):
self.html = self.load(self.pyfile.url, post=post_data)
if 'verification code is incorrect' not in self.html:
- self.correctCaptcha()
+ self.captcha.correct()
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
getInfo = create_getInfo(Keep2ShareCc)
diff --git a/module/plugins/hoster/KickloadCom.py b/module/plugins/hoster/KickloadCom.py
index 7690c85c8..2b23b1616 100644
--- a/module/plugins/hoster/KickloadCom.py
+++ b/module/plugins/hoster/KickloadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class KickloadCom(DeadHoster):
__name__ = "KickloadCom"
__type__ = "hoster"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?kickload\.com/get/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/KingfilesNet.py b/module/plugins/hoster/KingfilesNet.py
index 42547d658..98f74ad0d 100644
--- a/module/plugins/hoster/KingfilesNet.py
+++ b/module/plugins/hoster/KingfilesNet.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.internal.SolveMedia import SolveMedia
+from module.plugins.captcha.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class KingfilesNet(SimpleHoster):
__name__ = "KingfilesNet"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.09"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?kingfiles\.net/(?P<ID>\w{12})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -31,12 +32,12 @@ class KingfilesNet(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
- # Click the free user button
+ def handle_free(self, pyfile):
+ #: Click the free user button
post_data = {'op' : "download1",
'usr_login' : "",
'id' : self.info['pattern']['ID'],
@@ -44,18 +45,18 @@ class KingfilesNet(SimpleHoster):
'referer' : "",
'method_free': "+"}
- self.html = self.load(pyfile.url, post=post_data, decode=True)
+ self.html = self.load(pyfile.url, post=post_data)
solvemedia = SolveMedia(self)
response, challenge = solvemedia.challenge()
- # Make the downloadlink appear and load the file
+ #: Make the downloadlink appear and load the file
m = re.search(self.RAND_ID_PATTERN, self.html)
if m is None:
self.error(_("Random key not found"))
rand = m.group(1)
- self.logDebug("rand = ", rand)
+ self.log_debug("rand = ", rand)
post_data = {'op' : "download2",
'id' : self.info['pattern']['ID'],
@@ -67,7 +68,7 @@ class KingfilesNet(SimpleHoster):
'adcopy_challenge': challenge,
'down_direct' : "1"}
- self.html = self.load(pyfile.url, post=post_data, decode=True)
+ self.html = self.load(pyfile.url, post=post_data)
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
diff --git a/module/plugins/hoster/LemUploadsCom.py b/module/plugins/hoster/LemUploadsCom.py
index 098867c8b..1f4f96a1f 100644
--- a/module/plugins/hoster/LemUploadsCom.py
+++ b/module/plugins/hoster/LemUploadsCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class LemUploadsCom(DeadHoster):
__name__ = "LemUploadsCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?lemuploads\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py
index 62afb6c7c..e93b60460 100644
--- a/module/plugins/hoster/LetitbitNet.py
+++ b/module/plugins/hoster/LetitbitNet.py
@@ -10,22 +10,22 @@ import re
import urlparse
from module.common.json_layer import json_loads, json_dumps
-from module.network.RequestFactory import getURL
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SimpleHoster import SimpleHoster, secondsToMidnight
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.internal.SimpleHoster import SimpleHoster, seconds_to_midnight
def api_response(url):
- json_data = ["yw7XQy2v9", ["download/info", {"link": url}]]
- api_rep = getURL("http://api.letitbit.net/json",
- post={'r': json_dumps(json_data)})
+ json_data = ["yw7XQy2v9", ["download/info", {'link': url}]]
+ api_rep = get_url("http://api.letitbit.net/json",
+ post={'r': json_dumps(json_data)})
return json_loads(api_rep)
-def getInfo(urls):
+def get_info(urls):
for url in urls:
api_rep = api_response(url)
- if api_rep['status'] == 'OK':
+ if api_rep['status'] == "OK":
info = api_rep['data'][0]
yield (info['name'], info['size'], 2, url)
else:
@@ -35,7 +35,8 @@ def getInfo(urls):
class LetitbitNet(SimpleHoster):
__name__ = "LetitbitNet"
__type__ = "hoster"
- __version__ = "0.31"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(letitbit|shareflare)\.net/download/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -53,16 +54,16 @@ class LetitbitNet(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
- def handleFree(self, pyfile):
- action, inputs = self.parseHtmlForm('id="ifree_form"')
+ def handle_free(self, pyfile):
+ action, inputs = self.parse_html_form('id="ifree_form"')
if not action:
self.error(_("ifree_form"))
pyfile.size = float(inputs['sssize'])
- self.logDebug(action, inputs)
+ self.log_debug(action, inputs)
inputs['desc'] = ""
self.html = self.load(urlparse.urljoin("http://letitbit.net/", action), post=inputs)
@@ -70,12 +71,12 @@ class LetitbitNet(SimpleHoster):
m = re.search(self.SECONDS_PATTERN, self.html)
seconds = int(m.group(1)) if m else 60
- self.logDebug("Seconds found", seconds)
+ self.log_debug("Seconds found", seconds)
m = re.search(self.CAPTCHA_CONTROL_FIELD, self.html)
recaptcha_control_field = m.group(1)
- self.logDebug("ReCaptcha control field found", recaptcha_control_field)
+ self.log_debug("ReCaptcha control field found", recaptcha_control_field)
self.wait(seconds)
@@ -83,30 +84,30 @@ class LetitbitNet(SimpleHoster):
if res != '1':
self.error(_("Unknown response - ajax_check_url"))
- self.logDebug(res)
+ self.log_debug(res)
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge()
- post_data = {"recaptcha_challenge_field": challenge,
- "recaptcha_response_field": response,
- "recaptcha_control_field": recaptcha_control_field}
+ post_data = {'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field': response,
+ 'recaptcha_control_field': recaptcha_control_field}
- self.logDebug("Post data to send", post_data)
+ self.log_debug("Post data to send", post_data)
res = self.load("http://letitbit.net/ajax/check_recaptcha.php", post=post_data)
- self.logDebug(res)
+ self.log_debug(res)
if not res:
- self.invalidCaptcha()
+ self.captcha.invalid()
if res == "error_free_download_blocked":
- self.logWarning(_("Daily limit reached"))
- self.wait(secondsToMidnight(gmt=2), True)
+ self.log_warning(_("Daily limit reached"))
+ self.wait(seconds_to_midnight(gmt=2), True)
if res == "error_wrong_captcha":
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry()
elif res.startswith('['):
@@ -121,16 +122,16 @@ class LetitbitNet(SimpleHoster):
self.link = urls[0]
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
api_key = self.user
- premium_key = self.account.getAccountData(self.user)['password']
+ premium_key = self.account.get_info(self.user)['login']['password']
- json_data = [api_key, ["download/direct_links", {"pass": premium_key, "link": pyfile.url}]]
+ json_data = [api_key, ["download/direct_links", {'pass': premium_key, 'link': pyfile.url}]]
api_rep = self.load('http://api.letitbit.net/json', post={'r': json_dumps(json_data)})
- self.logDebug("API Data: " + api_rep)
+ self.log_debug("API Data: " + api_rep)
api_rep = json_loads(api_rep)
- if api_rep['status'] == 'FAIL':
+ if api_rep['status'] == "FAIL":
self.fail(api_rep['data'])
self.link = api_rep['data'][0][0]
diff --git a/module/plugins/hoster/LinksnappyCom.py b/module/plugins/hoster/LinksnappyCom.py
index 9c3af4ae3..1c3f86d4a 100644
--- a/module/plugins/hoster/LinksnappyCom.py
+++ b/module/plugins/hoster/LinksnappyCom.py
@@ -10,30 +10,29 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class LinksnappyCom(MultiHoster):
__name__ = "LinksnappyCom"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.11"
+ __status__ = "testing"
__pattern__ = r'https?://(?:[^/]+\.)?linksnappy\.com'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Linksnappy.com multi-hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
- SINGLE_CHUNK_HOSTERS = ["easybytez.com"]
-
-
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
host = self._get_host(pyfile.url)
json_params = json_dumps({'link' : pyfile.url,
'type' : host,
'username': self.user,
- 'password': self.account.getAccountData(self.user)['password']})
+ 'password': self.account.get_info(self.user)['login']['password']})
- r = self.load("http://gen.linksnappy.com/genAPI.php",
+ r = self.load("http://linksnappy.com/api/linkgen",
post={'genLinks': json_params})
- self.logDebug("JSON data: " + r)
+ self.log_debug("JSON data: " + r)
j = json_loads(r)['links'][0]
@@ -43,11 +42,6 @@ class LinksnappyCom(MultiHoster):
pyfile.name = j['filename']
self.link = j['generated']
- if host in self.SINGLE_CHUNK_HOSTERS:
- self.chunkLimit = 1
- else:
- self.setup()
-
@staticmethod
def _get_host(url):
diff --git a/module/plugins/hoster/LoadTo.py b/module/plugins/hoster/LoadTo.py
index d2b25f0db..7a42e0360 100644
--- a/module/plugins/hoster/LoadTo.py
+++ b/module/plugins/hoster/LoadTo.py
@@ -6,25 +6,26 @@
import re
-from module.plugins.internal.SolveMedia import SolveMedia
+from module.plugins.captcha.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class LoadTo(SimpleHoster):
__name__ = "LoadTo"
__type__ = "hoster"
- __version__ = "0.23"
+ __version__ = "0.25"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?load\.to/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
- __description__ = """ Load.to hoster plugin """
+ __description__ = """Load.to hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("halfman", "Pulpan3@gmail.com"),
("stickell", "l.stickell@yahoo.it")]
- NAME_PATTERN = r'<h1>(?P<N>.+)</h1>'
+ NAME_PATTERN = r'<h1>(?P<N>.+?)</h1>'
SIZE_PATTERN = r'Size: (?P<S>[\d.,]+) (?P<U>[\w^_]+)'
OFFLINE_PATTERN = r'>Can\'t find file'
@@ -36,23 +37,23 @@ class LoadTo(SimpleHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
- # Search for Download URL
+ def handle_free(self, pyfile):
+ #: Search for Download URL
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("LINK_FREE_PATTERN not found"))
self.link = m.group(1)
- # Set Timer - may be obsolete
+ #: Set Timer - may be obsolete
m = re.search(self.WAIT_PATTERN, self.html)
if m:
self.wait(m.group(1))
- # Load.to is using solvemedia captchas since ~july 2014:
+ #: Load.to is using solvemedia captchas since ~july 2014:
solvemedia = SolveMedia(self)
captcha_key = solvemedia.detect_key()
diff --git a/module/plugins/hoster/LolabitsEs.py b/module/plugins/hoster/LolabitsEs.py
index 61df5f0bb..766f9d5b8 100644
--- a/module/plugins/hoster/LolabitsEs.py
+++ b/module/plugins/hoster/LolabitsEs.py
@@ -1,15 +1,16 @@
# -*- coding: utf-8 -*
-import HTMLParser
import re
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+from module.utils import html_unescape
class LolabitsEs(SimpleHoster):
__name__ = "LolabitsEs"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?lolabits\.es/.+'
@@ -28,21 +29,22 @@ class LolabitsEs(SimpleHoster):
def setup(self):
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
fileid = re.search(self.FILEID_PATTERN, self.html).group(1)
- self.logDebug("FileID: " + fileid)
+ self.log_debug("FileID: " + fileid)
token = re.search(self.TOKEN_PATTERN, self.html).group(1)
- self.logDebug("Token: " + token)
+ self.log_debug("Token: " + token)
self.html = self.load("http://lolabits.es/action/License/Download",
post={'fileId' : fileid,
- '__RequestVerificationToken' : token}).decode('unicode-escape')
+ '__RequestVerificationToken' : token},
+ decode="unicode-escape")
- self.link = HTMLParser.HTMLParser().unescape(re.search(self.LINK_PATTERN, self.html).group(1))
+ self.link = html_unescape(re.search(self.LINK_PATTERN, self.html).group(1))
getInfo = create_getInfo(LolabitsEs)
diff --git a/module/plugins/hoster/LomafileCom.py b/module/plugins/hoster/LomafileCom.py
index ef05cd1ea..9e625a1eb 100644
--- a/module/plugins/hoster/LomafileCom.py
+++ b/module/plugins/hoster/LomafileCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class LomafileCom(DeadHoster):
__name__ = "LomafileCom"
__type__ = "hoster"
- __version__ = "0.52"
+ __version__ = "0.53"
+ __status__ = "testing"
__pattern__ = r'http://lomafile\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py
index f4932d93d..788c1aca8 100644
--- a/module/plugins/hoster/LuckyShareNet.py
+++ b/module/plugins/hoster/LuckyShareNet.py
@@ -2,16 +2,16 @@
import re
-from bottle import json_loads
-
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.common.json_layer import json_loads
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class LuckyShareNet(SimpleHoster):
__name__ = "LuckyShareNet"
__type__ = "hoster"
- __version__ = "0.07"
+ __version__ = "0.08"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?luckyshare\.net/(?P<ID>\d{10,})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -25,13 +25,13 @@ class LuckyShareNet(SimpleHoster):
OFFLINE_PATTERN = r'There is no such file available'
- def parseJson(self, rep):
+ def parse_json(self, rep):
if 'AJAX Error' in rep:
- html = self.load(self.pyfile.url, decode=True)
+ html = self.load(self.pyfile.url)
m = re.search(r"waitingtime = (\d+);", html)
if m:
seconds = int(m.group(1))
- self.logDebug("You have to wait %d seconds between free downloads" % seconds)
+ self.log_debug("You have to wait %d seconds between free downloads" % seconds)
self.retry(wait_time=seconds)
else:
self.error(_("Unable to detect wait time between free downloads"))
@@ -40,14 +40,14 @@ class LuckyShareNet(SimpleHoster):
return json_loads(rep)
- # TODO: There should be a filesize limit for free downloads
- # TODO: Some files could not be downloaded in free mode
- def handleFree(self, pyfile):
- rep = self.load(r"http://luckyshare.net/download/request/type/time/file/" + self.info['pattern']['ID'], decode=True)
+ #@TODO: There should be a filesize limit for free downloads
+ #: Some files could not be downloaded in free mode
+ def handle_free(self, pyfile):
+ rep = self.load(r"http://luckyshare.net/download/request/type/time/file/" + self.info['pattern']['ID'])
- self.logDebug("JSON: " + rep)
+ self.log_debug("JSON: " + rep)
- json = self.parseJson(rep)
+ json = self.parse_json(rep)
self.wait(json['time'])
recaptcha = ReCaptcha(self)
@@ -55,14 +55,14 @@ class LuckyShareNet(SimpleHoster):
for _i in xrange(5):
response, challenge = recaptcha.challenge()
rep = self.load(r"http://luckyshare.net/download/verify/challenge/%s/response/%s/hash/%s" %
- (challenge, response, json['hash']), decode=True)
- self.logDebug("JSON: " + rep)
+ (challenge, response, json['hash']))
+ self.log_debug("JSON: " + rep)
if 'link' in rep:
- json.update(self.parseJson(rep))
- self.correctCaptcha()
+ json.update(self.parse_json(rep))
+ self.captcha.correct()
break
elif 'Verification failed' in rep:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
self.error(_("Unable to get downlaod link"))
diff --git a/module/plugins/hoster/MediafireCom.py b/module/plugins/hoster/MediafireCom.py
index 09eb4705d..3ba191160 100644
--- a/module/plugins/hoster/MediafireCom.py
+++ b/module/plugins/hoster/MediafireCom.py
@@ -1,14 +1,15 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SolveMedia import SolveMedia
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.captcha.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class MediafireCom(SimpleHoster):
__name__ = "MediafireCom"
__type__ = "hoster"
- __version__ = "0.89"
+ __version__ = "0.90"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?mediafire\.com/(file/|view/\??|download(\.php\?|/)|\?)(?P<ID>\w{15})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -31,11 +32,11 @@ class MediafireCom(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleCaptcha(self):
+ def handle_captcha(self):
solvemedia = SolveMedia(self)
captcha_key = solvemedia.detect_key()
@@ -43,8 +44,7 @@ class MediafireCom(SimpleHoster):
response, challenge = solvemedia.challenge(captcha_key)
self.html = self.load("http://www.mediafire.com/?" + self.info['pattern']['ID'],
post={'adcopy_challenge': challenge,
- 'adcopy_response' : response},
- decode=True)
+ 'adcopy_response' : response})
return
recaptcha = ReCaptcha(self)
@@ -53,26 +53,25 @@ class MediafireCom(SimpleHoster):
if captcha_key:
response, challenge = recaptcha.challenge(captcha_key)
self.html = self.load(self.pyfile.url,
- post={'g-recaptcha-response': response},
- decode=True)
+ post={'g-recaptcha-response': response})
- def handleFree(self, pyfile):
- self.handleCaptcha()
+ def handle_free(self, pyfile):
+ self.handle_captcha()
if self.PASSWORD_PATTERN in self.html:
- password = self.getPassword()
+ password = self.get_password()
if not password:
self.fail(_("No password found"))
else:
- self.logInfo(_("Password protected link, trying: ") + password)
+ self.log_info(_("Password protected link, trying: ") + password)
self.html = self.load(self.link, post={'downloadp': password})
if self.PASSWORD_PATTERN in self.html:
self.fail(_("Incorrect password"))
- return super(MediafireCom, self).handleFree(pyfile)
+ return super(MediafireCom, self).handle_free(pyfile)
getInfo = create_getInfo(MediafireCom)
diff --git a/module/plugins/hoster/MegaCoNz.py b/module/plugins/hoster/MegaCoNz.py
index aa7755af4..d8a29817c 100644
--- a/module/plugins/hoster/MegaCoNz.py
+++ b/module/plugins/hoster/MegaCoNz.py
@@ -12,7 +12,7 @@ from Crypto.Cipher import AES
from Crypto.Util import Counter
from module.common.json_layer import json_loads, json_dumps
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
from module.utils import decode, fs_decode, fs_encode
@@ -48,9 +48,10 @@ from module.utils import decode, fs_decode, fs_encode
class MegaCoNz(Hoster):
__name__ = "MegaCoNz"
__type__ = "hoster"
- __version__ = "0.26"
+ __version__ = "0.31"
+ __status__ = "testing"
- __pattern__ = r'(?:https?://(?:www\.)?mega\.co\.nz/|mega:|chrome:.+?)#(?P<TYPE>N|)!(?P<ID>[\w^_]+)!(?P<KEY>[\w,-]+)'
+ __pattern__ = r'(https?://(?:www\.)?mega(\.co)?\.nz/|mega:|chrome:.+?)#(?P<TYPE>N|)!(?P<ID>[\w^_]+)!(?P<KEY>[\w,-]+)'
__description__ = """Mega.co.nz hoster plugin"""
__license__ = "GPLv3"
@@ -67,8 +68,10 @@ class MegaCoNz(Hoster):
return standard_b64decode(data + '=' * (-len(data) % 4))
- def getCipherKey(self, key):
- """ Construct the cipher key from the given data """
+ def get_cipher_key(self, key):
+ """
+ Construct the cipher key from the given data
+ """
a = array.array("I", self.b64_decode(key))
k = array.array("I", (a[0] ^ a[4], a[1] ^ a[5], a[2] ^ a[6], a[3] ^ a[7]))
@@ -79,44 +82,46 @@ class MegaCoNz(Hoster):
def api_response(self, **kwargs):
- """ Dispatch a call to the api, see https://mega.co.nz/#developers """
-
- # generate a session id, no idea where to obtain elsewhere
- uid = random.random.randint(10 << 9, 10 ** 10)
+ """
+ Dispatch a call to the api, see https://mega.co.nz/#developers
+ """
+ #: Generate a session id, no idea where to obtain elsewhere
+ uid = random.randint(10 << 9, 10 ** 10)
res = self.load(self.API_URL, get={'id': uid}, post=json_dumps([kwargs]))
- self.logDebug("Api Response: " + res)
+ self.log_debug("Api Response: " + res)
return json_loads(res)
- def decryptAttr(self, data, key):
- k, iv, meta_mac = self.getCipherKey(key)
+ def decrypt_attr(self, data, key):
+ k, iv, meta_mac = self.get_cipher_key(key)
cbc = AES.new(k, AES.MODE_CBC, "\0" * 16)
attr = decode(cbc.decrypt(self.b64_decode(data)))
- self.logDebug("Decrypted Attr: %s" % attr)
+ self.log_debug("Decrypted Attr: %s" % attr)
if not attr.startswith("MEGA"):
self.fail(_("Decryption failed"))
- # Data is padded, 0-bytes must be stripped
+ #: Data is padded, 0-bytes must be stripped
return json_loads(re.search(r'{.+?}', attr).group(0))
- def decryptFile(self, key):
- """ Decrypts the file at lastDownload` """
-
- # upper 64 bit of counter start
+ def decrypt_file(self, key):
+ """
+ Decrypts the file at last_download`
+ """
+ #: Upper 64 bit of counter start
n = self.b64_decode(key)[16:24]
- # convert counter to long and shift bytes
- k, iv, meta_mac = self.getCipherKey(key)
+ #: Convert counter to long and shift bytes
+ k, iv, meta_mac = self.get_cipher_key(key)
ctr = Counter.new(128, initial_value=long(n.encode("hex"), 16) << 64)
cipher = AES.new(k, AES.MODE_CTR, counter=ctr)
self.pyfile.setStatus("decrypting")
self.pyfile.setProgress(0)
- file_crypted = fs_encode(self.lastDownload)
+ file_crypted = fs_encode(self.last_download)
file_decrypted = file_crypted.rsplit(self.FILE_SUFFIX)[0]
try:
@@ -126,7 +131,7 @@ class MegaCoNz(Hoster):
except IOError, e:
self.fail(e)
- chunk_size = 2 ** 15 # buffer size, 32k
+ chunk_size = 2 ** 15 #: Buffer size, 32k
# file_mac = [0, 0, 0, 0] # calculate CBC-MAC for checksum
chunks = os.path.getsize(file_crypted) / chunk_size + 1
@@ -158,22 +163,22 @@ class MegaCoNz(Hoster):
f.close()
df.close()
- # if file_mac[0] ^ file_mac[1], file_mac[2] ^ file_mac[3] != meta_mac:
+ # if file_mac[0] ^ file_mac[1], file_mac[2] ^ file_mac[3] is not meta_mac:
# os.remove(file_decrypted)
# self.fail(_("Checksum mismatch"))
os.remove(file_crypted)
- self.lastDownload = fs_decode(file_decrypted)
+ self.last_download = fs_decode(file_decrypted)
- def checkError(self, code):
+ def check_error(self, code):
ecode = abs(code)
if ecode in (9, 16, 21):
self.offline()
elif ecode in (3, 13, 17, 18, 19):
- self.tempOffline()
+ self.temp_offline()
elif ecode in (1, 4, 6, 10, 15, 21):
self.retry(5, 30, _("Error code: [%s]") % -ecode)
@@ -186,23 +191,23 @@ class MegaCoNz(Hoster):
pattern = re.match(self.__pattern__, pyfile.url).groupdict()
id = pattern['ID']
key = pattern['KEY']
- public = pattern['TYPE'] == ''
+ public = pattern['TYPE'] == ""
- self.logDebug("ID: %s" % id, "Key: %s" % key, "Type: %s" % ("public" if public else "node"))
+ self.log_debug("ID: %s" % id, "Key: %s" % key, "Type: %s" % ("public" if public else "node"))
- # g is for requesting a download url
- # this is similar to the calls in the mega js app, documentation is very bad
+ #: G is for requesting a download url
+ #: This is similar to the calls in the mega js app, documentation is very bad
if public:
mega = self.api_response(a="g", g=1, p=id, ssl=1)[0]
else:
mega = self.api_response(a="g", g=1, n=id, ssl=1)[0]
if isinstance(mega, int):
- self.checkError(mega)
+ self.check_error(mega)
elif "e" in mega:
- self.checkError(mega['e'])
+ self.check_error(mega['e'])
- attr = self.decryptAttr(mega['at'], key)
+ attr = self.decrypt_attr(mega['at'], key)
pyfile.name = attr['n'] + self.FILE_SUFFIX
pyfile.size = mega['s']
@@ -211,7 +216,7 @@ class MegaCoNz(Hoster):
self.download(mega['g'])
- self.decryptFile(key)
+ self.decrypt_file(key)
- # Everything is finished and final name can be set
+ #: Everything is finished and final name can be set
pyfile.name = attr['n']
diff --git a/module/plugins/hoster/MegaDebridEu.py b/module/plugins/hoster/MegaDebridEu.py
index 9c8cc2a90..4afba0a3a 100644
--- a/module/plugins/hoster/MegaDebridEu.py
+++ b/module/plugins/hoster/MegaDebridEu.py
@@ -10,12 +10,14 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class MegaDebridEu(MultiHoster):
__name__ = "MegaDebridEu"
__type__ = "hoster"
- __version__ = "0.47"
+ __version__ = "0.50"
+ __status__ = "testing"
__pattern__ = r'http://((?:www\d+\.|s\d+\.)?mega-debrid\.eu|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/download/file/[\w^_]+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
- __description__ = """mega-debrid.eu multi-hoster plugin"""
+ __description__ = """Mega-debrid.eu multi-hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("D.Ducatel", "dducatel@je-geek.fr")]
@@ -28,9 +30,9 @@ class MegaDebridEu(MultiHoster):
Connexion to the mega-debrid API
Return True if succeed
"""
- user, data = self.account.selectAccount()
+ user, info = self.account.select()
jsonResponse = self.load(self.API_URL,
- get={'action': 'connectUser', 'login': user, 'password': data['password']})
+ get={'action': 'connectUser', 'login': user, 'password': info['login']['password']})
res = json_loads(jsonResponse)
if res['response_code'] == "ok":
@@ -40,7 +42,7 @@ class MegaDebridEu(MultiHoster):
return False
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
"""
Debrid a link
Return The debrided link if succeed or original link if fail
diff --git a/module/plugins/hoster/MegaFilesSe.py b/module/plugins/hoster/MegaFilesSe.py
index 249eff952..03c684751 100644
--- a/module/plugins/hoster/MegaFilesSe.py
+++ b/module/plugins/hoster/MegaFilesSe.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class MegaFilesSe(DeadHoster):
__name__ = "MegaFilesSe"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?megafiles\.se/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/MegaRapidCz.py b/module/plugins/hoster/MegaRapidCz.py
index e17dd4730..13f462585 100644
--- a/module/plugins/hoster/MegaRapidCz.py
+++ b/module/plugins/hoster/MegaRapidCz.py
@@ -4,25 +4,26 @@ import pycurl
import re
from module.network.HTTPRequest import BadHeader
-from module.network.RequestFactory import getRequest
-from module.plugins.internal.SimpleHoster import SimpleHoster, parseFileInfo
+from module.network.RequestFactory import getRequest as get_request
+from module.plugins.internal.SimpleHoster import SimpleHoster, parse_fileInfo
-def getInfo(urls):
- h = getRequest()
+def get_info(urls):
+ h = get_request()
h.c.setopt(pycurl.HTTPHEADER,
["Accept: text/html",
"User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0"])
for url in urls:
- html = h.load(url, decode=True)
- yield parseFileInfo(MegaRapidCz, url, html)
+ html = h.load(url)
+ yield parse_fileInfo(MegaRapidCz, url, html)
class MegaRapidCz(SimpleHoster):
__name__ = "MegaRapidCz"
__type__ = "hoster"
- __version__ = "0.56"
+ __version__ = "0.57"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(share|mega)rapid\.cz/soubor/\d+/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -48,10 +49,10 @@ class MegaRapidCz(SimpleHoster):
def setup(self):
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
m = re.search(self.LINK_PREMIUM_PATTERN, self.html)
if m:
self.link = m.group(1)
diff --git a/module/plugins/hoster/MegaRapidoNet.py b/module/plugins/hoster/MegaRapidoNet.py
index a3b4c72ba..6676a565d 100644
--- a/module/plugins/hoster/MegaRapidoNet.py
+++ b/module/plugins/hoster/MegaRapidoNet.py
@@ -5,10 +5,10 @@ import random
from module.plugins.internal.MultiHoster import MultiHoster
-def random_with_N_digits(n):
+def random_with_n_digits(n):
rand = "0."
not_zero = 0
- for i in range(1, n + 1):
+ for i in xrange(1, n + 1):
r = random.randint(0, 9)
if(r > 0):
not_zero += 1
@@ -23,10 +23,12 @@ def random_with_N_digits(n):
class MegaRapidoNet(MultiHoster):
__name__ = "MegaRapidoNet"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?\w+\.megarapido\.net/\?file=\w+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """MegaRapido.net multi-hoster plugin"""
__license__ = "GPLv3"
@@ -38,17 +40,17 @@ class MegaRapidoNet(MultiHoster):
ERROR_PATTERN = r'<\s*?div[^>]*?class\s*?=\s*?["\']?alert-message error.*?>([^<]*)'
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.html = self.load("http://megarapido.net/gerar.php",
post={'rand' :random_with_N_digits(16),
'urllist' : pyfile.url,
'links' : pyfile.url,
'exibir' : "normal",
'usar' : "premium",
- 'user' : self.account.getAccountInfo(self.user).get('sid', None),
+ 'user' : self.account.get_data(self.user).get('sid', None),
'autoreset': ""})
if "desloga e loga novamente para gerar seus links" in self.html.lower():
self.error("You have logged in at another place")
- return super(MegaRapidoNet, self).handlePremium(pyfile)
+ return super(MegaRapidoNet, self).handle_premium(pyfile)
diff --git a/module/plugins/hoster/MegacrypterCom.py b/module/plugins/hoster/MegacrypterCom.py
index 10a2eb025..a67dca5da 100644
--- a/module/plugins/hoster/MegacrypterCom.py
+++ b/module/plugins/hoster/MegacrypterCom.py
@@ -10,7 +10,8 @@ from module.plugins.hoster.MegaCoNz import MegaCoNz
class MegacrypterCom(MegaCoNz):
__name__ = "MegacrypterCom"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.23"
+ __status__ = "testing"
__pattern__ = r'https?://\w{0,10}\.?megacrypter\.com/[\w!-]+'
@@ -24,26 +25,28 @@ class MegacrypterCom(MegaCoNz):
def api_response(self, **kwargs):
- """ Dispatch a call to the api, see megacrypter.com/api_doc """
- self.logDebug("JSON request: " + json_dumps(kwargs))
+ """
+ Dispatch a call to the api, see megacrypter.com/api_doc
+ """
+ self.log_debug("JSON request: " + json_dumps(kwargs))
res = self.load(self.API_URL, post=json_dumps(kwargs))
- self.logDebug("API Response: " + res)
+ self.log_debug("API Response: " + res)
return json_loads(res)
def process(self, pyfile):
- # match is guaranteed because plugin was chosen to handle url
+ #: Match is guaranteed because plugin was chosen to handle url
node = re.match(self.__pattern__, pyfile.url).group(0)
- # get Mega.co.nz link info
+ #: get Mega.co.nz link info
info = self.api_response(link=node, m="info")
- # get crypted file URL
+ #: Get crypted file URL
dl = self.api_response(link=node, m="dl")
- # TODO: map error codes, implement password protection
+ #@TODO: map error codes, implement password protection
# if info['pass'] is True:
- # crypted_file_key, md5_file_key = info['key'].split("#")
+ # crypted_file_key, md5_file_key = info['key'].split("#")
key = self.b64_decode(info['key'])
@@ -51,7 +54,7 @@ class MegacrypterCom(MegaCoNz):
self.download(dl['url'])
- self.decryptFile(key)
+ self.decrypt_file(key)
- # Everything is finished and final name can be set
+ #: Everything is finished and final name can be set
pyfile.name = info['name']
diff --git a/module/plugins/hoster/MegareleaseOrg.py b/module/plugins/hoster/MegareleaseOrg.py
index 6349144ec..ab9a864c9 100644
--- a/module/plugins/hoster/MegareleaseOrg.py
+++ b/module/plugins/hoster/MegareleaseOrg.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class MegareleaseOrg(DeadHoster):
__name__ = "MegareleaseOrg"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?megarelease\.org/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/MegasharesCom.py b/module/plugins/hoster/MegasharesCom.py
index ed2363fe3..b6692263f 100644
--- a/module/plugins/hoster/MegasharesCom.py
+++ b/module/plugins/hoster/MegasharesCom.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class MegasharesCom(SimpleHoster):
__name__ = "MegasharesCom"
__type__ = "hoster"
- __version__ = "0.28"
+ __version__ = "0.29"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(d\d{2}\.)?megashares\.com/((index\.php)?\?d\d{2}=|dl/)\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -35,15 +36,15 @@ class MegasharesCom(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = self.premium
- def handlePremium(self, pyfile):
- self.handleDownload(True)
+ def handle_premium(self, pyfile):
+ self.handle_download(True)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if self.NO_SLOTS_PATTERN in self.html:
self.retry(wait_time=5 * 60)
@@ -55,10 +56,10 @@ class MegasharesCom(SimpleHoster):
for _i in xrange(5):
random_num = re.search(self.REACTIVATE_NUM_PATTERN, self.html).group(1)
- verifyinput = self.decryptCaptcha("http://d01.megashares.com/index.php",
+ verifyinput = self.captcha.decrypt("http://d01.megashares.com/index.php",
get={'secgfx': "gfx", 'random_num': random_num})
- self.logInfo(_("Reactivating passport %s: %s %s") % (passport_num, random_num, verifyinput))
+ self.log_info(_("Reactivating passport %s: %s %s") % (passport_num, random_num, verifyinput))
res = self.load("http://d01.megashares.com%s" % request_uri,
get={'rs' : "check_passport_renewal",
@@ -69,10 +70,10 @@ class MegasharesCom(SimpleHoster):
'rsrnd[]' : str(int(time.time() * 1000))})
if 'Thank you for reactivating your passport.' in res:
- self.correctCaptcha()
+ self.captcha.correct()
self.retry()
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
self.fail(_("Failed to reactivate passport"))
@@ -80,33 +81,33 @@ class MegasharesCom(SimpleHoster):
if m:
time = [int(x) for x in m.groups()]
renew = time[0] + (time[1] * 60) + (time[2] * 60)
- self.logDebug("Waiting %d seconds for a new passport" % renew)
+ self.log_debug("Waiting %d seconds for a new passport" % renew)
self.retry(wait_time=renew, reason=_("Passport renewal"))
- # Check traffic left on passport
+ #: Check traffic left on passport
m = re.search(self.PASSPORT_LEFT_PATTERN, self.html, re.M | re.S)
if m is None:
self.fail(_("Passport not found"))
- self.logInfo(_("Download passport: %s") % m.group(1))
+ self.log_info(_("Download passport: %s") % m.group(1))
data_left = float(m.group(2)) * 1024 ** {'B': 0, 'KB': 1, 'MB': 2, 'GB': 3}[m.group(3)]
- self.logInfo(_("Data left: %s %s (%d MB needed)") % (m.group(2), m.group(3), self.pyfile.size / 1048576))
+ self.log_info(_("Data left: %s %s (%d MB needed)") % (m.group(2), m.group(3), self.pyfile.size / 1048576))
if not data_left:
self.retry(wait_time=600, reason=_("Passport renewal"))
- self.handleDownload(False)
+ self.handle_download(False)
- def handleDownload(self, premium=False):
- # Find download link;
+ def handle_download(self, premium=False):
+ #: Find download link
m = re.search(self.LINK_PATTERN % (1 if premium else 2), self.html)
msg = _('%s download URL' % ('Premium' if premium else 'Free'))
if m is None:
self.error(msg)
self.link = m.group(1)
- self.logDebug("%s: %s" % (msg, self.link))
+ self.log_debug("%s: %s" % (msg, self.link))
getInfo = create_getInfo(MegasharesCom)
diff --git a/module/plugins/hoster/MegauploadCom.py b/module/plugins/hoster/MegauploadCom.py
index 590819f7f..468734c35 100644
--- a/module/plugins/hoster/MegauploadCom.py
+++ b/module/plugins/hoster/MegauploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class MegauploadCom(DeadHoster):
__name__ = "MegauploadCom"
__type__ = "hoster"
- __version__ = "0.31"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?megaupload\.com/\?.*&?(d|v)=\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/MegavideoCom.py b/module/plugins/hoster/MegavideoCom.py
index accd079fc..a3339a932 100644
--- a/module/plugins/hoster/MegavideoCom.py
+++ b/module/plugins/hoster/MegavideoCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class MegavideoCom(DeadHoster):
__name__ = "MegavideoCom"
__type__ = "hoster"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?megavideo\.com/\?.*&?(d|v)=\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/MovReelCom.py b/module/plugins/hoster/MovReelCom.py
index 2fe5184ae..dd70ce009 100644
--- a/module/plugins/hoster/MovReelCom.py
+++ b/module/plugins/hoster/MovReelCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class MovReelCom(XFSHoster):
__name__ = "MovReelCom"
__type__ = "hoster"
- __version__ = "1.24"
+ __version__ = "1.25"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?movreel\.com/\w{12}'
diff --git a/module/plugins/hoster/MultihostersCom.py b/module/plugins/hoster/MultihostersCom.py
index bcd7c6237..11c6c4379 100644
--- a/module/plugins/hoster/MultihostersCom.py
+++ b/module/plugins/hoster/MultihostersCom.py
@@ -6,7 +6,8 @@ from module.plugins.hoster.ZeveraCom import ZeveraCom
class MultihostersCom(ZeveraCom):
__name__ = "MultihostersCom"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)multihosters\.com/(getFiles\.ashx|Members/download\.ashx)\?.*ourl=.+'
diff --git a/module/plugins/hoster/MultishareCz.py b/module/plugins/hoster/MultishareCz.py
index bbb77f525..6b69fa9c2 100644
--- a/module/plugins/hoster/MultishareCz.py
+++ b/module/plugins/hoster/MultishareCz.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class MultishareCz(SimpleHoster):
__name__ = "MultishareCz"
__type__ = "hoster"
- __version__ = "0.40"
+ __version__ = "0.42"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?multishare\.cz/stahnout/(?P<ID>\d+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -22,26 +23,26 @@ class MultishareCz(SimpleHoster):
SIZE_REPLACEMENTS = [('&nbsp;', '')]
CHECK_TRAFFIC = True
- MULTI_HOSTER = True
+ LEECH_HOSTER = True
INFO_PATTERN = ur'(?:<li>Název|Soubor): <strong>(?P<N>[^<]+)</strong><(?:/li><li|br)>Velikost: <strong>(?P<S>[^<]+)</strong>'
OFFLINE_PATTERN = ur'<h1>Stáhnout soubor</h1><p><strong>PoşadovanÜ soubor neexistuje.</strong></p>'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.download("http://www.multishare.cz/html/download_free.php", get={'ID': self.info['pattern']['ID']})
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.download("http://www.multishare.cz/html/download_premium.php", get={'ID': self.info['pattern']['ID']})
- def handleMulti(self, pyfile):
- self.html = self.load('http://www.multishare.cz/html/mms_ajax.php', post={"link": pyfile.url}, decode=True)
+ def handle_multi(self, pyfile):
+ self.html = self.load('http://www.multishare.cz/html/mms_ajax.php', post={'link': pyfile.url})
- self.checkInfo()
+ self.check_info()
- if not self.checkTrafficLeft():
+ if not self.check_traffic_left():
self.fail(_("Not enough credit left to download file"))
self.download("http://dl%d.mms.multishare.cz/html/mms_process.php" % round(random.random() * 10000 * random.random()),
diff --git a/module/plugins/hoster/MyfastfileCom.py b/module/plugins/hoster/MyfastfileCom.py
index 662638843..bbd678ba0 100644
--- a/module/plugins/hoster/MyfastfileCom.py
+++ b/module/plugins/hoster/MyfastfileCom.py
@@ -9,10 +9,12 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class MyfastfileCom(MultiHoster):
__name__ = "MyfastfileCom"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'http://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/dl/'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Myfastfile.com multi-hoster plugin"""
__license__ = "GPLv3"
@@ -20,14 +22,14 @@ class MyfastfileCom(MultiHoster):
def setup(self):
- self.chunkLimit = -1
+ self.chunk_limit = -1
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.html = self.load('http://myfastfile.com/api.php',
- get={'user': self.user, 'pass': self.account.getAccountData(self.user)['password'],
+ get={'user': self.user, 'pass': self.account.get_info(self.user)['login']['password'],
'link': pyfile.url})
- self.logDebug("JSON data: " + self.html)
+ self.log_debug("JSON data: " + self.html)
self.html = json_loads(self.html)
if self.html['status'] != 'ok':
diff --git a/module/plugins/hoster/MystoreTo.py b/module/plugins/hoster/MystoreTo.py
index 531368134..e4432f491 100644
--- a/module/plugins/hoster/MystoreTo.py
+++ b/module/plugins/hoster/MystoreTo.py
@@ -11,7 +11,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class MystoreTo(SimpleHoster):
__name__ = "MystoreTo"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?mystore\.to/dl/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -27,12 +28,12 @@ class MystoreTo(SimpleHoster):
def setup(self):
- self.chunkLimit = 1
- self.resumeDownload = True
+ self.chunk_limit = 1
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
try:
fid = re.search(r'wert="(.+?)"', self.html).group(1)
diff --git a/module/plugins/hoster/MyvideoDe.py b/module/plugins/hoster/MyvideoDe.py
index 8af4a9a61..9abb0abe9 100644
--- a/module/plugins/hoster/MyvideoDe.py
+++ b/module/plugins/hoster/MyvideoDe.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.Hoster import Hoster
-from module.unescape import unescape
+from module.plugins.internal.Hoster import Hoster
+from module.utils import html_unescape
class MyvideoDe(Hoster):
__name__ = "MyvideoDe"
__type__ = "hoster"
- __version__ = "0.90"
+ __version__ = "0.92"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?myvideo\.de/watch/'
@@ -38,7 +39,7 @@ class MyvideoDe(Hoster):
def get_file_name(self):
file_name_pattern = r'<h1 class=\'globalHd\'>(.*)</h1>'
- return unescape(re.search(file_name_pattern, self.html).group(1).replace("/", "") + '.flv')
+ return html_unescape(re.search(file_name_pattern, self.html).group(1).replace("/", "") + '.flv')
def file_exists(self):
diff --git a/module/plugins/hoster/NahrajCz.py b/module/plugins/hoster/NahrajCz.py
index cf708be09..0d710c9b0 100644
--- a/module/plugins/hoster/NahrajCz.py
+++ b/module/plugins/hoster/NahrajCz.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class NahrajCz(DeadHoster):
__name__ = "NahrajCz"
__type__ = "hoster"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?nahraj\.cz/content/download/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/NarodRu.py b/module/plugins/hoster/NarodRu.py
index c201ac250..b0d4a4960 100644
--- a/module/plugins/hoster/NarodRu.py
+++ b/module/plugins/hoster/NarodRu.py
@@ -10,7 +10,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class NarodRu(SimpleHoster):
__name__ = "NarodRu"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?narod(\.yandex)?\.ru/(disk|start/\d+\.\w+-narod\.yandex\.ru)/(?P<ID>\d+)/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -32,7 +33,7 @@ class NarodRu(SimpleHoster):
LINK_FREE_PATTERN = r'<a class="h-link" rel="yandex_bar" href="(.+?)">'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
for _i in xrange(5):
self.html = self.load('http://narod.ru/disk/getcapchaxml/?rnd=%d' % int(random.random() * 777))
@@ -40,20 +41,20 @@ class NarodRu(SimpleHoster):
if m is None:
self.error(_("Captcha"))
- post_data = {"action": "sendcapcha"}
+ post_data = {'action': "sendcapcha"}
captcha_url, post_data['key'] = m.groups()
- post_data['rep'] = self.decryptCaptcha(captcha_url)
+ post_data['rep'] = self.captcha.decrypt(captcha_url)
- self.html = self.load(pyfile.url, post=post_data, decode=True)
+ self.html = self.load(pyfile.url, post=post_data)
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
self.link = urlparse.urljoin("http://narod.ru", m.group(1))
- self.correctCaptcha()
+ self.captcha.correct()
break
elif u'<b class="error-msg"><strong>ОшОблОсь?</strong>' in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
self.error(_("Download link"))
diff --git a/module/plugins/hoster/NetloadIn.py b/module/plugins/hoster/NetloadIn.py
index 82f5c22fb..ff9e75c72 100644
--- a/module/plugins/hoster/NetloadIn.py
+++ b/module/plugins/hoster/NetloadIn.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class NetloadIn(DeadHoster):
__name__ = "NetloadIn"
__type__ = "hoster"
- __version__ = "0.50"
+ __version__ = "0.51"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?netload\.(in|me)/(?P<PATH>datei|index\.php\?id=10&file_id=)(?P<ID>\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/NitroflareCom.py b/module/plugins/hoster/NitroflareCom.py
index a86d1af24..ad0573960 100644
--- a/module/plugins/hoster/NitroflareCom.py
+++ b/module/plugins/hoster/NitroflareCom.py
@@ -2,30 +2,29 @@
import re
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster
class NitroflareCom(SimpleHoster):
__name__ = "NitroflareCom"
__type__ = "hoster"
- __version__ = "0.13"
+ __version__ = "0.15"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?nitroflare\.com/view/(?P<ID>[\w^_]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
__description__ = """Nitroflare.com hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("sahil", "sahilshekhawat01@gmail.com"),
- ("Walter Purcaro", "vuolter@gmail.com"),
- ("Stickell", "l.stickell@yahoo.it")]
-
- # URL_REPLACEMENTS = [("http://", "https://")]
+ __authors__ = [("sahil" , "sahilshekhawat01@gmail.com"),
+ ("Walter Purcaro", "vuolter@gmail.com" ),
+ ("Stickell" , "l.stickell@yahoo.it" )]
INFO_PATTERN = r'title="(?P<N>.+?)".+>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
OFFLINE_PATTERN = r'>File doesn\'t exist'
- LINK_FREE_PATTERN = r'(https?://[\w\-]+\.nitroflare\.com/.+?)"'
+ LINK_PREMIUM_PATTERN = LINK_FREE_PATTERN = r'(https?://[\w\-]+\.nitroflare\.com/.+?)"'
RECAPTCHA_KEY = "6Lenx_USAAAAAF5L1pmTWvWcH73dipAEzNnmNLgy"
PREMIUM_ONLY_PATTERN = r'This file is available with Premium only'
@@ -33,15 +32,15 @@ class NitroflareCom(SimpleHoster):
# ERROR_PATTERN = r'downloading is not possible'
- def handleFree(self, pyfile):
- # used here to load the cookies which will be required later
+ def handle_free(self, pyfile):
+ #: Used here to load the cookies which will be required later
self.load(pyfile.url, post={'goToFreePage': ""})
self.load("http://nitroflare.com/ajax/setCookie.php", post={'fileId': self.info['pattern']['ID']})
self.html = self.load("http://nitroflare.com/ajax/freeDownload.php",
post={'method': "startTimer", 'fileId': self.info['pattern']['ID']})
- self.checkErrors()
+ self.check_errors()
try:
js_file = self.load("http://nitroflare.com/js/downloadFree.js?v=1.0.1")
@@ -61,12 +60,4 @@ class NitroflareCom(SimpleHoster):
'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
- if "The captcha wasn't entered correctly" in self.html:
- self.logWarning("The captcha wasn't entered correctly")
- return
-
- if "You have to fill the captcha" in self.html:
- self.logWarning("Captcha unfilled")
- return
-
- return super(NitroflareCom, self).handleFree(pyfile)
+ return super(NitroflareCom, self).handle_free(pyfile)
diff --git a/module/plugins/hoster/NoPremiumPl.py b/module/plugins/hoster/NoPremiumPl.py
index c3313c525..9e2a5a93c 100644
--- a/module/plugins/hoster/NoPremiumPl.py
+++ b/module/plugins/hoster/NoPremiumPl.py
@@ -7,10 +7,12 @@ from module.plugins.internal.MultiHoster import MultiHoster
class NoPremiumPl(MultiHoster):
__name__ = "NoPremiumPl"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://direct\.nopremium\.pl.+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """NoPremium.pl multi-hoster plugin"""
__license__ = "GPLv3"
@@ -37,68 +39,68 @@ class NoPremiumPl(MultiHoster):
def prepare(self):
super(NoPremiumPl, self).prepare()
- data = self.account.getAccountData(self.user)
+ data = self.account.get_data(self.user)
self.usr = data['usr']
self.pwd = data['pwd']
- def runFileQuery(self, url, mode=None):
+ def run_file_query(self, url, mode=None):
query = self.API_QUERY.copy()
- query["username"] = self.usr
- query["password"] = self.pwd
- query["url"] = url
+ query['username'] = self.usr
+ query['password'] = self.pwd
+ query['url'] = url
if mode == "fileinfo":
query['check'] = 2
query['loc'] = 1
- self.logDebug(query)
+ self.log_debug(query)
return self.load(self.API_URL, post=query)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
try:
- data = self.runFileQuery(pyfile.url, 'fileinfo')
+ data = self.run_file_query(pyfile.url, 'fileinfo')
except Exception:
- self.logDebug("runFileQuery error")
- self.tempOffline()
+ self.log_debug("runFileQuery error")
+ self.temp_offline()
try:
parsed = json_loads(data)
except Exception:
- self.logDebug("loads error")
- self.tempOffline()
+ self.log_debug("loads error")
+ self.temp_offline()
- self.logDebug(parsed)
+ self.log_debug(parsed)
if "errno" in parsed.keys():
- if parsed["errno"] in self.ERROR_CODES:
- # error code in known
- self.fail(self.ERROR_CODES[parsed["errno"]] % self.__name__)
+ if parsed['errno'] in self.ERROR_CODES:
+ #: Error code in known
+ self.fail(self.ERROR_CODES[parsed['errno']] % self.__name__)
else:
- # error code isn't yet added to plugin
+ #: Error code isn't yet added to plugin
self.fail(
- parsed["errstring"]
- or _("Unknown error (code: %s)") % parsed["errno"]
+ parsed['errstring']
+ or _("Unknown error (code: %s)") % parsed['errno']
)
if "sdownload" in parsed:
- if parsed["sdownload"] == "1":
+ if parsed['sdownload'] == "1":
self.fail(
_("Download from %s is possible only using NoPremium.pl website \
- directly") % parsed["hosting"])
+ directly") % parsed['hosting'])
- pyfile.name = parsed["filename"]
- pyfile.size = parsed["filesize"]
+ pyfile.name = parsed['filename']
+ pyfile.size = parsed['filesize']
try:
- self.link = self.runFileQuery(pyfile.url, 'filedownload')
+ self.link = self.run_file_query(pyfile.url, 'filedownload')
except Exception:
- self.logDebug("runFileQuery error #2")
- self.tempOffline()
+ self.log_debug("runFileQuery error #2")
+ self.temp_offline()
diff --git a/module/plugins/hoster/NosuploadCom.py b/module/plugins/hoster/NosuploadCom.py
index 241ee3a29..7de26f3fb 100644
--- a/module/plugins/hoster/NosuploadCom.py
+++ b/module/plugins/hoster/NosuploadCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class NosuploadCom(XFSHoster):
__name__ = "NosuploadCom"
__type__ = "hoster"
- __version__ = "0.31"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?nosupload\.com/\?d=\w{12}'
@@ -23,19 +24,19 @@ class NosuploadCom(XFSHoster):
WAIT_PATTERN = r'Please wait.*?>(\d+)</span>'
- def getDownloadLink(self):
- # stage1: press the "Free Download" button
- data = self.getPostParameters()
- self.html = self.load(self.pyfile.url, post=data, decode=True)
+ def get_download_link(self):
+ #: stage1: press the "Free Download" button
+ data = self.get_post_parameters()
+ self.html = self.load(self.pyfile.url, post=data)
- # stage2: wait some time and press the "Download File" button
- data = self.getPostParameters()
+ #: stage2: wait some time and press the "Download File" button
+ data = self.get_post_parameters()
wait_time = re.search(self.WAIT_PATTERN, self.html, re.M | re.S).group(1)
- self.logDebug("Hoster told us to wait %s seconds" % wait_time)
+ self.log_debug("Hoster told us to wait %s seconds" % wait_time)
self.wait(wait_time)
- self.html = self.load(self.pyfile.url, post=data, decode=True)
+ self.html = self.load(self.pyfile.url, post=data)
- # stage3: get the download link
+ #: stage3: get the download link
return re.search(self.LINK_PATTERN, self.html, re.S).group(1)
diff --git a/module/plugins/hoster/NovafileCom.py b/module/plugins/hoster/NovafileCom.py
index b00f71635..9ae73b1a8 100644
--- a/module/plugins/hoster/NovafileCom.py
+++ b/module/plugins/hoster/NovafileCom.py
@@ -10,7 +10,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class NovafileCom(XFSHoster):
__name__ = "NovafileCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?novafile\.com/\w{12}'
diff --git a/module/plugins/hoster/NowDownloadSx.py b/module/plugins/hoster/NowDownloadSx.py
index a1cf9baf7..876a7bcb5 100644
--- a/module/plugins/hoster/NowDownloadSx.py
+++ b/module/plugins/hoster/NowDownloadSx.py
@@ -9,7 +9,8 @@ from module.utils import fixup
class NowDownloadSx(SimpleHoster):
__name__ = "NowDownloadSx"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.11"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(nowdownload\.[a-zA-Z]{2,}/(dl/|download\.php.+?id=|mobile/(#/files/|.+?id=))|likeupload\.org/)\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -26,18 +27,18 @@ class NowDownloadSx(SimpleHoster):
TOKEN_PATTERN = r'"(/api/token\.php\?token=\w+)"'
CONTINUE_PATTERN = r'"(/dl2/\w+/\w+)"'
WAIT_PATTERN = r'\.countdown\(\{until: \+(\d+),'
- LINK_FREE_PATTERN = r'(http://s\d+\.coolcdn\.info/nowdownload/.+?)["\']'
+ LINK_FREE_PATTERN = r'(http://s\d+(?:\.coolcdn\.info|\.mighycdndelivery\.com)/nowdownload/.+?)["\']'
NAME_REPLACEMENTS = [("&#?\w+;", fixup), (r'<.*?>', '')]
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- self.chunkLimit = -1
+ self.chunk_limit = -1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
tokenlink = re.search(self.TOKEN_PATTERN, self.html)
continuelink = re.search(self.CONTINUE_PATTERN, self.html)
if tokenlink is None or continuelink is None:
@@ -49,7 +50,7 @@ class NowDownloadSx(SimpleHoster):
else:
wait = 60
- baseurl = "http://www.nowdownload.at"
+ baseurl = "http://www.nowdownload.ch"
self.html = self.load(baseurl + str(tokenlink.group(1)))
self.wait(wait)
diff --git a/module/plugins/hoster/NowVideoSx.py b/module/plugins/hoster/NowVideoSx.py
index 477379597..c1f369f2a 100644
--- a/module/plugins/hoster/NowVideoSx.py
+++ b/module/plugins/hoster/NowVideoSx.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class NowVideoSx(SimpleHoster):
__name__ = "NowVideoSx"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?nowvideo\.[a-zA-Z]{2,}/(video/|mobile/(#/videos/|.+?id=))(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -28,11 +29,11 @@ class NowVideoSx(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.html = self.load("http://www.nowvideo.sx/mobile/video.php", get={'id': self.info['pattern']['ID']})
m = re.search(self.LINK_FREE_PATTERN, self.html)
diff --git a/module/plugins/hoster/OboomCom.py b/module/plugins/hoster/OboomCom.py
index b50e2fb42..8420c6f02 100644
--- a/module/plugins/hoster/OboomCom.py
+++ b/module/plugins/hoster/OboomCom.py
@@ -6,18 +6,19 @@
import re
from module.common.json_layer import json_loads
-from module.plugins.Hoster import Hoster
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.internal.Hoster import Hoster
+from module.plugins.captcha.ReCaptcha import ReCaptcha
class OboomCom(Hoster):
__name__ = "OboomCom"
__type__ = "hoster"
- __version__ = "0.33"
+ __version__ = "0.36"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?oboom\.com/(?:#(?:id=|/)?)?(?P<ID>\w{8})'
- __description__ = """oboom.com hoster plugin"""
+ __description__ = """Oboom.com hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("stanley", "stanley.foerster@gmail.com")]
@@ -26,120 +27,119 @@ class OboomCom(Hoster):
def setup(self):
- self.chunkLimit = 1
- self.multiDL = self.resumeDownload = self.premium
+ self.chunk_limit = 1
+ self.multiDL = self.resume_download = self.premium
def process(self, pyfile):
self.pyfile.url.replace(".com/#id=", ".com/#")
self.pyfile.url.replace(".com/#/", ".com/#")
self.html = self.load(pyfile.url)
- self.getFileId(self.pyfile.url)
- self.getSessionToken()
- self.getFileInfo(self.sessionToken, self.fileId)
- self.pyfile.name = self.fileName
- self.pyfile.size = self.fileSize
+ self.get_file_id(self.pyfile.url)
+ self.get_session_token()
+ self.get_fileInfo(self.session_token, self.file_id)
+ self.pyfile.name = self.file_name
+ self.pyfile.size = self.file_size
if not self.premium:
- self.solveCaptcha()
- self.getDownloadTicket()
- self.download("https://%s/1.0/dlh" % self.downloadDomain, get={"ticket": self.downloadTicket, "http_errors": 0})
+ self.solve_captcha()
+ self.get_download_ticket()
+ self.download("http://%s/1.0/dlh" % self.download_domain, get={'ticket': self.download_ticket, 'http_errors': 0})
- def loadUrl(self, url, get=None):
+ def load_url(self, url, get=None):
if get is None:
- get = dict()
- return json_loads(self.load(url, get, decode=True))
+ get = {}
+ return json_loads(self.load(url, get))
- def getFileId(self, url):
- self.fileId = re.match(OboomCom.__pattern__, url).group('ID')
+ def get_file_id(self, url):
+ self.file_id = re.match(OboomCom.__pattern__, url).group('ID')
- def getSessionToken(self):
+ def get_session_token(self):
if self.premium:
- accountInfo = self.account.getAccountInfo(self.user, True)
+ accountInfo = self.account.get_data(self.user, True)
if "session" in accountInfo:
- self.sessionToken = accountInfo['session']
+ self.session_token = accountInfo['session']
else:
self.fail(_("Could not retrieve premium session"))
else:
- apiUrl = "https://www.oboom.com/1.0/guestsession"
- result = self.loadUrl(apiUrl)
+ apiUrl = "http://www.oboom.com/1.0/guestsession"
+ result = self.load_url(apiUrl)
if result[0] == 200:
- self.sessionToken = result[1]
+ self.session_token = result[1]
else:
self.fail(_("Could not retrieve token for guest session. Error code: %s") % result[0])
- def solveCaptcha(self):
+ def solve_captcha(self):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
- apiUrl = "https://www.oboom.com/1.0/download/ticket"
- params = {"recaptcha_challenge_field": challenge,
- "recaptcha_response_field": response,
- "download_id": self.fileId,
- "token": self.sessionToken}
- result = self.loadUrl(apiUrl, params)
+ apiUrl = "http://www.oboom.com/1.0/download/ticket"
+ params = {'recaptcha_challenge_field': challenge,
+ 'recaptcha_response_field': response,
+ 'download_id': self.file_id,
+ 'token': self.session_token}
+ result = self.load_url(apiUrl, params)
if result[0] == 200:
- self.downloadToken = result[1]
- self.downloadAuth = result[2]
- self.correctCaptcha()
- self.setWait(30)
- self.wait()
+ self.download_token = result[1]
+ self.download_auth = result[2]
+ self.captcha.correct()
+ self.wait(30)
break
elif result[0] == 400:
if result[1] == "incorrect-captcha-sol":
- self.invalidCaptcha()
+ self.captcha.invalid()
elif result[1] == "captcha-timeout":
- self.invalidCaptcha()
+ self.captcha.invalid()
elif result[1] == "forbidden":
self.retry(5, 15 * 60, _("Service unavailable"))
elif result[0] == 403:
- if result[1] == -1: # another download is running
- self.setWait(15 * 60)
+ if result[1] == -1: #: Another download is running
+ self.set_wait(15 * 60)
else:
- self.setWait(result[1], True)
+ self.set_wait(result[1], True)
self.wait()
self.retry(5)
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
self.fail(_("Received invalid captcha 5 times"))
- def getFileInfo(self, token, fileId):
- apiUrl = "https://api.oboom.com/1.0/info"
- params = {"token": token, "items": fileId, "http_errors": 0}
+ def get_fileInfo(self, token, fileId):
+ apiUrl = "http://api.oboom.com/1.0/info"
+ params = {'token': token, 'items': fileId, 'http_errors': 0}
- result = self.loadUrl(apiUrl, params)
+ result = self.load_url(apiUrl, params)
if result[0] == 200:
item = result[1][0]
if item['state'] == "online":
- self.fileSize = item['size']
- self.fileName = item['name']
+ self.file_size = item['size']
+ self.file_name = item['name']
else:
self.offline()
else:
self.fail(_("Could not retrieve file info. Error code %s: %s") % (result[0], result[1]))
- def getDownloadTicket(self):
- apiUrl = "https://api.oboom.com/1/dl"
- params = {"item": self.fileId, "http_errors": 0}
+ def get_download_ticket(self):
+ apiUrl = "http://api.oboom.com/1/dl"
+ params = {'item': self.file_id, 'http_errors': 0}
if self.premium:
- params['token'] = self.sessionToken
+ params['token'] = self.session_token
else:
- params['token'] = self.downloadToken
- params['auth'] = self.downloadAuth
+ params['token'] = self.download_token
+ params['auth'] = self.download_auth
- result = self.loadUrl(apiUrl, params)
+ result = self.load_url(apiUrl, params)
if result[0] == 200:
- self.downloadDomain = result[1]
- self.downloadTicket = result[2]
+ self.download_domain = result[1]
+ self.download_ticket = result[2]
elif result[0] == 421:
self.retry(wait_time=result[2] + 60, reason=_("Connection limit exceeded"))
else:
diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py
index 4b947c554..c564dc677 100644
--- a/module/plugins/hoster/OneFichierCom.py
+++ b/module/plugins/hoster/OneFichierCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class OneFichierCom(SimpleHoster):
__name__ = "OneFichierCom"
__type__ = "hoster"
- __version__ = "0.84"
+ __version__ = "0.86"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(?:(?P<ID1>\w+)\.)?(?P<HOST>1fichier\.com|alterupload\.com|cjoint\.net|d(es)?fichiers\.com|dl4free\.com|megadl\.fr|mesfichiers\.org|piecejointe\.net|pjointe\.com|tenvoi\.com)(?:/\?(?P<ID2>\w+))?'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -26,7 +27,6 @@ class OneFichierCom(SimpleHoster):
COOKIES = [("1fichier.com", "LG", "en")]
- DISPOSITION = False #: Remove in 0.4.10
NAME_PATTERN = r'>FileName :</td>\s*<td.*>(?P<N>.+?)<'
SIZE_PATTERN = r'>Size :</td>\s*<td.*>(?P<S>[\d.,]+) (?P<U>[\w^_]+)'
@@ -37,25 +37,25 @@ class OneFichierCom(SimpleHoster):
def setup(self):
self.multiDL = self.premium
- self.resumeDownload = True
+ self.resume_download = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
id = self.info['pattern']['ID1'] or self.info['pattern']['ID2']
- url, inputs = self.parseHtmlForm('action="https://1fichier.com/\?%s' % id)
+ url, inputs = self.parse_html_form('action="https://1fichier.com/\?%s' % id)
if not url:
self.fail(_("Download link not found"))
if "pass" in inputs:
- inputs['pass'] = self.getPassword()
+ inputs['pass'] = self.get_password()
inputs['submit'] = "Download"
self.download(url, post=inputs)
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.download(pyfile.url, post={'dl': "Download", 'did': 0})
diff --git a/module/plugins/hoster/OpenloadIo.py b/module/plugins/hoster/OpenloadIo.py
index c31b5b997..c46462344 100644
--- a/module/plugins/hoster/OpenloadIo.py
+++ b/module/plugins/hoster/OpenloadIo.py
@@ -6,21 +6,26 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class OpenloadIo(SimpleHoster):
__name__ = "OpenloadIo"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.04"
+ __status__ = "testing"
- __pattern__ = r'https?://(?:www\.)?openload\.io/f/\w{11}'
+ __pattern__ = r'https?://(?:www\.)?openload\.io/f/[\w_-]{11}'
__description__ = """Openload.io hoster plugin"""
__license__ = "GPLv3"
+ __authors__ = [(None, None)]
- NAME_PATTERN = r'<span id="filename">(?P<N>.+)</'
- SIZE_PATTERN = r'<span class="count">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<'
+
+ NAME_PATTERN = r'<span id="filename">(?P<N>.+?)</'
+ SIZE_PATTERN = r'<span class="count">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<'
OFFLINE_PATTERN = r">(We can't find the file you are looking for)"
- LINK_FREE_PATTERN = r'id="realdownload"><a href="(https?://[\w\.]+\.openload\.io/dl/.*?)"'
+ LINK_FREE_PATTERN = r'id="real\w*download"><a href="(https?://[\w\.]+\.openload\.io/dl/.*?)"'
+
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
+
getInfo = create_getInfo(OpenloadIo)
diff --git a/module/plugins/hoster/OronCom.py b/module/plugins/hoster/OronCom.py
index 2e4961704..e1887ce76 100644
--- a/module/plugins/hoster/OronCom.py
+++ b/module/plugins/hoster/OronCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class OronCom(DeadHoster):
__name__ = "OronCom"
__type__ = "hoster"
- __version__ = "0.14"
+ __version__ = "0.15"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?oron\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/OverLoadMe.py b/module/plugins/hoster/OverLoadMe.py
index d06baa0f5..0b5bab6a5 100644
--- a/module/plugins/hoster/OverLoadMe.py
+++ b/module/plugins/hoster/OverLoadMe.py
@@ -5,16 +5,18 @@ import urllib
from module.common.json_layer import json_loads
from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
-from module.utils import parseFileSize
+from module.utils import parseFileSize as parse_size
class OverLoadMe(MultiHoster):
__name__ = "OverLoadMe"
__type__ = "hoster"
- __version__ = "0.11"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'https?://.*overload\.me/.+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Over-Load.me multi-hoster plugin"""
__license__ = "GPLv3"
@@ -22,30 +24,27 @@ class OverLoadMe(MultiHoster):
def setup(self):
- self.chunkLimit = 5
+ self.chunk_limit = 5
- def handlePremium(self, pyfile):
- https = "https" if self.getConfig('ssl') else "http"
- data = self.account.getAccountData(self.user)
- page = self.load(https + "://api.over-load.me/getdownload.php",
+ def handle_premium(self, pyfile):
+ data = self.account.get_data(self.user)
+ page = self.load("https://api.over-load.me/getdownload.php",
get={'auth': data['password'],
'link': pyfile.url})
data = json_loads(page)
- self.logDebug(data)
+ self.log_debug(data)
if data['error'] == 1:
- self.logWarning(data['msg'])
- self.tempOffline()
+ self.log_warning(data['msg'])
+ self.temp_offline()
else:
+ self.link = data['downloadlink']
if pyfile.name and pyfile.name.endswith('.tmp') and data['filename']:
pyfile.name = data['filename']
- pyfile.size = parseFileSize(data['filesize'])
-
- http_repl = ["http://", "https://"]
- self.link = data['downloadlink'].replace(*http_repl if self.getConfig('ssl') else *http_repl[::-1])
+ pyfile.size = parse_size(data['filesize'])
getInfo = create_getInfo(OverLoadMe)
diff --git a/module/plugins/hoster/PandaplaNet.py b/module/plugins/hoster/PandaplaNet.py
index ae8406d82..4efe20b5a 100644
--- a/module/plugins/hoster/PandaplaNet.py
+++ b/module/plugins/hoster/PandaplaNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class PandaplaNet(DeadHoster):
__name__ = "PandaplaNet"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?pandapla\.net/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/PornhostCom.py b/module/plugins/hoster/PornhostCom.py
index 0c3b84a9d..8b0a80c7f 100644
--- a/module/plugins/hoster/PornhostCom.py
+++ b/module/plugins/hoster/PornhostCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class PornhostCom(Hoster):
__name__ = "PornhostCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?pornhost\.com/(\d+/\d+\.html|\d+)'
@@ -26,14 +27,15 @@ class PornhostCom(Hoster):
self.download(self.get_file_url())
- # Old interface
+ #: Old interface
def download_html(self):
url = self.pyfile.url
self.html = self.load(url)
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
@@ -45,7 +47,7 @@ class PornhostCom(Hoster):
url = re.search(r'width: 894px; height: 675px">.*?<img src="(.*?)"', self.html)
if url is None:
url = re.search(r'"http://file\d+\.pornhost\.com/\d+/.*?"',
- self.html) # TODO: fix this one since it doesn't match
+ self.html) #@TODO: fix this one since it doesn't match
return url.group(1).strip()
@@ -68,7 +70,8 @@ class PornhostCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/PornhubCom.py b/module/plugins/hoster/PornhubCom.py
index 16ce36ea9..5345566a1 100644
--- a/module/plugins/hoster/PornhubCom.py
+++ b/module/plugins/hoster/PornhubCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class PornhubCom(Hoster):
__name__ = "PornhubCom"
__type__ = "hoster"
- __version__ = "0.50"
+ __version__ = "0.52"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?pornhub\.com/view_video\.php\?viewkey=\w+'
@@ -32,14 +33,15 @@ class PornhubCom(Hoster):
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
url = "http://www.pornhub.com//gateway.php"
video_id = self.pyfile.url.split('=')[-1]
- # thanks to jD team for this one v
+ #: Thanks to jD team for this one v
post_data = "\x00\x03\x00\x00\x00\x01\x00\x0c\x70\x6c\x61\x79\x65\x72\x43\x6f\x6e\x66\x69\x67\x00\x02\x2f\x31\x00\x00\x00\x44\x0a\x00\x00\x00\x03\x02\x00"
post_data += chr(len(video_id))
post_data += video_id
@@ -78,7 +80,8 @@ class PornhubCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/PotloadCom.py b/module/plugins/hoster/PotloadCom.py
index 5a41f7d3c..8279412e4 100644
--- a/module/plugins/hoster/PotloadCom.py
+++ b/module/plugins/hoster/PotloadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class PotloadCom(DeadHoster):
__name__ = "PotloadCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?potload\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/PremiumTo.py b/module/plugins/hoster/PremiumTo.py
index ab5016673..ec02bb12d 100644
--- a/module/plugins/hoster/PremiumTo.py
+++ b/module/plugins/hoster/PremiumTo.py
@@ -11,10 +11,12 @@ from module.utils import fs_encode
class PremiumTo(MultiHoster):
__name__ = "PremiumTo"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.25"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Premium.to multi-hoster plugin"""
__license__ = "GPLv3"
@@ -26,8 +28,8 @@ class PremiumTo(MultiHoster):
CHECK_TRAFFIC = True
- def handlePremium(self, pyfile):
- #raise timeout to 2min
+ def handle_premium(self, pyfile):
+ #: Raise timeout to 2 min
self.download("http://premium.to/api/getfile.php",
get={'username': self.account.username,
'password': self.account.password,
@@ -35,14 +37,14 @@ class PremiumTo(MultiHoster):
disposition=True)
- def checkFile(self, rules={}):
- if self.checkDownload({'nopremium': "No premium account available"}):
+ def check_file(self):
+ if self.check_download({'nopremium': "No premium account available"}):
self.retry(60, 5 * 60, "No premium account available")
- err = ''
- if self.req.http.code == '420':
- # Custom error code send - fail
- file = fs_encode(self.lastDownload)
+ err = ""
+ if self.req.http.code == "420":
+ #: Custom error code send - fail
+ file = fs_encode(self.last_download)
with open(file, "rb") as f:
err = f.read(256).strip()
os.remove(file)
@@ -50,7 +52,7 @@ class PremiumTo(MultiHoster):
if err:
self.fail(err)
- return super(PremiumTo, self).checkFile(rules)
+ return super(PremiumTo, self).check_file()
getInfo = create_getInfo(PremiumTo)
diff --git a/module/plugins/hoster/PremiumizeMe.py b/module/plugins/hoster/PremiumizeMe.py
index 3227fb001..d968eccec 100644
--- a/module/plugins/hoster/PremiumizeMe.py
+++ b/module/plugins/hoster/PremiumizeMe.py
@@ -7,38 +7,40 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class PremiumizeMe(MultiHoster):
__name__ = "PremiumizeMe"
__type__ = "hoster"
- __version__ = "0.16"
+ __version__ = "0.20"
+ __status__ = "testing"
- __pattern__ = r'^unmatchable$' #: Since we want to allow the user to specify the list of hoster to use we let MultiHoster.coreReady
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __pattern__ = r'^unmatchable$' #: Since we want to allow the user to specify the list of hoster to use we let MultiHoster.activate
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Premiumize.me multi-hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("Florian Franzen", "FlorianFranzen@gmail.com")]
- def handlePremium(self, pyfile):
- # In some cases hostsers do not supply us with a filename at download, so we
- # are going to set a fall back filename (e.g. for freakshare or xfileshare)
- pyfile.name = pyfile.name.split('/').pop() # Remove everthing before last slash
+ def handle_premium(self, pyfile):
+ #: In some cases hostsers do not supply us with a filename at download, so we
+ #: Are going to set a fall back filename (e.g. for freakshare or xfileshare)
+ pyfile.name = pyfile.name.split('/').pop() #: Remove everthing before last slash
- # Correction for automatic assigned filename: Removing html at end if needed
+ #: Correction for automatic assigned filename: Removing html at end if needed
suffix_to_remove = ["html", "htm", "php", "php3", "asp", "shtm", "shtml", "cfml", "cfm"]
temp = pyfile.name.split('.')
if temp.pop() in suffix_to_remove:
pyfile.name = ".".join(temp)
- # Get account data
- user, data = self.account.selectAccount()
+ #: Get account data
+ user, info = self.account.select()
- # Get rewritten link using the premiumize.me api v1 (see https://secure.premiumize.me/?show=api)
- data = json_loads(self.load("https://api.premiumize.me/pm-api/v1.php",
+ #: Get rewritten link using the premiumize.me api v1 (see https://secure.premiumize.me/?show=api)
+ data = json_loads(self.load("http://api.premiumize.me/pm-api/v1.php", #@TODO: Revert to `https` in 0.4.10
get={'method' : "directdownloadlink",
'params[login]': user,
- 'params[pass]' : data['password'],
+ 'params[pass]' : info['login']['password'],
'params[link]' : pyfile.url}))
- # Check status and decide what to do
+ #: Check status and decide what to do
status = data['status']
if status == 200:
@@ -52,7 +54,7 @@ class PremiumizeMe(MultiHoster):
self.offline()
elif status >= 500:
- self.tempOffline()
+ self.temp_offline()
else:
self.fail(data['statusmessage'])
diff --git a/module/plugins/hoster/PromptfileCom.py b/module/plugins/hoster/PromptfileCom.py
index 3815a1a24..5f7510123 100644
--- a/module/plugins/hoster/PromptfileCom.py
+++ b/module/plugins/hoster/PromptfileCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class PromptfileCom(SimpleHoster):
__name__ = "PromptfileCom"
__type__ = "hoster"
- __version__ = "0.13"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?promptfile\.com/'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -18,29 +19,27 @@ class PromptfileCom(SimpleHoster):
__authors__ = [("igel", "igelkun@myopera.com")]
- INFO_PATTERN = r'<span style=".+?" title=".+?">(?P<N>.*?) \((?P<S>[\d.,]+) (?P<U>[\w^_]+)\)</span>'
+ INFO_PATTERN = r'<span style=".+?" title=".+?">(?P<N>.*?) \((?P<S>[\d.,]+) (?P<U>[\w^_]+)\)</span>'
OFFLINE_PATTERN = r'<span style=".+?" title="File Not Found">File Not Found</span>'
- CHASH_PATTERN = r'<input type="hidden" name="chash" value="(.+?)" />'
+ CHASH_PATTERN = r'<input type="hidden" name="chash" value="(.+?)" />'
LINK_FREE_PATTERN = r'<a href=\"(.+)\" target=\"_blank\" class=\"view_dl_link\">Download File</a>'
- def handleFree(self, pyfile):
- # STAGE 1: get link to continue
+ def handle_free(self, pyfile):
+ #: STAGE 1: get link to continue
m = re.search(self.CHASH_PATTERN, self.html)
if m is None:
self.error(_("CHASH_PATTERN not found"))
+
chash = m.group(1)
- self.logDebug("Read chash %s" % chash)
- # continue to stage2
- self.html = self.load(pyfile.url, decode=True, post={'chash': chash})
+ self.log_debug("Read chash %s" % chash)
- # STAGE 2: get the direct link
- m = re.search(self.LINK_FREE_PATTERN, self.html)
- if m is None:
- self.error(_("LINK_FREE_PATTERN not found"))
+ #: Continue to stage2
+ self.html = self.load(pyfile.url, post={'chash': chash})
- self.link = m.group(1)
+ #: STAGE 2: get the direct link
+ return super(PromptfileCom, self).handle_free(pyfile)
getInfo = create_getInfo(PromptfileCom)
diff --git a/module/plugins/hoster/PrzeklejPl.py b/module/plugins/hoster/PrzeklejPl.py
index e984d0033..b066444da 100644
--- a/module/plugins/hoster/PrzeklejPl.py
+++ b/module/plugins/hoster/PrzeklejPl.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class PrzeklejPl(DeadHoster):
__name__ = "PrzeklejPl"
__type__ = "hoster"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?przeklej\.pl/plik/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/PutdriveCom.py b/module/plugins/hoster/PutdriveCom.py
index 7f4b7b6cc..e924fbcfc 100644
--- a/module/plugins/hoster/PutdriveCom.py
+++ b/module/plugins/hoster/PutdriveCom.py
@@ -6,7 +6,8 @@ from module.plugins.hoster.ZeveraCom import ZeveraCom
class PutdriveCom(ZeveraCom):
__name__ = "PutdriveCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)putdrive\.com/(getFiles\.ashx|Members/download\.ashx)\?.*ourl=.+'
diff --git a/module/plugins/hoster/QuickshareCz.py b/module/plugins/hoster/QuickshareCz.py
index 1e0750b88..4311a82aa 100644
--- a/module/plugins/hoster/QuickshareCz.py
+++ b/module/plugins/hoster/QuickshareCz.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class QuickshareCz(SimpleHoster):
__name__ = "QuickshareCz"
__type__ = "hoster"
- __version__ = "0.56"
+ __version__ = "0.57"
+ __status__ = "testing"
__pattern__ = r'http://(?:[^/]*\.)?quickshare\.cz/stahnout-soubor/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -25,39 +26,39 @@ class QuickshareCz(SimpleHoster):
def process(self, pyfile):
- self.html = self.load(pyfile.url, decode=True)
- self.getFileInfo()
+ self.html = self.load(pyfile.url)
+ self.get_fileInfo()
- # parse js variables
+ #: Parse js variables
self.jsvars = dict((x, y.strip("'")) for x, y in re.findall(r"var (\w+) = ([\d.]+|'.+?')", self.html))
- self.logDebug(self.jsvars)
+ self.log_debug(self.jsvars)
pyfile.name = self.jsvars['ID3']
- # determine download type - free or premium
+ #: Determine download type - free or premium
if self.premium:
if 'UU_prihlasen' in self.jsvars:
- if self.jsvars['UU_prihlasen'] == '0':
- self.logWarning(_("User not logged in"))
+ if self.jsvars['UU_prihlasen'] == "0":
+ self.log_warning(_("User not logged in"))
self.relogin(self.user)
self.retry()
elif float(self.jsvars['UU_kredit']) < float(self.jsvars['kredit_odecet']):
- self.logWarning(_("Not enough credit left"))
+ self.log_warning(_("Not enough credit left"))
self.premium = False
if self.premium:
- self.handlePremium(pyfile)
+ self.handle_premium(pyfile)
else:
- self.handleFree(pyfile)
+ self.handle_free(pyfile)
- if self.checkDownload({"error": re.compile(r"\AChyba!")}, max_size=100):
+ if self.check_download({'error': re.compile(r"\AChyba!")}, max_size=100):
self.fail(_("File not m or plugin defect"))
- def handleFree(self, pyfile):
- # get download url
+ def handle_free(self, pyfile):
+ #: Get download url
download_url = '%s/download.php' % self.jsvars['server']
data = dict((x, self.jsvars[x]) for x in self.jsvars if x in ("ID1", "ID2", "ID3", "ID4"))
- self.logDebug("FREE URL1:" + download_url, data)
+ self.log_debug("FREE URL1:" + download_url, data)
self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0)
self.load(download_url, post=data)
@@ -69,20 +70,20 @@ class QuickshareCz(SimpleHoster):
self.fail(_("File not found"))
self.link = m.group(1).rstrip() #@TODO: Remove .rstrip() in 0.4.10
- self.logDebug("FREE URL2:" + self.link)
+ self.log_debug("FREE URL2:" + self.link)
- # check errors
+ #: Check errors
m = re.search(r'/chyba/(\d+)', self.link)
if m:
- if m.group(1) == '1':
+ if m.group(1) == "1":
self.retry(60, 2 * 60, "This IP is already downloading")
- elif m.group(1) == '2':
+ elif m.group(1) == "2":
self.retry(60, 60, "No free slots available")
else:
self.fail(_("Error %d") % m.group(1))
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
download_url = '%s/download_premium.php' % self.jsvars['server']
data = dict((x, self.jsvars[x]) for x in self.jsvars if x in ("ID1", "ID2", "ID4", "ID5"))
self.download(download_url, get=data)
diff --git a/module/plugins/hoster/RPNetBiz.py b/module/plugins/hoster/RPNetBiz.py
index 710faf25c..62e6bee4e 100644
--- a/module/plugins/hoster/RPNetBiz.py
+++ b/module/plugins/hoster/RPNetBiz.py
@@ -9,10 +9,12 @@ from module.common.json_layer import json_loads
class RPNetBiz(MultiHoster):
__name__ = "RPNetBiz"
__type__ = "hoster"
- __version__ = "0.14"
+ __version__ = "0.17"
+ __status__ = "testing"
__pattern__ = r'https?://.+rpnet\.biz'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """RPNet.biz multi-hoster plugin"""
__license__ = "GPLv3"
@@ -20,53 +22,51 @@ class RPNetBiz(MultiHoster):
def setup(self):
- self.chunkLimit = -1
+ self.chunk_limit = -1
- def handlePremium(self, pyfile):
- user, data = self.account.selectAccount()
+ def handle_premium(self, pyfile):
+ user, info = self.account.select()
- # Get the download link
+ #: Get the download link
res = self.load("https://premium.rpnet.biz/client_api.php",
- get={"username": user,
- "password": data['password'],
- "action" : "generate",
- "links" : pyfile.url})
+ get={'username': user,
+ 'password': info['login']['password'],
+ 'action' : "generate",
+ 'links' : pyfile.url})
- self.logDebug("JSON data: %s" % res)
- link_status = json_loads(res)['links'][0] # get the first link... since we only queried one
+ self.log_debug("JSON data: %s" % res)
+ link_status = json_loads(res)['links'][0] #: Get the first link... since we only queried one
- # Check if we only have an id as a HDD link
+ #: Check if we only have an id as a HDD link
if 'id' in link_status:
- self.logDebug("Need to wait at least 30 seconds before requery")
- self.setWait(30) # wait for 30 seconds
- self.wait()
- # Lets query the server again asking for the status on the link,
- # we need to keep doing this until we reach 100
+ self.log_debug("Need to wait at least 30 seconds before requery")
+ self.wait(30) #: Wait for 30 seconds
+ #: Lets query the server again asking for the status on the link,
+ #: We need to keep doing this until we reach 100
max_tries = 30
my_try = 0
while (my_try <= max_tries):
- self.logDebug("Try: %d ; Max Tries: %d" % (my_try, max_tries))
+ self.log_debug("Try: %d ; Max Tries: %d" % (my_try, max_tries))
res = self.load("https://premium.rpnet.biz/client_api.php",
- get={"username": user,
- "password": data['password'],
- "action": "downloadInformation",
- "id": link_status['id']})
- self.logDebug("JSON data hdd query: %s" % res)
+ get={'username': user,
+ 'password': info['login']['password'],
+ 'action' : "downloadInformation",
+ 'id' : link_status['id']})
+ self.log_debug("JSON data hdd query: %s" % res)
download_status = json_loads(res)['download']
- if download_status['status'] == '100':
+ if download_status['status'] == "100":
link_status['generated'] = download_status['rpnet_link']
- self.logDebug("Successfully downloaded to rpnet HDD: %s" % link_status['generated'])
+ self.log_debug("Successfully downloaded to rpnet HDD: %s" % link_status['generated'])
break
else:
- self.logDebug("At %s%% for the file download" % download_status['status'])
+ self.log_debug("At %s%% for the file download" % download_status['status'])
- self.setWait(30)
- self.wait()
+ self.wait(30)
my_try += 1
- if my_try > max_tries: # We went over the limit!
+ if my_try > max_tries: #: We went over the limit!
self.fail(_("Waited for about 15 minutes for download to finish but failed"))
if 'generated' in link_status:
diff --git a/module/plugins/hoster/RapideoPl.py b/module/plugins/hoster/RapideoPl.py
index 50804e8cd..e1a0d278f 100644
--- a/module/plugins/hoster/RapideoPl.py
+++ b/module/plugins/hoster/RapideoPl.py
@@ -7,10 +7,12 @@ from module.plugins.internal.MultiHoster import MultiHoster
class RapideoPl(MultiHoster):
__name__ = "RapideoPl"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Rapideo.pl multi-hoster plugin"""
__license__ = "GPLv3"
@@ -37,68 +39,68 @@ class RapideoPl(MultiHoster):
def prepare(self):
super(RapideoPl, self).prepare()
- data = self.account.getAccountData(self.user)
+ data = self.account.get_data(self.user)
self.usr = data['usr']
self.pwd = data['pwd']
- def runFileQuery(self, url, mode=None):
+ def run_file_query(self, url, mode=None):
query = self.API_QUERY.copy()
- query["username"] = self.usr
- query["password"] = self.pwd
- query["url"] = url
+ query['username'] = self.usr
+ query['password'] = self.pwd
+ query['url'] = url
if mode == "fileinfo":
query['check'] = 2
query['loc'] = 1
- self.logDebug(query)
+ self.log_debug(query)
return self.load(self.API_URL, post=query)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
try:
- data = self.runFileQuery(pyfile.url, 'fileinfo')
+ data = self.run_file_query(pyfile.url, 'fileinfo')
except Exception:
- self.logDebug("RunFileQuery error")
- self.tempOffline()
+ self.log_debug("RunFileQuery error")
+ self.temp_offline()
try:
parsed = json_loads(data)
except Exception:
- self.logDebug("Loads error")
- self.tempOffline()
+ self.log_debug("Loads error")
+ self.temp_offline()
- self.logDebug(parsed)
+ self.log_debug(parsed)
if "errno" in parsed.keys():
- if parsed["errno"] in self.ERROR_CODES:
- # error code in known
- self.fail(self.ERROR_CODES[parsed["errno"]] % self.__name__)
+ if parsed['errno'] in self.ERROR_CODES:
+ #: Error code in known
+ self.fail(self.ERROR_CODES[parsed['errno']] % self.__name__)
else:
- # error code isn't yet added to plugin
+ #: Error code isn't yet added to plugin
self.fail(
- parsed["errstring"]
- or _("Unknown error (code: %s)") % parsed["errno"]
+ parsed['errstring']
+ or _("Unknown error (code: %s)") % parsed['errno']
)
if "sdownload" in parsed:
- if parsed["sdownload"] == "1":
+ if parsed['sdownload'] == "1":
self.fail(
_("Download from %s is possible only using Rapideo.pl website \
- directly") % parsed["hosting"])
+ directly") % parsed['hosting'])
- pyfile.name = parsed["filename"]
- pyfile.size = parsed["filesize"]
+ pyfile.name = parsed['filename']
+ pyfile.size = parsed['filesize']
try:
- self.link = self.runFileQuery(pyfile.url, 'filedownload')
+ self.link = self.run_file_query(pyfile.url, 'filedownload')
except Exception:
- self.logDebug("runFileQuery error #2")
- self.tempOffline()
+ self.log_debug("runFileQuery error #2")
+ self.temp_offline()
diff --git a/module/plugins/hoster/RapidfileshareNet.py b/module/plugins/hoster/RapidfileshareNet.py
index 0bbaed57f..5dd3ba82d 100644
--- a/module/plugins/hoster/RapidfileshareNet.py
+++ b/module/plugins/hoster/RapidfileshareNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class RapidfileshareNet(XFSHoster):
__name__ = "RapidfileshareNet"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?rapidfileshare\.net/\w{12}'
diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py
index bd6bb8582..636ea1bcc 100644
--- a/module/plugins/hoster/RapidgatorNet.py
+++ b/module/plugins/hoster/RapidgatorNet.py
@@ -5,16 +5,17 @@ import re
from module.common.json_layer import json_loads
from module.network.HTTPRequest import BadHeader
-from module.plugins.internal.AdsCaptcha import AdsCaptcha
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SolveMedia import SolveMedia
+from module.plugins.captcha.AdsCaptcha import AdsCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.captcha.SolveMedia import SolveMedia
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RapidgatorNet(SimpleHoster):
__name__ = "RapidgatorNet"
__type__ = "hoster"
- __version__ = "0.34"
+ __version__ = "0.35"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(rapidgator\.net|rg\.to)/file/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -50,29 +51,29 @@ class RapidgatorNet(SimpleHoster):
def setup(self):
if self.account:
- self.sid = self.account.getAccountInfo(self.user).get('sid', None)
+ self.sid = self.account.get_data(self.user).get('sid', None)
else:
self.sid = None
if self.sid:
self.premium = True
- self.resumeDownload = self.multiDL = self.premium
- self.chunkLimit = 1
+ self.resume_download = self.multiDL = self.premium
+ self.chunk_limit = 1
def api_response(self, cmd):
try:
json = self.load('%s/%s' % (self.API_URL, cmd),
get={'sid': self.sid,
- 'url': self.pyfile.url}, decode=True)
- self.logDebug("API:%s" % cmd, json, "SID: %s" % self.sid)
+ 'url': self.pyfile.url})
+ self.log_debug("API:%s" % cmd, json, "SID: %s" % self.sid)
json = json_loads(json)
status = json['response_status']
msg = json['response_details']
except BadHeader, e:
- self.logError("API: %s" % cmd, e, "SID: %s" % self.sid)
+ self.log_error("API: %s" % cmd, e, "SID: %s" % self.sid)
status = e.code
msg = e
@@ -88,7 +89,7 @@ class RapidgatorNet(SimpleHoster):
self.retry(wait_time=60)
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.api_data = self.api_response('info')
self.api_data['md5'] = self.api_data['hash']
@@ -98,22 +99,22 @@ class RapidgatorNet(SimpleHoster):
self.link = self.api_response('download')['url']
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
jsvars = dict(re.findall(self.JSVARS_PATTERN, self.html))
- self.logDebug(jsvars)
+ self.log_debug(jsvars)
self.req.http.lastURL = pyfile.url
self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With: XMLHttpRequest"])
url = "http://rapidgator.net%s?fid=%s" % (
jsvars.get('startTimerUrl', '/download/AjaxStartTimer'), jsvars['fid'])
- jsvars.update(self.getJsonResponse(url))
+ jsvars.update(self.get_json_response(url))
self.wait(jsvars.get('secs', 45), False)
url = "http://rapidgator.net%s?sid=%s" % (
jsvars.get('getDownloadUrl', '/download/AjaxGetDownload'), jsvars['sid'])
- jsvars.update(self.getJsonResponse(url))
+ jsvars.update(self.get_json_response(url))
self.req.http.lastURL = pyfile.url
self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With:"])
@@ -127,7 +128,7 @@ class RapidgatorNet(SimpleHoster):
self.link = m.group(1)
break
else:
- captcha = self.handleCaptcha()
+ captcha = self.handle_captcha()
if not captcha:
self.error(_("Captcha pattern not found"))
@@ -139,25 +140,25 @@ class RapidgatorNet(SimpleHoster):
'adcopy_response' : response})
if "The verification code is incorrect" in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.correctCaptcha()
+ self.captcha.correct()
else:
self.error(_("Download link"))
- def handleCaptcha(self):
+ def handle_captcha(self):
for klass in (AdsCaptcha, ReCaptcha, SolveMedia):
inst = klass(self)
if inst.detect_key():
return inst
- def getJsonResponse(self, url):
- res = self.load(url, decode=True)
+ def get_json_response(self, url):
+ res = self.load(url)
if not res.startswith('{'):
self.retry()
- self.logDebug(url, res)
+ self.log_debug(url, res)
return json_loads(res)
diff --git a/module/plugins/hoster/RapiduNet.py b/module/plugins/hoster/RapiduNet.py
index da353ec70..267f41f36 100644
--- a/module/plugins/hoster/RapiduNet.py
+++ b/module/plugins/hoster/RapiduNet.py
@@ -5,14 +5,15 @@ import re
import time
from module.common.json_layer import json_loads
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RapiduNet(SimpleHoster):
__name__ = "RapiduNet"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?rapidu\.net/(?P<ID>\d{10})'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -33,23 +34,22 @@ class RapiduNet(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = self.premium
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.req.http.lastURL = pyfile.url
self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With: XMLHttpRequest"])
- jsvars = self.getJsonResponse("https://rapidu.net/ajax.php",
+ jsvars = self.get_json_response("https://rapidu.net/ajax.php",
get={'a': "getLoadTimeToDownload"},
- post={'_go': ""},
- decode=True)
+ post={'_go': ""})
- if str(jsvars['timeToDownload']) is "stop":
+ if str(jsvars['timeToDownload']) == "stop":
t = (24 * 60 * 60) - (int(time.time()) % (24 * 60 * 60)) + time.altzone
- self.logInfo("You've reach your daily download transfer")
+ self.log_info(_("You've reach your daily download transfer"))
self.retry(10, 10 if t < 1 else None, _("Try tomorrow again")) #@NOTE: check t in case of not synchronised clock
@@ -59,24 +59,23 @@ class RapiduNet(SimpleHoster):
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
- jsvars = self.getJsonResponse("https://rapidu.net/ajax.php",
+ jsvars = self.get_json_response("https://rapidu.net/ajax.php",
get={'a': "getCheckCaptcha"},
post={'_go' : "",
'captcha1': challenge,
'captcha2': response,
- 'fileId' : self.info['pattern']['ID']},
- decode=True)
+ 'fileId' : self.info['pattern']['ID']})
- if jsvars['message'] == 'success':
+ if jsvars['message'] == "success":
self.link = jsvars['url']
- def getJsonResponse(self, *args, **kwargs):
+ def get_json_response(self, *args, **kwargs):
res = self.load(*args, **kwargs)
if not res.startswith('{'):
self.retry()
- self.logDebug(res)
+ self.log_debug(res)
return json_loads(res)
diff --git a/module/plugins/hoster/RarefileNet.py b/module/plugins/hoster/RarefileNet.py
index a45e4ed4d..7b19996dc 100644
--- a/module/plugins/hoster/RarefileNet.py
+++ b/module/plugins/hoster/RarefileNet.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class RarefileNet(XFSHoster):
__name__ = "RarefileNet"
__type__ = "hoster"
- __version__ = "0.09"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?rarefile\.net/\w{12}'
diff --git a/module/plugins/hoster/RealdebridCom.py b/module/plugins/hoster/RealdebridCom.py
index 4500fcefc..6409701e4 100644
--- a/module/plugins/hoster/RealdebridCom.py
+++ b/module/plugins/hoster/RealdebridCom.py
@@ -6,16 +6,18 @@ import urllib
from module.common.json_layer import json_loads
from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
-from module.utils import parseFileSize
+from module.utils import parseFileSize as parse_size
class RealdebridCom(MultiHoster):
__name__ = "RealdebridCom"
__type__ = "hoster"
- __version__ = "0.67"
+ __version__ = "0.69"
+ __status__ = "testing"
__pattern__ = r'https?://((?:www\.|s\d+\.)?real-debrid\.com/dl/|[\w^_]\.rdb\.so/d/)[\w^_]+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Real-Debrid.com multi-hoster plugin"""
__license__ = "GPLv3"
@@ -23,34 +25,29 @@ class RealdebridCom(MultiHoster):
def setup(self):
- self.chunkLimit = 3
+ self.chunk_limit = 3
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
data = json_loads(self.load("https://real-debrid.com/ajax/unrestrict.php",
get={'lang' : "en",
'link' : pyfile.url,
- 'password': self.getPassword(),
+ 'password': self.get_password(),
'time' : int(time.time() * 1000)}))
- self.logDebug("Returned Data: %s" % data)
+ self.log_debug("Returned Data: %s" % data)
if data['error'] != 0:
if data['message'] == "Your file is unavailable on the hoster.":
self.offline()
else:
- self.logWarning(data['message'])
- self.tempOffline()
+ self.log_warning(data['message'])
+ self.temp_offline()
else:
if pyfile.name and pyfile.name.endswith('.tmp') and data['file_name']:
pyfile.name = data['file_name']
- pyfile.size = parseFileSize(data['file_size'])
+ pyfile.size = parse_size(data['file_size'])
self.link = data['generated_links'][0][-1]
- if self.getConfig('ssl'):
- self.link = self.link.replace("http://", "https://")
- else:
- self.link = self.link.replace("https://", "http://")
-
getInfo = create_getInfo(RealdebridCom)
diff --git a/module/plugins/hoster/RedtubeCom.py b/module/plugins/hoster/RedtubeCom.py
index 9051c498a..94a0ead20 100644
--- a/module/plugins/hoster/RedtubeCom.py
+++ b/module/plugins/hoster/RedtubeCom.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.Hoster import Hoster
-from module.unescape import unescape
+from module.plugins.internal.Hoster import Hoster
+from module.utils import html_unescape
class RedtubeCom(Hoster):
__name__ = "RedtubeCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?redtube\.com/\d+'
@@ -33,14 +34,13 @@ class RedtubeCom(Hoster):
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
- file_url = unescape(re.search(r'hashlink=(http.*?)"', self.html).group(1))
-
- return file_url
+ return html_unescape(re.search(r'hashlink=(http.*?)"', self.html).group(1))
def get_file_name(self):
@@ -51,7 +51,8 @@ class RedtubeCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/RehostTo.py b/module/plugins/hoster/RehostTo.py
index 9c07364ec..6f0645e9f 100644
--- a/module/plugins/hoster/RehostTo.py
+++ b/module/plugins/hoster/RehostTo.py
@@ -8,20 +8,22 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class RehostTo(MultiHoster):
__name__ = "RehostTo"
__type__ = "hoster"
- __version__ = "0.21"
+ __version__ = "0.23"
+ __status__ = "testing"
__pattern__ = r'https?://.*rehost\.to\..+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Rehost.com multi-hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.download("http://rehost.to/process_download.php",
get={'user': "cookie",
- 'pass': self.account.getAccountInfo(self.user)['session'],
+ 'pass': self.account.get_data(self.user)['session'],
'dl' : pyfile.url},
disposition=True)
diff --git a/module/plugins/hoster/RemixshareCom.py b/module/plugins/hoster/RemixshareCom.py
index d60101aed..295362174 100644
--- a/module/plugins/hoster/RemixshareCom.py
+++ b/module/plugins/hoster/RemixshareCom.py
@@ -16,7 +16,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RemixshareCom(SimpleHoster):
__name__ = "RemixshareCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://remixshare\.com/(download|dl)/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -40,10 +41,10 @@ class RemixshareCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
b = re.search(self.LINK_PATTERN, self.html)
if not b:
self.error(_("File url"))
diff --git a/module/plugins/hoster/RgHostNet.py b/module/plugins/hoster/RgHostNet.py
index 1a45def44..0aa4b7d73 100644
--- a/module/plugins/hoster/RgHostNet.py
+++ b/module/plugins/hoster/RgHostNet.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class RgHostNet(SimpleHoster):
__name__ = "RgHostNet"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?rghost\.(net|ru)/[\d-]+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
diff --git a/module/plugins/hoster/SafesharingEu.py b/module/plugins/hoster/SafesharingEu.py
index 08612e413..e7d53fe75 100644
--- a/module/plugins/hoster/SafesharingEu.py
+++ b/module/plugins/hoster/SafesharingEu.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class SafesharingEu(XFSHoster):
__name__ = "SafesharingEu"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?safesharing\.eu/\w{12}'
diff --git a/module/plugins/hoster/SecureUploadEu.py b/module/plugins/hoster/SecureUploadEu.py
index 6bfbce328..df2ac1627 100644
--- a/module/plugins/hoster/SecureUploadEu.py
+++ b/module/plugins/hoster/SecureUploadEu.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class SecureUploadEu(XFSHoster):
__name__ = "SecureUploadEu"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?secureupload\.eu/\w{12}'
diff --git a/module/plugins/hoster/SendspaceCom.py b/module/plugins/hoster/SendspaceCom.py
index 0ab20949d..13dd20b7c 100644
--- a/module/plugins/hoster/SendspaceCom.py
+++ b/module/plugins/hoster/SendspaceCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class SendspaceCom(SimpleHoster):
__name__ = "SendspaceCom"
__type__ = "hoster"
- __version__ = "0.17"
+ __version__ = "0.18"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?sendspace\.com/file/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -28,30 +29,30 @@ class SendspaceCom(SimpleHoster):
USER_CAPTCHA_PATTERN = r'<td><img src="/captchas/captcha\.php?user=(.+?))"></td>'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
params = {}
for _i in xrange(3):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
if 'captcha_hash' in params:
- self.correctCaptcha()
+ self.captcha.correct()
self.link = m.group(1)
break
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
if 'captcha_hash' in params:
- self.invalidCaptcha()
+ self.captcha.invalid()
captcha_url1 = "http://www.sendspace.com/" + m.group(1)
m = re.search(self.USER_CAPTCHA_PATTERN, self.html)
captcha_url2 = "http://www.sendspace.com/" + m.group(1)
params = {'captcha_hash': m.group(2),
'captcha_submit': 'Verify',
- 'captcha_answer': self.decryptCaptcha(captcha_url1) + " " + self.decryptCaptcha(captcha_url2)}
+ 'captcha_answer': self.captcha.decrypt(captcha_url1) + " " + self.captcha.decrypt(captcha_url2)}
else:
params = {'download': "Regular Download"}
- self.logDebug(params)
+ self.log_debug(params)
self.html = self.load(pyfile.url, post=params)
else:
self.fail(_("Download link not found"))
diff --git a/module/plugins/hoster/Share4WebCom.py b/module/plugins/hoster/Share4WebCom.py
index 7a276c1fe..3f128be5e 100644
--- a/module/plugins/hoster/Share4WebCom.py
+++ b/module/plugins/hoster/Share4WebCom.py
@@ -7,7 +7,8 @@ from module.plugins.internal.SimpleHoster import create_getInfo
class Share4WebCom(UnibytesCom):
__name__ = "Share4WebCom"
__type__ = "hoster"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?share4web\.com/get/\w+'
diff --git a/module/plugins/hoster/Share76Com.py b/module/plugins/hoster/Share76Com.py
index 4a4af1672..863fb0a7e 100644
--- a/module/plugins/hoster/Share76Com.py
+++ b/module/plugins/hoster/Share76Com.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class Share76Com(DeadHoster):
__name__ = "Share76Com"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?share76\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/ShareFilesCo.py b/module/plugins/hoster/ShareFilesCo.py
index d9a71d786..a42ceb91c 100644
--- a/module/plugins/hoster/ShareFilesCo.py
+++ b/module/plugins/hoster/ShareFilesCo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class ShareFilesCo(DeadHoster):
__name__ = "ShareFilesCo"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sharefiles\.co/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/SharebeesCom.py b/module/plugins/hoster/SharebeesCom.py
index 9387483cc..c987ac0f9 100644
--- a/module/plugins/hoster/SharebeesCom.py
+++ b/module/plugins/hoster/SharebeesCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class SharebeesCom(DeadHoster):
__name__ = "SharebeesCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sharebees\.com/\w{12}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 33e37cbc7..b5af3ea35 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -5,15 +5,16 @@ import time
import urllib
import urlparse
-from module.network.RequestFactory import getURL
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ShareonlineBiz(SimpleHoster):
__name__ = "ShareonlineBiz"
__type__ = "hoster"
- __version__ = "0.51"
+ __version__ = "0.55"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(share-online\.biz|egoshare\.com)/(download\.php\?id=|dl/)(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -36,70 +37,67 @@ class ShareonlineBiz(SimpleHoster):
@classmethod
- def apiInfo(cls, url):
- info = super(ShareonlineBiz, cls).apiInfo(url)
+ def api_info(cls, url):
+ info = super(ShareonlineBiz, cls).api_info(url)
- if url:
- field = getURL("http://api.share-online.biz/linkcheck.php",
- get={'md5' : "1",
- 'links': re.match(cls.__pattern__, url).group("ID")},
- decode=True).split(";")
+ field = get_url("http://api.share-online.biz/linkcheck.php",
+ get={'md5' : "1",
+ 'links': re.match(cls.__pattern__, url).group("ID")}).split(";")
- try:
- if field[1] == "OK":
- info['fileid'] = field[0]
- info['status'] = 2
- info['name'] = field[2]
- info['size'] = field[3] #: in bytes
- info['md5'] = field[4].strip().lower().replace("\n\n", "") #: md5
+ try:
+ if field[1] == "OK":
+ info['fileid'] = field[0]
+ info['status'] = 2
+ info['name'] = field[2]
+ info['size'] = field[3] #: In bytes
+ info['md5'] = field[4].strip().lower().replace("\n\n", "") #: md5
- elif field[1] in ("DELETED", "NOT FOUND"):
- info['status'] = 1
+ elif field[1] in ("DELETED", "NOTFOUND"):
+ info['status'] = 1
- except IndexError:
- pass
+ except IndexError:
+ pass
return info
def setup(self):
- self.resumeDownload = self.premium
+ self.resume_download = self.premium
self.multiDL = False
- def handleCaptcha(self):
+ def handle_captcha(self):
recaptcha = ReCaptcha(self)
for _i in xrange(5):
response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
m = re.search(r'var wait=(\d+);', self.html)
- self.setWait(int(m.group(1)) if m else 30)
+ self.set_wait(int(m.group(1)) if m else 30)
res = self.load("%s/free/captcha/%d" % (self.pyfile.url, int(time.time() * 1000)),
post={'dl_free' : "1",
'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
- if not res == '0':
- self.correctCaptcha()
+ if not res == "0":
+ self.captcha.correct()
return res
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
self.fail(_("No valid captcha solution received"))
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.wait(3)
self.html = self.load("%s/free/" % pyfile.url,
- post={'dl_free': "1", 'choice': "free"},
- decode=True)
+ post={'dl_free': "1", 'choice': "free"})
- self.checkErrors()
+ self.check_errors()
- res = self.handleCaptcha()
+ res = self.handle_captcha()
self.link = res.decode('base64')
if not self.link.startswith("http://"):
@@ -108,25 +106,25 @@ class ShareonlineBiz(SimpleHoster):
self.wait()
- def checkFile(self, rules={}):
- check = self.checkDownload({'cookie': re.compile(r'<div id="dl_failure"'),
+ def check_file(self):
+ check = self.check_download({'cookie': re.compile(r'<div id="dl_failure"'),
'fail' : re.compile(r"<title>Share-Online")})
if check == "cookie":
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry(5, 60, _("Cookie failure"))
elif check == "fail":
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry(5, 5 * 60, _("Download failed"))
- return super(ShareonlineBiz, self).checkFile(rules)
+ return super(ShareonlineBiz, self).check_file()
- def handlePremium(self, pyfile): #: should be working better loading (account) api internally
- html = self.load("http://api.share-online.biz/account.php",
+ def handle_premium(self, pyfile): #: Should be working better loading (account) api internally
+ html = self.load("https://api.share-online.biz/account.php",
get={'username': self.user,
- 'password': self.account.getAccountData(self.user)['password'],
+ 'password': self.account.get_info(self.user)['login']['password'],
'act' : "download",
'lid' : self.info['fileid']})
@@ -136,7 +134,7 @@ class ShareonlineBiz(SimpleHoster):
key, value = line.split(": ")
dlinfo[key.lower()] = value
- self.logDebug(dlinfo)
+ self.log_debug(dlinfo)
if not dlinfo['status'] == "online":
self.offline()
@@ -147,12 +145,12 @@ class ShareonlineBiz(SimpleHoster):
self.link = dlinfo['url']
if self.link == "server_under_maintenance":
- self.tempOffline()
+ self.temp_offline()
else:
self.multiDL = True
- def checkErrors(self):
+ def check_errors(self):
m = re.search(r"/failure/(.*?)/1", self.req.lastEffectiveURL)
if m is None:
self.info.pop('error', None)
@@ -161,11 +159,11 @@ class ShareonlineBiz(SimpleHoster):
errmsg = m.group(1).lower()
try:
- self.logError(errmsg, re.search(self.ERROR_PATTERN, self.html).group(1))
+ self.log_error(errmsg, re.search(self.ERROR_PATTERN, self.html).group(1))
except Exception:
- self.logError("Unknown error occurred", errmsg)
+ self.log_error(_("Unknown error occurred"), errmsg)
- if errmsg is "invalid":
+ if errmsg == "invalid":
self.fail(_("File not available"))
elif errmsg in ("freelimit", "size", "proxy"):
@@ -174,6 +172,9 @@ class ShareonlineBiz(SimpleHoster):
elif errmsg in ("expired", "server"):
self.retry(wait_time=600, reason=errmsg)
+ elif errmsg == "full":
+ self.retry(10, 600, _("Server is full"))
+
elif 'slot' in errmsg:
self.wantReconnect = True
self.retry(24, 3600, errmsg)
diff --git a/module/plugins/hoster/ShareplaceCom.py b/module/plugins/hoster/ShareplaceCom.py
index babd0d1d4..11aef0c90 100644
--- a/module/plugins/hoster/ShareplaceCom.py
+++ b/module/plugins/hoster/ShareplaceCom.py
@@ -3,13 +3,14 @@
import re
import urllib
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class ShareplaceCom(Hoster):
__name__ = "ShareplaceCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?shareplace\.(com|org)/\?\w+'
@@ -30,16 +31,14 @@ class ShareplaceCom(Hoster):
self.pyfile.name = self.get_file_name()
- wait_time = self.get_waiting_time()
- self.setWait(wait_time)
- self.wait()
+ self.wait(self.get_waiting_time())
def get_waiting_time(self):
if not self.html:
self.download_html()
- #var zzipitime = 15;
+ #: var zzipitime = 15
m = re.search(r'var zzipitime = (\d+);', self.html)
if m:
sec = int(m.group(1))
@@ -51,11 +50,12 @@ class ShareplaceCom(Hoster):
def download_html(self):
url = re.sub("shareplace.com\/\?", "shareplace.com//index1.php/?a=", self.pyfile.url)
- self.html = self.load(url, decode=True)
+ self.html = self.load(url)
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
url = re.search(r"var beer = '(.*?)';", self.html)
if url:
@@ -63,7 +63,7 @@ class ShareplaceCom(Hoster):
url = urllib.unquote(
url.replace("http://http:/", "").replace("vvvvvvvvv", "").replace("lllllllll", "").replace(
"teletubbies", ""))
- self.logDebug("URL: %s" % url)
+ self.log_debug("URL: %s" % url)
return url
else:
self.error(_("Absolute filepath not found"))
@@ -77,7 +77,8 @@ class ShareplaceCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/SharingmatrixCom.py b/module/plugins/hoster/SharingmatrixCom.py
index 3958ebbd6..e6d5d4ab8 100644
--- a/module/plugins/hoster/SharingmatrixCom.py
+++ b/module/plugins/hoster/SharingmatrixCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class SharingmatrixCom(DeadHoster):
__name__ = "SharingmatrixCom"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sharingmatrix\.com/file/\w+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/ShragleCom.py b/module/plugins/hoster/ShragleCom.py
index 689223322..1313ba0e0 100644
--- a/module/plugins/hoster/ShragleCom.py
+++ b/module/plugins/hoster/ShragleCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class ShragleCom(DeadHoster):
__name__ = "ShragleCom"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.23"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(cloudnator|shragle)\.com/files/(?P<ID>.+?)/'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/SimplyPremiumCom.py b/module/plugins/hoster/SimplyPremiumCom.py
index b3f52bc8c..be1578bfb 100644
--- a/module/plugins/hoster/SimplyPremiumCom.py
+++ b/module/plugins/hoster/SimplyPremiumCom.py
@@ -3,16 +3,18 @@
import re
from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
-from module.plugins.internal.SimpleHoster import secondsToMidnight
+from module.plugins.internal.SimpleHoster import seconds_to_midnight
class SimplyPremiumCom(MultiHoster):
__name__ = "SimplyPremiumCom"
__type__ = "hoster"
- __version__ = "0.08"
+ __version__ = "0.10"
+ __status__ = "testing"
__pattern__ = r'https?://.+simply-premium\.com'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Simply-Premium.com multi-hoster plugin"""
__license__ = "GPLv3"
@@ -20,10 +22,10 @@ class SimplyPremiumCom(MultiHoster):
def setup(self):
- self.chunkLimit = 16
+ self.chunk_limit = 16
- def checkErrors(self):
+ def check_errors(self):
if '<valid>0</valid>' in self.html or (
"You are not allowed to download from this host" in self.html and self.premium):
self.account.relogin(self.user)
@@ -33,30 +35,30 @@ class SimplyPremiumCom(MultiHoster):
self.offline()
elif "downloadlimit" in self.html:
- self.logWarning(_("Reached maximum connctions"))
+ self.log_warning(_("Reached maximum connctions"))
self.retry(5, 60, _("Reached maximum connctions"))
elif "trafficlimit" in self.html:
- self.logWarning(_("Reached daily limit for this host"))
- self.retry(wait_time=secondsToMidnight(gmt=2), reason="Daily limit for this host reached")
+ self.log_warning(_("Reached daily limit for this host"))
+ self.retry(wait_time=seconds_to_midnight(gmt=2), reason="Daily limit for this host reached")
elif "hostererror" in self.html:
- self.logWarning(_("Hoster temporarily unavailable, waiting 1 minute and retry"))
+ self.log_warning(_("Hoster temporarily unavailable, waiting 1 minute and retry"))
self.retry(5, 60, _("Hoster is temporarily unavailable"))
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
for i in xrange(5):
self.html = self.load("http://www.simply-premium.com/premium.php", get={'info': "", 'link': self.pyfile.url})
if self.html:
- self.logDebug("JSON data: " + self.html)
+ self.log_debug("JSON data: " + self.html)
break
else:
- self.logInfo(_("Unable to get API data, waiting 1 minute and retry"))
+ self.log_info(_("Unable to get API data, waiting 1 minute and retry"))
self.retry(5, 60, _("Unable to get API data"))
- self.checkErrors()
+ self.check_errors()
try:
self.pyfile.name = re.search(r'<name>([^<]+)</name>', self.html).group(1)
diff --git a/module/plugins/hoster/SimplydebridCom.py b/module/plugins/hoster/SimplydebridCom.py
index aae71d983..829609228 100644
--- a/module/plugins/hoster/SimplydebridCom.py
+++ b/module/plugins/hoster/SimplydebridCom.py
@@ -8,18 +8,20 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo, rep
class SimplydebridCom(MultiHoster):
__name__ = "SimplydebridCom"
__type__ = "hoster"
- __version__ = "0.17"
+ __version__ = "0.20"
+ __status__ = "testing"
__pattern__ = r'http://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/sd\.php'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Simply-debrid.com multi-hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("Kagenoshin", "kagenoshin@gmx.ch")]
- def handlePremium(self, pyfile):
- #fix the links for simply-debrid.com!
+ def handle_premium(self, pyfile):
+ #: Fix the links for simply-debrid.com!
self.link = replace_patterns(pyfile.url, [("clz.to", "cloudzer.net/file")
("http://share-online", "http://www.share-online")
("ul.to", "uploaded.net/file")
@@ -39,11 +41,11 @@ class SimplydebridCom(MultiHoster):
self.wait(5)
- def checkFile(self, rules={}):
- if self.checkDownload({"error": "No address associated with hostname"}):
+ def check_file(self):
+ if self.check_download({'error': "No address associated with hostname"}):
self.retry(24, 3 * 60, _("Bad file downloaded"))
- return super(SimplydebridCom, self).checkFile(rules)
+ return super(SimplydebridCom, self).check_file()
getInfo = create_getInfo(SimplydebridCom)
diff --git a/module/plugins/hoster/SizedriveCom.py b/module/plugins/hoster/SizedriveCom.py
index 3b9748fb6..8bfe46e86 100644
--- a/module/plugins/hoster/SizedriveCom.py
+++ b/module/plugins/hoster/SizedriveCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class SizedriveCom(SimpleHoster):
__name__ = "SizedriveCom"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sizedrive\.com/[rd]/(?P<ID>\w+)'
@@ -23,12 +24,12 @@ class SizedriveCom(SimpleHoster):
def setup(self):
- self.resumeDownload = False
+ self.resume_download = False
self.multiDL = False
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.wait(5)
self.html = self.load("http://www.sizedrive.com/getdownload.php",
post={'id': self.info['pattern']['ID']})
diff --git a/module/plugins/hoster/SmoozedCom.py b/module/plugins/hoster/SmoozedCom.py
index 9ae12f145..33d098a00 100644
--- a/module/plugins/hoster/SmoozedCom.py
+++ b/module/plugins/hoster/SmoozedCom.py
@@ -7,58 +7,56 @@ from module.plugins.internal.MultiHoster import MultiHoster
class SmoozedCom(MultiHoster):
__name__ = "SmoozedCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.08"
+ __status__ = "testing"
- __pattern__ = r'^unmatchable$' #: Since we want to allow the user to specify the list of hoster to use we let MultiHoster.coreReady
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __pattern__ = r'^unmatchable$' #: Since we want to allow the user to specify the list of hoster to use we let MultiHoster.activate
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Smoozed.com hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("", "")]
- def handleFree(self, pyfile):
- # In some cases hostsers do not supply us with a filename at download, so we
- # are going to set a fall back filename (e.g. for freakshare or xfileshare)
- pyfile.name = pyfile.name.split('/').pop() # Remove everthing before last slash
+ FILE_ERRORS = [("Error", r'{"state":"error"}'),
+ ("Retry", r'{"state":"retry"}')]
- # Correction for automatic assigned filename: Removing html at end if needed
+
+ def handle_free(self, pyfile):
+ #: In some cases hostsers do not supply us with a filename at download, so we
+ #: Are going to set a fall back filename (e.g. for freakshare or xfileshare)
+ pyfile.name = pyfile.name.split('/').pop() #: Remove everthing before last slash
+
+ #: Correction for automatic assigned filename: Removing html at end if needed
suffix_to_remove = ["html", "htm", "php", "php3", "asp", "shtm", "shtml", "cfml", "cfm"]
temp = pyfile.name.split('.')
if temp.pop() in suffix_to_remove:
pyfile.name = ".".join(temp)
- # Check the link
- get_data = {'session_key': self.account.getAccountInfo(self.user)['session'],
+ #: Check the link
+ get_data = {'session_key': self.account.get_data(self.user)['session'],
'url' : pyfile.url}
data = json_loads(self.load("http://www2.smoozed.com/api/check", get=get_data))
- if data["state"] != "ok":
- self.fail(data["message"])
+ if data['state'] != "ok":
+ self.fail(data['message'])
- if data["data"].get("state", "ok") != "ok":
- if data["data"] == "Offline":
+ if data['data'].get("state", "ok") != "ok":
+ if data['data'] == "Offline":
self.offline()
else:
- self.fail(data["data"]["message"])
+ self.fail(data['data']['message'])
- pyfile.name = data["data"]["name"]
- pyfile.size = int(data["data"]["size"])
+ pyfile.name = data['data']['name']
+ pyfile.size = int(data['data']['size'])
- # Start the download
+ #: Start the download
header = self.load("http://www2.smoozed.com/api/download", get=get_data, just_header=True)
if not "location" in header:
self.fail(_("Unable to initialize download"))
else:
- self.link = header["location"][-1] if isinstance(header["location"], list) else header["location"]
-
-
- def checkFile(self, rules={}):
- if self.checkDownload({'error': '{"state":"error"}',
- 'retry': '{"state":"retry"}'}):
- self.fail(_("Error response received"))
-
- return super(SmoozedCom, self).checkFile(rules)
+ self.link = header['location'][-1] if isinstance(header['location'], list) else header['location']
diff --git a/module/plugins/hoster/SockshareCom.py b/module/plugins/hoster/SockshareCom.py
index 44eedf9d4..b45a22b72 100644
--- a/module/plugins/hoster/SockshareCom.py
+++ b/module/plugins/hoster/SockshareCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class SockshareCom(DeadHoster):
__name__ = "SockshareCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?sockshare\.com/(mobile/)?(file|embed)/(?P<ID>\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/SolidfilesCom.py b/module/plugins/hoster/SolidfilesCom.py
index d359577d6..16e23045b 100644
--- a/module/plugins/hoster/SolidfilesCom.py
+++ b/module/plugins/hoster/SolidfilesCom.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Test links:
-# http://www.solidfiles.com/d/609cdb4b1b
+# http://www.solidfiles.com/d/609cdb4b1b
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class SolidfilesCom(SimpleHoster):
__name__ = "SolidfilesCom"
__type__ = "hoster"
- __version__ = "0.02"
+ __version__ = "0.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?solidfiles\.com\/d/\w+'
@@ -27,7 +28,7 @@ class SolidfilesCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
+ self.chunk_limit = 1
getInfo = create_getInfo(SolidfilesCom)
diff --git a/module/plugins/hoster/SoundcloudCom.py b/module/plugins/hoster/SoundcloudCom.py
index 8dff4f42a..b189ee1ba 100644
--- a/module/plugins/hoster/SoundcloudCom.py
+++ b/module/plugins/hoster/SoundcloudCom.py
@@ -9,7 +9,8 @@ from module.common.json_layer import json_loads
class SoundcloudCom(SimpleHoster):
__name__ = "SoundcloudCom"
__type__ = "hoster"
- __version__ = "0.11"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?soundcloud\.com/[\w-]+/[\w-]+'
__config__ = [("use_premium", "bool" , "Use premium account if available", True ),
@@ -24,7 +25,7 @@ class SoundcloudCom(SimpleHoster):
OFFLINE_PATTERN = r'<title>"SoundCloud - Hear the world’s sounds"</title>'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
try:
song_id = re.search(r'sounds:(\d+)"', self.html).group(1)
@@ -37,19 +38,19 @@ class SoundcloudCom(SimpleHoster):
except Exception:
client_id = "b45b1aa10f1ac2941910a7f0d10f8e28"
- # url to retrieve the actual song url
+ #: Url to retrieve the actual song url
streams = json_loads(self.load("https://api.soundcloud.com/tracks/%s/streams" % song_id,
get={'client_id': client_id}))
regex = re.compile(r'[^\d]')
- http_streams = sorted([(key, value) for key, value in streams.iteritems() if key.startswith('http_')],
+ http_streams = sorted([(key, value) for key, value in streams.items() if key.startswith('http_')],
key=lambda t: regex.sub(t[0], ''),
reverse=True)
- self.logDebug("Streams found: %s" % (http_streams or "None"))
+ self.log_debug("Streams found: %s" % (http_streams or "None"))
if http_streams:
- stream_name, self.link = http_streams[0 if self.getConfig('quality') == "Higher" else -1]
+ stream_name, self.link = http_streams[0 if self.get_config('quality') == "Higher" else -1]
pyfile.name += '.' + stream_name.split('_')[1].lower()
diff --git a/module/plugins/hoster/SpeedLoadOrg.py b/module/plugins/hoster/SpeedLoadOrg.py
index 18f04b611..abba1be79 100644
--- a/module/plugins/hoster/SpeedLoadOrg.py
+++ b/module/plugins/hoster/SpeedLoadOrg.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class SpeedLoadOrg(DeadHoster):
__name__ = "SpeedLoadOrg"
__type__ = "hoster"
- __version__ = "1.02"
+ __version__ = "1.03"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?speedload\.org/(?P<ID>\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/SpeedfileCz.py b/module/plugins/hoster/SpeedfileCz.py
index cd6d65082..75a55d490 100644
--- a/module/plugins/hoster/SpeedfileCz.py
+++ b/module/plugins/hoster/SpeedfileCz.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class SpeedfileCz(DeadHoster):
__name__ = "SpeedFileCz"
__type__ = "hoster"
- __version__ = "0.32"
+ __version__ = "0.33"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?speedfile\.cz/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/SpeedyshareCom.py b/module/plugins/hoster/SpeedyshareCom.py
index 91788b2c8..7d7a60f04 100644
--- a/module/plugins/hoster/SpeedyshareCom.py
+++ b/module/plugins/hoster/SpeedyshareCom.py
@@ -12,7 +12,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class SpeedyshareCom(SimpleHoster):
__name__ = "SpeedyshareCom"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(speedyshare\.com|speedy\.sh)/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -32,10 +33,10 @@ class SpeedyshareCom(SimpleHoster):
def setup(self):
self.multiDL = False
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.link = m.group(1)
diff --git a/module/plugins/hoster/StorageTo.py b/module/plugins/hoster/StorageTo.py
index feb9f3300..3d0852204 100644
--- a/module/plugins/hoster/StorageTo.py
+++ b/module/plugins/hoster/StorageTo.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class StorageTo(DeadHoster):
__name__ = "StorageTo"
__type__ = "hoster"
- __version__ = "0.01"
+ __version__ = "0.02"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?storage\.to/get/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/StreamCz.py b/module/plugins/hoster/StreamCz.py
index 97bed8109..a5578fd96 100644
--- a/module/plugins/hoster/StreamCz.py
+++ b/module/plugins/hoster/StreamCz.py
@@ -2,18 +2,18 @@
import re
-from module.network.RequestFactory import getURL
-from module.plugins.Hoster import Hoster
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.Hoster import Hoster
-def getInfo(urls):
+def get_info(urls):
result = []
for url in urls:
- html = getURL(url)
+ html = get_url(url)
if re.search(StreamCz.OFFLINE_PATTERN, html):
- # File offline
+ #: File offline
result.append((url, 0, 1, url))
else:
result.append((url, 0, 2, url))
@@ -23,7 +23,8 @@ def getInfo(urls):
class StreamCz(Hoster):
__name__ = "StreamCz"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?stream\.cz/[^/]+/\d+'
@@ -39,12 +40,12 @@ class StreamCz(Hoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
def process(self, pyfile):
- self.html = self.load(pyfile.url, decode=True)
+ self.html = self.load(pyfile.url)
if re.search(self.OFFLINE_PATTERN, self.html):
self.offline()
@@ -53,7 +54,7 @@ class StreamCz(Hoster):
if m is None:
self.error(_("CDN_PATTERN not found"))
cdn = m.groupdict()
- self.logDebug(cdn)
+ self.log_debug(cdn)
for cdnkey in ("cdnHD", "cdnHQ", "cdnLQ"):
if cdnkey in cdn and cdn[cdnkey] > '':
cdnid = cdn[cdnkey]
@@ -67,5 +68,5 @@ class StreamCz(Hoster):
pyfile.name = "%s-%s.%s.mp4" % (m.group(2), m.group(1), cdnkey[-2:])
download_url = "http://cdn-dispatcher.stream.cz/?id=" + cdnid
- self.logInfo(_("STREAM: %s") % cdnkey[-2:], download_url)
+ self.log_info(_("STREAM: %s") % cdnkey[-2:], download_url)
self.download(download_url)
diff --git a/module/plugins/hoster/StreamcloudEu.py b/module/plugins/hoster/StreamcloudEu.py
index 0f8c08ad9..97cde6e92 100644
--- a/module/plugins/hoster/StreamcloudEu.py
+++ b/module/plugins/hoster/StreamcloudEu.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class StreamcloudEu(XFSHoster):
__name__ = "StreamcloudEu"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.11"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?streamcloud\.eu/\w{12}'
@@ -22,8 +23,8 @@ class StreamcloudEu(XFSHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
- self.resumeDownload = self.premium
+ self.chunk_limit = 1
+ self.resume_download = self.premium
getInfo = create_getInfo(StreamcloudEu)
diff --git a/module/plugins/hoster/TurbobitNet.py b/module/plugins/hoster/TurbobitNet.py
index 254e06c2a..d323a214b 100644
--- a/module/plugins/hoster/TurbobitNet.py
+++ b/module/plugins/hoster/TurbobitNet.py
@@ -9,20 +9,20 @@ import urllib
from Crypto.Cipher import ARC4
-from module.network.RequestFactory import getURL
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, timestamp
class TurbobitNet(SimpleHoster):
__name__ = "TurbobitNet"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?turbobit\.net/(?:download/free/)?(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
- __description__ = """ Turbobit.net hoster plugin """
+ __description__ = """Turbobit.net hoster plugin"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz"),
("prOq", None)]
@@ -42,17 +42,16 @@ class TurbobitNet(SimpleHoster):
CAPTCHA_PATTERN = r'<img alt="Captcha" src="(.+?)"'
- def handleFree(self, pyfile):
- self.html = self.load("http://turbobit.net/download/free/%s" % self.info['pattern']['ID'],
- decode=True)
+ def handle_free(self, pyfile):
+ self.html = self.load("http://turbobit.net/download/free/%s" % self.info['pattern']['ID'])
- rtUpdate = self.getRtUpdate()
+ rtUpdate = self.get_rt_update()
- self.solveCaptcha()
+ self.solve_captcha()
self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With: XMLHttpRequest"])
- self.html = self.load(self.getDownloadUrl(rtUpdate))
+ self.html = self.load(self.get_download_url(rtUpdate))
self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With:"])
@@ -61,7 +60,7 @@ class TurbobitNet(SimpleHoster):
self.link = m.group(1)
- def solveCaptcha(self):
+ def solve_captcha(self):
for _i in xrange(5):
m = re.search(self.LIMIT_WAIT_PATTERN, self.html)
if m:
@@ -69,12 +68,12 @@ class TurbobitNet(SimpleHoster):
self.wait(wait_time, wait_time > 60)
self.retry()
- action, inputs = self.parseHtmlForm("action='#'")
+ action, inputs = self.parse_html_form("action='#'")
if not inputs:
self.error(_("Captcha form not found"))
- self.logDebug(inputs)
+ self.log_debug(inputs)
- if inputs['captcha_type'] == 'recaptcha':
+ if inputs['captcha_type'] == "recaptcha":
recaptcha = ReCaptcha(self)
inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge()
else:
@@ -82,44 +81,44 @@ class TurbobitNet(SimpleHoster):
if m is None:
self.error(_("captcha"))
captcha_url = m.group(1)
- inputs['captcha_response'] = self.decryptCaptcha(captcha_url)
+ inputs['captcha_response'] = self.captcha.decrypt(captcha_url)
- self.logDebug(inputs)
+ self.log_debug(inputs)
self.html = self.load(self.url, post=inputs)
if '<div class="captcha-error">Incorrect, try again!<' in self.html:
- self.invalidCaptcha()
+ self.captcha.invalid()
else:
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
self.fail(_("Invalid captcha"))
- def getRtUpdate(self):
- rtUpdate = self.getStorage("rtUpdate")
+ def get_rt_update(self):
+ rtUpdate = self.retrieve("rtUpdate")
if not rtUpdate:
- if self.getStorage("version") != self.__version__ \
- or int(self.getStorage("timestamp", 0)) + 86400000 < timestamp():
- # that's right, we are even using jdownloader updates
- rtUpdate = getURL("http://update0.jdownloader.org/pluginstuff/tbupdate.js")
+ if self.retrieve("version") is not self.__version__ \
+ or int(self.retrieve("timestamp", 0)) + 86400000 < timestamp():
+ #: that's right, we are even using jdownloader updates
+ rtUpdate = self.load("http://update0.jdownloader.org/pluginstuff/tbupdate.js")
rtUpdate = self.decrypt(rtUpdate.splitlines()[1])
- # but we still need to fix the syntax to work with other engines than rhino
+ #: But we still need to fix the syntax to work with other engines than rhino
rtUpdate = re.sub(r'for each\(var (\w+) in(\[[^\]]+\])\)\{',
r'zza=\2;for(var zzi=0;zzi<zza.length;zzi++){\1=zza[zzi];', rtUpdate)
rtUpdate = re.sub(r"for\((\w+)=", r"for(var \1=", rtUpdate)
- self.setStorage("rtUpdate", rtUpdate)
- self.setStorage("timestamp", timestamp())
- self.setStorage("version", self.__version__)
+ self.store("rtUpdate", rtUpdate)
+ self.store("timestamp", timestamp())
+ self.store("version", self.__version__)
else:
- self.logError(_("Unable to download, wait for update..."))
- self.tempOffline()
+ self.log_error(_("Unable to download, wait for update..."))
+ self.temp_offline()
return rtUpdate
- def getDownloadUrl(self, rtUpdate):
+ def get_download_url(self, rtUpdate):
self.req.http.lastURL = self.url
m = re.search("(/\w+/timeout\.js\?\w+=)([^\"\'<>]+)", self.html)
@@ -130,7 +129,7 @@ class TurbobitNet(SimpleHoster):
fun = self.load(url)
- self.setWait(65, False)
+ self.set_wait(65, False)
for b in [1, 3]:
self.jscode = "var id = \'%s\';var b = %d;var inn = \'%s\';%sout" % (
@@ -138,16 +137,16 @@ class TurbobitNet(SimpleHoster):
try:
out = self.js.eval(self.jscode)
- self.logDebug("URL", self.js.engine, out)
+ self.log_debug("URL", self.js.engine, out)
if out.startswith('/download/'):
return "http://turbobit.net%s" % out.strip()
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
if self.retries >= 2:
- # retry with updated js
- self.delStorage("rtUpdate")
+ #: Retry with updated js
+ self.delete("rtUpdate")
else:
self.retry()
@@ -159,7 +158,7 @@ class TurbobitNet(SimpleHoster):
return binascii.unhexlify(cipher.encrypt(binascii.unhexlify(data)))
- def getLocalTimeString(self):
+ def get_local_time_string(self):
lt = time.localtime()
tz = time.altzone if lt.tm_isdst else time.timezone
return "%s GMT%+03d%02d" % (time.strftime("%a %b %d %Y %H:%M:%S", lt), -tz // 3600, tz % 3600)
diff --git a/module/plugins/hoster/TurbouploadCom.py b/module/plugins/hoster/TurbouploadCom.py
index e4b53b818..ffb88d53b 100644
--- a/module/plugins/hoster/TurbouploadCom.py
+++ b/module/plugins/hoster/TurbouploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class TurbouploadCom(DeadHoster):
__name__ = "TurbouploadCom"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?turboupload\.com/(\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/TusfilesNet.py b/module/plugins/hoster/TusfilesNet.py
index 6021a4c30..8fadb41c3 100644
--- a/module/plugins/hoster/TusfilesNet.py
+++ b/module/plugins/hoster/TusfilesNet.py
@@ -1,13 +1,15 @@
# -*- coding: utf-8 -*-
from module.network.HTTPRequest import BadHeader
+from module.plugins.internal.Plugin import Retry
from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class TusfilesNet(XFSHoster):
__name__ = "TusfilesNet"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?tusfiles\.net/\w{12}'
@@ -18,21 +20,20 @@ class TusfilesNet(XFSHoster):
INFO_PATTERN = r'\](?P<N>.+) - (?P<S>[\d.,]+) (?P<U>[\w^_]+)\['
- OFFLINE_PATTERN = r'>File Not Found|<Title>TusFiles - Fast Sharing Files!|The file you are trying to download is no longer available'
def setup(self):
- self.chunkLimit = -1
+ self.chunk_limit = -1
self.multiDL = True
- self.resumeDownload = True
+ self.resume_download = True
- def downloadLink(self, link, disposition=True):
+ def download(self, url, *args, **kwargs):
try:
- return super(TusfilesNet, self).downloadLink(link, disposition)
+ return super(TusfilesNet, self).download(url, *args, **kwargs)
except BadHeader, e:
- if e.code is 503:
+ if e.code == 503:
self.multiDL = False
raise Retry("503")
diff --git a/module/plugins/hoster/TwoSharedCom.py b/module/plugins/hoster/TwoSharedCom.py
index 086228637..1335bafae 100644
--- a/module/plugins/hoster/TwoSharedCom.py
+++ b/module/plugins/hoster/TwoSharedCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class TwoSharedCom(SimpleHoster):
__name__ = "TwoSharedCom"
__type__ = "hoster"
- __version__ = "0.13"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?2shared\.com/(account/)?(download|get|file|document|photo|video|audio)/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -26,7 +27,7 @@ class TwoSharedCom(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py
index b43ff8d92..b402433a4 100644
--- a/module/plugins/hoster/UlozTo.py
+++ b/module/plugins/hoster/UlozTo.py
@@ -7,15 +7,16 @@ from module.common.json_layer import json_loads
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-def convertDecimalPrefix(m):
- # decimal prefixes used in filesize and traffic
+def convert_decimal_prefix(m):
+ #: Decimal prefixes used in filesize and traffic
return ("%%.%df" % {'k': 3, 'M': 6, 'G': 9}[m.group(2)] % float(m.group(1))).replace('.', '')
class UlozTo(SimpleHoster):
__name__ = "UlozTo"
__type__ = "hoster"
- __version__ = "1.09"
+ __version__ = "1.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj\.cz|zachowajto\.pl)/(?:live/)?(?P<ID>\w+/[^/?]*)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -31,10 +32,9 @@ class UlozTo(SimpleHoster):
OFFLINE_PATTERN = r'<title>404 - Page not found</title>|<h1 class="h1">File (has been deleted|was banned)</h1>'
URL_REPLACEMENTS = [(r'(?<=http://)([^/]+)', "www.ulozto.net")]
- SIZE_REPLACEMENTS = [(r'([\d.]+)\s([kMG])B', convertDecimalPrefix)]
+ SIZE_REPLACEMENTS = [(r'([\d.]+)\s([kMG])B', convert_decimal_prefix)]
CHECK_TRAFFIC = True
- DISPOSITION = False #: Remove in 0.4.10
ADULT_PATTERN = r'<form action="(.+?)" method="post" id="frm-askAgeForm">'
PASSWD_PATTERN = r'<div class="passwordProtectedFile">'
@@ -43,37 +43,37 @@ class UlozTo(SimpleHoster):
def setup(self):
- self.chunkLimit = 16 if self.premium else 1
+ self.chunk_limit = 16 if self.premium else 1
self.multiDL = True
- self.resumeDownload = True
+ self.resume_download = True
- def handleFree(self, pyfile):
- action, inputs = self.parseHtmlForm('id="frm-downloadDialog-freeDownloadForm"')
+ def handle_free(self, pyfile):
+ action, inputs = self.parse_html_form('id="frm-downloadDialog-freeDownloadForm"')
if not action or not inputs:
self.error(_("Free download form not found"))
- self.logDebug("inputs.keys = " + str(inputs.keys()))
- # get and decrypt captcha
+ self.log_debug("inputs.keys = " + str(inputs.keys()))
+ #: Get and decrypt captcha
if all(key in inputs for key in ("captcha_value", "captcha_id", "captcha_key")):
- # Old version - last seen 9.12.2013
- self.logDebug('Using "old" version')
+ #: Old version - last seen 9.12.2013
+ self.log_debug('Using "old" version')
- captcha_value = self.decryptCaptcha("http://img.uloz.to/captcha/%s.png" % inputs['captcha_id'])
- self.logDebug("CAPTCHA ID: " + inputs['captcha_id'] + ", CAPTCHA VALUE: " + captcha_value)
+ captcha_value = self.captcha.decrypt("http://img.uloz.to/captcha/%s.png" % inputs['captcha_id'])
+ self.log_debug("CAPTCHA ID: " + inputs['captcha_id'] + ", CAPTCHA VALUE: " + captcha_value)
inputs.update({'captcha_id': inputs['captcha_id'], 'captcha_key': inputs['captcha_key'], 'captcha_value': captcha_value})
elif all(key in inputs for key in ("captcha_value", "timestamp", "salt", "hash")):
- # New version - better to get new parameters (like captcha reload) because of image url - since 6.12.2013
- self.logDebug('Using "new" version')
+ #: New version - better to get new parameters (like captcha reload) because of image url - since 6.12.2013
+ self.log_debug('Using "new" version')
xapca = self.load("http://www.ulozto.net/reloadXapca.php", get={'rnd': str(int(time.time()))})
- self.logDebug("xapca = " + str(xapca))
+ self.log_debug("xapca = " + str(xapca))
data = json_loads(xapca)
- captcha_value = self.decryptCaptcha(str(data['image']))
- self.logDebug("CAPTCHA HASH: " + data['hash'], "CAPTCHA SALT: " + str(data['salt']), "CAPTCHA VALUE: " + captcha_value)
+ captcha_value = self.captcha.decrypt(str(data['image']))
+ self.log_debug("CAPTCHA HASH: " + data['hash'], "CAPTCHA SALT: " + str(data['salt']), "CAPTCHA VALUE: " + captcha_value)
inputs.update({'timestamp': data['timestamp'], 'salt': data['salt'], 'hash': data['hash'], 'captcha_value': captcha_value})
@@ -83,13 +83,13 @@ class UlozTo(SimpleHoster):
self.download("http://www.ulozto.net" + action, post=inputs)
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
self.download(pyfile.url, get={'do': "directDownload"})
- def checkErrors(self):
+ def check_errors(self):
if re.search(self.ADULT_PATTERN, self.html):
- self.logInfo(_("Adult content confirmation needed"))
+ self.log_info(_("Adult content confirmation needed"))
m = re.search(self.TOKEN_PATTERN, self.html)
if m is None:
@@ -97,16 +97,16 @@ class UlozTo(SimpleHoster):
self.html = self.load(pyfile.url,
get={'do': "askAgeForm-submit"},
- post={"agree": "Confirm", "_token_": m.group(1)})
+ post={'agree': "Confirm", '_token_': m.group(1)})
if self.PASSWD_PATTERN in self.html:
- password = self.getPassword()
+ password = self.get_password()
if password:
- self.logInfo(_("Password protected link, trying ") + password)
+ self.log_info(_("Password protected link, trying ") + password)
self.html = self.load(pyfile.url,
get={'do': "passwordProtectedForm-submit"},
- post={"password": password, "password_send": 'Send'})
+ post={'password': password, 'password_send': 'Send'})
if self.PASSWD_PATTERN in self.html:
self.fail(_("Incorrect password"))
@@ -116,20 +116,20 @@ class UlozTo(SimpleHoster):
if re.search(self.VIPLINK_PATTERN, self.html):
self.html = self.load(pyfile.url, get={'disclaimer': "1"})
- return super(UlozTo, self).checkErrors()
+ return super(UlozTo, self).check_errors()
- def checkFile(self, rules={}):
- check = self.checkDownload({
- "wrong_captcha": re.compile(r'<ul class="error">\s*<li>Error rewriting the text.</li>'),
- "offline" : re.compile(self.OFFLINE_PATTERN),
- "passwd" : self.PASSWD_PATTERN,
- "server_error" : 'src="http://img.ulozto.cz/error403/vykricnik.jpg"', # paralell dl, server overload etc.
- "not_found" : "<title>UloÅŸ.to</title>"
+ def check_file(self):
+ check = self.check_download({
+ 'wrong_captcha': re.compile(r'<ul class="error">\s*<li>Error rewriting the text.</li>'),
+ 'offline' : re.compile(self.OFFLINE_PATTERN),
+ 'passwd' : self.PASSWD_PATTERN,
+ 'server_error' : 'src="http://img.ulozto.cz/error403/vykricnik.jpg"', #: Paralell dl, server overload etc.
+ 'not_found' : "<title>UloÅŸ.to</title>"
})
if check == "wrong_captcha":
- self.invalidCaptcha()
+ self.captcha.invalid()
self.retry(reason=_("Wrong captcha code"))
elif check == "offline":
@@ -139,7 +139,7 @@ class UlozTo(SimpleHoster):
self.fail(_("Wrong password"))
elif check == "server_error":
- self.logError(_("Server error, try downloading later"))
+ self.log_error(_("Server error, try downloading later"))
self.multiDL = False
self.wait(1 * 60 * 60, True)
self.retry()
@@ -147,7 +147,7 @@ class UlozTo(SimpleHoster):
elif check == "not_found":
self.fail(_("Server error, file not downloadable"))
- return super(UlozTo, self).checkFile(rules)
+ return super(UlozTo, self).check_file()
getInfo = create_getInfo(UlozTo)
diff --git a/module/plugins/hoster/UloziskoSk.py b/module/plugins/hoster/UloziskoSk.py
index ad809b47c..7cbcb4d40 100644
--- a/module/plugins/hoster/UloziskoSk.py
+++ b/module/plugins/hoster/UloziskoSk.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UloziskoSk(SimpleHoster):
__name__ = "UloziskoSk"
__type__ = "hoster"
- __version__ = "0.25"
+ __version__ = "0.26"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?ulozisko\.sk/.+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -30,17 +31,17 @@ class UloziskoSk(SimpleHoster):
def process(self, pyfile):
- self.html = self.load(pyfile.url, decode=True)
- self.getFileInfo()
+ self.html = self.load(pyfile.url)
+ self.get_fileInfo()
m = re.search(self.IMG_PATTERN, self.html)
if m:
self.link = "http://ulozisko.sk" + m.group(1)
else:
- self.handleFree(pyfile)
+ self.handle_free(pyfile)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("LINK_FREE_PATTERN not found"))
@@ -51,22 +52,22 @@ class UloziskoSk(SimpleHoster):
self.error(_("ID_PATTERN not found"))
id = m.group(1)
- self.logDebug("URL:" + parsed_url + ' ID:' + id)
+ self.log_debug("URL:" + parsed_url + ' ID:' + id)
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m is None:
self.error(_("CAPTCHA_PATTERN not found"))
captcha_url = urlparse.urljoin("http://www.ulozisko.sk", m.group(1))
- captcha = self.decryptCaptcha(captcha_url, cookies=True)
+ captcha = self.captcha.decrypt(captcha_url, cookies=True)
- self.logDebug("CAPTCHA_URL:" + captcha_url + ' CAPTCHA:' + captcha)
+ self.log_debug("CAPTCHA_URL:" + captcha_url + ' CAPTCHA:' + captcha)
self.download(parsed_url,
- post={"antispam": captcha,
- "id" : id,
- "name" : pyfile.name,
- "but" : "++++STIAHNI+S%DABOR++++"})
+ post={'antispam': captcha,
+ 'id' : id,
+ 'name' : pyfile.name,
+ 'but' : "++++STIAHNI+S%DABOR++++"})
getInfo = create_getInfo(UloziskoSk)
diff --git a/module/plugins/hoster/UnibytesCom.py b/module/plugins/hoster/UnibytesCom.py
index d090c8e7d..ac2589f47 100644
--- a/module/plugins/hoster/UnibytesCom.py
+++ b/module/plugins/hoster/UnibytesCom.py
@@ -10,7 +10,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UnibytesCom(SimpleHoster):
__name__ = "UnibytesCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?unibytes\.com/[\w .-]{11}B'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -28,14 +29,14 @@ class UnibytesCom(SimpleHoster):
LINK_FREE_PATTERN = r'<a href="(.+?)">Download</a>'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
domain = "http://www.%s/" % self.HOSTER_DOMAIN
- action, post_data = self.parseHtmlForm('id="startForm"')
+ action, post_data = self.parse_html_form('id="startForm"')
self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0)
for _i in xrange(8):
- self.logDebug(action, post_data)
+ self.log_debug(action, post_data)
self.html = self.load(urlparse.urljoin(domain, action), post=post_data)
m = re.search(r'location:\s*(\S+)', self.req.http.header, re.I)
@@ -47,24 +48,24 @@ class UnibytesCom(SimpleHoster):
self.wait(10 * 60, True)
self.retry()
- if post_data['step'] == 'last':
+ if post_data['step'] == "last":
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
self.link = m.group(1)
- self.correctCaptcha()
+ self.captcha.correct()
break
else:
- self.invalidCaptcha()
+ self.captcha.invalid()
last_step = post_data['step']
- action, post_data = self.parseHtmlForm('id="stepForm"')
+ action, post_data = self.parse_html_form('id="stepForm"')
- if last_step == 'timer':
+ if last_step == "timer":
m = re.search(self.WAIT_PATTERN, self.html)
self.wait(m.group(1) if m else 60, False)
elif last_step in ("captcha", "last"):
- post_data['captcha'] = self.decryptCaptcha(urlparse.urljoin(domain, "/captcha.jpg"))
+ post_data['captcha'] = self.captcha.decrypt(urlparse.urljoin(domain, "/captcha.jpg"))
else:
self.fail(_("No valid captcha code entered"))
diff --git a/module/plugins/hoster/UnrestrictLi.py b/module/plugins/hoster/UnrestrictLi.py
index b63796fe0..082ad3e02 100644
--- a/module/plugins/hoster/UnrestrictLi.py
+++ b/module/plugins/hoster/UnrestrictLi.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class UnrestrictLi(DeadHoster):
__name__ = "UnrestrictLi"
__type__ = "hoster"
- __version__ = "0.23"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(unrestrict|unr)\.li/dl/[\w^_]+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/UpleaCom.py b/module/plugins/hoster/UpleaCom.py
index 9d460ef98..db9517f42 100644
--- a/module/plugins/hoster/UpleaCom.py
+++ b/module/plugins/hoster/UpleaCom.py
@@ -9,7 +9,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class UpleaCom(XFSHoster):
__name__ = "UpleaCom"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?uplea\.com/dl/\w{15}'
@@ -19,8 +20,6 @@ class UpleaCom(XFSHoster):
("GammaC0de", None)]
- DISPOSITION = False #@TODO: Remove in 0.4.10
-
HOSTER_DOMAIN = "uplea.com"
SIZE_REPLACEMENTS = [('ko','KB'), ('mo','MB'), ('go','GB'), ('Ko','KB'), ('Mo','MB'), ('Go','GB')]
@@ -38,11 +37,11 @@ class UpleaCom(XFSHoster):
def setup(self):
self.multiDL = False
- self.chunkLimit = 1
- self.resumeDownload = True
+ self.chunk_limit = 1
+ self.resume_download = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.STEP_PATTERN, self.html)
if m is None:
self.error(_("STEP_PATTERN not found"))
@@ -51,7 +50,7 @@ class UpleaCom(XFSHoster):
m = re.search(self.WAIT_PATTERN, self.html)
if m:
- self.logDebug(_("Waiting %s seconds") % m.group(1))
+ self.log_debug("Waiting %s seconds" % m.group(1))
self.wait(m.group(1), True)
self.retry()
diff --git a/module/plugins/hoster/UploadStationCom.py b/module/plugins/hoster/UploadStationCom.py
index 61226e3da..36b766b7e 100644
--- a/module/plugins/hoster/UploadStationCom.py
+++ b/module/plugins/hoster/UploadStationCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class UploadStationCom(DeadHoster):
__name__ = "UploadStationCom"
__type__ = "hoster"
- __version__ = "0.52"
+ __version__ = "0.53"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadstation\.com/file/(?P<ID>\w+)'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/UploadableCh.py b/module/plugins/hoster/UploadableCh.py
index f323a3538..88d79e9ba 100644
--- a/module/plugins/hoster/UploadableCh.py
+++ b/module/plugins/hoster/UploadableCh.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UploadableCh(SimpleHoster):
__name__ = "UploadableCh"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadable\.ch/file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -32,46 +33,45 @@ class UploadableCh(SimpleHoster):
RECAPTCHA_KEY = "6LdlJuwSAAAAAPJbPIoUhyqOJd7-yrah5Nhim5S3"
- def handleFree(self, pyfile):
- # Click the "free user" button and wait
- a = self.load(pyfile.url, post={'downloadLink': "wait"}, decode=True)
- self.logDebug(a)
+ def handle_free(self, pyfile):
+ #: Click the "free user" button and wait
+ a = self.load(pyfile.url, post={'downloadLink': "wait"})
+ self.log_debug(a)
self.wait(30)
- # Make the recaptcha appear and show it the pyload interface
- b = self.load(pyfile.url, post={'checkDownload': "check"}, decode=True)
- self.logDebug(b) #: Expected output: {"success":"showCaptcha"}
+ #: Make the recaptcha appear and show it the pyload interface
+ b = self.load(pyfile.url, post={'checkDownload': "check"})
+ self.log_debug(b) #: Expected output: {'success': "showCaptcha"}
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge(self.RECAPTCHA_KEY)
- # Submit the captcha solution
+ #: Submit the captcha solution
self.load("http://www.uploadable.ch/checkReCaptcha.php",
post={'recaptcha_challenge_field' : challenge,
'recaptcha_response_field' : response,
- 'recaptcha_shortencode_field': self.info['pattern']['ID']},
- decode=True)
+ 'recaptcha_shortencode_field': self.info['pattern']['ID']})
self.wait(3)
- # Get ready for downloading
- self.load(pyfile.url, post={'downloadLink': "show"}, decode=True)
+ #: Get ready for downloading
+ self.load(pyfile.url, post={'downloadLink': "show"})
self.wait(3)
- # Download the file
+ #: Download the file
self.download(pyfile.url, post={'download': "normal"}, disposition=True)
- def checkFile(self, rules={}):
- if self.checkDownload({'wait': re.compile("Please wait for")}):
- self.logInfo("Downloadlimit reached, please wait or reconnect")
+ def check_file(self):
+ if self.check_download({'wait': re.compile("Please wait for")}):
+ self.log_info(_("Downloadlimit reached, please wait or reconnect"))
self.wait(60 * 60, True)
self.retry()
- return super(UploadableCh, self).checkFile(rules)
+ return super(UploadableCh, self).check_file()
getInfo = create_getInfo(UploadableCh)
diff --git a/module/plugins/hoster/UploadboxCom.py b/module/plugins/hoster/UploadboxCom.py
index cb4f50184..a1053a413 100644
--- a/module/plugins/hoster/UploadboxCom.py
+++ b/module/plugins/hoster/UploadboxCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class UploadboxCom(DeadHoster):
__name__ = "Uploadbox"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadbox\.com/files/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py
index 16966a23d..c90f2bb0f 100644
--- a/module/plugins/hoster/UploadedTo.py
+++ b/module/plugins/hoster/UploadedTo.py
@@ -2,16 +2,18 @@
import re
import time
+import urlparse
-from module.network.RequestFactory import getURL
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UploadedTo(SimpleHoster):
__name__ = "UploadedTo"
__type__ = "hoster"
- __version__ = "0.89"
+ __version__ = "0.96"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(uploaded\.(to|net)|ul\.to)(/file/|/?\?id=|.*?&id=|/)(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -21,28 +23,30 @@ class UploadedTo(SimpleHoster):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- DISPOSITION = False
-
- API_KEY = "lhF2IeeprweDfu9ccWlxXVVypA5nA3EL"
+ CHECK_TRAFFIC = True
URL_REPLACEMENTS = [(__pattern__ + ".*", r'http://uploaded.net/file/\g<ID>')]
+ API_KEY = "lhF2IeeprweDfu9ccWlxXVVypA5nA3EL"
+
+ OFFLINE_PATTERN = r'>Page not found'
TEMP_OFFLINE_PATTERN = r'<title>uploaded\.net - Maintenance'
+ LINK_FREE_PATTERN = r"url:\s*'(.+?)'"
LINK_PREMIUM_PATTERN = r'<div class="tfree".*\s*<form method="post" action="(.+?)"'
- WAIT_PATTERN = r'Current waiting period: <span>(\d+)'
- DL_LIMIT_ERROR = r'You have reached the max. number of possible free downloads for this hour'
+ WAIT_PATTERN = r'Current waiting period: <span>(\d+)'
+ DL_LIMIT_PATTERN = r'You have reached the max. number of possible free downloads for this hour'
@classmethod
- def apiInfo(cls, url):
- info = super(UploadedTo, cls).apiInfo(url)
+ def api_info(cls, url):
+ info = super(UploadedTo, cls).api_info(url)
for _i in xrange(5):
- html = getURL("http://uploaded.net/api/filemultiple",
- get={"apikey": cls.API_KEY, 'id_0': re.match(cls.__pattern__, url).group('ID')},
- decode=True)
+ html = get_url("http://uploaded.net/api/filemultiple",
+ get={'apikey': cls.API_KEY,
+ 'id_0': re.match(cls.__pattern__, url).group('ID')})
if html != "can't find request":
api = html.split(",", 4)
@@ -58,42 +62,14 @@ class UploadedTo(SimpleHoster):
def setup(self):
- self.multiDL = self.resumeDownload = self.premium
- self.chunkLimit = 1 # critical problems with more chunks
-
-
- def checkErrors(self):
- if 'var free_enabled = false;' in self.html:
- self.logError(_("Free-download capacities exhausted"))
- self.retry(24, 5 * 60)
-
- elif "limit-size" in self.html:
- self.fail(_("File too big for free download"))
-
- elif "limit-slot" in self.html: # Temporary restriction so just wait a bit
- self.wait(30 * 60, True)
- self.retry()
-
- elif "limit-parallel" in self.html:
- self.fail(_("Cannot download in parallel"))
+ self.multiDL = self.resume_download = self.premium
+ self.chunk_limit = 1 #: Critical problems with more chunks
- elif "limit-dl" in self.html or self.DL_LIMIT_ERROR in self.html: # limit-dl
- self.wait(3 * 60 * 60, True)
- self.retry()
- elif '"err":"captcha"' in self.html:
- self.invalidCaptcha()
-
- else:
- m = re.search(self.WAIT_PATTERN, self.html)
- if m:
- self.wait(m.group(1))
-
-
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.load("http://uploaded.net/language/en", just_header=True)
- self.html = self.load("http://uploaded.net/js/download.js", decode=True)
+ self.html = self.load("http://uploaded.net/js/download.js")
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge()
@@ -102,23 +78,8 @@ class UploadedTo(SimpleHoster):
post={'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
- if "type:'download'" in self.html:
- self.correctCaptcha()
- try:
- self.link = re.search("url:'(.+?)'", self.html).group(1)
-
- except Exception:
- pass
-
- self.checkErrors()
-
-
- def checkFile(self, rules={}):
- if self.checkDownload({'limit-dl': self.DL_LIMIT_ERROR}):
- self.wait(3 * 60 * 60, True)
- self.retry()
-
- return super(UploadedTo, self).checkFile(rules)
+ super(UploadedTo, self).handle_free(pyfile)
+ self.check_errors()
getInfo = create_getInfo(UploadedTo)
diff --git a/module/plugins/hoster/UploadhereCom.py b/module/plugins/hoster/UploadhereCom.py
index bc94e644e..a3c41e824 100644
--- a/module/plugins/hoster/UploadhereCom.py
+++ b/module/plugins/hoster/UploadhereCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class UploadhereCom(DeadHoster):
__name__ = "UploadhereCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadhere\.com/\w{10}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/UploadheroCom.py b/module/plugins/hoster/UploadheroCom.py
index 5c74f10eb..2af0f32fc 100644
--- a/module/plugins/hoster/UploadheroCom.py
+++ b/module/plugins/hoster/UploadheroCom.py
@@ -12,7 +12,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UploadheroCom(SimpleHoster):
__name__ = "UploadheroCom"
__type__ = "hoster"
- __version__ = "0.18"
+ __version__ = "0.19"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadhero\.com?/dl/\w+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -38,15 +39,15 @@ class UploadheroCom(SimpleHoster):
LINK_PREMIUM_PATTERN = r'<a href="(.+?)" id="downloadnow"'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m is None:
self.error(_("Captcha not found"))
- captcha = self.decryptCaptcha(urlparse.urljoin("http://uploadhero.co", m.group(1)))
+ captcha = self.captcha.decrypt(urlparse.urljoin("http://uploadhero.co", m.group(1)))
self.html = self.load(pyfile.url,
- get={"code": captcha})
+ get={'code': captcha})
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
@@ -54,7 +55,7 @@ class UploadheroCom(SimpleHoster):
self.wait(50)
- def checkErrors(self):
+ def check_errors(self):
m = re.search(self.IP_BLOCKED_PATTERN, self.html)
if m:
self.html = self.load(urlparse.urljoin("http://uploadhero.co", m.group(1)))
@@ -64,7 +65,7 @@ class UploadheroCom(SimpleHoster):
self.wait(wait_time, True)
self.retry()
- return super(UploadheroCom, self).checkErrors()
+ return super(UploadheroCom, self).check_errors()
getInfo = create_getInfo(UploadheroCom)
diff --git a/module/plugins/hoster/UploadingCom.py b/module/plugins/hoster/UploadingCom.py
index c2e0d2873..36f0c766e 100644
--- a/module/plugins/hoster/UploadingCom.py
+++ b/module/plugins/hoster/UploadingCom.py
@@ -4,13 +4,15 @@ import pycurl
import re
from module.common.json_layer import json_loads
+from module.plugins.internal.Plugin import encode
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, timestamp
class UploadingCom(SimpleHoster):
__name__ = "UploadingCom"
__type__ = "hoster"
- __version__ = "0.40"
+ __version__ = "0.43"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploading\.com/files/(?:get/)?(?P<ID>\w+)'
@@ -21,7 +23,7 @@ class UploadingCom(SimpleHoster):
("zoidberg", "zoidberg@mujmail.cz")]
- NAME_PATTERN = r'id="file_title">(?P<N>.+)</'
+ NAME_PATTERN = r'id="file_title">(?P<N>.+?)</'
SIZE_PATTERN = r'size tip_container">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<'
OFFLINE_PATTERN = r'(Page|file) not found'
@@ -35,16 +37,16 @@ class UploadingCom(SimpleHoster):
if not "/get/" in pyfile.url:
pyfile.url = pyfile.url.replace("/files", "/files/get")
- self.html = self.load(pyfile.url, decode=True)
- self.getFileInfo()
+ self.html = self.load(pyfile.url)
+ self.get_fileInfo()
if self.premium:
- self.handlePremium(pyfile)
+ self.handle_premium(pyfile)
else:
- self.handleFree(pyfile)
+ self.handle_free(pyfile)
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
postData = {'action': 'get_link',
'code' : self.info['pattern']['ID'],
'pass' : 'undefined'}
@@ -57,11 +59,11 @@ class UploadingCom(SimpleHoster):
raise Exception("Plugin defect")
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search('<h2>((Daily )?Download Limit)</h2>', self.html)
if m:
- pyfile.error = m.group(1)
- self.logWarning(pyfile.error)
+ pyfile.error = encode(m.group(1))
+ self.log_warning(pyfile.error)
self.retry(6, (6 * 60 if m.group(2) else 15) * 60, pyfile.error)
ajax_url = "http://uploading.com/files/get/?ajax"
@@ -72,7 +74,7 @@ class UploadingCom(SimpleHoster):
if 'answer' in res and 'wait_time' in res['answer']:
wait_time = int(res['answer']['wait_time'])
- self.logInfo(_("Waiting %d seconds") % wait_time)
+ self.log_info(_("Waiting %d seconds") % wait_time)
self.wait(wait_time)
else:
self.error(_("No AJAX/WAIT"))
diff --git a/module/plugins/hoster/UploadkingCom.py b/module/plugins/hoster/UploadkingCom.py
index 0d60cef1f..54fe47cc8 100644
--- a/module/plugins/hoster/UploadkingCom.py
+++ b/module/plugins/hoster/UploadkingCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class UploadkingCom(DeadHoster):
__name__ = "UploadkingCom"
__type__ = "hoster"
- __version__ = "0.14"
+ __version__ = "0.15"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?uploadking\.com/\w{10}'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/UpstoreNet.py b/module/plugins/hoster/UpstoreNet.py
index 6410a2dce..12c667efb 100644
--- a/module/plugins/hoster/UpstoreNet.py
+++ b/module/plugins/hoster/UpstoreNet.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class UpstoreNet(SimpleHoster):
__name__ = "UpstoreNet"
__type__ = "hoster"
- __version__ = "0.06"
+ __version__ = "0.07"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?upstore\.net/'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -27,39 +28,39 @@ class UpstoreNet(SimpleHoster):
LINK_FREE_PATTERN = r'<a href="(https?://.*?)" target="_blank"><b>'
- def handleFree(self, pyfile):
- # STAGE 1: get link to continue
+ def handle_free(self, pyfile):
+ #: STAGE 1: get link to continue
m = re.search(self.CHASH_PATTERN, self.html)
if m is None:
self.error(_("CHASH_PATTERN not found"))
chash = m.group(1)
- self.logDebug("Read hash " + chash)
- # continue to stage2
+ self.log_debug("Read hash " + chash)
+ #: Continue to stage2
post_data = {'hash': chash, 'free': 'Slow download'}
- self.html = self.load(pyfile.url, post=post_data, decode=True)
+ self.html = self.load(pyfile.url, post=post_data)
- # STAGE 2: solv captcha and wait
- # first get the infos we need: recaptcha key and wait time
+ #: STAGE 2: solv captcha and wait
+ #: First get the infos we need: recaptcha key and wait time
recaptcha = ReCaptcha(self)
- # try the captcha 5 times
+ #: Try the captcha 5 times
for i in xrange(5):
m = re.search(self.WAIT_PATTERN, self.html)
if m is None:
self.error(_("Wait pattern not found"))
wait_time = int(m.group(1))
- # then, do the waiting
+ #: then, do the waiting
self.wait(wait_time)
- # then, handle the captcha
+ #: then, handle the captcha
response, challenge = recaptcha.challenge()
post_data.update({'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
- self.html = self.load(pyfile.url, post=post_data, decode=True)
+ self.html = self.load(pyfile.url, post=post_data)
- # STAGE 3: get direct link
+ #: STAGE 3: get direct link
m = re.search(self.LINK_FREE_PATTERN, self.html, re.S)
if m:
break
diff --git a/module/plugins/hoster/UptoboxCom.py b/module/plugins/hoster/UptoboxCom.py
index 2c06558e4..d6baa3990 100644
--- a/module/plugins/hoster/UptoboxCom.py
+++ b/module/plugins/hoster/UptoboxCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class UptoboxCom(XFSHoster):
__name__ = "UptoboxCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(uptobox|uptostream)\.com/\w{12}'
@@ -24,8 +25,8 @@ class UptoboxCom(XFSHoster):
def setup(self):
self.multiDL = True
- self.chunkLimit = 1
- self.resumeDownload = True
+ self.chunk_limit = 1
+ self.resume_download = True
getInfo = create_getInfo(UptoboxCom)
diff --git a/module/plugins/hoster/VeehdCom.py b/module/plugins/hoster/VeehdCom.py
index 78da91020..cf206992d 100644
--- a/module/plugins/hoster/VeehdCom.py
+++ b/module/plugins/hoster/VeehdCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class VeehdCom(Hoster):
__name__ = "VeehdCom"
__type__ = "hoster"
- __version__ = "0.23"
+ __version__ = "0.25"
+ __status__ = "testing"
__pattern__ = r'http://veehd\.com/video/\d+_\S+'
__config__ = [("filename_spaces", "bool", "Allow spaces in filename", False),
@@ -35,7 +36,7 @@ class VeehdCom(Hoster):
def download_html(self):
url = self.pyfile.url
- self.logDebug("Requesting page: %s" % url)
+ self.log_debug("Requesting page: %s" % url)
self.html = self.load(url)
@@ -58,17 +59,18 @@ class VeehdCom(Hoster):
name = m.group(1)
- # replace unwanted characters in filename
- if self.getConfig('filename_spaces'):
+ #: Replace unwanted characters in filename
+ if self.get_config('filename_spaces'):
pattern = '[^\w ]+'
else:
pattern = '[^\w.]+'
- return re.sub(pattern, self.getConfig('replacement_char'), name) + '.avi'
+ return re.sub(pattern, self.get_config('replacement_char'), name) + '.avi'
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/VeohCom.py b/module/plugins/hoster/VeohCom.py
index 57b24623b..7d46ee335 100644
--- a/module/plugins/hoster/VeohCom.py
+++ b/module/plugins/hoster/VeohCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class VeohCom(SimpleHoster):
__name__ = "VeohCom"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.23"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?veoh\.com/(tv/)?(watch|videos)/(?P<ID>v\w+)'
__config__ = [("use_premium", "bool" , "Use premium account if available", True ),
@@ -28,13 +29,13 @@ class VeohCom(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- self.chunkLimit = -1
+ self.chunk_limit = -1
- def handleFree(self, pyfile):
- quality = self.getConfig('quality')
+ def handle_free(self, pyfile):
+ quality = self.get_config('quality')
if quality == "Auto":
quality = ("High", "Low")
@@ -46,7 +47,7 @@ class VeohCom(SimpleHoster):
self.link = m.group(1).replace("\\", "")
return
else:
- self.logInfo(_("No %s quality video found") % q.upper())
+ self.log_info(_("No %s quality video found") % q.upper())
else:
self.fail(_("No video found!"))
diff --git a/module/plugins/hoster/VidPlayNet.py b/module/plugins/hoster/VidPlayNet.py
index f1a32a897..f9df18c85 100644
--- a/module/plugins/hoster/VidPlayNet.py
+++ b/module/plugins/hoster/VidPlayNet.py
@@ -9,7 +9,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class VidPlayNet(XFSHoster):
__name__ = "VidPlayNet"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.05"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?vidplay\.net/\w{12}'
diff --git a/module/plugins/hoster/VimeoCom.py b/module/plugins/hoster/VimeoCom.py
index a5196cb92..d47677c42 100644
--- a/module/plugins/hoster/VimeoCom.py
+++ b/module/plugins/hoster/VimeoCom.py
@@ -8,7 +8,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class VimeoCom(SimpleHoster):
__name__ = "VimeoCom"
__type__ = "hoster"
- __version__ = "0.04"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(player\.)?vimeo\.com/(video/)?(?P<ID>\d+)'
__config__ = [("use_premium", "bool" , "Use premium account if available" , True ),
@@ -20,7 +21,7 @@ class VimeoCom(SimpleHoster):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- NAME_PATTERN = r'<title>(?P<N>.+) on Vimeo<'
+ NAME_PATTERN = r'<title>(?P<N>.+?) on Vimeo<'
OFFLINE_PATTERN = r'class="exception_header"'
TEMP_OFFLINE_PATTERN = r'Please try again in a few minutes.<'
@@ -30,16 +31,16 @@ class VimeoCom(SimpleHoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
- self.chunkLimit = -1
+ self.chunk_limit = -1
- def handleFree(self, pyfile):
- password = self.getPassword()
+ def handle_free(self, pyfile):
+ password = self.get_password()
if self.js and 'class="btn iconify_down_b"' in self.html:
- html = self.js.eval(self.load(pyfile.url, get={'action': "download", 'password': password}, decode=True))
+ html = self.js.eval(self.load(pyfile.url, get={'action': "download", 'password': password}))
pattern = r'href="(?P<URL>http://vimeo\.com.+?)".*?\>(?P<QL>.+?) '
else:
html = self.load("https://player.vimeo.com/video/" + self.info['pattern']['ID'], get={'password': password})
@@ -47,14 +48,14 @@ class VimeoCom(SimpleHoster):
link = dict((l.group('QL').lower(), l.group('URL')) for l in re.finditer(pattern, html))
- if self.getConfig('original'):
+ if self.get_config('original'):
if "original" in link:
self.link = link[q]
return
else:
- self.logInfo(_("Original file not downloadable"))
+ self.log_info(_("Original file not downloadable"))
- quality = self.getConfig('quality')
+ quality = self.get_config('quality')
if quality == "Highest":
qlevel = ("hd", "sd", "mobile")
elif quality == "Lowest":
@@ -67,7 +68,7 @@ class VimeoCom(SimpleHoster):
self.link = link[q]
return
else:
- self.logInfo(_("No %s quality video found") % q.upper())
+ self.log_info(_("No %s quality video found") % q.upper())
else:
self.fail(_("No video found!"))
diff --git a/module/plugins/hoster/Vipleech4UCom.py b/module/plugins/hoster/Vipleech4UCom.py
index 5668e0fad..8eac61341 100644
--- a/module/plugins/hoster/Vipleech4UCom.py
+++ b/module/plugins/hoster/Vipleech4UCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class Vipleech4UCom(DeadHoster):
__name__ = "Vipleech4UCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.21"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?vipleech4u\.com/manager\.php'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/VkCom.py b/module/plugins/hoster/VkCom.py
new file mode 100644
index 000000000..d0b0b780e
--- /dev/null
+++ b/module/plugins/hoster/VkCom.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+#
+# Test links:
+# http://vk.com/video_ext.php?oid=166335015&id=162608895&hash=b55affa83774504b&hd=1
+
+import re
+
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class VkCom(SimpleHoster):
+ __name__ = "VkCom"
+ __type__ = "hoster"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r"https?://(?:www\.)?vk\.com/video_ext\.php/\?.+"
+ __config__ = [("quality", "Low;High;Auto", "Quality", "Auto")]
+
+ __description__ = """Vk.com hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ NAME_PATTERN = r'"md_title":"(?P<N>.+?)"'
+ OFFLINE_PATTERN = r'<div id="video_ext_msg">'
+
+ LINK_FREE_PATTERN = r'url\d+":"(.+?)"'
+
+
+ def handle_free(self, pyfile):
+ self.link = re.findall(self.LINK_FREE_PATTERN, self.html)[0 if self.get_config('quality') == "Low" else -1]
+
+
+getInfo = create_getInfo(VkCom)
diff --git a/module/plugins/hoster/WarserverCz.py b/module/plugins/hoster/WarserverCz.py
index 6cb94e57e..a356dccdd 100644
--- a/module/plugins/hoster/WarserverCz.py
+++ b/module/plugins/hoster/WarserverCz.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class WarserverCz(DeadHoster):
__name__ = "WarserverCz"
__type__ = "hoster"
- __version__ = "0.13"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?warserver\.cz/stahnout/\d+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/WebshareCz.py b/module/plugins/hoster/WebshareCz.py
index ae670c8d4..0a89363f8 100644
--- a/module/plugins/hoster/WebshareCz.py
+++ b/module/plugins/hoster/WebshareCz.py
@@ -2,61 +2,59 @@
import re
-from module.network.RequestFactory import getURL
+from module.network.RequestFactory import getURL as get_url
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class WebshareCz(SimpleHoster):
__name__ = "WebshareCz"
__type__ = "hoster"
- __version__ = "0.16"
+ __version__ = "0.19"
+ __status__ = "testing"
- __pattern__ = r'https?://(?:www\.)?webshare\.cz/(?:#/)?file/(?P<ID>\w+)'
+ __pattern__ = r'https?://(?:www\.)?(en\.)?webshare\.cz/(?:#/)?file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
__description__ = """WebShare.cz hoster plugin"""
__license__ = "GPLv3"
- __authors__ = [("stickell", "l.stickell@yahoo.it"),
- ("rush", "radek.senfeld@gmail.com")]
+ __authors__ = [("stickell", "l.stickell@yahoo.it "),
+ ("rush" , "radek.senfeld@gmail.com")]
@classmethod
- def getInfo(cls, url="", html=""):
- info = super(WebshareCz, cls).getInfo(url, html)
+ def api_info(cls, url):
+ info = super(WebshareCz, cls).api_info(url)
- if url:
- info['pattern'] = re.match(cls.__pattern__, url).groupdict()
+ info['pattern'] = re.match(cls.__pattern__, url).groupdict()
- api_data = getURL("https://webshare.cz/api/file_info/",
- post={'ident': info['pattern']['ID']},
- decode=True)
+ api_data = get_url("https://webshare.cz/api/file_info/",
+ post={'ident': info['pattern']['ID'], 'wst': ""})
- if 'File not found' in api_data:
- info['status'] = 1
- else:
- info["status"] = 2
- info['name'] = re.search('<name>(.+)</name>', api_data).group(1) or info['name']
- info['size'] = re.search('<size>(.+)</size>', api_data).group(1) or info['size']
+ if not re.search(r'<status>OK', api_data):
+ info['status'] = 1
+ else:
+ info['status'] = 2
+ info['name'] = re.search(r'<name>(.+?)<', api_data).group(1)
+ info['size'] = re.search(r'<size>(.+?)<', api_data).group(1)
return info
- def handleFree(self, pyfile):
- wst = self.account.infos['wst'] if self.account and 'wst' in self.account.infos else ""
+ def handle_free(self, pyfile):
+ wst = self.account.get_data(self.user).get('wst', None) if self.account else None
- api_data = getURL('https://webshare.cz/api/file_link/',
- post={'ident': self.info['pattern']['ID'], 'wst': wst},
- decode=True)
+ api_data = get_url("https://webshare.cz/api/file_link/",
+ post={'ident': self.info['pattern']['ID'], 'wst': wst})
- self.logDebug("API data: " + api_data)
+ self.log_debug("API data: " + api_data)
m = re.search('<link>(.+)</link>', api_data)
if m:
self.link = m.group(1)
- def handlePremium(self, pyfile):
- return self.handleFree(pyfile)
+ def handle_premium(self, pyfile):
+ return self.handle_free(pyfile)
getInfo = create_getInfo(WebshareCz)
diff --git a/module/plugins/hoster/WrzucTo.py b/module/plugins/hoster/WrzucTo.py
index f11d03ea8..4c3b47b37 100644
--- a/module/plugins/hoster/WrzucTo.py
+++ b/module/plugins/hoster/WrzucTo.py
@@ -9,7 +9,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class WrzucTo(SimpleHoster):
__name__ = "WrzucTo"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?wrzuc\.to/(\w+(\.wt|\.html)|(\w+/?linki/\w+))'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -29,17 +30,17 @@ class WrzucTo(SimpleHoster):
self.multiDL = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
data = dict(re.findall(r'(md5|file): "(.*?)"', self.html))
if len(data) != 2:
self.error(_("No file ID"))
self.req.http.c.setopt(pycurl.HTTPHEADER, ["X-Requested-With: XMLHttpRequest"])
self.req.http.lastURL = pyfile.url
- self.load("http://www.wrzuc.to/ajax/server/prepair", post={"md5": data['md5']})
+ self.load("http://www.wrzuc.to/ajax/server/prepair", post={'md5': data['md5']})
self.req.http.lastURL = pyfile.url
- self.html = self.load("http://www.wrzuc.to/ajax/server/download_link", post={"file": data['file']})
+ self.html = self.load("http://www.wrzuc.to/ajax/server/download_link", post={'file': data['file']})
data.update(re.findall(r'"(download_link|server_id)":"(.*?)"', self.html))
if len(data) != 4:
diff --git a/module/plugins/hoster/WuploadCom.py b/module/plugins/hoster/WuploadCom.py
index 73c008ae8..028e557e9 100644
--- a/module/plugins/hoster/WuploadCom.py
+++ b/module/plugins/hoster/WuploadCom.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class WuploadCom(DeadHoster):
__name__ = "WuploadCom"
__type__ = "hoster"
- __version__ = "0.23"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?wupload\..+?/file/((\w+/)?\d+)(/.*)?'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/X7To.py b/module/plugins/hoster/X7To.py
index 8e2dd3a53..285499807 100644
--- a/module/plugins/hoster/X7To.py
+++ b/module/plugins/hoster/X7To.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class X7To(DeadHoster):
__name__ = "X7To"
__type__ = "hoster"
- __version__ = "0.41"
+ __version__ = "0.42"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?x7\.to/'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py
index 169fbc8d3..8ede709de 100644
--- a/module/plugins/hoster/XFileSharingPro.py
+++ b/module/plugins/hoster/XFileSharingPro.py
@@ -8,7 +8,8 @@ from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo
class XFileSharingPro(XFSHoster):
__name__ = "XFileSharingPro"
__type__ = "hoster"
- __version__ = "0.46"
+ __version__ = "0.53"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?(?:\w+\.)*?(?P<DOMAIN>(?:[\d.]+|[\w\-^_]{3,}(?:\.[a-zA-Z]{2,}){1,2})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)'
@@ -20,40 +21,54 @@ class XFileSharingPro(XFSHoster):
URL_REPLACEMENTS = [("/embed-", "/")]
- def _log(self, type, args):
- msg = " | ".join(str(a).strip() for a in args if a)
- logger = getattr(self.log, type)
- logger("%s: %s: %s" % (self.__name__, self.HOSTER_NAME, msg or _("%s MARK" % type.upper())))
+ def _log(self, level, plugintype, pluginname, messages):
+ return super(XFileSharingPro, self)._log(level,
+ plugintype,
+ "%s: %s" % (pluginname, self.HOSTER_NAME),
+ messages)
def init(self):
- super(XFileSharingPro, self).init()
-
- self.__pattern__ = self.core.pluginManager.hosterPlugins[self.__name__]['pattern']
+ self.__pattern__ = self.pyload.pluginManager.hosterPlugins[self.__name__]['pattern']
self.HOSTER_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group("DOMAIN").lower()
- self.HOSTER_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+)', self.HOSTER_DOMAIN) if part != '.')
-
- account = self.core.accountManager.getAccountPlugin(self.HOSTER_NAME)
+ self.HOSTER_NAME = "".join(part.capitalize() for part in re.split(r'(\.|\d+|\-)', self.HOSTER_DOMAIN) if part != '.')
- if account and account.canUse():
- self.account = account
- elif self.account:
- self.account.HOSTER_DOMAIN = self.HOSTER_DOMAIN
+ def _setup(self):
+ account_name = self.__name__ if self.account.HOSTER_DOMAIN is None else self.HOSTER_NAME
+ self.chunk_limit = 1
+ self.multiDL = True
+ if self.account:
+ self.req = self.pyload.requestFactory.getRequest(accountname, self.user)
+ self.premium = self.account.is_premium(self.user)
+ self.resume_download = self.premium
else:
- return
+ self.req = self.pyload.requestFactory.getRequest(account_name)
+ self.premium = False
+ self.resume_download = False
+
+
+ def load_account(self):
+ if self.req:
+ self.req.close()
+
+ if not self.account:
+ self.account = self.pyload.accountManager.getAccountPlugin(self.HOSTER_NAME)
+
+ if not self.account:
+ self.account = self.pyload.accountManager.getAccountPlugin(self.__name__)
- self.user, data = self.account.selectAccount()
- self.req = self.account.getAccountRequest(self.user)
- self.premium = self.account.isPremium(self.user)
+ if self.account:
+ if not self.account.HOSTER_DOMAIN:
+ self.account.HOSTER_DOMAIN = self.HOSTER_DOMAIN
+ if not self.user:
+ self.user = self.account.select()[0]
- def setup(self):
- self.chunkLimit = 1
- self.resumeDownload = self.premium
- self.multiDL = True
+ if not self.user or not self.account.is_logged(self.user, True):
+ self.account = False
getInfo = create_getInfo(XFileSharingPro)
diff --git a/module/plugins/hoster/XHamsterCom.py b/module/plugins/hoster/XHamsterCom.py
index a1711cb0e..8df1a441f 100644
--- a/module/plugins/hoster/XHamsterCom.py
+++ b/module/plugins/hoster/XHamsterCom.py
@@ -4,7 +4,7 @@ import re
import urllib
from module.common.json_layer import json_loads
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
def clean_json(json_expr):
@@ -18,7 +18,8 @@ def clean_json(json_expr):
class XHamsterCom(Hoster):
__name__ = "XHamsterCom"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.14"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?xhamster\.com/movies/.+'
__config__ = [("type", ".mp4;.flv", "Preferred type", ".mp4")]
@@ -34,8 +35,8 @@ class XHamsterCom(Hoster):
if not self.file_exists():
self.offline()
- if self.getConfig('type'):
- self.desired_fmt = self.getConfig('type')
+ if self.get_config('type'):
+ self.desired_fmt = self.get_config('type')
pyfile.name = self.get_file_name() + self.desired_fmt
self.download(self.get_file_url())
@@ -47,7 +48,8 @@ class XHamsterCom(Hoster):
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
@@ -79,19 +81,19 @@ class XHamsterCom(Hoster):
self.error(_("file_url not found"))
file_url = file_url.group(1)
long_url = srv_url + file_url
- self.logDebug("long_url = " + long_url)
+ self.log_debug("long_url = " + long_url)
else:
if flashvars['file']:
file_url = urllib.unquote(flashvars['file'])
else:
self.error(_("file_url not found"))
- if url_mode == '3':
+ if url_mode == "3":
long_url = file_url
- self.logDebug("long_url = " + long_url)
+ self.log_debug("long_url = " + long_url)
else:
long_url = srv_url + "key=" + file_url
- self.logDebug("long_url = " + long_url)
+ self.log_debug("long_url = " + long_url)
return long_url
@@ -118,7 +120,8 @@ class XHamsterCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/XVideosCom.py b/module/plugins/hoster/XVideosCom.py
index a8f291824..d74f35616 100644
--- a/module/plugins/hoster/XVideosCom.py
+++ b/module/plugins/hoster/XVideosCom.py
@@ -3,13 +3,14 @@
import re
import urllib
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class XVideosCom(Hoster):
__name__ = "XVideos.com"
__type__ = "hoster"
- __version__ = "0.10"
+ __version__ = "0.12"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?xvideos\.com/video(\d+)'
diff --git a/module/plugins/hoster/XdadevelopersCom.py b/module/plugins/hoster/XdadevelopersCom.py
index 45d1e92cb..12f27c880 100644
--- a/module/plugins/hoster/XdadevelopersCom.py
+++ b/module/plugins/hoster/XdadevelopersCom.py
@@ -11,7 +11,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class XdadevelopersCom(SimpleHoster):
__name__ = "XdadevelopersCom"
__type__ = "hoster"
- __version__ = "0.03"
+ __version__ = "0.04"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)?forum\.xda-developers\.com/devdb/project/dl/\?id=\d+'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -28,11 +29,11 @@ class XdadevelopersCom(SimpleHoster):
def setup(self):
self.multiDL = True
- self.resumeDownload = True
- self.chunkLimit = 1
+ self.resume_download = True
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
self.link = pyfile.url + "&task=get" #@TODO: Revert to `get={'task': "get"}` in 0.4.10
diff --git a/module/plugins/hoster/Xdcc.py b/module/plugins/hoster/Xdcc.py
index d167e4cab..aba66ee94 100644
--- a/module/plugins/hoster/Xdcc.py
+++ b/module/plugins/hoster/Xdcc.py
@@ -8,14 +8,16 @@ import time
from select import select
-from module.plugins.Hoster import Hoster
-from module.utils import save_join
+from module.plugins.internal.Hoster import Hoster
+# from module.utils import decode
+from module.utils import save_join as fs_join
class Xdcc(Hoster):
__name__ = "Xdcc"
__type__ = "hoster"
- __version__ = "0.32"
+ __version__ = "0.34"
+ __status__ = "testing"
__config__ = [("nick", "str", "Nickname", "pyload"),
("ident", "str", "Ident", "pyloadident"),
@@ -27,20 +29,19 @@ class Xdcc(Hoster):
def setup(self):
- self.debug = 0 # 0,1,2
self.timeout = 30
self.multiDL = False
def process(self, pyfile):
- # change request type
- self.req = pyfile.m.core.requestFactory.getRequest(self.__name__, type="XDCC")
+ #: Change request type
+ self.req = self.pyload.requestFactory.getRequest(self.__name__, type="XDCC")
self.pyfile = pyfile
for _i in xrange(0, 3):
try:
- nmn = self.doDownload(pyfile.url)
- self.logDebug("Download of %s finished." % nmn)
+ nmn = self.do_download(pyfile.url)
+ self.log_debug("Download of %s finished." % nmn)
return
except socket.error, e:
if hasattr(e, "errno"):
@@ -49,9 +50,8 @@ class Xdcc(Hoster):
errno = e.args[0]
if errno == 10054:
- self.logDebug("Server blocked our ip, retry in 5 min")
- self.setWait(300)
- self.wait()
+ self.log_debug("Server blocked our ip, retry in 5 min")
+ self.wait(300)
continue
self.fail(_("Failed due to socket errors. Code: %d") % errno)
@@ -59,17 +59,17 @@ class Xdcc(Hoster):
self.fail(_("Server blocked our ip, retry again later manually"))
- def doDownload(self, url):
- self.pyfile.setStatus("waiting") # real link
+ def do_download(self, url):
+ self.pyfile.setStatus("waiting") #: Real link
m = re.match(r'xdcc://(.*?)/#?(.*?)/(.*?)/#?(\d+)/?', url)
server = m.group(1)
chan = m.group(2)
bot = m.group(3)
pack = m.group(4)
- nick = self.getConfig('nick')
- ident = self.getConfig('ident')
- real = self.getConfig('realname')
+ nick = self.get_config('nick')
+ ident = self.get_config('ident')
+ real = self.get_config('realname')
temp = server.split(':')
ln = len(temp)
@@ -81,30 +81,29 @@ class Xdcc(Hoster):
self.fail(_("Invalid hostname for IRC Server: %s") % server)
#######################
- # CONNECT TO IRC AND IDLE FOR REAL LINK
+ #: CONNECT TO IRC AND IDLE FOR REAL LINK
dl_time = time.time()
sock = socket.socket()
sock.connect((host, int(port)))
if nick == "pyload":
- nick = "pyload-%d" % (time.time() % 1000) # last 3 digits
+ nick = "pyload-%d" % (time.time() % 1000) #: last 3 digits
sock.send("NICK %s\r\n" % nick)
sock.send("USER %s %s bla :%s\r\n" % (ident, host, real))
- self.setWait(3)
- self.wait()
+ self.wait(3)
sock.send("JOIN #%s\r\n" % chan)
sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack))
- # IRC recv loop
+ #: IRC recv loop
readbuffer = ""
done = False
retry = None
m = None
while True:
- # done is set if we got our real link
+ #: Done is set if we got our real link
if done:
break
@@ -115,7 +114,7 @@ class Xdcc(Hoster):
sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack))
else:
- if (dl_time + self.timeout) < time.time(): # todo: add in config
+ if (dl_time + self.timeout) < time.time(): #@TODO: add in config
sock.send("QUIT :byebye\r\n")
sock.close()
self.fail(_("XDCC Bot did not answer"))
@@ -129,8 +128,8 @@ class Xdcc(Hoster):
readbuffer = temp.pop()
for line in temp:
- if self.debug is 2:
- print "*> " + unicode(line, errors='ignore')
+ # if self.pyload.debug:
+ # self.log_debug("*> " + decode(line))
line = line.rstrip()
first = line.split()
@@ -145,29 +144,29 @@ class Xdcc(Hoster):
continue
msg = {
- "origin": msg[0][1:],
- "action": msg[1],
- "target": msg[2],
- "text": msg[3][1:]
+ 'origin': msg[0][1:],
+ 'action': msg[1],
+ 'target': msg[2],
+ 'text': msg[3][1:]
}
- if nick == msg['target'][0:len(nick)] and "PRIVMSG" == msg['action']:
+ if nick is msg['target'][0:len(nick)] and "PRIVMSG" is msg['action']:
if msg['text'] == "\x01VERSION\x01":
- self.logDebug("Sending CTCP VERSION")
+ self.log_debug("Sending CTCP VERSION")
sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
elif msg['text'] == "\x01TIME\x01":
- self.logDebug("Sending CTCP TIME")
+ self.log_debug("Sending CTCP TIME")
sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time()))
elif msg['text'] == "\x01LAG\x01":
- pass # don't know how to answer
+ pass #: don't know how to answer
- if not (bot == msg['origin'][0:len(bot)]
- and nick == msg['target'][0:len(nick)]
+ if not (bot is msg['origin'][0:len(bot)]
+ and nick is msg['target'][0:len(nick)]
and msg['action'] in ("PRIVMSG", "NOTICE")):
continue
- if self.debug is 1:
- print "%s: %s" % (msg['origin'], msg['text'])
+ if self.pyload.debug:
+ self.log_debug(msg['origin'], msg['text'])
if "You already requested that pack" in msg['text']:
retry = time.time() + 300
@@ -179,7 +178,7 @@ class Xdcc(Hoster):
if m:
done = True
- # get connection data
+ #: Get connection data
ip = socket.inet_ntoa(struct.pack('L', socket.ntohl(int(m.group(2)))))
port = int(m.group(3))
packname = m.group(1)
@@ -189,20 +188,20 @@ class Xdcc(Hoster):
self.pyfile.name = packname
- download_folder = self.config['general']['download_folder']
- filename = save_join(download_folder, packname)
+ download_folder = self.pyload.config.get("general", "download_folder")
+ filename = fs_join(download_folder, packname)
- self.logInfo(_("Downloading %s from %s:%d") % (packname, ip, port))
+ self.log_info(_("Downloading %s from %s:%d") % (packname, ip, port))
self.pyfile.setStatus("downloading")
newname = self.req.download(ip, port, filename, sock, self.pyfile.setProgress)
- if newname and newname != filename:
- self.logInfo(_("%(name)s saved as %(newname)s") % {"name": self.pyfile.name, "newname": newname})
+ if newname and newname is not filename:
+ self.log_info(_("%(name)s saved as %(newname)s") % {'name': self.pyfile.name, 'newname': newname})
filename = newname
- # kill IRC socket
- # sock.send("QUIT :byebye\r\n")
+ #: kill IRC socket
+ #: sock.send("QUIT :byebye\r\n")
sock.close()
- self.lastDownload = filename
- return self.lastDownload
+ self.last_download = filename
+ return self.last_download
diff --git a/module/plugins/hoster/YadiSk.py b/module/plugins/hoster/YadiSk.py
index 3b4c9d985..a907cd282 100644
--- a/module/plugins/hoster/YadiSk.py
+++ b/module/plugins/hoster/YadiSk.py
@@ -10,7 +10,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class YadiSk(SimpleHoster):
__name__ = "YadiSk"
__type__ = "hoster"
- __version__ = "0.05"
+ __version__ = "0.06"
+ __status__ = "testing"
__pattern__ = r'https?://yadi\.sk/d/[\w-]+'
@@ -23,8 +24,8 @@ class YadiSk(SimpleHoster):
@classmethod
- def getInfo(cls, url="", html=""):
- info = super(YadiSk, cls).getInfo(url, html)
+ def get_info(cls, url="", html=""):
+ info = super(YadiSk, cls).get_info(url, html)
if html:
if 'idclient' not in info:
@@ -59,12 +60,12 @@ class YadiSk(SimpleHoster):
def setup(self):
- self.resumeDownload = False
+ self.resume_download = False
self.multiDL = False
- self.chunkLimit = 1
+ self.chunk_limit = 1
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if any(True for _k in ['id', 'sk', 'version', 'idclient'] if _k not in self.info):
self.error(_("Missing JSON data"))
diff --git a/module/plugins/hoster/YibaishiwuCom.py b/module/plugins/hoster/YibaishiwuCom.py
index 00185c05a..e0e90a311 100644
--- a/module/plugins/hoster/YibaishiwuCom.py
+++ b/module/plugins/hoster/YibaishiwuCom.py
@@ -10,7 +10,8 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class YibaishiwuCom(SimpleHoster):
__name__ = "YibaishiwuCom"
__type__ = "hoster"
- __version__ = "0.14"
+ __version__ = "0.15"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?(?:u\.)?115\.com/file/(?P<ID>\w+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
@@ -27,14 +28,14 @@ class YibaishiwuCom(SimpleHoster):
LINK_FREE_PATTERN = r'(/\?ct=(pickcode|download)[^"\']+)'
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
self.error(_("LINK_FREE_PATTERN not found"))
url = m.group(1)
- self.logDebug(('FREEUSER' if m.group(2) == 'download' else 'GUEST') + ' URL', url)
+ self.log_debug(('FREEUSER' if m.group(2) == "download" else 'GUEST') + ' URL', url)
res = json_loads(self.load(urlparse.urljoin("http://115.com", url), decode=False))
if "urls" in res:
@@ -49,7 +50,7 @@ class YibaishiwuCom(SimpleHoster):
for mr in mirrors:
try:
self.link = mr['url'].replace("\\", "")
- self.logDebug("Trying URL: " + self.link)
+ self.log_debug("Trying URL: " + self.link)
break
except Exception:
continue
diff --git a/module/plugins/hoster/YoupornCom.py b/module/plugins/hoster/YoupornCom.py
index 19d07fa36..02272bf36 100644
--- a/module/plugins/hoster/YoupornCom.py
+++ b/module/plugins/hoster/YoupornCom.py
@@ -2,13 +2,14 @@
import re
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class YoupornCom(Hoster):
__name__ = "YoupornCom"
__type__ = "hoster"
- __version__ = "0.20"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?youporn\.com/watch/.+'
@@ -29,11 +30,12 @@ class YoupornCom(Hoster):
def download_html(self):
url = self.pyfile.url
- self.html = self.load(url, post={"user_choice": "Enter"}, cookies=False)
+ self.html = self.load(url, post={'user_choice': "Enter"}, cookies=False)
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
if not self.html:
self.download_html()
@@ -50,7 +52,8 @@ class YoupornCom(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/YourfilesTo.py b/module/plugins/hoster/YourfilesTo.py
index d0316d3ac..a75bbcc94 100644
--- a/module/plugins/hoster/YourfilesTo.py
+++ b/module/plugins/hoster/YourfilesTo.py
@@ -1,14 +1,16 @@
# -*- coding: utf-8 -*-
-import reimport urllib
+import re
+import urllib
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
class YourfilesTo(Hoster):
__name__ = "YourfilesTo"
__type__ = "hoster"
- __version__ = "0.22"
+ __version__ = "0.24"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?yourfiles\.(to|biz)/\?d=\w+'
@@ -30,16 +32,14 @@ class YourfilesTo(Hoster):
self.pyfile.name = self.get_file_name()
- wait_time = self.get_waiting_time()
- self.setWait(wait_time)
- self.wait()
+ self.wait(self.get_waiting_time())
def get_waiting_time(self):
if not self.html:
self.download_html()
- #var zzipitime = 15;
+ #: var zzipitime = 15
m = re.search(r'var zzipitime = (\d+);', self.html)
if m:
sec = int(m.group(1))
@@ -55,7 +55,8 @@ class YourfilesTo(Hoster):
def get_file_url(self):
- """ returns the absolute downloadable filepath
+ """
+ Returns the absolute downloadable filepath
"""
url = re.search(r"var bla = '(.*?)';", self.html)
if url:
@@ -74,7 +75,8 @@ class YourfilesTo(Hoster):
def file_exists(self):
- """ returns True or False
+ """
+ Returns True or False
"""
if not self.html:
self.download_html()
diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py
index e2ab146a9..865eeef2e 100644
--- a/module/plugins/hoster/YoutubeCom.py
+++ b/module/plugins/hoster/YoutubeCom.py
@@ -2,17 +2,19 @@
import os
import re
-import subprocessimport urllib
+import subprocess
+import urllib
-from module.plugins.Hoster import Hoster
-from module.plugins.internal.SimpleHoster import replace_patterns
+from module.plugins.internal.Hoster import Hoster
+from module.plugins.internal.Plugin import replace_patterns
from module.utils import html_unescape
def which(program):
- """Works exactly like the unix command which
- Courtesy of http://stackoverflow.com/a/377028/675646"""
-
+ """
+ Works exactly like the unix command which
+ Courtesy of http://stackoverflow.com/a/377028/675646
+ """
isExe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK)
fpath, fname = os.path.split(program)
@@ -31,7 +33,8 @@ def which(program):
class YoutubeCom(Hoster):
__name__ = "YoutubeCom"
__type__ = "hoster"
- __version__ = "0.41"
+ __version__ = "0.44"
+ __status__ = "testing"
__pattern__ = r'https?://(?:[^/]*\.)?(youtube\.com|youtu\.be)/watch\?(?:.*&)?v=.+'
__config__ = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting" , "hd" ),
@@ -50,10 +53,10 @@ class YoutubeCom(Hoster):
URL_REPLACEMENTS = [(r'youtu\.be/', 'youtube.com/')]
- # Invalid characters that must be removed from the file name
+ #: Invalid characters that must be removed from the file name
invalidChars = u'\u2605:?><"|\\'
- # name, width, height, quality ranking, 3D
+ #: name, width, height, quality ranking, 3D
formats = {5 : (".flv" , 400 , 240 , 1 , False),
6 : (".flv" , 640 , 400 , 4 , False),
17 : (".3gp" , 176 , 144 , 0 , False),
@@ -78,88 +81,88 @@ class YoutubeCom(Hoster):
def setup(self):
- self.resumeDownload = True
+ self.resume_download = True
self.multiDL = True
def process(self, pyfile):
pyfile.url = replace_patterns(pyfile.url, self.URL_REPLACEMENTS)
- html = self.load(pyfile.url, decode=True)
+ html = self.load(pyfile.url)
if re.search(r'<div id="player-unavailable" class="\s*player-width player-height\s*">', html):
self.offline()
if "We have been receiving a large volume of requests from your network." in html:
- self.tempOffline()
+ self.temp_offline()
- #get config
- use3d = self.getConfig('3d')
+ #: Get config
+ use3d = self.get_config('3d')
if use3d:
- quality = {"sd": 82, "hd": 84, "fullhd": 85, "240p": 83, "360p": 82,
- "480p": 82, "720p": 84, "1080p": 85, "3072p": 85}
+ quality = {'sd': 82, 'hd': 84, 'fullhd': 85, '240p': 83, '360p': 82,
+ '480p': 82, '720p': 84, '1080p': 85, '3072p': 85}
else:
- quality = {"sd": 18, "hd": 22, "fullhd": 37, "240p": 5, "360p": 18,
- "480p": 35, "720p": 22, "1080p": 37, "3072p": 38}
+ quality = {'sd': 18, 'hd': 22, 'fullhd': 37, '240p': 5, '360p': 18,
+ '480p': 35, '720p': 22, '1080p': 37, '3072p': 38}
- desired_fmt = self.getConfig('fmt')
+ desired_fmt = self.get_config('fmt')
if not desired_fmt:
- desired_fmt = quality.get(self.getConfig('quality'), 18)
+ desired_fmt = quality.get(self.get_config('quality'), 18)
elif desired_fmt not in self.formats:
- self.logWarning(_("FMT %d unknown, using default") % desired_fmt)
+ self.log_warning(_("FMT %d unknown, using default") % desired_fmt)
desired_fmt = 0
- #parse available streams
+ #: Parse available streams
streams = re.search(r'"url_encoded_fmt_stream_map":"(.+?)",', html).group(1)
streams = [x.split('\u0026') for x in streams.split(',')]
streams = [dict((y.split('=', 1)) for y in x) for x in streams]
streams = [(int(x['itag']), urllib.unquote(x['url'])) for x in streams]
- # self.logDebug("Found links: %s" % streams)
+ # self.log_debug("Found links: %s" % streams)
- self.logDebug("AVAILABLE STREAMS: %s" % [x[0] for x in streams])
+ self.log_debug("AVAILABLE STREAMS: %s" % [x[0] for x in streams])
- #build dictionary of supported itags (3D/2D)
- allowed = lambda x: self.getConfig(self.formats[x][0])
+ #: Build dictionary of supported itags (3D/2D)
+ allowed = lambda x: self.get_config(self.formats[x][0])
streams = [x for x in streams if x[0] in self.formats and allowed(x[0])]
if not streams:
self.fail(_("No available stream meets your preferences"))
- fmt_dict = dict([x for x in streams if self.formats[x[0]][4] == use3d] or streams)
+ fmt_dict = dict([x for x in streams if self.formats[x[0]][4] is use3d] or streams)
- self.logDebug("DESIRED STREAM: ITAG:%d (%s) %sfound, %sallowed" %
+ self.log_debug("DESIRED STREAM: ITAG:%d (%s) %sfound, %sallowed" %
(desired_fmt, "%s %dx%d Q:%d 3D:%s" % self.formats[desired_fmt],
"" if desired_fmt in fmt_dict else "NOT ", "" if allowed(desired_fmt) else "NOT "))
- #return fmt nearest to quality index
+ #: Return fmt nearest to quality index
if desired_fmt in fmt_dict and allowed(desired_fmt):
fmt = desired_fmt
else:
- sel = lambda x: self.formats[x][3] # select quality index
+ sel = lambda x: self.formats[x][3] #: Select quality index
comp = lambda x, y: abs(sel(x) - sel(y))
- self.logDebug("Choosing nearest fmt: %s" % [(x, allowed(x), comp(x, desired_fmt)) for x in fmt_dict.keys()])
+ self.log_debug("Choosing nearest fmt: %s" % [(x, allowed(x), comp(x, desired_fmt)) for x in fmt_dict.keys()])
fmt = reduce(lambda x, y: x if comp(x, desired_fmt) <= comp(y, desired_fmt) and
sel(x) > sel(y) else y, fmt_dict.keys())
- self.logDebug("Chosen fmt: %s" % fmt)
+ self.log_debug("Chosen fmt: %s" % fmt)
url = fmt_dict[fmt]
- self.logDebug("URL: %s" % url)
+ self.log_debug("URL: %s" % url)
- #set file name
+ #: Set file name
file_suffix = self.formats[fmt][0] if fmt in self.formats else ".flv"
file_name_pattern = '<meta name="title" content="(.+?)">'
name = re.search(file_name_pattern, html).group(1).replace("/", "")
- # Cleaning invalid characters from the file name
+ #: Cleaning invalid characters from the file name
name = name.encode('ascii', 'replace')
- for c in self.invalidChars:
+ for c in self.invalid_chars:
name = name.replace(c, '_')
pyfile.name = html_unescape(name)
diff --git a/module/plugins/hoster/ZDF.py b/module/plugins/hoster/ZDF.py
index 8d3de5b26..f0b85d11a 100644
--- a/module/plugins/hoster/ZDF.py
+++ b/module/plugins/hoster/ZDF.py
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
import re
+import xml.etree.ElementTree as etree
-from xml.etree.ElementTree import fromstring
-
-from module.plugins.Hoster import Hoster
+from module.plugins.internal.Hoster import Hoster
# Based on zdfm by Roland Beermann (http://github.com/enkore/zdfm/)
class ZDF(Hoster):
__name__ = "ZDF Mediathek"
__type__ = "hoster"
- __version__ = "0.80"
+ __version__ = "0.84"
+ __status__ = "testing"
__pattern__ = r'http://(?:www\.)?zdf\.de/ZDFmediathek/\D*(\d+)\D*'
@@ -42,7 +42,7 @@ class ZDF(Hoster):
def process(self, pyfile):
- xml = fromstring(self.load(self.XML_API % self.get_id(pyfile.url)))
+ xml = etree.fromstring(self.load(self.XML_API % self.get_id(pyfile.url), decode=False))
status = xml.findtext("./status/statuscode")
if status != "ok":
@@ -51,7 +51,7 @@ class ZDF(Hoster):
video = xml.find("video")
title = video.findtext("information/title")
- pyfile.name = title
+ pyfile.name = title.encode("Latin-1")
target_url = sorted((v for v in video.iter("formitaet") if self.video_valid(v)),
key=self.video_key)[-1].findtext("url")
diff --git a/module/plugins/hoster/ZShareNet.py b/module/plugins/hoster/ZShareNet.py
index 6e4508a18..b5dd66769 100644
--- a/module/plugins/hoster/ZShareNet.py
+++ b/module/plugins/hoster/ZShareNet.py
@@ -6,7 +6,8 @@ from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo
class ZShareNet(DeadHoster):
__name__ = "ZShareNet"
__type__ = "hoster"
- __version__ = "0.21"
+ __version__ = "0.22"
+ __status__ = "testing"
__pattern__ = r'https?://(?:ww[2w]\.)?zshares?\.net/.+'
__config__ = [] #@TODO: Remove in 0.4.10
diff --git a/module/plugins/hoster/ZahikiNet.py b/module/plugins/hoster/ZahikiNet.py
new file mode 100644
index 000000000..f9ea995ba
--- /dev/null
+++ b/module/plugins/hoster/ZahikiNet.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
+
+
+class ZahikiNet(SimpleHoster):
+ __name__ = "ZahikiNet"
+ __type__ = "hoster"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'https?://(?:www\.)?zahiki\.net/\w+/.+'
+
+ __description__ = """Zahiki.net hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ DIRECT_LINK = True
+
+ NAME_PATTERN = r'/(?P<N>.+?) </title>'
+ OFFLINE_PATTERN = r'>(Not Found|Il file selezionato non esiste)'
+
+ LINK_FREE_PATTERN = r'file: "(.+?)"'
+
+
+ def setup(self):
+ self.resume_download = True
+ self.multiDL = True
+ self.limitDL = 6
+
+
+getInfo = create_getInfo(ZahikiNet)
diff --git a/module/plugins/hoster/ZeveraCom.py b/module/plugins/hoster/ZeveraCom.py
index 617e00e58..ff3a43e6d 100644
--- a/module/plugins/hoster/ZeveraCom.py
+++ b/module/plugins/hoster/ZeveraCom.py
@@ -9,10 +9,12 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo
class ZeveraCom(MultiHoster):
__name__ = "ZeveraCom"
__type__ = "hoster"
- __version__ = "0.29"
+ __version__ = "0.32"
+ __status__ = "testing"
__pattern__ = r'https?://(?:www\.)zevera\.com/(getFiles\.ashx|Members/download\.ashx)\?.*ourl=.+'
- __config__ = [("use_premium", "bool", "Use premium account if available", True)]
+ __config__ = [("use_premium" , "bool", "Use premium account if available" , True),
+ ("revertfailed", "bool", "Revert to standard download if fails", True)]
__description__ = """Zevera.com multi-hoster plugin"""
__license__ = "GPLv3"
@@ -20,15 +22,11 @@ class ZeveraCom(MultiHoster):
("Walter Purcaro", "vuolter@gmail.com")]
- def handlePremium(self, pyfile):
- self.link = "https://%s/getFiles.ashx?ourl=%s" % (self.account.HOSTER_DOMAIN, pyfile.url)
-
+ FILE_ERRORS = [("Error", r'action="ErrorDownload.aspx')]
- def checkFile(self, rules={}):
- if self.checkDownload({"error": 'action="ErrorDownload.aspx'}):
- self.fail(_("Error response received"))
- return super(ZeveraCom, self).checkFile(rules)
+ def handle_premium(self, pyfile):
+ self.link = "https://%s/getFiles.ashx?ourl=%s" % (self.account.HOSTER_DOMAIN, pyfile.url)
getInfo = create_getInfo(ZeveraCom)
diff --git a/module/plugins/hoster/ZippyshareCom.py b/module/plugins/hoster/ZippyshareCom.py
index d776e5928..1b29948ce 100644
--- a/module/plugins/hoster/ZippyshareCom.py
+++ b/module/plugins/hoster/ZippyshareCom.py
@@ -3,18 +3,19 @@
import re
import urllib
-from BeautifulSoup import BeautifulSoup
+import BeautifulSoup
-from module.plugins.internal.ReCaptcha import ReCaptcha
+from module.plugins.captcha.ReCaptcha import ReCaptcha
from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class ZippyshareCom(SimpleHoster):
__name__ = "ZippyshareCom"
__type__ = "hoster"
- __version__ = "0.79"
+ __version__ = "0.82"
+ __status__ = "testing"
- __pattern__ = r'http://www\d{0,2}\.zippyshare\.com/v(/|iew\.jsp.*key=)(?P<KEY>[\w^_]+)'
+ __pattern__ = r'http://www\d{0,3}\.zippyshare\.com/v(/|iew\.jsp.*key=)(?P<KEY>[\w^_]+)'
__config__ = [("use_premium", "bool", "Use premium account if available", True)]
__description__ = """Zippyshare.com hoster plugin"""
@@ -33,12 +34,12 @@ class ZippyshareCom(SimpleHoster):
def setup(self):
- self.chunkLimit = -1
+ self.chunk_limit = -1
self.multiDL = True
- self.resumeDownload = True
+ self.resume_download = True
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
recaptcha = ReCaptcha(self)
captcha_key = recaptcha.detect_key()
@@ -53,41 +54,41 @@ class ZippyshareCom(SimpleHoster):
else:
self.link = self.get_link()
- if self.link and pyfile.name == 'file.html':
+ if self.link and pyfile.name == "file.html":
pyfile.name = urllib.unquote(self.link.split('/')[-1])
def get_link(self):
- # get all the scripts inside the html body
- soup = BeautifulSoup(self.html)
+ #: Get all the scripts inside the html body
+ soup = BeautifulSoup.BeautifulSoup(self.html)
scripts = (s.getText().strip() for s in soup.body.findAll('script', type='text/javascript'))
- # meant to be populated with the initialization of all the DOM elements found in the scripts
+ #: Meant to be populated with the initialization of all the DOM elements found in the scripts
initScripts = set()
- def replElementById(element):
- id = element.group(1) # id might be either 'x' (a real id) or x (a variable)
- attr = element.group(4) # attr might be None
+ def repl_element_by_id(element):
+ id = element.group(1) #: Id might be either 'x' (a real id) or x (a variable)
+ attr = element.group(4) #: Attr might be None
varName = re.sub(r'-', '', 'GVAR[%s+"_%s"]' %(id, attr))
realid = id.strip('"\'')
- if id != realid: #id is not a variable, so look for realid.attr in the html
+ if id is not realid: #: Id is not a variable, so look for realid.attr in the html
initValues = filter(None, [elt.get(attr, None) for elt in soup.findAll(id=realid)])
initValue = '"%s"' % initValues[-1] if initValues else 'null'
initScripts.add('%s = %s;' % (varName, initValue))
return varName
- # handle all getElementById
+ #: Handle all getElementById
reVar = r'document.getElementById\(([\'"\w-]+)\)(\.)?(getAttribute\([\'"])?(\w+)?([\'"]\))?'
- scripts = [re.sub(reVar, replElementById, script) for script in scripts if script]
+ scripts = [re.sub(reVar, repl_element_by_id, script) for script in scripts if script]
- # add try/catch in JS to handle deliberate errors
+ #: Add try/catch in JS to handle deliberate errors
scripts = ['\n'.join(('try{', script, '} catch(err){}')) for script in scripts]
- # get the file's url by evaluating all the scripts
- scripts = ['var GVAR = {}'] + list(initScripts) + scripts + ['GVAR["dlbutton_href"]']
+ #: Get the file's url by evaluating all the scripts
+ scripts = ["var GVAR = {}"] + list(initScripts) + scripts + ['GVAR["dlbutton_href"]']
return self.js.eval('\n'.join(scripts))
diff --git a/module/plugins/internal/Account.py b/module/plugins/internal/Account.py
new file mode 100644
index 000000000..2713e8da4
--- /dev/null
+++ b/module/plugins/internal/Account.py
@@ -0,0 +1,397 @@
+# -*- coding: utf-8 -*-
+
+import copy
+import random
+import time
+import threading
+import traceback
+
+from module.plugins.internal.Plugin import Plugin
+from module.utils import compare_time, lock, parseFileSize as parse_size
+
+
+class Account(Plugin):
+ __name__ = "Account"
+ __type__ = "account"
+ __version__ = "0.17"
+ __status__ = "testing"
+
+ __description__ = """Base account plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ LOGIN_TIMEOUT = 10 * 60 #: After that time (in minutes) pyload will relogin the account
+ INFO_THRESHOLD = 30 * 60 #: After that time (in minutes) account data will be reloaded
+
+
+ def __init__(self, manager, accounts):
+ self._init(manager.core)
+
+ self.lock = threading.RLock()
+ self.accounts = accounts #@TODO: Remove in 0.4.10
+
+ self.init()
+ self.init_accounts(accounts)
+
+
+ def init(self):
+ """
+ Initialize additional data structures
+ """
+ pass
+
+
+ def login(self, user, password, data, req):
+ """
+ Login into account, the cookies will be saved so user can be recognized
+ """
+ pass
+
+
+ @lock
+ def _login(self, user):
+ try:
+ info = self.info[user]
+ info['login']['timestamp'] = time.time() #: Set timestamp for login
+
+ self.req = self.get_request(user)
+ self.login(user, info['login']['password'], info['data'], self.req)
+
+ except Exception, e:
+ self.log_warning(_("Could not login user `%s`") % user, e)
+ res = info['login']['valid'] = False
+ self.accounts[user]['valid'] = False #@TODO: Remove in 0.4.10
+
+ if self.pyload.debug:
+ traceback.print_exc()
+
+ else:
+ res = info['login']['valid'] = True
+ self.accounts[user]['valid'] = True #@TODO: Remove in 0.4.10
+
+ finally:
+ self.clean()
+ return res
+
+
+ def relogin(self, user):
+ self.log_info(_("Relogin user `%s`...") % user)
+
+ req = self.get_request(user)
+ if req:
+ req.clearCookies()
+ self.clean()
+
+ return self._login(user)
+
+
+ #@TODO: Rewrite in 0.4.10
+ def init_accounts(self, accounts):
+ for user, data in accounts.items():
+ self.add(user, data['password'], data['options'])
+
+
+ @lock
+ def add(self, user, password=None, options={}):
+ if user not in self.info:
+ self.info[user] = {'login': {'valid' : None,
+ 'password' : password or "",
+ 'timestamp': 0},
+ 'data' : {'options' : options,
+ 'premium' : None,
+ 'validuntil' : None,
+ 'trafficleft': None,
+ 'maxtraffic' : None}}
+
+ #@TODO: Remove in 0.4.10
+ self.accounts[user] = self.info[user]['data']
+ self.accounts[user].update({'login' : user,
+ 'type' : self.__name__,
+ 'valid' : self.info[user]['login']['valid'],
+ 'password': self.info[user]['login']['password']})
+
+ self.log_info(_("Login user `%s`...") % user)
+ self._login(user)
+ return True
+
+ else:
+ self.log_error(_("Error adding user `%s`") % user, _("User already exists"))
+
+
+ @lock
+ def update(self, user, password=None, options={}):
+ """
+ Updates account and return true if anything changed
+ """
+ if not (password or options):
+ return
+
+ if user not in self.info:
+ return self.add(user, password, options)
+
+ else:
+ if password:
+ self.info[user]['login']['password'] = password
+ self.accounts[user]['password'] = password #@TODO: Remove in 0.4.10
+ self.relogin(user)
+
+ if options:
+ before = self.info[user]['data']['options']
+ self.info[user]['data']['options'].update(options)
+ return self.info[user]['data']['options'] != before
+
+ return True
+
+
+ #: Deprecated method, use `update` instead (Remove in 0.4.10)
+ def updateAccounts(self, *args, **kwargs):
+ return self.update(*args, **kwargs)
+
+
+ def remove(self, user=None): # -> def remove
+ if not user:
+ self.info.clear()
+ self.accounts.clear() #@TODO: Remove in 0.4.10
+
+ elif user in self.info:
+ self.info.pop(user, None)
+ self.accounts.pop(user, None) #@TODO: Remove in 0.4.10
+
+
+ #: Deprecated method, use `remove` instead (Remove in 0.4.10)
+ def removeAccount(self, *args, **kwargs):
+ return self.remove(*args, **kwargs)
+
+
+ #@NOTE: Remove in 0.4.10?
+ def get_data(self, user, reload=False):
+ if not user:
+ return
+
+ info = self.get_info(user, reload)
+ if info and 'data' in info:
+ return info['data']
+
+
+ #: Deprecated method, use `get_data` instead (Remove in 0.4.10)
+ def getAccountData(self, *args, **kwargs):
+ if 'force' in kwargs:
+ kwargs['reload'] = kwargs['force']
+ kwargs.pop('force', None)
+
+ data = self.get_data(*args, **kwargs) or {}
+ if 'options' not in data:
+ data['options'] = {'limitdl': ['0']}
+
+ return data
+
+
+ def get_info(self, user, reload=False):
+ """
+ Retrieve account infos for an user, do **not** overwrite this method!\\
+ just use it to retrieve infos in hoster plugins. see `parse_info`
+
+ :param user: username
+ :param reload: reloads cached account information
+ :return: dictionary with information
+ """
+ if user not in self.info:
+ self.log_error(_("User `%s` not found while retrieving account info") % user)
+ return
+
+ elif reload:
+ self.log_info(_("Parsing account info for user `%s`...") % user)
+ info = self._parse_info(user)
+
+ safe_info = copy.deepcopy(info)
+ safe_info['login']['password'] = "**********"
+ safe_info['data']['password'] = "**********" #@TODO: Remove in 0.4.10
+ self.log_debug("Account info for user `%s`: %s" % (user, safe_info))
+
+ elif self.INFO_THRESHOLD > 0 and self.info[user]['login']['timestamp'] + self.INFO_THRESHOLD < time.time():
+ self.log_debug("Reached data timeout for %s" % user)
+ info = self.get_info(user, True)
+
+ else:
+ info = self.info[user]
+
+ return info
+
+
+ def is_premium(self, user):
+ if not user:
+ return False
+
+ info = self.get_info(user)
+ return info['data']['premium']
+
+
+ def _parse_info(self, user):
+ info = self.info[user]
+
+ if not info['login']['valid']:
+ return info
+
+ try:
+ self.req = self.get_request(user)
+ extra_info = self.parse_info(user, info['login']['password'], info, self.req)
+
+ if extra_info and isinstance(extra_info, dict):
+ info['data'].update(extra_info)
+
+ except (Fail, Exception), e:
+ self.log_warning(_("Error loading info for user `%s`") % user, e)
+
+ if self.pyload.debug:
+ traceback.print_exc()
+
+ finally:
+ self.clean()
+
+ self.info[user].update(info)
+ return info
+
+
+ def parse_info(self, user, password, info, req):
+ """
+ This should be overwritten in account plugin
+ and retrieving account information for user
+
+ :param user:
+ :param req: `Request` instance
+ :return:
+ """
+ pass
+
+
+ #: Remove in 0.4.10
+ def getAllAccounts(self, *args, **kwargs):
+ return [self.getAccountData(user, *args, **kwargs) for user, info in self.info.items()]
+
+
+ def login_fail(self, reason=_("Login handshake has failed")):
+ return self.fail(reason)
+
+
+ def get_request(self, user=None):
+ if not user:
+ user, info = self.select()
+
+ return self.pyload.requestFactory.getRequest(self.__name__, user)
+
+
+ def get_cookies(self, user=None):
+ if not user:
+ user, info = self.select()
+
+ return self.pyload.requestFactory.getCookieJar(self.__name__, user)
+
+
+ def select(self):
+ """
+ Returns a valid account name and info
+ """
+ free_accounts = {}
+ premium_accounts = {}
+
+ for user, info in self.info.items():
+ if not info['login']['valid']:
+ continue
+
+ data = info['data']
+
+ if "time" in data['options'] and data['options']['time']:
+ time_data = ""
+ try:
+ time_data = data['options']['time'][0]
+ start, end = time_data.split("-")
+
+ if not compare_time(start.split(":"), end.split(":")):
+ continue
+
+ except Exception:
+ self.log_warning(_("Wrong time format `%s` for account `%s`, use 1:22-3:44") % (user, time_data))
+
+ if data['trafficleft'] == 0:
+ continue
+
+ if time.time() > data['validuntil'] > 0:
+ continue
+
+ if data['premium']:
+ premium_accounts[user] = info
+
+ else:
+ free_accounts[user] = info
+
+ account_list = (premium_accounts or free_accounts).items()
+
+ if not account_list:
+ return None, None
+
+ validuntil_list = [(user, info) for user, info in account_list if info['data']['validuntil']]
+
+ if not validuntil_list:
+ return random.choice(account_list) #@TODO: Random account?! Recheck in 0.4.10
+
+ return sorted(validuntil_list,
+ key=lambda a: a[1]['data']['validuntil'],
+ reverse=True)[0]
+
+
+ def parse_traffic(self, value, unit=None): #: Return kilobytes
+ if not unit and not isinstance(value, basestring):
+ unit = "KB"
+
+ return parse_size(value, unit)
+
+
+ def empty(self, user):
+ if user not in self.info:
+ return
+
+ self.log_warning(_("Account `%s` has not enough traffic") % user, _("Checking again in 30 minutes"))
+
+ self.info[user]['data']['trafficleft'] = 0
+ self.schedule_refresh(user, 30 * 60)
+
+
+ def expired(self, user):
+ if user not in self.info:
+ return
+
+ self.log_warning(_("Account `%s` is expired") % user, _("Checking again in 60 minutes"))
+
+ self.info[user]['data']['validuntil'] = time.time() - 1
+ self.schedule_refresh(user, 60 * 60)
+
+
+ def schedule_refresh(self, user, time=0):
+ """
+ Add task to refresh account info to sheduler
+ """
+ self.log_debug("Scheduled refresh for user `%s` in %s seconds" % (user, time))
+ self.pyload.scheduler.addJob(time, self.get_info, [user, True])
+
+
+ #: Deprecated method, use `schedule_refresh` instead (Remove in 0.4.10)
+ def scheduleRefresh(self, *args, **kwargs):
+ if 'force' in kwargs:
+ kwargs.pop('force', None) #@TODO: Recheck in 0.4.10
+ return self.schedule_refresh(*args, **kwargs)
+
+
+ @lock
+ def is_logged(self, user, relogin=False):
+ """
+ Checks if user is still logged in
+ """
+ if user in self.info:
+ if self.LOGIN_TIMEOUT > 0 and self.info[user]['login']['timestamp'] + self.LOGIN_TIMEOUT < time.time():
+ self.log_debug("Reached login timeout for %s" % user)
+ return self.relogin(user) if relogin else False
+ else:
+ return True
+ else:
+ return False
diff --git a/module/plugins/internal/Addon.py b/module/plugins/internal/Addon.py
new file mode 100644
index 000000000..45ca98eac
--- /dev/null
+++ b/module/plugins/internal/Addon.py
@@ -0,0 +1,245 @@
+# -*- coding: utf-8 -*-
+
+import traceback
+
+from module.plugins.internal.Plugin import Plugin
+
+
+class Expose(object):
+ """
+ Used for decoration to declare rpc services
+ """
+ def __new__(cls, f, *args, **kwargs):
+ hookManager.addRPC(f.__module__, f.func_name, f.func_doc)
+ return f
+
+
+def threaded(fn):
+
+ def run(*args, **kwargs):
+ hookManager.startThread(fn, *args, **kwargs)
+
+ return run
+
+
+class Addon(Plugin):
+ __name__ = "Addon"
+ __type__ = "hook" #@TODO: Change to `addon` in 0.4.10
+ __version__ = "0.04"
+ __status__ = "testing"
+
+ __config__ = [] #: [("name", "type", "desc", "default")]
+ __threaded__ = [] #@TODO: Remove in 0.4.10
+
+ __description__ = """Base addon plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def __init__(self, core, manager):
+ self._init(core)
+
+ #: `HookManager`
+ self.manager = manager
+
+ #: Automatically register event listeners for functions, attribute will be deleted dont use it yourself
+ self.event_map = {}
+
+ #: Deprecated alternative to event_map
+ #: List of events the plugin can handle, name the functions exactly like eventname.
+ self.event_list = [] #@NOTE: dont make duplicate entries in event_map
+
+ #: Callback of periodical job task, used by HookManager
+ self.cb = None
+ self.interval = 60
+
+ self.init()
+ self.init_events()
+
+
+ def init_events(self):
+ if self.event_map:
+ for event, funcs in self.event_map.items():
+ if type(funcs) in (list, tuple):
+ for f in funcs:
+ self.manager.addEvent(event, getattr(self, f))
+ else:
+ self.manager.addEvent(event, getattr(self, funcs))
+
+ #: Delete for various reasons
+ self.event_map = None
+
+ if self.event_list:
+ self.log_debug("Deprecated method `event_list`, use `event_map` instead")
+
+ for f in self.event_list:
+ self.manager.addEvent(f, getattr(self, f))
+
+ self.event_list = None
+
+
+ def init_periodical(self, delay=0, threaded=False):
+ self.cb = self.pyload.scheduler.addJob(max(0, delay), self._periodical, [threaded], threaded=threaded)
+
+
+ #: Deprecated method, use `init_periodical` instead (Remove in 0.4.10)
+ def initPeriodical(self, *args, **kwargs):
+ return self.init_periodical(*args, **kwargs)
+
+
+ def _periodical(self, threaded):
+ if self.interval < 0:
+ self.cb = None
+ return
+
+ try:
+ self.periodical()
+
+ except Exception, e:
+ self.log_error(_("Error executing periodical task: %s") % e)
+ if self.pyload.debug:
+ traceback.print_exc()
+
+ self.cb = self.pyload.scheduler.addJob(self.interval, self._periodical, [threaded], threaded=threaded)
+
+
+ def periodical(self):
+ pass
+
+
+ def __repr__(self):
+ return "<Addon %s>" % self.__name__
+
+
+ def is_activated(self):
+ """
+ Checks if addon is activated
+ """
+ return self.get_config("activated")
+
+
+ #: Deprecated method, use `is_activated` instead (Remove in 0.4.10)
+ def isActivated(self, *args, **kwargs):
+ return self.is_activated(*args, **kwargs)
+
+
+ def deactivate(self):
+ """
+ Called when addon was deactivated
+ """
+ pass
+
+
+ #: Deprecated method, use `deactivate` instead (Remove in 0.4.10)
+ def unload(self, *args, **kwargs):
+ return self.deactivate(*args, **kwargs)
+
+
+ def activate(self):
+ """
+ Called when addon was activated
+ """
+ pass
+
+
+ #: Deprecated method, use `activate` instead (Remove in 0.4.10)
+ def coreReady(self, *args, **kwargs):
+ return self.activate(*args, **kwargs)
+
+
+ def exit(self):
+ """
+ Called by core.shutdown just before pyLoad exit
+ """
+ pass
+
+
+ #: Deprecated method, use `exit` instead (Remove in 0.4.10)
+ def coreExiting(self, *args, **kwargs):
+ self.unload(*args, **kwargs) #@TODO: Fix in 0.4.10
+ return self.exit(*args, **kwargs)
+
+
+ def download_preparing(self, pyfile):
+ pass
+
+
+ #: Deprecated method, use `download_preparing` instead (Remove in 0.4.10)
+ def downloadPreparing(self, pyfile):
+ if pyfile.plugin.req is not None: #@TODO: Remove in 0.4.10
+ return self.download_preparing(pyfile)
+
+
+ def download_finished(self, pyfile):
+ pass
+
+
+ #: Deprecated method, use `download_finished` instead (Remove in 0.4.10)
+ def downloadFinished(self, *args, **kwargs):
+ return self.download_finished(*args, **kwargs)
+
+
+ def download_failed(self, pyfile):
+ pass
+
+
+ #: Deprecated method, use `download_failed` instead (Remove in 0.4.10)
+ def downloadFailed(self, *args, **kwargs):
+ return self.download_failed(*args, **kwargs)
+
+
+ def package_finished(self, pypack):
+ pass
+
+
+ #: Deprecated method, use `package_finished` instead (Remove in 0.4.10)
+ def packageFinished(self, *args, **kwargs):
+ return self.package_finished(*args, **kwargs)
+
+
+ def before_reconnect(self, ip):
+ pass
+
+
+ #: Deprecated method, use `before_reconnect` instead (Remove in 0.4.10)
+ def beforeReconnecting(self, *args, **kwargs):
+ return self.before_reconnect(*args, **kwargs)
+
+
+ def after_reconnect(self, ip, oldip):
+ pass
+
+
+ #: Deprecated method, use `after_reconnect` instead (Remove in 0.4.10)
+ def afterReconnecting(self, ip):
+ return self.after_reconnect(ip, None)
+
+
+ def captcha_task(self, task):
+ """
+ New captcha task for the plugin, it MUST set the handler and timeout or will be ignored
+ """
+ pass
+
+
+ #: Deprecated method, use `captcha_task` instead (Remove in 0.4.10)
+ def newCaptchaTask(self, *args, **kwargs):
+ return self.captcha_task(*args, **kwargs)
+
+
+ def captcha_correct(self, task):
+ pass
+
+
+ #: Deprecated method, use `captcha_correct` instead (Remove in 0.4.10)
+ def captchaCorrect(self, *args, **kwargs):
+ return self.captcha_correct(*args, **kwargs)
+
+
+ def captcha_invalid(self, task):
+ pass
+
+
+ #: Deprecated method, use `captcha_invalid` instead (Remove in 0.4.10)
+ def captchaInvalid(self, *args, **kwargs):
+ return self.captcha_invalid(*args, **kwargs)
diff --git a/module/plugins/internal/Captcha.py b/module/plugins/internal/Captcha.py
index b4af46493..c08050ee8 100644
--- a/module/plugins/internal/Captcha.py
+++ b/module/plugins/internal/Captcha.py
@@ -1,56 +1,141 @@
# -*- coding: utf-8 -*-
-from module.plugins.Plugin import Base
+from __future__ import with_statement
+import os
+import time
+import traceback
-#@TODO: Extend (new) Plugin class; remove all `html` args
-class Captcha(Base):
+from module.plugins.internal.Plugin import Plugin
+
+
+class Captcha(Plugin):
__name__ = "Captcha"
__type__ = "captcha"
- __version__ = "0.29"
+ __version__ = "0.42"
+ __status__ = "testing"
- __description__ = """Base captcha service plugin"""
+ __description__ = """Base anti-captcha plugin"""
__license__ = "GPLv3"
- __authors__ = [("pyLoad Team", "admin@pyload.org")]
-
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- key = None #: last key detected
+ def __init__(self, plugin): #@TODO: Pass pyfile instead plugin, so store plugin's html in its associated pyfile as data
+ self._init(plugin.pyload)
- def __init__(self, plugin):
self.plugin = plugin
- super(Captcha, self).__init__(plugin.core)
+ self.task = None #: captchaManager task
+
+ self.init()
+
+
+ def init(self):
+ """
+ Initialize additional data structures
+ """
+ pass
+
+
+ def _log(self, level, plugintype, pluginname, messages):
+ return self.plugin._log(level,
+ plugintype,
+ self.plugin.__name__,
+ (self.__name__,) + messages)
+
+
+ def recognize(self, image):
+ """
+ Extend to build your custom anti-captcha ocr
+ """
+ pass
+
+
+ def decrypt(self, url, get={}, post={}, ref=False, cookies=False, decode=False,
+ input_type='jpg', output_type='textual', ocr=True, timeout=120):
+ img = self.load(url, get=get, post=post, ref=ref, cookies=cookies, decode=decode)
+ return self._decrypt(img, input_type, output_type, ocr, timeout)
+
+
+ #@TODO: Definitely choose a better name for this method!
+ def _decrypt(self, raw, input_type='jpg', output_type='textual', ocr=False, timeout=120):
+ """
+ Loads a captcha and decrypts it with ocr, plugin, user input
+
+ :param raw: image raw data
+ :param get: get part for request
+ :param post: post part for request
+ :param cookies: True if cookies should be enabled
+ :param input_type: Type of the Image
+ :param output_type: 'textual' if text is written on the captcha\
+ or 'positional' for captcha where the user have to click\
+ on a specific region on the captcha
+ :param ocr: if True, ocr is not used
+
+ :return: result of decrypting
+ """
+ result = ""
+ time_ref = ("%.2f" % time.time())[-6:].replace(".", "")
+
+ with open(os.path.join("tmp", "captcha_image_%s_%s.%s" % (self.plugin.__name__, time_ref, input_type)), "wb") as tmp_img:
+ tmp_img.write(raw)
+
+ if ocr:
+ if isinstance(ocr, basestring):
+ OCR = self.pyload.pluginManager.loadClass("captcha", ocr) #: Rename `captcha` to `ocr` in 0.4.10
+ result = OCR(self.plugin).recognize(tmp_img.name)
+ else:
+ result = self.recognize(tmp_img.name)
+
+ if not result:
+ captchaManager = self.pyload.captchaManager
+
+ try:
+ self.task = captchaManager.newTask(raw, input_type, tmp_img.name, output_type)
+
+ captchaManager.handleCaptcha(self.task)
+
+ self.task.setWaiting(max(timeout, 50)) #@TODO: Move to `CaptchaManager` in 0.4.10
+ while self.task.isWaiting():
+ if self.plugin.pyfile.abort:
+ self.plugin.abort()
+ time.sleep(1)
+
+ finally:
+ captchaManager.removeTask(self.task)
+
+ if self.task.error:
+ self.fail(self.task.error)
+ elif not self.task.result:
+ self.invalid()
+ self.plugin.retry(reason=_("No captcha result obtained in appropiate time"))
- #@TODO: Recheck in 0.4.10
- def fail(self, reason):
- self.plugin.fail(reason)
- raise AttributeError(reason)
+ result = self.task.result
+ if not self.pyload.debug:
+ try:
+ os.remove(tmp_img.name)
- #@TODO: Recheck in 0.4.10
- def retrieve_key(self, html):
- if self.detect_key(html):
- return self.key
- else:
- self.fail(_("%s key not found") % self.__name__)
+ except OSError, e:
+ self.log_warning(_("Error removing: %s") % tmp_img.name, e)
+ traceback.print_exc()
+ self.log_info(_("Captcha result: ") + result) #@TODO: Remove from here?
- #@TODO: Recheck in 0.4.10
- def retrieve_html(self):
- if hasattr(self.plugin, "html") and self.plugin.html:
- return self.plugin.html
- else:
- self.fail(_("%s html not found") % self.__name__)
+ return result
- def detect_key(self, html=None):
- raise NotImplementedError
+ def invalid(self):
+ if not self.task:
+ return
+ self.log_error(_("Invalid captcha"))
+ self.task.invalid()
- def challenge(self, key=None, html=None):
- raise NotImplementedError
+ def correct(self):
+ if not self.task:
+ return
- def result(self, server, challenge):
- raise NotImplementedError
+ self.log_info(_("Correct captcha"))
+ self.task.correct()
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py
new file mode 100644
index 000000000..20dc60427
--- /dev/null
+++ b/module/plugins/internal/CaptchaService.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.Captcha import Captcha
+
+
+class CaptchaService(Captcha):
+ __name__ = "CaptchaService"
+ __type__ = "captcha"
+ __version__ = "0.32"
+ __status__ = "testing"
+
+ __description__ = """Base anti-captcha service plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def init(self):
+ self.key = None #: Last key detected
+
+
+ #@TODO: Recheck in 0.4.10
+ def retrieve_key(self, data):
+ if self.detect_key(data):
+ return self.key
+ else:
+ self.fail(_("%s key not found") % self.__name__)
+
+
+ #@TODO: Recheck in 0.4.10, html is now pyfile.data
+ def retrieve_data(self):
+ if hasattr(self.plugin, "html") and self.plugin.html:
+ return self.plugin.html
+ else:
+ self.fail(_("%s data not found") % self.__name__)
+
+
+ def detect_key(self, data=None):
+ raise NotImplementedError
+
+
+ def challenge(self, key=None, data=None):
+ raise NotImplementedError
+
+
+ def result(self, server, challenge):
+ raise NotImplementedError
diff --git a/module/plugins/internal/Container.py b/module/plugins/internal/Container.py
new file mode 100644
index 000000000..729592a0d
--- /dev/null
+++ b/module/plugins/internal/Container.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import os
+import re
+import traceback
+
+from module.plugins.internal.Crypter import Crypter
+from module.plugins.internal.Plugin import exists
+from module.utils import save_join as fs_join
+
+
+class Container(Crypter):
+ __name__ = "Container"
+ __type__ = "container"
+ __version__ = "0.06"
+ __status__ = "testing"
+
+ __pattern__ = r'^unmatchable$'
+ __config__ = [] #: [("name", "type", "desc", "default")]
+
+ __description__ = """Base container decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("mkaay", "mkaay@mkaay.de")]
+
+
+ def process(self, pyfile):
+ """
+ Main method
+ """
+ self._load2disk()
+
+ self.decrypt(pyfile)
+
+ self.delete_tmp()
+
+ if self.urls:
+ self._generate_packages()
+
+ elif not self.packages:
+ self.error(_("No link grabbed"), "decrypt")
+
+ self._create_packages()
+
+
+ #: Deprecated method, use `_load2disk` instead (Remove in 0.4.10)
+ def loadToDisk(self, *args, **kwargs):
+ return self._load2disk(*args, **kwargs)
+
+
+ def _load2disk(self):
+ """
+ Loads container to disk if its stored remotely and overwrite url,
+ or check existent on several places at disk
+ """
+ if self.pyfile.url.startswith("http"):
+ self.pyfile.name = re.findall("([^\/=]+)", self.pyfile.url)[-1]
+ content = self.load(self.pyfile.url)
+ self.pyfile.url = fs_join(self.pyload.config.get("general", "download_folder"), self.pyfile.name)
+ try:
+ with open(self.pyfile.url, "wb") as f:
+ f.write(content)
+
+ except IOError, e:
+ self.fail(str(e)) #@TODO: Remove `str` in 0.4.10
+
+ else:
+ self.pyfile.name = os.path.basename(self.pyfile.url)
+ if not exists(self.pyfile.url):
+ if exists(fs_join(pypath, self.pyfile.url)):
+ self.pyfile.url = fs_join(pypath, self.pyfile.url)
+ else:
+ self.fail(_("File not exists"))
+
+
+ #: Deprecated method, use `delete_tmp` instead (Remove in 0.4.10)
+ def deleteTmp(self, *args, **kwargs):
+ return self.delete_tmp(*args, **kwargs)
+
+
+ def delete_tmp(self):
+ if not self.pyfile.name.startswith("tmp_"):
+ return
+
+ try:
+ os.remove(self.pyfile.url)
+ except OSError, e:
+ self.log_warning(_("Error removing: %s") % self.pyfile.url, e)
+ if self.pyload.debug:
+ traceback.print_exc()
diff --git a/module/plugins/internal/Crypter.py b/module/plugins/internal/Crypter.py
new file mode 100644
index 000000000..d0e8eb1b4
--- /dev/null
+++ b/module/plugins/internal/Crypter.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+
+import urlparse
+
+from module.plugins.internal.Hoster import Hoster, _fixurl
+from module.utils import save_path as safe_filename
+
+
+class Crypter(Hoster):
+ __name__ = "Crypter"
+ __type__ = "crypter"
+ __version__ = "0.07"
+ __status__ = "testing"
+
+ __pattern__ = r'^unmatchable$'
+ __config__ = [("use_subfolder", "bool", "Save package to subfolder", True), #: Overrides pyload.config.get("general", "folder_per_package")
+ ("subfolder_per_package", "bool", "Create a subfolder for each package", True)]
+
+ __description__ = """Base decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ html = None #: Last html loaded #@TODO: Move to Hoster
+
+
+ def __init__(self, pyfile):
+ super(Crypter, self).__init__(pyfile)
+
+ #: Put all packages here. It's a list of tuples like: ( name, [list of links], folder )
+ self.packages = []
+
+ #: List of urls, pyLoad will generate packagenames
+ self.urls = []
+
+
+ def process(self, pyfile):
+ """
+ Main method
+ """
+ self.decrypt(pyfile)
+
+ if self.urls:
+ self._generate_packages()
+
+ elif not self.packages:
+ self.error(_("No link grabbed"), "decrypt")
+
+ self._create_packages()
+
+
+ def decrypt(self, pyfile):
+ raise NotImplementedError
+
+
+ def _generate_packages(self):
+ """
+ Generate new packages from self.urls
+ """
+ packages = [(name, links, None) for name, links in self.pyload.api.generatePackages(self.urls).items()]
+ self.packages.extend(packages)
+
+
+ def _create_packages(self):
+ """
+ Create new packages from self.packages
+ """
+ package_folder = self.pyfile.package().folder
+ package_password = self.pyfile.package().password
+ package_queue = self.pyfile.package().queue
+
+ folder_per_package = self.pyload.config.get("general", "folder_per_package")
+ use_subfolder = self.get_config('use_subfolder', folder_per_package)
+ subfolder_per_package = self.get_config('subfolder_per_package', True)
+
+ for name, links, folder in self.packages:
+ self.log_debug("Parsed package: %s" % name,
+ "%d links" % len(links),
+ "Saved to folder: %s" % folder if folder else "Saved to download folder")
+
+ pid = self.pyload.api.addPackage(name, map(self.fixurl, links), package_queue)
+
+ if package_password:
+ self.pyload.api.setPackageData(pid, {'password': package_password})
+
+ #: Workaround to do not break API addPackage method
+ set_folder = lambda x: self.pyload.api.setPackageData(pid, {'folder': x or ""})
+
+ if use_subfolder:
+ if not subfolder_per_package:
+ set_folder(package_folder)
+ self.log_debug("Set package %(name)s folder to: %(folder)s" % {'name': name, 'folder': folder})
+
+ elif not folder_per_package or name is not folder:
+ if not folder:
+ folder = urlparse.urlparse(_fixurl(name)).path.split("/")[-1]
+
+ set_folder(safe_filename(folder))
+ self.log_debug("Set package %(name)s folder to: %(folder)s" % {'name': name, 'folder': folder})
+
+ elif folder_per_package:
+ set_folder(None)
diff --git a/module/plugins/internal/DeadCrypter.py b/module/plugins/internal/DeadCrypter.py
index c93447164..e7cc6ff39 100644
--- a/module/plugins/internal/DeadCrypter.py
+++ b/module/plugins/internal/DeadCrypter.py
@@ -1,31 +1,30 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleCrypter import create_getInfo
-from module.plugins.Crypter import Crypter as _Crypter
+from module.plugins.internal.Crypter import Crypter, create_getInfo
-class DeadCrypter(_Crypter):
+class DeadCrypter(Crypter):
__name__ = "DeadCrypter"
__type__ = "crypter"
- __version__ = "0.05"
+ __version__ = "0.09"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
- __description__ = """ Crypter is no longer available """
+ __description__ = """Crypter is no longer available"""
__license__ = "GPLv3"
__authors__ = [("stickell", "l.stickell@yahoo.it")]
@classmethod
- def apiInfo(cls, url):
- api = super(DeadCrypter, cls).apiInfo(url)
- api['status'] = 1
- return api
+ def get_info(cls, *args, **kwargs):
+ info = super(DeadCrypter, cls).get_info(*args, **kwargs)
+ info['status'] = 1
+ return info
def setup(self):
- self.pyfile.error = "Crypter is no longer available"
- self.offline() #@TODO: self.offline("Crypter is no longer available")
+ self.offline(_("Crypter is no longer available"))
getInfo = create_getInfo(DeadCrypter)
diff --git a/module/plugins/internal/DeadHoster.py b/module/plugins/internal/DeadHoster.py
index f159ae5fa..250287d25 100644
--- a/module/plugins/internal/DeadHoster.py
+++ b/module/plugins/internal/DeadHoster.py
@@ -1,31 +1,30 @@
# -*- coding: utf-8 -*-
-from module.plugins.internal.SimpleHoster import create_getInfo
-from module.plugins.Hoster import Hoster as _Hoster
+from module.plugins.internal.Hoster import Hoster, create_getInfo
-class DeadHoster(_Hoster):
+class DeadHoster(Hoster):
__name__ = "DeadHoster"
__type__ = "hoster"
- __version__ = "0.15"
+ __version__ = "0.19"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
- __description__ = """ Hoster is no longer available """
+ __description__ = """Hoster is no longer available"""
__license__ = "GPLv3"
__authors__ = [("zoidberg", "zoidberg@mujmail.cz")]
@classmethod
- def apiInfo(cls, url):
- api = super(DeadHoster, cls).apiInfo(url)
- api['status'] = 1
- return api
+ def get_info(cls, *args, **kwargs):
+ info = super(DeadHoster, cls).get_info(*args, **kwargs)
+ info['status'] = 1
+ return info
def setup(self):
- self.pyfile.error = "Hoster is no longer available"
- self.offline() #@TODO: self.offline("Hoster is no longer available")
+ self.offline(_("Hoster is no longer available"))
getInfo = create_getInfo(DeadHoster)
diff --git a/module/plugins/internal/Extractor.py b/module/plugins/internal/Extractor.py
index 159b65ffe..7f5212090 100644
--- a/module/plugins/internal/Extractor.py
+++ b/module/plugins/internal/Extractor.py
@@ -4,6 +4,7 @@ import os
import re
from module.PyFile import PyFile
+from module.plugins.internal.Plugin import Plugin
class ArchiveError(Exception):
@@ -18,9 +19,11 @@ class PasswordError(Exception):
pass
-class Extractor:
+class Extractor(Plugin):
__name__ = "Extractor"
- __version__ = "0.24"
+ __type__ = "extractor"
+ __version__ = "0.33"
+ __status__ = "testing"
__description__ = """Base extractor plugin"""
__license__ = "GPLv3"
@@ -29,32 +32,34 @@ class Extractor:
EXTENSIONS = []
- VERSION = ""
REPAIR = False
+ VERSION = None
@classmethod
- def isArchive(cls, filename):
+ def is_archive(cls, filename):
name = os.path.basename(filename).lower()
return any(name.endswith(ext) for ext in cls.EXTENSIONS)
@classmethod
- def isMultipart(cls, filename):
+ def is_multipart(cls, filename):
return False
@classmethod
- def isUsable(cls):
- """ Check if system statisfy dependencies
+ def find(cls):
+ """
+ Check if system statisfy dependencies
:return: boolean
"""
- return None
+ pass
@classmethod
- def getTargets(cls, files_ids):
- """ Filter suited targets from list of filename id tuple list
+ def get_targets(cls, files_ids):
+ """
+ Filter suited targets from list of filename id tuple list
:param files_ids: List of filepathes
:return: List of targets, id tuple list
"""
@@ -62,15 +67,15 @@ class Extractor:
processed = []
for fname, id, fout in files_ids:
- if cls.isArchive(fname):
- pname = re.sub(cls.re_multipart, '', fname) if cls.isMultipart(fname) else os.path.splitext(fname)[0]
+ if cls.is_archive(fname):
+ pname = re.sub(cls.re_multipart, "", fname) if cls.is_multipart(fname) else os.path.splitext(fname)[0]
if pname not in processed:
processed.append(pname)
targets.append((fname, id, fout))
return targets
- def __init__(self, manager, filename, out,
+ def __init__(self, plugin, filename, out,
fullpath=True,
overwrite=False,
excludefiles=[],
@@ -78,8 +83,12 @@ class Extractor:
delete='No',
keepbroken=False,
fid=None):
- """ Initialize extractor for specific file """
- self.manager = manager
+ """
+ Initialize extractor for specific file
+ """
+ self._init(plugin.pyload)
+
+ self.plugin = plugin
self.filename = filename
self.out = out
self.fullpath = fullpath
@@ -90,17 +99,29 @@ class Extractor:
self.keepbroken = keepbroken
self.files = [] #: Store extracted files here
- pyfile = self.manager.core.files.getFile(fid) if fid else None
- self.notifyProgress = lambda x: pyfile.setProgress(x) if pyfile else lambda x: None
+ pyfile = self.pyload.files.getFile(fid) if fid else None
+ self.notify_progress = lambda x: pyfile.setProgress(x) if pyfile else lambda x: None
+
+ self.init()
def init(self):
- """ Initialize additional data structures """
+ """
+ Initialize additional data structures
+ """
pass
+ def _log(self, level, plugintype, pluginname, messages):
+ return self.plugin._log(level,
+ plugintype,
+ self.plugin.__name__,
+ (self.__name__,) + messages)
+
+
def check(self):
- """Quick Check by listing content of archive.
+ """
+ Quick Check by listing content of archive.
Raises error if password is needed, integrity is questionable or else.
:raises PasswordError
@@ -109,8 +130,10 @@ class Extractor:
"""
raise NotImplementedError
+
def verify(self):
- """Testing with Extractors buildt-in method
+ """
+ Testing with Extractors buildt-in method
Raises error if password is needed, integrity is questionable or else.
:raises PasswordError
@@ -125,7 +148,8 @@ class Extractor:
def extract(self, password=None):
- """Extract the archive. Raise specific errors in case of failure.
+ """
+ Extract the archive. Raise specific errors in case of failure.
:param progress: Progress function, call this to update status
:param password password to use
@@ -137,8 +161,9 @@ class Extractor:
raise NotImplementedError
- def getDeleteFiles(self):
- """Return list of files to delete, do *not* delete them here.
+ def get_delete_files(self):
+ """
+ Return list of files to delete, do *not* delete them here.
:return: List with paths of files to delete
"""
@@ -146,5 +171,7 @@ class Extractor:
def list(self, password=None):
- """Populate self.files at some point while extracting"""
+ """
+ Populate self.files at some point while extracting
+ """
return self.files
diff --git a/module/plugins/internal/Hook.py b/module/plugins/internal/Hook.py
new file mode 100644
index 000000000..1f566f824
--- /dev/null
+++ b/module/plugins/internal/Hook.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.Addon import Addon, threaded
+
+
+class Hook(Addon):
+ __name__ = "Hook"
+ __type__ = "hook"
+ __version__ = "0.13"
+ __status__ = "testing"
+
+ __config__ = [] #: [("name", "type", "desc", "default")]
+
+ __description__ = """Base hook plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("mkaay" , "mkaay@mkaay.de" ),
+ ("RaNaN" , "RaNaN@pyload.org" ),
+ ("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def __init__(self, core, manager):
+ super(Hook, self).__init__(core, manager)
+ self.init_periodical(10)
+
+
+ #@TODO: Remove in 0.4.10
+ def _log(self, level, plugintype, pluginname, messages):
+ return super(Addon, self)._log(level, plugintype, pluginname.replace("Hook", ""), messages)
diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py
new file mode 100644
index 000000000..a0cdb1e2e
--- /dev/null
+++ b/module/plugins/internal/Hoster.py
@@ -0,0 +1,648 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import inspect
+import os
+import random
+import time
+import traceback
+import urlparse
+
+from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.Plugin import (Plugin, Abort, Fail, Reconnect, Retry, Skip,
+ chunks, encode, exists, fixurl as _fixurl, replace_patterns,
+ seconds_to_midnight, set_cookie, set_cookies, parse_html_form,
+ parse_html_tag_attr_value, timestamp)
+from module.utils import fs_decode, fs_encode, save_join as fs_join, save_path as safe_filename
+
+
+#@TODO: Remove in 0.4.10
+def parse_fileInfo(klass, url="", html=""):
+ info = klass.get_info(url, html)
+ return info['name'], info['size'], info['status'], info['url']
+
+
+#@TODO: Remove in 0.4.10
+def getInfo(urls):
+ #: result = [ .. (name, size, status, url) .. ]
+ pass
+
+
+#@TODO: Remove in 0.4.10
+def create_getInfo(klass):
+ def get_info(urls):
+ for url in urls:
+ if hasattr(klass, "URL_REPLACEMENTS"):
+ url = replace_patterns(url, klass.URL_REPLACEMENTS)
+ yield parse_fileInfo(klass, url)
+
+ return get_info
+
+
+class Hoster(Plugin):
+ __name__ = "Hoster"
+ __type__ = "hoster"
+ __version__ = "0.19"
+ __status__ = "testing"
+
+ __pattern__ = r'^unmatchable$'
+ __config__ = [] #: [("name", "type", "desc", "default")]
+
+ __description__ = """Base hoster plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN" , "RaNaN@pyload.org" ),
+ ("spoob" , "spoob@pyload.org" ),
+ ("mkaay" , "mkaay@mkaay.de" ),
+ ("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def __init__(self, pyfile):
+ self._init(pyfile.m.core)
+
+ #: Engage wan reconnection
+ self.wantReconnect = False #@TODO: Change to `want_reconnect` in 0.4.10
+
+ #: Enable simultaneous processing of multiple downloads
+ self.multiDL = True #@TODO: Change to `multi_dl` in 0.4.10
+ self.limitDL = 0 #@TODO: Change to `limit_dl` in 0.4.10
+
+ #: time.time() + wait in seconds
+ self.wait_until = 0
+ self.waiting = False
+
+ #: Account handler instance, see :py:class:`Account`
+ self.account = None
+ self.user = None
+ self.req = None #: Browser instance, see `network.Browser`
+
+ #: Associated pyfile instance, see `PyFile`
+ self.pyfile = pyfile
+
+ self.thread = None #: Holds thread in future
+
+ #: Location where the last call to download was saved
+ self.last_download = ""
+
+ #: Re match of the last call to `checkDownload`
+ self.last_check = None
+
+ #: Js engine, see `JsEngine`
+ self.js = self.pyload.js
+
+ #: Captcha stuff
+ self.captcha = Captcha(self)
+
+ #: Some plugins store html code here
+ self.html = None
+
+ #: Dict of the amount of retries already made
+ self.retries = {}
+ self.retry_free = False #@TODO: Recheck in 0.4.10
+
+ self._setup()
+ self.init()
+
+
+ @classmethod
+ def get_info(cls, url="", html=""):
+ url = _fixurl(url)
+ url_p = urlparse.urlparse(url)
+ return {'name' : (url_p.path.split('/')[-1] or
+ url_p.query.split('=', 1)[::-1][0].split('&', 1)[0] or
+ url_p.netloc.split('.', 1)[0]),
+ 'size' : 0,
+ 'status': 3 if url else 8,
+ 'url' : url}
+
+
+ def init(self):
+ """
+ Initialize the plugin (in addition to `__init__`)
+ """
+ pass
+
+
+ def setup(self):
+ """
+ Setup for enviroment and other things, called before downloading (possibly more than one time)
+ """
+ pass
+
+
+ def _setup(self):
+ if self.account:
+ self.req = self.pyload.requestFactory.getRequest(self.__name__, self.user)
+ self.chunk_limit = -1 #: -1 for unlimited
+ self.resume_download = True
+ self.premium = self.account.is_premium(self.user)
+ else:
+ self.req = self.pyload.requestFactory.getRequest(self.__name__)
+ self.chunk_limit = 1
+ self.resume_download = False
+ self.premium = False
+
+
+ def load_account(self):
+ if self.req:
+ self.req.close()
+
+ if not self.account:
+ self.account = self.pyload.accountManager.getAccountPlugin(self.__name__)
+
+ if self.account:
+ if not self.user:
+ self.user = self.account.select()[0]
+
+ if not self.user or not self.account.is_logged(self.user, True):
+ self.account = False
+
+
+ def preprocessing(self, thread):
+ """
+ Handles important things to do before starting
+ """
+ self.thread = thread
+
+ if self.retry_free:
+ self.account = False
+ else:
+ self.load_account() #@TODO: Move to PluginThread in 0.4.10
+ self.retry_free = False
+
+ self._setup()
+ self.setup()
+
+ self.pyload.hookManager.downloadPreparing(self.pyfile) #@TODO: Recheck in 0.4.10
+
+ if self.pyfile.abort:
+ self.abort()
+
+ self.pyfile.setStatus("starting")
+ self.log_debug("PROCESS URL " + self.pyfile.url, "PLUGIN VERSION %s" % self.__version__)
+
+ return self.process(self.pyfile)
+
+
+ def process(self, pyfile):
+ """
+ The 'main' method of every plugin, you **have to** overwrite it
+ """
+ raise NotImplementedError
+
+
+ def set_reconnect(self, reconnect):
+ reconnect = bool(reconnect)
+
+ self.log_info(_("RECONNECT ") + ("enabled" if reconnect else "disabled"))
+ self.log_debug("Previous wantReconnect: %s" % self.wantReconnect)
+
+ self.wantReconnect = reconnect
+
+
+ def set_wait(self, seconds, reconnect=None):
+ """
+ Set a specific wait time later used with `wait`
+
+ :param seconds: wait time in seconds
+ :param reconnect: True if a reconnect would avoid wait time
+ """
+ wait_time = max(int(seconds), 1)
+ wait_until = time.time() + wait_time + 1
+
+ self.log_info(_("WAIT %d seconds") % wait_time)
+ self.log_debug("Previous waitUntil: %f" % self.pyfile.waitUntil)
+
+ self.pyfile.waitUntil = wait_until
+
+ if reconnect is not None:
+ self.set_reconnect(reconnect)
+
+
+ def wait(self, seconds=None, reconnect=None):
+ """
+ Waits the time previously set
+ """
+ pyfile = self.pyfile
+
+ if seconds is not None:
+ self.set_wait(seconds)
+
+ if reconnect is not None:
+ self.set_reconnect(reconnect)
+
+ self.waiting = True
+
+ status = pyfile.status #@NOTE: Remove in 0.4.10
+ pyfile.setStatus("waiting")
+
+ if not self.wantReconnect or self.account:
+ if self.account:
+ self.log_warning("Ignore reconnection due logged account")
+
+ while pyfile.waitUntil > time.time():
+ if pyfile.abort:
+ self.abort()
+
+ time.sleep(2)
+
+ else:
+ while pyfile.waitUntil > time.time():
+ if pyfile.abort:
+ self.abort()
+
+ if self.thread.m.reconnecting.isSet():
+ self.waiting = False
+ self.wantReconnect = False
+ raise Reconnect
+
+ self.thread.m.reconnecting.wait(2)
+ time.sleep(2)
+
+ self.waiting = False
+ pyfile.status = status #@NOTE: Remove in 0.4.10
+
+
+ def skip(self, reason=""):
+ """
+ Skip and give reason
+ """
+ raise Skip(encode(reason)) #@TODO: Remove `encode` in 0.4.10
+
+
+ def abort(self, reason=""):
+ """
+ Abort and give reason
+ """
+ #@TODO: Remove in 0.4.10
+ if reason:
+ self.pyfile.error = encode(reason)
+
+ raise Abort
+
+
+ def offline(self, reason=""):
+ """
+ Fail and indicate file is offline
+ """
+ #@TODO: Remove in 0.4.10
+ if reason:
+ self.pyfile.error = encode(reason)
+
+ raise Fail("offline")
+
+
+ def temp_offline(self, reason=""):
+ """
+ Fail and indicates file ist temporary offline, the core may take consequences
+ """
+ #@TODO: Remove in 0.4.10
+ if reason:
+ self.pyfile.error = encode(reason)
+
+ raise Fail("temp. offline")
+
+
+ def retry(self, max_tries=5, wait_time=1, reason=""):
+ """
+ Retries and begin again from the beginning
+
+ :param max_tries: number of maximum retries
+ :param wait_time: time to wait in seconds
+ :param reason: reason for retrying, will be passed to fail if max_tries reached
+ """
+ id = inspect.currentframe().f_back.f_lineno
+ if id not in self.retries:
+ self.retries[id] = 0
+
+ if 0 < max_tries <= self.retries[id]:
+ self.fail(reason or _("Max retries reached"))
+
+ self.wait(wait_time, False)
+
+ self.retries[id] += 1
+ raise Retry(encode(reason)) #@TODO: Remove `encode` in 0.4.10
+
+
+ def restart(self, reason=None, nopremium=False):
+ if not reason:
+ reason = _("Fallback to free download") if nopremium else _("Restart")
+
+ if nopremium:
+ if self.premium:
+ self.retry_free = True
+ else:
+ self.fail("%s | %s" % (reason, _("Download was already free")))
+
+ raise Retry(encode(reason)) #@TODO: Remove `encode` in 0.4.10
+
+
+ def fixurl(self, url):
+ url = _fixurl(url)
+
+ if not urlparse.urlparse(url).scheme:
+ url_p = urlparse.urlparse(self.pyfile.url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
+ url = urlparse.urljoin(baseurl, url)
+
+ return url
+
+
+ def download(self, url, get={}, post={}, ref=True, cookies=True, disposition=True):
+ """
+ Downloads the content at url to download folder
+
+ :param url:
+ :param get:
+ :param post:
+ :param ref:
+ :param cookies:
+ :param disposition: if True and server provides content-disposition header\
+ the filename will be changed if needed
+ :return: The location where the file was saved
+ """
+ if self.pyfile.abort:
+ self.abort()
+
+ url = self.fixurl(url)
+
+ if not url or not isinstance(url, basestring):
+ self.fail(_("No url given"))
+
+ if self.pyload.debug:
+ self.log_debug("DOWNLOAD URL " + url,
+ *["%s=%s" % (key, val) for key, val in locals().items() if key not in ("self", "url")])
+
+ name = _fixurl(self.pyfile.name)
+ self.pyfile.name = urlparse.urlparse(name).path.split('/')[-1] or name
+
+ self.captcha.correct()
+ self.check_for_same_files()
+
+ self.pyfile.setStatus("downloading")
+
+ download_folder = self.pyload.config.get("general", "download_folder")
+ download_location = fs_join(download_folder, self.pyfile.package().folder)
+
+ if not exists(download_location):
+ try:
+ os.makedirs(download_location)
+ except Exception, e:
+ self.fail(e)
+
+ self.set_permissions(download_location)
+
+ location = fs_decode(download_location)
+ filename = os.path.join(location, safe_filename(self.pyfile.name)) #@TODO: Move `safe_filename` check to HTTPDownload in 0.4.10
+
+ self.pyload.hookManager.dispatchEvent("download_start", self.pyfile, url, filename)
+
+ if self.pyfile.abort:
+ self.abort()
+
+ try:
+ newname = self.req.httpDownload(url, filename, get=get, post=post, ref=ref, cookies=cookies,
+ chunks=self.get_chunk_count(), resume=self.resume_download,
+ progressNotify=self.pyfile.setProgress, disposition=disposition)
+ finally:
+ self.pyfile.size = self.req.size
+
+ #@TODO: Recheck in 0.4.10
+ if disposition and newname:
+ finalname = urlparse.urlparse(newname).path.split('/')[-1].split(' filename*=')[0]
+
+ if finalname != newname != self.pyfile.name:
+ try:
+ os.rename(fs_join(location, newname), fs_join(location, finalname))
+
+ except OSError, e:
+ self.log_warning(_("Error renaming `%s` to `%s`") % (newname, finalname), e)
+ finalname = newname
+
+ self.log_info(_("`%s` saved as `%s`") % (self.pyfile.name, finalname))
+ self.pyfile.name = finalname
+ filename = os.path.join(location, finalname)
+
+ self.set_permissions(fs_encode(filename))
+
+ self.last_download = filename
+
+ return self.last_download
+
+
+ def check_download(self, rules, delete=False, file_size=0, size_tolerance=1024, read_size=1048576):
+ """
+ Checks the content of the last downloaded file, re match is saved to `lastCheck`
+
+ :param rules: dict with names and rules to match (compiled regexp or strings)
+ :param delete: delete if matched
+ :param file_size: expected file size
+ :param size_tolerance: size check tolerance
+ :param read_size: amount of bytes to read from files
+ :return: dictionary key of the first rule that matched
+ """
+ do_delete = False
+ last_download = fs_encode(self.last_download)
+
+ if not self.last_download or not exists(last_download):
+ self.last_download = ""
+ self.fail(self.pyfile.error or _("No file downloaded"))
+
+ try:
+ download_size = os.stat(last_download).st_size
+
+ if download_size < 1:
+ do_delete = True
+ self.fail(_("Empty file"))
+
+ elif file_size > 0:
+ diff = abs(file_size - download_size)
+
+ if diff > size_tolerance:
+ do_delete = True
+ self.fail(_("File size mismatch | Expected file size: %s | Downloaded file size: %s")
+ % (file_size, download_size))
+
+ elif diff != 0:
+ self.log_warning(_("File size is not equal to expected size"))
+
+ with open(last_download, "rb") as f:
+ content = f.read(read_size)
+
+ #: Produces encoding errors, better log to other file in the future?
+ # self.log_debug("Content: %s" % content)
+ for name, rule in rules.items():
+ if isinstance(rule, basestring):
+ if rule in content:
+ do_delete = True
+ return name
+
+ elif hasattr(rule, "search"):
+ m = rule.search(content)
+ if m:
+ do_delete = True
+ self.last_check = m
+ return name
+ finally:
+ if delete and do_delete:
+ try:
+ os.remove(last_download)
+
+ except OSError, e:
+ self.log_warning(_("Error removing: %s") % last_download, e)
+ if self.pyload.debug:
+ traceback.print_exc()
+
+ else:
+ self.last_download = ""
+ self.log_info(_("File deleted"))
+
+
+ def direct_link(self, url, follow_location=None):
+ link = ""
+
+ if follow_location is None:
+ redirect = 1
+
+ elif type(follow_location) is int:
+ redirect = max(follow_location, 1)
+
+ else:
+ redirect = self.get_config("maxredirs", 10, "UserAgentSwitcher")
+
+ for i in xrange(redirect):
+ try:
+ self.log_debug("Redirect #%d to: %s" % (i, url))
+ header = self.load(url, just_header=True)
+
+ except Exception: #: Bad bad bad... rewrite this part in 0.4.10
+ res = self.load(url,
+ just_header=True,
+ req=self.pyload.requestFactory.getRequest())
+
+ header = {'code': req.code}
+ for line in res.splitlines():
+ line = line.strip()
+ if not line or ":" not in line:
+ continue
+
+ key, none, value = line.partition(":")
+ key = key.lower().strip()
+ value = value.strip()
+
+ if key in header:
+ if type(header[key]) is list:
+ header[key].append(value)
+ else:
+ header[key] = [header[key], value]
+ else:
+ header[key] = value
+
+ if 'content-disposition' in header:
+ link = url
+
+ elif 'location' in header and header['location']:
+ location = header['location']
+
+ if not urlparse.urlparse(location).scheme:
+ url_p = urlparse.urlparse(url)
+ baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
+ location = urlparse.urljoin(baseurl, location)
+
+ if 'code' in header and header['code'] == 302:
+ link = location
+
+ if follow_location:
+ url = location
+ continue
+
+ else:
+ extension = os.path.splitext(urlparse.urlparse(url).path.split('/')[-1])[-1]
+
+ if 'content-type' in header and header['content-type']:
+ mimetype = header['content-type'].split(';')[0].strip()
+
+ elif extension:
+ mimetype = mimetypes.guess_type(extension, False)[0] or "application/octet-stream"
+
+ else:
+ mimetype = ""
+
+ if mimetype and (link or 'html' not in mimetype):
+ link = url
+ else:
+ link = ""
+
+ break
+
+ else:
+ try:
+ self.log_error(_("Too many redirects"))
+ except Exception:
+ pass
+
+ return link
+
+
+ def parse_html_form(self, attr_str="", input_names={}):
+ return parse_html_form(attr_str, self.html, input_names)
+
+
+ def check_traffic_left(self):
+ if not self.account:
+ return True
+
+ traffic = self.account.get_data(self.user, True)['trafficleft']
+
+ if traffic is None:
+ return False
+ elif traffic == -1:
+ return True
+ else:
+ size = self.pyfile.size / 1024
+ self.log_info(_("Filesize: %s KiB, Traffic left for user %s: %s KiB") % (size, self.user, traffic))
+ return size <= traffic
+
+
+ def get_password(self):
+ """
+ Get the password the user provided in the package
+ """
+ return self.pyfile.package().password or ""
+
+
+ #: Deprecated method, use `check_for_same_files` instead (Remove in 0.4.10)
+ def checkForSameFiles(self, *args, **kwargs):
+ return self.check_for_same_files(*args, **kwargs)
+
+
+ def check_for_same_files(self, starting=False):
+ """
+ Checks if same file was/is downloaded within same package
+
+ :param starting: indicates that the current download is going to start
+ :raises Skip:
+ """
+ pack = self.pyfile.package()
+
+ for pyfile in self.pyload.files.cache.values():
+ if pyfile != self.pyfile and pyfile.name is self.pyfile.name and pyfile.package().folder is pack.folder:
+ if pyfile.status in (0, 12): #: Finished or downloading
+ self.skip(pyfile.pluginname)
+ elif pyfile.status in (5, 7) and starting: #: A download is waiting/starting and was appenrently started before
+ self.skip(pyfile.pluginname)
+
+ download_folder = self.pyload.config.get("general", "download_folder")
+ location = fs_join(download_folder, pack.folder, self.pyfile.name)
+
+ if starting and self.pyload.config.get("download", "skip_existing") and exists(location):
+ size = os.stat(location).st_size
+ if size >= self.pyfile.size:
+ self.skip("File exists")
+
+ pyfile = self.pyload.db.findDuplicates(self.pyfile.id, self.pyfile.package().folder, self.pyfile.name)
+ if pyfile:
+ if exists(location):
+ self.skip(pyfile[0])
+
+ self.log_debug("File %s not skipped, because it does not exists." % self.pyfile.name)
diff --git a/module/plugins/internal/MultiCrypter.py b/module/plugins/internal/MultiCrypter.py
new file mode 100644
index 000000000..ca7b03941
--- /dev/null
+++ b/module/plugins/internal/MultiCrypter.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.SimpleCrypter import SimpleCrypter
+
+
+class MultiCrypter(SimpleCrypter):
+ __name__ = "MultiCrypter"
+ __type__ = "hoster"
+ __version__ = "0.02"
+ __status__ = "testing"
+
+ __pattern__ = r'^unmatchable$'
+ __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True),
+ ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
+
+ __description__ = """Multi decrypter plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def init(self):
+ self.CRYPTER_NAME = self.pyload.pluginManager.crypterPlugins[self.__name__]['name']
+
+
+ def _log(self, level, plugintype, pluginname, messages):
+ return super(MultiCrypter, self)._log(level,
+ plugintype,
+ pluginname,
+ (self.CRYPTER_NAME,) + messages)
diff --git a/module/plugins/internal/MultiHook.py b/module/plugins/internal/MultiHook.py
index 01ff4b07d..42a1985b5 100644
--- a/module/plugins/internal/MultiHook.py
+++ b/module/plugins/internal/MultiHook.py
@@ -4,14 +4,15 @@ import re
import time
import traceback
-from module.plugins.Hook import Hook
+from module.plugins.internal.Hook import Hook
from module.utils import decode, remove_chars
class MultiHook(Hook):
__name__ = "MultiHook"
__type__ = "hook"
- __version__ = "0.45"
+ __version__ = "0.54"
+ __status__ = "testing"
__config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"),
("pluginlist" , "str" , "Plugin list (comma separated)", "" ),
@@ -54,9 +55,7 @@ class MultiHook(Hook):
(r'^0' , "zero" )]
- def setup(self):
- self.info = {} #@TODO: Remove in 0.4.10
-
+ def init(self):
self.plugins = []
self.supported = []
self.new_supported = []
@@ -67,76 +66,58 @@ class MultiHook(Hook):
self.pluginname = None
self.plugintype = None
- self.initPlugin()
+ self.init_plugin()
- def initPlugin(self):
+ def init_plugin(self):
self.pluginname = self.__name__.rsplit("Hook", 1)[0]
- plugin, self.plugintype = self.core.pluginManager.findPlugin(self.pluginname)
+ plugin, self.plugintype = self.pyload.pluginManager.findPlugin(self.pluginname)
if plugin:
- self.pluginmodule = self.core.pluginManager.loadModule(self.plugintype, self.pluginname)
+ self.pluginmodule = self.pyload.pluginManager.loadModule(self.plugintype, self.pluginname)
self.pluginclass = getattr(self.pluginmodule, self.pluginname)
else:
- self.logWarning("Hook plugin will be deactivated due missing plugin reference")
- self.setConfig('activated', False)
+ self.log_warning(_("Hook plugin will be deactivated due missing plugin reference"))
+ self.set_config('activated', False)
- def loadAccount(self):
- self.account = self.core.accountManager.getAccountPlugin(self.pluginname)
+ def load_account(self):
+ self.account = self.pyload.accountManager.getAccountPlugin(self.pluginname)
- if self.account and not self.account.canUse():
- self.account = None
+ if self.account and not self.account.select()[0]:
+ self.account = False
if not self.account and hasattr(self.pluginclass, "LOGIN_ACCOUNT") and self.pluginclass.LOGIN_ACCOUNT:
- self.logWarning("Hook plugin will be deactivated due missing account reference")
- self.setConfig('activated', False)
-
+ self.log_warning(_("Hook plugin will be deactivated due missing account reference"))
+ self.set_config('activated', False)
- def getURL(self, *args, **kwargs): #@TODO: Remove in 0.4.10
- """ see HTTPRequest for argument list """
- h = pyreq.getHTTPRequest(timeout=120)
- try:
- if not 'decode' in kwargs:
- kwargs['decode'] = True
- rep = h.load(*args, **kwargs)
- finally:
- h.close()
- return rep
+ def activate(self):
+ self.init_periodical(threaded=True)
- def getConfig(self, option, default=''): #@TODO: Remove in 0.4.10
- """getConfig with default value - sublass may not implements all config options"""
- try:
- return self.getConf(option)
-
- except KeyError:
- return default
-
-
- def pluginsCached(self):
+ def plugins_cached(self):
if self.plugins:
return self.plugins
- for _i in xrange(2):
+ for _i in xrange(5):
try:
- pluginset = self._pluginSet(self.getHosters())
+ pluginset = self._plugin_set(self.get_hosters())
break
except Exception, e:
- self.logDebug(e, "Waiting 1 minute and retry")
+ self.log_warning(e, _("Waiting 1 minute and retry"))
time.sleep(60)
else:
- self.logWarning(_("Fallback to default reload interval due plugin parse error"))
+ self.log_error(_("No hoster list retrieved"))
self.interval = self.MIN_RELOAD_INTERVAL
return list()
try:
- configmode = self.getConfig("pluginmode", 'all')
+ configmode = self.get_config('pluginmode', 'all')
if configmode in ("listed", "unlisted"):
- pluginlist = self.getConfig("pluginlist", '').replace('|', ',').replace(';', ',').split(',')
- configset = self._pluginSet(pluginlist)
+ pluginlist = self.get_config('pluginlist', '').replace('|', ',').replace(';', ',').split(',')
+ configset = self._plugin_set(pluginlist)
if configmode == "listed":
pluginset &= configset
@@ -144,14 +125,14 @@ class MultiHook(Hook):
pluginset -= configset
except Exception, e:
- self.logError(e)
+ self.log_error(e)
self.plugins = list(pluginset)
return self.plugins
- def _pluginSet(self, plugins):
+ def _plugin_set(self, plugins):
regexp = re.compile(r'^[\w\-.^_]{3,63}\.[a-zA-Z]{2,}$', re.U)
plugins = [decode(p.strip()).lower() for p in plugins if regexp.match(p.strip())]
@@ -163,39 +144,28 @@ class MultiHook(Hook):
return set(plugins)
- def getHosters(self):
- """Load list of supported hoster
+ def get_hosters(self):
+ """
+ Load list of supported hoster
:return: List of domain names
"""
raise NotImplementedError
- #: Threaded _periodical, remove in 0.4.10 and use built-in flag for that
- def _periodical(self):
- try:
- if self.isActivated():
- self.periodical()
-
- except Exception, e:
- self.core.log.error(_("Error executing hooks: %s") % str(e))
- if self.core.debug:
- traceback.print_exc()
-
- self.cb = self.core.scheduler.addJob(self.interval, self._periodical)
-
-
def periodical(self):
- """reload plugin list periodically"""
- self.loadAccount()
+ """
+ Reload plugin list periodically
+ """
+ self.load_account()
- if self.getConfig("reload", True):
- self.interval = max(self.getConfig("reloadinterval", 12) * 60 * 60, self.MIN_RELOAD_INTERVAL)
+ if self.get_config('reload', True):
+ self.interval = max(self.get_config('reloadinterval', 12) * 60 * 60, self.MIN_RELOAD_INTERVAL)
else:
- self.core.scheduler.removeJob(self.cb)
+ self.pyload.scheduler.removeJob(self.cb)
self.cb = None
- self.logInfo(_("Reloading supported %s list") % self.plugintype)
+ self.log_info(_("Reloading supported %s list") % self.plugintype)
old_supported = self.supported
@@ -203,27 +173,27 @@ class MultiHook(Hook):
self.new_supported = []
self.plugins = []
- self.overridePlugins()
+ self.override_plugins()
old_supported = [plugin for plugin in old_supported if plugin not in self.supported]
if old_supported:
- self.logDebug("Unload: %s" % ", ".join(old_supported))
+ self.log_debug("Unload: %s" % ", ".join(old_supported))
for plugin in old_supported:
- self.unloadPlugin(plugin)
+ self.unload_plugin(plugin)
- def overridePlugins(self):
+ def override_plugins(self):
excludedList = []
if self.plugintype == "hoster":
- pluginMap = dict((name.lower(), name) for name in self.core.pluginManager.hosterPlugins.iterkeys())
- accountList = [account.type.lower() for account in self.core.api.getAccounts(False) if account.valid and account.premium]
+ pluginMap = dict((name.lower(), name) for name in self.pyload.pluginManager.hosterPlugins.keys())
+ accountList = [account.type.lower() for account in self.pyload.api.getAccounts(False) if account.valid and account.premium]
else:
pluginMap = {}
- accountList = [name[::-1].replace("Folder"[::-1], "", 1).lower()[::-1] for name in self.core.pluginManager.crypterPlugins.iterkeys()]
+ accountList = [name[::-1].replace("Folder"[::-1], "", 1).lower()[::-1] for name in self.pyload.pluginManager.crypterPlugins.keys()]
- for plugin in self.pluginsCached():
+ for plugin in self.plugins_cached():
name = remove_chars(plugin, "-.")
if name in accountList:
@@ -235,39 +205,39 @@ class MultiHook(Hook):
self.new_supported.append(plugin)
if not self.supported and not self.new_supported:
- self.logError(_("No %s loaded") % self.plugintype)
+ self.log_error(_("No %s loaded") % self.plugintype)
return
- # inject plugin plugin
- self.logDebug("Overwritten %ss: %s" % (self.plugintype, ", ".join(sorted(self.supported))))
+ #: Inject plugin plugin
+ self.log_debug("Overwritten %ss: %s" % (self.plugintype, ", ".join(sorted(self.supported))))
for plugin in self.supported:
- hdict = self.core.pluginManager.plugins[self.plugintype][plugin]
+ hdict = self.pyload.pluginManager.plugins[self.plugintype][plugin]
hdict['new_module'] = self.pluginmodule
hdict['new_name'] = self.pluginname
if excludedList:
- self.logInfo(_("%ss not overwritten: %s") % (self.plugintype.capitalize(), ", ".join(sorted(excludedList))))
+ self.log_info(_("%ss not overwritten: %s") % (self.plugintype.capitalize(), ", ".join(sorted(excludedList))))
if self.new_supported:
plugins = sorted(self.new_supported)
- self.logDebug("New %ss: %s" % (self.plugintype, ", ".join(plugins)))
+ self.log_debug("New %ss: %s" % (self.plugintype, ", ".join(plugins)))
- # create new regexp
+ #: Create new regexp
regexp = r'.*(?P<DOMAIN>%s).*' % "|".join(x.replace('.', '\.') for x in plugins)
- if hasattr(self.pluginclass, "__pattern__") and isinstance(self.pluginclass.__pattern__, basestring) and '://' in self.pluginclass.__pattern__:
+ if hasattr(self.pluginclass, "__pattern__") and isinstance(self.pluginclass.__pattern__, basestring) and "://" in self.pluginclass.__pattern__:
regexp = r'%s|%s' % (self.pluginclass.__pattern__, regexp)
- self.logDebug("Regexp: %s" % regexp)
+ self.log_debug("Regexp: %s" % regexp)
- hdict = self.core.pluginManager.plugins[self.plugintype][self.pluginname]
+ hdict = self.pyload.pluginManager.plugins[self.plugintype][self.pluginname]
hdict['pattern'] = regexp
hdict['re'] = re.compile(regexp)
- def unloadPlugin(self, plugin):
- hdict = self.core.pluginManager.plugins[self.plugintype][plugin]
+ def unload_plugin(self, plugin):
+ hdict = self.pyload.pluginManager.plugins[self.plugintype][plugin]
if "module" in hdict:
hdict.pop('module', None)
@@ -276,13 +246,15 @@ class MultiHook(Hook):
hdict.pop('new_name', None)
- def unload(self):
- """Remove override for all plugins. Scheduler job is removed by hookmanager"""
+ def deactivate(self):
+ """
+ Remove override for all plugins. Scheduler job is removed by hookmanager
+ """
for plugin in self.supported:
- self.unloadPlugin(plugin)
+ self.unload_plugin(plugin)
- # reset pattern
- hdict = self.core.pluginManager.plugins[self.plugintype][self.pluginname]
+ #: Reset pattern
+ hdict = self.pyload.pluginManager.plugins[self.plugintype][self.pluginname]
hdict['pattern'] = getattr(self.pluginclass, "__pattern__", r'^unmatchable$')
hdict['re'] = re.compile(hdict['pattern'])
diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py
index ff4414034..c0c928a45 100644
--- a/module/plugins/internal/MultiHoster.py
+++ b/module/plugins/internal/MultiHoster.py
@@ -2,14 +2,15 @@
import re
-from module.plugins.Plugin import Fail, Retry
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookies
+from module.plugins.internal.Plugin import Fail, encode
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookie, set_cookies
class MultiHoster(SimpleHoster):
__name__ = "MultiHoster"
__type__ = "hoster"
- __version__ = "0.40"
+ __version__ = "0.50"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
__config__ = [("use_premium" , "bool", "Use premium account if available" , True),
@@ -20,76 +21,90 @@ class MultiHoster(SimpleHoster):
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ HOSTER_NAME = None
+
+ LEECH_HOSTER = False
LOGIN_ACCOUNT = True
- def setup(self):
- self.chunkLimit = 1
- self.multiDL = bool(self.account)
- self.resumeDownload = self.premium
+ def init(self):
+ self.HOSTER_NAME = self.pyload.pluginManager.hosterPlugins[self.__name__]['name']
- def prepare(self):
- self.info = {}
- self.html = ""
- self.link = "" #@TODO: Move to hoster class in 0.4.10
- self.directDL = False #@TODO: Move to hoster class in 0.4.10
+ def _log(self, level, plugintype, pluginname, messages):
+ return super(MultiHoster, self)._log(level,
+ plugintype,
+ pluginname,
+ (self.HOSTER_NAME,) + messages)
- if not self.getConfig('use_premium', True):
- self.retryFree()
- if self.LOGIN_ACCOUNT and not self.account:
- self.fail(_("Required account not found"))
+ def setup(self):
+ self.chunk_limit = 1
+ self.multiDL = bool(self.account)
+ self.resume_download = self.premium
+
- self.req.setOption("timeout", 120)
+ def prepare(self):
+ #@TODO: Recheck in 0.4.10
+ plugin = self.pyload.pluginManager.hosterPlugins[self.__name__]
+ name = plugin['name']
+ module = plugin['module']
+ klass = getattr(module, name)
- if isinstance(self.COOKIES, list):
- set_cookies(self.req.cj, self.COOKIES)
+ self.get_info = klass.get_info
if self.DIRECT_LINK is None:
- self.directDL = self.__pattern__ != r'^unmatchable$' and re.match(self.__pattern__, self.pyfile.url)
+ direct_dl = self.__pattern__ != r'^unmatchable$' and re.match(self.__pattern__, self.pyfile.url)
else:
- self.directDL = self.DIRECT_LINK
+ direct_dl = self.DIRECT_LINK
+
+ super(MultiHoster, self).prepare()
- self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)
+ self.direct_dl = direct_dl
def process(self, pyfile):
try:
self.prepare()
+ self.check_info() #@TODO: Remove in 0.4.10
+
+ if self.direct_dl:
+ self.log_info(_("Looking for direct download link..."))
+ self.handle_direct(pyfile)
- if self.directDL:
- self.checkInfo()
- self.logDebug("Looking for direct download link...")
- self.handleDirect(pyfile)
+ if self.link or was_downloaded():
+ self.log_info(_("Direct download link detected"))
+ else:
+ self.log_info(_("Direct download link not found"))
- if not self.link and not self.lastDownload:
+ if not self.link and not self.last_download:
self.preload()
- self.checkErrors()
- self.checkStatus(getinfo=False)
+ self.check_errors()
+ self.check_status(getinfo=False)
- if self.premium and (not self.CHECK_TRAFFIC or self.checkTrafficLeft()):
- self.logDebug("Handled as premium download")
- self.handlePremium(pyfile)
+ if self.premium and (not self.CHECK_TRAFFIC or self.check_traffic_left()):
+ self.log_info(_("Processing as premium download..."))
+ self.handle_premium(pyfile)
- elif not self.LOGIN_ACCOUNT or (not self.CHECK_TRAFFIC or self.checkTrafficLeft()):
- self.logDebug("Handled as free download")
- self.handleFree(pyfile)
+ elif not self.LOGIN_ACCOUNT or (not self.CHECK_TRAFFIC or self.check_traffic_left()):
+ self.log_info(_("Processing as free download..."))
+ self.handle_free(pyfile)
- self.downloadLink(self.link, True)
- self.checkFile()
+ if not self.last_download:
+ self.log_info(_("Downloading file..."))
+ self.download(self.link, disposition=self.DISPOSITION)
- except Fail, e: #@TODO: Move to PluginThread in 0.4.10
- err = str(e) #@TODO: Recheck in 0.4.10
+ self.check_file()
+ except Fail, e: #@TODO: Move to PluginThread in 0.4.10
if self.premium:
- self.logWarning(_("Premium download failed"))
- self.retryFree()
+ self.log_warning(_("Premium download failed"))
+ self.restart(nopremium=True)
- elif self.getConfig("revertfailed", True) \
- and "new_module" in self.core.pluginManager.hosterPlugins[self.__name__]:
- hdict = self.core.pluginManager.hosterPlugins[self.__name__]
+ elif self.get_config("revertfailed", True) \
+ and "new_module" in self.pyload.pluginManager.hosterPlugins[self.__name__]:
+ hdict = self.pyload.pluginManager.hosterPlugins[self.__name__]
tmp_module = hdict['new_module']
tmp_name = hdict['new_name']
@@ -101,17 +116,17 @@ class MultiHoster(SimpleHoster):
hdict['new_module'] = tmp_module
hdict['new_name'] = tmp_name
- raise Retry(_("Revert to original hoster plugin"))
+ self.restart(_("Revert to original hoster plugin"))
else:
- raise Fail(err)
+ raise Fail(encode(e)) #@TODO: Remove `encode` in 0.4.10
- def handlePremium(self, pyfile):
- return self.handleFree(pyfile)
+ def handle_premium(self, pyfile):
+ return self.handle_free(pyfile)
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if self.premium:
raise NotImplementedError
else:
diff --git a/module/plugins/captcha/OCR.py b/module/plugins/internal/OCR.py
index 1874ba07d..b24b3058b 100644
--- a/module/plugins/captcha/OCR.py
+++ b/module/plugins/internal/OCR.py
@@ -11,33 +11,54 @@ except ImportError:
import logging
import os
import subprocess
-#import tempfile
+# import tempfile
+import traceback
-from module.utils import save_join
+from module.plugins.internal.Plugin import Plugin
+from module.utils import save_join as fs_join
-class OCR(object):
+class OCR(Plugin):
__name__ = "OCR"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.19"
+ __status__ = "testing"
__description__ = """OCR base plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- self.logger = logging.getLogger("log")
+ def __init__(self, plugin):
+ self._init(plugin.pyload)
+ self.plugin = plugin
+ self.init()
+
+
+ def init(self):
+ """
+ Initialize additional data structures
+ """
+ pass
+
+
+ def _log(self, level, plugintype, pluginname, messages):
+ return self.plugin._log(level,
+ plugintype,
+ self.plugin.__name__,
+ (self.__name__,) + messages)
def load_image(self, image):
self.image = Image.open(image)
self.pixels = self.image.load()
- self.result_captcha = ''
+ self.result_captcha = ""
- def unload(self):
- """delete all tmp images"""
+ def deactivate(self):
+ """
+ Delete all tmp images
+ """
pass
@@ -46,31 +67,32 @@ class OCR(object):
def run(self, command):
- """Run a command"""
-
- popen = subprocess.Popen(command, bufsize = -1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ """
+ Run a command
+ """
+ popen = subprocess.Popen(command, bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
popen.wait()
- output = popen.stdout.read() +" | "+ popen.stderr.read()
+ output = popen.stdout.read() + " | " + popen.stderr.read()
popen.stdout.close()
popen.stderr.close()
- self.logger.debug("Tesseract ReturnCode %s Output: %s" % (popen.returncode, output))
+ self.pyload.log_debug("Tesseract ReturnCode " + popen.returncode, "Output: " + output)
- def run_tesser(self, subset=False, digits=True, lowercase=True, uppercase=True):
- #tmpTif = tempfile.NamedTemporaryFile(suffix=".tif")
+ def run_tesser(self, subset=False, digits=True, lowercase=True, uppercase=True, pagesegmode=None):
+ # tmpTif = tempfile.NamedTemporaryFile(suffix=".tif")
try:
- tmpTif = open(save_join("tmp", "tmpTif_%s.tif" % self.__name__), "wb")
+ tmpTif = open(fs_join("tmp", "tmpTif_%s.tif" % self.__name__), "wb")
tmpTif.close()
- #tmpTxt = tempfile.NamedTemporaryFile(suffix=".txt")
- tmpTxt = open(save_join("tmp", "tmpTxt_%s.txt" % self.__name__), "wb")
+ # tmpTxt = tempfile.NamedTemporaryFile(suffix=".txt")
+ tmpTxt = open(fs_join("tmp", "tmpTxt_%s.txt" % self.__name__), "wb")
tmpTxt.close()
except IOError, e:
- self.logError(e)
+ self.log_error(e)
return
- self.logger.debug("save tiff")
+ self.pyload.log_debug("Saving tiff...")
self.image.save(tmpTif.name, 'TIFF')
if os.name == "nt":
@@ -78,11 +100,14 @@ class OCR(object):
else:
tessparams = ["tesseract"]
- tessparams.extend( [os.path.abspath(tmpTif.name), os.path.abspath(tmpTxt.name).replace(".txt", "")] )
+ tessparams.extend([os.path.abspath(tmpTif.name), os.path.abspath(tmpTxt.name).replace(".txt", "")])
+
+ if pagesegmode:
+ tessparams.extend(["-psm", str(pagesegmode)])
if subset and (digits or lowercase or uppercase):
- #tmpSub = tempfile.NamedTemporaryFile(suffix=".subset")
- with open(save_join("tmp", "tmpSub_%s.subset" % self.__name__), "wb") as tmpSub:
+ # tmpSub = tempfile.NamedTemporaryFile(suffix=".subset")
+ with open(fs_join("tmp", "tmpSub_%s.subset" % self.__name__), "wb") as tmpSub:
tmpSub.write("tessedit_char_whitelist ")
if digits:
@@ -96,9 +121,9 @@ class OCR(object):
tessparams.append("nobatch")
tessparams.append(os.path.abspath(tmpSub.name))
- self.logger.debug("run tesseract")
+ self.pyload.log_debug("Running tesseract...")
self.run(tessparams)
- self.logger.debug("read txt")
+ self.pyload.log_debug("Reading txt...")
try:
with open(tmpTxt.name, 'r') as f:
@@ -106,17 +131,19 @@ class OCR(object):
except Exception:
self.result_captcha = ""
- self.logger.debug(self.result_captcha)
+ self.pyload.log_info(_("OCR result: ") + self.result_captcha)
try:
os.remove(tmpTif.name)
os.remove(tmpTxt.name)
if subset and (digits or lowercase or uppercase):
os.remove(tmpSub.name)
- except Exception:
- pass
+ except OSError, e:
+ self.log_warning(e)
+ if self.pyload.debug:
+ traceback.print_exc()
- def get_captcha(self, name):
+ def recognize(self, name):
raise NotImplementedError
@@ -147,15 +174,15 @@ class OCR(object):
for y in xrange(h):
if pixels[x, y] == 255:
continue
- # No point in processing white pixels since we only want to remove black pixel
+ #: No point in processing white pixels since we only want to remove black pixel
count = 0
try:
- if pixels[x-1, y-1] != 255:
+ if pixels[x - 1, y - 1] != 255:
count += 1
- if pixels[x-1, y] != 255:
+ if pixels[x - 1, y] != 255:
count += 1
- if pixels[x-1, y + 1] != 255:
+ if pixels[x - 1, y + 1] != 255:
count += 1
if pixels[x, y + 1] != 255:
count += 1
@@ -163,19 +190,19 @@ class OCR(object):
count += 1
if pixels[x + 1, y] != 255:
count += 1
- if pixels[x + 1, y-1] != 255:
+ if pixels[x + 1, y - 1] != 255:
count += 1
- if pixels[x, y-1] != 255:
+ if pixels[x, y - 1] != 255:
count += 1
except Exception:
pass
- # not enough neighbors are dark pixels so mark this pixel
- # to be changed to white
+ #: Not enough neighbors are dark pixels so mark this pixel
+ #: To be changed to white
if count < allowed:
pixels[x, y] = 1
- # second pass: this time set all 1's to 255 (white)
+ #: Second pass: this time set all 1's to 255 (white)
for x in xrange(w):
for y in xrange(h):
if pixels[x, y] == 1:
@@ -185,8 +212,9 @@ class OCR(object):
def derotate_by_average(self):
- """rotate by checking each angle and guess most suitable"""
-
+ """
+ Rotate by checking each angle and guess most suitable
+ """
w, h = self.image.size
pixels = self.pixels
@@ -211,7 +239,6 @@ class OCR(object):
if pixels[x, y] == 0:
pixels[x, y] = 255
-
count = {}
for x in xrange(w):
@@ -240,7 +267,7 @@ class OCR(object):
hkey = 0
hvalue = 0
- for key, value in highest.iteritems():
+ for key, value in highest.items():
if value > hvalue:
hkey = key
hvalue = value
@@ -305,9 +332,9 @@ class OCR(object):
else:
result = self.result_captcha
- for key, item in values.iteritems():
+ for key, item in values.items():
- if key.__class__ == str:
+ if key.__class__ is str:
result = result.replace(key, item)
else:
for expr in key:
diff --git a/module/plugins/internal/Plugin.py b/module/plugins/internal/Plugin.py
new file mode 100644
index 000000000..7b45c40a8
--- /dev/null
+++ b/module/plugins/internal/Plugin.py
@@ -0,0 +1,399 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import datetime
+import inspect
+import os
+import re
+import urllib
+
+if os.name != "nt":
+ import grp
+ import pwd
+
+from module.plugins.Plugin import Abort, Fail, Reconnect, Retry, SkipDownload as Skip #@TODO: Remove in 0.4.10
+from module.utils import fs_encode, fs_decode, html_unescape, save_join as fs_join
+
+
+#@TODO: Move to utils in 0.4.10
+def decode(string, encoding='utf8'):
+ """ Decode string to unicode with utf8 """
+ if type(string) is str:
+ return string.decode(encoding, "replace")
+ else:
+ return string
+
+
+#@TODO: Move to utils in 0.4.10
+def encode(string, encoding='utf8'):
+ """ Decode string to utf8 """
+ if type(string) is unicode:
+ return string.encode(encoding, "replace")
+ else:
+ return string
+
+
+#@TODO: Move to utils in 0.4.10
+def exists(path):
+ if os.path.exists(path):
+ if os.name == "nt":
+ dir, name = os.path.split(path)
+ return name in os.listdir(dir)
+ else:
+ return True
+ else:
+ return False
+
+
+#@TODO: Move to utils in 0.4.10
+def fixurl(url):
+ return html_unescape(urllib.unquote(url.decode('unicode-escape'))).strip().rstrip('/')
+
+
+#@TODO: Move to utils in 0.4.10
+def timestamp():
+ return int(time.time() * 1000)
+
+
+def seconds_to_midnight(gmt=0):
+ now = datetime.datetime.utcnow() + datetime.timedelta(hours=gmt)
+
+ if now.hour == 0 and now.minute < 10:
+ midnight = now
+ else:
+ midnight = now + datetime.timedelta(days=1)
+
+ td = midnight.replace(hour=0, minute=10, second=0, microsecond=0) - now
+
+ if hasattr(td, 'total_seconds'):
+ res = td.total_seconds()
+ else: #@NOTE: work-around for python 2.5 and 2.6 missing datetime.timedelta.total_seconds
+ res = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
+
+ return int(res)
+
+
+def replace_patterns(string, ruleslist):
+ for r in ruleslist:
+ rf, rt = r
+ string = re.sub(rf, rt, string)
+ return string
+
+
+#@TODO: Remove in 0.4.10 and fix CookieJar.setCookie
+def set_cookie(cj, domain, name, value):
+ return cj.setCookie(domain, name, encode(value))
+
+
+def set_cookies(cj, cookies):
+ for cookie in cookies:
+ if isinstance(cookie, tuple) and len(cookie) == 3:
+ set_cookie(cj, *cookie)
+
+
+def parse_html_tag_attr_value(attr_name, tag):
+ m = re.search(r"%s\s*=\s*([\"']?)((?<=\")[^\"]+|(?<=')[^']+|[^>\s\"'][^>\s]*)\1" % attr_name, tag, re.I)
+ return m.group(2) if m else None
+
+
+def parse_html_form(attr_str, html, input_names={}):
+ for form in re.finditer(r"(?P<TAG><form[^>]*%s[^>]*>)(?P<CONTENT>.*?)</?(form|body|html)[^>]*>" % attr_str,
+ html, re.S | re.I):
+ inputs = {}
+ action = parse_html_tag_attr_value("action", form.group('TAG'))
+
+ for inputtag in re.finditer(r'(<(input|textarea)[^>]*>)([^<]*(?=</\2)|)', form.group('CONTENT'), re.S | re.I):
+ name = parse_html_tag_attr_value("name", inputtag.group(1))
+ if name:
+ value = parse_html_tag_attr_value("value", inputtag.group(1))
+ if not value:
+ inputs[name] = inputtag.group(3) or ""
+ else:
+ inputs[name] = value
+
+ if input_names:
+ #: Check input attributes
+ for key, val in input_names.items():
+ if key in inputs:
+ if isinstance(val, basestring) and inputs[key] is val:
+ continue
+ elif isinstance(val, tuple) and inputs[key] in val:
+ continue
+ elif hasattr(val, "search") and re.match(val, inputs[key]):
+ continue
+ break #: Attibute value does not match
+ else:
+ break #: Attibute name does not match
+ else:
+ return action, inputs #: Passed attribute check
+ else:
+ #: No attribute check
+ return action, inputs
+
+ return {}, None #: No matching form found
+
+
+#@TODO: Move to utils in 0.4.10
+def chunks(iterable, size):
+ it = iter(iterable)
+ item = list(islice(it, size))
+ while item:
+ yield item
+ item = list(islice(it, size))
+
+
+class Plugin(object):
+ __name__ = "Plugin"
+ __type__ = "hoster"
+ __version__ = "0.30"
+ __status__ = "testing"
+
+ __pattern__ = r'^unmatchable$'
+ __config__ = [] #: [("name", "type", "desc", "default")]
+
+ __description__ = """Base plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN" , "RaNaN@pyload.org" ),
+ ("spoob" , "spoob@pyload.org" ),
+ ("mkaay" , "mkaay@mkaay.de" ),
+ ("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def __init__(self, core):
+ self._init(core)
+ self.init()
+
+
+ def _init(self, core):
+ self.pyload = core
+ self.info = {} #: Provide information in dict here
+ self.req = None
+
+
+ def init(self):
+ """
+ Initialize the plugin (in addition to `__init__`)
+ """
+ pass
+
+
+ def _log(self, level, plugintype, pluginname, messages):
+ log = getattr(self.pyload.log, level)
+ msg = encode(" | ".join((a if isinstance(a, basestring) else str(a)).strip() for a in messages if a))
+ log("%(plugintype)s %(pluginname)s%(id)s: %(msg)s"
+ % {'plugintype': plugintype.upper(),
+ 'pluginname': pluginname,
+ 'id' : ("[%s]" % self.pyfile.id) if hasattr(self, 'pyfile') else "",
+ 'msg' : msg})
+
+
+ def log_debug(self, *args):
+ if self.pyload.debug:
+ return self._log("debug", self.__type__, self.__name__, args)
+
+
+ def log_info(self, *args):
+ return self._log("info", self.__type__, self.__name__, args)
+
+
+ def log_warning(self, *args):
+ return self._log("warning", self.__type__, self.__name__, args)
+
+
+ def log_error(self, *args):
+ return self._log("error", self.__type__, self.__name__, args)
+
+
+ def log_critical(self, *args):
+ return self._log("critical", self.__type__, self.__name__, args)
+
+
+ def set_permissions(self, path):
+ if not os.path.exists(path):
+ return
+
+ try:
+ if self.pyload.config.get("permission", "change_file"):
+ if os.path.isfile(path):
+ os.chmod(path, int(self.pyload.config.get("permission", "file"), 8))
+
+ elif os.path.isdir(path):
+ os.chmod(path, int(self.pyload.config.get("permission", "folder"), 8))
+
+ except OSError, e:
+ self.log_warning(_("Setting path mode failed"), e)
+
+ try:
+ if os.name != "nt" and self.pyload.config.get("permission", "change_dl"):
+ uid = pwd.getpwnam(self.pyload.config.get("permission", "user"))[2]
+ gid = grp.getgrnam(self.pyload.config.get("permission", "group"))[2]
+ os.chown(path, uid, gid)
+
+ except OSError, e:
+ self.log_warning(_("Setting owner and group failed"), e)
+
+
+ def get_chunk_count(self):
+ if self.chunk_limit <= 0:
+ return self.pyload.config.get("download", "chunks")
+ return min(self.pyload.config.get("download", "chunks"), self.chunk_limit)
+
+
+ def set_config(self, option, value):
+ """
+ Set config value for current plugin
+
+ :param option:
+ :param value:
+ :return:
+ """
+ self.pyload.config.setPlugin(self.__name__, option, value)
+
+
+ def get_config(self, option, default="", plugin=None):
+ """
+ Returns config value for current plugin
+
+ :param option:
+ :return:
+ """
+ try:
+ return self.pyload.config.getPlugin(plugin or self.__name__, option)
+
+ except KeyError:
+ self.log_debug("Config option `%s` not found, use default `%s`" % (option, default or None)) #@TODO: Restore to `log_warning` in 0.4.10
+ return default
+
+
+ def store(self, key, value):
+ """
+ Saves a value persistently to the database
+ """
+ self.pyload.db.setStorage(self.__name__, key, value)
+
+
+ def retrieve(self, key, default=None):
+ """
+ Retrieves saved value or dict of all saved entries if key is None
+ """
+ return self.pyload.db.getStorage(self.__name__, key) or default
+
+
+ def delete(self, key):
+ """
+ Delete entry in db
+ """
+ self.pyload.db.delStorage(self.__name__, key)
+
+
+ def fail(self, reason):
+ """
+ Fail and give reason
+ """
+ raise Fail(encode(reason)) #@TODO: Remove `encode` in 0.4.10
+
+
+ def error(self, reason="", type=_("Parse")):
+ if not reason:
+ type = _("Unknown")
+
+ msg = _("%s error") % type.strip().capitalize() if type else _("Error")
+ msg += (": %s" % reason.strip()) if reason else ""
+ msg += _(" | Plugin may be out of date")
+
+ raise Fail(encode(msg)) #@TODO: Remove `encode` in 0.4.10
+
+
+ def load(self, url, get={}, post={}, ref=True, cookies=True, just_header=False, decode=True, multipart=False, req=None):
+ """
+ Load content at url and returns it
+
+ :param url:
+ :param get:
+ :param post:
+ :param ref:
+ :param cookies:
+ :param just_header: If True only the header will be retrieved and returned as dict
+ :param decode: Wether to decode the output according to http header, should be True in most cases
+ :return: Loaded content
+ """
+ if hasattr(self, 'pyfile') and self.pyfile.abort:
+ self.abort()
+
+ url = fixurl(url)
+
+ if not url or not isinstance(url, basestring):
+ self.fail(_("No url given"))
+
+ if self.pyload.debug:
+ self.log_debug("LOAD URL " + url,
+ *["%s=%s" % (key, val) for key, val in locals().items() if key not in ("self", "url")])
+
+ if req is None:
+ req = self.req or self.pyload.requestFactory.getRequest(self.__name__)
+
+ #@TODO: Move to network in 0.4.10
+ if isinstance(cookies, list):
+ set_cookies(req.cj, cookies)
+
+ res = req.load(url, get, post, ref, bool(cookies), just_header, multipart, decode is True) #@TODO: Fix network multipart in 0.4.10
+
+ #@TODO: Move to network in 0.4.10
+ if decode:
+ res = html_unescape(res)
+
+ #@TODO: Move to network in 0.4.10
+ if isinstance(decode, basestring):
+ res = decode(res, decode)
+
+ if self.pyload.debug:
+ frame = inspect.currentframe()
+ framefile = fs_join("tmp", self.__name__, "%s_line%s.dump.html" % (frame.f_back.f_code.co_name, frame.f_back.f_lineno))
+ try:
+ if not exists(os.path.join("tmp", self.__name__)):
+ os.makedirs(os.path.join("tmp", self.__name__))
+
+ with open(framefile, "wb") as f:
+ del frame #: Delete the frame or it wont be cleaned
+ f.write(encode(res))
+
+ except IOError, e:
+ self.log_error(e)
+
+ if just_header:
+ #: Parse header
+ header = {'code': req.code}
+ for line in res.splitlines():
+ line = line.strip()
+ if not line or ":" not in line:
+ continue
+
+ key, none, value = line.partition(":")
+ key = key.strip().lower()
+ value = value.strip()
+
+ if key in header:
+ if type(header[key]) is list:
+ header[key].append(value)
+ else:
+ header[key] = [header[key], value]
+ else:
+ header[key] = value
+ res = header
+
+ return res
+
+
+ def clean(self):
+ """
+ Clean everything and remove references
+ """
+ try:
+ self.req.close()
+ except Exception:
+ pass
+
+ for a in ("pyfile", "thread", "html", "req"):
+ if hasattr(self, a):
+ setattr(self, a, None)
diff --git a/module/plugins/internal/SevenZip.py b/module/plugins/internal/SevenZip.py
index 624f6c939..5811c28de 100644
--- a/module/plugins/internal/SevenZip.py
+++ b/module/plugins/internal/SevenZip.py
@@ -5,12 +5,13 @@ import re
import subprocess
from module.plugins.internal.UnRar import ArchiveError, CRCError, PasswordError, UnRar, renice
-from module.utils import fs_encode, save_join
+from module.utils import fs_encode, save_join as fs_join
class SevenZip(UnRar):
__name__ = "SevenZip"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """7-Zip extractor plugin"""
__license__ = "GPLv3"
@@ -18,9 +19,7 @@ class SevenZip(UnRar):
("Walter Purcaro", "vuolter@gmail.com")]
- CMD = "7z"
- VERSION = ""
-
+ CMD = "7z"
EXTENSIONS = [".7z", ".xz", ".zip", ".gz", ".gzip", ".tgz", ".bz2", ".bzip2",
".tbz2", ".tbz", ".tar", ".wim", ".swm", ".lzma", ".rar", ".cab",
".arj", ".z", ".taz", ".cpio", ".rpm", ".deb", ".lzh", ".lha",
@@ -37,23 +36,27 @@ class SevenZip(UnRar):
@classmethod
- def isUsable(cls):
- if os.name == "nt":
- cls.CMD = os.path.join(pypath, "7z.exe")
- p = subprocess.Popen([cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
- else:
+ def find(cls):
+ try:
+ if os.name == "nt":
+ cls.CMD = os.path.join(pypath, "7z.exe")
+
p = subprocess.Popen([cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
- m = cls.re_version.search(out)
- cls.VERSION = m.group(1) if m else '(version unknown)'
+ except OSError:
+ return False
+
+ else:
+ m = cls.re_version.search(out)
+ if m is not None:
+ cls.VERSION = m.group(1)
- return True
+ return True
def verify(self, password):
- # 7z can't distinguish crc and pw error in test
+ #: 7z can't distinguish crc and pw error in test
p = self.call_cmd("l", "-slt", fs_encode(self.filename))
out, err = p.communicate()
@@ -72,7 +75,7 @@ class SevenZip(UnRar):
p = self.call_cmd("l", "-slt", fs_encode(self.filename))
out, err = p.communicate()
- # check if output or error macthes the 'wrong password'-Regexp
+ #: Check if output or error macthes the 'wrong password'-Regexp
if self.re_wrongpwd.search(out):
raise PasswordError
@@ -91,7 +94,7 @@ class SevenZip(UnRar):
renice(p.pid, self.renice)
- # communicate and retrieve stderr
+ #: Communicate and retrieve stderr
self._progress(p)
err = p.stderr.read().strip()
@@ -102,7 +105,7 @@ class SevenZip(UnRar):
elif self.re_wrongcrc.search(err):
raise CRCError(err)
- else: #: raise error if anything is on stderr
+ else: #: Raise error if anything is on stderr
raise ArchiveError(err)
if p.returncode > 1:
@@ -126,7 +129,7 @@ class SevenZip(UnRar):
result = set()
for groups in self.re_filelist.findall(out):
f = groups[-1].strip()
- result.add(save_join(self.out, f))
+ result.add(fs_join(self.out, f))
return list(result)
@@ -134,20 +137,20 @@ class SevenZip(UnRar):
def call_cmd(self, command, *xargs, **kwargs):
args = []
- #overwrite flag
+ #: Overwrite flag
if self.overwrite:
args.append("-y")
- #set a password
- if "password" in kwargs and kwargs["password"]:
- args.append("-p%s" % kwargs["password"])
+ #: Set a password
+ if "password" in kwargs and kwargs['password']:
+ args.append("-p%s" % kwargs['password'])
else:
args.append("-p-")
#@NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue
call = [self.CMD, command] + args + list(xargs)
- self.manager.logDebug(" ".join(call))
+ self.log_debug(" ".join(call))
p = subprocess.Popen(call, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p
diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py
index b843a28f0..6a3f91a5b 100644
--- a/module/plugins/internal/SimpleCrypter.py
+++ b/module/plugins/internal/SimpleCrypter.py
@@ -1,27 +1,26 @@
# -*- coding: utf-8 -*-
import re
-import urlparse
-from module.plugins.Crypter import Crypter
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookies
+from module.plugins.internal.Crypter import Crypter
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookie, set_cookies
from module.utils import fixup, html_unescape
class SimpleCrypter(Crypter, SimpleHoster):
__name__ = "SimpleCrypter"
__type__ = "crypter"
- __version__ = "0.46"
+ __version__ = "0.60"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
- __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides core.config['general']['folder_per_package']
+ __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config['general']['folder_per_package']
("subfolder_per_pack", "bool", "Create a subfolder for each package", True)]
__description__ = """Simple decrypter plugin"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
-
"""
Following patterns should be defined by each crypter:
@@ -49,121 +48,93 @@ class SimpleCrypter(Crypter, SimpleHoster):
and its loadPage method:
- def loadPage(self, page_n):
+ def load_page(self, page_n):
return the html of the page number page_n
"""
- LINK_PATTERN = None
-
- NAME_REPLACEMENTS = [("&#?\w+;", fixup)]
- URL_REPLACEMENTS = []
-
- TEXT_ENCODING = False #: Set to True or encoding name if encoding in http header is not correct
- COOKIES = True #: or False or list of tuples [(domain, name, value)]
-
- LOGIN_ACCOUNT = False
- LOGIN_PREMIUM = False
+ DIRECT_LINK = True
+ LEECH_HOSTER = False
#@TODO: Remove in 0.4.10
- def init(self):
- account_name = (self.__name__ + ".py").replace("Folder.py", "").replace(".py", "")
- account = self.pyfile.m.core.accountManager.getAccountPlugin(account_name)
-
- if account and account.canUse():
- self.user, data = account.selectAccount()
- self.req = account.getAccountRequest(self.user)
- self.premium = account.isPremium(self.user)
+ def _setup(self):
+ orig_name = self.__name__
+ self.__name__ = (orig_name + ".py").replace("Folder.py", "").replace(".py", "")
- self.account = account
+ super(SimpleCrypter, self)._setup()
+ self.__name__ = orig_name
- def prepare(self):
- self.pyfile.error = "" #@TODO: Remove in 0.4.10
- self.info = {}
- self.html = ""
- self.links = [] #@TODO: Move to hoster class in 0.4.10
+ #@TODO: Remove in 0.4.10
+ def load_account(self):
+ orig_name = self.__name__
+ self.__name__ = (orig_name + ".py").replace("Folder.py", "").replace(".py", "")
- if self.LOGIN_PREMIUM and not self.premium:
- self.fail(_("Required premium account not found"))
+ super(SimpleCrypter, self).load_account()
- if self.LOGIN_ACCOUNT and not self.account:
- self.fail(_("Required account not found"))
+ self.__name__ = orig_name
- self.req.setOption("timeout", 120)
- if isinstance(self.COOKIES, list):
- set_cookies(self.req.cj, self.COOKIES)
+ def handle_direct(self, pyfile):
+ for i in xrange(self.get_config("maxredirs", plugin="UserAgentSwitcher")):
+ redirect = self.link or pyfile.url
+ self.log_debug("Redirect #%d to: %s" % (i, redirect))
- self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)
+ header = self.load(redirect, just_header=True)
+ if 'location' in header and header['location']:
+ self.link = header['location']
+ else:
+ break
+ else:
+ self.log_error(_("Too many redirects"))
def decrypt(self, pyfile):
self.prepare()
+ self.check_info() #@TODO: Remove in 0.4.10
- self.preload()
- self.checkInfo()
-
- self.links = self.getLinks()
+ if self.direct_dl:
+ self.log_debug(_("Looking for direct download link..."))
+ self.handle_direct(pyfile)
- if hasattr(self, 'PAGES_PATTERN') and hasattr(self, 'loadPage'):
- self.handlePages(pyfile)
+ if self.link or self.links or self.urls or self.packages:
+ self.log_info(_("Direct download link detected"))
+ else:
+ self.log_info(_("Direct download link not found"))
- self.logDebug("Package has %d links" % len(self.links))
+ if not (self.link or self.links or self.urls or self.packages):
+ self.preload()
- if self.links:
- self.packages = [(self.info['name'], self.links, self.info['folder'])]
+ self.links = self.get_links() or list()
- elif not self.urls and not self.packages: #@TODO: Remove in 0.4.10
- self.fail(_("No link grabbed"))
+ if hasattr(self, 'PAGES_PATTERN') and hasattr(self, 'loadPage'):
+ self.handle_pages(pyfile)
+ self.log_debug("Package has %d links" % len(self.links))
- def checkNameSize(self, getinfo=True):
- if not self.info or getinfo:
- self.logDebug("File info (BEFORE): %s" % self.info)
- self.info.update(self.getInfo(self.pyfile.url, self.html))
- self.logDebug("File info (AFTER): %s" % self.info)
-
- try:
- url = self.info['url'].strip()
- name = self.info['name'].strip()
- if name and name != url:
- self.pyfile.name = name
+ if self.link:
+ self.urls.append(self.link)
- except Exception:
- pass
-
- try:
- folder = self.info['folder'] = self.pyfile.name
-
- except Exception:
- pass
-
- self.logDebug("File name: %s" % self.pyfile.name,
- "File folder: %s" % self.pyfile.name)
+ if self.links:
+ name = folder = pyfile.name
+ self.packages.append((name, self.links, folder))
- def getLinks(self):
+ def get_links(self):
"""
Returns the links extracted from self.html
You should override this only if it's impossible to extract links using only the LINK_PATTERN.
"""
- url_p = urlparse.urlparse(self.pyfile.url)
- baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
-
- links = [urlparse.urljoin(baseurl, link) if not urlparse.urlparse(link).scheme else link \
- for link in re.findall(self.LINK_PATTERN, self.html)]
-
- return [html_unescape(l.strip().decode('unicode-escape')) for l in links]
+ return re.findall(self.LINK_PATTERN, self.html)
- def handlePages(self, pyfile):
+ def handle_pages(self, pyfile):
try:
pages = int(re.search(self.PAGES_PATTERN, self.html).group(1))
except Exception:
pages = 1
for p in xrange(2, pages + 1):
- self.html = self.loadPage(p)
- self.links += self.getLinks()
+ self.html = self.load_page(p)
+ self.links += self.get_links()
diff --git a/module/plugins/internal/SimpleDereferer.py b/module/plugins/internal/SimpleDereferer.py
deleted file mode 100644
index 2e7e08321..000000000
--- a/module/plugins/internal/SimpleDereferer.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import re
-
-from module.plugins.Crypter import Crypter
-from module.plugins.internal.SimpleHoster import create_getInfo, set_cookies
-from module.utils import html_unescape
-
-
-class SimpleDereferer(Crypter):
- __name__ = "SimpleDereferer"
- __type__ = "crypter"
- __version__ = "0.14"
-
- __pattern__ = r'^unmatchable$'
- __config__ = [] #@TODO: Remove in 0.4.10
-
- __description__ = """Simple dereferer plugin"""
- __license__ = "GPLv3"
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
-
-
- """
- Following patterns should be defined by each crypter:
-
- LINK_PATTERN: Regex to catch the redirect url in group(1)
- example: LINK_PATTERN = r'<div class="link"><a href="(.+?)"'
-
- OFFLINE_PATTERN: (optional) Checks if the page is unreachable
- example: OFFLINE_PATTERN = r'File (deleted|not found)'
-
- TEMP_OFFLINE_PATTERN: (optional) Checks if the page is temporarily unreachable
- example: TEMP_OFFLINE_PATTERN = r'Server maintainance'
-
-
- You can override the getLinks method if you need a more sophisticated way to extract the redirect url.
- """
-
- URL_REPLACEMENTS = []
-
- LINK_PATTERN = None
-
- TEXT_ENCODING = False
- COOKIES = True
-
-
- def handleDirect(self, pyfile):
- header = self.load(pyfile.url, just_header=True, decode=True)
- if 'location' in header and header['location']:
- self.link = header['location']
-
-
- def decrypt(self, pyfile):
- self.prepare()
-
- self.handleDirect(pyfile)
-
- if not self.link:
- self.preload()
- self.checkStatus()
-
- self.link = self.getLink()
-
- if self.link:
- self.urls = [self.link]
-
- elif not self.urls and not self.packages: #@TODO: Remove in 0.4.10
- self.fail(_("No link grabbed"))
-
-
- def prepare(self):
- self.info = {}
- self.html = ""
- self.link = "" #@TODO: Move to hoster class in 0.4.10
-
- self.req.setOption("timeout", 120)
-
- if isinstance(self.COOKIES, list):
- set_cookies(self.req.cj, self.COOKIES)
-
- self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)
-
-
- def preload(self):
- self.html = self.load(self.pyfile.url, cookies=bool(self.COOKIES), decode=not self.TEXT_ENCODING)
-
- if isinstance(self.TEXT_ENCODING, basestring):
- self.html = unicode(self.html, self.TEXT_ENCODING)
-
-
- def checkStatus(self):
- if hasattr(self, "OFFLINE_PATTERN") and re.search(self.OFFLINE_PATTERN, self.html):
- self.offline()
-
- elif hasattr(self, "TEMP_OFFLINE_PATTERN") and re.search(self.TEMP_OFFLINE_PATTERN, self.html):
- self.tempOffline()
-
-
- def getLink(self):
- try:
- link = re.search(self.LINK_PATTERN, self.html).group(1)
-
- except Exception, e:
- self.logWarning(e)
-
- else:
- return html_unescape(link.strip().decode('unicode-escape')) #@TODO: Move this check to plugin `load` method in 0.4.10
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index 1d44a6642..9c310ca27 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -1,245 +1,30 @@
# -*- coding: utf-8 -*-
-import datetime
+from __future__ import with_statement
+
import mimetypes
import os
import re
import time
-import urllib
import urlparse
from module.PyFile import statusMap as _statusMap
-from module.network.CookieJar import CookieJar
from module.network.HTTPRequest import BadHeader
-from module.network.RequestFactory import getURL
-from module.plugins.Hoster import Hoster
-from module.plugins.Plugin import Fail, Retry
-from module.utils import fixup, fs_encode, html_unescape, parseFileSize
+from module.network.RequestFactory import getURL as get_url
+from module.plugins.internal.Hoster import Hoster, create_getInfo, parse_fileInfo
+from module.plugins.internal.Plugin import Fail, encode, fixurl, replace_patterns, seconds_to_midnight, set_cookie, set_cookies
+from module.utils import fixup, fs_encode, parseFileSize as parse_size
#@TODO: Adapt and move to PyFile in 0.4.10
-statusMap = dict((v, k) for k, v in _statusMap.iteritems())
-
-
-#@TODO: Remove in 0.4.10 and redirect to self.error instead
-def _error(self, reason, type):
- if not reason and not type:
- type = "unknown"
-
- msg = _("%s error") % type.strip().capitalize() if type else _("Error")
- msg += (": %s" % reason.strip()) if reason else ""
- msg += _(" | Plugin may be out of date")
-
- raise Fail(msg)
-
-
-#@TODO: Remove in 0.4.10
-def _wait(self, seconds, reconnect):
- if seconds:
- self.setWait(int(seconds) + 1)
-
- if reconnect is not None:
- self.wantReconnect = reconnect
-
- super(SimpleHoster, self).wait()
-
-
-def replace_patterns(string, ruleslist):
- for r in ruleslist:
- rf, rt = r
- string = re.sub(rf, rt, string)
- return string
-
-
-def set_cookies(cj, cookies):
- for cookie in cookies:
- if isinstance(cookie, tuple) and len(cookie) == 3:
- domain, name, value = cookie
- cj.setCookie(domain, name, value)
-
-
-def parseHtmlTagAttrValue(attr_name, tag):
- m = re.search(r"%s\s*=\s*([\"']?)((?<=\")[^\"]+|(?<=')[^']+|[^>\s\"'][^>\s]*)\1" % attr_name, tag, re.I)
- return m.group(2) if m else None
-
-
-def parseHtmlForm(attr_str, html, input_names={}):
- for form in re.finditer(r"(?P<TAG><form[^>]*%s[^>]*>)(?P<CONTENT>.*?)</?(form|body|html)[^>]*>" % attr_str,
- html, re.S | re.I):
- inputs = {}
- action = parseHtmlTagAttrValue("action", form.group('TAG'))
-
- for inputtag in re.finditer(r'(<(input|textarea)[^>]*>)([^<]*(?=</\2)|)', form.group('CONTENT'), re.S | re.I):
- name = parseHtmlTagAttrValue("name", inputtag.group(1))
- if name:
- value = parseHtmlTagAttrValue("value", inputtag.group(1))
- if not value:
- inputs[name] = inputtag.group(3) or ""
- else:
- inputs[name] = value
-
- if input_names:
- # check input attributes
- for key, val in input_names.iteritems():
- if key in inputs:
- if isinstance(val, basestring) and inputs[key] == val:
- continue
- elif isinstance(val, tuple) and inputs[key] in val:
- continue
- elif hasattr(val, "search") and re.match(val, inputs[key]):
- continue
- break #: attibute value does not match
- else:
- break #: attibute name does not match
- else:
- return action, inputs #: passed attribute check
- else:
- # no attribute check
- return action, inputs
-
- return {}, None #: no matching form found
-
-
-#@TODO: Remove in 0.4.10
-def parseFileInfo(plugin, url="", html=""):
- if hasattr(plugin, "getInfo"):
- info = plugin.getInfo(url, html)
- res = info['name'], info['size'], info['status'], info['url']
- else:
- url = urllib.unquote(url)
- url_p = urlparse.urlparse(url)
- res = ((url_p.path.split('/')[-1]
- or url_p.query.split('=', 1)[::-1][0].split('&', 1)[0]
- or url_p.netloc.split('.', 1)[0]),
- 0,
- 3 if url else 8,
- url)
-
- return res
-
-
-#@TODO: Remove in 0.4.10
-def create_getInfo(plugin):
- def getInfo(urls):
- for url in urls:
- if hasattr(plugin, "URL_REPLACEMENTS"):
- url = replace_patterns(url, plugin.URL_REPLACEMENTS)
- yield parseFileInfo(plugin, url)
-
- return getInfo
-
-
-def timestamp():
- return int(time.time() * 1000)
-
-
-#@TODO: Move to hoster class in 0.4.10
-def getFileURL(self, url, follow_location=None):
- link = ""
- redirect = 1
-
- if type(follow_location) is int:
- redirect = max(follow_location, 1)
- else:
- redirect = 10
-
- for i in xrange(redirect):
- try:
- self.logDebug("Redirect #%d to: %s" % (i, url))
- header = self.load(url, just_header=True, decode=True)
-
- except Exception: #: Bad bad bad... rewrite this part in 0.4.10
- req = pyreq.getHTTPRequest()
- res = req.load(url, just_header=True, decode=True)
-
- req.close()
-
- header = {"code": req.code}
- for line in res.splitlines():
- line = line.strip()
- if not line or ":" not in line:
- continue
-
- key, none, value = line.partition(":")
- key = key.lower().strip()
- value = value.strip()
-
- if key in header:
- if type(header[key]) == list:
- header[key].append(value)
- else:
- header[key] = [header[key], value]
- else:
- header[key] = value
-
- if 'content-disposition' in header:
- link = url
-
- elif 'location' in header and header['location']:
- location = header['location']
-
- if not urlparse.urlparse(location).scheme:
- url_p = urlparse.urlparse(url)
- baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
- location = urlparse.urljoin(baseurl, location)
-
- if 'code' in header and header['code'] == 302:
- link = location
-
- if follow_location:
- url = location
- continue
-
- else:
- extension = os.path.splitext(urlparse.urlparse(url).path.split('/')[-1])[-1]
-
- if 'content-type' in header and header['content-type']:
- mimetype = header['content-type'].split(';')[0].strip()
-
- elif extension:
- mimetype = mimetypes.guess_type(extension, False)[0] or "application/octet-stream"
-
- else:
- mimetype = ""
-
- if mimetype and (link or 'html' not in mimetype):
- link = url
- else:
- link = ""
-
- break
-
- else:
- try:
- self.logError(_("Too many redirects"))
- except Exception:
- pass
-
- return link
-
-
-def secondsToMidnight(gmt=0):
- now = datetime.datetime.utcnow() + datetime.timedelta(hours=gmt)
-
- if now.hour is 0 and now.minute < 10:
- midnight = now
- else:
- midnight = now + datetime.timedelta(days=1)
-
- td = midnight.replace(hour=0, minute=10, second=0, microsecond=0) - now
-
- if hasattr(td, 'total_seconds'):
- res = td.total_seconds()
- else: #@NOTE: work-around for python 2.5 and 2.6 missing datetime.timedelta.total_seconds
- res = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
-
- return int(res)
+statusMap = dict((v, k) for k, v in _statusMap.items())
class SimpleHoster(Hoster):
__name__ = "SimpleHoster"
__type__ = "hoster"
- __version__ = "1.50"
+ __version__ = "1.80"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
__config__ = [("use_premium", "bool", "Use premium account if available" , True),
@@ -249,7 +34,6 @@ class SimpleHoster(Hoster):
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
-
"""
Info patterns:
@@ -258,6 +42,7 @@ class SimpleHoster(Hoster):
or
NAME_PATTERN: (mandatory) Name that will be set for the file
example: NAME_PATTERN = r'(?P<N>file_name)'
+
SIZE_PATTERN: (mandatory) Size that will be checked for the file
example: SIZE_PATTERN = r'(?P<S>file_size) (?P<U>size_unit)'
@@ -285,8 +70,8 @@ class SimpleHoster(Hoster):
IP_BLOCKED_PATTERN: (optional)
example: IP_BLOCKED_PATTERN = r'in your country'
- DOWNLOAD_LIMIT_PATTERN: (optional)
- example: DOWNLOAD_LIMIT_PATTERN = r'download limit'
+ DL_LIMIT_PATTERN: (optional)
+ example: DL_LIMIT_PATTERN = r'download limit'
SIZE_LIMIT_PATTERN: (optional)
example: SIZE_LIMIT_PATTERN = r'up to'
@@ -295,49 +80,50 @@ class SimpleHoster(Hoster):
example: ERROR_PATTERN = r''
- Instead overriding handleFree and handlePremium methods you may define the following patterns for basic link handling:
+ Instead overriding handle_free and handle_premium methods you may define the following patterns for basic link handling:
- LINK_FREE_PATTERN: (optional) group(1) should be the direct link for free download
- example: LINK_FREE_PATTERN = r'<div class="link"><a href="(.+?)"'
+ LINK_PATTERN: (optional) group(1) should be the direct link for free and premium download
+ example: LINK_PATTERN = r'<div class="link"><a href="(.+?)"'
+ or
+ LINK_FREE_PATTERN: (optional) group(1) should be the direct link for free download
+ example: LINK_FREE_PATTERN = r'<div class="link"><a href="(.+?)"'
- LINK_PREMIUM_PATTERN: (optional) group(1) should be the direct link for premium download
- example: LINK_PREMIUM_PATTERN = r'<div class="link"><a href="(.+?)"'
+ LINK_PREMIUM_PATTERN: (optional) group(1) should be the direct link for premium download
+ example: LINK_PREMIUM_PATTERN = r'<div class="link"><a href="(.+?)"'
"""
-
NAME_REPLACEMENTS = [("&#?\w+;", fixup)]
SIZE_REPLACEMENTS = []
URL_REPLACEMENTS = []
- TEXT_ENCODING = False #: Set to True or encoding name if encoding value in http header is not correct
+ FILE_ERRORS = [('Html error' , r'\A(?:\s*<.+>)?((?:[\w\s]*(?:[Ee]rror|ERROR)\s*\:?)?\s*\d{3})(?:\Z|\s+)'),
+ ('Request error', r'([Aa]n error occured while processing your request)' ),
+ ('Html file' , r'\A\s*<!DOCTYPE html' )]
+
+ CHECK_FILE = True #: Set to False to not check the last downloaded file with declared error patterns
+ CHECK_TRAFFIC = False #: Set to True to reload checking traffic left for premium account
COOKIES = True #: or False or list of tuples [(domain, name, value)]
- CHECK_TRAFFIC = False #: Set to True to force checking traffic left for premium account
- DIRECT_LINK = None #: Set to True to looking for direct link (as defined in handleDirect method), set to None to do it if self.account is True else False
- MULTI_HOSTER = False #: Set to True to leech other hoster link (as defined in handleMulti method)
- LOGIN_ACCOUNT = False #: Set to True to require account login
+ DIRECT_LINK = None #: Set to True to looking for direct link (as defined in handle_direct method), set to None to do it if self.account is True else False
DISPOSITION = True #: Set to True to use any content-disposition value in http header as file name
+ LOGIN_ACCOUNT = False #: Set to True to require account login
+ LOGIN_PREMIUM = False #: Set to True to require premium account login
+ LEECH_HOSTER = False #: Set to True to leech other hoster link (as defined in handle_multi method)
+ TEXT_ENCODING = True #: Set to encoding name if encoding value in http header is not correct
- directLink = getFileURL #@TODO: Remove in 0.4.10
+ LINK_PATTERN = None
@classmethod
- def apiInfo(cls, url):
- url = urllib.unquote(url)
- url_p = urlparse.urlparse(url)
- return {'name' : (url_p.path.split('/')[-1]
- or url_p.query.split('=', 1)[::-1][0].split('&', 1)[0]
- or url_p.netloc.split('.', 1)[0]),
- 'size' : 0,
- 'status': 3 if url else 8,
- 'url' : url}
+ def api_info(cls, url):
+ return super(SimpleHoster, cls).get_info(url)
@classmethod
- def getInfo(cls, url="", html=""):
- info = cls.apiInfo(url)
- online = True if info['status'] is 2 else False
+ def get_info(cls, url="", html=""):
+ info = cls.api_info(url)
+ online = True if info['status'] == 2 else False
try:
- info['pattern'] = re.match(cls.__pattern__, url).groupdict() #: pattern groups will be saved here
+ info['pattern'] = re.match(cls.__pattern__, url).groupdict() #: Pattern groups will be saved here
except Exception:
info['pattern'] = {}
@@ -347,20 +133,17 @@ class SimpleHoster(Hoster):
info['error'] = "missing url"
info['status'] = 1
- elif info['status'] is 3:
+ elif info['status'] == 3:
try:
- html = getURL(url, cookies=cls.COOKIES, decode=not cls.TEXT_ENCODING)
-
- if isinstance(cls.TEXT_ENCODING, basestring):
- html = unicode(html, cls.TEXT_ENCODING)
+ html = get_url(url, cookies=cls.COOKIES, decode=cls.TEXT_ENCODING)
except BadHeader, e:
info['error'] = "%d: %s" % (e.code, e.content)
- if e.code is 404:
+ if e.code == 404:
info['status'] = 1
- elif e.code is 503:
+ elif e.code == 503:
info['status'] = 6
except Exception:
@@ -392,17 +175,17 @@ class SimpleHoster(Hoster):
info['status'] = 2
if 'N' in info['pattern']:
- info['name'] = replace_patterns(urllib.unquote(info['pattern']['N'].strip()),
+ info['name'] = replace_patterns(fixurl(info['pattern']['N']),
cls.NAME_REPLACEMENTS)
if 'S' in info['pattern']:
size = replace_patterns(info['pattern']['S'] + info['pattern']['U'] if 'U' in info['pattern'] else info['pattern']['S'],
cls.SIZE_REPLACEMENTS)
- info['size'] = parseFileSize(size)
+ info['size'] = parse_size(size)
elif isinstance(info['size'], basestring):
unit = info['units'] if 'units' in info else None
- info['size'] = parseFileSize(info['size'], unit)
+ info['size'] = parse_size(info['size'], unit)
if 'H' in info['pattern']:
hashtype = info['pattern']['T'] if 'T' in info['pattern'] else "hash"
@@ -415,156 +198,155 @@ class SimpleHoster(Hoster):
def setup(self):
- self.resumeDownload = self.multiDL = self.premium
+ self.resume_download = self.multiDL = self.premium
def prepare(self):
- self.pyfile.error = "" #@TODO: Remove in 0.4.10
+ self.pyfile.error = "" #@TODO: Remove in 0.4.10
+ self.html = "" #@TODO: Recheck in 0.4.10
+ self.link = "" #@TODO: Recheck in 0.4.10
+ self.last_download = ""
+ self.direct_dl = False
+ self.leech_dl = False
- self.info = {}
- self.html = ""
- self.link = "" #@TODO: Move to hoster class in 0.4.10
- self.directDL = False #@TODO: Move to hoster class in 0.4.10
- self.multihost = False #@TODO: Move to hoster class in 0.4.10
+ if not self.get_config('use_premium', True):
+ self.restart(nopremium=True)
- if not self.getConfig('use_premium', True):
- self.retryFree()
+ if self.LOGIN_PREMIUM and not self.premium:
+ self.fail(_("Required premium account not found"))
+ self.LOGIN_ACCOUNT = True
if self.LOGIN_ACCOUNT and not self.account:
self.fail(_("Required account not found"))
self.req.setOption("timeout", 120)
- if isinstance(self.COOKIES, list):
- set_cookies(self.req.cj, self.COOKIES)
+ if self.LINK_PATTERN:
+ if not hasattr(self, 'LINK_FREE_PATTERN'):
+ self.LINK_FREE_PATTERN = self.LINK_PATTERN
- if (self.MULTI_HOSTER
- and (self.__pattern__ != self.core.pluginManager.hosterPlugins[self.__name__]['pattern']
- or re.match(self.__pattern__, self.pyfile.url) is None)):
- self.multihost = True
- return
+ if not hasattr(self, 'LINK_PREMIUM_PATTERN'):
+ self.LINK_PREMIUM_PATTERN = self.LINK_PATTERN
+
+ if (self.LEECH_HOSTER
+ and (self.__pattern__ is not self.pyload.pluginManager.hosterPlugins[self.__name__]['pattern']
+ and re.match(self.__pattern__, self.pyfile.url) is None)):
+ self.leech_dl = True
+
+ if self.leech_dl:
+ self.direct_dl = False
- if self.DIRECT_LINK is None:
- self.directDL = bool(self.account)
+ elif self.DIRECT_LINK is None:
+ self.direct_dl = bool(self.account)
else:
- self.directDL = self.DIRECT_LINK
+ self.direct_dl = self.DIRECT_LINK
- self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)
+ if not self.leech_dl:
+ self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS)
def preload(self):
- self.html = self.load(self.pyfile.url, cookies=bool(self.COOKIES), decode=not self.TEXT_ENCODING)
-
- if isinstance(self.TEXT_ENCODING, basestring):
- self.html = unicode(self.html, self.TEXT_ENCODING)
+ self.html = self.load(self.pyfile.url,
+ cookies=self.COOKIES,
+ ref=False,
+ decode=self.TEXT_ENCODING)
def process(self, pyfile):
try:
self.prepare()
- self.checkInfo()
-
- if self.directDL:
- self.logDebug("Looking for direct download link...")
- self.handleDirect(pyfile)
+ self.check_info() #@TODO: Remove in 0.4.10
- if self.multihost and not self.link and not self.lastDownload:
- self.logDebug("Looking for leeched download link...")
- self.handleMulti(pyfile)
+ if self.leech_dl:
+ self.log_info(_("Processing as debrid download..."))
+ self.handle_multi(pyfile)
- if not self.link and not self.lastDownload:
- self.MULTI_HOSTER = False
- self.retry(1, reason="Multi hoster fails")
+ if not self.link and not was_downloaded():
+ self.log_info(_("Failed to leech url"))
- if not self.link and not self.lastDownload:
- self.preload()
- self.checkInfo()
-
- if self.premium and (not self.CHECK_TRAFFIC or self.checkTrafficLeft()):
- self.logDebug("Handled as premium download")
- self.handlePremium(pyfile)
-
- elif not self.LOGIN_ACCOUNT or (not self.CHECK_TRAFFIC or self.checkTrafficLeft()):
- self.logDebug("Handled as free download")
- self.handleFree(pyfile)
-
- self.downloadLink(self.link, self.DISPOSITION)
- self.checkFile()
+ else:
+ if not self.link and self.direct_dl and not self.last_download:
+ self.log_info(_("Looking for direct download link..."))
+ self.handle_direct(pyfile)
- except Fail, e: #@TODO: Move to PluginThread in 0.4.10
- err = str(e) #@TODO: Recheck in 0.4.10
+ if self.link or self.last_download:
+ self.log_info(_("Direct download link detected"))
+ else:
+ self.log_info(_("Direct download link not found"))
- if err == _("No captcha result obtained in appropiate time by any of the plugins."): #@TODO: Fix in 0.4.10
- self.checkFile()
+ if not self.link and not self.last_download:
+ self.preload()
- elif self.getConfig('fallback', True) and self.premium:
- self.logWarning(_("Premium download failed"), e)
- self.retryFree()
+ if 'status' not in self.info or self.info['status'] is 3: #@TODO: Recheck in 0.4.10
+ self.check_info()
- else:
- raise Fail(err)
+ if self.premium and (not self.CHECK_TRAFFIC or self.check_traffic_left()):
+ self.log_info(_("Processing as premium download..."))
+ self.handle_premium(pyfile)
+ elif not self.LOGIN_ACCOUNT or (not self.CHECK_TRAFFIC or self.check_traffic_left()):
+ self.log_info(_("Processing as free download..."))
+ self.handle_free(pyfile)
- def downloadLink(self, link, disposition=True):
- if not link or not isinstance(link, basestring):
- return
+ if not self.last_download:
+ self.log_info(_("Downloading file..."))
+ self.download(self.link, disposition=self.DISPOSITION)
- self.correctCaptcha()
+ self.check_file()
- link = html_unescape(link.strip().decode('unicode-escape')) #@TODO: Move this check to plugin `load` method in 0.4.10
+ except Fail, e: #@TODO: Move to PluginThread in 0.4.10
+ if self.get_config('fallback', True) and self.premium:
+ self.log_warning(_("Premium download failed"), e)
+ self.restart(nopremium=True)
- if not urlparse.urlparse(link).scheme:
- url_p = urlparse.urlparse(self.pyfile.url)
- baseurl = "%s://%s" % (url_p.scheme, url_p.netloc)
- link = urlparse.urljoin(baseurl, link)
+ else:
+ raise Fail(encode(e)) #@TODO: Remove `encode` in 0.4.10
- self.download(link, ref=False, disposition=disposition)
+ def check_file(self):
+ self.log_info(_("Checking file..."))
- def checkFile(self, rules={}):
- if self.cTask and not self.lastDownload:
- self.invalidCaptcha()
+ if self.captcha.task and not self.last_download:
+ self.captcha.invalid()
self.retry(10, reason=_("Wrong captcha"))
- elif not self.lastDownload or not os.path.exists(fs_encode(self.lastDownload)):
- self.lastDownload = ""
- self.error(self.pyfile.error or _("No file downloaded"))
+ # 10485760 is 10MB, tolerance is used when comparing displayed size on the hoster website to real size
+ # For example displayed size can be 1.46GB for example, but real size can be 1.4649853GB
+ elif self.check_download({'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')},
+ file_size=self.info['size'] if 'size' in self.info else 0,
+ size_tolerance=10485760,
+ delete=True):
+ self.error(_("Empty file"))
else:
- errmsg = self.checkDownload({'Empty file': re.compile(r'\A\s*\Z'),
- 'Html error': re.compile(r'\A(?:\s*<.+>)?((?:[\w\s]*(?:[Ee]rror|ERROR)\s*\:?)?\s*\d{3})(?:\Z|\s+)')})
-
- if not errmsg:
- for r, p in [('Html file' , re.compile(r'\A\s*<!DOCTYPE html') ),
- ('Request error', re.compile(r'([Aa]n error occured while processing your request)'))]:
- if r not in rules:
- rules[r] = p
-
- for r, a in [('Error' , "ERROR_PATTERN" ),
- ('Premium only', "PREMIUM_ONLY_PATTERN"),
- ('Wait error' , "WAIT_PATTERN" )]:
- if r not in rules and hasattr(self, a):
- rules[r] = getattr(self, a)
-
- errmsg = self.checkDownload(rules)
+ self.log_debug("Using default check rules...")
+ for r, p in self.FILE_ERRORS:
+ errmsg = self.check_download({r: re.compile(p)})
+ if errmsg is not None:
+ errmsg = errmsg.strip().capitalize()
- if not errmsg:
- return
-
- errmsg = errmsg.strip().capitalize()
+ try:
+ errmsg += " | " + self.last_check.group(1).strip()
+ except Exception:
+ pass
- try:
- errmsg += " | " + self.lastCheck.group(1).strip()
- except Exception:
- pass
+ self.log_warning(_("Check result: ") + errmsg, _("Waiting 1 minute and retry"))
+ self.wantReconnect = True
+ self.retry(wait_time=60, reason=errmsg)
+ else:
+ if self.CHECK_FILE:
+ self.log_debug("Using custom check rules...")
+ with open(fs_encode(self.last_download), "rb") as f:
+ self.html = f.read(1048576) #@TODO: Recheck in 0.4.10
+ self.check_errors()
- self.logWarning("Check result: " + errmsg, "Waiting 1 minute and retry")
- self.retry(3, 60, errmsg)
+ self.log_info(_("No errors found"))
+ self.pyfile.error = ""
- def checkErrors(self):
+ def check_errors(self):
if not self.html:
- self.logWarning(_("No html code to check"))
+ self.log_warning(_("No html code to check"))
return
if hasattr(self, 'IP_BLOCKED_PATTERN') and re.search(self.IP_BLOCKED_PATTERN, self.html):
@@ -577,20 +359,20 @@ class SimpleHoster(Hoster):
elif hasattr(self, 'SIZE_LIMIT_PATTERN') and re.search(self.SIZE_LIMIT_PATTERN, self.html):
self.fail(_("File too large for free download"))
- elif hasattr(self, 'DOWNLOAD_LIMIT_PATTERN') and re.search(self.DOWNLOAD_LIMIT_PATTERN, self.html):
- m = re.search(self.DOWNLOAD_LIMIT_PATTERN, self.html)
+ elif hasattr(self, 'DL_LIMIT_PATTERN') and re.search(self.DL_LIMIT_PATTERN, self.html):
+ m = re.search(self.DL_LIMIT_PATTERN, self.html)
try:
errmsg = m.group(1).strip()
except Exception:
errmsg = m.group(0).strip()
self.info['error'] = re.sub(r'<.*?>', " ", errmsg)
- self.logWarning(self.info['error'])
+ self.log_warning(self.info['error'])
if re.search('da(il)?y|today', errmsg, re.I):
- wait_time = secondsToMidnight(gmt=2)
+ wait_time = seconds_to_midnight(gmt=2)
else:
- wait_time = sum(int(v) * {"hr": 3600, "hour": 3600, "min": 60, "sec": 1, "": 1}[u.lower()] for v, u in
+ wait_time = sum(int(v) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, "": 1}[u.lower()] for v, u in
re.findall(r'(\d+)\s*(hr|hour|min|sec|)', errmsg, re.I))
self.wantReconnect = wait_time > 300
@@ -608,13 +390,13 @@ class SimpleHoster(Hoster):
errmsg = m.group(0).strip()
self.info['error'] = re.sub(r'<.*?>', " ", errmsg)
- self.logWarning(self.info['error'])
+ self.log_warning(self.info['error'])
- if re.search('limit|wait', errmsg, re.I):
+ if re.search('limit|wait|slot', errmsg, re.I):
if re.search("da(il)?y|today", errmsg):
- wait_time = secondsToMidnight(gmt=2)
+ wait_time = seconds_to_midnight(gmt=2)
else:
- wait_time = sum(int(v) * {"hr": 3600, "hour": 3600, "min": 60, "sec": 1, "": 1}[u.lower()] for v, u in
+ wait_time = sum(int(v) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, "": 1}[u.lower()] for v, u in
re.findall(r'(\d+)\s*(hr|hour|min|sec|)', errmsg, re.I))
self.wantReconnect = wait_time > 300
@@ -624,20 +406,26 @@ class SimpleHoster(Hoster):
self.fail(_("Connection from your current IP address is not allowed"))
elif re.search('captcha|code', errmsg, re.I):
- self.invalidCaptcha()
+ self.captcha.invalid()
+ self.retry(10, reason=_("Wrong captcha"))
elif re.search('countdown|expired', errmsg, re.I):
- self.retry(wait_time=60, reason=_("Link expired"))
+ self.retry(10, 60, _("Link expired"))
elif re.search('maintenance|maintainance|temp', errmsg, re.I):
- self.tempOffline()
+ self.temp_offline()
- elif re.search('up to', errmsg, re.I):
+ elif re.search('up to|size', errmsg, re.I):
self.fail(_("File too large for free download"))
- elif re.search('offline|delet|remov|not (found|available)', errmsg, re.I):
+ elif re.search('offline|delet|remov|not? (found|(longer)? available)', errmsg, re.I):
self.offline()
+ elif re.search('filename', errmsg, re.I):
+ url_p = urlparse.urlparse(self.pyfile.url)
+ self.pyfile.url = "%s://%s/%s" % (url_p.scheme, url_p.netloc, url_p.path.split('/')[0])
+ self.retry(1, reason=_("Wrong url"))
+
elif re.search('premium', errmsg, re.I):
self.fail(_("File can be downloaded by premium users only"))
@@ -653,98 +441,102 @@ class SimpleHoster(Hoster):
except Exception:
waitmsg = m.group(0).strip()
- wait_time = sum(int(v) * {"hr": 3600, "hour": 3600, "min": 60, "sec": 1, "": 1}[u.lower()] for v, u in
+ wait_time = sum(int(v) * {'hr': 3600, 'hour': 3600, 'min': 60, 'sec': 1, "": 1}[u.lower()] for v, u in
re.findall(r'(\d+)\s*(hr|hour|min|sec|)', waitmsg, re.I))
self.wait(wait_time, wait_time > 300)
self.info.pop('error', None)
- def checkStatus(self, getinfo=True):
+ def check_status(self, getinfo=True):
if not self.info or getinfo:
- self.logDebug("Update file info...")
- self.logDebug("Previous file info: %s" % self.info)
- self.info.update(self.getInfo(self.pyfile.url, self.html))
- self.logDebug("Current file info: %s" % self.info)
+ self.log_info(_("Updating file info..."))
+ old_info = self.info.copy()
+ self.info.update(self.get_info(self.pyfile.url, self.html))
+ self.log_debug("File info: %s" % self.info)
+ self.log_debug("Previous file info: %s" % old_info)
try:
- status = self.info['status']
+ status = self.info['status'] or None
- if status is 1:
+ if status == 1:
self.offline()
- elif status is 6:
- self.tempOffline()
+ elif status == 6:
+ self.temp_offline()
- elif status is 8:
- self.fail(self.info['error'] if 'error' in self.info else _("Failed"))
+ elif status == 8:
+ if 'error' in self.info:
+ self.fail(self.info['error'])
+ else:
+ self.fail(_("File status: " + statusMap[status]))
finally:
- self.logDebug("File status: %s" % statusMap[status])
+ self.log_info(_("File status: ") + (statusMap[status] if status else _("Unknown")))
- def checkNameSize(self, getinfo=True):
+ def check_name_size(self, getinfo=True):
if not self.info or getinfo:
- self.logDebug("Update file info...")
- self.logDebug("Previous file info: %s" % self.info)
- self.info.update(self.getInfo(self.pyfile.url, self.html))
- self.logDebug("Current file info: %s" % self.info)
+ self.log_info(_("Updating file info..."))
+ old_info = self.info.copy()
+ self.info.update(self.get_info(self.pyfile.url, self.html))
+ self.log_debug("File info: %s" % self.info)
+ self.log_debug("Previous file info: %s" % old_info)
try:
url = self.info['url'].strip()
name = self.info['name'].strip()
- if name and name != url:
- self.pyfile.name = name
- except Exception:
+ except KeyError:
pass
- try:
- size = self.info['size']
- if size > 0:
- self.pyfile.size = size
+ else:
+ if name and name is not url:
+ self.pyfile.name = name
- except Exception:
- pass
+ if 'size' in self.info and self.info['size'] > 0:
+ self.pyfile.size = int(self.info['size']) #@TODO: Fix int conversion in 0.4.10
+
+ # self.pyfile.sync()
+
+ name = self.pyfile.name
+ size = self.pyfile.size
+ folder = self.info['folder'] = name
- self.logDebug("File name: %s" % self.pyfile.name,
- "File size: %s byte" % self.pyfile.size if self.pyfile.size > 0 else "File size: Unknown")
+ self.log_info(_("File name: ") + name)
+ self.log_info(_("File size: %s bytes") % size if size > 0 else _("File size: Unknown"))
+ # self.log_info("File folder: " + folder)
- def checkInfo(self):
- self.checkNameSize()
+ #@TODO: Rewrite in 0.4.10
+ def check_info(self):
+ self.check_name_size()
if self.html:
- self.checkErrors()
- self.checkNameSize()
+ self.check_errors()
+ self.check_name_size()
- self.checkStatus(getinfo=False)
+ self.check_status(getinfo=False)
- #: Deprecated
- def getFileInfo(self):
+ #: Deprecated method (Remove in 0.4.10)
+ def get_fileInfo(self):
self.info = {}
- self.checkInfo()
+ self.check_info()
return self.info
- def handleDirect(self, pyfile):
- link = self.directLink(pyfile.url, self.resumeDownload)
-
- if link:
- self.logInfo(_("Direct download link detected"))
- self.link = link
- else:
- self.logDebug("Direct download link not found")
+ def handle_direct(self, pyfile):
+ self.link = self.direct_link(pyfile.url, self.resume_download)
- def handleMulti(self, pyfile): #: Multi-hoster handler
+ def handle_multi(self, pyfile): #: Multi-hoster handler
pass
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
if not hasattr(self, 'LINK_FREE_PATTERN'):
- self.logError(_("Free download not implemented"))
+ self.log_error(_("Free download not implemented"))
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m is None:
@@ -753,77 +545,14 @@ class SimpleHoster(Hoster):
self.link = m.group(1)
- def handlePremium(self, pyfile):
+ def handle_premium(self, pyfile):
if not hasattr(self, 'LINK_PREMIUM_PATTERN'):
- self.logError(_("Premium download not implemented"))
- self.logDebug("Handled as free download")
- self.handleFree(pyfile)
+ self.log_error(_("Premium download not implemented"))
+ self.log_info(_("Processing as free download..."))
+ self.handle_free(pyfile)
m = re.search(self.LINK_PREMIUM_PATTERN, self.html)
if m is None:
self.error(_("Premium download link not found"))
else:
self.link = m.group(1)
-
-
- def longWait(self, wait_time=None, max_tries=3):
- if wait_time and isinstance(wait_time, (int, long, float)):
- time_str = "%dh %dm" % divmod(wait_time / 60, 60)
- else:
- wait_time = 900
- time_str = _("(unknown time)")
- max_tries = 100
-
- self.logInfo(_("Download limit reached, reconnect or wait %s") % time_str)
-
- self.wait(wait_time, True)
- self.retry(max_tries=max_tries, reason=_("Download limit reached"))
-
-
- def parseHtmlForm(self, attr_str="", input_names={}):
- return parseHtmlForm(attr_str, self.html, input_names)
-
-
- def checkTrafficLeft(self):
- if not self.account:
- return True
-
- traffic = self.account.getAccountInfo(self.user, True)['trafficleft']
-
- if traffic is None:
- return False
- elif traffic == -1:
- return True
- else:
- size = self.pyfile.size / 1024
- self.logInfo(_("Filesize: %i KiB, Traffic left for user %s: %i KiB") % (size, self.user, traffic))
- return size <= traffic
-
-
- #@TODO: Remove in 0.4.10
- def getConfig(self, option, default=''):
- """getConfig with default value - sublass may not implements all config options"""
- try:
- return self.getConf(option)
-
- except KeyError:
- return default
-
-
- def retryFree(self):
- if not self.premium:
- return
- self.premium = False
- self.account = None
- self.req = self.core.requestFactory.getRequest(self.__name__)
- self.retries = -1
- raise Retry(_("Fallback to free download"))
-
-
- #@TODO: Remove in 0.4.10
- def wait(self, seconds=0, reconnect=None):
- return _wait(self, seconds, reconnect)
-
-
- def error(self, reason="", type="parse"):
- return _error(self, reason, type)
diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py
index 5b9f2e1c3..0386991d9 100644
--- a/module/plugins/internal/UnRar.py
+++ b/module/plugins/internal/UnRar.py
@@ -8,7 +8,7 @@ from glob import glob
from string import digits
from module.plugins.internal.Extractor import Extractor, ArchiveError, CRCError, PasswordError
-from module.utils import fs_decode, fs_encode, save_join
+from module.utils import fs_decode, fs_encode, save_join as fs_join
def renice(pid, value):
@@ -22,7 +22,8 @@ def renice(pid, value):
class UnRar(Extractor):
__name__ = "UnRar"
- __version__ = "1.20"
+ __version__ = "1.25"
+ __status__ = "testing"
__description__ = """Rar extractor plugin"""
__license__ = "GPLv3"
@@ -31,12 +32,10 @@ class UnRar(Extractor):
("Immenz" , "immenz@gmx.net" )]
- CMD = "unrar"
- VERSION = ""
+ CMD = "unrar"
EXTENSIONS = [".rar"]
-
- re_multipart = re.compile(r'\.(part|r)(\d+)(?:\.rar)?(\.rev|\.bad)?',re.I)
+ re_multipart = re.compile(r'\.(part|r)(\d+)(?:\.rar)?(\.rev|\.bad)?', re.I)
re_filefixed = re.compile(r'Building (.+)')
re_filelist = re.compile(r'^(.)(\s*[\w\.\-]+)\s+(\d+\s+)+(?:\d+\%\s+)?[\d\-]{8}\s+[\d\:]{5}', re.M|re.I)
@@ -48,38 +47,40 @@ class UnRar(Extractor):
@classmethod
- def isUsable(cls):
- if os.name == "nt":
- try:
+ def find(cls):
+ try:
+ if os.name == "nt":
cls.CMD = os.path.join(pypath, "RAR.exe")
- p = subprocess.Popen([cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
- cls.__name__ = "RAR"
- cls.REPAIR = True
+ else:
+ cls.CMD = "rar"
- except OSError:
- cls.CMD = os.path.join(pypath, "UnRAR.exe")
- p = subprocess.Popen([cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
- else:
+ p = subprocess.Popen([cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ # cls.__name__ = "RAR"
+ cls.REPAIR = True
+
+ except OSError:
try:
- p = subprocess.Popen(["rar"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
- cls.__name__ = "RAR"
- cls.REPAIR = True
+ if os.name == "nt":
+ cls.CMD = os.path.join(pypath, "UnRAR.exe")
+ else:
+ cls.CMD = "unrar"
- except OSError: #: fallback to unrar
p = subprocess.Popen([cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
+ except OSError:
+ return False
+
m = cls.re_version.search(out)
- cls.VERSION = m.group(1) if m else '(version unknown)'
+ if m is not None:
+ cls.VERSION = m.group(1)
return True
@classmethod
- def isMultipart(cls, filename):
+ def is_multipart(cls, filename):
return True if cls.re_multipart.search(filename) else False
@@ -105,7 +106,7 @@ class UnRar(Extractor):
if self.re_wrongcrc.search(err):
raise CRCError(err)
- # output only used to check if passworded files are present
+ #: Output only used to check if passworded files are present
for attr in self.re_filelist.findall(out):
if attr[0].startswith("*"):
raise PasswordError
@@ -114,7 +115,7 @@ class UnRar(Extractor):
def repair(self):
p = self.call_cmd("rc", fs_encode(self.filename))
- # communicate and retrieve stderr
+ #: Communicate and retrieve stderr
self._progress(p)
err = p.stderr.read().strip()
if err or p.returncode:
@@ -126,17 +127,17 @@ class UnRar(Extractor):
s = ""
while True:
c = process.stdout.read(1)
- # quit loop on eof
+ #: Quit loop on eof
if not c:
break
- # reading a percentage sign -> set progress and restart
- if c == '%':
- self.notifyProgress(int(s))
+ #: Reading a percentage sign -> set progress and restart
+ if c == "%":
+ self.notify_progress(int(s))
s = ""
- # not reading a digit -> therefore restart
+ #: Not reading a digit -> therefore restart
elif c not in digits:
s = ""
- # add digit to progressstring
+ #: Add digit to progressstring
else:
s += c
@@ -148,7 +149,7 @@ class UnRar(Extractor):
renice(p.pid, self.renice)
- # communicate and retrieve stderr
+ #: Communicate and retrieve stderr
self._progress(p)
err = p.stderr.read().strip()
@@ -159,7 +160,7 @@ class UnRar(Extractor):
elif self.re_wrongcrc.search(err):
raise CRCError(err)
- else: #: raise error if anything is on stderr
+ else: #: Raise error if anything is on stderr
raise ArchiveError(err)
if p.returncode:
@@ -168,15 +169,15 @@ class UnRar(Extractor):
self.files = self.list(password)
- def getDeleteFiles(self):
+ def get_delete_files(self):
dir, name = os.path.split(self.filename)
- # actually extracted file
+ #: Actually extracted file
files = [self.filename]
- # eventually Multipart Files
- files.extend(save_join(dir, os.path.basename(file)) for file in filter(self.isMultipart, os.listdir(dir))
- if re.sub(self.re_multipart,".rar",name) == re.sub(self.re_multipart,".rar",file))
+ #: eventually Multipart Files
+ files.extend(fs_join(dir, os.path.basename(file)) for file in filter(self.is_multipart, os.listdir(dir))
+ if re.sub(self.re_multipart, ".rar", name) == re.sub(self.re_multipart, ".rar", file))
return files
@@ -190,20 +191,19 @@ class UnRar(Extractor):
if "Cannot open" in err:
raise ArchiveError(_("Cannot open file"))
- if err.strip(): #: only log error at this point
- self.manager.logError(err.strip())
+ if err.strip(): #: Only log error at this point
+ self.log_error(err.strip())
result = set()
if not self.fullpath and self.VERSION.startswith('5'):
- # NOTE: Unrar 5 always list full path
+ #@NOTE: Unrar 5 always list full path
for f in fs_decode(out).splitlines():
- f = save_join(self.out, os.path.basename(f.strip()))
+ f = fs_join(self.out, os.path.basename(f.strip()))
if os.path.isfile(f):
- result.add(save_join(self.out, os.path.basename(f)))
+ result.add(fs_join(self.out, os.path.basename(f)))
else:
for f in fs_decode(out).splitlines():
- f = f.strip()
- result.add(save_join(self.out, f))
+ result.add(fs_join(self.out, f.strip()))
return list(result)
@@ -211,7 +211,7 @@ class UnRar(Extractor):
def call_cmd(self, command, *xargs, **kwargs):
args = []
- # overwrite flag
+ #: Overwrite flag
if self.overwrite:
args.append("-o+")
else:
@@ -222,10 +222,10 @@ class UnRar(Extractor):
for word in self.excludefiles:
args.append("-x'%s'" % word.strip())
- # assume yes on all queries
+ #: Assume yes on all queries
args.append("-y")
- # set a password
+ #: Set a password
if "password" in kwargs and kwargs['password']:
args.append("-p%s" % kwargs['password'])
else:
@@ -234,10 +234,10 @@ class UnRar(Extractor):
if self.keepbroken:
args.append("-kb")
- # NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue
+ #@NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue
call = [self.CMD, command] + args + list(xargs)
- self.manager.logDebug(" ".join(call))
+ self.log_debug(" ".join(call))
p = subprocess.Popen(call, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p
diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py
index 8d3fec370..9a01611bf 100644
--- a/module/plugins/internal/UnZip.py
+++ b/module/plugins/internal/UnZip.py
@@ -12,19 +12,20 @@ from module.utils import fs_encode
class UnZip(Extractor):
__name__ = "UnZip"
- __version__ = "1.12"
+ __version__ = "1.15"
+ __status__ = "testing"
__description__ = """Zip extractor plugin"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ VERSION = "%s.%s.%s" % (sys.version_info[0], sys.version_info[1], sys.version_info[2])
EXTENSIONS = [".zip", ".zip64"]
- VERSION ="(python %s.%s.%s)" % (sys.version_info[0], sys.version_info[1], sys.version_info[2])
@classmethod
- def isUsable(cls):
+ def find(cls):
return sys.version_info[:2] >= (2, 6)
diff --git a/module/plugins/internal/XFSAccount.py b/module/plugins/internal/XFSAccount.py
index e619cb038..e0f6b1ee8 100644
--- a/module/plugins/internal/XFSAccount.py
+++ b/module/plugins/internal/XFSAccount.py
@@ -4,14 +4,15 @@ import re
import time
import urlparse
-from module.plugins.Account import Account
-from module.plugins.internal.SimpleHoster import parseHtmlForm, set_cookies
+from module.plugins.internal.Account import Account
+from module.plugins.internal.Plugin import parse_html_form, set_cookie
class XFSAccount(Account):
__name__ = "XFSAccount"
__type__ = "account"
- __version__ = "0.37"
+ __version__ = "0.42"
+ __status__ = "testing"
__description__ = """XFileSharing account plugin"""
__license__ = "GPLv3"
@@ -30,34 +31,15 @@ class XFSAccount(Account):
VALID_UNTIL_PATTERN = r'Premium.[Aa]ccount expire:.*?(\d{1,2} [\w^_]+ \d{4})'
TRAFFIC_LEFT_PATTERN = r'Traffic available today:.*?<b>\s*(?P<S>[\d.,]+|[Uu]nlimited)\s*(?:(?P<U>[\w^_]+)\s*)?</b>'
- TRAFFIC_LEFT_UNIT = "MB" #: used only if no group <U> was found
+ TRAFFIC_LEFT_UNIT = "MB" #: Used only if no group <U> was found
LEECH_TRAFFIC_PATTERN = r'Leech Traffic left:<b>.*?(?P<S>[\d.,]+|[Uu]nlimited)\s*(?:(?P<U>[\w^_]+)\s*)?</b>'
- LEECH_TRAFFIC_UNIT = "MB" #: used only if no group <U> was found
+ LEECH_TRAFFIC_UNIT = "MB" #: Used only if no group <U> was found
LOGIN_FAIL_PATTERN = r'Incorrect Login or Password|account was banned|Error<'
- def __init__(self, manager, accounts): #@TODO: remove in 0.4.10
- self.init()
- return super(XFSAccount, self).__init__(manager, accounts)
-
-
- def init(self):
- if not self.HOSTER_DOMAIN:
- self.logError(_("Missing HOSTER_DOMAIN"))
- self.COOKIES = False
-
- else:
- if not self.HOSTER_URL:
- self.HOSTER_URL = "http://www.%s/" % self.HOSTER_DOMAIN
-
- if isinstance(self.COOKIES, list):
- self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
- set_cookies(req.cj, self.COOKIES)
-
-
- def loadAccountInfo(self, user, req):
+ def parse_info(self, user, password, data, req):
validuntil = None
trafficleft = None
leechtraffic = None
@@ -69,32 +51,34 @@ class XFSAccount(Account):
'leechtraffic': leechtraffic,
'premium' : premium}
- html = req.load(self.HOSTER_URL, get={'op': "my_account"}, decode=True)
+ html = self.load(self.HOSTER_URL,
+ get={'op': "my_account"},
+ cookies=self.COOKIES)
premium = True if re.search(self.PREMIUM_PATTERN, html) else False
m = re.search(self.VALID_UNTIL_PATTERN, html)
if m:
expiredate = m.group(1).strip()
- self.logDebug("Expire date: " + expiredate)
+ self.log_debug("Expire date: " + expiredate)
try:
validuntil = time.mktime(time.strptime(expiredate, "%d %B %Y"))
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
- self.logDebug("Valid until: %s" % validuntil)
+ self.log_debug("Valid until: %s" % validuntil)
if validuntil > time.mktime(time.gmtime()):
premium = True
trafficleft = -1
else:
premium = False
- validuntil = None #: registered account type (not premium)
+ validuntil = None #: Registered account type (not premium)
else:
- self.logDebug("VALID_UNTIL_PATTERN not found")
+ self.log_debug("VALID_UNTIL_PATTERN not found")
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
if m:
@@ -114,12 +98,12 @@ class XFSAccount(Account):
else:
unit = ""
- trafficleft = self.parseTraffic(size + unit)
+ trafficleft = self.parse_traffic(size + unit)
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
- self.logDebug("TRAFFIC_LEFT_PATTERN not found")
+ self.log_debug("TRAFFIC_LEFT_PATTERN not found")
leech = [m.groupdict() for m in re.finditer(self.LEECH_TRAFFIC_PATTERN, html)]
if leech:
@@ -141,12 +125,12 @@ class XFSAccount(Account):
else:
unit = ""
- leechtraffic += self.parseTraffic(size + unit)
+ leechtraffic += self.parse_traffic(size + unit)
except Exception, e:
- self.logError(e)
+ self.log_error(e)
else:
- self.logDebug("LEECH_TRAFFIC_PATTERN not found")
+ self.log_debug("LEECH_TRAFFIC_PATTERN not found")
return {'validuntil' : validuntil,
'trafficleft' : trafficleft,
@@ -154,28 +138,39 @@ class XFSAccount(Account):
'premium' : premium}
- def login(self, user, data, req):
- if not self.HOSTER_URL: #@TODO: Remove in 0.4.10
- raise Exception(_("Missing HOSTER_DOMAIN"))
+ def login(self, user, password, data, req):
+ if self.HOSTER_DOMAIN:
+ if not self.HOSTER_URL:
+ self.HOSTER_URL = "http://www.%s/" % self.HOSTER_DOMAIN
+
+ if self.COOKIES:
+ if isinstance(self.COOKIES, list) and not self.COOKIES.count((self.HOSTER_DOMAIN, "lang", "english")):
+ self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+ else:
+ set_cookie(self.req.cj, self.HOSTER_DOMAIN, "lang", "english")
+
+ if not self.HOSTER_URL:
+ self.login_fail(_("Missing HOSTER_URL"))
if not self.LOGIN_URL:
self.LOGIN_URL = urlparse.urljoin(self.HOSTER_URL, "login.html")
- html = req.load(self.LOGIN_URL, decode=True)
- action, inputs = parseHtmlForm('name="FL"', html)
+ html = self.load(self.LOGIN_URL, cookies=self.COOKIES)
+
+ action, inputs = parse_html_form('name="FL"', html)
if not inputs:
inputs = {'op' : "login",
'redirect': self.HOSTER_URL}
inputs.update({'login' : user,
- 'password': data['password']})
+ 'password': password})
if action:
url = urlparse.urljoin("http://", action)
else:
url = self.HOSTER_URL
- html = req.load(url, post=inputs, decode=True)
+ html = self.load(url, post=inputs, cookies=self.COOKIES)
if re.search(self.LOGIN_FAIL_PATTERN, html):
- self.wrongPassword()
+ self.login_fail()
diff --git a/module/plugins/internal/XFSCrypter.py b/module/plugins/internal/XFSCrypter.py
index 80eff53ea..4c059d647 100644
--- a/module/plugins/internal/XFSCrypter.py
+++ b/module/plugins/internal/XFSCrypter.py
@@ -1,12 +1,14 @@
# -*- coding: utf-8 -*-
+from module.plugins.internal.Plugin import set_cookie
from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo
class XFSCrypter(SimpleCrypter):
__name__ = "XFSCrypter"
__type__ = "crypter"
- __version__ = "0.09"
+ __version__ = "0.13"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
@@ -19,10 +21,10 @@ class XFSCrypter(SimpleCrypter):
URL_REPLACEMENTS = [(r'&?per_page=\d+', ""), (r'[?/&]+$', ""), (r'(.+/[^?]+)$', r'\1?'), (r'$', r'&per_page=10000')]
- LINK_PATTERN = r'<(?:td|TD).*?>\s*(?:<.+>\s*)?<a href="(.+?)".*?>.+?(?:</a>)?\s*(?:<.+>\s*)?</(?:td|TD)>'
NAME_PATTERN = r'<[Tt]itle>.*?\: (?P<N>.+) folder</[Tt]itle>'
+ LINK_PATTERN = r'<(?:td|TD).*?>\s*(?:<.+>\s*)?<a href="(.+?)".*?>.+?(?:</a>)?\s*(?:<.+>\s*)?</(?:td|TD)>'
- OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed)'
+ OFFLINE_PATTERN = r'>\s*(No such user|\w+ (Not Found|file (was|has been) removed|no longer available)'
TEMP_OFFLINE_PATTERN = r'>\s*\w+ server (is in )?(maintenance|maintainance)'
@@ -32,14 +34,17 @@ class XFSCrypter(SimpleCrypter):
account = self.account
else:
account_name = (self.__name__ + ".py").replace("Folder.py", "").replace(".py", "")
- account = self.pyfile.m.core.accountManager.getAccountPlugin(account_name)
+ account = self.pyload.accountManager.getAccountPlugin(account_name)
if account and hasattr(account, "HOSTER_DOMAIN") and account.HOSTER_DOMAIN:
self.HOSTER_DOMAIN = account.HOSTER_DOMAIN
else:
self.fail(_("Missing HOSTER_DOMAIN"))
- if isinstance(self.COOKIES, list):
- self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+ if self.COOKIES:
+ if isinstance(self.COOKIES, list) and not self.COOKIES.count((self.HOSTER_DOMAIN, "lang", "english")):
+ self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+ else:
+ set_cookie(self.req.cj, self.HOSTER_DOMAIN, "lang", "english")
return super(XFSCrypter, self).prepare()
diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py
index 34e319500..5e0830dc6 100644
--- a/module/plugins/internal/XFSHoster.py
+++ b/module/plugins/internal/XFSHoster.py
@@ -3,18 +3,19 @@
import pycurl
import random
import re
-import urlparse
-from module.plugins.internal.ReCaptcha import ReCaptcha
-from module.plugins.internal.SolveMedia import SolveMedia
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight
+from module.plugins.captcha.ReCaptcha import ReCaptcha
+from module.plugins.captcha.SolveMedia import SolveMedia
+from module.plugins.internal.Plugin import set_cookie
+from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, seconds_to_midnight
from module.utils import html_unescape
class XFSHoster(SimpleHoster):
__name__ = "XFSHoster"
__type__ = "hoster"
- __version__ = "0.52"
+ __version__ = "0.57"
+ __status__ = "testing"
__pattern__ = r'^unmatchable$'
@@ -27,14 +28,12 @@ class XFSHoster(SimpleHoster):
HOSTER_DOMAIN = None
- TEXT_ENCODING = False
- DIRECT_LINK = None
- MULTI_HOSTER = True #@NOTE: Should be default to False for safe, but I'm lazy...
+ LEECH_HOSTER = True #@NOTE: Should be default to False for safe, but I'm lazy...
NAME_PATTERN = r'(Filename[ ]*:[ ]*</b>(</td><td nowrap>)?|name="fname"[ ]+value="|<[\w^_]+ class="(file)?name">)\s*(?P<N>.+?)(\s*<|")'
SIZE_PATTERN = r'(Size[ ]*:[ ]*</b>(</td><td>)?|File:.*>|</font>\s*\(|<[\w^_]+ class="size">)\s*(?P<S>[\d.,]+)\s*(?P<U>[\w^_]+)'
- OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed)'
+ OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed|no longer available)'
TEMP_OFFLINE_PATTERN = r'>\s*\w+ server (is in )?(maintenance|maintainance)'
WAIT_PATTERN = r'<span id="countdown_str".*>(\d+)</span>|id="countdown" value=".*?(\d+).*?"'
@@ -43,7 +42,6 @@ class XFSHoster(SimpleHoster):
ERROR_PATTERN = r'(?:class=["\']err["\'].*?>|<[Cc]enter><b>|>Error</td>|>\(ERROR:)(?:\s*<.+?>\s*)*(.+?)(?:["\']|<|\))'
LINK_LEECH_PATTERN = r'<h2>Download Link</h2>\s*<textarea[^>]*>([^<]+)'
- LINK_PATTERN = None #: final download url pattern
CAPTCHA_PATTERN = r'(https?://[^"\']+?/captchas?/[^"\']+)'
CAPTCHA_BLOCK_PATTERN = r'>Enter code.*?<div.*?>(.+?)</div>'
@@ -51,29 +49,34 @@ class XFSHoster(SimpleHoster):
SOLVEMEDIA_PATTERN = None
FORM_PATTERN = None
- FORM_INPUTS_MAP = None #: dict passed as input_names to parseHtmlForm
+ FORM_INPUTS_MAP = None #: Dict passed as input_names to parse_html_form
def setup(self):
- self.chunkLimit = -1 if self.premium else 1
- self.resumeDownload = self.multiDL = self.premium
+ self.chunk_limit = -1 if self.premium else 1
+ self.resume_download = self.multiDL = self.premium
def prepare(self):
- """ Initialize important variables """
+ """
+ Initialize important variables
+ """
if not self.HOSTER_DOMAIN:
if self.account:
account = self.account
else:
- account = self.pyfile.m.core.accountManager.getAccountPlugin(self.__name__)
+ account = self.pyload.accountManager.getAccountPlugin(self.__name__)
if account and hasattr(account, "HOSTER_DOMAIN") and account.HOSTER_DOMAIN:
self.HOSTER_DOMAIN = account.HOSTER_DOMAIN
else:
self.fail(_("Missing HOSTER_DOMAIN"))
- if isinstance(self.COOKIES, list):
- self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+ if self.COOKIES:
+ if isinstance(self.COOKIES, list) and not self.COOKIES.count((self.HOSTER_DOMAIN, "lang", "english")):
+ self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english"))
+ else:
+ set_cookie(self.req.cj, self.HOSTER_DOMAIN, "lang", "english")
if not self.LINK_PATTERN:
pattern = r'(?:file: "(.+?)"|(https?://(?:www\.)?([^/]*?%s|\d+\.\d+\.\d+\.\d+)(\:\d+)?(/d/|(/files)?/\d+/\w+/).+?)["\'<])'
@@ -82,24 +85,24 @@ class XFSHoster(SimpleHoster):
super(XFSHoster, self).prepare()
if self.DIRECT_LINK is None:
- self.directDL = self.premium
+ self.direct_dl = self.premium
- def handleFree(self, pyfile):
+ def handle_free(self, pyfile):
for i in xrange(1, 6):
- self.logDebug("Getting download link #%d" % i)
+ self.log_debug("Getting download link #%d" % i)
- self.checkErrors()
+ self.check_errors()
m = re.search(self.LINK_PATTERN, self.html, re.S)
if m:
break
- data = self.getPostParameters()
+ data = self.get_post_parameters()
self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 0)
- self.html = self.load(pyfile.url, post=data, decode=True)
+ self.html = self.load(pyfile.url, post=data)
self.req.http.c.setopt(pycurl.FOLLOWLOCATION, 1)
@@ -111,24 +114,24 @@ class XFSHoster(SimpleHoster):
if m:
break
else:
- self.logError(data['op'] if 'op' in data else _("UNKNOWN"))
- return ""
+ if 'op' in data:
+ self.error(_("Missing OP data after: ") + data['op'])
- self.link = m.group(1).strip() #@TODO: Remove .strip() in 0.4.10
+ self.link = m.group(1)
- def handlePremium(self, pyfile):
- return self.handleFree(pyfile)
+ def handle_premium(self, pyfile):
+ return self.handle_free(pyfile)
- def handleMulti(self, pyfile):
+ def handle_multi(self, pyfile):
if not self.account:
self.fail(_("Only registered or premium users can use url leech feature"))
- #only tested with easybytez.com
+ #: Only tested with easybytez.com
self.html = self.load("http://www.%s/" % self.HOSTER_DOMAIN)
- action, inputs = self.parseHtmlForm()
+ action, inputs = self.parse_html_form()
upload_id = "%012d" % int(random.random() * 10 ** 12)
action += upload_id + "&js_on=1&utype=prem&upload_type=url"
@@ -137,19 +140,19 @@ class XFSHoster(SimpleHoster):
inputs['url_mass'] = pyfile.url
inputs['up1oad_type'] = 'url'
- self.logDebug(action, inputs)
+ self.log_debug(action, inputs)
- self.req.setOption("timeout", 600) #: wait for file to upload to easybytez.com
+ self.req.setOption("timeout", 600) #: Wait for file to upload to easybytez.com
self.html = self.load(action, post=inputs)
- self.checkErrors()
+ self.check_errors()
- action, inputs = self.parseHtmlForm('F1')
+ action, inputs = self.parse_html_form('F1')
if not inputs:
self.retry(reason=self.info['error'] if 'error' in self.info else _("TEXTAREA F1 not found"))
- self.logDebug(inputs)
+ self.log_debug(inputs)
stmsg = inputs['st']
@@ -160,38 +163,38 @@ class XFSHoster(SimpleHoster):
self.retry(20, 3 * 60, _("Can not leech file"))
elif 'today' in stmsg:
- self.retry(wait_time=secondsToMidnight(gmt=2), reason=_("You've used all Leech traffic today"))
+ self.retry(wait_time=seconds_to_midnight(gmt=2), reason=_("You've used all Leech traffic today"))
else:
self.fail(stmsg)
- #get easybytez.com link for uploaded file
+ #: Get easybytez.com link for uploaded file
m = re.search(self.LINK_LEECH_PATTERN, self.html)
if m is None:
self.error(_("LINK_LEECH_PATTERN not found"))
- header = self.load(m.group(1), just_header=True, decode=True)
+ header = self.load(m.group(1), just_header=True)
if 'location' in header: #: Direct download link
self.link = header['location']
- def getPostParameters(self):
+ def get_post_parameters(self):
if self.FORM_PATTERN or self.FORM_INPUTS_MAP:
- action, inputs = self.parseHtmlForm(self.FORM_PATTERN or "", self.FORM_INPUTS_MAP or {})
+ action, inputs = self.parse_html_form(self.FORM_PATTERN or "", self.FORM_INPUTS_MAP or {})
else:
- action, inputs = self.parseHtmlForm(input_names={'op': re.compile(r'^download')})
+ action, inputs = self.parse_html_form(input_names={'op': re.compile(r'^download')})
if not inputs:
- action, inputs = self.parseHtmlForm('F1')
+ action, inputs = self.parse_html_form('F1')
if not inputs:
self.retry(reason=self.info['error'] if 'error' in self.info else _("TEXTAREA F1 not found"))
- self.logDebug(inputs)
+ self.log_debug(inputs)
if 'op' in inputs:
if "password" in inputs:
- password = self.getPassword()
+ password = self.get_password()
if password:
inputs['password'] = password
else:
@@ -201,9 +204,9 @@ class XFSHoster(SimpleHoster):
m = re.search(self.WAIT_PATTERN, self.html)
if m:
wait_time = int(m.group(1))
- self.setWait(wait_time, False)
+ self.set_wait(wait_time, False)
- self.handleCaptcha(inputs)
+ self.handle_captcha(inputs)
self.wait()
else:
inputs['referer'] = self.pyfile.url
@@ -218,11 +221,11 @@ class XFSHoster(SimpleHoster):
return inputs
- def handleCaptcha(self, inputs):
+ def handle_captcha(self, inputs):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
captcha_url = m.group(1)
- inputs['code'] = self.decryptCaptcha(captcha_url)
+ inputs['code'] = self.captcha.decrypt(captcha_url)
return
m = re.search(self.CAPTCHA_BLOCK_PATTERN, self.html, re.S)
@@ -230,11 +233,11 @@ class XFSHoster(SimpleHoster):
captcha_div = m.group(1)
numerals = re.findall(r'<span.*?padding-left\s*:\s*(\d+).*?>(\d)</span>', html_unescape(captcha_div))
- self.logDebug(captcha_div)
+ self.log_debug(captcha_div)
inputs['code'] = "".join(a[1] for a in sorted(numerals, key=lambda num: int(num[0])))
- self.logDebug("Captcha code: %s" % inputs['code'], numerals)
+ self.log_debug("Captcha code: %s" % inputs['code'], numerals)
return
recaptcha = ReCaptcha(self)
@@ -245,7 +248,7 @@ class XFSHoster(SimpleHoster):
captcha_key = recaptcha.detect_key()
else:
- self.logDebug("ReCaptcha key: %s" % captcha_key)
+ self.log_debug("ReCaptcha key: %s" % captcha_key)
if captcha_key:
inputs['recaptcha_response_field'], inputs['recaptcha_challenge_field'] = recaptcha.challenge(captcha_key)
@@ -259,7 +262,7 @@ class XFSHoster(SimpleHoster):
captcha_key = solvemedia.detect_key()
else:
- self.logDebug("SolveMedia key: %s" % captcha_key)
+ self.log_debug("SolveMedia key: %s" % captcha_key)
if captcha_key:
inputs['adcopy_response'], inputs['adcopy_challenge'] = solvemedia.challenge(captcha_key)