Tips for coding python scripts / plugins compatible with Linux, Mac, Windows AND Xbox

  Thread Rating:
  • 2 Votes - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
Temhil Offline
Skilled Python Coder
Posts: 397
Joined: Apr 2008
Reputation: 1
Location: Canada
Exclamation  Tips for coding python scripts / plugins compatible with Linux, Mac, Windows AND Xbox
Post: #1
Hi Guys,

I am developing (at least trying Big Grin) XBMC scripts with a French community of users using XBMC some on Linux and some on XBOX (and recently some on windows).
We went few time through the problem of having python script for XBMC NOT compatible for both Linux/Mac and XBOX/Windows.

Hopefully we have found a solution which should be compatible with all the platforms: Linux/Mac and XBOX/Windows
I don't know it has been already a topic on this subject, so sorry if I repeat something but it is better to give this information again since it could be very useful for XBMC Script developers.

The main problem between the 2 platforms Linux/Mac and XBOX/windows is:
  • the format of the path,
  • certain os command does NOT return the same result depending on the OS


Here is an example of code to add to your script in order to find the current path of your script:
Code:
############################################################################
# Get current working directory and update internal vars with it  
############################################################################

# Set paths
if os.name=='posix':
    # Linux case
    ROOTDIR = os.path.abspath(os.curdir).replace(';','')
else:
    # Xbox and Windows case
    ROOTDIR = os.getcwd().replace(';','')

IMAGEDIR    = os.path.join(ROOTDIR, "images")
CACHEDIR    = os.path.join(ROOTDIR, "cache")
DOWNLOADDIR = os.path.join(ROOTDIR, "download")

The other important thing is to only use the 'os.path.join' command instead of a combination of '+' and the os separtor '/' or '\\'.
And if you need to use this separator, it is better to use 'os.sep' instead.

Now an example of code of how to use those paths in order to remain compatible with all the platforms:
Code:
os.remove(os.path.join(DOWNLOADDIR, filename))

Those examples have been tested and work on both Linux/Xbox platforms.

I hope it will help. If every XBMC script developer could do script compatible script between platform it would be nice for the end user.
Right now we can see the issue with Linux users who try to use some script and it doesn't work because of issue on the format of the path used in the script, my guess is it is the same for Mac user too, and it would be a shame not to fix that on new scripts :o.

If you have a better way of writing thos code, please feel free to share with us. Thanks Big Grin
find quote
Gamester17 Offline
Team-XBMC Forum Moderator
Posts: 10,523
Joined: Sep 2003
Reputation: 9
Location: Sweden
Lightbulb  Great but...
Post: #2
Temhil Wrote:The main problem between the 2 platforms Linux/Mac and XBOX/windows is:
  • the format of the path,
  • certain os command does NOT return the same result depending on the OS
would it not be best to try to get those two root causes fixed in XBMC instead of working around them? Confused
...I am not sure if they should be classified as bugs or feature request but please submit new tickets on trac
http://trac.xbmc.org

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
(This post was last modified: 2008-09-08 23:03 by Gamester17.)
find quote
jmarshall Offline
Team-XBMC Developer
Posts: 26,181
Joined: Oct 2003
Reputation: 175
Post: #3
os.getcwd() should return the same thing (i.e. no ; at the end) nowadays.

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


[Image: badge.gif]
find quote
Temhil Offline
Skilled Python Coder
Posts: 397
Joined: Apr 2008
Reputation: 1
Location: Canada
Post: #4
I fully agree with you Gamester17 it should be the same whatever the OS is, so for time being at least script can run on all platform with this workaround.
Nevertheless, even if that will be fix, developer of script will need to use command as os.join and os.sep instead of writing in the code something like:
Code:
filepath=ROOTDIR + '/' + filename

@Gamester17 - I am not familiar with ticket, how do you file it?

@jmarshall, exactly, that was the command I was talking about - one of the biggest problem is os.getcwd() does not return the same thing. For the format of the path if developer only use os.join and os.sep, it is OK, but with the issue on os.getcwd() for Linux case, we are not able to get the current directory properly.
find quote
jmarshall Offline
Team-XBMC Developer
Posts: 26,181
Joined: Oct 2003
Reputation: 175
Post: #5
Please produce a simple example script that fails to return the correct result from os.getcwd().

Tickets are at http://trac.xbmc.org (login is your forum login).

Cheers
Jonathan

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


[Image: badge.gif]
(This post was last modified: 2008-09-09 10:27 by Gamester17.)
find quote
Gamester17 Offline
Team-XBMC Forum Moderator
Posts: 10,523
Joined: Sep 2003
Reputation: 9
Location: Sweden
Post: #6
Trac is our tracking-system for tracking feature requests, bug reports, and code patches that is submitted to us.
http://trac.xbmc.org

Again I am not sure if your specific concern should be classified as a bug or a feature request but set it as a bug for now.

HOW-TO submit a feature request:
http://wiki.xbmc.org/?title=What_is_XBMC...to_XBMC.3F

