├── song
├── commands
│ ├── __init__.py
│ ├── MusicWebsiteParser
│ │ ├── __init__.py
│ │ ├── MusicWebsiteParser.py
│ │ ├── MusicWebsiteFactory.py
│ │ ├── YoutubeParser.py
│ │ └── MrJattParser.py
│ ├── SearchEngineParser
│ │ ├── __init__.py
│ │ ├── SearchEngineFactory.py
│ │ ├── SearchEngineParser.py
│ │ └── GoogleParser.py
│ ├── base.py
│ ├── FactoryProducer.py
│ ├── download.py
│ └── FileDownload.py
├── __init__.py
└── cli.py
├── setup.cfg
├── requirements.txt
├── MANIFEST.in
├── .gitignore
├── LICENSE
├── setup.py
├── README.md
└── README.rst
/song/commands/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/song/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '2.9.1'
--------------------------------------------------------------------------------
/song/commands/MusicWebsiteParser/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/song/commands/SearchEngineParser/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | # setup.cfg
2 | [bdist_wheel]
3 | universal=1
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | docopt
2 | requests
3 | BeautifulSoup
4 | tqdm
5 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.rst
2 | exclude *.mp3
3 | exclude .gitignore
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
3 | /dist/
4 |
5 | /*.egg-info
6 |
7 | *.mp3
8 |
9 | /build/
--------------------------------------------------------------------------------
/song/commands/SearchEngineParser/SearchEngineFactory.py:
--------------------------------------------------------------------------------
1 | from .GoogleParser import GoogleParser
2 |
3 | class SearchEngineFactory:
4 |
5 | def getParser(self,parser_name):
6 | if parser_name.lower()=="google":
7 | return GoogleParser()
8 | else:
9 | raise NotImplementedError("parser for this search engine is not implemented yet")
--------------------------------------------------------------------------------
/song/commands/MusicWebsiteParser/MusicWebsiteParser.py:
--------------------------------------------------------------------------------
1 | class MusicWebsiteParser:
2 | '''
3 | Base class for music website parsers
4 | Every parser needs to implement it
5 |
6 | '''
7 | def Parse(self,url):
8 | '''It will parse the html page specified by url
9 | and return the resource url from where the music file needs to be downloaded
10 | '''
11 | raise NotImplementedError('You must implement the Parse() method yourself!')
--------------------------------------------------------------------------------
/song/commands/SearchEngineParser/SearchEngineParser.py:
--------------------------------------------------------------------------------
1 | class SearchEngineParser:
2 | '''It is the base class for Search Engine Parser
3 | Every Search Engine Parser needs to implement this class
4 | '''
5 | def Parse(self,song_name,website):
6 | '''
7 | It will search for "song_name website" in the Search Engine results
8 | and return the url of website
9 | '''
10 | raise NotImplementedError('You must implement the Parse() method yourself!')
--------------------------------------------------------------------------------
/song/commands/base.py:
--------------------------------------------------------------------------------
1 | # skele/commands/base.py
2 | """The base command."""
3 |
4 |
5 | class Base(object):
6 | """A base command."""
7 | """Here is a module named base! I don't know what the issue is here!"""
8 |
9 | def __init__(self, options, *args, **kwargs):
10 | self.options = options
11 | self.args = args
12 | self.kwargs = kwargs
13 |
14 | def run(self):
15 | raise NotImplementedError('You must implement the run() method yourself!')
16 |
--------------------------------------------------------------------------------
/song/commands/MusicWebsiteParser/MusicWebsiteFactory.py:
--------------------------------------------------------------------------------
1 | from .MrJattParser import MrJattParser
2 | from .YoutubeParser import YoutubeParser
3 | class MusicWebsiteFactory:
4 |
5 | def getParser(self,parser_name):
6 | #print "fuck yeh"
7 | #print parser_name
8 | parser_name.lower()
9 | if parser_name.lower()=="mr jatt":
10 | return MrJattParser()
11 | elif parser_name.lower()=="youtube":
12 | return YoutubeParser()
13 | else:
14 | raise NotImplementedError('parser for this music website not implemented')
--------------------------------------------------------------------------------
/song/commands/FactoryProducer.py:
--------------------------------------------------------------------------------
1 | from MusicWebsiteParser.MusicWebsiteFactory import MusicWebsiteFactory
2 | from SearchEngineParser.SearchEngineFactory import SearchEngineFactory
3 |
4 | class FactoryProducer:
5 |
6 | def getFactory(self,factory_name):
7 | if factory_name.lower()=="search engine parser factory":
8 | return SearchEngineFactory()
9 | elif factory_name.lower()=="music website parser factory":
10 | return MusicWebsiteFactory()
11 | else:
12 | raise NotImplementedError("%s not implemented"%factory_name)
13 |
--------------------------------------------------------------------------------
/song/commands/MusicWebsiteParser/YoutubeParser.py:
--------------------------------------------------------------------------------
1 | from .MusicWebsiteParser import MusicWebsiteParser
2 | from ..FileDownload import FileDownload
3 | from BeautifulSoup import BeautifulSoup
4 |
5 | class YoutubeParser(MusicWebsiteParser):
6 |
7 | def Parse(self,song_name):
8 | song_name = '+'.join(song_name)
9 | url="https://www.youtube.com/results?search_query="
10 | url=url+song_name
11 | file_download=FileDownload()
12 | html=file_download.get_html_response(url)
13 | soup=BeautifulSoup(html)
14 | download_url = soup.find('a',attrs={'class':'yt-uix-tile-link yt-ui-ellipsis yt-ui-ellipsis-2 yt-uix-sessionlink spf-link '})
15 | temp_url='https://www.youtube.com'
16 | final_url=temp_url+download_url.get('href')
17 | return final_url
18 |
19 |
--------------------------------------------------------------------------------
/song/cli.py:
--------------------------------------------------------------------------------
1 | """
2 | song
3 |
4 | Usage:
5 | song -d [--download-all] TEXT...
6 | song -h | --help
7 | song --version
8 | song -y TEXT...
9 | song --ty SONGFILE...
10 | song --td SONGFILE...
11 |
12 | Options:
13 | -h --help Show this screen.
14 | --version Show version.
15 |
16 | Examples:
17 | song -d wo lamhe
18 |
19 | Help:
20 | For help using this tool, please open an issue on the Github repository:
21 | https://github.com/ankitmathur3193/song-cli
22 | """
23 | from inspect import getmembers, isclass
24 |
25 | from docopt import docopt
26 |
27 | from __init__ import __version__ as VERSION
28 |
29 | def main():
30 | """Main CLI entrypoint."""
31 | #print VERSION
32 | from commands.download import Download
33 | options = docopt(__doc__, version=VERSION)
34 | #print "You reached here"
35 | #print options
36 | print "working."
37 | p=Download(options)
38 | p.run()
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 ankit mathur
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/song/commands/SearchEngineParser/GoogleParser.py:
--------------------------------------------------------------------------------
1 | from .SearchEngineParser import SearchEngineParser
2 | from ..FileDownload import FileDownload
3 | from BeautifulSoup import BeautifulSoup
4 |
5 | class GoogleParser(SearchEngineParser):
6 | '''
7 | A parser for google search Engine
8 | '''
9 |
10 | def google_url(self,song_name,website):
11 | ''' It will return the google url to be searched'''
12 | name='+'.join(song_name)
13 | prefix='https://www.google.co.in/search?q='
14 | website=website.split(" ")
15 | suffix='+'.join(website)
16 | url=prefix+name+suffix
17 | #print url
18 | return url
19 |
20 | def parse_google(self,html):
21 | '''It will parse google html response
22 | and return the first url
23 | '''
24 | soup = BeautifulSoup(html)
25 | href=soup.find('div','g').find('a').get('href')
26 | href_list=href.split('&')
27 | download_url=href_list[0]
28 | download_url=download_url.strip()
29 | download_url=download_url.replace('/url?q=','')
30 | return download_url
31 |
32 |
33 | def Parse(self,song_name,website):
34 | '''
35 | song_name is a list of strings
36 | website is a string
37 | It will return the url from where music file needs to be downloaded
38 | '''
39 | url_to_be_parsed=self.google_url(song_name,website)
40 | file_download=FileDownload()
41 | html=file_download.get_html_response(url_to_be_parsed)
42 | website_url=self.parse_google(html)
43 | return website_url
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from codecs import open
2 | from os.path import abspath, dirname, join
3 | from subprocess import call
4 |
5 | from setuptools import Command, find_packages, setup
6 | from song import __version__ as VERSION
7 | this_dir = abspath(dirname(__file__))
8 | with open(join(this_dir, 'README.rst'), encoding='utf-8') as file:
9 | long_description = file.read()
10 |
11 |
12 | setup(
13 | name = 'song',
14 | version = VERSION,
15 | author = 'ankit mathur',
16 | author_email = 'ankitmathur.dtu@gmail.com',
17 | license = 'MIT',
18 | description = ' A script to download hindi and punjabi songs from internet',
19 | long_description = long_description,
20 | url = 'https://github.com/ankitmathur3193/song-cli',
21 | keywords = ['song', 'download', 'script', 'youtube-dl','tqdm','requests','beautiful soup'],
22 | packages = find_packages(exclude=['docs', 'tests*']),
23 | install_requires = ['docopt==0.6.2','requests==2.20.0','BeautifulSoup==3.2.1','tqdm==4.11.2','youtube-dl==2017.05.26'],
24 | classifiers = [
25 | 'Intended Audience :: Developers',
26 | 'Topic :: Utilities',
27 | 'License :: Public Domain',
28 | 'Natural Language :: English',
29 | 'Operating System :: OS Independent',
30 | 'Programming Language :: Python :: 2',
31 | 'Programming Language :: Python :: 2.6',
32 | 'Programming Language :: Python :: 2.7',
33 | ],
34 | entry_points = {
35 | 'console_scripts': [
36 | 'song=song.cli:main',
37 | ],
38 | },
39 |
40 | )
--------------------------------------------------------------------------------
/song/commands/download.py:
--------------------------------------------------------------------------------
1 | # skele/commands/download.py
2 | """The hello command."""
3 |
4 |
5 | from json import dumps
6 |
7 | from base import Base
8 | from FactoryProducer import FactoryProducer
9 | from FileDownload import FileDownload
10 | class Download(Base):
11 |
12 | def run(self):
13 | name=self.options["TEXT"]
14 | download_all_flag = self.options["--download-all"]
15 | if self.options['-y'] == True:
16 | self.download_from_youtube(name)
17 | elif self.options['-d'] == True:
18 | self.download_from_mr_jatt(name,download_all_flag)
19 | elif self.options['--ty'] == True: #determines if the '-yt' tag is there and returns object at that value
20 | songfile = self.options["SONGFILE"][0] #determines if options list has SONGFILE (name defined in cli.py in comments)
21 | #and takes the 0th element in the songfile array, which gives the actual file of the song, not just a list with one element
22 | with open(songfile) as f:
23 | content = f.readlines() #content is a list with lines of the textfile which should be song titles
24 | content = [x.strip() for x in content] #removes ending whitespaces and endlines
25 | for song in content:
26 | self.download_from_youtube(song.split()) #creates a list with each word of the song separated by spaces
27 | #this is done so YoutubeParser.py can concatenate them with '+' signs to generate a URL to search youtube
28 | elif self.options['--td'] == True:
29 | songfile = self.options["SONGFILE"][0]
30 | with open(songfile) as f:
31 | content = f.readlines()
32 | content = [x.strip() for x in content]
33 | for song in content:
34 | self.download_from_mr_jatt(song.split(), download_all_flag)
35 |
36 |
37 | def download_from_youtube(self,name):
38 | factory = FactoryProducer()
39 | p = factory.getFactory("search engine parser factory")
40 | print "Download from youtube"
41 | q = factory.getFactory("music website parser factory")
42 | q = q.getParser("youtube")
43 | link = q.Parse(name)
44 | file_download=FileDownload()
45 | file_download.file_download_using_youtube_dl(link)
46 |
47 |
48 | def download_from_mr_jatt(self,name,flag):
49 | factory = FactoryProducer()
50 | p = factory.getFactory("search engine parser factory")
51 | p=p.getParser("google")
52 | website_url = p.Parse(name,"mr jatt")
53 | q = factory.getFactory("music website parser factory")
54 | q = q.getParser("mr jatt")
55 | download_url = q.Parse(website_url,name,flag)
56 | file_download=FileDownload()
57 | if flag == True:
58 | print "All songs will be downloaded for %s"%(' '.join(name))
59 | for url in download_url:
60 | print url[0],url[1]
61 | temp = q.Parse(url[0],url[1],False)
62 | file_download.file_download_cross_platform(temp)
63 | else:
64 | file_download.file_download_cross_platform(download_url)
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://badge.fury.io/py/song)
2 | [](https://github.com/ankitmathur3193/song-cli/blob/master/LICENSE)
3 | # SONG DOWNLOADER #
4 | A **command line** interface for **downloading Songs/mp3** from Internet
5 |
6 | Just type the **name of the song** and it will download the song for you
7 |
8 | ## Features ##
9 | * song can download music from https://www.youtube.com/ and https://mr-jatt.com/
10 | * song query Google for finding link associated to https://mr-jatt.com/
11 | * It then parses Mr-jatt.com for finding download link of the mp3 file and downloads it.
12 | ## For Installing ##
13 | ```
14 | pip install song
15 | ```
16 | ## For Upgrading ##
17 | ```
18 | pip install --upgrade song
19 | ```
20 | ## For Uninstalling ##
21 | ```
22 | pip uninstall song
23 | ```
24 | ## Usage: ##
25 | ```
26 | song -y [ song_name ]
27 | song -d [ song_name | singer_name | movie_name ]
28 | song -d --download-all [ singer_name | movie_name ]
29 | song --ty [ textfile.txt ]
30 | song --td [ textfile.txt ]
31 | song --version
32 | ```
33 | Optional arguments are:
34 | * -y : For downloading mp3 from **youtube**
35 | * -d : For downloading mp3 from **mr-jatt**
36 | * --ty : For downloading all songs in specified text file from **youtube** mp3 format
37 | * --td : For downloading all songs in specified text file from **mr-jatt** mp3 format
38 | * --download-all : For downloading **all songs** of a **movie or top songs of a singer**
39 | * --version : For printing song version
40 |
41 | ## Example: ##
42 | * ### For Downloading Song From Youtube ###
43 | ```
44 | song -y roar
45 | ```
46 |
47 | 
48 |
49 | * ### For Downloading Song (It will download the file in current working directory) ###
50 | ```
51 | song -d tum hi ho
52 | ```
53 |
54 | 
55 |
56 | * For Downloading **all songs** of a **movie or top songs of a singer**
57 | ```
58 | song -d --download-all dhoom
59 | ```
60 |
61 | 
62 |
63 | * ### For Listing songs of a Movie
64 | ```
65 | song -d dangal
66 | ```
67 |
68 | 
69 |
70 |
71 | * ### For Listing Top songs of an Artist ###
72 | ```
73 | song -d sunidhi chauhan
74 | ```
75 |
76 | 
77 |
78 | ## TODO ##
79 | - [X] Add support for Hollywood/English Songs
80 | - [ ] Implement Unit Testing
81 | - [X] Option for downloading all songs of a movie
82 | - [X] Option for downloading all top songs of a artist
83 |
84 | ## Disclaimer ##
85 |
86 | Downloading copyrighted material may be illegal in your country. Use at your own risk.
87 |
88 | ## Want to Contribute ##
89 | - Clone the repository
90 |
91 | ```
92 | $ git clone https://github.com/ankitmathur3193/song-cli.git
93 | ```
94 |
95 | - Build from source
96 |
97 | ```
98 | $ cd song-cli-master
99 | $ python setup.py develop
100 | ```
101 |
102 |
103 |
104 |
105 |
106 |
107 | ----------------------------------------------------
108 |
--------------------------------------------------------------------------------
/song/commands/MusicWebsiteParser/MrJattParser.py:
--------------------------------------------------------------------------------
1 | from .MusicWebsiteParser import MusicWebsiteParser
2 | from ..FileDownload import FileDownload
3 | from BeautifulSoup import BeautifulSoup
4 | import re
5 |
6 | class MrJattParser(MusicWebsiteParser):
7 | '''
8 | Parser for https://mr-jatt.com/
9 |
10 | '''
11 |
12 |
13 | def missing_schema(self,html,song_name):
14 | '''
15 | It will print the list of songs that can be downloaded
16 | '''
17 | #html=self.get_html_response(url)
18 | soup=BeautifulSoup(html)
19 | name=' '.join(song_name)
20 | print '%s not found'%name
21 | print "But you can download any of the following songs :"
22 | a_list=soup.findAll('a','touch')
23 | for x in xrange(len(a_list)-1):
24 | r=a_list[x]
25 | p=str(r)
26 | q=re.sub(r'||||||','',p)
27 | print q
28 |
29 | def list_of_all_href(self,html):
30 | '''
31 | It will return all hyper links found in the mr-jatt page for download
32 | '''
33 | soup=BeautifulSoup(html)
34 | links=[]
35 | a_list=soup.findAll('a','touch')
36 | for x in xrange(len(a_list)-1):
37 | link = a_list[x].get('href')
38 | name = a_list[x]
39 | name = str(name)
40 | name=re.sub(r'||||||','',name)
41 | name=re.sub(r'^[0-9]+\.','',name)
42 | links.append([link,name])
43 |
44 | #quit()
45 | return links
46 |
47 | def check_if_song_name(self,html):
48 | '''
49 | Returns true if user entered artist or movie name
50 | '''
51 | soup=BeautifulSoup(html)
52 | a_list=soup.findAll('a','touch')
53 | #print a_list
54 | text=[str(x) for x in a_list]
55 | text=''.join(text)
56 | text=text.lower()
57 | string1='download in 48 kbps'
58 | string2='download in 128 kbps'
59 | string3='download in 320 kbps'
60 |
61 | href=''
62 | if string3 in text:
63 | #print 'Downloading in 320 kbps'
64 | href=a_list[2].get('href')
65 |
66 | elif string2 in text:
67 | #print 'Downloading in 128 kbps'
68 | href=a_list[1].get('href')
69 |
70 | elif string1 in text:
71 | #print 'Downloading in 48 kbps'
72 | href=a_list[0].get('href')
73 | else:
74 | return (True,'nothing')
75 |
76 | return (False,href)
77 |
78 | def Parse(self,url,song_name,flag):
79 | '''
80 | It will the resource URL if song is found,
81 | Otherwise it will return the list of songs that can be downloaded
82 | '''
83 | file_download=FileDownload()
84 | html=file_download.get_html_response(url)
85 | if flag == False:
86 | soup=BeautifulSoup(html)
87 | a_list=soup.findAll('a','touch')
88 | #print a_list
89 | text=[str(x) for x in a_list]
90 | text=''.join(text)
91 | text=text.lower()
92 | string1='download in 48 kbps'
93 | string2='download in 128 kbps'
94 | string3='download in 320 kbps'
95 |
96 | href=''
97 | if string3 in text:
98 | print 'Downloading in 320 kbps'
99 | href=a_list[2].get('href')
100 |
101 | elif string2 in text:
102 | print 'Downloading in 128 kbps'
103 | href=a_list[1].get('href')
104 |
105 | elif string1 in text:
106 | print 'Downloading in 48 kbps'
107 | href=a_list[0].get('href')
108 | else:
109 | self.missing_schema(html,song_name)
110 | quit()
111 |
112 | return href
113 | else:
114 | x,href=self.check_if_song_name(html)
115 | links = []
116 | if x==True:
117 | links=self.list_of_all_href(html)
118 | else:
119 | file_download=FileDownload()
120 | file_download.file_download_cross_platform(href)
121 | quit()
122 |
123 |
124 | return links
125 |
126 |
127 |
--------------------------------------------------------------------------------
/song/commands/FileDownload.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import os
3 | import os.path
4 | import subprocess
5 | from tqdm import tqdm
6 |
7 | class FileDownload:
8 |
9 | def get_html_response(self,url):
10 | '''It will download the html page specified by url and return the html response '''
11 | print "Downloading page %s .."%url
12 | try:
13 | response=requests.get(url,timeout=50)
14 | except requests.exceptions.SSLError:
15 | try:
16 | response=requests.get(url,verify=False,timeout=50)
17 | except requests.exceptions.RequestException as e:
18 | print e
19 | quit()
20 | except requests.exceptions.RequestException as e:
21 | print e
22 | quit()
23 |
24 | return response.content
25 |
26 |
27 | def file_download_using_requests(self,url):
28 | '''It will download file specified by url using requests module'''
29 | file_name=url.split('/')[-1]
30 |
31 | if os.path.exists(os.path.join(os.getcwd(),file_name)):
32 | print 'File already exists'
33 | return
34 | #print 'Downloading file %s '%file_name
35 | #print 'Downloading from %s'%url
36 |
37 |
38 |
39 | try:
40 | r=requests.get(url,stream=True,timeout=200)
41 | except requests.exceptions.SSLError:
42 | try:
43 | response=requests.get(url,stream=True,verify=False,timeout=200)
44 | except requests.exceptions.RequestException as e:
45 | print e
46 | quit()
47 | except requests.exceptions.RequestException as e:
48 | print e
49 | quit()
50 | chunk_size = 1024
51 | total_size = int(r.headers['Content-Length'])
52 | total_chunks = total_size/chunk_size
53 |
54 | file_iterable = r.iter_content(chunk_size = chunk_size)
55 | tqdm_iter = tqdm(iterable = file_iterable,total = total_chunks,unit = 'KB',
56 | leave = False
57 | )
58 | with open(file_name,'wb') as f:
59 | for data in tqdm_iter:
60 | f.write(data)
61 |
62 |
63 | #total_size=float(r.headers['Content-Length'])/(1024*1024)
64 | '''print 'Total size of file to be downloaded %.2f MB '%total_size
65 | total_downloaded_size=0.0
66 | with open(file_name,'wb') as f:
67 | for chunk in r.iter_content(chunk_size=1*1024*1024):
68 | if chunk:
69 | size_of_chunk=float(len(chunk))/(1024*1024)
70 | total_downloaded_size+=size_of_chunk
71 | print '{0:.0%} Downloaded'.format(total_downloaded_size/total_size)
72 | f.write(chunk)'''
73 |
74 | print 'Downloaded file %s '%file_name
75 |
76 |
77 | def file_download_using_wget(self,url):
78 | '''It will download file specified by url using wget utility of linux '''
79 | file_name=url.split('/')[-1]
80 | print 'Downloading file %s '%file_name
81 | command='wget -c --read-timeout=50 --tries=3 -q --show-progress --no-check-certificate '
82 | url='"'+url+'"'
83 | command=command+url
84 | os.system(command)
85 |
86 | def file_download_cross_platform(self,url):
87 | file_name=url.split('/')[-1]
88 | if os.path.exists(os.path.join(os.getcwd(),file_name)):
89 | print 'File already exists'
90 | return
91 | print 'Downloading file %s '%file_name,'wb'
92 | #command='wget -c --read-timeout=50 --tries=3 -q --show-progress --no-check-certificate '
93 | try:
94 | #raise Exception('I know Python!')
95 | #print 'file download using wget'
96 | subprocess.call(['wget','-c','--read-timeout=50','--tries=3','-q','--show-progress','--no-check-certificate',url])
97 | except:
98 | #print 'file download using requests'
99 | self.file_download_using_requests(url);
100 |
101 |
102 | def file_download_using_youtube_dl(self,url):
103 | #command = 'youtube-dl -cit --embed-thumbnail --no-warnings --extract-audio --audio-quality 0 --audio-format mp3 '
104 | subprocess.call(['youtube-dl','-cit','--embed-thumbnail','--no-warnings','--extract-audio','--audio-quality', '0','--audio-format', 'mp3',url])
105 |
106 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | |PyPI version| |license|
2 |
3 | SONG DOWNLOADER
4 | ===============
5 |
6 | A **command line** interface for **downloading Songs/mp3** from Internet
7 |
8 | Just type the **name of the song** and it will download for you
9 |
10 | Features
11 | --------
12 | - song can download music from https://www.youtube.com/ and https://mr-jatt.com/
13 | - song query Google for finding link associated to https://mr-jatt.com/
14 | - It then parses Mr-jatt.com for finding download link of the mp3 file and downloads it.
15 |
16 | For Installing
17 | --------------
18 |
19 | ::
20 |
21 | pip install song
22 |
23 | For Upgrading
24 | -------------
25 |
26 | ::
27 |
28 | pip install --upgrade song
29 |
30 | For Uninstalling
31 | ----------------
32 |
33 | ::
34 |
35 | pip uninstall song
36 |
37 | Usage:
38 | ------
39 |
40 | ::
41 |
42 | song -y [ song_name ]
43 | song -d [ song_name | singer_name | movie_name ]
44 | song -d --download-all [ singer_name | movie_name ]
45 | song --ty [ textfile.txt ]
46 | song --td [ textfile.txt ]
47 | song --version
48 |
49 | Optional arguments are:
50 |
51 | - -y : For downloading mp3 from **youtube**
52 |
53 | - -d : For downloading mp3 from **mr-jatt**
54 |
55 | - --download-all : For downloading **all songs** of a **movie or top songs of a singer**
56 | - --ty : For downloading all songs in specified text file from **youtube** in mp3 format
57 | - --td : For downloading all songs in specified text file from **mr-jatt** in mp3 format
58 |
59 | - --version : For printing song version
60 |
61 |
62 |
63 | Example:
64 | --------
65 |
66 | - .. rubric:: For Downloading Song From Youtube
67 | :name: for-downloading-song-from-youtube
68 |
69 | ::
70 |
71 | song -y tum hi ho
72 |
73 | .. figure:: https://cloud.githubusercontent.com/assets/15183662/26529632/28499f54-43e1-11e7-87a6-f4c0c3e2fd0b.png
74 | :alt: youtube example
75 |
76 |
77 |
78 |
79 | - .. rubric:: For Downloading Song from Mr-jatt (It will download the file in
80 | current working directory)
81 | :name: for-downloading-song-it-will-download-the-file-in-current-working-directory
82 |
83 | ::
84 |
85 | song -d tum hi ho
86 |
87 | .. figure:: https://cloud.githubusercontent.com/assets/15183662/26523026/cdc7d2e6-432a-11e7-941b-76fa9c465093.png
88 | :alt: song-cli example
89 |
90 |
91 |
92 | - .. rubric:: For Downloading **all songs** of a **movie or top songs of a singer**
93 | :name: For Downloading **all songs** of a **movie or top songs of a singer**
94 |
95 | ::
96 |
97 | song -d --download-all dhoom
98 |
99 | .. figure:: https://cloud.githubusercontent.com/assets/15183662/26556972/929c1c12-44bb-11e7-8fbc-48b389de7a82.png
100 | :alt: download all songs
101 |
102 |
103 |
104 |
105 |
106 | - .. rubric:: For Listing songs of a Movie
107 | :name: for-listing-songs-of-a-movie
108 |
109 | ``song -d dangal``
110 |
111 | .. figure:: https://cloud.githubusercontent.com/assets/15183662/26523019/b009e7b2-432a-11e7-8241-919f95c993bf.png
112 | :alt: after movie name
113 |
114 |
115 |
116 | - .. rubric:: For Listing Top songs of a Artist
117 | :name: for-listing-top-songs-of-a-artist
118 |
119 | ::
120 |
121 | song -d sunidhi chauhan
122 |
123 | .. figure:: https://cloud.githubusercontent.com/assets/15183662/26523023/c1a272dc-432a-11e7-85e7-1757a40da341.png
124 | :alt: artist\_top\_songs
125 |
126 |
127 |
128 | TODO
129 | ----
130 |
131 | - [ X ] Add support for Hollywood/English Songs
132 | - [ ] Implement Unit Testing
133 | - [ X ] Option for downloading all songs of a movie
134 | - [ X ] Option for downloading all top songs of a artist
135 |
136 | Disclaimer
137 | ----------
138 |
139 | Downloading copyrighted material may be illegal in your country. Use at your own risk.
140 |
141 | Want to Contribute
142 | ------------------
143 |
144 | - Clone the repository
145 |
146 | ::
147 |
148 | $ git clone https://github.com/ankitmathur3193/song-cli.git
149 |
150 | - Install dependencies
151 |
152 | ::
153 |
154 | $ pip install -r requirements.txt
155 |
156 | --------------
157 |
158 | .. |PyPI version| image:: https://badge.fury.io/py/song.svg
159 | :target: https://badge.fury.io/py/song
160 | .. |license| image:: https://img.shields.io/github/license/mashape/apistatus.svg
161 | :target: https://github.com/ankitmathur3193/song-cli/blob/master/LICENSE
162 |
--------------------------------------------------------------------------------