Skip to content

Commit ebbcef5

Browse files
committed
Better po file formatting
Fixes bug with unicode strings Fixes bug with mp3 files with no tags Fixes bug in reading windowsids from settings Improves onShutdown task
1 parent 2571364 commit ebbcef5

19 files changed

+670
-258
lines changed

addon.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="script.service.kodi.callbacks" name="Kodi Callbacks" version="0.9.9" provider-name="KenV99">
2+
<addon id="script.service.kodi.callbacks" name="Kodi Callbacks" version="1.0.0" provider-name="KenV99">
33
<requires>
44
<import addon="xbmc.python" version="2.20.0"/>
55
<import addon="script.module.requests" version="2.3.0"/>

changelog.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
v1.0.0 (2016-05-29)
2+
Better po file formatting
3+
Fixes bug with unicode strings
4+
Fixes bug with mp3 files with no tags
5+
Fixes bug in reading windowsids from settings
6+
Improves onShutdown task
7+
18
v0.9.9 (2016-03-22)
29
Version changed to meet official repo rules
310

default.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
testdebug = False # TODO: check
2323
testTasks = False # TODO: check
2424
branch = 'master'
25-
build = '1009'
25+
build = '1015'
2626

2727
from resources.lib.utils.debugger import startdebugger
2828

resources/language/English/strings.po

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
msgid ""
66
msgstr ""
77
"Project-Id-Version: XBMC Addons\n"
8+
"Report-Msgid-Bugs-To: [email protected]\n"
89
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
910
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11+
"Last-Translator: Kodi Translation Team\n"
12+
"Language-Team: English (http://www.transifex.com/projects/p/xbmc-addons/language/en/)\n"
1013
"MIME-Version: 1.0\n"
1114
"Content-Type: text/plain; charset=UTF-8\n"
1215
"Content-Transfer-Encoding: 8bit\n"
@@ -17,7 +20,7 @@ msgid "Callbacks for Kodi"
1720
msgstr ""
1821

1922
msgctxt "Addon Description"
20-
msgid "Provides user definable actions for specific events within Kodi. Credit to Yesudeep Mangalapilly (gorakhargosh on github) and contributors for watchdog and pathtools modules."
23+
msgid "Provides user definable actions for specific events within Kodi. Credit to Yesudeep Mangalapilly (gorakhargosh on github) and contributors for watchdog and pathtools modules. "
2124
msgstr ""
2225

2326
msgctxt "Addon Disclaimer"

resources/lib/dialogtb.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,22 @@ def onFocus(self, controlID):
6161
def show_textbox(title, msg):
6262
_addon_ = xbmcaddon.Addon('script.service.kodi.callbacks')
6363
_cwd_ = xbmc.translatePath(_addon_.getAddonInfo('path'))
64-
msgbox = MessageDialog("DialogTextBox.xml", _cwd_, "Default")
64+
msgbox = MessageDialog(u"DialogTextBox.xml", _cwd_, u"Default")
6565
xt = type(msg)
6666
if xt is str or xt is unicode:
67-
wmsg = '\n'.join(textwrap.wrap(msg, 62))
67+
wmsg = u'\n'.join(textwrap.wrap(msg, 62))
6868
elif xt is list:
6969
tmsg = []
7070
for i in msg:
7171
omsg = textwrap.wrap(i, width=62, break_long_words=True)
7272
l1 = []
7373
for i1 in omsg:
74-
l1.append('i=%s, len=%s' % (i1, len(i1)))
75-
nmsg = '\n'.join(omsg) + '\n'
74+
l1.append(u'i=%s, len=%s' % (i1, len(i1)))
75+
nmsg = u'\n'.join(omsg) + u'\n'
7676
tmsg.append(nmsg)
77-
wmsg = ''.join(tmsg)
77+
wmsg = u''.join(tmsg)
7878
else:
79-
wmsg = ''
79+
wmsg = u''
8080
msgbox.set_text(title, wmsg)
8181
msgbox.doModal()
8282
del msg