HOW-TO submit a bug report:
http://wiki.xbmc.org/?title=HOW-TO_Submi...Bug_Report

HOW-TO submit a code patch:
http://wiki.xbmc.org/?title=HOW-TO_submit_a_patch

Wink

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
find quote
blittan Offline
Team-XBMC Handyman
Posts: 1,747
Joined: Jun 2004
Reputation: 11
Location: Sweden
Post: #7
os.path.join should always be used to avoid errors.

os.getcwd() should to my knowledge return correct paths on xbox, linux, windows (can't test mac, since i dont own one *yet*)

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
If you don't have the time to read them, please don't take the time to post in this forum!
For troubleshooting and bug reporting please make sure you read this first.
find quote
BigBellyBilly Offline
Skilled Python Coder
Posts: 900
Joined: Feb 2005
Reputation: 2
Location: UK
Post: #8
thanks for the info on ROOTDIR and I'll be changing all my code to use os.path.join as I update them for Atlantis scripting changes.

quick question, is this:
p = os.path.join('Q:','scripts',__scriptname__)

the same as

p = 'Q:\\scripts\\' + __scriptname__

in that its still from the Q: root ?
thanks

My Addons (myTV, T3CH Upgrader, DVDProfiler, BBCPodRadio, Comics, Football, GoogleReader, reeplay.it, Metacritic, Phonebin, FileViewer,SVN Repo Installer (contributor)) available at Box.net
find quote
Temhil Offline
Skilled Python Coder
Posts: 397
Joined: Apr 2008
Reputation: 1
Location: Canada
Post: #9
BigBellyBilly Wrote:thanks for the info on ROOTDIR and I'll be changing all my code to use os.path.join as I update them for Atlantis scripting changes.

quick question, is this:
p = os.path.join('Q:','scripts',__scriptname__)

the same as

p = 'Q:\\scripts\\' + __scriptname__

in that its still from the Q: root ?
thanks

I didn't try os.path.join with more than 2 arguments, but according to the documentation, what you wrote is correct and does what you said, here is what doc says:
[INDENT]join( path1[, path2[, ...]])
Join one or more path components intelligently. If any component is an absolute path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of path1, and optionally path2, etc., with exactly one directory separator (os.sep) inserted between components, unless path2 is empty. Note that on Windows, since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\\foo. [/INDENT]

Other than that sorry I didn't opened an ticket yet since I don't have ogs for Linux (I don't have currently Linux PC)
find quote
BigBellyBilly Offline
Skilled Python Coder
Posts: 900
Joined: Feb 2005
Reputation: 2
Location: UK
Post: #10
yeah, I know you could have multiple params, but it was 'from root' I was unsure about.
But after some testing, I've found that its best to also use the os.sep

to get -> T:\script_data\myscriptname

use -> p = os.path.join('T:'+os.sep,'script_data',__scriptname__)

works on xbox , windows port. I'm assuming ok on linux
cheers
BBB

My Addons (myTV, T3CH Upgrader, DVDProfiler, BBCPodRadio, Comics, Football, GoogleReader, reeplay.it, Metacritic, Phonebin, FileViewer,SVN Repo Installer (contributor)) available at Box.net
find quote
Temhil Offline
Skilled Python Coder
Posts: 397
Joined: Apr 2008
Reputation: 1
Location: Canada
Thumbs Up  FIXED in XBMC Beta1
Post: #11
Hi guys,

Sorry for coming back only now but since I don't have Linux box I wasn't able to generate logs for opening a bug.

Good news!
With MAC OS port I tried it and now it seems this issue has beem solved in XBMC Beta1 (probably before).
So now instead of doing a test on the OS, it just takes one line of code:
Code:
ROOTDIR = xbmc.translatePath( os.path.join( os.getcwd().replace( ";", "" )))
find quote
Nuka1195 Offline
Skilled Python Coder
Posts: 3,910
Joined: Dec 2004
Reputation: 18
Post: #12
what are you joining?

PHP Code:
ROOTDIR os.getcwd() 
will suffice.

For python coding questions first see http://mirrors.xbmc.org/docs/python-docs/
find quote
blittan Offline
Team-XBMC Handyman
Posts: 1,747
Joined: Jun 2004
Reputation: 11
Location: Sweden
Post: #13
for backwards compability, use os.getcwd().replace(';','')

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
If you don't have the time to read them, please don't take the time to post in this forum!
For troubleshooting and bug reporting please make sure you read this first.
find quote
CrashX Offline
Posting Freak
Posts: 1,164
Joined: Jan 2009
Reputation: 2
Post: #14
Found this info quite usefull:-

http://xbmc.org/jmarshall/2009/02/10/cha...d-plugins/
find quote
CrashX Offline
Posting Freak
Posts: 1,164
Joined: Jan 2009
Reputation: 2
Post: #15
Linux is case sensitive. Hence default.py and default.tbn is not the same as Default.py and Default.tbn. This will actually cause the plugin not to load on linux but will work fine on windows. http://forum.xbmc.org/showthread.php?tid=45547
find quote
Post Reply