Overview

Request 3789 (accepted)

Update to 1.10

Submit package home:Aloysi...:Multimedia / python-tvdb_api to package Multimedia / python-tvdb_api

python-tvdb_api.changes Changed
x
 
1
@@ -1,4 +1,10 @@
2
 -------------------------------------------------------------------
3
+Fri Apr 21 12:40:16 UTC 2017 - aloisio@gmx.com
4
+
5
+- Update to version 1.10
6
+- Spec cleanup
7
+
8
+-------------------------------------------------------------------
9
 Mon Feb  4 14:26:00 UTC 2013 - hvogel@opensuse.org
10
 
11
 - Update to version 1.8.2
12
python-tvdb_api.spec Changed
77
 
1
@@ -1,32 +1,57 @@
2
+#
3
+# spec file for package python-tvdb_api
4
+#
5
+# Copyright (c) 2017 Packman Team <packman@links2linux.de>
6
+#
7
+# All modifications and additions to the file contributed by third parties
8
+# remain the property of their copyright owners, unless otherwise agreed
9
+# upon. The license for this file, and modifications and additions to the
10
+# file, is the same license as for the pristine package itself (unless the
11
+# license for the pristine package is not an Open Source License, in which
12
+# case the license is the MIT License). An "Open Source License" is a
13
+# license that conforms to the Open Source Definition (Version 1.9)
14
+# published by the Open Source Initiative.
15
+
16
+# Please submit bugfixes or comments via http://bugs.links2linux.org/
17
+#
18
+
19
+
20
 %define modname tvdb_api
21
-Name:      python-tvdb_api
22
-Summary:   Python module to access the API from thetvdb.com
23
-License:   GPL
24
-Url:       http://pypi.python.org/pypi/tvdb_api
25
-Group:         Productivity/Multimedia/Other
26
-Version:   1.8.2
27
-Release:   1
28
-Source0:   tvdb_api-%version.tar.bz2
29
-BuildRoot:     %{_tmppath}/%{name}-buildroot
30
-BuildRequires: python-devel python-setuptools
31
+Name:           python-tvdb_api
32
+Version:        1.10
33
+Release:        0
34
+Summary:        Python module to access the API from thetvdb.com
35
+# The UnLicense (https://unlicense.org)
36
+License:        SUSE-Permissive
37
+Group:          Productivity/Multimedia/Other
38
+Url:            https://github.com/dbr/tvdb_api/tree/master
39
+Source0:        https://files.pythonhosted.org/packages/source/t/%{modname}/%{modname}-%{version}.tar.gz
40
+BuildRequires:  python-devel
41
+BuildRequires:  python-setuptools
42
+BuildRoot:      %{_tmppath}/%{name}-%{version}-build
43
+BuildArch:      noarch
44
 %py_requires
45
 
46
 %description
47
-tvdb_api is an easy to use interface to thetvdb.com
48
+tvdb_api is an easy to use interface to thetvdb.com via python
49
 
50
 %prep
51
-%setup -q -n %modname-%version
52
+%setup -q -n %{modname}-%{version}
53
+for file in {tvdb_cache,tvdb_api,tvdb_ui,tvdb_exceptions}
54
+do
55
+    sed -i "1d" $file.py
56
+done
57
 
58
 %build
59
+python setup.py build
60
 
61
 %install
62
-python setup.py install --root=$RPM_BUILD_ROOT --prefix=%_prefix \
63
-       --record-rpm=INSTALLED_FILES
64
-
65
-%clean
66
-rm -rf $RPM_BUILD_ROOT
67
+python setup.py install --root=%{buildroot} --prefix=%{_prefix}
68
 
69
-%files -f INSTALLED_FILES
70
+%files
71
 %defattr(-,root,root)
72
+%doc UNLICENSE readme.md
73
+%{python_sitelib}/tvdb_*.py*
74
+%{python_sitelib}/%{modname}-%{version}-py%{python_version}.egg-info
75
 
76
 %changelog
77
tvdb_api-1.8.2.tar.bz2/PKG-INFO -> tvdb_api-1.10.tar.gz/PKG-INFO Changed
22
 
1
@@ -1,6 +1,6 @@
2
-Metadata-Version: 1.0
3
+Metadata-Version: 1.1
4
 Name: tvdb_api
5
-Version: 1.8.2
6
+Version: 1.10
7
 Summary: Interface to thetvdb.com
8
 Home-page: http://github.com/dbr/tvdb_api/tree/master
9
 Author: dbr/Ben
10
@@ -22,6 +22,11 @@
11
 Classifier: Natural Language :: English
12
 Classifier: Operating System :: OS Independent
13
 Classifier: Programming Language :: Python
14
+Classifier: Programming Language :: Python :: 2
15
+Classifier: Programming Language :: Python :: 2.6
16
+Classifier: Programming Language :: Python :: 2.7
17
+Classifier: Programming Language :: Python :: 3.3
18
+Classifier: Programming Language :: Python :: 3.4
19
 Classifier: Topic :: Multimedia
20
 Classifier: Topic :: Utilities
21
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
tvdb_api-1.8.2.tar.bz2/Rakefile -> tvdb_api-1.10.tar.gz/Rakefile Changed
14
 
1
@@ -47,10 +47,10 @@
2
 end
3
 
4
 desc "Upload current version to PyPi"
5
-task :topypi => :test do
6
+task :topypi do
7
   cur_file = File.open("tvdb_api.py").read()
8
   tvdb_api_version = cur_file.scan(/__version__ = "(.*)"/)
9
-  tvdb_api_version = tvdb_api_version[0][0].to_f
10
+  tvdb_api_version = tvdb_api_version[0][0]
11
 
12
   puts "Build sdist and send tvdb_api v#{tvdb_api_version} to PyPi?"
13
   if $stdin.gets.chomp == "y"
14
tvdb_api-1.8.2.tar.bz2/readme.md -> tvdb_api-1.10.tar.gz/readme.md Changed
35
 
1
@@ -2,6 +2,8 @@
2
 
3
 `tvdb_api` is an easy to use interface to [thetvdb.com][tvdb]
4
 