resources/lib/kodilogging.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def log(loglevel=None, msg=''):
6262
if isinstance(msg, str):
6363
msg = msg.decode("utf-8")
6464
if KodiLogger.kodirunning:
65-
message = u"$$$ [%s] - %s" % ('kodi.callbacks', msg)
66-
xbmc.log(msg=message.encode("utf-8"), level=loglevel)
65+
message = u"$$$ [%s] - %s" % (u'kodi.callbacks', msg)
66+
xbmc.log(msg=message.encode("utf-8", errors='replace'), level=loglevel)
6767
else:
6868
print msg

resources/lib/publishers/log.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import threading
2222
from Queue import Queue, Empty
2323
import re
24+
import codecs
2425
from resources.lib.pubsub import Publisher, Topic, Message
2526
from resources.lib.events import Events
2627
from resources.lib.utils.poutil import KodiPo
@@ -39,7 +40,7 @@ def __init__(self, interval=100):
3940
self.interval = interval
4041

4142
def run(self):
42-
f = open(self.logfn, 'r')
43+
f = codecs.open(self.logfn, 'r', encoding='utf-8', errors='ignore')
4344
f.seek(0, 2) # Seek @ EOF
4445
fsize_old = f.tell()
4546
while not self.__abort_evt.is_set():

resources/lib/publishers/player.py

Lines changed: 65 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def getTitle(self):
113113
tries += 1
114114
title = xbmc.getInfoLabel('MusicPlayer.Title')
115115
if title is None or title == '':
116-
return 'Kodi cannot detect title'
116+
return u'Kodi cannot detect title'
117117
else:
118118
return title
119119
elif self.isPlayingVideo():
@@ -137,46 +137,46 @@ def getTitle(self):
137137
title = ''
138138
else:
139139
try:
140-
title = ret['result']['item']['title']
140+
title = ret[u'result'][u'item'][u'title']
141141
except KeyError:
142-
title = 'Kodi cannot detect title'
142+
title = u'Kodi cannot detect title'
143143
else:
144-
if title == '':
145-
title = ret['result']['item']['label']
146-
if title == '':
147-
title = 'Kodi cannot detect title'
144+
if title == u'':
145+
title = ret[u'result'][u'item'][u'label']
146+
if title == u'':
147+
title = u'Kodi cannot detect title'
148148
return title
149149
else:
150150
return title
151151
else:
152-
return 'Kodi cannot detect title - none playing'
152+
return u'Kodi cannot detect title - none playing'
153153

