From 6be6e0ab2b43a9dd31f94edc160384bf9a94b0a0 Mon Sep 17 00:00:00 2001 From: r0oth3x49 Date: Mon, 21 May 2018 06:44:58 +0500 Subject: [PATCH] udemy-dl v0.5, Added feature to authenticate using cookies, Added feature to save lecture titles to text file, Added feature to download courses containing unicode characters in title, added file to listdown contributors --- AUTHOR | 1 - AUTHOR.md | 3 + CHANGELOG.md | 7 + CONTRIBUTORS.md | 14 + README.md | 71 ++-- udemy-dl.py | 797 ++++++++++++++++++++++++------------- udemy/__init__.py | 2 +- udemy/_auth.py | 13 +- udemy/_colorized/banner.py | 2 +- udemy/_extract.py | 50 ++- udemy/_internal.py | 11 +- udemy/_shared.py | 102 ++++- udemy/_udemy.py | 5 +- 13 files changed, 728 insertions(+), 350 deletions(-) delete mode 100644 AUTHOR create mode 100644 AUTHOR.md create mode 100644 CONTRIBUTORS.md diff --git a/AUTHOR b/AUTHOR deleted file mode 100644 index 467a6ca..0000000 --- a/AUTHOR +++ /dev/null @@ -1 +0,0 @@ -Nasir Khan (r0ot h3x49) \ No newline at end of file diff --git a/AUTHOR.md b/AUTHOR.md new file mode 100644 index 0000000..89e35df --- /dev/null +++ b/AUTHOR.md @@ -0,0 +1,3 @@ +# *Nasir Khan (r0ot h3x49)* + + - **https://r0oth3x49.herokuapp.com** \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d230454..9604754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 0.5 (2018-05-21) + +Features: + - Authentication using cookies thanks to @jhonyyy90 for sharing credentials (option: `-k / --cookies`). + - Download/save lecture names to file thanks to @serhattsnmz (option: `--names`). + - Download lectures containing unsafe (`unicode`) characters in title/name thanks to @tofanelli and @Chlitzxer (option: `--unsafe`). + ## 0.4 (2018-02-26) Features: diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..8ce7315 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,14 @@ +### List of contributors who made the contribution either in form of feature request or a bugfix + - @jdsantiagojr (fixed UnicodeEncode error) + - @kizbitz (fixed TypeError: write() argument must be str, not bytes) + - @SalihKARAHAN (Added Turkish character support) + - @Stekot (Remove windows reserved characters from the title) + - @ghost (added pep8 on udemy-dl.py) + - @serhattsnmz (added fix for password error, suggested some great features) + - @Nocxy (Checked with the recent version of MAC oSx) + - @tofanelli (gave support to many users and also suggested some features) + - @NoMoreUsernamesAvailable (Feature request for Umlauts (unicode based characters) in filenames) + - @RuthlessRuler (Requested to add support Aria2c downloader) + - @alfari16 (Download from specific chapter) + +> Thanks to all other contributors if i missed any one. \ No newline at end of file diff --git a/README.md b/README.md index e604467..b16328d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ # udemy-dl **A cross-platform python based utility to download courses from udemy for personal offline use.** -[![udemy.png](https://s26.postimg.org/fo84ef1qx/udemy.png)](https://postimg.org/image/brusifgr9/) +[![udemy-dl-0-5.png](https://s26.postimg.cc/67x3wfak9/udemy-dl-0-5.png)](https://postimg.cc/image/s73ijmred/) ## ***Features*** @@ -23,34 +23,9 @@ - Download lecture(s) by providing range in a chapter (option: `--lecture-start, --lecture-end`). - Download lecture(s) requested resolution (option: `-q / --quality`). - Download course to user requested path (option: `-o / --output`). - - -## ***Requirements*** - -- Python (2 or 3) -- Python `pip` -- Python module `requests` -- Python module `colorama` -- Python module `unidecode` -- Python module `six` -- Python module `requests[security]` or `pyOpenSSL` - -## ***Module Installation*** - - pip install -r requirements.txt - -## ***Tested on*** - -- Windows 7/8/8.1/10 -- Kali linux (2017.2) -- Ubuntu-LTS (64-bit) (tested with super user) -- Mac OSX 10.9.5 (tested with super user) - -## ***Download udemy-dl*** - -You can download the latest version of udemy-dl by cloning the GitHub repository. - - git clone https://github.com/r0oth3x49/udemy-dl.git +- Authentication using cookies (option: `-k / --cookies`). +- Download/save lecture names (option: `--names`). +- Download lectures containing unsafe *unicode* characters in title/name (option: `--unsafe`). ## ***Issue Reporting Guideline*** @@ -83,6 +58,33 @@ experience the problem? All these details will help to fix any potential bugs as > > Any other information you want to share that is relevant to the issue being reported. +## ***Requirements*** + +- Python (2 or 3) +- Python `pip` +- Python module `requests` +- Python module `colorama` +- Python module `unidecode` +- Python module `six` +- Python module `requests[security]` or `pyOpenSSL` + +## ***Module Installation*** + + pip install -r requirements.txt + +## ***Tested on*** + +- Windows 7/8/8.1/10 +- Kali linux (2017.2) +- Ubuntu-LTS (64-bit) (tested with super user) +- Mac OSX 10.9.5 (tested with super user) + +## ***Download udemy-dl*** + +You can download the latest version of udemy-dl by cloning the GitHub repository. + + git clone https://github.com/r0oth3x49/udemy-dl.git + ## ***Usage*** @@ -140,9 +142,10 @@ experience the problem? All these details will help to fix any potential bugs as

 Author: Nasir khan (r0ot h3x49)
 
-Usage: udemy-dl.py [-h] [-v] [-u] [-p] [-o] [-q] [-c] [-l] [--chapter-start]
-                   [--chapter-end] [--lecture-start] [--lecture-end] [--save]
-                   [--info] [--cache] [--sub-only] [--skip-sub]
+usage: udemy-dl.py [-h] [-v] [-u] [-p] [-k] [-o] [-q] [-c] [-l]
+                   [--chapter-start] [--chapter-end] [--lecture-start]
+                   [--lecture-end] [--save] [--info] [--cache] [--names]
+                   [--unsafe] [--sub-only] [--skip-sub]
                    course
 
 A cross-platform python based utility to download courses from udemy for
@@ -158,6 +161,7 @@ General:
 Authentication:
   -u , --username   Username in udemy.
   -p , --password   Password of your account.
+  -k , --cookies    Cookies to authenticate with.
 
 Advance:
   -o , --output     Download to specific directory.
@@ -173,10 +177,13 @@ Others:
   --save            Do not download but save links to a file.
   --info            List all lectures with available resolution.
   --cache           Cache your credentials to use it later.
+  --names           Do not download but save lecture names to file.
+  --unsafe          Download all course with unsafe names.
   --sub-only        Download captions/subtitle only.
   --skip-sub        Download course but skip captions/subtitle.
 
 Example:
   python udemy-dl.py  COURSE_URL
+  python udemy-dl.py  COURSE_URL -k cookies.txt
   python udemy-dl.py -u user@domain.com -p p4ssw0rd COURSE_URL
 