5
+It supports Python 2.6, 2.7, 3.3 and 3.4
6
+
7
 `tvnamer` has moved to a separate repository: [github.com/dbr/tvnamer][tvnamer] - it is a utility which uses `tvdb_api` to rename files from `some.show.s01e03.blah.abc.avi` to `Some Show - [01x03] - The Episode Name.avi` (which works by getting the episode name from `tvdb_api`)
8
 
9
 [![Build Status](https://secure.travis-ci.org/dbr/tvdb_api.png?branch=master)](http://travis-ci.org/dbr/tvdb_api)
10
@@ -38,7 +40,7 @@
11
 
12
 There are several exceptions you may catch, these can be imported from `tvdb_api`:
13
 
14
-- `tvdb_error` - this is raised when there is an error communicating with [www.thetvdb.com][tvdb] (a network error most commonly)
15
+- `tvdb_error` - this is raised when there is an error communicating with [thetvdb.com][tvdb] (a network error most commonly)
16
 - `tvdb_userabort` - raised when a user aborts the Select Series dialog (by `ctrl+c`, or entering `q`)
17
 - `tvdb_shownotfound` - raised when `t['show name']` cannot find anything
18
 - `tvdb_seasonnotfound` - raised when the requested series (`t['show name][99]`) does not exist
19
@@ -63,7 +65,7 @@
20
 The data is stored in an attribute named `data`, within the Show instance:
21
 
22
     >>> t['scrubs'].data.keys()
23
-    ['networkid', 'rating', 'airs_dayofweek', 'contentrating', 'seriesname', 'id', 'airs_time', 'network', 'fanart', 'lastupdated', 'actors', 'ratingcount', 'status', 'added', 'poster', 'imdb_id', 'genre', 'banner', 'seriesid', 'language', 'zap2it_id', 'addedby', 'firstaired', 'runtime', 'overview']
24
+    ['networkid', 'rating', 'airs_dayofweek', 'contentrating', 'seriesname', 'id', 'airs_time', 'network', 'fanart', 'lastupdated', 'actors', 'ratingcount', 'status', 'added', 'poster', 'imdb_id', 'genre', 'banner', 'seriesid', 'language', 'zap2it_id', 'addedby', 'tms_wanted', 'firstaired', 'runtime', 'overview']
25
 
26
 Although each element is also accessible via `t['scrubs']` for ease-of-use:
27
 
28
@@ -105,5 +107,5 @@
29
     >>> t['scrubs']['actors']
30
     u'|Zach Braff|Donald Faison|Sarah Chalke|Christa Miller|Aloma Wright|Robert Maschio|Sam Lloyd|Neil Flynn|Ken Jenkins|Judy Reyes|John C. McGinley|Travis Schuldt|Johnny Kastl|Heather Graham|Michael Mosley|Kerry Bish\xe9|Dave Franco|Eliza Coupe|'
31
 
32
-[tvdb]: http://www.thetvdb.com
33
+[tvdb]: http://thetvdb.com
34
 [tvnamer]: http://github.com/dbr/tvnamer
35
tvdb_api-1.8.2.tar.bz2/setup.py -> tvdb_api-1.10.tar.gz/setup.py Changed
49
 
1
@@ -1,7 +1,25 @@
2
+import sys
3
 from setuptools import setup
4
+
5
+IS_PY2 = sys.version_info[0] == 2
6
+
7
+_requirements = []
8
+if not IS_PY2:
9
+    _requirements.append('requests_cache')
10
+
11
+    # 'requests' is installed as requirement by requests-cache,
12
+    # commented out because it triggers a bug in setuptool:
13
+    # https://bitbucket.org/pypa/setuptools/issue/196/tests_require-pytest-pytest-cov-breaks
14
+
15
+
16
+_modules = ['tvdb_api', 'tvdb_ui', 'tvdb_exceptions']
17
+if IS_PY2:
18
+    _modules.append('tvdb_cache')
19
+
20
+
21
 setup(
22
 name = 'tvdb_api',
23
-version='1.8.2',
24
+version='1.10',
25
 
26
 author='dbr/Ben',
27
 description='Interface to thetvdb.com',
28
@@ -21,13 +39,19 @@
29
 u'Stole a Badge'
30
 """,
31
 
32
-py_modules = ['tvdb_api', 'tvdb_ui', 'tvdb_exceptions', 'tvdb_cache'],
33
+py_modules = _modules,
34
+install_requires = _requirements,
35
 
36
 classifiers=[
37
     "Intended Audience :: Developers",
38
     "Natural Language :: English",
39
     "Operating System :: OS Independent",
40
     "Programming Language :: Python",
41
+    "Programming Language :: Python :: 2",
42
+    "Programming Language :: Python :: 2.6",
43
+    "Programming Language :: Python :: 2.7",
44
+    "Programming Language :: Python :: 3.3",
45
+    "Programming Language :: Python :: 3.4",
46
     "Topic :: Multimedia",
47
     "Topic :: Utilities",
48
     "Topic :: Software Development :: Libraries :: Python Modules",
49
tvdb_api-1.8.2.tar.bz2/tests/test_tvdb_api.py -> tvdb_api-1.10.tar.gz/tests/test_tvdb_api.py Changed
137
 
1
@@ -21,6 +21,10 @@
2
 from tvdb_api import (tvdb_shownotfound, tvdb_seasonnotfound,
3
 tvdb_episodenotfound, tvdb_attributenotfound)
4
 
5
+
6
+IS_PY2 = sys.version_info[0] == 2
7
+
8
+
9
 class test_tvdb_basic(unittest.TestCase):
10
     # Used to store the cached instance of Tvdb()
11
     t = None
12
@@ -99,6 +103,10 @@
13
             show
14
         )
15
 
16
+    def test_no_season(self):
17
+        show = self.t['Katekyo Hitman Reborn']
18
+        print(tvdb_api)
19
+        print(show[1][1])
20
 
21
 class test_tvdb_errors(unittest.TestCase):
22
     # Used to store the cached instance of Tvdb()
23
@@ -229,7 +237,7 @@
24
         """Check valid_languages is up-to-date (compared to languages.xml)
25
         """
26
         et = self.t._getetsrc(
27
-            "http://www.thetvdb.com/api/%s/languages.xml" % (
28
+            "http://thetvdb.com/api/%s/languages.xml" % (
29
                 self.t.config['apikey']
30
             )
31
         )
32
@@ -452,13 +460,16 @@
33
             self.fail("Expected ValueError from setting cache to float")
34
 
35
     def test_custom_urlopener(self):
36
+        if not IS_PY2:
37
+            raise unittest.SkipTest("cannot supply custom opener in Python 3 because requests is used")
38
+
39
         class UsedCustomOpener(Exception):
40
             pass
41
 
42
         import urllib2
43
         class TestOpener(urllib2.BaseHandler):
44
             def default_open(self, request):
45
-                print request.get_method()
46
+                print(request.get_method())
47
                 raise UsedCustomOpener("Something")
48
 
49
         custom_opener = urllib2.build_opener(TestOpener())
50
@@ -470,6 +481,26 @@
51
         else:
52
             self.fail("Did not use custom opener")
53
 
54
+    def test_custom_request_session(self):
55
+        if IS_PY2:
56
+            return
57
+        from requests import Session as OriginalSession
58
+        class Used(Exception):
59
+            pass
60
+        class CustomCacheForTest(OriginalSession):
61
+            call_count = 0
62
+            def request(self, *args, **kwargs):
63
+                raise Used("Hurray")
64
+        c = CustomCacheForTest()
65
+        t = tvdb_api.Tvdb(cache = c)
66
+        try:
67
+            t['scrubs']
68
+        except Used:
69
+            pass
70
+        else:
71
+            self.fail("Did not use custom session")
72
+
73
+
74
 class test_tvdb_by_id(unittest.TestCase):
75
     t = None
76
     def setUp(self):
77
@@ -505,6 +536,59 @@
78
         self.assertEquals(self.t['My Name Is Earl'][1][4]['episodename'], 'Faked His Own Death')
79
 
80
 
81
+class test_tvdb_show_ordering(unittest.TestCase):
82
+    # Used to store the cached instance of Tvdb()
83
+    t_dvd = None
84
+    t_air = None
85
+
86
+    def setUp(self):
87
+        if self.t_dvd is None:
88
+            self.t_dvd = tvdb_api.Tvdb(cache = True, useZip = True, dvdorder=True)
89
+
90
+        if self.t_air is None:
91
+            self.t_air = tvdb_api.Tvdb(cache = True, useZip = True)
92
+
93
+    def test_ordering(self):
94
+        """Test Tvdb.search method
95
+        """
96
+        self.assertEquals(u'The Train Job', self.t_air['Firefly'][1][1]['episodename'])
97
+        self.assertEquals(u'Serenity', self.t_dvd['Firefly'][1][1]['episodename'])
98
+
99
+        self.assertEquals(u'The Cat & the Claw (Part 1)', self.t_air['Batman The Animated Series'][1][1]['episodename'])
100
+        self.assertEquals(u'On Leather Wings', self.t_dvd['Batman The Animated Series'][1][1]['episodename'])
101
+
102
+class test_tvdb_show_search(unittest.TestCase):
103
+    # Used to store the cached instance of Tvdb()
104
+    t = None
105
+
106
+    def setUp(self):
107
+        if self.t is None:
108
+            self.__class__.t = tvdb_api.Tvdb(cache = True, useZip = True)
109
+
110
+    def test_search(self):
111
+        """Test Tvdb.search method
112
+        """
113
+        results = self.t.search("my name is earl")
114
+        all_ids = [x['seriesid'] for x in results]
115
+        self.assertTrue('75397' in all_ids)
116
+
117
+
118
+class test_tvdb_alt_names(unittest.TestCase):
119
+    t = None
120
+    def setUp(self):
121
+        if self.t is None:
122
+            self.__class__.t = tvdb_api.Tvdb(cache = True, actors = True)
123
+
124
+    def test_1(self):
125
+        """Tests basic access of series name alias
126
+        """
127
+        results = self.t.search("Don't Trust the B---- in Apartment 23")
128
+        series = results[0]
129
+        self.assertTrue(
130
+            'Apartment 23' in series['aliasnames']
131
+        )
132
+
133
+
134
 if __name__ == '__main__':
135
     runner = unittest.TextTestRunner(verbosity = 2)
136
     unittest.main(testRunner = runner)
137
tvdb_api-1.8.2.tar.bz2/tvdb_api.egg-info/PKG-INFO -> tvdb_api-1.10.tar.gz/tvdb_api.egg-info/PKG-INFO Changed
22
 
1
@@ -1,6 +1,6 @@
2
-Metadata-Version: 1.0
3
+Metadata-Version: 1.1
4
 Name: tvdb-api
5
-Version: 1.8.2
6
+Version: 1.10
7
 Summary: Interface to thetvdb.com
8
 Home-page: http://github.com/dbr/tvdb_api/tree/master
9
 Author: dbr/Ben
10
@@ -22,6 +22,11 @@
11
 Classifier: Natural Language :: English
12
 Classifier: Operating System :: OS Independent
13
 Classifier: Programming Language :: Python
14
+Classifier: Programming Language :: Python :: 2
15
+Classifier: Programming Language :: Python :: 2.6
16
+Classifier: Programming Language :: Python :: 2.7
17
+Classifier: Programming Language :: Python :: 3.3
18
+Classifier: Programming Language :: Python :: 3.4
19
 Classifier: Topic :: Multimedia
20
 Classifier: Topic :: Utilities
21
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
tvdb_api-1.8.2.tar.bz2/tvdb_api.py -> tvdb_api-1.10.tar.gz/tvdb_api.py Changed
593
 
1
@@ -5,7 +5,7 @@
2
 #repository:http://github.com/dbr/tvdb_api
3
 #license:unlicense (http://unlicense.org/)
4
 
5
-"""Simple-to-use Python interface to The TVDB's API (www.thetvdb.com)
6
+"""Simple-to-use Python interface to The TVDB's API (thetvdb.com)
7
 
8
 Example usage:
9
 
10
@@ -15,14 +15,23 @@
11
 u'Cabin Fever'
12
 """
13
 __author__ = "dbr/Ben"
14
-__version__ = "1.8.2"
15
+__version__ = "1.10"
16
+
17
+import sys
18
+
19
+IS_PY2 = sys.version_info[0] == 2
20
 
21
 import os
22
 import time
23
-import urllib
24
-import urllib2
25
+if IS_PY2:
26
+    import urllib
27
+    import urllib2
28
+    from tvdb_cache import CacheHandler
29
+    from urllib import quote as url_quote
30
+else:
31
+    import requests
32
+    from urllib.parse import quote as url_quote
33
 import getpass
34
-import StringIO
35
 import tempfile
36
 import warnings
37
 import logging
38
@@ -40,7 +49,13 @@
39
     gzip = None
40
 
41
 
42
-from tvdb_cache import CacheHandler
43
+if IS_PY2:
44
+    int_types = (int, long)
45
+    text_type = unicode
46
+else:
47
+    int_types = int
48
+    text_type = str
49
+
50
 
51
 from tvdb_ui import BaseUI, ConsoleUI
52
 from tvdb_exceptions import (tvdb_error, tvdb_userabort, tvdb_shownotfound,
53
@@ -65,16 +80,12 @@
54
 
55
         #keep only the 100th latest results
56
         if time.time() - self._lastgc > 20:
57
-            tbd = self._stack[:-100]
58
-            i = 0
59
-            for o in tbd:
60
+            for o in self._stack[:-100]:
61
                 del self[o]
62
-                del self._stack[i]
63
-                i += 1
64
+            self._stack = self._stack[-100:]
65
+
66
+            self._lastgc = time.time()
67
 
68
-            _lastgc = time.time()
69
-            del tbd
70
-                    
71
         super(ShowContainer, self).__setitem__(key, value)
72
 
73
 
74
@@ -171,7 +182,7 @@
75
             searchresult = cur_season.search(term = term, key = key)
76
             if len(searchresult) != 0:
77
                 results.extend(searchresult)
78
-        #end for cur_season
79
+
80
         return results
81
 
82
 
83
@@ -259,16 +270,14 @@
84
         if term == None:
85
             raise TypeError("must supply string to search for (contents)")
86
 
87
-        term = unicode(term).lower()
88
+        term = text_type(term).lower()
89
         for cur_key, cur_value in self.items():
90
-            cur_key, cur_value = unicode(cur_key).lower(), unicode(cur_value).lower()
91
+            cur_key, cur_value = text_type(cur_key).lower(), text_type(cur_value).lower()
92
             if key is not None and cur_key != key:
93
                 # Do not search this key
94
                 continue
95
-            if cur_value.find( unicode(term).lower() ) > -1:
96
+            if cur_value.find( text_type(term).lower() ) > -1:
97
                 return self
98
-            #end if cur_value.find()
99
-        #end for cur_key, cur_value
100
 
101
 
102
 class Actors(list):
103
@@ -308,7 +317,8 @@
104
                 search_all_languages = False,
105
                 apikey = None,
106
                 forceConnect=False,
107
-                useZip=False):
108
+                useZip=False,
109
+                dvdorder=False):
110
 
111
         """interactive (True/False):
112
             When True, uses built-in console UI is used to select the correct show.
113
@@ -333,6 +343,12 @@
114
             an arbitrary Python object, which is used as a urllib2
115
             opener, which should be created by urllib2.build_opener
116
 
117
+            In Python 3, True/False enable or disable default
118
+            caching. Passing string specified directory where to store
119
+            the "tvdb.sqlite3" cache file. Also a custom
120
+            requests.Session instance can be passed (e.g maybe a
121
+            customised instance of requests_cache.CachedSession)
122
+
123
         banners (True/False):
124
             Retrieves the banners for a show. These are accessed
125
             via the _banners key of a Show(), for example:
126
@@ -382,6 +398,7 @@
127
             And only the main language xml is used, the actor and banner xml are lost.
128
         """
129
         
130
+
131
         global lastTimeout
132
         
133
         # if we're given a lastTimeout that is less than 1 min just give up
134
@@ -410,33 +427,61 @@
135
 
136
         self.config['useZip'] = useZip
137
 
138
+        self.config['dvdorder'] = dvdorder
139
 
140
-        if cache is True:
141
-            self.config['cache_enabled'] = True
142
-            self.config['cache_location'] = self._getTempDir()
143
-            self.urlopener = urllib2.build_opener(
144
-                CacheHandler(self.config['cache_location'])
145
-            )
146
+        if not IS_PY2: # FIXME: Allow using requests in Python 2?
147
+            import requests_cache
148
+            if cache is True:
149
+                self.session = requests_cache.CachedSession(
150
+                    expire_after=21600, # 6 hours
151
+                    backend='sqlite',
152
+                    cache_name=self._getTempDir(),
153
+                    )
154
+                self.config['cache_enabled'] = True
155
+            elif cache is False:
156
+                self.session = requests.Session()
157
+                self.config['cache_enabled'] = False
158
+            elif isinstance(cache, text_type):
159
+                # Specified cache path
160
+                self.session = requests_cache.CachedSession(
161
+                    expire_after=21600, # 6 hours
162
+                    backend='sqlite',
163
+                    cache_name=os.path.join(cache, "tvdb_api"),
164
+                    )
165
+            else:
166
+                self.session = cache
167
+                try:
168
+                    self.session.get
169
+                except AttributeError:
170
+                    raise ValueError("cache argument must be True/False, string as cache path or requests.Session-type object (e.g from requests_cache.CachedSession)")
171
+        else:
172
+            # For backwards compatibility in Python 2.x
173
+            if cache is True:
174
+                self.config['cache_enabled'] = True
175
+                self.config['cache_location'] = self._getTempDir()
176
+                self.urlopener = urllib2.build_opener(
177
+                    CacheHandler(self.config['cache_location'])
178
+                )
179
 
180
-        elif cache is False:
181
-            self.config['cache_enabled'] = False
182
-            self.urlopener = urllib2.build_opener() # default opener with no caching
183
+            elif cache is False:
184
+                self.config['cache_enabled'] = False
185
+                self.urlopener = urllib2.build_opener() # default opener with no caching
186
 
187
-        elif isinstance(cache, basestring):
188
-            self.config['cache_enabled'] = True
189
-            self.config['cache_location'] = cache
190
-            self.urlopener = urllib2.build_opener(
191
-                CacheHandler(self.config['cache_location'])
192
-            )
193
+            elif isinstance(cache, basestring):
194
+                self.config['cache_enabled'] = True
195
+                self.config['cache_location'] = cache
196
+                self.urlopener = urllib2.build_opener(
197
+                    CacheHandler(self.config['cache_location'])
198
+                )
199
 
200
-        elif isinstance(cache, urllib2.OpenerDirector):
201
-            # If passed something from urllib2.build_opener, use that
202
-            log().debug("Using %r as urlopener" % cache)
203
-            self.config['cache_enabled'] = True
204
-            self.urlopener = cache
205
+            elif isinstance(cache, urllib2.OpenerDirector):
206
+                # If passed something from urllib2.build_opener, use that
207
+                log().debug("Using %r as urlopener" % cache)
208
+                self.config['cache_enabled'] = True
209
+                self.urlopener = cache
210
 
211
-        else:
212
-            raise ValueError("Invalid value for Cache %r (type was %s)" % (cache, type(cache)))
213
+            else:
214
+                raise ValueError("Invalid value for Cache %r (type was %s)" % (cache, type(cache)))
215
 
216
         self.config['banners_enabled'] = banners
217
         self.config['actors_enabled'] = actors
218
@@ -448,7 +493,7 @@
219
             logging.basicConfig(level=logging.DEBUG)
220
 
221
 
222
-        # List of language from http://www.thetvdb.com/api/0629B785CE550C8D/languages.xml
223
+        # List of language from http://thetvdb.com/api/0629B785CE550C8D/languages.xml
224
         # Hard-coded here as it is realtively static, and saves another HTTP request, as
225
         # recommended on http://thetvdb.com/wiki/index.php/API:languages.xml
226
         self.config['valid_languages'] = [
227
@@ -477,7 +522,7 @@
228
 
229
         # The following url_ configs are based of the
230
         # http://thetvdb.com/wiki/index.php/Programmers_API
231
-        self.config['base_url'] = "http://www.thetvdb.com"
232
+        self.config['base_url'] = "http://thetvdb.com"
233
 
234
         if self.config['search_all_languages']:
235
             self.config['url_getSeries'] = u"%(base_url)s/api/GetSeries.php?seriesname=%%s&language=all" % self.config
236
@@ -493,8 +538,6 @@
237
         self.config['url_seriesBanner'] = u"%(base_url)s/api/%(apikey)s/series/%%s/banners.xml" % self.config
238
         self.config['url_artworkPrefix'] = u"%(base_url)s/banners/%%s" % self.config
239
 
240
-    #end __init__
241
-
242
     def _getTempDir(self):
243
         """Returns the [system temp dir]/tvdb_api-u501 (or
244
         tvdb_api-myuser)
245
@@ -503,67 +546,96 @@
246
             uid = "u%d" % (os.getuid())
247
         else:
248
             # For Windows
249
-            uid = getpass.getuser()
250
+            try:
251
+                uid = getpass.getuser()
252
+            except ImportError:
253
+                return os.path.join(tempfile.gettempdir(), "tvdb_api")
254
 
255
         return os.path.join(tempfile.gettempdir(), "tvdb_api-%s" % (uid))
256
 
257
     def _loadUrl(self, url, recache = False, language=None):
258
-        global lastTimeout
259
-        try:
260
-            log().debug("Retrieving URL %s" % url)
261
-            resp = self.urlopener.open(url)
262
-            if 'x-local-cache' in resp.headers:
263
-                log().debug("URL %s was cached in %s" % (
264
-                    url,
265
-                    resp.headers['x-local-cache'])
266
-                )
267
-                if recache:
268
-                    log().debug("Attempting to recache %s" % url)
269
-                    resp.recache()
270
-        except (IOError, urllib2.URLError), errormsg:
271
-            if not str(errormsg).startswith('HTTP Error'):
272
-                lastTimeout = datetime.datetime.now()
273
-            raise tvdb_error("Could not connect to server: %s" % (errormsg))
274
-        #end try
275
-        
276
-        # handle gzipped content,
277
-        # http://dbr.lighthouseapp.com/projects/13342/tickets/72-gzipped-data-patch
278
-        if 'gzip' in resp.headers.get("Content-Encoding", ''):
279
-            if gzip:
280
-                stream = StringIO.StringIO(resp.read())
281
-                gz = gzip.GzipFile(fileobj=stream)
282
-                return gz.read()
283
-
284
-            raise tvdb_error("Received gzip data from thetvdb.com, but could not correctly handle it")
285
+        if not IS_PY2:
286
+            # Python 3: return content at URL as bytes
287
+            resp = self.session.get(url)
288
+            if 'application/zip' in resp.headers.get("Content-Type", ''):
289
+                try:
290
+                    # TODO: The zip contains actors.xml and banners.xml, which are currently ignored [GH-20]
291
+                    log().debug("We recived a zip file unpacking now ...")
292
+                    from io import BytesIO
293
+                    myzipfile = zipfile.ZipFile(BytesIO(resp.content))
294
+                    return myzipfile.read('%s.xml' % language)
295
+                except zipfile.BadZipfile:
296
+                    self.session.cache.delete_url(url)
297
+                    raise tvdb_error("Bad zip file received from thetvdb.com, could not read it")
298
+            return resp.content
299
 
300
-        if 'application/zip' in resp.headers.get("Content-Type", ''):
301
+        else:
302
+            global lastTimeout
303
             try:
304
-                # TODO: The zip contains actors.xml and banners.xml, which are currently ignored [GH-20]
305
-                log().debug("We recived a zip file unpacking now ...")
306
-                zipdata = StringIO.StringIO()
307
-                zipdata.write(resp.read())
308
-                myzipfile = zipfile.ZipFile(zipdata)
309
-                return myzipfile.read('%s.xml' % language)
310
-            except zipfile.BadZipfile:
311
+                log().debug("Retrieving URL %s" % url)
312
+                resp = self.urlopener.open(url)
313
                 if 'x-local-cache' in resp.headers:
314
-                    resp.delete_cache()
315
-                raise tvdb_error("Bad zip file received from thetvdb.com, could not read it")
316
-
317
-        return resp.read()
318
+                    log().debug("URL %s was cached in %s" % (
319
+                        url,
320
+                        resp.headers['x-local-cache'])
321
+                    )
322
+                    if recache:
323
+                        log().debug("Attempting to recache %s" % url)
324
+                        resp.recache()
325
+            except (IOError, urllib2.URLError) as errormsg:
326
+                if not str(errormsg).startswith('HTTP Error'):
327
+                    lastTimeout = datetime.datetime.now()
328
+                raise tvdb_error("Could not connect to server: %s" % (errormsg))
329
+
330
+
331
+            # handle gzipped content,
332
+            # http://dbr.lighthouseapp.com/projects/13342/tickets/72-gzipped-data-patch
333
+            if 'gzip' in resp.headers.get("Content-Encoding", ''):
334
+                if gzip:
335
+                    from StringIO import StringIO
336
+                    stream = StringIO(resp.read())
337
+                    gz = gzip.GzipFile(fileobj=stream)
338
+                    return gz.read()
339
+
340
+                raise tvdb_error("Received gzip data from thetvdb.com, but could not correctly handle it")
341
+
342
+            if 'application/zip' in resp.headers.get("Content-Type", ''):
343
+                try:
344
+                    # TODO: The zip contains actors.xml and banners.xml, which are currently ignored [GH-20]
345
+                    log().debug("We recived a zip file unpacking now ...")
346
+                    from StringIO import StringIO
347
+                    zipdata = StringIO()
348
+                    zipdata.write(resp.read())
349
+                    myzipfile = zipfile.ZipFile(zipdata)
350
+                    return myzipfile.read('%s.xml' % language)
351
+                except zipfile.BadZipfile:
352
+                    if 'x-local-cache' in resp.headers:
353
+                        resp.delete_cache()
354
+                    raise tvdb_error("Bad zip file received from thetvdb.com, could not read it")
355
+
356
+            return resp.read()
357
 
358
     def _getetsrc(self, url, language=None):
359
         """Loads a URL using caching, returns an ElementTree of the source
360
         """
361
         src = self._loadUrl(url, language=language)
362
+
363
+
364
+        # TVDB doesn't sanitize \r (CR) from user input in some fields,
365
+        # remove it to avoid errors. Change from SickBeard, from will14m
366
+        if not IS_PY2:
367
+            # Remove trailing \r byte
368
+            src = src.replace(b"\r", b"")
369
+        else:
370
+            src = src.rstrip("\r") # FIXME: this seems wrong
371
+
372
         try:
373
-            # TVDB doesn't sanitize \r (CR) from user input in some fields,
374
-            # remove it to avoid errors. Change from SickBeard, from will14m
375
-            return ElementTree.fromstring(src.rstrip("\r"))
376
+            return ElementTree.fromstring(src)
377
         except SyntaxError:
378
             src = self._loadUrl(url, recache=True, language=language)
379
             try:
380
-                return ElementTree.fromstring(src.rstrip("\r"))
381
-            except SyntaxError, exceptionmsg:
382
+                return ElementTree.fromstring(src)
383
+            except SyntaxError as exceptionmsg:
384
                 errormsg = "There was an error with the XML retrieved from thetvdb.com:\n%s" % (
385
                     exceptionmsg
386
                 )
387
@@ -576,7 +648,6 @@
388
                 errormsg += "\nIf this does not resolve the issue, please try again later. If the error persists, report a bug on"
389
                 errormsg += "\nhttp://dbr.lighthouseapp.com/projects/13342-tvdb_api/overview\n"
390
                 raise tvdb_error(errormsg)
391
-    #end _getetsrc
392
 
393
     def _setItem(self, sid, seas, ep, attrib, value):
394
         """Creates a new episode, creating Show(), Season() and
395
@@ -600,7 +671,6 @@
396
         if ep not in self.shows[sid][seas]:
397
             self.shows[sid][seas][ep] = Episode(season = self.shows[sid][seas])
398
         self.shows[sid][seas][ep][attrib] = value
399
-    #end _set_item
400
 
401
     def _setShowData(self, sid, key, value):
402
         """Sets self.shows[sid] to a new Show instance, or sets the data
403
@@ -619,15 +689,12 @@
404
         data = data.replace(u"&amp;", u"&")
405
         data = data.strip()
406
         return data
407
-    #end _cleanData
408
 
409
-    def _getSeries(self, series):
410
-        """This searches TheTVDB.com for the series name,
411
-        If a custom_ui UI is configured, it uses this to select the correct
412
-        series. If not, and interactive == True, ConsoleUI is used, if not
413
-        BaseUI is used to select the first result.
414
+    def search(self, series):
415
+        """This searches TheTVDB.com for the series name
416
+        and returns the result list
417
         """
418
-        series = urllib.quote(series.encode("utf-8"))
419
+        series = url_quote(series.encode("utf-8"))
420
         log().debug("Searching for show %s" % series)
421
         seriesEt = self._getetsrc(self.config['url_getSeries'] % (series))
422
         allSeries = []
423
@@ -635,9 +702,20 @@
424
             result = dict((k.tag.lower(), k.text) for k in series.getchildren())
425
             result['id'] = int(result['id'])
426
             result['lid'] = self.config['langabbv_to_id'][result['language']]
427
+            if 'aliasnames' in result:
428
+                result['aliasnames'] = result['aliasnames'].split("|")
429
             log().debug('Found series %(seriesname)s' % result)
430
             allSeries.append(result)
431
-        #end for series
432
+        
433
+        return allSeries
434
+
435
+    def _getSeries(self, series):
436
+        """This searches TheTVDB.com for the series name,
437
+        If a custom_ui UI is configured, it uses this to select the correct
438
+        series. If not, and interactive == True, ConsoleUI is used, if not
439
+        BaseUI is used to select the first result.
440
+        """
441
+        allSeries = self.search(series)
442
 
443
         if len(allSeries) == 0:
444
             log().debug('Series result returned zero')
445
@@ -653,16 +731,12 @@
446
             else:
447
                 log().debug('Interactively selecting show using ConsoleUI')
448
                 ui = ConsoleUI(config = self.config)
449
-            #end if config['interactive]
450
-        #end if custom_ui != None
451
 
452
         return ui.selectSeries(allSeries)
453
 
454
-    #end _getSeries
455
-
456
     def _parseBanners(self, sid):
457
         """Parses banners XML, from
458
-        http://www.thetvdb.com/api/[APIKEY]/series/[SERIES ID]/banners.xml
459
+        http://thetvdb.com/api/[APIKEY]/series/[SERIES ID]/banners.xml
460
 
461
         Banners are retrieved using t['show name]['_banners'], for example:
462
 
463
@@ -670,7 +744,7 @@
464
         >>> t['scrubs']['_banners'].keys()
465
         ['fanart', 'poster', 'series', 'season']
466
         >>> t['scrubs']['_banners']['poster']['680x1000']['35308']['_bannerpath']
467
-        u'http://www.thetvdb.com/banners/posters/76156-2.jpg'
468
+        u'http://thetvdb.com/banners/posters/76156-2.jpg'
469
         >>>
470
 
471
         Any key starting with an underscore has been processed (not the raw
472
@@ -703,7 +777,7 @@
473
                 tag, value = tag.lower(), value.lower()
474
                 banners[btype][btype2][bid][tag] = value
475
 
476
-            for k, v in banners[btype][btype2][bid].items():
477
+            for k, v in list(banners[btype][btype2][bid].items()):
478
                 if k.endswith("path"):
479
                     new_key = "_%s" % (k)
480
                     log().debug("Transforming %s to %s" % (k, new_key))
481
@@ -714,7 +788,7 @@
482
 
483
     def _parseActors(self, sid):
484
         """Parsers actors XML, from
485
-        http://www.thetvdb.com/api/[APIKEY]/series/[SERIES ID]/actors.xml
486
+        http://thetvdb.com/api/[APIKEY]/series/[SERIES ID]/actors.xml
487
 
488
         Actors are retrieved using t['show name]['_actors'], for example:
489
 
490
@@ -731,7 +805,7 @@
491
         >>> actors[0]['name']
492
         u'Zach Braff'
493
         >>> actors[0]['image']
494
-        u'http://www.thetvdb.com/banners/actors/43640.jpg'
495
+        u'http://thetvdb.com/banners/actors/43640.jpg'
496
 
497
         Any key starting with an underscore has been processed (not the raw
498
         data from the XML)
499
@@ -790,7 +864,6 @@
500
                     value = self._cleanData(value)
501
 
502
             self._setShowData(sid, tag, value)
503
-        #end for series
504
 
505
         # Parse banners
506
         if self.config['banners_enabled']:
507
@@ -811,8 +884,31 @@
508
         epsEt = self._getetsrc( url, language=language)
509
 
510
         for cur_ep in epsEt.findall("Episode"):
511
-            seas_no = int(cur_ep.find('SeasonNumber').text)
512
-            ep_no = int(cur_ep.find('EpisodeNumber').text)
513
+
514
+            if self.config['dvdorder']:
515
+                log().debug('Using DVD ordering.')
516
+                use_dvd = cur_ep.find('DVD_season').text != None and cur_ep.find('DVD_episodenumber').text != None
517
+            else:
518
+                use_dvd = False
519
+
520
+            if use_dvd:
521
+                elem_seasnum, elem_epno = cur_ep.find('DVD_season'), cur_ep.find('DVD_episodenumber')
522
+            else:
523
+                elem_seasnum, elem_epno = cur_ep.find('SeasonNumber'), cur_ep.find('EpisodeNumber')
524
+
525
+            if elem_seasnum is None or elem_epno is None:
526
+                log().warning("An episode has incomplete season/episode number (season: %r, episode: %r)" % (
527
+                    elem_seasnum, elem_epno))
528
+                log().debug(
529
+                    " ".join(
530
+                        "%r is %r" % (child.tag, child.text) for child in cur_ep.getchildren()))
531
+                # TODO: Should this happen?
532
+                continue # Skip to next episode
533
+
534
+            # float() is because https://github.com/dbr/tvnamer/issues/95 - should probably be fixed in TVDB data
535
+            seas_no = int(float(elem_seasnum.text))
536
+            ep_no = int(float(elem_epno.text))
537
+
538
             for cur_item in cur_ep.getchildren():
539
                 tag = cur_item.tag.lower()
540
                 value = cur_item.text
541
@@ -822,8 +918,6 @@
542
                     else:
543
                         value = self._cleanData(value)
544
                 self._setItem(sid, seas_no, ep_no, tag, value)
545
-        #end for cur_ep
546
-    #end _geEps
547
 
548
     def _nameToSid(self, name):
549
         """Takes show name, returns the correct series ID (if the show has
550
@@ -841,15 +935,14 @@
551
 
552
             self.corrections[name] = sid
553
             self._getShowData(selected_series['id'], selected_series['language'])
554
-        #end if name in self.corrections
555
+
556
         return sid
557
-    #end _nameToSid
558
 
559
     def __getitem__(self, key):
560
         """Handles tvdb_instance['seriesname'] calls.
561
         The dict index should be the show id
562
         """
563
-        if isinstance(key, (int, long)):
564
+        if isinstance(key, int_types):
565
             # Item is integer, treat as show id
566
             if key not in self.shows:
567
                 self._getShowData(key, self.config['language'])
568
@@ -859,12 +952,10 @@
569
         sid = self._nameToSid(key)
570
         log().debug('Got series id %s' % (sid))
571
         return self.shows[sid]
572
-    #end __getitem__
573
 
574
     def __repr__(self):
575
         return str(self.shows)
576
-    #end __repr__
577
-#end Tvdb
578
+
579
 
580
 def main():
581
     """Simple example of using tvdb_api - it just
582
@@ -874,8 +965,8 @@
583
     logging.basicConfig(level=logging.DEBUG)
584
 
585
     tvdb_instance = Tvdb(interactive=True, cache=False)
586
-    print tvdb_instance['Lost']['seriesname']
587
-    print tvdb_instance['Lost'][1][4]['episodename']
588
+    print(tvdb_instance['Lost']['seriesname'])
589
+    print(tvdb_instance['Lost'][1][4]['episodename'])
590
 
591
 if __name__ == '__main__':
592
     main()
593
tvdb_api-1.8.2.tar.bz2/tvdb_cache.py -> tvdb_api-1.10.tar.gz/tvdb_cache.py Changed
18
 
1
@@ -12,7 +12,7 @@
2
 from __future__ import with_statement
3
 
4
 __author__ = "dbr/Ben"
5
-__version__ = "1.8.2"
6
+__version__ = "1.10"
7
 
8
 import os
9
 import time
10
@@ -159,7 +159,6 @@
11
                 )
12
             else:
13
                 set_cache_header = True
14
-            #end if x-cache in response
15
 
16
             return CachedResponse(
17
                 self.cache_location,
18
tvdb_api-1.8.2.tar.bz2/tvdb_exceptions.py -> tvdb_api-1.10.tar.gz/tvdb_exceptions.py Changed
40
 
1
@@ -9,7 +9,7 @@
2
 """
3
 
4
 __author__ = "dbr/Ben"
5
-__version__ = "1.8.2"
6
+__version__ = "1.10"
7
 
8
 __all__ = ["tvdb_error", "tvdb_userabort", "tvdb_shownotfound",
9
 "tvdb_seasonnotfound", "tvdb_episodenotfound", "tvdb_attributenotfound"]
10
@@ -20,7 +20,7 @@
11
     pass
12
 
13
 class tvdb_error(tvdb_exception):
14
-    """An error with www.thetvdb.com (Cannot connect, for example)
15
+    """An error with thetvdb.com (Cannot connect, for example)
16
     """
17
     pass
18
 
19
@@ -31,17 +31,17 @@
20
     pass
21
 
22
 class tvdb_shownotfound(tvdb_exception):
23
-    """Show cannot be found on www.thetvdb.com (non-existant show)
24
+    """Show cannot be found on thetvdb.com (non-existant show)
25
     """
26
     pass
27
 
28
 class tvdb_seasonnotfound(tvdb_exception):
29
-    """Season cannot be found on www.thetvdb.com
30
+    """Season cannot be found on thetvdb.com
31
     """
32
     pass
33
 
34
 class tvdb_episodenotfound(tvdb_exception):
35
-    """Episode cannot be found on www.thetvdb.com
36
+    """Episode cannot be found on thetvdb.com
37
     """
38
     pass
39
 
40
tvdb_api-1.8.2.tar.bz2/tvdb_ui.py -> tvdb_api-1.10.tar.gz/tvdb_ui.py Changed
109
 
1
@@ -43,13 +43,23 @@
2
 """
3
 
4
 __author__ = "dbr/Ben"
5
-__version__ = "1.8.2"
6
+__version__ = "1.10"
7
 
8
+import sys
9
 import logging
10
 import warnings
11
 
12
 from tvdb_exceptions import tvdb_userabort
13
 
14
+
15
+IS_PY2 = sys.version_info[0] == 2
16
+
17
+if IS_PY2:
18
+    user_input = raw_input
19
+else:
20
+    user_input = input
21
+
22
+
23
 def log():
24
     return logging.getLogger(__name__)
25
 
26
@@ -80,7 +90,7 @@
27
         else:
28
             toshow = allSeries
29
 
30
-        print "TVDB Search Results:"
31
+        print("TVDB Search Results:")
32
         for i, cshow in enumerate(toshow):
33
             i_show = i + 1 # Start at more human readable number 1 (not 0)
34
             log().debug('Showing allSeries[%s], series %s)' % (i_show, allSeries[i]['seriesname']))
35
@@ -89,31 +99,35 @@
36
             else:
37
                 extra = ""
38
 
39
-            print "%s -> %s [%s] # http://thetvdb.com/?tab=series&id=%s&lid=%s%s" % (
40
+            output = "%s -> %s [%s] # http://thetvdb.com/?tab=series&id=%s&lid=%s%s" % (
41
                 i_show,
42
-                cshow['seriesname'].encode("UTF-8", "ignore"),
43
-                cshow['language'].encode("UTF-8", "ignore"),
44
+                cshow['seriesname'],
45
+                cshow['language'],
46
                 str(cshow['id']),
47
                 cshow['lid'],
48
                 extra
49
             )
50
+            if IS_PY2:
51
+                print(output.encode("UTF-8", "ignore"))
52
+            else:
53
+                print(output)
54
 
55
     def selectSeries(self, allSeries):
56
         self._displaySeries(allSeries)
57
 
58
         if len(allSeries) == 1:
59
             # Single result, return it!
60
-            print "Automatically selecting only result"
61
+            print("Automatically selecting only result")
62
             return allSeries[0]
63
 
64
         if self.config['select_first'] is True:
65
-            print "Automatically returning first search result"
66
+            print("Automatically returning first search result")
67
             return allSeries[0]
68
 
69
         while True: # return breaks this loop
70
             try:
71
-                print "Enter choice (first number, return for default, 'all', ? for help):"
72
-                ans = raw_input()
73
+                print("Enter choice (first number, return for default, 'all', ? for help):")
74
+                ans = user_input()
75
             except KeyboardInterrupt:
76
                 raise tvdb_userabort("User aborted (^c keyboard interupt)")
77
             except EOFError:
78
@@ -131,13 +145,13 @@
79
                     log().debug('Got quit command (q)')
80
                     raise tvdb_userabort("User aborted ('q' quit command)")
81
                 elif ans == "?":
82
-                    print "## Help"
83
-                    print "# Enter the number that corresponds to the correct show."
84
-                    print "# a - display all results"
85
-                    print "# all - display all results"
86
-                    print "# ? - this help"
87
-                    print "# q - abort tvnamer"
88
-                    print "# Press return with no input to select first result"
89
+                    print("## Help")
90
+                    print("# Enter the number that corresponds to the correct show.")
91
+                    print("# a - display all results")
92
+                    print("# all - display all results")
93
+                    print("# ? - this help")
94
+                    print("# q - abort tvnamer")
95
+                    print("# Press return with no input to select first result")
96
                 elif ans.lower() in ["a", "all"]:
97
                     self._displaySeries(allSeries, limit = None)
98
                 else:
99
@@ -148,8 +162,6 @@
100
                     return allSeries[selected_id]
101
                 except IndexError:
102
                     log().debug('Invalid show number entered!')
103
-                    print "Invalid number (%s) selected!"
104
+                    print("Invalid number (%s) selected!")
105
                     self._displaySeries(allSeries)
106
-            #end try
107
-        #end while not valid_input
108
 
109
Refresh

No build results available

Refresh

No rpmlint results available

Request History
Luigi Baldoni's avatar

Aloysius created request almost 8 years ago

Update to 1.10


Olaf Hering's avatar

olh accepted request almost 8 years ago