154154
def getAudioInfo(self, playerid):
155155
try:
156156
info = json.loads(xbmc.executeJSONRPC(
157157
'{"jsonrpc": "2.0", "method": "Player.GetItem", "params": { "properties": ["title", "album",'
158158
' "artist", "duration", "file", "streamdetails"], "playerid": %s }, "id": "AudioGetItem"}'
159159
% playerid))['result']['item']
160-
if 'artist' in info.keys():
161-
t = info['artist']
162-
if isinstance(t, list):
163-
info['artist'] = t[0]
160+
if u'artist' in info.keys():
161+
t = info[u'artist']
162+
if isinstance(t, list) and len(t) > 0:
163+
info[u'artist'] = t[0]
164164
elif isinstance(t, unicode):
165165
if t != u'':
166-
info['artist'] = t
166+
info[u'artist'] = t
167167
else:
168-
info['artist'] = u'unknown'
168+
info[u'artist'] = u'unknown'
169169
else:
170-
info['artist'] = u'unknown'
170+
info[u'artist'] = u'unknown'
171171
else:
172-
info['artist'] = u'unknown'
173-
items = ['duration', 'id', 'label', 'type']
172+
info[u'artist'] = u'unknown'
173+
items = [u'duration', u'id', u'label', u'type']
174174
for item in items:
175175
try:
176176
del info[item]
177177
except KeyError:
178178
pass
179-
info['mediaType'] = 'audio'
179+
info[u'mediaType'] = u'audio'
180180
except RuntimeError:
181181
self.info = {}
182182
else:
@@ -191,43 +191,61 @@ def getVideoInfo(self, playerid):
191191
except RuntimeError:
192192
self.info = {}
193193
else:
194-
items = ['label', 'id', 'tvshowid']
194+
items = [u'label', u'id', u'tvshowid']
195195
for item in items:
196196
try:
197197
del info[item]
198198
except KeyError:
199199
pass
200-
items = {'mediaType': 'type', 'fileName': 'file'}
200+
items = {u'mediaType': u'type', u'fileName': u'file'}
201201
for item in items.keys():
202202
try:
203203
t = items[item]
204204
info[item] = info.pop(t, 'unknown')
205205
except KeyError:
206-
info[item] = 'unknown'
206+
info[item] = u'unknown'
207207
if info['mediaType'] != 'musicvideo':
208-
items = ['artist', 'album']
208+
items = [u'artist', u'album']
209209
for item in items:
210210
try:
211211
del info[item]
212212
except KeyError:
213213
pass
214214
else:
215-
info['artist'] = info['artist'][0]
216-
if 'streamdetails' in info.keys():
217-
sd = info.pop('streamdetails', {})
218-
info['stereomode'] = sd['video'][0]['stereomode']
219-
info['width'] = str(sd['video'][0]['width'])
220-
info['height'] = str(sd['video'][0]['height'])
221-
info['aspectRatio'] = str(int((sd['video'][0]['aspect'] * 100.0) + 0.5) / 100.0)
222-
if info['mediaType'] == u'episode':
223-
items = ['episode', 'season']
215+
try:
216+
info[u'artist'] = info[u'artist'][0]
217+
except (KeyError, IndexError):
218+
info[u'artist'] = u'unknown'
219+
if u'streamdetails' in info.keys():
220+
sd = info.pop(u'streamdetails', {})
221+
try:
222+
info[u'stereomode'] = sd[u'video'][0][u'stereomode']
223+
except (KeyError, IndexError):
224+
info[u'stereomode'] = u'unknown'
225+
else:
226+
if info[u'stereomode'] == u'':
227+
info[u'stereomode'] = u'unknown'
228+
try:
229+
info[u'width'] = unicode(sd[u'video'][0][u'width'])
230+
except (KeyError, IndexError):
231+
info[u'width'] = u'unknown'
232+
try:
233+
info[u'height'] = unicode(sd[u'video'][0][u'height'])
234+
except (KeyError, IndexError):
235+
info[u'height'] = u'unknown'
236+
try:
237+
info[u'aspectRatio'] = unicode(int((sd[u'video'][0][u'aspect'] * 100.0) + 0.5) / 100.0)
238+
except (KeyError, IndexError):
239+
info[u'aspectRatio'] = u'unknown'
240+
if info[u'mediaType'] == u'episode':
241+
items = [u'episode', u'season']
224242
for item in items:
225243
try:
226-
info[item] = str(info[item]).zfill(2)
244+
info[item] = unicode(info[item]).zfill(2)
227245
except KeyError:
228-
info[item] = 'unknown'
246+
info[item] = u'unknown'
229247
else:
230-
items = ['episode', 'season', 'showtitle']
248+
items = [u'episode', u'season', u'showtitle']
231249
for item in items:
232250
try:
233251
del info[item]
@@ -261,52 +279,52 @@ def getInfo(self):
261279
self.info = {}
262280

263281
def rectifyUnknowns(self):
264-
items = {'filename': self.getPlayingFileX, 'aspectRatio': self.getAspectRatio, 'height': self.getResoluion,
265-
'title': self.getTitle}
282+
items = {u'fileName': self.getPlayingFileX, u'aspectRatio': self.getAspectRatio, u'height': self.getResoluion,
283+
u'title': self.getTitle}
266284
for item in items.keys():
267285
if item not in self.info.keys():
268286
self.info[item] = items[item]()
269287
else:
270288
try:
271-
if self.info[item] == '' or self.info[item] == 'unknown':
289+
if self.info[item] == '' or self.info[item] == u'unknown':
272290
self.info[item] = items[item]()
273291
except KeyError:
274292
pass
275293
pt = self.playing_type()
276-
if 'mediaType' not in self.info.keys():
277-
self.info['mediaType'] = pt
294+
if u'mediaType' not in self.info.keys():
295+
self.info[u'mediaType'] = pt
278296
else:
279297
try:
280-
if pt != 'unknown' and self.info['mediaType'] != pt:
281-
self.info['mediaType'] = pt
298+
if pt != u'unknown' and self.info[u'mediaType'] != pt:
299+
self.info[u'mediaType'] = pt
282300
except KeyError:
283301
pass
284302

