diff --git a/Changelog.md b/Changelog.md index 71958b8..afbd7f2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,6 @@ + # Changelog - Re-did the entire codebase and implemented hulu API to scrap data. - Proxy support added. +- Fix for #22 +- Added Verbose Logging. \ No newline at end of file diff --git a/ReadMe.md b/ReadMe.md index 505ccf6..575fbd3 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,4 +1,4 @@ -# Hulusubs_dl | [![Build Status](https://travis-ci.com/Xonshiz/Hulu-Subs-Downloader.svg?branch=master)](https://travis-ci.com/Xonshiz/Hulu-Subs-Downloader) | [![GitHub release](https://img.shields.io/github/release/xonshiz/Hulu-Subs-Downloader.svg?style=flat-square)](https://github.com/xonshiz/Hulu-Subs-Downloader/releases/latest) | [![Github All Releases](https://img.shields.io/github/downloads/xonshiz/Hulu-Subs-Downloader/total.svg?style=flat-square)](https://github.com/xonshiz/Hulu-Subs-Downloader/releases) [![Open Source Helpers](https://www.codetriage.com/xonshiz/hulu-subs-downloader/badges/users.svg)](https://www.codetriage.com/xonshiz/hulu-subs-downloader) +# Hulusubs_dl | [![Build Status](https://travis-ci.com/Xonshiz/Hulusubs_dl.svg?branch=master)](https://travis-ci.com/github/Xonshiz/Hulusubs_dl) | [![GitHub release](https://img.shields.io/github/v/release/xonshiz/hulusubs_dl.svg?style=flat-square)](https://github.com/Xonshiz/Hulusubs_dl/releases/) | [![Github All Releases](https://img.shields.io/github/downloads/xonshiz/Hulusubs_dl/total.svg?style=flat-square)](https://github.com/xonshiz/Hulusubs_dl/releases) [![Open Source Helpers](https://www.codetriage.com/xonshiz/hulu-subs-downloader/badges/users.svg)](https://www.codetriage.com/xonshiz/hulu-subs-downloader) Hulusubs_dl is a command line tool to download subtitles from Hulu. Made for educational purposes. Since it's Python based, it can be easily deployed on every platform (Windows, macOS, Linux/Ubuntu etc.). You can find the installation instructions in #Installation Section of this readme. @@ -103,7 +103,8 @@ Currently, the script supports these arguments : ``` -h, --help Prints the basic help menu of the script and exits. -url,--hulu-url Url of the Hulu video or series to download subtitles from. --V,--version Prints the VERSION and exits. +--version Prints the VERSION and exits. +-v,--verbose Enables Verbose logging. -dd,--download-directory Specifies custom download location for the subtitles. -cookie, --set-cookie Saves/Updates Hulu Cookie -ext, --subtitle-extension Specifies the format of final subtitle file. Default is SRT. @@ -141,6 +142,7 @@ If you provide multiple proxies, the tool randomly chooses either of the proxies ## Opening Issues If you're opening a new Issue, please keep these points in your issue description: +- Run the script with `-v` or `--verbose` option and upload the errorlog file that tool creates. (remove your login credentials from it). - Your operating system (Windows, MacOS, Ubuntu etc.) - Operating System version: Windows 10/MacOS Catalina/Ubuntu 16 etc. - Which version are you using: Python Script/Windows EXE Binary/MacOS Homebrew @@ -152,9 +154,25 @@ If you're opening an issue to recommend some enhancements/changes, please be as - What you're about to write, does it explain the problem and solution properly? IS it enough for anyone to understand? ## How To Contribute -If you can make this tool better or fix some edge case(s), please feel free to `fork` this repository and then raise a `PR` after your changes. -Just make sure that the imports are proper, basic python naming conventions are followed. -If it's just a typo in some file, please just open an issue about it. When I have multiple open issues with typo fixes, I'll make the necessary changes. Reason being that I want to avoid useless CI getting triggered and pushing useless updates across the channel. +- If you can make this tool better or fix some edge case(s), please feel free to `fork` this repository and then raise a `PR` after your changes. +- Send PRs to `dev` branch only (don't send direct to master). +- Just make sure that the imports are proper, basic python naming conventions are followed. +- Add the necessary information about the change in "changelog.md". +- Remember to bump up the version in __version__.py. (Read how to name the version below). +- If it's just a typo in some file, please just open an issue about it. When I have multiple open issues with typo fixes, I'll make the necessary changes. Reason being that I want to avoid useless CI getting triggered and pushing useless updates across the channel. + +### Version Convention +You can find the version in `__verion__.py`. Just update the value according to these rules. + +Convention: Year.Month.Date + +So, if you're making that PR on 23rd June, 2020, version would be : 2020.06.23 + +What if you've raised multiple PRs on same day? Simple, just append version for the day like: + +Convention: Year.Month.Date.RecurrenceCount + +Again, taking example of 23rd June, 2020, let's say you've made 3 different PRs, different versions would be: `2020.06.23.1`, `2020.06.23.2` and `2020.06.23.3` # Donations If you're feeling generous, you can donate some $$ via Paypal: diff --git a/create_windows_exe_binary.sh b/create_mac_binary.sh similarity index 100% rename from create_windows_exe_binary.sh rename to create_mac_binary.sh diff --git a/docs/Changelog.md b/docs/Changelog.md index 7a2c214..afbd7f2 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -2,3 +2,5 @@ # Changelog - Re-did the entire codebase and implemented hulu API to scrap data. - Proxy support added. +- Fix for #22 +- Added Verbose Logging. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 3299db5..575fbd3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,19 +1,38 @@ -# Hulu Subs Downloader | [![Build Status](https://travis-ci.org/Xonshiz/Hulu-Subs-Downloader.svg?branch=master)](https://travis-ci.org/Xonshiz/Hulu-Subs-Downloader) | [![GitHub release](https://img.shields.io/github/release/xonshiz/Hulu-Subs-Downloader.svg?style=flat-square)](https://github.com/xonshiz/Hulu-Subs-Downloader/releases/latest) | [![Github All Releases](https://img.shields.io/github/downloads/xonshiz/Hulu-Subs-Downloader/total.svg?style=flat-square)](https://github.com/xonshiz/Hulu-Subs-Downloader/releases) [![Open Source Helpers](https://www.codetriage.com/xonshiz/hulu-subs-downloader/badges/users.svg)](https://www.codetriage.com/xonshiz/hulu-subs-downloader) -Hulusubs_dl is a command line tool to download subtitles from Hulu. Made for educational purposes (Hehe). +# Hulusubs_dl | [![Build Status](https://travis-ci.com/Xonshiz/Hulusubs_dl.svg?branch=master)](https://travis-ci.com/github/Xonshiz/Hulusubs_dl) | [![GitHub release](https://img.shields.io/github/v/release/xonshiz/hulusubs_dl.svg?style=flat-square)](https://github.com/Xonshiz/Hulusubs_dl/releases/) | [![Github All Releases](https://img.shields.io/github/downloads/xonshiz/Hulusubs_dl/total.svg?style=flat-square)](https://github.com/xonshiz/Hulusubs_dl/releases) [![Open Source Helpers](https://www.codetriage.com/xonshiz/hulu-subs-downloader/badges/users.svg)](https://www.codetriage.com/xonshiz/hulu-subs-downloader) +Hulusubs_dl is a command line tool to download subtitles from Hulu. Made for educational purposes. Since it's Python based, it can be easily deployed on every platform (Windows, macOS, Linux/Ubuntu etc.). You can find the installation instructions in #Installation Section of this readme. -#### **NOTE:** +**NOTE:** + This tool is based around and work with your hulu account's COOKIES. But, please do remember that you should NEVER share your account cookies with anyone and anywhere. Person having access to your cookies can use your account. Even when you're sharing any script failure, remember to not share/post your account cookies. +## Table of Content +* [Prerequisite](#prerequisite) +* [Python Support](#python-support) +* [Usage](#usage) +* [Things To Remember](#things-to-remember) +* [How To Find Hulu Cookie](#how-to-find-hulu-cookie) +* [Walkthrough Video](#walkthrough-video) +* [Installation](#installation) + * [Windows](#windows-exe-binary-installation) + * [Linux/Debian/Ubuntu](#linuxubuntukubuntu-or-any-other-linux-flavor-installation) + * [Mac OS X](#macos) +* [List of Arguments](#list-of-arguments) +* [Supported Formats](#supported-formats) +* [Proxy Usage](#proxy-usage) +* [Opening Issues](#opening-issues) +* [How To Contribute](#how-to-contribute) +* [Donations](#donations) + ## Prerequisite: Since Hulu has now protected their content behind an "auth" wall, we can't access the website. In layman words, we need to log in to Hulu, in order to watch anything or to be able to get basic things to extract the subtitles. -When you run the tool first time, it asks for "cookie" value. You can see it in #HowToFindCookie section of this readme. +When you run the tool first time, it asks for "cookie" value. You can see it in [`#How To Find Hulu Cookie`](#how-to-find-hulu-cookie) section of this readme. Also, there's a "configuration file" that is automatically made by this tool. It has some basic settings that you can use as "default" values. Some values saved in config file are: - Default Download Location: Tool will download the subtitles files in this directory (the tool makes proper folders). -- Extension: Extention of final subtitle file. You can choose from "Srt, ttml, vtt". Most players will play SRT subtitle files. +- Extension: Extension of final subtitle file. You can choose from "Srt, ttml, vtt, smi". Most players will play SRT subtitle files. - Language: Hulu has 2 languages available at the moment, i.e., "English" & "Spanish". You can download either of them. Type in "en" or "es" for respective languages. You can specify these values in the file once and then tool will use these defaults. You can use "arguments" to override these anytime. You would need to pass the argument with the script (described later in this readme). @@ -21,103 +40,111 @@ You can specify these values in the file once and then tool will use these defau ## Python Support This script should run on both Python 2 and 3. Check travisCI builds for exact python versions. -## List of Arguments -Currently, the script supports these arguments : -``` --h, --help Prints the basic help menu of the script and exits. --url,--hulu-url Url of the Hulu video or series to download subtitles from. --V,--version Prints the VERSION and exits. --dd,--download-directory Specifies custom download location for the subtitles. --cookie, --set-cookie Saves/Updates Hulu Cookie --ext, --subtitle-extension Specifies the format of final subtitle file. Default is SRT. --lang, --subtitle-language Specifies the language of the subtitle to download (subtitle in that language should be available on Hulu). --skip-conf, --skip-config Skips reading the config file (default values). Could be handy if you're writing batch scipts. --proxy, --proxy If you have an http/https proxy, you can provide it here. Tool will use this proxy to make all connections to Hulu. --config, --make-config Creates/Resets config file & exits(overwrites current default values). -``` - -## Proxy Usage -If you're not in US region and don't want to set up a system wide VPN, then you can provide any http/https proxy and hulusubs_dl would use this proxy to make all connections to Hulu. -Using proxy is simple, you can provide it like this -`python __main__.py -proxy 123.456.789.0123:4444` +## Usage +Using this tool can be a little tricky for some people at first, but it's pretty much straightforward. Try to follow along. +Make sure you've gone through [`#Prerequisites`](#prerequisite) and have proper version downloaded and installed on your system from the #Installation section. -If you're on windows, you won't be using `__main__.py`, instead you'll use `hulusubs_dl.exe`. Command would become: -`python hulusubs_dl.exe -proxy 123.456.789.0123:4444` +## Things To Remember +- You should renew your cookie value from time to time. These cookies expire after some time. So, if you're not able to log in or get the subtitles, try to renew your cookies. Renew cookies meaning, do the steps of [`#How To Find Hulu Cookie`](#how-to-find-hulu-cookie) again. +- If the tool isn't working, always try to download the latest release and then try again. If it still fails, open an issue here. +- Account COOKIES is sensitive data. Never share/post them anywhere. -You can also save proxies in the config file, so that you don't have to pass them as arguments everytime. -Trigger make config via `--make-config` flag and when the tool asks for Proxy, input proxy like this: +## How To Find Hulu Cookie +- Make sure you're in US region (use a VPN or Proxy) and open up your browser. +- Go to hulu.com and make sure you're not signed in (If you're signed in, just logout). +- Open developer console (Most browsers have shortcut F12). +- Navigate to "Network" tab. +- Log into hulu now. You'll see that "Network" tab now has many urls populated. +- There should be a "filter" option somewhere in developer console. You need to paste and filter this URL `discover.hulu.com/content/v5/me/state` +- You'll see only some URLs will be there now. Just select anyone of them and in that you need to see "Request Header" section. +- Copy the "Cookie" value from it. It'll be a very long text value. Copy all of it. +- Paste that cookie value when the hulusubs_dl asks for it. -Single Proxy : `123.456.789.0123:4444` +Refer to this screenshot for some clarification: -Multiple Proxies: `123.456.789.0123:4444;2212.127.11.32:5555` (Notice how we're splitting multiple proxies based on ';') +[![N|Solid](https://i.imgur.com/4Z0KOn4.png)](https://i.imgur.com/4Z0KOn4.png) -If you provide multiple proxies, the tool randomly chooses either of the proxies for every connection. This could avoid proxy ban, if you're using this too much. +## Walkthrough Video +If you're stuck somewhere or need clarification, here's an in-depth video on how to install and use this tool (Windows & Mac). +Video will be sharing in a week or so from now. -## Windows EXE Binary Installation +## Installation +### Windows EXE Binary Installation If you're on windows, it's recommended that you download and use "windows exe binary" to save your time. You can download the latest windows release from [RELEASE SECTION](https://github.com/Xonshiz/Hulu-Subs-Downloader/releases/latest) -Go there and download the ".exe" file. Then follow the usage instructions in #Usage. -After downloading this exe file, place it in some location that you can access. Because you would need to run this script everytime you want to download subtitles. +Go there and download the ".exe" file. Then follow the usage instructions in [Usage](#usage). +After downloading this exe file, place it in some location that you can access. Because you would need to run this script every time you want to download subtitles. Don't put this in your "Windows" or "System" folders. It might cause conflicts with permissions. -## Linux/Ubuntu/Kubuntu or any other linux flavor Installation +### Linux/Ubuntu/Kubuntu or any other linux flavor Installation Since I cannot generate a "binary" for these distributions, you will have to install and use python version directly. It's pretty much straightforward, you can just use pip to install hulusubs_dl. `pip install hulusubs_dl` -If for some reason, you're unable to use `pip`, try with `easy_install`. If everything fails, you can download code from this repository. +If for some reason, you're unable to use `pip`, try with `easy_install`. + +If everything fails, you can download code from this repository and then run. But, now you'll need to install the dependencies yourself. After downloading, navigate to this folder in your terminal and you can see a "requirements.txt" file. +You can install all dependencies via `pip install -r requirements.txt` All the external dependencies required by this tool are mentioned in that file. You can install them one by one. Since you're doing things manually, you might need to give this file executable rights, which can be done like this: `chmod +x __main__.py` -## MacOS -You can install this from homebrew. I'm working on it, will update this section soon. +### MacOS +If you're on macOS, it's recommended that you download and use "macOS binary" to save your time. +You can download the latest macOS release from [RELEASE SECTION](https://github.com/Xonshiz/Hulu-Subs-Downloader/releases/latest) +Go there and download the "hulusubs_dl" file. Do verify that you're not downloading "hulusubs_dl.exe". Then follow the usage instructions in [Usage](#usage). +After downloading this file, place it in some location that you can access. Because you would need to run this script every time you want to download subtitles. +Don't put this in restricted places like "/bin/ or "System" folders. It might cause conflicts with permissions. -## Usage -Using this tool can be a little tricky for some people at first, but it's pretty much straightforward. Try to follow along. -Make sure you've gone through #Prerequisites and have proper version downloaded and installed on your system from the #Installation section. +## List of Arguments +Currently, the script supports these arguments : + +``` +-h, --help Prints the basic help menu of the script and exits. +-url,--hulu-url Url of the Hulu video or series to download subtitles from. +--version Prints the VERSION and exits. +-v,--verbose Enables Verbose logging. +-dd,--download-directory Specifies custom download location for the subtitles. +-cookie, --set-cookie Saves/Updates Hulu Cookie +-ext, --subtitle-extension Specifies the format of final subtitle file. Default is SRT. +-lang, --subtitle-language Specifies the language of the subtitle to download (subtitle in that language should be available on Hulu). +-skip-conf, --skip-config Skips reading the config file (default values). Could be handy if you're writing batch scipts. +-proxy, --proxy If you have an http/https proxy, you can provide it here. Tool will use this proxy to make all connections to Hulu. +-config, --make-config Creates/Resets config file & exits(overwrites current default values). +``` ## Supported Formats Some arguments support some specific range of values. You can see them below here. Values are separated via ';'. + ``` -lang, --subtitle-language : en (default);es -ext, --subtitle-extension: srt (default);ttml;vtt;smi ``` -## How To Find Hulu Cookie -- Make sure you're in US region (use a VPN or Proxy) and open up your browser. -- Go to hulu.com and make sure you're not signed in (If you're signed in, just logout). -- Open developer console (Most browsers have shortcut F12). -- Navigate to "Network" tab. -- Log into hulu now. You'll see that "Network" tab now has many urls populated. -- There should be a "filter" option somewhere in developer console. You need to paste and filter this URL `discover.hulu.com/content/v5/me/state` -- You'll see only some URLs will be there now. Just select anyone of them and in that you need to see "Request Header" section. -- Copy the "Cookie" value from it. It'll be a very long text value. Copy all of it. -- Paste that cookie value when the hulusubs_dl asks for it. +## Proxy Usage +If you're not in US region and don't want to set up a system wide VPN, then you can provide any http/https proxy and hulusubs_dl would use this proxy to make all connections to Hulu. +Using proxy is simple, you can provide it like this +`python __main__.py -proxy 123.456.789.0123:4444` -Refer to this screenshot for some clarification: +If you're on windows, you won't be using `__main__.py`, instead you'll use `hulusubs_dl.exe`. Command would become: +`python hulusubs_dl.exe -proxy 123.456.789.0123:4444` -[![N|Solid](https://i.imgur.com/4Z0KOn4.png)](https://i.imgur.com/4Z0KOn4.png) +You can also save proxies in the config file, so that you don't have to pass them as arguments everytime. +Trigger make config via `--make-config` flag and when the tool asks for Proxy, input proxy like this: -## Things To Remember -- You should renew your cookie value from time to time. These cookies expire after some time. So, if you're not able to log in or get the subtitles, try to renew your cookies. Renew cookies meaning, do the steps of #GetHuluCookies again. -- If the tool isn't working, always try to download the latest release and then try again. If it still fails, open an issue here. -- Account COOKIES is sensitive data. Never share/post them anywhere. +Single Proxy : `123.456.789.0123:4444` -## Walkthrough Video -If you're stuck somewhere or need clarification, here's an in-depth video on how to install and use this tool (Windows & Mac). +Multiple Proxies: `123.456.789.0123:4444;2212.127.11.32:5555` (Notice how we're splitting multiple proxies based on ';') -## How To Contribute -If you can make this tool better or fix some edge case(s), please feel free to `fork` this repository and then raise a `PR` after your changes. -Just make sure that the imports are proper, basic python naming conventions are followed. -If it's just a typo in some file, please just open an issue about it. When I have multiple open issues with typo fixes, I'll make the necessary changes. Reason being that I want to avoid useless CI getting triggered and pushing useless updates across the channel. +If you provide multiple proxies, the tool randomly chooses either of the proxies for every connection. This could avoid proxy ban, if you're using this too much. ## Opening Issues If you're opening a new Issue, please keep these points in your issue description: +- Run the script with `-v` or `--verbose` option and upload the errorlog file that tool creates. (remove your login credentials from it). - Your operating system (Windows, MacOS, Ubuntu etc.) -- Operating System verion: Windows 10/MacOS Catalina/Ubuntu 16 etc. +- Operating System version: Windows 10/MacOS Catalina/Ubuntu 16 etc. - Which version are you using: Python Script/Windows EXE Binary/MacOS Homebrew - URL to the Hulu series which failed. - Detailed Description of the issue you're facing. @@ -126,3 +153,32 @@ If you're opening an issue to recommend some enhancements/changes, please be as - Will this "enhancement" be good for general public? or is it just for "you"? I cannot develop things just for 1 person. This tool is built for general masses and any custom enhancement would be charged. - What you're about to write, does it explain the problem and solution properly? IS it enough for anyone to understand? +## How To Contribute +- If you can make this tool better or fix some edge case(s), please feel free to `fork` this repository and then raise a `PR` after your changes. +- Send PRs to `dev` branch only (don't send direct to master). +- Just make sure that the imports are proper, basic python naming conventions are followed. +- Add the necessary information about the change in "changelog.md". +- Remember to bump up the version in __version__.py. (Read how to name the version below). +- If it's just a typo in some file, please just open an issue about it. When I have multiple open issues with typo fixes, I'll make the necessary changes. Reason being that I want to avoid useless CI getting triggered and pushing useless updates across the channel. + +### Version Convention +You can find the version in `__verion__.py`. Just update the value according to these rules. + +Convention: Year.Month.Date + +So, if you're making that PR on 23rd June, 2020, version would be : 2020.06.23 + +What if you've raised multiple PRs on same day? Simple, just append version for the day like: + +Convention: Year.Month.Date.RecurrenceCount + +Again, taking example of 23rd June, 2020, let's say you've made 3 different PRs, different versions would be: `2020.06.23.1`, `2020.06.23.2` and `2020.06.23.3` + +# Donations +If you're feeling generous, you can donate some $$ via Paypal: + +Paypal : [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/xonshiz) + +Any amount is appreciated :) + + diff --git a/hulusubs_dl/.DS_Store b/hulusubs_dl/.DS_Store index be6aeed..f253c95 100644 Binary files a/hulusubs_dl/.DS_Store and b/hulusubs_dl/.DS_Store differ diff --git a/hulusubs_dl/Hulusubs_dl_Error_Log.log b/hulusubs_dl/Hulusubs_dl_Error_Log.log new file mode 100644 index 0000000..5438d2f --- /dev/null +++ b/hulusubs_dl/Hulusubs_dl_Error_Log.log @@ -0,0 +1,4 @@ +DEBUG: Arguments Provided : Namespace(download_directory=None, hulu_url=None, make_config=False, proxy=[], set_cookie=None, skip_config=False, subtitle_extension='srt', subtitle_language='en', verbose=True, version=False) +DEBUG: Operating System : Darwin - 20.2.0 - Darwin Kernel Version 20.2.0: Wed Dec 2 20:39:59 PST 2020; root:xnu-7195.60.75~1/RELEASE_X86_64 +DEBUG: Python Version : 3.8.2 (64bit) +DEBUG: Hulusubs_dl Version : 2021.01.08.1 diff --git a/hulusubs_dl/__version__.py b/hulusubs_dl/__version__.py index d790517..f19cac3 100644 --- a/hulusubs_dl/__version__.py +++ b/hulusubs_dl/__version__.py @@ -1,4 +1,4 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -__version__ = "2021.01.06" +__version__ = "2021.01.08.1" diff --git a/hulusubs_dl/cust_utils/browser_instance.py b/hulusubs_dl/cust_utils/browser_instance.py index 94b1826..e0b750f 100644 --- a/hulusubs_dl/cust_utils/browser_instance.py +++ b/hulusubs_dl/cust_utils/browser_instance.py @@ -3,6 +3,7 @@ import requests import json from random import random +import logging def get_user_agent(): @@ -34,6 +35,9 @@ def get_request(url, cookie_value, text_only=False, **kwargs): "https": _rand_proxy } + logging.debug('GET url: {0}'.format(url)) + logging.debug('GET proxy: {0}'.format(proxy)) + sess = requests.session() connection = sess.get(url, headers=headers, proxies=proxy) @@ -73,6 +77,8 @@ def post_request(url, data, cookie_value, **kwargs): "http": _rand_proxy, "https": _rand_proxy } + logging.debug('POST url: {0}'.format(url)) + logging.debug('POST proxy: {0}'.format(proxy)) sess = requests.session() connection = sess.post(url, data=data, headers=headers, proxies=proxy) diff --git a/hulusubs_dl/cust_utils/utils.py b/hulusubs_dl/cust_utils/utils.py index af723a6..37a02ca 100644 --- a/hulusubs_dl/cust_utils/utils.py +++ b/hulusubs_dl/cust_utils/utils.py @@ -129,3 +129,9 @@ def read_file_data(file_path, file_name): with open(file_location, 'r') as f: content = f.read().strip() return None if content == "" else content + + +def get_clean_path_name(path_name): + remove_punctuation_map = dict((ord(char), None) for char in '\/*?:"<>|,;\'') + path_name.translate(remove_punctuation_map) + return path_name diff --git a/hulusubs_dl/hulu.py b/hulusubs_dl/hulu.py index 24fdc03..e64bfe2 100644 --- a/hulusubs_dl/hulu.py +++ b/hulusubs_dl/hulu.py @@ -7,6 +7,7 @@ import os import re from time import sleep +import logging class Hulu: @@ -19,20 +20,27 @@ def __init__(self, url, cookie_value, language, extension, download_location, pr print("URL Not Supported") def episode_link(self, url, cookie_value, language, extension, download_location, proxy=None): + logging.debug('Called: episode_link()') transcript_urls = {} eab_id = str(url).split('/watch/')[-1].replace('/', '') + logging.debug('initial eab_id: {0}'.format(eab_id)) eab_id_information = hulu_api.get_full_eab_id(eab_id, cookie_value) + logging.debug('\n----\neab_id_information: {0}\n----\n'.format(eab_id_information)) eab_id = dict(eab_id_information).get('eab_id', None) + logging.debug('eab_id: {0}'.format(eab_id)) if not eab_id: print("You seem to be out of USA. Use a VPN/Proxy.") return False payload = utils.get_playlist_body(eab_id=eab_id) + logging.debug('\n----\npayload: {0}\n----\n'.format(payload)) if payload: # Logic to find the URL for the language and extension provided and download it. playlist_info = hulu_api.get_playlist_information(payload, cookie_value) + logging.debug('\n----\nplaylist_info: {0}\n----\n'.format(playlist_info)) if playlist_info: playlist_info = dict(playlist_info) transcripts = playlist_info.get('transcripts_urls', None) + logging.debug('\n----\ntranscripts: {0}\n----\n'.format(transcripts)) if not transcripts: print("Couldn't find transcript URLs.Exiting.") return False @@ -41,19 +49,23 @@ def episode_link(self, url, cookie_value, language, extension, download_location # we will convert webvtt to any other subtitle format.So,we'll use that URL to get subtitle content. if extension not in utils.DEFAULT_SUB_EXT: transcript_urls[extension] = transcript_urls.get('webvtt', {}) + logging.debug('\n----\ntranscript_urls: {0}\n----\n'.format(transcript_urls)) video_metadata = dict(hulu_api.get_eab_id_metadata(eab_id, cookie_value, language)).get('items', {}) + logging.debug('\n----\nvideo_metadata: {0}\n----\n'.format(video_metadata)) video_metadata = dict(list(video_metadata)[0]) - series_name = video_metadata.get('series_name', "No Name Found") + series_name = utils.get_clean_path_name(video_metadata.get('series_name', "No Name Found")) season_number = video_metadata.get('season', "01") episode_number = video_metadata.get('number', "01") file_name = '{0} - S{1}E{2} [{3} Sub].{4}'.format(series_name, season_number, episode_number, language, extension) + logging.debug('\n----\nfile_name: {0}\n----\n'.format(file_name)) print("Downloading Subtitle For {0}".format(file_name)) selected_extension = transcript_urls.get(extension, None) if not selected_extension: print("Couldn't find {0} in Hulu".format(extension)) else: url = str(dict(selected_extension).get(language, None)).strip() + logging.debug('subtitle url eab_id: {0}'.format(url)) subtitle_content = browser_instance.get_request(url, cookie_value, text_only=True) path_created = path_util.create_paths( download_location + os.sep + series_name + os.sep + season_number) @@ -72,11 +84,14 @@ def episode_link(self, url, cookie_value, language, extension, download_location def show_link(self, url, cookie_value, language, extension, download_location, proxy=None): eab_id_matches = re.findall(r'-([0-9A-Za-z]+)', str(url).split('/series/')[-1]) + logging.debug('eab_id_matches: {0}'.format(eab_id_matches)) if eab_id_matches and len(eab_id_matches) > 1: eab_id_matches.pop(0) eab_id = '-'.join(eab_id_matches) + logging.debug('initial eab_id: {0}'.format(eab_id)) series_metadata = {} series_metadata = hulu_api.get_series_metadata(eab_id, cookie_value) + logging.debug('\n----\ninitial series_metadata: {0}\n----\n'.format(series_metadata)) if not series_metadata: print("Couldn't get series metadata. Exiting") return False @@ -90,6 +105,7 @@ def show_link(self, url, cookie_value, language, extension, download_location, p episodes_metadata = curr_item break series_metadata = dict(episodes_metadata).get('items', {}) + logging.debug('\n----\nseries_metadata: {0}\n----\n'.format(series_metadata)) season_numbers = [] season_episodes = [] if not series_metadata: @@ -102,6 +118,7 @@ def show_link(self, url, cookie_value, language, extension, download_location, p if current_id: season_numbers.append(str(current_id).split('::')[-1]) print("Getting Data For {0} Seasons.".format(len(season_numbers))) + logging.debug('\n----\nseason_numbers: {0}\n----\n'.format(season_numbers)) for season in season_numbers: # For every season, we'll collect EAB IDs of the episodes. season_metadata = dict(hulu_api.get_series_season_metadata(eab_id, cookie_value, season)).get('items', @@ -109,6 +126,7 @@ def show_link(self, url, cookie_value, language, extension, download_location, p for season_item in season_metadata: season_episodes.append(dict(season_item).get('id', None)) print("Total Episodes To Download: {0}".format(len(season_episodes))) + logging.debug('\n----\nseason_episodes: {0}\n----\n'.format(season_episodes)) for episode_eab in season_episodes: if episode_eab: sleep(1) # Let's not bombard Hulu's API with requests. diff --git a/hulusubs_dl/hulu_subs_dl.py b/hulusubs_dl/hulu_subs_dl.py index 0d9c6a2..6973bca 100644 --- a/hulusubs_dl/hulu_subs_dl.py +++ b/hulusubs_dl/hulu_subs_dl.py @@ -4,6 +4,8 @@ import os import sys import argparse +import logging +import platform from .cust_utils import * from .__version__ import __version__ from .hulu import Hulu @@ -23,12 +25,33 @@ def __init__(self, argv, cwd): self.subtitle_lang = None self.subtitle_extension = None self.proxy = [] + self.logger = False skip_config = False args = self.add_argparse() if args.version: print(__version__) sys.exit(0) + if args.verbose: + print("\n***Starting the script in Verbose Mode***\n") + try: + os.remove("Error_Log.log") + # with open(str(args.download_directory[0]) + str(os.sep) + "Error_Log.log", "w") as wf: + # wf.write("Writing...") + except Exception as VerboseError: + # print(VerboseError) + pass + logging.basicConfig(format='%(levelname)s: %(message)s', + filename=str(cwd) + str(os.sep) + "Hulusubs_dl_Error_Log.log", + level=logging.DEBUG) + logging.debug("Arguments Provided : %s" % args) + logging.debug("Operating System : %s - %s - %s" % (platform.system(), + platform.release(), + platform.version() + )) + logging.debug("Python Version : %s (%s)" % (platform.python_version(), platform.architecture()[0])) + logging.debug("Hulusubs_dl Version : {0}".format(__version__)) + self.logger = True if args.make_config: config_object = self.get_config_file_data() config_data = self.ask_config_file_data(config_object) @@ -49,6 +72,7 @@ def __init__(self, argv, cwd): print("Reading Configuration File.") if path_util.file_exists(cwd, config_file_name): config_file_data = eval(utils.read_file_data(cwd, config_file_name)) + logging.debug("\n----\nconfig_file_data: {0}\n----\n".format(config_file_data)) else: # ask config data from user config_object = self.get_config_file_data() @@ -85,6 +109,8 @@ def __init__(self, argv, cwd): if not args.set_cookie and path_util.file_exists(cwd, cookie_file_name): cookie_file_data = utils.read_file_data(cwd, cookie_file_name) + if not cookie_file_data: + logging.debug("No Cookie Found") else: cookie_from_user = self.get_cookie_from_user() cookie_written = utils.create_file(cwd, cookie_file_name, @@ -102,8 +128,11 @@ def __init__(self, argv, cwd): else: current_try += 1 - # Everything is set, let's call the main boss - Hulu(url, cookie_file_data, self.subtitle_lang, self.subtitle_extension, self.download_location, self.proxy) + try: + # Everything is set, let's call the main boss + Hulu(url, cookie_file_data, self.subtitle_lang, self.subtitle_extension, self.download_location, self.proxy) + except Exception as HuluException: + logging.debug("HuluException: {0}".format(HuluException)) def set_config_file_data(self, config_file_data): # We'll map the data to variables in this method @@ -174,5 +203,7 @@ def add_argparse(): parser.add_argument('-skip-conf', '--skip-config', action='store_true', help='Skips reading config file.') parser.add_argument('-proxy', '--proxy', nargs=1, help='Provides the Proxy to be used.', default=[]) parser.add_argument('-config', '--make-config', action='store_true', help='Creates/Resets Config File & exits.') + parser.add_argument("-v", "--verbose", help="Prints important debugging messages on screen.", action="store_true") args = parser.parse_args() return args +