├── tests ├── __init__.py ├── test_util.py ├── test_common.py └── test.py ├── src └── you_get │ ├── util │ ├── __init__.py │ ├── term.py │ ├── strings.py │ ├── fs.py │ ├── git.py │ └── log.py │ ├── cli_wrapper │ ├── __init__.py │ ├── player │ │ ├── wmp.py │ │ ├── mplayer.py │ │ ├── dragonplayer.py │ │ ├── gnome_mplayer.py │ │ ├── vlc.py │ │ ├── __init__.py │ │ └── __main__.py │ ├── openssl │ │ └── __init__.py │ ├── transcoder │ │ ├── libav.py │ │ ├── __init__.py │ │ ├── ffmpeg.py │ │ └── mencoder.py │ └── downloader │ │ └── __init__.py │ ├── version.py │ ├── processor │ ├── __init__.py │ ├── join_ts.py │ └── rtmpdump.py │ ├── __init__.py │ ├── extractors │ ├── khan.py │ ├── alive.py │ ├── archive.py │ ├── cbs.py │ ├── freesound.py │ ├── bandcamp.py │ ├── magisto.py │ ├── quanmin.py │ ├── heavymusic.py │ ├── ted.py │ ├── giphy.py │ ├── metacafe.py │ ├── mixcloud.py │ ├── iqilu.py │ ├── douyin.py │ ├── theplatform.py │ ├── facebook.py │ ├── huomaotv.py │ ├── musicplayon.py │ ├── interest.py │ ├── ehow.py │ ├── vine.py │ ├── vidto.py │ ├── baomihua.py │ ├── dailymotion.py │ ├── yizhibo.py │ ├── naver.py │ ├── kuaishou.py │ ├── suntv.py │ ├── iwara.py │ ├── kuwo.py │ ├── veoh.py │ ├── w56.py │ ├── joy.py │ ├── panda.py │ ├── videomega.py │ ├── qingting.py │ ├── soundcloud.py │ ├── mtv81.py │ ├── qq_egame.py │ ├── pinterest.py │ ├── ifeng.py │ ├── nicovideo.py │ ├── yinyuetai.py │ ├── fantasy.py │ ├── infoq.py │ ├── nanagogo.py │ ├── miomio.py │ ├── kugou.py │ ├── miaopai.py │ ├── __init__.py │ ├── zhanqi.py │ ├── instagram.py │ ├── douban.py │ ├── lizhi.py │ ├── huaban.py │ ├── toutiao.py │ ├── fc2video.py │ ├── vk.py │ ├── bigthink.py │ ├── longzhu.py │ ├── tucao.py │ ├── cntv.py │ ├── imgur.py │ ├── douyutv.py │ ├── ku6.py │ ├── qie_video.py │ ├── sohu.py │ ├── bokecc.py │ ├── showroom.py │ ├── pixnet.py │ ├── qie.py │ ├── yixia.py │ ├── ckplayer.py │ ├── ixigua.py │ ├── twitter.py │ ├── coub.py │ ├── ximalaya.py │ ├── dilidili.py │ ├── tudou.py │ └── universal.py │ ├── json_output.py │ └── __main__.py ├── MANIFEST.in ├── setup.cfg ├── you-get.plugin.zsh ├── you-get ├── .travis.yml ├── Makefile ├── contrib └── completion │ ├── you-get-completion.bash │ ├── _you-get │ └── you-get.fish ├── .gitignore ├── LICENSE.txt ├── setup.py ├── you-get.json ├── CONTRIBUTING.md ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md └── README.rst /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/wmp.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/openssl/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/mplayer.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/transcoder/libav.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/downloader/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/dragonplayer.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/gnome_mplayer.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/transcoder/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/transcoder/ffmpeg.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/transcoder/mencoder.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/vlc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from .mplayer import * 4 | -------------------------------------------------------------------------------- /src/you_get/version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | script_name = 'you-get' 4 | __version__ = '0.4.1040' 5 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.rst 2 | include *.txt 3 | include Makefile 4 | include README.md 5 | include you-get 6 | include you-get.json 7 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [build] 2 | force = 0 3 | 4 | [global] 5 | verbose = 0 6 | 7 | [egg_info] 8 | tag_build = 9 | tag_date = 0 10 | tag_svn_revision = 0 11 | -------------------------------------------------------------------------------- /you-get.plugin.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | alias you-get="noglob python3 $(dirname $0)/you-get" 3 | alias you-vlc="noglob python3 $(dirname $0)/you-get --player vlc" 4 | -------------------------------------------------------------------------------- /src/you_get/processor/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from .join_flv import concat_flv 4 | from .join_mp4 import concat_mp4 5 | from .ffmpeg import * 6 | from .rtmpdump import * 7 | -------------------------------------------------------------------------------- /src/you_get/cli_wrapper/player/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' WIP 4 | def main(): 5 | script_main('you-get', any_download, any_download_playlist) 6 | 7 | if __name__ == "__main__": 8 | main() 9 | ''' 10 | -------------------------------------------------------------------------------- /src/you_get/util/term.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def get_terminal_size(): 4 | """Get (width, height) of the current terminal.""" 5 | try: 6 | import fcntl, termios, struct # fcntl module only available on Unix 7 | return struct.unpack('hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '1234')) 8 | except: 9 | return (40, 80) 10 | -------------------------------------------------------------------------------- /tests/test_util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import unittest 4 | 5 | from you_get.util.fs import * 6 | 7 | class TestUtil(unittest.TestCase): 8 | def test_legitimize(self): 9 | self.assertEqual(legitimize("1*2", os="Linux"), "1*2") 10 | self.assertEqual(legitimize("1*2", os="Darwin"), "1*2") 11 | self.assertEqual(legitimize("1*2", os="Windows"), "1-2") 12 | -------------------------------------------------------------------------------- /tests/test_common.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import unittest 4 | 5 | from you_get.common import * 6 | 7 | class TestCommon(unittest.TestCase): 8 | 9 | def test_match1(self): 10 | self.assertEqual(match1('http://youtu.be/1234567890A', r'youtu.be/([^/]+)'), '1234567890A') 11 | self.assertEqual(match1('http://youtu.be/1234567890A', r'youtu.be/([^/]+)', r'youtu.(\w+)'), ['1234567890A', 'be']) 12 | -------------------------------------------------------------------------------- /src/you_get/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This file is Python 2 compliant. 3 | 4 | import sys 5 | 6 | if sys.version_info[0] == 3: 7 | #from .extractor import Extractor, VideoExtractor 8 | #from .util import log 9 | 10 | from .__main__ import * 11 | 12 | #from .common import * 13 | #from .version import * 14 | #from .cli_wrapper import * 15 | #from .extractor import * 16 | else: 17 | # Don't import anything. 18 | pass 19 | -------------------------------------------------------------------------------- /you-get: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os, sys 3 | 4 | _srcdir = '%s/src/' % os.path.dirname(os.path.realpath(__file__)) 5 | _filepath = os.path.dirname(sys.argv[0]) 6 | sys.path.insert(1, os.path.join(_filepath, _srcdir)) 7 | 8 | if sys.version_info[0] == 3: 9 | import you_get 10 | if __name__ == '__main__': 11 | you_get.main(repo_path=_filepath) 12 | else: # Python 2 13 | from you_get.util import log 14 | log.e("[fatal] Python 3 is required!") 15 | log.wtf("try to run this script using 'python3 you-get'.") 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://travis-ci.org/soimort/you-get 2 | language: python 3 | python: 4 | - "3.2" 5 | - "3.3" 6 | - "3.4" 7 | - "3.5" 8 | - "3.6" 9 | - "nightly" 10 | - "pypy3" 11 | script: make test 12 | sudo: false 13 | notifications: 14 | webhooks: 15 | urls: 16 | - https://webhooks.gitter.im/e/43cd57826e88ed8f2152 17 | on_success: change # options: [always|never|change] default: always 18 | on_failure: always # options: [always|never|change] default: always 19 | on_start: never # options: [always|never|change] default: always 20 | -------------------------------------------------------------------------------- /src/you_get/extractors/khan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['khan_download'] 4 | 5 | from ..common import * 6 | from .youtube import YouTube 7 | 8 | def khan_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 9 | html = get_content(url) 10 | youtube_url = re.search(' unicode''' 16 | s = m.group(0)[2:].rstrip(';;') 17 | if s.startswith('x'): 18 | return chr(int('0'+s, 16)) 19 | else: 20 | return chr(int(s)) 21 | 22 | from .fs import legitimize 23 | 24 | def get_filename(htmlstring): 25 | return legitimize(unescape_html(htmlstring)) 26 | 27 | def parameterize(string): 28 | return "'%s'" % string.replace("'", r"'\''") 29 | -------------------------------------------------------------------------------- /src/you_get/extractors/magisto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['magisto_download'] 4 | 5 | from ..common import * 6 | import json 7 | 8 | def magisto_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 9 | html = get_html(url) 10 | 11 | video_hash = r1(r'video\/([a-zA-Z0-9]+)', url) 12 | api_url = 'https://www.magisto.com/api/video/{}'.format(video_hash) 13 | content = get_html(api_url) 14 | data = json.loads(content) 15 | title1 = data['title'] 16 | title2 = data['creator'] 17 | title = "%s - %s" % (title1, title2) 18 | url = data['video_direct_url'] 19 | type, ext, size = url_info(url) 20 | 21 | print_info(site_info, title, type, size) 22 | if not info_only: 23 | download_urls([url], title, ext, size, output_dir, merge=merge) 24 | 25 | site_info = "Magisto.com" 26 | download = magisto_download 27 | download_playlist = playlist_not_supported('magisto') 28 | -------------------------------------------------------------------------------- /src/you_get/extractors/quanmin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['quanmin_download'] 4 | 5 | from ..common import * 6 | import json 7 | 8 | def quanmin_download(url, output_dir = '.', merge = True, info_only = False, **kwargs): 9 | roomid = url.split('/')[3].split('?')[0] 10 | 11 | json_request_url = 'http://m.quanmin.tv/json/rooms/{}/noinfo6.json'.format(roomid) 12 | content = get_html(json_request_url) 13 | data = json.loads(content) 14 | 15 | title = data["title"] 16 | 17 | if not data["play_status"]: 18 | raise ValueError("The live stream is not online!") 19 | 20 | real_url = data["live"]["ws"]["flv"]["5"]["src"] 21 | 22 | print_info(site_info, title, 'flv', float('inf')) 23 | if not info_only: 24 | download_urls([real_url], title, 'flv', None, output_dir, merge = merge) 25 | 26 | site_info = "quanmin.tv" 27 | download = quanmin_download 28 | download_playlist = playlist_not_supported('quanmin') 29 | -------------------------------------------------------------------------------- /src/you_get/extractors/heavymusic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['heavymusic_download'] 4 | 5 | from ..common import * 6 | 7 | def heavymusic_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 8 | html = get_html(url) 9 | tracks = re.findall(r'href="(online2\.php[^"]+)"', html) 10 | for track in tracks: 11 | band = r1(r'band=([^&]*)', track) 12 | album = r1(r'album=([^&]*)', track) 13 | title = r1(r'track=([^&]*)', track) 14 | file_url = 'http://www.heavy-music.ru/online2.php?band=%s&album=%s&track=%s' % (parse.quote(band), parse.quote(album), parse.quote(title)) 15 | _, _, size = url_info(file_url) 16 | 17 | print_info(site_info, title, 'mp3', size) 18 | if not info_only: 19 | download_urls([file_url], title[:-4], 'mp3', size, output_dir, merge=merge) 20 | 21 | site_info = "heavy-music.ru" 22 | download = heavymusic_download 23 | download_playlist = heavymusic_download 24 | -------------------------------------------------------------------------------- /src/you_get/extractors/ted.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['ted_download'] 4 | 5 | from ..common import * 6 | import json 7 | 8 | def ted_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 9 | html = get_html(url) 10 | patt = r'"__INITIAL_DATA__"\s*:\s*\{(.+)\}' 11 | metadata = json.loads('{' + match1(html, patt) + '}') 12 | title = metadata['talks'][0]['title'] 13 | nativeDownloads = metadata['talks'][0]['downloads']['nativeDownloads'] 14 | for quality in ['high', 'medium', 'low']: 15 | if quality in nativeDownloads: 16 | url = nativeDownloads[quality] 17 | type, ext, size = url_info(url) 18 | print_info(site_info, title, type, size) 19 | if not info_only: 20 | download_urls([url], title, ext, size, output_dir, merge=merge) 21 | break 22 | 23 | site_info = "TED.com" 24 | download = ted_download 25 | download_playlist = playlist_not_supported('ted') 26 | -------------------------------------------------------------------------------- /src/you_get/extractors/giphy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['giphy_download'] 4 | 5 | from ..common import * 6 | import json 7 | 8 | def giphy_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 9 | html = get_html(url) 10 | 11 | url = list(set([ 12 | unicodize(str.replace(i, '\\/', '/')) 13 | for i in re.findall(r'', html) 14 | ])) 15 | 16 | title = r1(r'', html) 17 | 18 | if title is None: 19 | title = url[0] 20 | 21 | type, ext, size = url_info(url[0], True) 22 | size = urls_size(url) 23 | 24 | type = "video/mp4" 25 | ext = "mp4" 26 | 27 | print_info(site_info, title, type, size) 28 | if not info_only: 29 | download_urls(url, title, ext, size, output_dir, merge=False) 30 | 31 | site_info = "Giphy.com" 32 | download = giphy_download 33 | download_playlist = playlist_not_supported('giphy') 34 | -------------------------------------------------------------------------------- /src/you_get/extractors/metacafe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['metacafe_download'] 4 | 5 | from ..common import * 6 | import urllib.error 7 | from urllib.parse import unquote 8 | 9 | def metacafe_download(url, output_dir = '.', merge = True, info_only = False, **kwargs): 10 | if re.match(r'http://www.metacafe.com/watch/\w+', url): 11 | html =get_content(url) 12 | title = r1(r'>> import you_get" % you_get.version.__version__)') 9 | 10 | test: 11 | $(SETUP) test 12 | 13 | clean: 14 | zenity --question 15 | rm -fr build/ dist/ src/*.egg-info/ 16 | find . | grep __pycache__ | xargs rm -fr 17 | find . | grep .pyc | xargs rm -f 18 | 19 | all: build sdist bdist bdist_egg bdist_wheel 20 | 21 | html: 22 | pandoc README.md > README.html 23 | 24 | rst: 25 | pandoc -s -t rst README.md > README.rst 26 | 27 | build: 28 | $(SETUP) build 29 | 30 | sdist: 31 | $(SETUP) sdist 32 | 33 | bdist: 34 | $(SETUP) bdist 35 | 36 | bdist_egg: 37 | $(SETUP) bdist_egg 38 | 39 | bdist_wheel: 40 | $(SETUP) bdist_wheel 41 | 42 | install: 43 | $(SETUP) install --user --prefix= 44 | 45 | release: 46 | zenity --question 47 | $(SETUP) sdist bdist_wheel upload --sign 48 | -------------------------------------------------------------------------------- /src/you_get/extractors/mixcloud.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['mixcloud_download'] 4 | 5 | from ..common import * 6 | 7 | def mixcloud_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 8 | html = get_html(url, faker=True) 9 | title = r1(r'(.+)', html) 12 | 13 | if title is None: 14 | title = url 15 | 16 | sd_urls = list(set([ 17 | unicodize(str.replace(i, '\\/', '/')) 18 | for i in re.findall(r'sd_src_no_ratelimit:"([^"]*)"', html) 19 | ])) 20 | hd_urls = list(set([ 21 | unicodize(str.replace(i, '\\/', '/')) 22 | for i in re.findall(r'hd_src_no_ratelimit:"([^"]*)"', html) 23 | ])) 24 | urls = hd_urls if hd_urls else sd_urls 25 | 26 | type, ext, size = url_info(urls[0], True) 27 | size = urls_size(urls) 28 | 29 | print_info(site_info, title, type, size) 30 | if not info_only: 31 | download_urls(urls, title, ext, size, output_dir, merge=False) 32 | 33 | site_info = "Facebook.com" 34 | download = facebook_download 35 | download_playlist = playlist_not_supported('facebook') 36 | -------------------------------------------------------------------------------- /src/you_get/extractors/huomaotv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __all__ = ['huomaotv_download'] 4 | 5 | from ..common import * 6 | 7 | 8 | def get_mobile_room_url(room_id): 9 | return 'http://www.huomao.com/mobile/mob_live/%s' % room_id 10 | 11 | 12 | def get_m3u8_url(stream_id): 13 | return 'http://live-ws.huomaotv.cn/live/%s/playlist.m3u8' % stream_id 14 | 15 | 16 | def huomaotv_download(url, output_dir='.', merge=True, info_only=False, **kwargs): 17 | room_id_pattern = r'huomao.com/(\d+)' 18 | room_id = match1(url, room_id_pattern) 19 | html = get_content(get_mobile_room_url(room_id)) 20 | 21 | stream_id_pattern = r'id="html_stream" value="(\w+)"' 22 | stream_id = match1(html, stream_id_pattern) 23 | 24 | m3u8_url = get_m3u8_url(stream_id) 25 | 26 | title = match1(html, r'