Repository: pymedusa/Medusa

Issue:
Could not get a downloaded release name from the history table
Whenever I try to manually download a subtitle, it throws this error: "Could not get a downloaded release name from the history table".

The log doesn't provide any additional information:

> 2022-06-28 08:43:59 INFO	Thread-2 :: [ee1b898] Manual searching subtitles for: xxx
> 2022-06-28 08:43:59 INFO	Thread-2 :: [ee1b898] Starting to manual searching subtitles

I have subtitle providers available, and I can see that the subtitle is available on their site.

What can I do to fix this? it happens to all shows, all episodes.
(Auto downloading subtitles doesn't work either)

Thanks!


Discussion:
Did you download the episode through medusa, for which you are trying to get a sub?
Which subtitle provider did you have configured?
Enable debug logs, search for subtitle and post logs.
Thank you for the quick reply!

Medusa auto-downloaded it, I only had to move it to the post-processing folder manually because I've been having some issues with auto-tools (it doesn't auto-move to the completed download folder).
This also happens with manual downloads
Using opensubtitles and Wizdom (Wizdom is the more important one for me)
I have debug logs enabled, here's the log:

> 2022-06-28 09:00:22 WARNING	Thread :: [ee1b898] Unexpected error. Provider opensubtitles
> Traceback (most recent call last):
>   File "/app/medusa/ext/subliminal/core.py", line 115, in list_subtitles_provider
>     return self[provider].list_subtitles(video, provider_languages)
>   File "/app/medusa/ext/subliminal/core.py", line 67, in __getitem__
>     provider.initialize()
>   File "/app/medusa/ext/subliminal/providers/opensubtitles.py", line 129, in initialize
>     response = checked(self.server.LogIn(self.username, self.password, 'eng', self.user_agent))
>   File "/app/medusa/ext/subliminal/providers/opensubtitles.py", line 278, in checked
>     raise Unauthorized
> subliminal.providers.opensubtitles.Unauthorized
> 2022-06-28 09:00:22 WARNING	Thread :: [ee1b898] Unexpected error. Provider wizdom
> Traceback (most recent call last):
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 597, in urlopen
>     httplib_response = self._make_request(conn, method, url,
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 384, in _make_request
>     six.raise_from(e, None)
>   File "<string>", line 2, in raise_from
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 380, in _make_request
>     httplib_response = conn.getresponse()
>   File "/usr/lib/python3.9/http/client.py", line 1371, in getresponse
>     response.begin()
>   File "/usr/lib/python3.9/http/client.py", line 319, in begin
>     version, status, reason = self._read_status()
>   File "/usr/lib/python3.9/http/client.py", line 280, in _read_status
>     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
>   File "/usr/lib/python3.9/socket.py", line 704, in readinto
>     return self._sock.recv_into(b)
> ConnectionResetError: [Errno 104] Connection reset by peer
> During handling of the above exception, another exception occurred:
> Traceback (most recent call last):
>   File "/app/medusa/ext/requests/adapters.py", line 439, in send
>     resp = conn.urlopen(
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 637, in urlopen
>     retries = retries.increment(method, url, error=e, _pool=self,
>   File "/app/medusa/ext/urllib3/util/retry.py", line 367, in increment
>     raise six.reraise(type(error), error, _stacktrace)
>   File "/app/medusa/ext/urllib3/packages/six.py", line 685, in reraise
>     raise value.with_traceback(tb)
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 597, in urlopen
>     httplib_response = self._make_request(conn, method, url,
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 384, in _make_request
>     six.raise_from(e, None)
>   File "<string>", line 2, in raise_from
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 380, in _make_request
>     httplib_response = conn.getresponse()
>   File "/usr/lib/python3.9/http/client.py", line 1371, in getresponse
>     response.begin()
>   File "/usr/lib/python3.9/http/client.py", line 319, in begin
>     version, status, reason = self._read_status()
>   File "/usr/lib/python3.9/http/client.py", line 280, in _read_status
>     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
>   File "/usr/lib/python3.9/socket.py", line 704, in readinto
>     return self._sock.recv_into(b)
> urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
> During handling of the above exception, another exception occurred:
> Traceback (most recent call last):
>   File "/app/medusa/ext/subliminal/core.py", line 115, in list_subtitles_provider
>     return self[provider].list_subtitles(video, provider_languages)
>   File "/app/medusa/medusa/subtitle_providers/wizdom.py", line 193, in list_subtitles
>     return [s for s in self.query(title, season, episode, year, filename, imdb_id) if s.language in languages]
>   File "/app/medusa/medusa/subtitle_providers/wizdom.py", line 144, in query
>     r = self.session.get(url)
>   File "/app/medusa/ext/requests/sessions.py", line 555, in get
>     return self.request('GET', url, **kwargs)
>   File "/app/medusa/ext/requests/sessions.py", line 542, in request
>     resp = self.send(prep, **send_kwargs)
>   File "/app/medusa/ext/requests/sessions.py", line 655, in send
>     r = adapter.send(request, **kwargs)
>   File "/app/medusa/ext/requests/adapters.py", line 498, in send
>     raise ConnectionError(err, request=request)
> requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
> 2022-06-28 09:00:22 INFO	Thread :: [ee1b898] Manual searching subtitles for: xxx
> 2022-06-28 09:00:22 INFO	Thread :: [ee1b898] Starting to manual searching subtitles
> 2022-06-28 08:59:18 WARNING	Thread :: [ee1b898] Unexpected error. Provider opensubtitles
Another log specific for Wizdom

> 2022-06-28 09:09:47 WARNING	Thread :: [ee1b898] Unexpected error. Provider wizdom
> Traceback (most recent call last):
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 597, in urlopen
>     httplib_response = self._make_request(conn, method, url,
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 384, in _make_request
>     six.raise_from(e, None)
>   File "<string>", line 2, in raise_from
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 380, in _make_request
>     httplib_response = conn.getresponse()
>   File "/usr/lib/python3.9/http/client.py", line 1371, in getresponse
>     response.begin()
>   File "/usr/lib/python3.9/http/client.py", line 319, in begin
>     version, status, reason = self._read_status()
>   File "/usr/lib/python3.9/http/client.py", line 280, in _read_status
>     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
>   File "/usr/lib/python3.9/socket.py", line 704, in readinto
>     return self._sock.recv_into(b)
> ConnectionResetError: [Errno 104] Connection reset by peer
> During handling of the above exception, another exception occurred:
> Traceback (most recent call last):
>   File "/app/medusa/ext/requests/adapters.py", line 439, in send
>     resp = conn.urlopen(
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 637, in urlopen
>     retries = retries.increment(method, url, error=e, _pool=self,
>   File "/app/medusa/ext/urllib3/util/retry.py", line 367, in increment
>     raise six.reraise(type(error), error, _stacktrace)
>   File "/app/medusa/ext/urllib3/packages/six.py", line 685, in reraise
>     raise value.with_traceback(tb)
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 597, in urlopen
>     httplib_response = self._make_request(conn, method, url,
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 384, in _make_request
>     six.raise_from(e, None)
>   File "<string>", line 2, in raise_from
>   File "/app/medusa/ext/urllib3/connectionpool.py", line 380, in _make_request
>     httplib_response = conn.getresponse()
>   File "/usr/lib/python3.9/http/client.py", line 1371, in getresponse
>     response.begin()
>   File "/usr/lib/python3.9/http/client.py", line 319, in begin
>     version, status, reason = self._read_status()
>   File "/usr/lib/python3.9/http/client.py", line 280, in _read_status
>     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
>   File "/usr/lib/python3.9/socket.py", line 704, in readinto
>     return self._sock.recv_into(b)
> urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
> During handling of the above exception, another exception occurred:
> Traceback (most recent call last):
>   File "/app/medusa/ext/subliminal/core.py", line 115, in list_subtitles_provider
>     return self[provider].list_subtitles(video, provider_languages)
>   File "/app/medusa/medusa/subtitle_providers/wizdom.py", line 193, in list_subtitles
>     return [s for s in self.query(title, season, episode, year, filename, imdb_id) if s.language in languages]
>   File "/app/medusa/medusa/subtitle_providers/wizdom.py", line 144, in query
>     r = self.session.get(url)
>   File "/app/medusa/ext/requests/sessions.py", line 555, in get
>     return self.request('GET', url, **kwargs)
>   File "/app/medusa/ext/requests/sessions.py", line 542, in request
>     resp = self.send(prep, **send_kwargs)
>   File "/app/medusa/ext/requests/sessions.py", line 655, in send
>     r = adapter.send(request, **kwargs)
>   File "/app/medusa/ext/requests/adapters.py", line 498, in send
>     raise ConnectionError(err, request=request)
> requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
> 2022-06-28 09:09:47 INFO	Thread :: [ee1b898] Manual searching subtitles for: xxx
> 2022-06-28 09:09:47 INFO	Thread :: [ee1b898] Starting to manual searching subtitles
So opensubtitles seems your not authenticated. but could also be that the provider is broken in subliminal (which is the package we use for the subtitle searching).

Wizdom is having connection issues. Also a subliminal error. Better report there.
https://github.com/Diaoul/subliminal
the warning your getting `"Could not get a downloaded release name from the history table"` could be caused because your postprocessing loop isn't complete. But that warning can also be ignored. If the subtitle provider is working, it should show results.
I'll open up a report there as well. Thank you. 
For the post processing loop - I think it does get completed given I transfer manually and get a notification from medusa that it got added correctly, but subtitles are not added (I have a telegram notification set up)
Maybe you'll need to enable `Use Failed Downloads` in config - search.. You could try that.
Wizdom is a medusa added custom subtitle provider. So this is a medusa bug.
I'll see if its an easy fix.
Thank you so much, I appreciate your help!
So apparently their json api, is down.
So if you enter this url in your browser, you'll get an error message.
`https://json.wizdom.xyz/tt0475784.json`.

Where normally you would get sub results.
So we could just not use the json api, and scrape the site.
But it'd rather know if this is a temp issue their having.

But I don't know hebrew, and I don't know if it's possible to get into contact with them.
Also the kodi addon is having the same issues.
https://github.com/wizupdate/service.subtitles.wizdom/issues/4
Thank you for the update, 
I've sent them a message via the contact me page, hope to get an answer soon.
Hello @p0psicles 
I got a response that their API has been updated and all addons need to comply with the new updates
I've also asked for samples/demo/documentation but have yet to receive anything
That's good news. As soon as I have the specs I'll fix it
As far as I can see there was a new addon released two months ago for Wizdom:
https://github.com/repoil/club/blob/master/service.subtitles.wizdom/service.subtitles.wizdom-2.0.6.zip

As part of it I can see some changes to how they pull subtitles:
```
def searchByIMDB(imdb, season=0, episode=0, version=0):
	filename = 'wizdom.imdb.%s.%s.%s.json' % (imdb, season, episode)
	url = "http://%s/search?action=by_id&imdb=%s&season=%s&episode=%s&version=%s" % (
		myDomain, imdb, season, episode, version)

	wlog("searchByIMDB:%s" % url)
	json = cachingJSON(filename,url)
	subs_rate = []  # TODO remove not in used
	if json != 0:
		for item_data in json:
			listitem = ListItem(label="Hebrew", label2=item_data["versioname"],
								thumbnailImage="he", iconImage="%s" % (item_data["score"]/2))
			if int(item_data["score"]) > 8:
				listitem.setProperty("sync", "true")
			url = "plugin://%s/?action=download&versioname=%s&id=%s&imdb=%s&season=%s&episode=%s" % (
					myScriptID, item_data["versioname"], item_data["id"],imdb, season, episode)
			addDirectoryItem(handle=int(sys.argv[1]), url=url, listitem=listitem, isFolder=False)
```

I'm not a coder, and there might be something that I am missing, hope that helps?
Okay, they got back to me with this:
The changes in the paths are:
For Download:
[[https://wizdom.xyz/files/sub/](https://deref-mail.com/mail/client/8DIQrmLahVI/dereferrer/?redirectUrl=https%3A%2F%2Fwizdom.xyz%2Ffiles%2Fsub%2F){WIZDUM_SUB_ID}]

For Search:
[[https://wizdom.xyz/search](https://deref-mail.com/mail/client/RuL4XqcxLYI/dereferrer/?redirectUrl=https%3A%2F%2Fwizdom.xyz%2Fsearch)] and then the query parameters are the same
 
Sorry for over-responding here, but as I get new information I share, as this is important to me :) 
Yeah that should be enough. I'll fix it when I get to it 
OKay so a valid search api call is `https://wizdom.xyz/api/search?action=by_id&imdb=tt10945036&season=1&episode=10`

Resolving patch:
diff --git a/medusa/subtitle_providers/wizdom.py b/medusa/subtitle_providers/wizdom.py
--- a/medusa/subtitle_providers/wizdom.py
+++ b/medusa/subtitle_providers/wizdom.py
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-import bisect
 import io
 import logging
 import os
@@ -31,8 +30,9 @@ class WizdomSubtitle(Subtitle):
     """Wizdom Subtitle."""
     provider_name = 'wizdom'
 
-    def __init__(self, language, hearing_impaired, page_link, series, season, episode, title, imdb_id, subtitle_id,
-                 releases):
+    def __init__(self, language, hearing_impaired, page_link, series,
+                 season, episode, title, imdb_id, subtitle_id, release):
+
         super(WizdomSubtitle, self).__init__(language, hearing_impaired, page_link)
         self.series = series
         self.season = season
@@ -41,7 +41,7 @@ def __init__(self, language, hearing_impaired, page_link, series, season, episod
         self.imdb_id = imdb_id
         self.subtitle_id = subtitle_id
         self.downloaded = 0
-        self.releases = releases
+        self.release = release
 
     @property
     def id(self):
@@ -65,13 +65,12 @@ def get_matches(self, video):
             if video.series_imdb_id and self.imdb_id == video.series_imdb_id:
                 matches.add('series_imdb_id')
             # guess
-            for release in self.releases:
-                matches |= guess_matches(video, guessit(release, {'type': 'episode'}))
+            matches |= guess_matches(video, guessit(self.release, {'type': 'episode'}))
+
         # movie
         elif isinstance(video, Movie):
             # guess
-            for release in self.releases:
-                matches |= guess_matches(video, guessit(release, {'type': 'movie'}))
+            matches |= guess_matches(video, guessit(self.release, {'type': 'movie'}))
 
         # title
         if video.title and sanitize(self.title) == sanitize(video.title):
@@ -127,6 +126,22 @@ def _search_imdb_id(self, title, year, is_movie):
                 return str(r.json().get('imdb_id', '')) or None
         return None
 
+    def _get_subtitles_for_episode(self, imdb_id, season, episode):
+        """Search for subtitle by imdb_id, season and episode."""
+        logger.debug('Using IMDB ID %r', imdb_id)
+
+        url = f'https://{self.server_url}/api/search?action=by_id&imdb={imdb_id}&season={season}&episode={episode}'
+        results = []
+        try:
+            # search
+            response = self.session.get(url)
+            response.raise_for_status()
+            results = response.json()
+        except (Exception, ValueError):
+            logger.warning('Error trying to search for subtitle for imdb_id: %s, season: %s, episode: %s',
+                           imdb_id, season, episode)
+        return results
+
     def query(self, title, season=None, episode=None, year=None, filename=None, imdb_id=None):
         # search for the IMDB ID if needed.
         is_movie = not (season and episode)
@@ -134,25 +149,13 @@ def query(self, title, season=None, episode=None, year=None, filename=None, imdb
         if not imdb_id:
             return {}
 
-        # search
-        logger.debug('Using IMDB ID %r', imdb_id)
-        url = 'http://json.{}/{}.json'.format(self.server_url, imdb_id)
-        page_link = 'http://{}/#/{}/{}'.format(self.server_url, 'movies' if is_movie else 'series', imdb_id)
+        page_link = 'https://{}/#/{}/{}'.format(self.server_url, 'movies' if is_movie else 'series', imdb_id)
 
         # get the list of subtitles
         logger.debug('Getting the list of subtitles')
-        r = self.session.get(url)
-        r.raise_for_status()
-        try:
-            results = r.json()
-        except ValueError:
-            return {}
 
-        # filter irrelevant results
-        if not is_movie:
-            results = results.get('subs', {}).get(str(season), {}).get(str(episode), [])
-        else:
-            results = results.get('subs', [])
+        # Get subtitles
+        results = self._get_subtitles_for_episode(imdb_id, season, episode)
 
         # loop over results
         subtitles = {}
@@ -160,18 +163,11 @@ def query(self, title, season=None, episode=None, year=None, filename=None, imdb
             language = Language.fromalpha2('he')
             hearing_impaired = False
             subtitle_id = result['id']
-            release = result['version']
-
-            # add the release and increment downloaded count if we already have the subtitle
-            if subtitle_id in subtitles:
-                logger.debug('Found additional release %r for subtitle %d', release, subtitle_id)
-                bisect.insort_left(subtitles[subtitle_id].releases, release)  # deterministic order
-                subtitles[subtitle_id].downloaded += 1
-                continue
+            release = result['versioname']
 
             # otherwise create it
             subtitle = WizdomSubtitle(language, hearing_impaired, page_link, title, season, episode, title, imdb_id,
-                                      subtitle_id, [release])
+                                      subtitle_id, release)
             logger.debug('Found subtitle %r', subtitle)
             subtitles[subtitle_id] = subtitle
 
@@ -194,7 +190,7 @@ def list_subtitles(self, video, languages):
 
     def download_subtitle(self, subtitle):
         # download
-        url = 'http://zip.{}/{}.zip'.format(self.server_url, subtitle.subtitle_id)
+        url = f'https://{self.server_url}/api/files/sub/{subtitle.subtitle_id}'
         r = self.session.get(url, headers={'Referer': subtitle.page_link}, timeout=10)
         r.raise_for_status()
 


Test patch: