Skip to content

Commit

Permalink
fixes Diaoul#428; I'm not proud of this fix; but it resolves the issue.
Browse files Browse the repository at this point in the history
Hopefully the Addic7ed administrator can respond to my email inquiring as to why they are blocking us by the User-Agent string.

Automation is the 21st century of the internet; No one wants to click 8
times past banners just to get a 1KB (in size) subtitle. Most people
have Ad blocking software and don't even see these banners anyway. There
are many other ways to get people on board with helping them out
financially (if that's what this is about), and at the same time
accomodate those who've automated their service. I will roll back this
commit when we can come to a better resolution.
  • Loading branch information
caronc committed Jan 28, 2015
1 parent d45e3b0 commit 3acbefb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 45 deletions.
21 changes: 21 additions & 0 deletions subliminal/api.py
Expand Up @@ -10,9 +10,30 @@
from .exceptions import ProviderNotAvailable, InvalidSubtitle
from .subtitle import get_subtitle_path
from socket import error as socket_error
from random import randint

logger = logging.getLogger(__name__)

# Agent List
AGENT_LIST = (
'Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:33.0) Gecko/20100101 Firefox/33.0',
'Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/31.0',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0',
'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36',
'Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko',
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A',
'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25',
)

# Returns a random agent to use from the list above
RANDOM_USER_AGENT = AGENT_LIST[randint(0, len(AGENT_LIST)-1)]

#: Entry point for the providers
PROVIDERS_ENTRY_POINT = 'subliminal.providers'

Expand Down
10 changes: 0 additions & 10 deletions subliminal/cli.py
Expand Up @@ -52,11 +52,6 @@ def subliminal():
filtering_group.add_argument('-f', '--force', action='store_true',
help='force subtitle download for videos with existing subtitles')

# addic7ed
addic7ed_group = parser.add_argument_group('addic7ed')
addic7ed_group.add_argument('--addic7ed-username', metavar='USERNAME', help='username for addic7ed provider')
addic7ed_group.add_argument('--addic7ed-password', metavar='PASSWORD', help='password for addic7ed provider')

# output
output_group = parser.add_argument_group('output')
output_exclusive_group = output_group.add_mutually_exclusive_group()
Expand Down Expand Up @@ -100,11 +95,6 @@ def subliminal():

# parse provider configs
provider_configs = {}
if (args.addic7ed_username is not None and args.addic7ed_password is None
or args.addic7ed_username is None and args.addic7ed_password is not None):
parser.error('argument --addic7ed-username/--addic7ed-password: both arguments are required or none')
if args.addic7ed_username is not None and args.addic7ed_password is not None:
provider_configs['addic7ed'] = {'username': args.addic7ed_username, 'password': args.addic7ed_password}

# parse color
if args.color and colorlog is None:
Expand Down
43 changes: 8 additions & 35 deletions subliminal/providers/addic7ed.py
Expand Up @@ -9,6 +9,7 @@
from . import IGNORED_CHARACTERS_RE
from .. import __version__
from ..cache import region
from ..api import RANDOM_USER_AGENT
from ..exceptions import ProviderConfigurationError, ProviderNotAvailable, InvalidSubtitle
from ..subtitle import Subtitle, is_valid_subtitle
from ..video import Episode
Expand Down Expand Up @@ -62,41 +63,13 @@ class Addic7edProvider(Provider):
video_types = (Episode,)
server = 'http://www.addic7ed.com'

def __init__(self, username=None, password=None):
if username is not None and password is None or username is None and password is not None:
raise ProviderConfigurationError('Username and password must be specified')
self.username = username
self.password = password
self.logged_in = False

def initialize(self):
self.session = requests.Session()
self.session.headers = {'User-Agent': 'Subliminal/%s' % __version__}
# login
if self.username is not None and self.password is not None:
logger.debug('Logging in to Addic7ed')
data = {'username': self.username, 'password': self.password, 'Submit': 'Log in'}
try:
r = self.session.post(self.server + '/dologin.php', data, timeout=10, allow_redirects=False)
except requests.Timeout:
raise ProviderNotAvailable('Timeout after 10 seconds')
if r.status_code == 302:
logger.debug('Successfully logged in to Addic7ed.')
self.logged_in = True
else:
logger.error('Failed to login to Addic7ed!')

def terminate(self):
# logout
if self.logged_in:
try:
r = self.session.get(self.server + '/logout.php', timeout=10)
logger.debug('Successfully logged out of Addic7ed.')
except requests.Timeout:
raise ProviderNotAvailable('Timeout after 10 seconds')
if r.status_code != 200:
raise ProviderNotAvailable('Request failed with status code %d' % r.status_code)
self.session.close()
#self.session.headers = {'User-Agent': 'Subliminal/%s' % __version__}
self.session.headers = {
'User-Agent': RANDOM_USER_AGENT,
'Referer': self.server,
}

def get(self, url, params=None):
"""Make a GET request on `url` with the given parameters
Expand All @@ -109,7 +82,7 @@ def get(self, url, params=None):
"""
try:
r = self.session.get(self.server + url, params=params, timeout=10)
r = self.session.get(self.server + url, params=params, timeout=30)
except requests.Timeout:
raise ProviderNotAvailable('Timeout after 10 seconds')
if r.status_code != 200:
Expand Down Expand Up @@ -184,7 +157,7 @@ def list_subtitles(self, video, languages):

def download_subtitle(self, subtitle):
try:
r = self.session.get(self.server + subtitle.download_link, timeout=10,
r = self.session.get(self.server + subtitle.download_link, timeout=30,
headers={'Referer': self.server + subtitle.referer})
except requests.Timeout:
raise ProviderNotAvailable('Timeout after 10 seconds')
Expand Down

7 comments on commit 3acbefb

@Diaoul
Copy link

@Diaoul Diaoul commented on 3acbefb Jan 31, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK now I understand. I've been contacted by Addic7ed developers in April 2014 and they wanted to know what information we would need from them because they were interested in building an API.

They didn't respond to my last email so I don't think they developed that API.

@sioban
Copy link

@sioban sioban commented on 3acbefb Feb 1, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least leaving the choice to the user would be a good idea.
I mean, using an alternate user agent might be an option.

@pannal
Copy link

@pannal pannal commented on 3acbefb Sep 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this problem still existing?

@Diaoul
Copy link

@Diaoul Diaoul commented on 3acbefb Sep 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so.

@pannal
Copy link

@pannal pannal commented on 3acbefb Sep 12, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, still getting ERROR (logger:31) - subliminal.api: Unexpected error in provider 'addic7ed', discarding it errors. Are you sure? How can I get further information on that error? Not seeing anything further in "com.plexapp.agents.subliminal.log", "com.plexapp.system.log", "Plex Media Server.log".

@caronc
Copy link
Owner Author

@caronc caronc commented on 3acbefb Sep 12, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just chiming in with a bit of confusion. Are you receiving your errors using this fork which has this patch in place? Or are you getting the errors by other means? I realize this might be a bit of a rhetorical question because I can't imagine any Plex addons are using anything but the upstream branch.

@pannal
Copy link

@pannal pannal commented on 3acbefb Sep 12, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess i was wrong about this one, as the errors I've mentioned are unrelated and self-generated. I'm currently playing around in the Plex sandbox.

Please sign in to comment.