3
3
# Copyright (C) 2015 - Philipp Temminghoff <[email protected] >
4
4
# This program is Free Software see LICENSE file for details
5
5
6
- import sys
7
- import codecs
6
+ from urllib .parse import quote_plus
8
7
import os
9
8
import time
10
9
import hashlib
11
10
import requests
12
11
import json
13
- from urllib .parse import quote_plus
14
12
13
+ import xbmc
15
14
import xbmcaddon
16
15
import xbmcvfs
17
- import xbmc
18
16
19
17
HEADERS = {'User-agent' : 'Mozilla/5.0' }
20
18
24
22
ADDON_ID = ADDON .getAddonInfo ('id' )
25
23
ADDON_DATA_PATH = xbmcvfs .translatePath ("special://profile/addon_data/%s" % ADDON_ID )
26
24
27
- MONITOR = xbmc .Monitor ()
28
-
29
25
30
26
def get_autocomplete_items (search_str , limit = 10 , provider = None ):
31
27
"""
@@ -39,6 +35,8 @@ def get_autocomplete_items(search_str, limit=10, provider=None):
39
35
provider = GoogleProvider (limit = limit )
40
36
elif SETTING ("autocomplete_provider" ) == "bing" :
41
37
provider = BingProvider (limit = limit )
38
+ elif SETTING ("autocomplete_provider" ) == "tmdb" :
39
+ provider = TmdbProvider (limit = limit )
42
40
else :
43
41
provider = LocalDictProvider (limit = limit )
44
42
provider .limit = limit
@@ -53,9 +51,8 @@ def prep_search_str(text):
53
51
54
52
55
53
class BaseProvider (object ):
56
-
57
54
def __init__ (self , * args , ** kwargs ):
58
- self .limit = int ( kwargs .get ("limit" , 10 ) )
55
+ self .limit = kwargs .get ("limit" , 10 )
59
56
60
57
def get_predictions (self , search_str ):
61
58
if not search_str :
@@ -86,7 +83,10 @@ def __init__(self, *args, **kwargs):
86
83
self .youtube = kwargs .get ("youtube" , False )
87
84
88
85
def fetch_data (self , search_str ):
89
- url = "search?hl=%s&q=%s&json=t&client=serp" % (SETTING ("autocomplete_lang" ), quote_plus (search_str ))
86
+ url = "search?hl=%s&q=%s&json=t&client=serp" % (
87
+ SETTING ("autocomplete_lang" ),
88
+ quote_plus (search_str ),
89
+ )
90
90
if self .youtube :
91
91
url += "&ds=yt"
92
92
result = get_JSON_response (url = self .BASE_URL + url ,
@@ -107,17 +107,47 @@ def __init__(self, *args, **kwargs):
107
107
108
108
def fetch_data (self , search_str ):
109
109
url = "query=%s" % (quote_plus (search_str ))
110
- result = get_JSON_response (url = self . BASE_URL + url ,
111
- headers = HEADERS ,
112
- folder = "Bing" )
110
+ result = get_JSON_response (
111
+ url = self . BASE_URL + url , headers = HEADERS , folder = "Bing"
112
+ )
113
113
if not result :
114
114
return []
115
115
else :
116
116
return result [1 ]
117
117
118
118
119
- class LocalDictProvider (BaseProvider ):
119
+ class TmdbProvider (BaseProvider ):
120
+
121
+ BASE_URL = "https://www.themoviedb.org/search/multi?"
120
122
123
+ def __init__ (self , * args , ** kwargs ):
124
+ super (TmdbProvider , self ).__init__ (* args , ** kwargs )
125
+
126
+ def fetch_data (self , search_str ):
127
+ url = "language=%s&query=%s" % (
128
+ SETTING ("autocomplete_lang" ),
129
+ quote_plus (search_str ),
130
+ )
131
+ result = get_JSON_response (
132
+ url = self .BASE_URL + url , headers = HEADERS , folder = "TMDB"
133
+ )
134
+ if not result or "results" not in result :
135
+ return []
136
+ out = []
137
+ for i in result ["results" ]:
138
+ title = None
139
+ if "media_type" in i :
140
+ if i ["media_type" ] == "movie" :
141
+ title = i ["title" ]
142
+ elif i ["media_type" ] in ["tv" , "person" ]:
143
+ title = i ["name" ]
144
+ else :
145
+ title = i
146
+ out .append (title )
147
+ return out
148
+
149
+
150
+ class LocalDictProvider (BaseProvider ):
121
151
def __init__ (self , * args , ** kwargs ):
122
152
super (LocalDictProvider , self ).__init__ (* args , ** kwargs )
123
153
@@ -131,14 +161,14 @@ def get_predictions(self, search_str):
131
161
search_str = search_str [k + 1 :]
132
162
local = SETTING ("autocomplete_lang_local" )
133
163
path = os .path .join (ADDON_PATH , "resources" , "data" , "common_%s.txt" % (local if local else "en" ))
134
- with codecs . open (path , encoding = "utf8" ) as f :
135
- for line in f .readlines ( ):
164
+ with xbmcvfs . File (path ) as f :
165
+ for line in f .read (). split ( ' \n ' ):
136
166
if not line .startswith (search_str ) or len (line ) <= 2 :
137
167
continue
138
168
li = {"label" : line ,
139
169
"search_string" : line }
140
170
listitems .append (li )
141
- if len (listitems ) > self .limit :
171
+ if len (listitems ) > int ( self .limit ) :
142
172
break
143
173
return listitems
144
174
@@ -148,11 +178,11 @@ def get_JSON_response(url="", cache_days=7.0, folder=False, headers=False):
148
178
get JSON response for *url, makes use of file cache.
149
179
"""
150
180
now = time .time ()
151
- hashed_url = hashlib .md5 (url .encode ()).hexdigest ()
181
+ hashed_url = hashlib .md5 (url .encode ('utf-8' )).hexdigest ()
152
182
if folder :
153
- cache_path = xbmcvfs .translatePath (os .path .join (ADDON_DATA_PATH , folder ))
183
+ cache_path = xbmc .translatePath (os .path .join (ADDON_DATA_PATH , folder ))
154
184
else :
155
- cache_path = xbmcvfs .translatePath (os .path .join (ADDON_DATA_PATH ))
185
+ cache_path = xbmc .translatePath (os .path .join (ADDON_DATA_PATH ))
156
186
path = os .path .join (cache_path , hashed_url + ".txt" )
157
187
cache_seconds = int (cache_days * 86400.0 )
158
188
if xbmcvfs .exists (path ) and ((now - os .path .getmtime (path )) < cache_seconds ):
@@ -183,16 +213,17 @@ def get_http(url=None, headers=False):
183
213
"""
184
214
succeed = 0
185
215
if not headers :
186
- headers = HEADERS
187
- while succeed < 2 and not MONITOR .abortRequested ():
216
+ headers = {
'User-agent' :
'XBMC/16.0 ( [email protected] )' }
217
+ monitor = xbmc .Monitor ()
218
+ while (succeed < 2 ) and (not monitor .abortRequested ()):
188
219
try :
189
220
r = requests .get (url , headers = headers )
190
221
if r .status_code != 200 :
191
222
raise Exception
192
223
return r .text
193
224
except Exception :
194
225
log ("get_http: could not get data from %s" % url )
195
- xbmc . sleep ( 1000 )
226
+ monitor . waitForAbort ( 1 )
196
227
succeed += 1
197
228
return None
198
229
@@ -203,8 +234,9 @@ def read_from_file(path="", raw=False):
203
234
"""
204
235
if not xbmcvfs .exists (path ):
205
236
return False
237
+
206
238
try :
207
- with open (path ) as f :
239
+ with xbmcvfs . File (path ) as f :
208
240
log ("opened textfile %s." % (path ))
209
241
if raw :
210
242
return f .read ()
@@ -230,8 +262,8 @@ def save_to_file(content, filename, path=""):
230
262
text_file_path = os .path .join (path , filename + ".txt" )
231
263
now = time .time ()
232
264
233
- with open (text_file_path , 'w' ) as f :
234
- json .dump (content , f )
265
+ with xbmcvfs . File (text_file_path , "w" ) as text_file :
266
+ json .dump (content , text_file )
235
267
236
268
log ("saved textfile %s. Time: %f" % (text_file_path , time .time () - now ))
237
269
return True
0 commit comments