diff --git a/udemy-dl.py b/udemy-dl.py index f4c5a11..f01b481 100644 --- a/udemy-dl.py +++ b/udemy-dl.py @@ -22,38 +22,58 @@ class Udemy(WebVtt2Srt, ProgressBar): - def __init__(self, url, username, password): + def __init__(self, url, username='', password='', cookies=''): self.url = url self.username = username self.password = password + self.cookies = cookies super(Udemy, self).__init__() - def _write_to_file(self, filepath='', lecture=''): + def _write_to_file(self, filepath='', lecture='', names_only=False, unsafe=False): retVal = {} filename = filepath + filename += '-names-only.txt' if names_only else ".txt" + fmode = "a" + if not unsafe: + title = lecture.title + url = lecture.url + url_or_name = url if not names_only else title + url_or_name += "\n" + if unsafe: + title = u'%s' % (lecture.unsafe_title) + url = lecture.url + url_or_name = url if not names_only else title + url_or_name += "\n" + if pyver == 3: - with open('{}.txt'.format(filename), 'a', encoding='utf-8') as f: + with open(filename, fmode, encoding='utf-8') as f: try: - f.write('{}\n'.format(lecture.url)) + f.write(url_or_name) except Exception as e: retVal = {'status' : 'False', 'msg' : 'Python3 Exception : {}'.format(e)} else: retVal = {'status' : 'True', 'msg' : 'download'} f.close() else: - with open('{}.txt'.format(filename), 'a') as f: + if names_only and unsafe: + url_or_name = url_or_name.encode('utf-8') + with open(filename, fmode) as f: try: - f.write('{}\n'.format(lecture.url)) + f.write(url_or_name) except Exception as e: retVal = {'status' : 'False', 'msg' : 'Python2 Exception : {}'.format(e)} else: retVal = {'status' : 'True', 'msg' : 'download'} f.close() + return retVal - def course_save(self, path='', quality='', caption_only=False, skip_captions=False): - sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") - course = udemy.course(self.url, self.username, self.password) + def course_save(self, path='', quality='', caption_only=False, skip_captions=False, names_only=False, unsafe=False): + if not self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") + if self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login using cookies ...\n") + course = udemy.course(url=self.url, username=self.username, password=self.password, cookies=self.cookies) course_id = course.id course_name = course.title total_lectures = course.lectures @@ -74,7 +94,10 @@ def course_save(self, path='', quality='', caption_only=False, skip_captions=Fal if os.path.isfile(filepath): with open(filepath, 'w') as f: f.close() - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Writing course content(s) to '%s.txt'\n" % (course_name)) + if not names_only: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Writing course content(s) to '%s.txt'\n" % (course_name)) + if names_only: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Writing course lecture names to '%s-names-only.txt'\n" % (course_name)) for chapter in chapters: chapter_id = chapter.id chapter_title = chapter.title @@ -99,30 +122,36 @@ def course_save(self, path='', quality='', caption_only=False, skip_captions=Fal if caption_only and not skip_captions: if lecture_subtitles: for subtitle in lecture_subtitles: - self._write_to_file(filepath=course_path, lecture=subtitle) + self._write_to_file(filepath=course_path, lecture=subtitle, names_only=names_only, unsafe=unsafe) if lecture_assets: for asset in lecture_assets: - self._write_to_file(filepath=course_path, lecture=asset) + self._write_to_file(filepath=course_path, lecture=asset, names_only=names_only, unsafe=unsafe) elif skip_captions and not caption_only: if lecture_best: - self._write_to_file(filepath=course_path, lecture=lecture_best) + self._write_to_file(filepath=course_path, lecture=lecture_best, names_only=names_only, unsafe=unsafe) if lecture_assets: for asset in lecture_assets: - self._write_to_file(filepath=course_path, lecture=asset) + self._write_to_file(filepath=course_path, lecture=asset, names_only=names_only, unsafe=unsafe) else: if lecture_best: - self._write_to_file(filepath=course_path, lecture=lecture_best) + self._write_to_file(filepath=course_path, lecture=lecture_best, names_only=names_only, unsafe=unsafe) if lecture_assets: for asset in lecture_assets: - self._write_to_file(filepath=course_path, lecture=asset) + self._write_to_file(filepath=course_path, lecture=asset, names_only=names_only, unsafe=unsafe) if lecture_subtitles: for subtitle in lecture_subtitles: - self._write_to_file(filepath=course_path, lecture=subtitle) - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Written successfully under '{name}.txt'.\n".format(name=course_path)) - - def course_list_down(self, chapter_number='', lecture_number=''): - sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") - course = udemy.course(self.url, self.username, self.password) + self._write_to_file(filepath=course_path, lecture=subtitle, names_only=names_only, unsafe=unsafe) + if not names_only: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Written successfully under '{name}.txt'.\n".format(name=course_path)) + if names_only: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Written successfully under '{name}-names-only.txt'.\n".format(name=course_path)) + + def course_list_down(self, chapter_number='', lecture_number='', unsafe=False): + if not self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") + if self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login using cookies ...\n") + course = udemy.course(url=self.url, username=self.username, password=self.password, cookies=self.cookies) course_id = course.id course_name = course.title total_lectures = course.lectures @@ -134,7 +163,7 @@ def course_list_down(self, chapter_number='', lecture_number=''): if chapter_number and chapter_number > 0 and chapter_number <= total_chapters: chapter = chapters[chapter_number-1] chapter_id = chapter.id - chapter_title = chapter.title + chapter_title = chapter.title if not unsafe else "%02d" % (int(chapter.index)) lectures = chapter.get_lectures() lectures_count = chapter.lectures sys.stdout.write ('\n' + fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s-%s)\n" % (chapter_title, chapter_id)) @@ -244,7 +273,7 @@ def course_list_down(self, chapter_number='', lecture_number=''): else: for chapter in chapters: chapter_id = chapter.id - chapter_title = chapter.title + chapter_title = chapter.title if not unsafe else "%02d" % (int(chapter.index)) lectures = chapter.get_lectures() lectures_count = chapter.lectures sys.stdout.write ('\n' + fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s-%s)\n" % (chapter_title, chapter_id)) @@ -300,40 +329,45 @@ def course_list_down(self, chapter_number='', lecture_number=''): in_MB = "MB " if size < 1024.00 else 'GB ' sys.stdout.write('\t- ' + fg + sd + "{:<22} {:<8}{}{}{}{}\n".format(str(subtitle), subtitle.extension, sz, in_MB, fy, sb)) - def download_assets(self, lecture_assets='', filepath=''): + def download_assets(self, lecture_assets='', filepath='', unsafe=False): if lecture_assets: for assets in lecture_assets: - title = assets.filename + title = assets.filename if not unsafe else "%s" % (assets) mediatype = assets.mediatype if mediatype == "external_link": - assets.download(filepath=filepath, quiet=True, callback=self.show_progress) + assets.download(filepath=filepath, unsafe=unsafe, quiet=True, callback=self.show_progress) else: sys.stdout.write(fc + sd + "\n[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Downloading asset(s)\n") sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Downloading (%s)\n" % (title)) try: - retval = assets.download(filepath=filepath, quiet=True, callback=self.show_progress) + retval = assets.download(filepath=filepath, unsafe=unsafe, quiet=True, callback=self.show_progress) except KeyboardInterrupt: sys.stdout.write (fc + sd + "\n[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") sys.exit(0) else: msg = retval.get('msg') if msg == 'already downloaded': - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Asset : '%s' " % (assets.filename) + fy + sb + "(already downloaded).\n") + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Asset : '%s' " % (title) + fy + sb + "(already downloaded).\n") elif msg == 'download': - sys.stdout.write (fc + sd + "[" + fm + sb + "+" + fc + sd + "] : " + fg + sd + "Downloaded (%s)\n" % (assets.filename)) + sys.stdout.write (fc + sd + "[" + fm + sb + "+" + fc + sd + "] : " + fg + sd + "Downloaded (%s)\n" % (title)) else: - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Asset : '%s' " % (assets.filename) + fc + sb + "(download skipped).\n") + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Asset : '%s' " % (title) + fc + sb + "(download skipped).\n") sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "{}\n".format(msg)) - def download_subtitles(self, lecture_subtitles='', filepath=''): + def download_subtitles(self, lecture_subtitles='', filepath='', unsafe=False): if lecture_subtitles: for subtitles in lecture_subtitles: - title = subtitles.title + '-' + subtitles.language - filename = "%s\\%s" % (filepath, subtitles.filename) if os.name == 'nt' else "%s/%s" % (filepath, subtitles.filename) + title = subtitles.title + '-' + subtitles.language if not unsafe else "%s" % (subtitles) + if not unsafe: + filename = "%s\\%s" % (filepath, subtitles.filename) if os.name == 'nt' else "%s/%s" % (filepath, subtitles.filename) + if unsafe: + filename = u"%s\\%s" % (filepath, subtitles.unsafe_filename) if os.name == 'nt' else u"%s/%s" % (filepath, subtitles.unsafe_filename) + sys.stdout.write(fc + sd + "\n[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Downloading subtitle(s)\n") sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Downloading (%s)\n" % (title)) + try: - retval = subtitles.download(filepath=filepath, quiet=True, callback=self.show_progress) + retval = subtitles.download(filepath=filepath, unsafe=unsafe, quiet=True, callback=self.show_progress) except KeyboardInterrupt: sys.stdout.write (fc + sd + "\n[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") sys.exit(0) @@ -349,48 +383,57 @@ def download_subtitles(self, lecture_subtitles='', filepath=''): sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Subtitle : '%s' " % (title) + fc + sb + "(download skipped).\n") sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "{}\n".format(msg)) - def download_lectures(self, lecture_best='', lecture_title='', inner_index='', lectures_count='', filepath=''): + def download_lectures(self, lecture_best='', lecture_title='', inner_index='', lectures_count='', filepath='', unsafe=False): if lecture_best: sys.stdout.write(fc + sd + "\n[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture(s) : ({index} of {total})\n".format(index=inner_index, total=lectures_count)) sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Downloading (%s)\n" % (lecture_title)) try: - retval = lecture_best.download(filepath=filepath, quiet=True, callback=self.show_progress) + retval = lecture_best.download(filepath=filepath, unsafe=unsafe, quiet=True, callback=self.show_progress) except KeyboardInterrupt: sys.stdout.write (fc + sd + "\n[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") sys.exit(0) else: msg = retval.get('msg') if msg == 'already downloaded': - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture : '%s' " % (lecture_title) + fy + sb + "(already downloaded).\n") + if not unsafe: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture : '%s' " % (lecture_title) + fy + sb + "(already downloaded).\n") + if unsafe: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "'%s' " % (lecture_title) + fy + sb + "(already downloaded).\n") elif msg == 'download': sys.stdout.write (fc + sd + "[" + fm + sb + "+" + fc + sd + "] : " + fg + sd + "Downloaded (%s)\n" % (lecture_title)) else: - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture : '%s' " % (lecture_title) + fc + sb + "(download skipped).\n") + if not unsafe: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture : '%s' " % (lecture_title) + fc + sb + "(download skipped).\n") + if unsafe: + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "'%s' " % (lecture_title) + fc + sb + "(download skipped).\n") sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "{}\n".format(msg)) - def download_captions_only(self, lecture_subtitles='', lecture_assets='', filepath=''): + def download_captions_only(self, lecture_subtitles='', lecture_assets='', filepath='', unsafe=False): if lecture_subtitles: - self.download_subtitles(lecture_subtitles=lecture_subtitles, filepath=filepath) + self.download_subtitles(lecture_subtitles=lecture_subtitles, filepath=filepath, unsafe=unsafe) if lecture_assets: - self.download_assets(lecture_assets=lecture_assets, filepath=filepath) + self.download_assets(lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) - def download_lectures_only(self, lecture_best='', lecture_title='', inner_index='', lectures_count='', lecture_assets='', filepath=''): + def download_lectures_only(self, lecture_best='', lecture_title='', inner_index='', lectures_count='', lecture_assets='', filepath='', unsafe=False): if lecture_best: - self.download_lectures(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, filepath=filepath) + self.download_lectures(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, filepath=filepath, unsafe=unsafe) if lecture_assets: - self.download_assets(lecture_assets=lecture_assets, filepath=filepath) + self.download_assets(lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) - def download_lectures_and_captions(self, lecture_best='', lecture_title='', inner_index='', lectures_count='', lecture_subtitles='', lecture_assets='', filepath=''): + def download_lectures_and_captions(self, lecture_best='', lecture_title='', inner_index='', lectures_count='', lecture_subtitles='', lecture_assets='', filepath='', unsafe=False): if lecture_best: - self.download_lectures(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, filepath=filepath) + self.download_lectures(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, filepath=filepath, unsafe=unsafe) if lecture_subtitles: - self.download_subtitles(lecture_subtitles=lecture_subtitles, filepath=filepath) + self.download_subtitles(lecture_subtitles=lecture_subtitles, filepath=filepath, unsafe=unsafe) if lecture_assets: - self.download_assets(lecture_assets=lecture_assets, filepath=filepath) - - def course_download(self, path='', quality='', caption_only=False, skip_captions=False): - sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") - course = udemy.course(self.url, self.username, self.password) + self.download_assets(lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) + + def course_download(self, path='', quality='', caption_only=False, skip_captions=False, unsafe=False): + if not self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") + if self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login using cookies ...\n") + course = udemy.course(url=self.url, username=self.username, password=self.password, cookies=self.cookies) course_id = course.id course_name = course.title chapters = course.get_chapters() @@ -412,25 +455,32 @@ def course_download(self, path='', quality='', caption_only=False, skip_captions chapter_title = chapter.title lectures = chapter.get_lectures() lectures_count = chapter.lectures - filepath = "%s\\%s" % (course_path, chapter_title) if os.name == 'nt' else "%s/%s" % (course_path, chapter_title) + if unsafe: + filepath = u"%s\\%s" % (course_path, chapter.unsafe_title) if os.name == 'nt' else u"%s/%s" % (course_path, chapter.unsafe_title) + if not unsafe: + filepath = "%s\\%s" % (course_path, chapter_title) if os.name == 'nt' else "%s/%s" % (course_path, chapter_title) try: os.makedirs(filepath) except Exception as e: pass sys.stdout.write (fc + sd + "\n[" + fm + sb + "*" + fc + sd + "] : " + fm + sb + "Downloading chapter : ({index} of {total})\n".format(index=chapter_index, total=total_chapters)) - sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s)\n" % (chapter_title)) - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Found (%s) lectures ...\n" % (lectures_count)) + if not unsafe: + sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s)\n" % (chapter_title)) + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Found (%s) lectures ...\n" % (lectures_count)) + if unsafe: + sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%02d-%s)\n" % (int(chapter_index), chapter_id)) + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture(s) (%s).\n" % (lectures_count)) inner_index = 1 for lecture in lectures: lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -443,8 +493,8 @@ def course_download(self, path='', quality='', caption_only=False, skip_captions if not lecture_best: lecture_best = lecture_best if lecture.html: - lecture.dump(filepath=filepath) - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath) + lecture.dump(filepath=filepath, unsafe=unsafe) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -457,13 +507,16 @@ def course_download(self, path='', quality='', caption_only=False, skip_captions if not lecture_best: lecture_best = lecture_best if lecture.html: - lecture.dump(filepath=filepath) - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + lecture.dump(filepath=filepath, unsafe=unsafe) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) inner_index += 1 - def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', lecture_number='', lecture_start='', lecture_end='', path='', quality='', caption_only=False, skip_captions=False): - sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") - course = udemy.course(self.url, self.username, self.password) + def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', lecture_number='', lecture_start='', lecture_end='', path='', quality='', caption_only=False, skip_captions=False, unsafe=False): + if not self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login as " + fm + sb +"(%s)" % (self.username) + fg + sb +"...\n") + if self.cookies: + sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to login using cookies ...\n") + course = udemy.course(url=self.url, username=self.username, password=self.password, cookies=self.cookies) course_id = course.id course_name = course.title chapters = course.get_chapters() @@ -492,27 +545,35 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', lectures_count = chapter.lectures if lecture_end and lecture_end > lectures_count: lecture_end = lectures_count - filepath = "%s\\%s" % (course_path, chapter_title) if os.name == 'nt' else "%s/%s" % (course_path, chapter_title) + + if unsafe: + filepath = u"%s\\%s" % (course_path, chapter.unsafe_title) if os.name == 'nt' else u"%s/%s" % (course_path, chapter.unsafe_title) + if not unsafe: + filepath = "%s\\%s" % (course_path, chapter_title) if os.name == 'nt' else "%s/%s" % (course_path, chapter_title) try: os.makedirs(filepath) except Exception as e: pass sys.stdout.write (fc + sd + "\n[" + fm + sb + "*" + fc + sd + "] : " + fm + sb + "Downloading chapter : ({index})\n".format(index=chapter_index)) - sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s)\n" % (chapter_title)) - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Found (%s) lectures ...\n" % (lectures_count)) + if not unsafe: + sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s)\n" % (chapter_title)) + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Found (%s) lectures ...\n" % (lectures_count)) + if unsafe: + sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%02d-%s)\n" % (int(chapter_index), chapter_id)) + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture(s) (%s).\n" % (lectures_count)) lecture_start = _lectures_start lecture_end = lectures_count if lecture_start and not lecture_end else _lectures_end if lecture_number and lecture_number > 0 and lecture_number <= lectures_count: lecture = lectures[lecture_number-1] lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -526,7 +587,7 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', lecture_best = lecture_best if lecture.html: lecture.dump(filepath=filepath) - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -540,19 +601,19 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', lecture_best = lecture_best if lecture.html: lecture.dump(filepath=filepath) - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif lecture_start and lecture_start > 0 and lecture_start <= lecture_end and lecture_end <= lectures_count: while lecture_start <= lecture_end: lecture = lectures[lecture_start-1] lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -565,8 +626,8 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', if not lecture_best: lecture_best = lecture_best if lecture.html: - lecture.dump(filepath=filepath) - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_assets=lecture_assets, filepath=filepath) + lecture.dump(filepath=filepath, unsafe=unsafe) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -579,21 +640,21 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', if not lecture_best: lecture_best = lecture_best if lecture.html: - lecture.dump(filepath=filepath) - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + lecture.dump(filepath=filepath, unsafe=unsafe) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) lecture_start += 1 else: inner_index = 1 for lecture in lectures: lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -606,8 +667,8 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', if not lecture_best: lecture_best = lecture_best if lecture.html: - lecture.dump(filepath=filepath) - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath) + lecture.dump(filepath=filepath, unsafe=unsafe) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -620,8 +681,8 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', if not lecture_best: lecture_best = lecture_best if lecture.html: - lecture.dump(filepath=filepath) - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + lecture.dump(filepath=filepath, unsafe=unsafe) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) inner_index += 1 elif chapter_start and chapter_start > 0 and chapter_start <= chapter_end and chapter_end <= total_chapters: while chapter_start <= chapter_end: @@ -631,27 +692,34 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', chapter_title = chapter.title lectures = chapter.get_lectures() lectures_count = chapter.lectures - filepath = "%s\\%s" % (course_path, chapter_title) if os.name == 'nt' else "%s/%s" % (course_path, chapter_title) + if unsafe: + filepath = u"%s\\%s" % (course_path, chapter.unsafe_title) if os.name == 'nt' else u"%s/%s" % (course_path, chapter.unsafe_title) + if not unsafe: + filepath = "%s\\%s" % (course_path, chapter_title) if os.name == 'nt' else "%s/%s" % (course_path, chapter_title) try: os.makedirs(filepath) except Exception as e: pass sys.stdout.write (fc + sd + "\n[" + fm + sb + "*" + fc + sd + "] : " + fm + sb + "Downloading chapter : ({index} of {total})\n".format(index=chapter_start, total=chapter_end)) - sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s)\n" % (chapter_title)) - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Found (%s) lectures ...\n" % (lectures_count)) + if not unsafe: + sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%s)\n" % (chapter_title)) + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Found (%s) lectures ...\n" % (lectures_count)) + if unsafe: + sys.stdout.write (fc + sd + "[" + fw + sb + "+" + fc + sd + "] : " + fw + sd + "Chapter (%02d-%s)\n" % (int(chapter_index), chapter_id)) + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Lecture(s) (%s).\n" % (lectures_count)) lecture_start = _lectures_start lecture_end = lectures_count if lecture_start and not lecture_end else _lectures_end if lecture_number and lecture_number > 0 and lecture_number <= lectures_count: lecture = lectures[lecture_number-1] lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -663,7 +731,7 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', index += 1 if not lecture_best: lecture_best = lecture_best - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -675,19 +743,19 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', index += 1 if not lecture_best: lecture_best = lecture_best - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_number, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif lecture_start and lecture_start > 0 and lecture_start <= lecture_end and lecture_end <= lectures_count: while lecture_start <= lecture_end: lecture = lectures[lecture_start-1] lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -699,7 +767,7 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', index += 1 if not lecture_best: lecture_best = lecture_best - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -711,20 +779,20 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', index += 1 if not lecture_best: lecture_best = lecture_best - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=lecture_start, lectures_count=lecture_end, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) lecture_start += 1 else: inner_index = 1 for lecture in lectures: lecture_id = lecture.id lecture_index = lecture.index - lecture_title = lecture.title + lecture_title = lecture.title if not unsafe else "Lecture id : %s" % (lecture_id) lecture_assets = lecture.assets lecture_subtitles = lecture.subtitles lecture_best = lecture.getbest() lecture_streams = lecture.streams if caption_only and not skip_captions: - self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_captions_only(lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) elif skip_captions and not caption_only: if quality: index = 0 @@ -736,7 +804,7 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', index += 1 if not lecture_best: lecture_best = lecture_best - self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_only(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) else: if quality: index = 0 @@ -748,7 +816,7 @@ def chapter_download(self, chapter_number='', chapter_start='', chapter_end='', index += 1 if not lecture_best: lecture_best = lecture_best - self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath) + self.download_lectures_and_captions(lecture_best=lecture_best, lecture_title=lecture_title, inner_index=inner_index, lectures_count=lectures_count, lecture_subtitles=lecture_subtitles, lecture_assets=lecture_assets, filepath=filepath, unsafe=unsafe) inner_index += 1 chapter_start += 1 else: @@ -791,6 +859,11 @@ def main(): dest='password',\ type=str,\ help="Password of your account.",metavar='') + authentication.add_argument( + '-k', '--cookies',\ + dest='cookies',\ + type=str,\ + help="Cookies to authenticate with.",metavar='') advance = parser.add_argument_group("Advance") advance.add_argument( @@ -850,6 +923,16 @@ def main(): dest='cache',\ action='store_true',\ help="Cache your credentials to use it later.") + other.add_argument( + '--names',\ + dest='names_only',\ + action='store_true',\ + help="Do not download but save lecture names to file.") + other.add_argument( + '--unsafe',\ + dest='unsafe',\ + action='store_true',\ + help="Download all course with unsafe names.") other.add_argument( '--sub-only',\ dest='caption_only',\ @@ -862,46 +945,21 @@ def main(): help="Download course but skip captions/subtitle.") options = parser.parse_args() - if not options.username and not options.password: - username = fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Username : " + fg + sb - password = fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Password : " + fc + sb - config = use_cached_credentials() - if config and isinstance(config, dict): - sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Loading configs..") - email = config.get('username') or None - passwd = config.get('password') or None - quality = config.get('quality') or None - output = config.get('output') or None - time.sleep(1) - if email and passwd: - sys.stdout.write ("\r" + fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Loading configs.. (" + fc + sb + "done" + fg + sd + ")\n") - else: - sys.stdout.write ("\r" + fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Loading configs.. (" + fr + sb + "failed" + fg + sd + ")\n") - email = getpass.getuser(prompt=username) - passwd = getpass.getpass(prompt=password) - print("") - else: - email = getpass.getuser(prompt=username) - passwd = getpass.getpass(prompt=password) - print("") - if email and passwd: - udemy = Udemy(url=options.course, username=email, password=passwd) - else: - sys.stdout.write('\n' + fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sb + "Username and password is required.\n") - sys.exit(0) - - if options.cache: - cache_credentials() - + if options.cookies: + f_in = open(options.cookies) + cookies = [line for line in (l.strip() for l in f_in) if line] + f_in.close() + cookies = cookies[0] + udemy = Udemy(url=options.course, cookies=cookies) if options.list and not options.save: - try: - udemy.course_list_down(chapter_number=options.chapter, lecture_number=options.lecture) - except KeyboardInterrupt as e: - sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") - sys.exit(0) + try: + udemy.course_list_down(chapter_number=options.chapter, lecture_number=options.lecture, unsafe=options.unsafe) + except KeyboardInterrupt as e: + sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") + sys.exit(0) elif not options.list and options.save: try: - udemy.course_save(path=options.output, quality=options.quality, caption_only=options.caption_only, skip_captions=options.skip_captions) + udemy.course_save(path=options.output, quality=options.quality, caption_only=options.caption_only, skip_captions=options.skip_captions, names_only=options.names_only, unsafe=options.unsafe) except KeyboardInterrupt as e: sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") sys.exit(0) @@ -913,39 +971,39 @@ def main(): if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.lecture_start and options.lecture_end and not options.lecture: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.lecture_start and not options.lecture_end and not options.lecture: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) else: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_number=options.chapter, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.chapter_start and options.chapter_end and not options.chapter: @@ -953,39 +1011,39 @@ def main(): if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.lecture_start and options.lecture_end and not options.lecture: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.lecture_start and not options.lecture_end and not options.lecture: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) else: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.chapter_start and not options.chapter_end and not options.chapter: @@ -993,208 +1051,391 @@ def main(): if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.lecture_start and options.lecture_end and not options.lecture: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) elif options.lecture_start and not options.lecture_end and not options.lecture: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) else: if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, caption_only=options.caption_only) + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) else: - udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality) + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, unsafe=options.unsafe) else: if options.caption_only and not options.skip_captions: - udemy.course_download(caption_only=options.caption_only, path=options.output) + udemy.course_download(caption_only=options.caption_only, path=options.output, unsafe=options.unsafe) elif not options.caption_only and options.skip_captions: - udemy.course_download(skip_captions=options.skip_captions, path=options.output, quality=options.quality) + udemy.course_download(skip_captions=options.skip_captions, path=options.output, quality=options.quality, unsafe=options.unsafe) else: - udemy.course_download(path=options.output, quality=options.quality) + udemy.course_download(path=options.output, quality=options.quality, unsafe=options.unsafe) + + + if not options.cookies: + if not options.username and not options.password: + username = fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Username : " + fg + sb + password = fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Password : " + fc + sb + config = use_cached_credentials() + if config and isinstance(config, dict): + sys.stdout.write (fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Loading configs..") + email = config.get('username') or None + passwd = config.get('password') or None + quality = config.get('quality') or None + output = config.get('output') or None + time.sleep(1) + if email and passwd: + sys.stdout.write ("\r" + fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Loading configs.. (" + fc + sb + "done" + fg + sd + ")\n") + else: + sys.stdout.write ("\r" + fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sd + "Loading configs.. (" + fr + sb + "failed" + fg + sd + ")\n") + email = getpass.getuser(prompt=username) + passwd = getpass.getpass(prompt=password) + print("") + else: + email = getpass.getuser(prompt=username) + passwd = getpass.getpass(prompt=password) + print("") + if email and passwd: + udemy = Udemy(url=options.course, username=email, password=passwd) + else: + sys.stdout.write('\n' + fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sb + "Username and password is required.\n") + sys.exit(0) - elif options.username and options.password: - - udemy = Udemy(url=options.course, username=options.username, password=options.password) - - if options.cache: - cache_credentials(username=options.username, password=options.password) + if options.cache: + cache_credentials() - if options.list and not options.save: - try: - udemy.course_list_down(chapter_number=options.chapter, lecture_number=options.lecture) - except KeyboardInterrupt as e: - sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") - sys.exit(0) - elif not options.list and options.save: - try: - udemy.course_save(path=options.output, quality=options.quality, caption_only=options.caption_only, skip_captions=options.skip_captions) - except KeyboardInterrupt as e: - sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") - sys.exit(0) - elif not options.list and not options.save: + if options.list and not options.save: + try: + udemy.course_list_down(chapter_number=options.chapter, lecture_number=options.lecture, unsafe=options.unsafe) + except KeyboardInterrupt as e: + sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") + sys.exit(0) + elif not options.list and options.save: + try: + udemy.course_save(path=options.output, quality=options.quality, caption_only=options.caption_only, skip_captions=options.skip_captions, names_only=options.names_only, unsafe=options.unsafe) + except KeyboardInterrupt as e: + sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") + sys.exit(0) + elif not options.list and not options.save: - if options.chapter and not options.chapter_end and not options.chapter_start: + if options.chapter and not options.chapter_end and not options.chapter_start: - if options.lecture and not options.lecture_end and not options.lecture_start: + if options.lecture and not options.lecture_end and not options.lecture_start: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions) - else: - udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) - elif options.lecture_start and options.lecture_end and not options.lecture: + elif options.lecture_start and options.lecture_end and not options.lecture: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) - else: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) - elif options.lecture_start and not options.lecture_end and not options.lecture: + elif options.lecture_start and not options.lecture_end and not options.lecture: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) - else: - udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) - else: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, skip_captions=options.skip_captions) else: - udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, unsafe=options.unsafe) - elif options.chapter_start and options.chapter_end and not options.chapter: + elif options.chapter_start and options.chapter_end and not options.chapter: + + if options.lecture and not options.lecture_end and not options.lecture_start: - if options.lecture and not options.lecture_end and not options.lecture_start: + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions) - else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality) + elif options.lecture_start and options.lecture_end and not options.lecture: - elif options.lecture_start and options.lecture_end and not options.lecture: + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + elif options.lecture_start and not options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) + else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, unsafe=options.unsafe) - elif options.lecture_start and not options.lecture_end and not options.lecture: + elif options.chapter_start and not options.chapter_end and not options.chapter: + + if options.lecture and not options.lecture_end and not options.lecture_start: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and not options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) + else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, unsafe=options.unsafe) else: + if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, caption_only=options.caption_only) + + udemy.course_download(caption_only=options.caption_only, path=options.output, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + + udemy.course_download(skip_captions=options.skip_captions, path=options.output, quality=options.quality, unsafe=options.unsafe) + else: - udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality) - elif options.chapter_start and not options.chapter_end and not options.chapter: + udemy.course_download(path=options.output, quality=options.quality, unsafe=options.unsafe) - if options.lecture and not options.lecture_end and not options.lecture_start: + elif options.username and options.password: + + udemy = Udemy(url=options.course, username=options.username, password=options.password) + + if options.cache: + cache_credentials(username=options.username, password=options.password) + if options.list and not options.save: + try: + udemy.course_list_down(chapter_number=options.chapter, lecture_number=options.lecture, unsafe=options.unsafe) + except KeyboardInterrupt as e: + sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") + sys.exit(0) + elif not options.list and options.save: + # pprint(vars(options)) + # exit(0) + try: + udemy.course_save(path=options.output, quality=options.quality, caption_only=options.caption_only, skip_captions=options.skip_captions, names_only=options.names_only, unsafe=options.unsafe) + except KeyboardInterrupt as e: + sys.stdout.write (fc + sd + "[" + fr + sb + "-" + fc + sd + "] : " + fr + sd + "User Interrupted..\n") + sys.exit(0) + elif not options.list and not options.save: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions) - else: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality) + if options.chapter and not options.chapter_end and not options.chapter_start: - elif options.lecture_start and options.lecture_end and not options.lecture: + if options.lecture and not options.lecture_end and not options.lecture_start: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions) - else: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter,lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) - elif options.lecture_start and not options.lecture_end and not options.lecture: + elif options.lecture_start and options.lecture_end and not options.lecture: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and not options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) + else: - udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_number=options.chapter, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.chapter_start and options.chapter_end and not options.chapter: + + if options.lecture and not options.lecture_end and not options.lecture_start: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and not options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) - else: - if options.caption_only and not options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, caption_only=options.caption_only) - elif not options.caption_only and options.skip_captions: - udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions) else: - udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, chapter_end=options.chapter_end, path=options.output, quality=options.quality, unsafe=options.unsafe) - else: + elif options.chapter_start and not options.chapter_end and not options.chapter: - if options.caption_only and not options.skip_captions: + if options.lecture and not options.lecture_end and not options.lecture_start: - udemy.course_download(caption_only=options.caption_only, path=options.output) - elif not options.caption_only and options.skip_captions: + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_number=options.lecture, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, lecture_end=options.lecture_end, path=options.output, quality=options.quality, unsafe=options.unsafe) + + elif options.lecture_start and not options.lecture_end and not options.lecture: + + + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, lecture_start=options.lecture_start, path=options.output, quality=options.quality, unsafe=options.unsafe) - udemy.course_download(skip_captions=options.skip_captions, path=options.output, quality=options.quality) + else: + if options.caption_only and not options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, caption_only=options.caption_only, unsafe=options.unsafe) + elif not options.caption_only and options.skip_captions: + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, skip_captions=options.skip_captions, unsafe=options.unsafe) + else: + udemy.chapter_download(chapter_start=options.chapter_start, path=options.output, quality=options.quality, unsafe=options.unsafe) else: - udemy.course_download(path=options.output, quality=options.quality) + if options.caption_only and not options.skip_captions: + + udemy.course_download(caption_only=options.caption_only, path=options.output, unsafe=options.unsafe) + + elif not options.caption_only and options.skip_captions: + + udemy.course_download(skip_captions=options.skip_captions, path=options.output, quality=options.quality, unsafe=options.unsafe) + + else: + + udemy.course_download(path=options.output, quality=options.quality, unsafe=options.unsafe) if __name__ == '__main__': try: diff --git a/udemy/__init__.py b/udemy/__init__.py index c5f68bb..55f3d35 100644 --- a/udemy/__init__.py +++ b/udemy/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -__version__ = "0.4" +__version__ = "0.5" __author__ = "Nasir Khan (r0ot h3x49)" __license__ = 'MIT' __copyright__ = 'Copyright (c) 2018 Nasir Khan (r0ot h3x49)' diff --git a/udemy/_auth.py b/udemy/_auth.py index d1389cc..5c42b3a 100644 --- a/udemy/_auth.py +++ b/udemy/_auth.py @@ -66,13 +66,14 @@ def _form_hidden_input(self, form_id): }) return login_form - def authenticate(self): - form = self._form_hidden_input('login-form') - auth_response = self._session._post(LOGIN_URL, data=form) - auth_cookies = auth_response.cookies + def authenticate(self, access_token='', client_id=''): + if not access_token and not client_id: + form = self._form_hidden_input('login-form') + auth_response = self._session._post(LOGIN_URL, data=form) + auth_cookies = auth_response.cookies - access_token = auth_cookies.get('access_token') or None - client_id = auth_cookies.get('client_id') or None + access_token = auth_cookies.get('access_token') or None + client_id = auth_cookies.get('client_id') or None if access_token and client_id: self._session._set_auth_headers(access_token=access_token, client_id=client_id) diff --git a/udemy/_colorized/banner.py b/udemy/_colorized/banner.py index d907be0..c476008 100644 --- a/udemy/_colorized/banner.py +++ b/udemy/_colorized/banner.py @@ -32,7 +32,7 @@ def banner(): %s%s / /_/ / /_/ / __/ / / / / / /_/ /_____/ /_/ / / %s%s \__,_/\__,_/\___/_/ /_/ /_/\__, / \__,_/_/ %s%s /____/ - %s%sVersion : %s%s0.4 + %s%sVersion : %s%s0.5 %s%sAuthor : %s%sNasir Khan (r0ot h3x49) %s%sGithub : %s%shttps://github.com/r0oth3x49 diff --git a/udemy/_extract.py b/udemy/_extract.py index cffb243..5bae1a3 100644 --- a/udemy/_extract.py +++ b/udemy/_extract.py @@ -37,6 +37,7 @@ unescapeHTML ) from ._compat import ( + re, time, encoding, conn_error, @@ -57,6 +58,11 @@ class Udemy(ProgressBar): def __init__(self): self._session = '' + def _clean(self, text): + ok = re.compile(r'[^\\/:*?"<>|]') + text = "".join(x if ok.match(x) else "_" for x in text) + return re.sub('\.+$', '', text) if text.endswith(".") else text + def _course_name(self, url): if '/learn/v4' in url: url = url.split("learn/v4")[0] @@ -67,9 +73,15 @@ def _sanitize(self, unsafetext): text = sanitize(slugify(unsafetext, lower=False, spaces=True, ok=SLUG_OK + '().')) return text - def _login(self, username='', password=''): - auth = UdemyAuth(username=username, password=password) - self._session = auth.authenticate() + def _login(self, username='', password='', cookies=''): + if not cookies: + auth = UdemyAuth(username=username, password=password) + self._session = auth.authenticate() + if cookies: + access_token = re.search(r'(?<=access_token=)(\w+)', str(cookies)).group() + client_id = re.search(r'(?<=client_id=)([a-fA-F\d]{32})', str(cookies)).group() + auth = UdemyAuth() + self._session = auth.authenticate(access_token=access_token, client_id=client_id) if self._session is not None: return {'login' : 'successful'} else: @@ -79,6 +91,9 @@ def _logout(self): return self._session.terminate() def _extract_course_info(self, url): + if 'www' not in url: + self._session._headers['Host'] = url.replace("https://", "").split('/', 1)[0] + self._session._headers['Referer'] = url try: webpage = self._session._get(url).text except conn_error as e: @@ -98,7 +113,7 @@ def _extract_course_info(self, url): fatal=False, ) course_id = course.get('id') or search_regex( - (r'"id"\s*:\s*(\d+)', r'data-course-id=["\'](\d+)'), + (r'data-course-id=["\'](\d+)', r'"id"\s*:\s*(\d+)'), webpage, 'course id' ) @@ -337,14 +352,15 @@ def _real_extract(self, url=''): if clazz == 'chapter': lectures = [] chapter_index = entry.get('object_index') - chapter_title = self._sanitize(entry.get('title')) - chapter_title = re.sub('\.+$', '', chapter_title) if chapter_title.endswith(".") else chapter_title + chapter_title = self._clean(self._sanitize(entry.get('title'))) chapter = "{0:02d} {1!s}".format(chapter_index, chapter_title) + unsafe_chapter = u'{0:02d} '.format(chapter_index) + self._clean(entry.get('title')) if chapter not in _udemy['chapters']: _udemy['chapters'].append({ 'chapter_title' : chapter, 'chapter_id' : entry.get("id"), 'chapter_index' : chapter_index, + 'unsafe_chapter' : unsafe_chapter, 'lectures' : [], }) counter += 1 @@ -352,16 +368,17 @@ def _real_extract(self, url=''): lecture_id = entry.get("id") if len(_udemy['chapters']) == 0: - lectures = [] - chapter_index = entry.get('object_index') - chapter_title = self._sanitize(entry.get('title')) - chapter_title = re.sub('\.+$', '', chapter_title) if chapter_title.endswith(".") else chapter_title - chapter = "{0:03d} {1!s}".format(chapter_index, chapter_title) + lectures = [] + chapter_index = entry.get('object_index') + chapter_title = self._clean(self._sanitize(entry.get('title'))) + chapter = "{0:03d} {1!s}".format(chapter_index, chapter_title) + unsafe_chapter = u'{0:02d} '.format(chapter_index) + self._clean(entry.get('title')) if chapter not in _udemy['chapters']: _udemy['chapters'].append({ 'chapter_title' : chapter, 'chapter_id' : lecture_id, 'chapter_index' : chapter_index, + 'unsafe_chapter' : unsafe_chapter, 'lectures' : [], }) counter += 1 @@ -394,6 +411,7 @@ def _real_extract(self, url=''): lecture_index = entry.get('object_index') lecture_title = self._sanitize(entry.get('title')) lecture = "{0:03d} {1!s}".format(lecture_index, lecture_title) + unsafe_lecture = u'{0:03d} '.format(lecture_index) + entry.get('title') data, subs = self._html_to_json(view_html, lecture_id) if data and isinstance(data, dict): sources = data.get('sources') @@ -403,6 +421,7 @@ def _real_extract(self, url=''): 'lecture_index' : lecture_index, 'lectures_id' : lecture_id, 'lecture_title' : lecture, + 'unsafe_lecture' : unsafe_lecture, 'duration' : duration, 'assets' : retVal, 'assets_count' : len(retVal), @@ -416,6 +435,7 @@ def _real_extract(self, url=''): 'lecture_index' : lecture_index, 'lectures_id' : lecture_id, 'lecture_title' : lecture, + 'unsafe_lecture' : unsafe_lecture, 'html_content' : view_html, 'extension' : 'html', 'assets' : retVal, @@ -429,6 +449,7 @@ def _real_extract(self, url=''): lecture_index = entry.get('object_index') lecture_title = self._sanitize(entry.get('title')) lecture = "{0:03d} {1!s}".format(lecture_index, lecture_title) + unsafe_lecture = u'{0:03d} '.format(lecture_index) + entry.get('title') data = asset.get('stream_urls') if data and isinstance(data, dict): sources = data.get('Video') @@ -438,6 +459,7 @@ def _real_extract(self, url=''): 'lecture_index' : lecture_index, 'lectures_id' : lecture_id, 'lecture_title' : lecture, + 'unsafe_lecture' : unsafe_lecture, 'duration' : duration, 'assets' : retVal, 'assets_count' : len(retVal), @@ -451,6 +473,7 @@ def _real_extract(self, url=''): 'lecture_index' : lecture_index, 'lectures_id' : lecture_id, 'lecture_title' : lecture, + 'unsafe_lecture' : unsafe_lecture, 'html_content' : asset.get('body'), 'extension' : 'html', 'assets' : retVal, @@ -466,12 +489,13 @@ def _real_extract(self, url=''): if len(_udemy['chapters']) == 0: lectures = [] chapter_index = entry.get('object_index') - chapter_title = self._sanitize(entry.get('title')) - chapter_title = re.sub('\.+$', '', chapter_title) if chapter_title.endswith(".") else chapter_title + chapter_title = self._clean(self._sanitize(entry.get('title'))) chapter = "{0:03d} {1!s}".format(chapter_index, chapter_title) + unsafe_chapter = u'{0:02d} '.format(chapter_index) + self._clean(entry.get('title')) if chapter not in _udemy['chapters']: _udemy['chapters'].append({ 'chapter_title' : chapter, + 'unsafe_chapter' : unsafe_chapter, 'chapter_id' : lecture_id, 'chapter_index' : chapter_index, 'lectures' : [], diff --git a/udemy/_internal.py b/udemy/_internal.py index c832fdd..d4ddbba 100644 --- a/udemy/_internal.py +++ b/udemy/_internal.py @@ -46,8 +46,10 @@ def __init__(self, *args, **kwargs): def _fetch_course(self): if self._have_basic: return - - auth = self._login(username=self._username, password=self._password) + if not self._cookies: + auth = self._login(username=self._username, password=self._password) + if self._cookies: + auth = self._login(cookies=self._cookies) if auth.get('login') == 'successful': sys.stdout.write(fc + sd + "[" + fm + sb + "+" + fc + sd + "] : " + fg + sb + "Logged in successfully.\n") sys.stdout.write('\r' + fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Downloading course information .. \r") @@ -60,7 +62,8 @@ def _fetch_course(self): self._total_lectures = self._info['total_lectures'] self._chapters = [InternUdemyChapter(z) for z in self._info['chapters']] sys.stdout.write(fc + sd + "[" + fm + sb + "*" + fc + sd + "] : " + fg + sb + "Trying to logout now...\n") - self._logout() + if not self._cookies: + self._logout() sys.stdout.write(fc + sd + "[" + fm + sb + "+" + fc + sd + "] : " + fg + sb + "Logged out successfully.\n") self._have_basic = True if auth.get('login') == 'failed': @@ -75,6 +78,7 @@ def __init__(self, chapter): self._chapter_id = chapter['chapter_id'] self._chapter_title = chapter['chapter_title'] + self._unsafe_title = chapter['unsafe_chapter'] self._chapter_index = chapter['chapter_index'] self._lectures_count = chapter['lectures_count'] self._lectures = [InternUdemyLecture(z) for z in chapter['lectures']] @@ -88,6 +92,7 @@ def __init__(self, lectures): self._lecture_id = self._info['lectures_id'] self._lecture_title = self._info['lecture_title'] + self._unsafe_title = self._info['unsafe_lecture'] self._lecture_index = self._info['lecture_index'] self._subtitles_count = self._info['subtitle_count'] diff --git a/udemy/_shared.py b/udemy/_shared.py index 38ebefe..5ee04f3 100644 --- a/udemy/_shared.py +++ b/udemy/_shared.py @@ -42,11 +42,12 @@ class UdemyCourse(object): - def __init__(self, url, username, password, basic=True, callback=None): + def __init__(self, url, username='', password='', cookies='', basic=True, callback=None): self._url = url self._username = username self._password = password + self._cookies = cookies self._callback = callback or (lambda x: None) self._have_basic = False @@ -99,6 +100,7 @@ def __init__(self): self._chapter_id = None self._chapter_index = None self._chapter_title = None + self._unsafe_title = None self._lectures_count = None self._lectures = [] @@ -119,6 +121,10 @@ def index(self): def title(self): return self._chapter_title + @property + def unsafe_title(self): + return self._unsafe_title + @property def lectures(self): return self._lectures_count @@ -135,6 +141,7 @@ def __init__(self): self._extension = None self._lecture_id = None self._lecture_title = None + self._unsafe_title = None self._lecture_index = None self._sources_count = None self._assets_count = None @@ -161,6 +168,10 @@ def index(self): def title(self): return self._lecture_title + @property + def unsafe_title(self): + return self._unsafe_title + @property def html(self): return self._html_content @@ -207,7 +218,7 @@ def _sortkey(x, keyres=0, keyftype=0): def getbest(self): return self._getbest() - def dump(self, filepath): + def dump(self, filepath, unsafe=False): retVal = {} data = ''' @@ -228,13 +239,18 @@ def dump(self, filepath): ''' % (self.title, self.html) html = data.encode('utf-8').strip() - filename = "%s\\%s" % (filepath, self.title) if os.name == 'nt' else "%s/%s" % (filepath, self.title) + if not unsafe: + filename = "%s\\%s" % (filepath, self.title) if os.name == 'nt' else "%s/%s" % (filepath, self.title) + filename += ".html" + if unsafe: + filename = u"%s\\%s" % (filepath, self.unsafe_title) if os.name == 'nt' else u"%s/%s" % (filepath, self.unsafe_title) + filename += ".html" if os.path.isfile(filename): retVal = {"status" : "True", "msg" : "already downloaded"} return retVal - with open('{}.html'.format(filename), 'wb') as f: + with open(filename, 'wb') as f: try: f.write(html) except Exception as e: @@ -271,6 +287,12 @@ def _generate_filename(self): filename += "." + self.extension return filename + def _generate_unsafe_filename(self): + ok = re.compile(r'[^\\/:*?"<>|]') + filename = "".join(x if ok.match(x) else "_" for x in self.unsafe_title) + filename += "." + self.extension + return filename + @property def resolution(self): return self._resolution @@ -283,6 +305,10 @@ def quality(self): def url(self): return self._url + @property + def id(self): + return self._parent.id + @property def dimention(self): return self._dimention @@ -301,6 +327,16 @@ def filename(self): def title(self): return self._parent.title + @property + def unsafe_title(self): + return self._parent.unsafe_title + + @property + def unsafe_filename(self): + if not self._filename: + self._filename = self._generate_unsafe_filename() + return self._filename + @property def mediatype(self): return self._mediatype @@ -316,18 +352,18 @@ def get_filesize(self): self._fsize = 0 return self._fsize - def download(self, filepath="", quiet=False, callback=lambda *x: None): + def download(self, filepath="", unsafe=False, quiet=False, callback=lambda *x: None): savedir = filename = "" retVal = {} if filepath and os.path.isdir(filepath): - savedir, filename = filepath, self.filename + savedir, filename = filepath, self.filename if not unsafe else self.unsafe_filename elif filepath: savedir, filename = os.path.split(filepath) else: - filename = self.filename + filename = self.filename if not unsafe else self.unsafe_filename filepath = os.path.join(savedir, filename) @@ -463,6 +499,12 @@ def _generate_filename(self): filename += ".{}".format(self.extension) return filename + def _generate_unsafe_filename(self): + ok = re.compile(r'[^\\/:*?"<>|]') + filename = "".join(x if ok.match(x) else "_" for x in self.unsafe_title) + filename += ".{}".format(self.extension) + return filename + def _write_external_links(self, filepath): retVal = {} filename = filepath @@ -486,6 +528,10 @@ def _write_external_links(self, filepath): f.close() return retVal + @property + def id(self): + return self._parent.id + @property def url(self): return self._url @@ -498,12 +544,22 @@ def extension(self): def title(self): return self._parent.title + @property + def unsafe_title(self): + return self._parent.unsafe_title + @property def filename(self): if not self._filename: self._filename = self._generate_filename() return self._filename + @property + def unsafe_filename(self): + if not self._filename: + self._filename = self._generate_unsafe_filename() + return self._filename + @property def mediatype(self): return self._mediatype @@ -519,18 +575,18 @@ def get_filesize(self): self._fsize = 0 return self._fsize - def download(self, filepath="", quiet=False, callback=lambda *x: None): + def download(self, filepath="", unsafe=False, quiet=False, callback=lambda *x: None): savedir = filename = "" retVal = {} if filepath and os.path.isdir(filepath): - savedir, filename = filepath, self.filename + savedir, filename = filepath, self.filename if not unsafe else self.unsafe_filename elif filepath: savedir, filename = os.path.split(filepath) else: - filename = self.filename + filename = self.filename if not unsafe else self.unsafe_filename filepath = os.path.join(savedir, filename) @@ -670,6 +726,16 @@ def _generate_filename(self): filename += "-{}.{}".format(self.language, self.extension) return filename + def _generate_unsafe_filename(self): + ok = re.compile(r'[^\\/:*?"<>|]') + filename = "".join(x if ok.match(x) else "_" for x in self.unsafe_title) + filename += "-{}.{}".format(self.language, self.extension) + return filename + + @property + def id(self): + return self._parent.id + @property def url(self): return self._url @@ -686,12 +752,22 @@ def language(self): def title(self): return self._parent.title + @property + def unsafe_title(self): + return self._parent.unsafe_title + @property def filename(self): if not self._filename: self._filename = self._generate_filename() return self._filename + @property + def unsafe_filename(self): + if not self._filename: + self._filename = self._generate_unsafe_filename() + return self._filename + @property def mediatype(self): return self._mediatype @@ -707,18 +783,18 @@ def get_filesize(self): self._fsize = 0 return self._fsize - def download(self, filepath="", quiet=False, callback=lambda *x: None): + def download(self, filepath="", unsafe=False, quiet=False, callback=lambda *x: None): savedir = filename = "" retVal = {} if filepath and os.path.isdir(filepath): - savedir, filename = filepath, self.filename + savedir, filename = filepath, self.filename if not unsafe else self.unsafe_filename elif filepath: savedir, filename = os.path.split(filepath) else: - filename = self.filename + filename = self.filename if not unsafe else self.unsafe_filename filepath = os.path.join(savedir, filename) diff --git a/udemy/_udemy.py b/udemy/_udemy.py index 4686bf4..a7458c6 100644 --- a/udemy/_udemy.py +++ b/udemy/_udemy.py @@ -26,12 +26,13 @@ from ._internal import InternUdemyCourse as Udemy -def course(url, username, password, basic=True, callback=None): +def course(url, username='', password='', cookies='', basic=True, callback=None): """Returns udemy course instance. @params: url : Udemy course url required : type (string). username : Udemy email account required : type (string). password : Udemy account password required : type (string) + cookies : Udemy account logged in browser cookies optional : type (string) """ - return Udemy(url, username, password, basic, callback) \ No newline at end of file + return Udemy(url, username, password, cookies, basic, callback) \ No newline at end of file