Great stuff zag, I wish you luck in your journey. Python is pretty easy to understand and to master if you come from php. Documentation for addon development is not bad at all if you know how to program in python in the first place but I agree it is not great if you don't know how to program in python and want to get started by "learning python for kodi"...like I did. The process of making and debugging an addon can be sometimes quite boring since you don't have any way of executing the code if it uses any of the kodi modules without try, try and try again in kodi itself. I think there is a way to debug it without having it running on kodi but still, you don't know if the code actually works...you just know there isn't any typo.
So basically, notepad++ opened, log file opened, change the code hit return, enter the addon again, check the log for errors. If the code is not giving you errors and it doesn't do what you want it to do, add some prints along the way to understand where it is failing.
As for python versions kodi uses 2.7 in most platforms but uses 2.6 on android (not sure if anything else uses it). This can be tricky if you use modules like datetime since some methods like total_seconds() are not available in python2.6 but are in 2.7. I wouldn't bother with it for now.
A few tips:
-Learn well the basics of python data structures and variables type:
https://docs.python.org/2/tutorial/datastructures.html
Then you'll understand easier the code of other addons. They usually just save data to a datastructure and retrieve it later.
A few tips for kodi related stuff:
-Python api documentation is here:
http://mirrors.kodi.tv/docs/python-docs/14.x-helix/
You'll find there all the classes and specific functions of each module. Please try to master classes and functions, that will make you understand how python works. As an example, look at 'xbmc' module.
Let's say you want to create an instance of the Player() class and then use the play function of this class. You'd do something like this:
Code:
import xbmc
myplayer = xbmc.Player()
myplayer.play('http://some_internet_video_link')
For functions that don't belong to any class you'll do something like below. For instance, suppose you want to know the inet ip address of your machine using the xbmc module (check the standalone function list on the bottom of xbmc module documentation):
Code:
import xbmc
print "My ip is " + xbmc.getIPAddress()
Concatenation is done using + instead of php . for variables of the same type.
Stuff I wished someone has told me before I started:
1) Trigger actions
Sometimes you want to execute certain functions in kodi that are not exposed to the python api. In this case, if you can't find any method in the documentation you should check:
-XBMC builtin functions (
http://kodi.wiki/view/List_of_built-in_functions)
-JSON-RPC API (
http://kodi.wiki/view/JSON-RPC_API/v6) (json is more used to retrieve data instead of trigger an action so it's mentioned a bit below).
Simple examples using builtin functions:
Suppose you want to restart the pvr manager. You won't find any way to do this in the python modules. You can do that using a kodi builtin function:
Code:
import xbmc
xbmc.executebuiltin('StartPVRManager')
Suppose you want to take a screenshot of your kodi screen from python:
Code:
import xbmc
xbmc.executebuiltin('TakeScreenshot')
There isn't any way to execute the stuff above without builtin functions.
2) Get information back from kodi
Sometimes you want to get some parameters or settings from kodi and you won't find a way of retrieving this info from the python api. In these cases you should look into:
-JSON-RPC API (
http://kodi.wiki/view/JSON-RPC_API/v6)
-Kodi boolean functions (
http://kodi.wiki/view/List_of_boolean_conditions)
-Kodi infolabels (
http://kodi.wiki/view/InfoLabels)
2.1) JSON - You may want to use the json-rpc api if you want to have in python some very detailed information and there is no other way to grab it. Let's say you want to grab all the channel groups of your pvr (TV channels):
Code:
import xbmc
import json
response = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "PVR.GetChannelGroups", "params": {"channeltype" : "tv"}, "id": 1 }')
response_as_a_python_dictionary = json.loads(response)
This will help you understand why I said in the beginning to understand very well data structures. executeJSONRPC gets the info as simple string. json.loads converts this response into a python dictionary, you can use to retrieve specific information. Look below:
Code:
print type(response)
returns:
<type 'str'>
Code:
print type(response_as_a_python_dictionary)
returns:
<type 'dict'>
Code:
print response_as_a_python_dictionary
returns:
{u'jsonrpc': u'2.0', u'id': 1, u'result': {u'channelgroups': [{u'channeltype': u'tv', u'channelgroupid': 23, u'label': u'All channels'}, {u'channeltype': u'tv', u'channelgroupid': 24, u'label': u'Sport'}, {u'channeltype': u'tv', u'channelgroupid': 25, u'label': u'Entertainment'}, {u'channeltype': u'tv', u'channelgroupid': 26, u'label': u'Documentary'}}}
Getting info from the dictionary is terribly easy! Again to stress you need to understand very well data structures...the overall response_as_a_python_dictionary variable is a python dictionary (see {}) . Dictionaries have keys and values. Those values can be of any type. In the case above, the value for the key 'result' is another dictionary (see {}) . For this this dictionary, the key 'channelgroups' is a list (see [] ), each item in this list is another dictionary (see {}).
So suppose we want to grab a list of all channel group labels (code documented):
Code:
#we start by creating an empty list
my_channellabels = []
#we iterate the items in the list that are the value of 'channelgroups' key that itself is the value of 'result' key of the main dictionary
for sub_dictionary in response_as_a_python_dictionary['result']['channelgroups']:
#we append the value of the key 'label' to my_channellabels list
my_channellabels.append(sub_dictionary['label']
#we print the overall list
print my_channellabels
result will be: ['All channels','Sport','Entertainment',''Documentary'']
2.2) Boolean functions
Boolean functions return True of False if a given condition is verified. You usually don't have any way of checking if the user has some property defined in any other way (probably with json you can grab them as well) and it is too simple!
Suppose you want to know if the user is running Windows:
Code:
import xbmc
condition = xbmc.getCondVisibility('System.Platform.Windows')
if condition:
print "The user is running windows. Virus everywhere..."
else:
print "The user is not running windows. What is we running?"
condition = xbmc.getCondVisibility('System.Platform.OSX')
if condition:
print "The user is running osx, he has a starbucks free pass"
else:
condition = xbmc.getCondVisibility('System.Platform.Linux')
if condition:
print "Oh no, another geeky nerd"
else:
print "the user is not running windows, not osx, not linux. "
2.3) Infolabels
Infolabels are another way of getting short and specific info from kodi you can use to later execute specific functions or perform some actions. Unlike boolean conditions (true false for a given condition), they return strings. Suppose you want to know title of the media that is playing. In this example we'll mix boolean conditions with infolabels.
Code:
import xbmc
condition = xbmc.getCondVisibility('Player.HasMedia')
if condition:
print "Kodi is playing something..."
is_video = xbmc.getCondVisibility('Player.HasVideo')
if is_video:
print "Kodi is playing the following video: " + xbmc.getInfoLabel('VideoPlayer.Title')
else:
#It is playing music
print "kodi is playing the following music: " + xbmc.getInfoLabel('MusicPlayer.Title') + ' from ' + xbmc.getInfoLabel('MusicPlayer.Artist') + ' and the album is ' + xbmc.getInfoLabel('MusicPlayer.Album')
else:
print "Kodi is not playing anything"
Another example, get the user's weather conditions:
Code:
import xbmc
weatherconditions = xbmc.getInfoLabel('Weather.Conditions')
weatherlocation = xbmc.getInfoLabel('Weather.Location')
if 'rain' in weatherconditions and 'London' in weatherlocation:
print "Oh god...it's raining in London. The world is about to end!"
-----------------------------------
I wish you luck in your journey. The stuff above is pretty simple and just stresses ways of getting data, conditions and perform actions. Usually you see questions in the forum about "how to get this" and "how to get that" and the solution is often the same...infolabels, boolean conditions, json rpc.
Since you are a web developer you could probably create a simple blog to document your journey. Probably we can even get other people to contribute and submit posts. Later with proper tutorials they could be moved to the wiki.
Subscribed the thread, anything you need just ask. I finish by saying I really wished everyone would be like you around these forums...trying to learn, to help others, to document stuff with a lot of detail without keeping the solution for yourself or answer in 2 or 3 words just to stress "how good I am" and how my ego is big.
Cheers