diff --git a/README.md b/README.md index 0293e4f..217ea5b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![GitHub downloads](https://img.shields.io/github/downloads/KurtBestor/Hitomi-Downloader/latest/total.svg?logo=github)](https://github.com/KurtBestor/Hitomi-Downloader/releases/latest) [![GitHub downloads](https://img.shields.io/github/downloads/KurtBestor/Hitomi-Downloader/total.svg?logo=github)](https://github.com/KurtBestor/Hitomi-Downloader/releases) +## Links - [Download](https://github.com/KurtBestor/Hitomi-Downloader/releases/latest) - [Issues](https://github.com/KurtBestor/Hitomi-Downloader/issues) - [Scripts](https://github.com/KurtBestor/Hitomi-Downloader/wiki/Scripts) @@ -15,6 +16,19 @@ ## Demo +## Features +- 🍰 Simple and clear user interface +- 🚀 Download acceleration +- 💻 Supports 32 threads in a single task +- 🚥 Supports speed limit +- 📜 Supports user scripts +- 🧲 Supports BitTorrent & Magnet +- 🎞️ Supports M3U8 & MPD format videos +- 🌙 Dark mode +- 🧳 Portable +- 📋 Clipboard monitor +- 🗃️ Easy to organize tasks + ## Supported Sites | Site | URL | | :--: | -- | @@ -32,6 +46,7 @@ | **Epio** | | | **E(x)Hentai Galleries** |
| | **Facebook** | | +| **FC2 Video** | | | **Flickr** | | | **Gelbooru** | | | **hanime.tv** | | @@ -44,6 +59,7 @@ | **Jmana** | | | **カクヨム** | | | **LHScan** | | +| **Likee** | | | **Luscious** | | | **Manamoa** | | | **MyReadingManga** | | @@ -51,6 +67,7 @@ | **Naver Post** | | | **Naver Webtoon** | | | **nhentai** | | +| **nhentai.com** | | | **Niconico** | | | **ニジエ** | | | **Pawoo** | | @@ -75,3 +92,4 @@ | **XVideos** | | | **Yande.re** | | | **YouTube** | | +| **and more...** | [Supported sites by youtube-dl](http://ytdl-org.github.io/youtube-dl/supportedsites.html) | diff --git a/src/extractor/afreeca_downloader.py b/src/extractor/afreeca_downloader.py index 5e94f63..e970051 100644 --- a/src/extractor/afreeca_downloader.py +++ b/src/extractor/afreeca_downloader.py @@ -31,9 +31,6 @@ class Downloader_afreeca(Downloader): single = True display_name = 'AfreecaTV' - def init(self): - self.url = self.url.replace('afreeca_', '') - def read(self): session = Session() video = get_video(self.url, session) diff --git a/src/extractor/artstation_downloader.py b/src/extractor/artstation_downloader.py index b674ea9..cba10e6 100644 --- a/src/extractor/artstation_downloader.py +++ b/src/extractor/artstation_downloader.py @@ -28,7 +28,7 @@ class Downloader_artstation(Downloader): display_name = 'ArtStation' def init(self): - self.url_main = 'https://www.artstation.com/{}'.format(self.id.replace('artstation_', '').replace('/', '/')) + self.url_main = 'https://www.artstation.com/{}'.format(self.id.replace('artstation_', '', 1).replace('/', '/')) if '/artwork/' in self.url: pass#raise NotImplementedError('Single post') @@ -53,7 +53,7 @@ def name(self): def read(self): cw = self.customWidget self.title = self.name - id = self.id.replace('artstation_', '').replace('/', '/') + id = self.id.replace('artstation_', '', 1).replace('/', '/') if '/' in id: type = id.split('/')[1] id = id.split('/')[0] diff --git a/src/extractor/asiansister_downloader.py b/src/extractor/asiansister_downloader.py index 10ab14f..fb28ded 100644 --- a/src/extractor/asiansister_downloader.py +++ b/src/extractor/asiansister_downloader.py @@ -13,7 +13,6 @@ class Downloader_asiansister(Downloader): @try_n(4) def init(self): - self.url = self.url.replace('asiansister_', '') html = downloader.read_html(self.url) self.soup = Soup(html) diff --git a/src/extractor/asmhentai_downloader.py b/src/extractor/asmhentai_downloader.py index b8dd93b..37eec0d 100644 --- a/src/extractor/asmhentai_downloader.py +++ b/src/extractor/asmhentai_downloader.py @@ -28,7 +28,6 @@ def init(self): @classmethod def fix_url(cls, url): - url = url.replace('asmhentai_', '') id_ = get_id(url) return 'https://asmhentai.com/g/{}/'.format(id_) diff --git a/src/extractor/avgle_downloader.py b/src/extractor/avgle_downloader.py index 1e6d487..de4e099 100644 --- a/src/extractor/avgle_downloader.py +++ b/src/extractor/avgle_downloader.py @@ -18,7 +18,6 @@ class Downloader_avgle(Downloader): URLS = ['avgle.com'] def init(self): - self.url = self.url.replace('avgle_', '', 1) if not self.customWidget.data_: link = 'https://github.com/KurtBestor/Hitomi-Downloader/wiki/Chrome-Extension' webbrowser.open(link) diff --git a/src/extractor/baraag_downloader.py b/src/extractor/baraag_downloader.py index 52e1a51..fd4a872 100644 --- a/src/extractor/baraag_downloader.py +++ b/src/extractor/baraag_downloader.py @@ -21,7 +21,6 @@ def init(self): @classmethod def fix_url(cls, url): - url = url.replace('baraag_', '') id_ = get_id(url) or url return 'https://baraag.net/{}'.format(id_) diff --git a/src/extractor/bcy_downloader.py b/src/extractor/bcy_downloader.py index bd11cf5..ae63774 100644 --- a/src/extractor/bcy_downloader.py +++ b/src/extractor/bcy_downloader.py @@ -16,7 +16,6 @@ class Downloader_bcy(Downloader): display_name = '半次元' def init(self): - self.url = self.url.replace('bcy_', '') self.html = downloader.read_html(self.url) self.info = get_info(self.url, self.html) diff --git a/src/extractor/bdsmlr_downloader.py b/src/extractor/bdsmlr_downloader.py index fabfe6e..6f20e45 100644 --- a/src/extractor/bdsmlr_downloader.py +++ b/src/extractor/bdsmlr_downloader.py @@ -17,8 +17,6 @@ class Downloader_bdsmlr(Downloader): display_name = 'BDSMlr' def init(self): - self.url = self.url.replace('bdsmlr_', '') - if u'bdsmlr.com/post/' in self.url: return self.Invalid(tr_(u'개별 다운로드는 지원하지 않습니다: {}').format(self.url), fail=False) diff --git a/src/extractor/bili_downloader.py b/src/extractor/bili_downloader.py index 59b7bb5..78769fa 100644 --- a/src/extractor/bili_downloader.py +++ b/src/extractor/bili_downloader.py @@ -69,8 +69,8 @@ class Downloader_bili(Downloader): def init(self): self.url = fix_url(self.url, self.customWidget) - if 'bili_' in self.url: - self.url = u'https://www.bilibili.com/video/{}'.format(self.url.replace('bili_', '')) + if 'bilibili.com' not in self.url.lower(): + self.url = 'https://www.bilibili.com/video/{}'.format(self.url) self.url = self.url.replace('m.bilibili', 'bilibili') @property @@ -96,7 +96,7 @@ def read(self): title += (u'_p{}').format(page) title = format_filename(title, self.id_, '.mp4')[:-4] n = int(math.ceil(8.0 / len(videos))) - self.customWidget.print_(('n_threads: {}').format(n)) + self.print_(('n_threads: {}').format(n)) self.enableSegment(n_threads=n) self.title = title diff --git a/src/extractor/comicwalker_downloader.py b/src/extractor/comicwalker_downloader.py index caee8b7..f7d3cd9 100644 --- a/src/extractor/comicwalker_downloader.py +++ b/src/extractor/comicwalker_downloader.py @@ -50,9 +50,6 @@ class Downloader_comicwalker(Downloader): display_name = 'ComicWalker' _soup = None pages = None - - def init(self): - self.url = url = self.url.replace('comicwalker_', '') @property def soup(self): diff --git a/src/extractor/danbooru_downloader.py b/src/extractor/danbooru_downloader.py index e95fa88..171f526 100644 --- a/src/extractor/danbooru_downloader.py +++ b/src/extractor/danbooru_downloader.py @@ -20,7 +20,6 @@ class Downloader_danbooru(Downloader): _name = None def init(self): - self.url = self.url.replace('danbooru_', '') if 'donmai.us' in self.url: self.url = self.url.replace('http://', 'https://') else: diff --git a/src/extractor/discord_emoji_downloader.py b/src/extractor/discord_emoji_downloader.py index 21f4e2f..f9b4f73 100644 --- a/src/extractor/discord_emoji_downloader.py +++ b/src/extractor/discord_emoji_downloader.py @@ -37,7 +37,7 @@ def init(self): pass def read(self): - token_guild_id_list = self.url.replace("discord_", "", 1).split( + token_guild_id_list = self.url.split( "/" ) # 값을 어떻게 받을지 몰라서 일단 나눴어요. discord_이메일/비밀번호/서버아이디 또는 discord_토큰/서버아이디 이런식으로 받게 해놨어요. diff --git a/src/extractor/gelbooru_downloader.py b/src/extractor/gelbooru_downloader.py index a79ca2e..592400c 100644 --- a/src/extractor/gelbooru_downloader.py +++ b/src/extractor/gelbooru_downloader.py @@ -36,7 +36,6 @@ class Downloader_gelbooru(Downloader): _name = None def init(self): - self.url = self.url.replace('gelbooru_', '') if 'gelbooru.com' in self.url.lower(): self.url = self.url.replace('http://', 'https://') else: diff --git a/src/extractor/hameln_downloader.py b/src/extractor/hameln_downloader.py index 0fe6555..ef8f279 100644 --- a/src/extractor/hameln_downloader.py +++ b/src/extractor/hameln_downloader.py @@ -18,7 +18,6 @@ class Downloader_hameln(Downloader): detect_removed = False def init(self): - self.url = self.url.replace('hameln_', '') id_ = re.find('/novel/([^/]+)', self.url) if id_ is not None: self.url = 'https://syosetu.org/novel/{}/'.format(id_) diff --git a/src/extractor/hanime_downloader.py b/src/extractor/hanime_downloader.py index 737cb35..345e463 100644 --- a/src/extractor/hanime_downloader.py +++ b/src/extractor/hanime_downloader.py @@ -41,10 +41,6 @@ class Downloader_hanime(Downloader): single = True display_name = 'hanime.tv' - def init(self): - if self.url.startswith('hanime_'): - self.url = self.url.replace('hanime_', '', 1) - def read(self): cw = self.customWidget video, session = get_video(self.url) diff --git a/src/extractor/hf_downloader.py b/src/extractor/hf_downloader.py index 47fda9c..fed5b85 100644 --- a/src/extractor/hf_downloader.py +++ b/src/extractor/hf_downloader.py @@ -44,8 +44,6 @@ def f(_): def get_username(url): if 'user/' in url: username = url.split('user/')[1].split('?')[0].split('/')[0] - else: - username = url.replace('hf_', '') return username diff --git a/src/extractor/manatoki_downloader.py b/src/extractor/manatoki_downloader.py index 842810f..b5156fc 100644 --- a/src/extractor/manatoki_downloader.py +++ b/src/extractor/manatoki_downloader.py @@ -34,8 +34,6 @@ class Downloader_manatoki(Downloader): @try_n(2) def init(self): - self.url = self.url.replace('manatoki_', '') - self.session, self.soup, url = get_soup(self.url) self.url = self.fix_url(url) diff --git a/src/extractor/naverpost_downloader.py b/src/extractor/naverpost_downloader.py index d25d289..79f12b4 100644 --- a/src/extractor/naverpost_downloader.py +++ b/src/extractor/naverpost_downloader.py @@ -53,7 +53,6 @@ class DownloaderNaverPost(Downloader): URLS = ["m.post.naver.com", "post.naver.com"] def init(self): - self.url = self.url.replace("naver_post_", "") self.parsed_url = urlparse(self.url) # url 나눔 self.soup = get_soup(self.url) diff --git a/src/extractor/nhentai_downloader.py b/src/extractor/nhentai_downloader.py index 7b8c704..d292492 100644 --- a/src/extractor/nhentai_downloader.py +++ b/src/extractor/nhentai_downloader.py @@ -15,7 +15,6 @@ class Downloader_nhentai(Downloader): display_name = 'nhentai' def init(self): - self.url = self.url.replace('nhentai_', '') self.url = 'https://nhentai.net/g/{}/'.format(self.id_) @property diff --git a/src/extractor/pawoo_downloader.py b/src/extractor/pawoo_downloader.py index cd2969c..ee438ce 100644 --- a/src/extractor/pawoo_downloader.py +++ b/src/extractor/pawoo_downloader.py @@ -13,7 +13,6 @@ class Downloader_pawoo(Downloader): URLS = ['pawoo.net'] def init(self): - self.url = self.url.replace('pawoo_', '') self.url = 'https://pawoo.net/{}'.format(self.id_) self.referer = self.url diff --git a/src/extractor/pixiv_comic_downloader.py b/src/extractor/pixiv_comic_downloader.py index 20e74af..bf88a54 100644 --- a/src/extractor/pixiv_comic_downloader.py +++ b/src/extractor/pixiv_comic_downloader.py @@ -33,7 +33,6 @@ class Downloader_pixiv_comic(Downloader): display_name = 'pixivコミック' def init(self): - self.url = self.url.replace('pixiv_comic_', '') if '/viewer/' in self.url: html = downloader.read_html(self.url) id = re.find('/works/([0-9]+)', html) diff --git a/src/extractor/pixiv_downloader.py b/src/extractor/pixiv_downloader.py index 7ad078f..da23863 100644 --- a/src/extractor/pixiv_downloader.py +++ b/src/extractor/pixiv_downloader.py @@ -44,6 +44,7 @@ class Downloader_pixiv(Downloader): info = None _id = None keep_date = True + strip_header = False atts = ['_format', '_format_name', 'imgs'] def init(self): @@ -51,13 +52,13 @@ def init(self): url = self.url # Determine the type - if 'bookmark.php?type=user' in url or headers['following'] in url: + if 'bookmark.php?type=user' in url or url.startswith(headers['following']): type = 'following' - elif 'bookmark.php' in url or headers['bookmark'] in url or '/bookmarks/' in url: + elif 'bookmark.php' in url or url.startswith(headers['bookmark']) or '/bookmarks/' in url: type = 'bookmark' - elif 'illust_id=' in url or headers['illust'] in url or '/artworks/' in url: + elif 'illust_id=' in url or url.startswith(headers['illust']) or '/artworks/' in url: type = 'illust' - elif 'search.php' in url or headers['search'] in url: + elif 'search.php' in url or url.startswith(headers['search']): type = 'search' order = query_url(url).get('order', ['date_d'])[0] # data_d, date, popular_d, popular_male_d, popular_female_d scd = query_url(url).get('scd', [None])[0] # 2019-09-27 @@ -91,7 +92,7 @@ def init(self): 'blt': blt, 'bgt': bgt, 'type': type_} - elif 'id=' in url and 'mode=' not in url or headers['user'] in url or 'pixiv.me' in url or '/users/' in url: + elif 'id=' in url and 'mode=' not in url or url.startswith(headers['user']) or 'pixiv.me' in url or '/users/' in url: type = 'user' else: self.Invalid((u'[pixiv] Can not determine type: {}').format(url)) diff --git a/src/extractor/sankaku_downloader.py b/src/extractor/sankaku_downloader.py index dbb22fb..bdee973 100644 --- a/src/extractor/sankaku_downloader.py +++ b/src/extractor/sankaku_downloader.py @@ -28,7 +28,6 @@ class Downloader_sankaku(Downloader): display_name = 'Sankaku Complex' def init(self): - self.url = self.url.replace('sankaku_', '') if '/post/' in self.url: return self.Invalid('Single post is not supported') diff --git a/src/extractor/syosetu_downloader.py b/src/extractor/syosetu_downloader.py index f96e6c3..4ecdd72 100644 --- a/src/extractor/syosetu_downloader.py +++ b/src/extractor/syosetu_downloader.py @@ -40,7 +40,6 @@ class Downloader_syosetu(Downloader): display_name = '小説家になろう' def init(self): - self.url = self.url.replace('syosetu_', '') self.url = (u'https://ncode.syosetu.com/{}/').format(self.id_) @property diff --git a/src/extractor/torrent_downloader.py b/src/extractor/torrent_downloader.py index 04539a9..a3e4c8a 100644 --- a/src/extractor/torrent_downloader.py +++ b/src/extractor/torrent_downloader.py @@ -28,8 +28,6 @@ def init(self): global torrent if torrent is None: import torrent - if self.url.startswith('torrent_'): - self.url = self.url.replace('torrent_', '', 1) @property def name(self): diff --git a/src/extractor/twitch_downloader.py b/src/extractor/twitch_downloader.py index 004e0b6..3622b18 100644 --- a/src/extractor/twitch_downloader.py +++ b/src/extractor/twitch_downloader.py @@ -21,7 +21,7 @@ def init(self): url = 'https://' + url self.url = url else: - url = 'https://www.twitch.tv/videos/{}'.format(url.replace('twitch_', '')) + url = 'https://www.twitch.tv/videos/{}'.format(url) self.url = url @classmethod diff --git a/src/extractor/twitter_downloader.py b/src/extractor/twitter_downloader.py index 904791c..ce74cf3 100644 --- a/src/extractor/twitter_downloader.py +++ b/src/extractor/twitter_downloader.py @@ -67,7 +67,6 @@ class Downloader_twitter(Downloader): def init(self): self.session = get_session() - self.url = self.url.replace('twitter_', '') #self.url = fix_url(self.url) self.artist, self.username = get_artist_username(self.url, self.session) if self.username == 'home': @@ -84,7 +83,7 @@ def fix_url(cls, url): @classmethod def key_id(cls, url): - return cls.fix_url(url).lower() + return url.lower() def read(self): cw = self.customWidget @@ -126,7 +125,10 @@ class TwitterAPI(object): def __init__(self, session, cw=None): self.session = session self.cw = cw - csrf = hashlib.md5(str(time()).encode()).hexdigest() + csrf = session.cookies.get('ct0', domain='.twitter.com') + print('csrf:', csrf) + if not csrf: + csrf = hashlib.md5(str(time()).encode()).hexdigest() hdr = { "authorization": AUTH, "x-twitter-client-language": "en", @@ -182,7 +184,11 @@ def _call(self, url_api, referer='https://twitter.com', params=None): if params: url_api = update_url_query(url_api, params) #print('call:', url_api) - data = downloader.read_json(url_api, referer, session=self.session) + r = self.session.get(url_api, headers={'Referer': referer}) + csrf = r.cookies.get('ct0') + if csrf: + self.session.headers['x-csrf-token'] = csrf + data = json.loads(r.text) return data def search(self, query): @@ -231,6 +237,9 @@ def _pagination(self, url_api, params=None, entry_tweet="tweet-", entry_cursor=" for try_ in range(n_try): try: data = self._call(url_api, params=params) + if 'globalObjects' not in data: + try_ = n_try + raise Exception(str(data['errors'])) tweets = data["globalObjects"]["tweets"] break except Exception as e: diff --git a/src/extractor/wikiart_downloader.py b/src/extractor/wikiart_downloader.py index c9dde4f..2351788 100644 --- a/src/extractor/wikiart_downloader.py +++ b/src/extractor/wikiart_downloader.py @@ -25,8 +25,6 @@ class Downloader_wikiart(Downloader): display_name = 'WikiArt' def init(self): - self.url = self.url.replace('wikiart_', '') - self.url = u'https://www.wikiart.org/en/{}'.format(self.id_) html = downloader.read_html(self.url) self.soup = Soup(html) diff --git a/src/extractor/worldcos_downloader.py b/src/extractor/worldcos_downloader.py index 9e380f5..7578059 100644 --- a/src/extractor/worldcos_downloader.py +++ b/src/extractor/worldcos_downloader.py @@ -23,7 +23,6 @@ class Downloader_worldcos(Downloader): display_name = 'World Cosplay' def init(self): - self.url = self.url.replace('worldcos_', '') if 'worldcosplay.net' in self.url.lower(): self.url = self.url.replace('http://', 'https://') else: diff --git a/src/extractor/xhamster_downloader.py b/src/extractor/xhamster_downloader.py index 11db5b0..0679b8c 100644 --- a/src/extractor/xhamster_downloader.py +++ b/src/extractor/xhamster_downloader.py @@ -1,5 +1,5 @@ import downloader, ree as re -from utils import Downloader, get_outdir, Soup, get_p2f, LazyUrl, get_print, cut_pair, get_ext, try_n, format_filename, clean_title +from utils import Downloader, get_outdir, Soup, LazyUrl, get_print, cut_pair, get_ext, try_n, format_filename, clean_title from timee import sleep from error_printer import print_error import os @@ -20,7 +20,6 @@ class Downloader_xhamster(Downloader): display_name = 'xHamster' def init(self): - self.url = self.url.replace('xhamster_', '') if re.search(r'xhamsterlive[0-9]*\.', self.url): raise Exception('xHamsterLive') if not re.search(r'xhamster[0-9]*\.', self.url): @@ -40,22 +39,8 @@ def read(self): if '/users/' in self.url: info = read_channel(self.url, cw) urls = info['urls'] - p2f = get_p2f(cw) - if p2f: - self.single = False - self.title = clean_title(info['title']) - videos = [Video(url) for url in urls] - self.urls = [video.url for video in videos] - video = videos[0] - video.url() - downloader.download(video.info['thumbnail'], buffer=thumb) - self.setIcon(thumb) - return - else: - cw.gal_num = self.url = urls.pop(0) - if urls and cw.alive: - s = u', '.join(urls) - self.exec_queue.put((s, 'downButton(customWidget)')) + videos = [Video(url) for url in urls] + video = self.process_playlist(info['title'], videos) elif '/photos/gallery/' in self.url: info = read_gallery(self.url, cw) for img in info['imgs']: @@ -66,21 +51,20 @@ def read(self): self.disableSegment() return else: - urls = [] - video = Video(self.url) - video.url() - self.urls.append(video.url) + video = Video(self.url) + video.url() + self.urls.append(video.url) + self.title = video.title downloader.download(video.info['thumbnail'], buffer=thumb) self.setIcon(thumb) - self.title = video.title class Video(object): _url = None def __init__(self, url): - url = downloader.real_url(url) + #url = downloader.real_url(url) self.url = LazyUrl(url, self.get, self) @try_n(2) @@ -130,36 +114,56 @@ def get_info(url): return info +def read_page(username, p, cw): + print_ = get_print(cw) + url = 'https://xhamster.com/users/{}/videos/{}'.format(username, p) + print_(url) + n = 4 + for try_ in range(n): + try: + soup = downloader.read_soup(url) + items = soup.findAll('div', class_='thumb-list__item') + if not items and try_ < n-1: + continue + break + except Exception as e: + e_ = e + print(e) + else: + raise e_ + return items + + def read_channel(url, cw=None): print_ = get_print(cw) username = url.split('/users/')[1].split('/')[0] info = {} - html = downloader.read_html(url) - soup = Soup(html) + soup = downloader.read_soup(url) title = soup.find('div', class_='user-name').text.strip() info['title'] = u'[Channel] {}'.format(title) - items = [] - for p in range(1, 21): - url = 'https://xhamster.com/users/{}/videos/{}'.format(username, p) - print_(url) - html = downloader.read_html(url) - soup = Soup(html) - items_ = soup.findAll('div', class_='thumb-list__item') - if not items_: + urls = [] + urls_set = set() + for p in range(1, 101): + items = read_page(username, p, cw) + if not items: print('no items') break - for item in items_: - items.append(item) - - urls = [] - for item in items: - url = item.a.attrs['href'] - if url in urls: - print('duplicate:', url) - continue - urls.append(url) + for item in items: + if item.find('span', class_='thumb-image-container__status-text'): #2858 + continue + url = item.a.attrs['href'] + if url in urls_set: + print('duplicate:', url) + continue + urls_set.add(url) + urls.append(url) + s = '{} {} - {}'.format(tr_('읽는 중...'), info['title'], len(urls)) + if cw: + cw.setTitle(s) + else: + print(s) info['urls'] = urls @@ -194,8 +198,7 @@ def read_gallery(url, cw=None): info = {} - html = downloader.read_html(url) - soup = Soup(html) + soup = downloader.read_soup(url) h1 = soup.find('h1') if h1.find('a'): diff --git a/src/extractor/xnxx_downloader.py b/src/extractor/xnxx_downloader.py index e8b5265..f51f0c3 100644 --- a/src/extractor/xnxx_downloader.py +++ b/src/extractor/xnxx_downloader.py @@ -37,9 +37,6 @@ class Downloader_xnxx(Downloader): single = True display_name = 'XNXX' - def init(self): - self.url = self.url.replace('xnxx_', '') - def read(self): video = get_video(self.url) self.urls.append(video.url) diff --git a/src/extractor/xvideo_downloader.py b/src/extractor/xvideo_downloader.py index 769eaee..0266d6f 100644 --- a/src/extractor/xvideo_downloader.py +++ b/src/extractor/xvideo_downloader.py @@ -1,5 +1,5 @@ import downloader -from utils import Downloader, Soup, LazyUrl, urljoin, format_filename, clean_title, Session, get_ext, get_p2f, get_print, get_max_range +from utils import Downloader, Soup, LazyUrl, urljoin, format_filename, clean_title, Session, get_ext, get_print, get_max_range from io import BytesIO from constants import try_n import ree as re @@ -49,7 +49,6 @@ class Downloader_xvideo(Downloader): display_name = 'XVideos' def init(self): - self.url = self.url.replace('xvideo_', '') if 'xvideos.' in self.url.lower(): self.url = self.url.replace('http://', 'https://') else: @@ -65,31 +64,22 @@ def key_id(cls, url): res = re.find(CHANNEL_PATTERN, url) if res: return '_'.join(res) - return self.fix_url(url) + return url def read(self): cw = self.customWidget + res = re.find(CHANNEL_PATTERN, self.url) if res: header, username = res info = read_channel(self.url, cw) - p2f = get_p2f(cw) - if p2f: - self.single = False - videos = [Video(url) for url in info['urls']] - self.urls = [video.url for video in videos] - videos[0].url() - self.title = clean_title('[Channel] {}'.format(info['name'])) - self.setIcon(videos[0].thumb) - return - else: - cw.gal_num = self.url = info['urls'].pop(0) - if info['urls'] and cw.alive: - s = ', '.join(info['urls']) - self.exec_queue.put((s, 'downButton(customWidget)')) - video = Video(self.url) - video.url() - self.title = video.title + videos = [Video(url) for url in info['urls']] + video = self.process_playlist('[Channel] {}'.format(info['name']), videos) + else: + video = Video(self.url) + video.url() + self.title = video.title + self.setIcon(video.thumb) self.urls.append(video.url) diff --git a/src/extractor/yandere_downloader.py b/src/extractor/yandere_downloader.py index 682d905..e8471c6 100644 --- a/src/extractor/yandere_downloader.py +++ b/src/extractor/yandere_downloader.py @@ -1,10 +1,14 @@ -from bs4 import BeautifulSoup -from urllib.request import urlopen from urllib.parse import unquote -from utils import Downloader, urljoin, clean_title +from utils import Downloader, urljoin, clean_title, try_n from translator import tr_ import ree as re import os +import downloader + + +@try_n(4) +def read_soup(url): + return downloader.read_soup(url) @Downloader.register @@ -13,9 +17,6 @@ class Downloader_yandere(Downloader): URLS = ['yande.re'] MAX_CORE = 4 - def init(self): - pass - @classmethod def fix_url(cls, url): url = re.sub(r'\?page=[0-9]+&', '?', url) @@ -33,8 +34,7 @@ def read(self): ids = set() url = self.url while True: - html = urlopen(url) - soup = BeautifulSoup(html, "html.parser") + soup = read_soup(url) tmp = soup.find_all(attrs={'class':'directlink'}, href=True) for image_html in tmp: image_url = image_html['href'] diff --git a/src/extractor/youku_downloader.py b/src/extractor/youku_downloader.py index cf03f8f..8cd491b 100644 --- a/src/extractor/youku_downloader.py +++ b/src/extractor/youku_downloader.py @@ -11,9 +11,6 @@ class Downloader_youku(Downloader): type = 'youku' single = True URLS = ['v.youku.com'] - - def init(self): - self.url = self.url.replace('youku_', '', 1) def read(self): video = Video(self.url) diff --git a/src/extractor/youporn_downloader.py b/src/extractor/youporn_downloader.py index 7a51e89..8cd6db6 100644 --- a/src/extractor/youporn_downloader.py +++ b/src/extractor/youporn_downloader.py @@ -17,8 +17,8 @@ class Downloader_youporn(Downloader): display_name = 'YouPorn' def init(self): - if self.url.startswith('youporn_'): - self.url = 'https://www.youporn.com/watch/{}'.format(self.url.replace('youporn_', '', 1)) + if 'youporn.com' not in self.url.lower(): + self.url = 'https://www.youporn.com/watch/{}'.format(self.url) def read(self): video = Video(self.url) diff --git a/src/extractor/youtube_downloader.py b/src/extractor/youtube_downloader.py index 7291d8e..91dfbfc 100644 --- a/src/extractor/youtube_downloader.py +++ b/src/extractor/youtube_downloader.py @@ -7,7 +7,7 @@ from error_printer import print_error from timee import sleep import ree as re -from utils import urljoin, Downloader, Soup, try_n, get_print, filter_range, get_p2f, LazyUrl, query_url, compatstr, uuid, get_max_range, format_filename, clean_title, get_resolution, get_abr +from utils import urljoin, Downloader, Soup, try_n, get_print, filter_range, LazyUrl, query_url, compatstr, uuid, get_max_range, format_filename, clean_title, get_resolution, get_abr import ffmpeg import sys import constants @@ -331,9 +331,6 @@ class Downloader_youtube(Downloader): def init(self): ui_setting = self.ui_setting - if 'youtube_' in self.url: - self.url = u'https://www.youtube.com/watch?v={}'.format(self.url.replace('youtube_','')) - if self.customWidget.format: ext_result = self.customWidget.format else: @@ -348,6 +345,8 @@ def init(self): @classmethod def fix_url(cls, url): # 2033 + if not re.match('https?://.+', url, re.IGNORECASE): + url = 'https://www.youtube.com/watch?v={}'.format(url) qs = query_url(url) if 'v' in qs: url = url.split('?')[0] + '?v={}'.format(qs['v'][0]) @@ -379,27 +378,14 @@ def read(self): else: raise Exception('No videos') - if len(videos) > 1: - p2f = get_p2f(cw) - if p2f: - self.single = False - self.title = clean_title(info['title']) - self.urls = [video.url for video in videos] - video = videos[0] - self.setIcon(video.thumb) - return - else: - video = videos.pop(0) - cw.gal_num = cw.url = video.url._url - if videos and cw.alive: - s = u', '.join(video.url._url for video in videos) - self.exec_queue.put(([s, {'youtube':cw.format}], 'downButton(cw[0], format_selector=cw[1])')) - - self.urls.append(video.url) + if info['type'] != 'single': + video = self.process_playlist(info['title'], videos) + else: + self.urls.append(video.url) + self.title = video.title + self.artist = video.username self.setIcon(video.thumb) - - self.title = video.title def int_(x): @@ -417,15 +403,18 @@ def get_videos(url, type='video', only_mp4=False, audio_included=False, max_res= if '/channel/' in url or '/user/' in url or '/c/' in url: info = read_channel(url, n=n, cw=cw) + info['type'] = 'channel' info['title'] = u'[Channel] {}'.format(info['uploader']) if cw: info['urls'] = filter_range(info['urls'], cw.range) elif '/playlist' in url: info = read_playlist(url, n=n, cw=cw) + info['type'] = 'playlist' info['title'] = u'[Playlist] {}'.format(info['title']) if cw: info['urls'] = filter_range(info['urls'], cw.range) else: + info['type'] = 'single' info['urls'] = [url] info['videos'] = [Video(url, type, only_mp4, audio_included, max_res, max_abr, cw) for url in info['urls']]