285303
def getPlayingFileX(self):
286304
try:
287305
fn = self.getPlayingFile()
288306
except RuntimeError:
289-
fn = 'unknown'
307+
fn = u'unknown'
290308
if fn is None or fn == '':
291-
fn = 'unknown'
309+
fn = u'unknown'
292310
return xbmc.translatePath(fn)
293311

294312
@staticmethod
295313
def getAspectRatio():
296314
ar = xbmc.getInfoLabel("VideoPlayer.VideoAspect")
297315
if ar is None:
298-
ar = 'unknown'
316+
ar = u'unknown'
299317
elif ar == '':
300-
ar = 'unknown'
318+
ar = u'unknown'
301319
return str(ar)
302320

303321
@staticmethod
304322
def getResoluion():
305323
vr = xbmc.getInfoLabel("VideoPlayer.VideoResolution")
306324
if vr is None:
307-
vr = 'unknown'
325+
vr = u'unknown'
308326
elif vr == '':
309-
vr = 'unknown'
327+
vr = u'unknown'
310328
return str(vr)
311329

312330
def onPlayBackStarted(self):

resources/lib/publishers/watchdogStartup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def start(self):
7878
diff = DirectorySnapshotDiff(oldsnapshot, newsnapshot)
7979
changes = self.getChangesFromDiff(diff)
8080
if len(changes) > 0:
81-
eh = EventHandler(patterns=setting['ws_patterns'].split(','), ignore_patterns=setting['ws_ignore_patterns'].split(','),
81+
eh = EventHandler(patterns=setting['ws_patterns'].split(u','), ignore_patterns=setting['ws_ignore_patterns'].split(u','),
8282
ignore_directories=setting['ws_ignore_directories'])
8383
observer = Observer()
8484
try:
@@ -98,7 +98,7 @@ def start(self):
9898
self.publish(message)
9999
else:
100100
message = Message(Topic('onStartupFileChanges', setting['key']), listOfChanges=[{'DirsDeleted':folder}])
101-
log(msg=_('Watchdog Startup folder not found: %s') % folder)
101+
log(msg=_(u'Watchdog Startup folder not found: %s') % folder)
102102
self.publish(message)
103103

104104
@staticmethod

resources/lib/pubsub.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def __eq__(self, other):
106106

107107
def __repr__(self):
108108
if self.has_subtopic():
109-
return '%s:%s' % (self.topic, self.subtopic)
109+
return u'%s:%s' % (self.topic, self.subtopic)
110110
else:
111111
return self.topic
112112

@@ -161,6 +161,8 @@ def run(self):
161161

162162
def abort(self, timeout=0):
163163
if self.running:
164+
while not self._message_q.empty(): #Fixes bug where Shutdown event does not run bc abort called
165+
time.sleep(0.1)
164166
self._abort_evt.set()
165167
if timeout > 0:
166168
self.join(timeout)
@@ -302,15 +304,15 @@ def addTaskManager(self, tm):
302304
def notify(self, message):
303305
for taskmanager in self.taskmanagers:
304306
try:
305-
self.logger.log(self.loglevel, _('Task starting for %s') % message.topic)
307+
self.logger.log(self.loglevel, _(u'Task starting for %s') % message.topic)
306308
taskmanager.start(message.topic, **message.kwargs)
307309
except TaskManagerException_TaskAlreadyRunning as e:
308-
self.logger.log(self.loglevel, '%s - %s' % (message.topic, e.message))
310+
self.logger.log(self.loglevel, u'%s - %s' % (message.topic, e.message))
309311
except TaskManagerException_TaskInRefractoryPeriod as e:
310-
self.logger.log(self.loglevel, '%s - %s' % (message.topic, e.message))
312+
self.logger.log(self.loglevel, u'%s - %s' % (message.topic, e.message))
311313
except TaskManagerException_TaskCountExceeded as e:
312-
self.logger.log(self.loglevel, '%s - %s' % (message.topic, e.message))
314+
self.logger.log(self.loglevel, u'%s - %s' % (message.topic, e.message))
313315
except Exception as e:
314316
raise e
315317
else:
316-
self.logger.log(self.loglevel, _('Task finalized for %s') % message.topic)
318+
self.logger.log(self.loglevel, _(u'Task finalized for %s') % message.topic)

0 commit comments

Comments
 (0)