OK. I have reviewed the changes I did to the script to fix the encoding errors. First here is a log of a sample Crash (not the full log, just the python error):
http://pastebin.com/vuZpMNux
You can see that I use to check for encoding issues a windows portable installation in a path with non-ascii chars (C:\Users\Jesús\) This always troubles scripts that doesn't keep track in their programming that each str variable is encoded either using "utf-8" (all strings returned by xbmc modules) or "mbcs" (Python uses the name “mbcs” to refer to whatever the currently configured encoding is for the filesystem. Don't know how it handles when the system has 2 filesystems with different encodings, if that's possible).
When programming if you don't want to keep in mind the encoding of each srt variable the easiest thing to do is decode them (to unicode) as soon as you load them. Luckily most Python standard libraries and xbmc modules accept unicode variables perfectly. And for the ones that don't you can encode on the fly to the adequate encoding (I have never needed to encode for a system call. Just a few xbmc calls require utf-8 strs).
But enough bla bla lets check TV Show Next Aired Problems...
In the log we see the error:
Code:
File "C:\Users\Jesús\Programas\XBMC12\portable_data\addons\script.tv.show.next.aired\default.py", line 140, in update_data
elif time() - os.path.getmtime(dbfile) > 86400:
...
WindowsError: (3, 'El sistema no puede encontrar la ruta especificada', 'C:\\Users\\Jes\xc3\xbas\\Programas\\XBMC12\\portable_data\\userdata\\addon_data\\script.tv.show.next.aired\\next_aired.db')
This spanish texts means that the system can't find the path. That is because we passed a utf-8 encoded string to a system call when the filesystem encoding is "latin". So the path in fact doesn't exist.
And how do I know dbfile is utf-8 encoded? Let's backtrack the code:
Line 140: elif time() - os.path.getmtime(
dbfile) > 86400:
#dbfile is defined in:
Line 134: dbfile = os.path.join(
DATA_PATH , "next_aired.db" )
#DATA_PATH is defined in:
Line 23: DATA_PATH = os.path.join( xbmc.translatePath( "special://profile/addon_data/" ), __addonid__ )
So in the beginning DATA_PATH is obtained from a call to a xbmc module (translatePath) that is passed to a system call (os.path.join).
This, in concept, is already a programming error since we are giving a system call (that accepts unicode or "mbcs" encoded strings) a "utf-8" encoded string. In the practice this kind of works because all os.path.join does is appending strings with the adecuate path separator ("\" or "/" depending on the system) so we get a string path encoded with "utf-8".
But this utf-8 encoding is not good for os.path.getmtime in line 140 and we get the "file not found" error
One way to fix this specific problem will be to decode/reencode the dbfile string adequately:
Code:
elif time() - os.path.getmtime(dbfile.decode("utf-8").encode("mbcs")) > 86400:
This fix that crash, but is not the nicest solution, nor my style. Also we will get more errors from the implicit error in DATA_PATH.
As I said in the beginning the best way is to decode things to unicode as soon as we get the value. Most modules will work fine with unicode.
So finally this are the changes I did (I have to declare that I'm doing the changes again as I write this because when I got the old version back to compare the changes I destroyed the new version DAHH
):
Line 17: __cwd__ = __addon__.getAddonInfo('path')
.decode("utf-8")
Line 23: DATA_PATH = os.path.join( xbmc.translatePath( "special://profile/addon_data/" )
.decode("utf-8"), __addonid__ )
Line 24: RESOURCES_PATH = xbmc.translatePath( os.path.join( __cwd__, 'resources' ).encode("utf-8") ).decode("utf-8") #When in doubt I prefer to pass xbmc modules utf-8 strings and then decode to unicode the final path
Line 37: #Redefine the whole log procedure:
def log(txt): #Changes to admit both unicode strings and str encoded with "utf-8" (or ascii). will fail with other encodings.
> if isinstance (txt,str):
>> txt = txt.decode("utf-8") #if it is str we assume it's "utf-8" encoded. will fail if called with other encodings (latin, etc) BE ADVISED!
#At this point we are sure txt is a unicode string.
> message =
u'%s: %s' % (__addonid__, txt)
> xbmc.log(msg=message
.encode("utf-8"), level=xbmc.LOGDEBUG
Sorry about the formatting. I have to go pick up my wife and don't have any more time. I hope it is good enough.
If needed I can push the changes or send a diff or whatever you think is convenient.
Cheers.