<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://kodi.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SimpleKodi</id>
	<title>Official Kodi Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://kodi.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SimpleKodi"/>
	<link rel="alternate" type="text/html" href="https://kodi.wiki/view/Special:Contributions/SimpleKodi"/>
	<updated>2026-06-16T14:35:04Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://kodi.wiki/index.php?title=Audio-video_add-on_tutorial&amp;diff=113045</id>
		<title>Audio-video add-on tutorial</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=Audio-video_add-on_tutorial&amp;diff=113045"/>
		<updated>2016-01-10T09:35:42Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: Added a Video Tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav|[[Development]]|[[Add-on development]]}}&lt;br /&gt;
&lt;br /&gt;
This page will outline the basics of creating your first Python add-on for Kodi. It assumes you&#039;re at least familiar with the basics of Python (or at least, programming in general). If not, we recommend visiting the [http://docs.python.org/2/tutorial/ Python tutorial] first, and then returning here.&lt;br /&gt;
&lt;br /&gt;
=Video Tutorial=&lt;br /&gt;
{{youtube|FtQgZ2bxFkk}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/FtQgZ2bxFkk Video&#039;s Description.]&lt;br /&gt;
&lt;br /&gt;
*This video will help you make a video add-on for Kodi. The video&#039;s steps might be different from the written tutorial below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Before we get started =&lt;br /&gt;
{{See also|Add-on structure}}&lt;br /&gt;
&lt;br /&gt;
The first step to making an add-on is to put the basic structure in place. Make sure your directory is properly named, e.g. &amp;lt;code&amp;gt;plugin.video.my-addon&amp;lt;/code&amp;gt;, and that you have a properly-constructed &amp;lt;code&amp;gt;[[addon.xml]]&amp;lt;/code&amp;gt; file. Once these are done, you can get started writing the actual code for your add-on!&lt;br /&gt;
&lt;br /&gt;
= Hello, World! =&lt;br /&gt;
&lt;br /&gt;
The simplest form of Python add-on is one that gets run, adds some list items, and exits to let Kodi take over the navigation; people who have written server-side code for the web should be familiar with how this works. (More complex add-ons can process user input in real-time, but we&#039;ll discuss those later.) Let&#039;s start by looking at an extremely basic example script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import xbmcgui&lt;br /&gt;
import xbmcplugin&lt;br /&gt;
&lt;br /&gt;
addon_handle = int(sys.argv[1])&lt;br /&gt;
&lt;br /&gt;
xbmcplugin.setContent(addon_handle, &#039;movies&#039;)&lt;br /&gt;
&lt;br /&gt;
url = &#039;http://localhost/some_video.mkv&#039;&lt;br /&gt;
li = xbmcgui.ListItem(&#039;My First Video!&#039;, iconImage=&#039;DefaultVideo.png&#039;)&lt;br /&gt;
xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)&lt;br /&gt;
&lt;br /&gt;
xbmcplugin.endOfDirectory(addon_handle)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While not particularly exciting, this shows the minimal amount of code you need to get an Kodi add-on up and running in Python. First, we get the add-on&#039;s process handle from &amp;lt;code&amp;gt;sys.argv[1]&amp;lt;/code&amp;gt;. We need this to tell Kodi who we are. Next, we tell Kodi that we&#039;re going to show a list of &amp;lt;code&amp;gt;&#039;movies&#039;&amp;lt;/code&amp;gt;. There are other options, like &amp;lt;code&amp;gt;&#039;audio&#039;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&#039;episodes&#039;&amp;lt;/code&amp;gt;; these just change some details of how Kodi presents your add-on.&lt;br /&gt;
&lt;br /&gt;
The most important part is that we create an &amp;lt;code&amp;gt;xbmcgui.ListItem&amp;lt;/code&amp;gt; with the name and icon we want (&amp;lt;code&amp;gt;&#039;DefaultVideo.png&#039;&amp;lt;/code&amp;gt; comes from the Kodi skin), set it to be a video item, and then add it to the directory. Once we&#039;re done adding items, we need to be sure to call &amp;lt;code&amp;gt;xbmcplugin.endOfDirectory&amp;lt;/code&amp;gt; to let Kodi know we&#039;re done!&lt;br /&gt;
&lt;br /&gt;
= Navigating between pages =&lt;br /&gt;
&lt;br /&gt;
While the first example might be enough for extremely simple add-ons, most add-ons will want to have the ability to navigate between different pages. Most add-ons are designed to imitate a folder hierarchy where opening folder items shows a different list of items, and going &amp;quot;up&amp;quot; returns you to the parent folder.&lt;br /&gt;
&lt;br /&gt;
== Retrieving arguments ==&lt;br /&gt;
&lt;br /&gt;
As we saw in the first example, Kodi passes some arguments to us via &amp;lt;code&amp;gt;sys.argv&amp;lt;/code&amp;gt;. This is important, since it&#039;s what will let us tailor the output on the add-on based on user input. Remember, much like a web site, each folder (or page) in an Kodi add-on is the result of a separate invocation of our script. The arguments available to us are:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;prettytable&amp;quot; &lt;br /&gt;
! Index !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || The base URL of your add-on, e.g. &amp;lt;code&amp;gt;&#039;plugin://plugin.video.myaddon/&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || The process handle for this add-on, as a numeric string&lt;br /&gt;
|-&lt;br /&gt;
| 2 || The query string passed to your add-on, e.g. &amp;lt;code&amp;gt;&#039;?foo=bar&amp;amp;baz=quux&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Of particular interest is &amp;lt;code&amp;gt;sys.argv[2]&amp;lt;/code&amp;gt;, which is what we&#039;ll generally use to show different things in the add-on.&lt;br /&gt;
&lt;br /&gt;
=== Multiple content types ===&lt;br /&gt;
{{See also|Addon.xml#&amp;lt;provides&amp;gt; element}}&lt;br /&gt;
&lt;br /&gt;
If your add-on provides multiple content types, e.g. &amp;lt;code&amp;gt;audio&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;video&amp;lt;/code&amp;gt;, when the user invokes your add-on from the add-on list, Kodi will add a &amp;lt;code&amp;gt;content_type&amp;lt;/code&amp;gt; parameter to your add-on&#039;s query string. For example: &amp;lt;code&amp;gt;&#039;?content_type=audio&#039;&amp;lt;/code&amp;gt;. This will allow you to modify the output depending on what context your add-on was invoked in.&lt;br /&gt;
&lt;br /&gt;
== Passing arguments ==&lt;br /&gt;
&lt;br /&gt;
Now that we know how to retrieve the arguments passed to our add-on, we&#039;ll have to actually pass some along to it. Generally speaking, this involves creating a folder &amp;lt;code&amp;gt;ListItem&amp;lt;/code&amp;gt; with a URL back to your add-on; then the next invocation of the add-on will parse those arguments and do something with them. Let&#039;s look at another brief example that adds some folders to let the user navigate between different pages of the add-on:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
import urllib&lt;br /&gt;
import urlparse&lt;br /&gt;
import xbmcgui&lt;br /&gt;
import xbmcplugin&lt;br /&gt;
&lt;br /&gt;
base_url = sys.argv[0]&lt;br /&gt;
addon_handle = int(sys.argv[1])&lt;br /&gt;
args = urlparse.parse_qs(sys.argv[2][1:])&lt;br /&gt;
&lt;br /&gt;
xbmcplugin.setContent(addon_handle, &#039;movies&#039;)&lt;br /&gt;
&lt;br /&gt;
def build_url(query):&lt;br /&gt;
    return base_url + &#039;?&#039; + urllib.urlencode(query)&lt;br /&gt;
&lt;br /&gt;
mode = args.get(&#039;mode&#039;, None)&lt;br /&gt;
&lt;br /&gt;
if mode is None:&lt;br /&gt;
    url = build_url({&#039;mode&#039;: &#039;folder&#039;, &#039;foldername&#039;: &#039;Folder One&#039;})&lt;br /&gt;
    li = xbmcgui.ListItem(&#039;Folder One&#039;, iconImage=&#039;DefaultFolder.png&#039;)&lt;br /&gt;
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url,&lt;br /&gt;
                                listitem=li, isFolder=True)&lt;br /&gt;
&lt;br /&gt;
    url = build_url({&#039;mode&#039;: &#039;folder&#039;, &#039;foldername&#039;: &#039;Folder Two&#039;})&lt;br /&gt;
    li = xbmcgui.ListItem(&#039;Folder Two&#039;, iconImage=&#039;DefaultFolder.png&#039;)&lt;br /&gt;
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url,&lt;br /&gt;
                                listitem=li, isFolder=True)&lt;br /&gt;
&lt;br /&gt;
    xbmcplugin.endOfDirectory(addon_handle)&lt;br /&gt;
&lt;br /&gt;
elif mode[0] == &#039;folder&#039;:&lt;br /&gt;
    foldername = args[&#039;foldername&#039;][0]&lt;br /&gt;
    url = &#039;http://localhost/some_video.mkv&#039;&lt;br /&gt;
    li = xbmcgui.ListItem(foldername + &#039; Video&#039;, iconImage=&#039;DefaultVideo.png&#039;)&lt;br /&gt;
    xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)&lt;br /&gt;
    xbmcplugin.endOfDirectory(addon_handle)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, many parts of our code are very similar to the first example. There are a few important additions, however. First, we want to respond to the arguments supplied to our script, so we parse the query string with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
urlparse.parse_qs(sys.argv[2][1:])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We skip the first character, since it&#039;s always &amp;lt;code&amp;gt;&#039;?&#039;&amp;lt;/code&amp;gt;. This will give us a &amp;lt;code&amp;gt;dict&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;list&amp;lt;/code&amp;gt;s; for example, &amp;lt;code&amp;gt;&#039;?foo=bar&amp;amp;foo=baz&amp;amp;quux=spam&#039;&amp;lt;/code&amp;gt; would be converted to &amp;lt;code&amp;gt;{&#039;foo&#039;: [&#039;bar&#039;, &#039;baz&#039;], &#039;quux&#039;: [&#039;spam&#039;]}&amp;lt;/code&amp;gt;. With this information, we can tailor the output of our add-on to the supplied arguments.&lt;br /&gt;
&lt;br /&gt;
We also need to be able to create links back to our add-on in order to display related pages (e.g. subfolders). We can do this by creating an &amp;lt;code&amp;gt;xbmc.ListItem&amp;lt;/code&amp;gt;, passing &amp;lt;code&amp;gt;isFolder=True&amp;lt;/code&amp;gt;, and setting the URL of the item to point back to our add-on. We create the URL in the helper function &amp;lt;code&amp;gt;build_url()&amp;lt;/code&amp;gt;, which gives us a URL that looks something like:&lt;br /&gt;
&lt;br /&gt;
 plugin://plugin.video.myaddon/?mode=folder&amp;amp;foldername=Folder+One&lt;br /&gt;
&lt;br /&gt;
= Working with user settings =&lt;br /&gt;
{{See also|Add-on settings}}&lt;br /&gt;
&lt;br /&gt;
Your add-on may require some configurable options for the user (e.g. login credentials for a service). These can be stored as settings. To use settings with your add-on, you&#039;ll need to make a file defining the settings in &amp;lt;code&amp;gt;resources/settings.xml&amp;lt;/code&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;settings&amp;gt;&lt;br /&gt;
    &amp;lt;setting id=&amp;quot;my_setting&amp;quot; type=&amp;quot;bool&amp;quot; default=&amp;quot;true&amp;quot; label=&amp;quot;My Setting&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/settings&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will allow the user to open the settings for your add-on and modify this setting as needed. Then, in your add-on, you can retrieve or set this setting with the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
my_addon = xbmcaddon.Addon()&lt;br /&gt;
my_setting = my_addon.getSetting(&#039;my_setting&#039;) # returns the string &#039;true&#039; or &#039;false&#039;&lt;br /&gt;
my_addon.setSetting(&#039;my_setting&#039;, &#039;false&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Showing additional metadata =&lt;br /&gt;
&lt;br /&gt;
We&#039;ve already seen how to show some basic metadata, like the icon image and the type of the item (&amp;lt;code&amp;gt;&#039;video&#039;&amp;lt;/code&amp;gt; in our case). However, there are many more pieces of metadata that Kodi understands, and adding them can make life easier on your users. We&#039;ll take a look at some of the more important ones. You can also find a full list in the [http://mirrors.kodi.tv/docs/python-docs/ Python documentation] for &amp;lt;code&amp;gt;[http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcgui.html#ListItem xbmcgui.ListItem]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Icons, thumbnails and artwork ==&lt;br /&gt;
&lt;br /&gt;
Our previous examples already showed how to set an icon, but you can also set a thumbnail, fanart (full-screen background images) and other artwork. They can be set with the &amp;lt;code&amp;gt;ListItem.setArt&amp;lt;/code&amp;gt; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
li = xbmcgui.ListItem(label=&#039;My video&#039;)&lt;br /&gt;
li.setIconImage(&#039;icon.png&#039;)&lt;br /&gt;
li.setArt({&#039;thumb&#039;: &#039;thumbnail.jpg&#039;, &#039;poster&#039;: &#039;poster.jpg&#039; &#039;fanart&#039;: &#039;fanart.jpg&#039;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note|In Kodi Isengard and earlier the &#039;icon&#039; type is not available for setArt. You must use &amp;lt;code&amp;gt;ListItem.setIconImage(...)&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you&#039;d prefer to show the default fanart from your add-on, you can get the path to that image from the &amp;lt;code&amp;gt;[http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcaddon.html#Addon xbmcaddon.Addon]&amp;lt;/code&amp;gt; object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
my_addon = xbmcaddon.Addon(&#039;plugin.video.myaddon&#039;)&lt;br /&gt;
# ...&lt;br /&gt;
li.setArt({&#039;fanart&#039;: my_addon.getAddonInfo(&#039;fanart&#039;)})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Info labels ==&lt;br /&gt;
&lt;br /&gt;
Kodi also lets you add useful information about each list item, like the cast, episode number, play count, and duration. The specific fields available depend on whether your list item is video, audio, or a picture. In all cases though, the format is roughly the same. For example, to add info labels to a movie, you might do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
info = {&lt;br /&gt;
    &#039;genre&#039;: &#039;Horror&#039;,&lt;br /&gt;
    &#039;year&#039;: 1979,&lt;br /&gt;
    &#039;title&#039;: &#039;Alien&#039;,&lt;br /&gt;
}&lt;br /&gt;
li.setInfo(&#039;video&#039;, info)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a full list of the available info labels, consult the documentation for &amp;lt;code&amp;gt;[http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcgui.html#ListItem-setInfo ListItem.setInfo]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Stream info ==&lt;br /&gt;
&lt;br /&gt;
In addition to metadata about the file&#039;s contents, you can add information about the audio/video streams themselves. For a video, you might do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
video_info = {&lt;br /&gt;
    &#039;codec&#039;: &#039;h264&#039;,&lt;br /&gt;
    &#039;aspect&#039;: 1.78,&lt;br /&gt;
    &#039;width&#039;: 1280,&lt;br /&gt;
    &#039;height&#039;: 720,&lt;br /&gt;
}&lt;br /&gt;
li.addStreamInfo(&#039;video&#039;, video_info)&lt;br /&gt;
li.addStreamInfo(&#039;audio&#039;, {&#039;codec&#039;: &#039;dts&#039;, &#039;language&#039;: &#039;en&#039;, &#039;channels&#039;: 2})&lt;br /&gt;
li.addStreamInfo(&#039;subtitle&#039;, {&#039;language&#039;: &#039;en&#039;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For complete documentation about this function, see &amp;lt;code&amp;gt;[http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcgui.html#ListItem-addStreamInfo ListItem.addStreamInfo]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Adding context menus =&lt;br /&gt;
&lt;br /&gt;
In addition to the default action for a list item (e.g. playing the video), your add-on can provide additional actions for an item in the context menu. Note that this only applies to list items in &#039;&#039;your&#039;&#039; add-on. Currently, you&#039;re not able to modify the context menu for movies in the user&#039;s library. To add a context menu item, you need to give it a label and a [[List of built-in functions|built-in function]] as a string:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
li.addContextMenuItems([ (&#039;Refresh&#039;, &#039;Container.Refresh&#039;),&lt;br /&gt;
                         (&#039;Go up&#039;, &#039;Action(ParentDir)&#039;) ])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also elect to show &#039;&#039;only&#039;&#039; your context menu items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
li.addContextMenuItems([ (&#039;Refresh&#039;, &#039;Container.Refresh&#039;) ], replaceItems=True)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Add-on development|*]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=HOW-TO:Video_addon&amp;diff=113044</id>
		<title>HOW-TO:Video addon</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=HOW-TO:Video_addon&amp;diff=113044"/>
		<updated>2016-01-10T09:32:33Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: Video Tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav|[[Development]]|[[Add-on development]]|[[Python development]]|[[Python examples]]}}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Video Tutorial=&lt;br /&gt;
{{youtube|FtQgZ2bxFkk}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/FtQgZ2bxFkk Video&#039;s Description.]&lt;br /&gt;
&lt;br /&gt;
*This video will help you make a video add-on for Kodi. The video&#039;s steps might be different from the written tutorial below.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
This tutorial will explain how to write your first Kodi/XBMC video plugin Add-on&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Tools=&lt;br /&gt;
Assuming you have already followed the Hello World Add-on you will have a text editor already setup. Since we are dealing with videos this time its probably a good idea to have a video player setup. We recommend another great open source project for this&lt;br /&gt;
&lt;br /&gt;
- VLC http://www.videolan.org/vlc/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installing=&lt;br /&gt;
For this example we will use 2 nice basic video Add-on tutorials You can find the source-code here:&lt;br /&gt;
&lt;br /&gt;
https://github.com/romanvm/plugin.video.example&lt;br /&gt;
&lt;br /&gt;
You can either download as a zip and install both of these inside the kodi GUI from the install from zip feature. Or extract the zip into your userdata/add-ons folder.&lt;br /&gt;
&lt;br /&gt;
=Testing=&lt;br /&gt;
You can first give the add-on a test run by going to:&lt;br /&gt;
System &amp;gt;&amp;gt; Add-Ons &amp;gt;&amp;gt; Enabled Add-Ons &amp;gt;&amp;gt; Video Add-Ons &amp;gt;&amp;gt; Example Kodi video Plugin. You should now be able to watch some test videos hosted from an internet web server.&lt;br /&gt;
&lt;br /&gt;
[[File:Videotutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=Explanation=&lt;br /&gt;
So whats happening in this add-on?&lt;br /&gt;
&lt;br /&gt;
Basically the Add-on is checking a website for the hosted videos. In this example we are directly linking to the videos, but there are possibilities for dynamic content and scraping of just about any online source&lt;br /&gt;
&lt;br /&gt;
Once the video link is sent to Kodi, our video player takes over and buffers, then plays the video just like any other media.&lt;br /&gt;
&lt;br /&gt;
=Structure=&lt;br /&gt;
main.py &amp;lt;-- This is the actual python code for your Add-On&lt;br /&gt;
&lt;br /&gt;
addon.xml &amp;lt;-- This is the Add-Ons metadata&lt;br /&gt;
&lt;br /&gt;
icon.png &amp;lt;-- A PNG icon for the add-on. It can be 256x256 or 512x512 pixels big. Try to make it look nice!&lt;br /&gt;
&lt;br /&gt;
Readme.md &amp;lt;-- The readme text file with a description of the Add-on and install instructions. This shows on the front of the GitHub page and helps users to understand your Add-on before downloading.&lt;br /&gt;
&lt;br /&gt;
=The Code=&lt;br /&gt;
So now we come to the actual Add-On code, this is where most of your Add-on is written and is a simple text file containing python code.&lt;br /&gt;
&lt;br /&gt;
First we initialize the Add-on and import and bits we need&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
     import sys&lt;br /&gt;
     from urlparse import parse_qsl&lt;br /&gt;
     import xbmcgui&lt;br /&gt;
     import xbmcplugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we do something else...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
     # Get the plugin url in plugin:// notation.&lt;br /&gt;
     __url__ = sys.argv[0]&lt;br /&gt;
     # Get the plugin handle as an integer number.&lt;br /&gt;
     __handle__ = int(sys.argv[1])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we use a fixed set of properties simply for demonstrating purposes. In a &amp;quot;real life&amp;quot; plugin you will need to get info and links to video files/streams from some web-site or online service.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
VIDEOS = {&#039;Animals&#039;: [{&#039;name&#039;: &#039;Crab&#039;,&lt;br /&gt;
                       &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/crab.jpg&#039;,&lt;br /&gt;
                       &#039;video&#039;: &#039;http://www.vidsplay.com/vids/crab.mp4&#039;,&lt;br /&gt;
                       &#039;genre&#039;: &#039;Animals&#039;},&lt;br /&gt;
                      {&#039;name&#039;: &#039;Alligator&#039;,&lt;br /&gt;
                       &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/alligator.jpg&#039;,&lt;br /&gt;
                       &#039;video&#039;: &#039;http://www.vidsplay.com/vids/alligator.mp4&#039;,&lt;br /&gt;
                       &#039;genre&#039;: &#039;Animals&#039;},&lt;br /&gt;
                      {&#039;name&#039;: &#039;Turtle&#039;,&lt;br /&gt;
                       &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/turtle.jpg&#039;,&lt;br /&gt;
                       &#039;video&#039;: &#039;http://www.vidsplay.com/vids/turtle.mp4&#039;,&lt;br /&gt;
                       &#039;genre&#039;: &#039;Animals&#039;}&lt;br /&gt;
                      ],&lt;br /&gt;
            &#039;Cars&#039;: [{&#039;name&#039;: &#039;Postal Truck&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/us_postal.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/us_postal.mp4&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Cars&#039;},&lt;br /&gt;
                     {&#039;name&#039;: &#039;Traffic&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/traffic1.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/traffic1.avi&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Cars&#039;},&lt;br /&gt;
                     {&#039;name&#039;: &#039;Traffic Arrows&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/traffic_arrows.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/traffic_arrows.mp4&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Cars&#039;}&lt;br /&gt;
                     ],&lt;br /&gt;
            &#039;Food&#039;: [{&#039;name&#039;: &#039;Chicken&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/chicken.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/bbqchicken.mp4&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Food&#039;},&lt;br /&gt;
                     {&#039;name&#039;: &#039;Hamburger&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/hamburger.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/hamburger.mp4&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Food&#039;},&lt;br /&gt;
                     {&#039;name&#039;: &#039;Pizza&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/pizza.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/pizza.mp4&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Food&#039;}&lt;br /&gt;
                     ]}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now we define something else...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
def get_categories():&lt;br /&gt;
         &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
         Get the list of video categories.&lt;br /&gt;
         Here you can insert some parsing code that retrieves&lt;br /&gt;
         the list of video categories (e.g. &#039;Movies&#039;, &#039;TV-shows&#039;, &#039;Documentaries&#039; etc.)&lt;br /&gt;
         from some site or server.&lt;br /&gt;
         :return: list&lt;br /&gt;
         &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
         return VIDEOS.keys()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now we define something else...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
def get_videos(category):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Get the list of videofiles/streams.&lt;br /&gt;
    Here you can insert some parsing code that retrieves&lt;br /&gt;
    the list of videostreams in a given category from some site or server.&lt;br /&gt;
    :param category: str&lt;br /&gt;
    :return: list&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return VIDEOS[category]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now we define the list of categories&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
def list_categories():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Create the list of video categories in the Kodi interface.&lt;br /&gt;
    :return: None&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    # Get video categories&lt;br /&gt;
    categories = get_categories()&lt;br /&gt;
    # Create a list for our items.&lt;br /&gt;
    listing = []&lt;br /&gt;
    # Iterate through categories&lt;br /&gt;
    for category in categories:&lt;br /&gt;
        # Create a list item with a text label and a thumbnail image.&lt;br /&gt;
        list_item = xbmcgui.ListItem(label=category, thumbnailImage=VIDEOS[category][0][&#039;thumb&#039;])&lt;br /&gt;
        # Set a fanart image for the list item.&lt;br /&gt;
        # Here we use the same image as the thumbnail for simplicity&#039;s sake.&lt;br /&gt;
        list_item.setProperty(&#039;fanart_image&#039;, VIDEOS[category][0][&#039;thumb&#039;])&lt;br /&gt;
        # Set additional info for the list item.&lt;br /&gt;
        # Here we use a category name for both properties for for simplicity&#039;s sake.&lt;br /&gt;
        # setInfo allows to set various information for an item.&lt;br /&gt;
        # For available properties see the following link:&lt;br /&gt;
        # http://mirrors.xbmc.org/docs/python-docs/15.x-isengard/xbmcgui.html#ListItem-setInfo&lt;br /&gt;
        list_item.setInfo(&#039;video&#039;, {&#039;title&#039;: category, &#039;genre&#039;: category})&lt;br /&gt;
        # Create a URL for the plugin recursive callback.&lt;br /&gt;
        # Example: plugin://plugin.video.example/?action=listing&amp;amp;category=Animals&lt;br /&gt;
        url = &#039;{0}?action=listing&amp;amp;category={1}&#039;.format(__url__, category)&lt;br /&gt;
        # is_folder = True means that this item opens a sub-list of lower level items.&lt;br /&gt;
        is_folder = True&lt;br /&gt;
        # Add our item to the listing as a 3-element tuple.&lt;br /&gt;
        listing.append((url, list_item, is_folder))&lt;br /&gt;
    # Add our listing to Kodi.&lt;br /&gt;
    # Large lists and/or slower systems benefit from adding all items at once via addDirectoryItems&lt;br /&gt;
    # instead of adding one by ove via addDirectoryItem.&lt;br /&gt;
    xbmcplugin.addDirectoryItems(__handle__, listing, len(listing))&lt;br /&gt;
    # Add a sort method for the virtual folder items (alphabetically, ignore articles)&lt;br /&gt;
    xbmcplugin.addSortMethod(__handle__, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)&lt;br /&gt;
    # Finish creating a virtual folder.&lt;br /&gt;
    xbmcplugin.endOfDirectory(__handle__)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here we list the videos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
def list_videos(category):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Create the list of playable videos in the Kodi interface.&lt;br /&gt;
    :param category: str&lt;br /&gt;
    :return: None&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    # Get the list of videos in the category.&lt;br /&gt;
    videos = get_videos(category)&lt;br /&gt;
    # Create a list for our items.&lt;br /&gt;
    listing = []&lt;br /&gt;
    # Iterate through videos.&lt;br /&gt;
    for video in videos:&lt;br /&gt;
        # Create a list item with a text label and a thumbnail image.&lt;br /&gt;
        list_item = xbmcgui.ListItem(label=video[&#039;name&#039;], thumbnailImage=video[&#039;thumb&#039;])&lt;br /&gt;
        # Set a fanart image for the list item.&lt;br /&gt;
        # Here we use the same image as the thumbnail for simplicity&#039;s sake.&lt;br /&gt;
        list_item.setProperty(&#039;fanart_image&#039;, video[&#039;thumb&#039;])&lt;br /&gt;
        # Set additional info for the list item.&lt;br /&gt;
        list_item.setInfo(&#039;video&#039;, {&#039;title&#039;: video[&#039;name&#039;], &#039;genre&#039;: video[&#039;genre&#039;]})&lt;br /&gt;
        # Set &#039;IsPlayable&#039; property to &#039;true&#039;.&lt;br /&gt;
        # This is mandatory for playable items!&lt;br /&gt;
        list_item.setProperty(&#039;IsPlayable&#039;, &#039;true&#039;)&lt;br /&gt;
        # Create a URL for the plugin recursive callback.&lt;br /&gt;
        # Example: plugin://plugin.video.example/?action=play&amp;amp;video=http://www.vidsplay.com/vids/crab.mp4&lt;br /&gt;
        url = &#039;{0}?action=play&amp;amp;video={1}&#039;.format(__url__, video[&#039;video&#039;])&lt;br /&gt;
        # Add the list item to a virtual Kodi folder.&lt;br /&gt;
        # is_folder = False means that this item won&#039;t open any sub-list.&lt;br /&gt;
        is_folder = False&lt;br /&gt;
        # Add our item to the listing as a 3-element tuple.&lt;br /&gt;
        listing.append((url, list_item, is_folder))&lt;br /&gt;
    # Add our listing to Kodi.&lt;br /&gt;
    # Large lists and/or slower systems benefit from adding all items at once via addDirectoryItems&lt;br /&gt;
    # instead of adding one by ove via addDirectoryItem.&lt;br /&gt;
    xbmcplugin.addDirectoryItems(__handle__, listing, len(listing))&lt;br /&gt;
    # Add a sort method for the virtual folder items (alphabetically, ignore articles)&lt;br /&gt;
    xbmcplugin.addSortMethod(__handle__, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)&lt;br /&gt;
    # Finish creating a virtual folder.&lt;br /&gt;
    xbmcplugin.endOfDirectory(__handle__)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we tell Kodi how to find the video path to play the videos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
def play_video(path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Play a video by the provided path.&lt;br /&gt;
    :param path: str&lt;br /&gt;
    :return: None&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    # Create a playable item with a path to play.&lt;br /&gt;
    play_item = xbmcgui.ListItem(path=path)&lt;br /&gt;
    # Pass the item to the Kodi player.&lt;br /&gt;
    xbmcplugin.setResolvedUrl(__handle__, True, listitem=play_item)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is the router function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
def router(paramstring):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Router function that calls other functions&lt;br /&gt;
    depending on the provided paramstring&lt;br /&gt;
    :param paramstring:&lt;br /&gt;
    :return:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    # Parse a URL-encoded paramstring to the dictionary of&lt;br /&gt;
    # {&amp;lt;parameter&amp;gt;: &amp;lt;value&amp;gt;} elements&lt;br /&gt;
    params = dict(parse_qsl(paramstring[1:]))&lt;br /&gt;
    # Check the parameters passed to the plugin&lt;br /&gt;
    if params:&lt;br /&gt;
        if params[&#039;action&#039;] == &#039;listing&#039;:&lt;br /&gt;
            # Display the list of videos in a provided category.&lt;br /&gt;
            list_videos(params[&#039;category&#039;])&lt;br /&gt;
        elif params[&#039;action&#039;] == &#039;play&#039;:&lt;br /&gt;
            # Play a video from a provided URL.&lt;br /&gt;
            play_video(params[&#039;video&#039;])&lt;br /&gt;
    else:&lt;br /&gt;
        # If the plugin is called from Kodi UI without any parameters,&lt;br /&gt;
        # display the list of video categories&lt;br /&gt;
        list_categories()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call the router function&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    # Call the router function and pass the plugin call parameters to it.&lt;br /&gt;
    router(sys.argv[2])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Changing the code=&lt;br /&gt;
&lt;br /&gt;
Hopefully by now you have managed to run the Add-On, understand the structure and can see what the code can do. Now lets trying changing it a little!&lt;br /&gt;
&lt;br /&gt;
Since we already have the Add-on installed we can go directly to the Kodi userdata folder and edit the python directly. You can also have Kodi open at this time ready to run the Add-on when required. Just switch between your text editor and Kodi any time.&lt;br /&gt;
&lt;br /&gt;
Now open up the main.py file from your userdata folder and lets change what the text says.&lt;br /&gt;
&lt;br /&gt;
                 &#039;Cars&#039;: [{&#039;name&#039;: &#039;Postal Truck&#039;,&lt;br /&gt;
                      &#039;thumb&#039;: &#039;http://www.vidsplay.com/vids/us_postal.jpg&#039;,&lt;br /&gt;
                      &#039;video&#039;: &#039;http://www.vidsplay.com/vids/us_postal.mp4&#039;,&lt;br /&gt;
                      &#039;genre&#039;: &#039;Cars&#039;},&lt;br /&gt;
&lt;br /&gt;
Try changing some of the links to another jpeg file or hosted online video. Also try to change the genre and see how that effects the view in Kodi.&lt;br /&gt;
&lt;br /&gt;
Click save on your text editor and now try running the Add-On inside Kodi. You should see the new video links and navigation right away.&lt;br /&gt;
&lt;br /&gt;
Congratulations! you&#039;ve just played an online video from your very own Video Add-on&lt;br /&gt;
&lt;br /&gt;
=Final Thoughts=&lt;br /&gt;
&lt;br /&gt;
Writing a Video Add-on is actually pretty simple once you get the basic structure correct. You can scrape most online sources with Regex, or host your own videos on the web. You can also play youtube clips or vevo videos using some additional easy to use modules.&lt;br /&gt;
&lt;br /&gt;
If you have any questions about this tutorial, feel free to discuss it on our forums here: http://forum.kodi.tv/showthread.php?tid=248774&lt;br /&gt;
&lt;br /&gt;
=Extra info=&lt;br /&gt;
&lt;br /&gt;
Just a reminder...&lt;br /&gt;
IMPORTANT!!!!!!!   Do not mix tabs and spaces in python&lt;br /&gt;
&lt;br /&gt;
[[Category:Add-on development]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=HOW-TO:Create_a_RSS_Feed&amp;diff=111291</id>
		<title>HOW-TO:Create a RSS Feed</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=HOW-TO:Create_a_RSS_Feed&amp;diff=111291"/>
		<updated>2016-01-03T06:36:42Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav| [[RSSFeeds.xml]] }}&lt;br /&gt;
&amp;lt;section begin=&amp;quot;intro&amp;quot; /&amp;gt;This is a HOW-TO on creating your own RSS Feed that you can use on Kodi.&amp;lt;section end=&amp;quot;intro&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This tutorial might work with Kodi only. Some RSS Feed readers might not recognize the RSS we will make.&lt;br /&gt;
&lt;br /&gt;
Please keep in mind that this is a simple and easy way of doing it. I know it might not be the right way but it works.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Video Tutorial&#039;&#039;&#039; ==&lt;br /&gt;
{{youtube|lE1hDN_xKPc}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/lE1hDN_xKPc Video&#039;s Description.]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Creating the XML file&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
The only type of RSS Feed that Kodi reads are .xml files&lt;br /&gt;
&lt;br /&gt;
Start by creating a normal text file and rename it to &#039;&#039;&#039;RSSFeed.xml&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Your first three lines should look like this: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;rss version=&amp;quot;2.0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;channel&amp;gt;&lt;br /&gt;
  &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Between &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt; you&#039;re suppose to add your RSS Feed&#039;s name. Which will be in blue in Kodi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After that you can start adding &amp;quot;items&amp;quot; which is basically what will be shown when the text starts moving.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Again between &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt; you should put in the text that you want to be shown.&lt;br /&gt;
&lt;br /&gt;
Your XML file &#039;&#039;&#039;HAS&#039;&#039;&#039; to contain three or more &amp;quot;items&amp;quot;. If not Kodi will not read your RSS Feed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the code by closing it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/channel&amp;gt;&lt;br /&gt;
&amp;lt;/rss&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Example&#039;&#039;&#039; ==&lt;br /&gt;
Below is an example of what your XML file should look like.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;rss version=&amp;quot;2.0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;channel&amp;gt;&lt;br /&gt;
  &amp;lt;title&amp;gt;My RSS Feed&amp;lt;/title&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Hello everyone!&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Updates are coming soon. Stay tuned!&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Enjoy your day.&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 &amp;lt;/channel&amp;gt;&lt;br /&gt;
&amp;lt;/rss&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You can have many more &amp;quot;items&amp;quot; but make sure to have at lease three of them.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Uploading your file&#039;&#039;&#039; ==&lt;br /&gt;
The final step is to upload your .xml file to a webhost. It can be any host but make sure your file&#039;s name has the extention .xml at the end of it&#039;s name.&lt;br /&gt;
&lt;br /&gt;
Copy the link of you file and insert it into Kodi.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;See also&#039;&#039;&#039; ==&lt;br /&gt;
* [[RSSFeeds.xml]]&lt;br /&gt;
* [[RSS ticker]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Isengard updated}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[User:SimpleKodi|SimpleKodi]] ([[User talk:SimpleKodi|talk]])&#039;&#039;&#039;&lt;br /&gt;
[[Category:Settings]]&lt;br /&gt;
[[Category:Manual]]&lt;br /&gt;
[[Category:How-to]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=HOW-TO:Create_a_RSS_Feed&amp;diff=111290</id>
		<title>HOW-TO:Create a RSS Feed</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=HOW-TO:Create_a_RSS_Feed&amp;diff=111290"/>
		<updated>2016-01-03T06:34:57Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: How to create a RSS Feed for kodi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav| [[RSSFeeds.xml]] }}&lt;br /&gt;
&amp;lt;section begin=&amp;quot;intro&amp;quot; /&amp;gt;This is a HOW-TO on creating your own RSS Feed that you can use on Kodi.&amp;lt;section end=&amp;quot;intro&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This tutorial might work with Kodi only. Some RSS Feed readers might not recognize the RSS we will make.&lt;br /&gt;
&lt;br /&gt;
Please keep in mind that this is a simple and easy way of doing it. I know it might not be the right way but it works.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Video Tutorial&#039;&#039;&#039; ==&lt;br /&gt;
{{youtube|lE1hDN_xKPc}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/lE1hDN_xKPc Video&#039;s Description.]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Creating the XML file&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
The only type of RSS Feed that Kodi reads are .xml files&lt;br /&gt;
&lt;br /&gt;
Start by creating a normal text file and rename it to &#039;&#039;&#039;RSSFeed.xml&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Your first three lines should look like this: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;rss version=&amp;quot;2.0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;channel&amp;gt;&lt;br /&gt;
  &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Between &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt; you&#039;re suppose to add your RSS Feed&#039;s name. Which will be in blue in Kodi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After that you can start adding &amp;quot;items&amp;quot; which is basically what will be shown when the text starts moving.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
Again between &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt; you should put in the text that you want to be shown.&lt;br /&gt;
&lt;br /&gt;
Your XML file &#039;&#039;&#039;HAS&#039;&#039;&#039; to contain three or more &amp;quot;items&amp;quot;. If not Kodi will not read your RSS Feed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finish the code by closing it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/channel&amp;gt;&lt;br /&gt;
&amp;lt;/rss&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Example&#039;&#039;&#039; ==&lt;br /&gt;
Below is an example of what your XML file should look like.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;rss version=&amp;quot;2.0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;channel&amp;gt;&lt;br /&gt;
  &amp;lt;title&amp;gt;My RSS Feed&amp;lt;/title&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Hello everyone!&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Updates are coming soon. Stay tuned!&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;item&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Enjoy your day.&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/item&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 &amp;lt;/channel&amp;gt;&lt;br /&gt;
&amp;lt;/rss&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You can have many more &amp;quot;items&amp;quot; but make sure to have at lease three of them.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Uploading your file&#039;&#039;&#039; ==&lt;br /&gt;
The final step is to upload your .xml file to a webhost. It can be any host but make sure your file&#039;s name has the extention .xml at the end of it&#039;s name.&lt;br /&gt;
&lt;br /&gt;
Copy the link of you file and insert it into Kodi.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;See also&#039;&#039;&#039; ==&lt;br /&gt;
* [[RSSFeeds.xml]]&lt;br /&gt;
* [[RSS ticker]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Isengard updated}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[User:SimpleKodi|SimpleKodi]] ([[User talk:SimpleKodi|talk]])&#039;&#039;&#039;&lt;br /&gt;
[[Category:Settings]]&lt;br /&gt;
[[Category:Manual]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=109719</id>
		<title>Archive:Create a repository for add-ons</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=109719"/>
		<updated>2015-12-21T06:03:41Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav|[[Development]]|[[Add-on development]]|[[Add-on repositories]]}}&lt;br /&gt;
&lt;br /&gt;
When you have created your repository, feel free to add it to the [[3rd party add-on repositories]] list.&lt;br /&gt;
&lt;br /&gt;
==Video Tutorial==&lt;br /&gt;
{{youtube|zm1pvAt5uvU}}&lt;br /&gt;
&lt;br /&gt;
[https://www.youtube.com/watch?v=zm1pvAt5uvU Video&#039;s Description.]&lt;br /&gt;
*This video will help you create a Repository for Kodi. The video&#039;s steps are different from the written tutorial.&lt;br /&gt;
* Helper Python script [https://github.com/virajkanwade/kodi-create-repo https://github.com/virajkanwade/kodi-create-repo]&lt;br /&gt;
&lt;br /&gt;
== Things you will require ==&lt;br /&gt;
* Any HTTP server. A popular method is to use the svn or git source code servers of googlecode, gitorious and github.&lt;br /&gt;
  - In your code project page, make sure you set up the correct version control system (source tab). Most skins use SVN.&lt;br /&gt;
  - This will get you the right checkout address (link) and folder structure.&lt;br /&gt;
* A folder containing one or more add-on.&lt;br /&gt;
  - Start by installing an svn program (like Tortoisesvn).&lt;br /&gt;
  - Right click the empty folder, choose &#039;SVN Checkout&#039; to let it build a folder structure inside.&lt;br /&gt;
  - Make sure you get asked for authentication (!), the folders look like your source code server.&lt;br /&gt;
  - If you don&#039;t get asked for authentication check your server settings and http vs https links.&lt;br /&gt;
  - Make a test.txt file in the trunk, right click to mark it as &#039;add&#039; and use and use &#039;SVN Commit&#039; on top folder.&lt;br /&gt;
* Make the following two files using the python code below. These 2 files are made from the addon.xml files in the folders below (from the addons). Where you can have your addon unzipped (or zipped as long as there is an addon.xml file next to it, that is always up to date with the one in the zip).&lt;br /&gt;
  - A master addon&#039;&#039;&#039;s&#039;&#039;&#039;.xml file. This file contains metadata about all available add-ons.&lt;br /&gt;
  - A checksum of the above file (this file only contains a hash of addons.xml).&lt;br /&gt;
* A zipped repository add-on for distribution. This allows you to share your repository with others.&lt;br /&gt;
  - Easiest way is to have a look at another repository file and change the name, info and links.&lt;br /&gt;
  - You can also have a look at how other repos set up their folder structure.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;[https://raw.github.com/garbear/unqlocked/master/addons_xml_generator.py] to generate the master xml and the MD5. Put it in the folder with all your add-ons (it needs to see addon.xml files in a folder below) and run it from your Python interpreter. If using a source code server, you can now upload your add-on folder via svn or git to your repository. Every time you update an add-on run the addons_xml_generator.py before uploading the add-ons folder.&lt;br /&gt;
&lt;br /&gt;
* For Windows users. Install the latest version of Python.msi (from their website) in it&#039;s default directory. Python (.py) files should now be associated with python.exe and can be run like a program.&lt;br /&gt;
* Make a new text file and name it &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;. Open it with Notepad++ (or equivalent) and paste the following code inside.&lt;br /&gt;
&lt;br /&gt;
addons_xml_generator.py&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# *&lt;br /&gt;
# *  Copyright (C) 2012-2013 Garrett Brown&lt;br /&gt;
# *  Copyright (C) 2010      j48antialias&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is free software; you can redistribute it and/or modify&lt;br /&gt;
# *  it under the terms of the GNU General Public License as published by&lt;br /&gt;
# *  the Free Software Foundation; either version 2, or (at your option)&lt;br /&gt;
# *  any later version.&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is distributed in the hope that it will be useful,&lt;br /&gt;
# *  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;br /&gt;
# *  GNU General Public License for more details.&lt;br /&gt;
# *&lt;br /&gt;
# *  You should have received a copy of the GNU General Public License&lt;br /&gt;
# *  along with XBMC; see the file COPYING.  If not, write to&lt;br /&gt;
# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.&lt;br /&gt;
# *  http://www.gnu.org/copyleft/gpl.html&lt;br /&gt;
# *&lt;br /&gt;
# *  Based on code by j48antialias:&lt;br /&gt;
# *  https://anarchintosh-projects.googlecode.com/files/addons_xml_generator.py&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; addons.xml generator &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Compatibility with 3.0, 3.1 and 3.2 not supporting u&amp;quot;&amp;quot; literals&lt;br /&gt;
if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
    import codecs&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return codecs.unicode_escape_decode(x)[0]&lt;br /&gt;
else:&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return x&lt;br /&gt;
&lt;br /&gt;
class Generator:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Generates a new addons.xml file from each addons addon.xml file&lt;br /&gt;
        and a new addons.xml.md5 hash file. Must be run from the root of&lt;br /&gt;
        the checked-out repo. Only handles single depth folder structure.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __init__( self ):&lt;br /&gt;
        # generate files&lt;br /&gt;
        self._generate_addons_file()&lt;br /&gt;
        self._generate_md5_file()&lt;br /&gt;
        # notify user&lt;br /&gt;
        print(&amp;quot;Finished updating addons xml and md5 files&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    def _generate_addons_file( self ):&lt;br /&gt;
        # addon list&lt;br /&gt;
        addons = os.listdir( &amp;quot;.&amp;quot; )&lt;br /&gt;
        # final addons text&lt;br /&gt;
        addons_xml = u(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot; encoding=\&amp;quot;UTF-8\&amp;quot; standalone=\&amp;quot;yes\&amp;quot;?&amp;gt;\n&amp;lt;addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # loop thru and add each addons addon.xml file&lt;br /&gt;
        for addon in addons:&lt;br /&gt;
            try:&lt;br /&gt;
                # skip any file or .svn folder or .git folder&lt;br /&gt;
                if ( not os.path.isdir( addon ) or addon == &amp;quot;.svn&amp;quot; or addon == &amp;quot;.git&amp;quot; ): continue&lt;br /&gt;
                # create path&lt;br /&gt;
                _path = os.path.join( addon, &amp;quot;addon.xml&amp;quot; )&lt;br /&gt;
                # split lines for stripping&lt;br /&gt;
                xml_lines = open( _path, &amp;quot;r&amp;quot; , encoding=&amp;quot;UTF-8&amp;quot;).read().splitlines()&lt;br /&gt;
                # new addon&lt;br /&gt;
                addon_xml = &amp;quot;&amp;quot;&lt;br /&gt;
                # loop thru cleaning each line&lt;br /&gt;
                for line in xml_lines:&lt;br /&gt;
                    # skip encoding format line&lt;br /&gt;
                    if ( line.find( &amp;quot;&amp;lt;?xml&amp;quot; ) &amp;gt;= 0 ): continue&lt;br /&gt;
                    # add line&lt;br /&gt;
                    if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
                        addon_xml += unicode( line.rstrip() + &amp;quot;\n&amp;quot;, &amp;quot;UTF-8&amp;quot; )&lt;br /&gt;
                    else:&lt;br /&gt;
                        addon_xml += line.rstrip() + &amp;quot;\n&amp;quot;&lt;br /&gt;
                # we succeeded so add to our final addons.xml text&lt;br /&gt;
                addons_xml += addon_xml.rstrip() + &amp;quot;\n\n&amp;quot;&lt;br /&gt;
            except Exception as e:&lt;br /&gt;
                # missing or poorly formatted addon.xml&lt;br /&gt;
                print(&amp;quot;Excluding %s for %s&amp;quot; % ( _path, e ))&lt;br /&gt;
        # clean and add closing tag&lt;br /&gt;
        addons_xml = addons_xml.strip() + u(&amp;quot;\n&amp;lt;/addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # save file&lt;br /&gt;
        self._save_file( addons_xml.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml&amp;quot; )&lt;br /&gt;
    &lt;br /&gt;
    def _generate_md5_file( self ):&lt;br /&gt;
        # create a new md5 hash&lt;br /&gt;
        try:&lt;br /&gt;
            import md5&lt;br /&gt;
            m = md5.new( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot; ).read() ).hexdigest()&lt;br /&gt;
        except ImportError:&lt;br /&gt;
            import hashlib&lt;br /&gt;
            m = hashlib.md5( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot;, encoding=&amp;quot;UTF-8&amp;quot; ).read().encode( &amp;quot;UTF-8&amp;quot; ) ).hexdigest()&lt;br /&gt;
        &lt;br /&gt;
        # save file&lt;br /&gt;
        try:&lt;br /&gt;
            self._save_file( m.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml.md5&amp;quot; )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred creating addons.xml.md5 file!\n%s&amp;quot; % e)&lt;br /&gt;
    &lt;br /&gt;
    def _save_file( self, data, file ):&lt;br /&gt;
        try:&lt;br /&gt;
            # write data to the file (use b for Python 3)&lt;br /&gt;
            open( file, &amp;quot;wb&amp;quot; ).write( data )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred saving %s file!\n%s&amp;quot; % ( file, e ))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if ( __name__ == &amp;quot;__main__&amp;quot; ):&lt;br /&gt;
    # start&lt;br /&gt;
    Generator()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Repository Files ==&lt;br /&gt;
Repositories are distributed just like any other add-on. In order for you to browse one in XBMC, you&#039;ll need to [[Add-ons_for_XBMC_(Developement)|create an add-on]] and install it. The repository addon extends the xbmc.addon.repository extension point, so in addition to the general XML structure and icons required for an icon, you&#039;ll need an &amp;lt;extension&amp;gt; block specfically pointing to your repository.&lt;br /&gt;
Use the addon.xml of any of the [[3rd party add-on repositories]] as a template.&lt;br /&gt;
Online repositories should always have zip set to true, both for efficiency of download and for the protection that .zip offers by way of verifying the download (i.e. can we unzip it).&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
=== Using your repo to host images ===&lt;br /&gt;
You may as a developer need to host images from time to time.&lt;br /&gt;
Something like photobucket or flickr may work, but you can also use your repo.&lt;br /&gt;
Commit an image to it, and then form the url to it as you would if you were accessing the image via git or svn (like below):&lt;br /&gt;
&lt;br /&gt;
http://xbmc-adult.googlecode.com/svn/trunk/repository.xbmc-adult/icon.png&lt;br /&gt;
&lt;br /&gt;
This can then be accessed easily from python code, or even embedded on the XBMC forums.&lt;br /&gt;
&lt;br /&gt;
=== How to make an add-on self-updating without distributing a repository file ===&lt;br /&gt;
This is optional.&lt;br /&gt;
You still need a repository for this, you just distribute the actual zipped plugin or script, as opposed to the repository file.&lt;br /&gt;
First you need to have a working repository file.&lt;br /&gt;
Copy the equivalent of this code from the addon.xml of your repository file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;extension point=&amp;quot;xbmc.addon.repository&amp;quot;&lt;br /&gt;
              name=&amp;quot;Official XBMC.org Add-on Repository&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;info compressed=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml&amp;lt;/info&amp;gt;&lt;br /&gt;
    &amp;lt;checksum&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml.md5&amp;lt;/checksum&amp;gt;&lt;br /&gt;
    &amp;lt;datadir zip=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre&amp;lt;/datadir&amp;gt;&lt;br /&gt;
  &amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Then simply add it under the other &amp;lt;extension point&amp;gt; entries of your add-on&#039;s addon.xml&lt;br /&gt;
The name= part of this repository extension must never be the same as your add-on.&lt;br /&gt;
&lt;br /&gt;
==More Video Tutorials==&lt;br /&gt;
===Update Your Repository===&lt;br /&gt;
{{youtube|tXzPUs9FaF8}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/tXzPUs9FaF8 Video&#039;s Description.]&lt;br /&gt;
&lt;br /&gt;
===Add more Add-ons to your Repository===&lt;br /&gt;
{{youtube|2OPjwdbBSkw}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/2OPjwdbBSkw Video&#039;s Description.]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[3rd party add-on repositories]]&lt;br /&gt;
&#039;&#039;&#039;Development:&#039;&#039;&#039;&lt;br /&gt;
* [[Add-on development]]&lt;br /&gt;
* [[Add-on repositories]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Add-on development]]&lt;br /&gt;
[[Category:Skin development]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=Add-on:YouTube&amp;diff=107912</id>
		<title>Add-on:YouTube</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=Add-on:YouTube&amp;diff=107912"/>
		<updated>2015-12-13T21:26:27Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Addon &lt;br /&gt;
|Name=YouTube&lt;br /&gt;
|provider-name=bromix&lt;br /&gt;
|ID=plugin.video.youtube&lt;br /&gt;
|latest-version=5.1.12&lt;br /&gt;
|extension point=xbmc.python.pluginsource&lt;br /&gt;
|provides=video&lt;br /&gt;
|Summary=Plugin for YouTube&lt;br /&gt;
|Description=YouTube is a one of the biggest video-sharing websites of the world.&lt;br /&gt;
|Platform=all&lt;br /&gt;
|Language=&lt;br /&gt;
|License=GNU GENERAL PUBLIC LICENSE. Version 2, June 1991&lt;br /&gt;
|Forum=http://forum.kodi.tv/showthread.php?tid=200735&lt;br /&gt;
|Website=http://www.youtube.com&lt;br /&gt;
|Source=https://github.com/bromix/plugin.video.youtube&lt;br /&gt;
|Email=bromix at gmx dot net&lt;br /&gt;
|broken=&lt;br /&gt;
|icon url=http://mirrors.kodi.tv/addons/jarvis/plugin.video.youtube/icon.png}}&lt;br /&gt;
&lt;br /&gt;
==Video Tutorial==&lt;br /&gt;
{{youtube|-ARBt2G7XWo}}&lt;br /&gt;
&lt;br /&gt;
[https://youtu.be/-ARBt2G7XWo Video&#039;s Description.]&lt;br /&gt;
*This video will show you how to install the YouTube add-on on Kodi.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
=== Integration with strm files ===&lt;br /&gt;
Youtube streams can be integrated into the video library with [[Strm|strm files]]. &lt;br /&gt;
&lt;br /&gt;
The syntax for a youtube-URL like &amp;lt;nowiki&amp;gt;https://www.youtube.com/watch?v=$VIDEOID&amp;lt;/nowiki&amp;gt; or &amp;lt;nowiki&amp;gt;https://www.youtube.com/playlist?list=$PLAYLISTID&amp;lt;/nowiki&amp;gt; in a strm file is&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;plugin://plugin.video.youtube/?path=/root/video&amp;amp;action=play_video&amp;amp;videoid=$VIDEOID&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;plugin://plugin.video.youtube/?path=/root/video&amp;amp;action=play_all&amp;amp;playlist=$PLAYLISTID&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
=== Similar page names ===&lt;br /&gt;
{{#lst:YouTube|similar pages}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Social media]]&lt;br /&gt;
[[Category:Helix add-on repository]]&lt;br /&gt;
[[Category:Jarvis add-on repository]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=107901</id>
		<title>Archive:Create a repository for add-ons</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=107901"/>
		<updated>2015-12-13T03:02:22Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav|[[Development]]|[[Add-on development]]|[[Add-on repositories]]}}&lt;br /&gt;
&lt;br /&gt;
When you have created your repository, feel free to add it to the [[3rd party add-on repositories]] list.&lt;br /&gt;
&lt;br /&gt;
==Video Tutorial==&lt;br /&gt;
{{youtube|zm1pvAt5uvU}}&lt;br /&gt;
&lt;br /&gt;
[https://www.youtube.com/watch?v=zm1pvAt5uvU Video&#039;s Description.]&lt;br /&gt;
*This video will help you create a Repository for Kodi. The video&#039;s steps are different from the written tutorial.&lt;br /&gt;
&lt;br /&gt;
== Things you will require ==&lt;br /&gt;
* Any HTTP server. A popular method is to use the svn or git source code servers of googlecode, gitorious and github.&lt;br /&gt;
  - In your code project page, make sure you set up the correct version control system (source tab). Most skins use SVN.&lt;br /&gt;
  - This will get you the right checkout address (link) and folder structure.&lt;br /&gt;
* A folder containing one or more add-on.&lt;br /&gt;
  - Start by installing an svn program (like Tortoisesvn).&lt;br /&gt;
  - Right click the empty folder, choose &#039;SVN Checkout&#039; to let it build a folder structure inside.&lt;br /&gt;
  - Make sure you get asked for authentication (!), the folders look like your source code server.&lt;br /&gt;
  - If you don&#039;t get asked for authentication check your server settings and http vs https links.&lt;br /&gt;
  - Make a test.txt file in the trunk, right click to mark it as &#039;add&#039; and use and use &#039;SVN Commit&#039; on top folder.&lt;br /&gt;
* Make the following two files using the python code below. These 2 files are made from the addon.xml files in the folders below (from the addons). Where you can have your addon unzipped (or zipped as long as there is an addon.xml file next to it, that is always up to date with the one in the zip).&lt;br /&gt;
  - A master addon&#039;&#039;&#039;s&#039;&#039;&#039;.xml file. This file contains metadata about all available add-ons.&lt;br /&gt;
  - A checksum of the above file (this file only contains a hash of addons.xml).&lt;br /&gt;
* A zipped repository add-on for distribution. This allows you to share your repository with others.&lt;br /&gt;
  - Easiest way is to have a look at another repository file and change the name, info and links.&lt;br /&gt;
  - You can also have a look at how other repos set up their folder structure.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;[https://raw.github.com/garbear/unqlocked/master/addons_xml_generator.py] to generate the master xml and the MD5. Put it in the folder with all your add-ons (it needs to see addon.xml files in a folder below) and run it from your Python interpreter. If using a source code server, you can now upload your add-on folder via svn or git to your repository. Every time you update an add-on run the addons_xml_generator.py before uploading the add-ons folder.&lt;br /&gt;
&lt;br /&gt;
* For Windows users. Install the latest version of Python.msi (from their website) in it&#039;s default directory. Python (.py) files should now be associated with python.exe and can be run like a program.&lt;br /&gt;
* Make a new text file and name it &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;. Open it with Notepad++ (or equivalent) and paste the following code inside.&lt;br /&gt;
&lt;br /&gt;
addons_xml_generator.py&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# *&lt;br /&gt;
# *  Copyright (C) 2012-2013 Garrett Brown&lt;br /&gt;
# *  Copyright (C) 2010      j48antialias&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is free software; you can redistribute it and/or modify&lt;br /&gt;
# *  it under the terms of the GNU General Public License as published by&lt;br /&gt;
# *  the Free Software Foundation; either version 2, or (at your option)&lt;br /&gt;
# *  any later version.&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is distributed in the hope that it will be useful,&lt;br /&gt;
# *  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;br /&gt;
# *  GNU General Public License for more details.&lt;br /&gt;
# *&lt;br /&gt;
# *  You should have received a copy of the GNU General Public License&lt;br /&gt;
# *  along with XBMC; see the file COPYING.  If not, write to&lt;br /&gt;
# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.&lt;br /&gt;
# *  http://www.gnu.org/copyleft/gpl.html&lt;br /&gt;
# *&lt;br /&gt;
# *  Based on code by j48antialias:&lt;br /&gt;
# *  https://anarchintosh-projects.googlecode.com/files/addons_xml_generator.py&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; addons.xml generator &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Compatibility with 3.0, 3.1 and 3.2 not supporting u&amp;quot;&amp;quot; literals&lt;br /&gt;
if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
    import codecs&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return codecs.unicode_escape_decode(x)[0]&lt;br /&gt;
else:&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return x&lt;br /&gt;
&lt;br /&gt;
class Generator:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Generates a new addons.xml file from each addons addon.xml file&lt;br /&gt;
        and a new addons.xml.md5 hash file. Must be run from the root of&lt;br /&gt;
        the checked-out repo. Only handles single depth folder structure.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __init__( self ):&lt;br /&gt;
        # generate files&lt;br /&gt;
        self._generate_addons_file()&lt;br /&gt;
        self._generate_md5_file()&lt;br /&gt;
        # notify user&lt;br /&gt;
        print(&amp;quot;Finished updating addons xml and md5 files&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    def _generate_addons_file( self ):&lt;br /&gt;
        # addon list&lt;br /&gt;
        addons = os.listdir( &amp;quot;.&amp;quot; )&lt;br /&gt;
        # final addons text&lt;br /&gt;
        addons_xml = u(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot; encoding=\&amp;quot;UTF-8\&amp;quot; standalone=\&amp;quot;yes\&amp;quot;?&amp;gt;\n&amp;lt;addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # loop thru and add each addons addon.xml file&lt;br /&gt;
        for addon in addons:&lt;br /&gt;
            try:&lt;br /&gt;
                # skip any file or .svn folder or .git folder&lt;br /&gt;
                if ( not os.path.isdir( addon ) or addon == &amp;quot;.svn&amp;quot; or addon == &amp;quot;.git&amp;quot; ): continue&lt;br /&gt;
                # create path&lt;br /&gt;
                _path = os.path.join( addon, &amp;quot;addon.xml&amp;quot; )&lt;br /&gt;
                # split lines for stripping&lt;br /&gt;
                xml_lines = open( _path, &amp;quot;r&amp;quot; , encoding=&amp;quot;UTF-8&amp;quot;).read().splitlines()&lt;br /&gt;
                # new addon&lt;br /&gt;
                addon_xml = &amp;quot;&amp;quot;&lt;br /&gt;
                # loop thru cleaning each line&lt;br /&gt;
                for line in xml_lines:&lt;br /&gt;
                    # skip encoding format line&lt;br /&gt;
                    if ( line.find( &amp;quot;&amp;lt;?xml&amp;quot; ) &amp;gt;= 0 ): continue&lt;br /&gt;
                    # add line&lt;br /&gt;
                    if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
                        addon_xml += unicode( line.rstrip() + &amp;quot;\n&amp;quot;, &amp;quot;UTF-8&amp;quot; )&lt;br /&gt;
                    else:&lt;br /&gt;
                        addon_xml += line.rstrip() + &amp;quot;\n&amp;quot;&lt;br /&gt;
                # we succeeded so add to our final addons.xml text&lt;br /&gt;
                addons_xml += addon_xml.rstrip() + &amp;quot;\n\n&amp;quot;&lt;br /&gt;
            except Exception as e:&lt;br /&gt;
                # missing or poorly formatted addon.xml&lt;br /&gt;
                print(&amp;quot;Excluding %s for %s&amp;quot; % ( _path, e ))&lt;br /&gt;
        # clean and add closing tag&lt;br /&gt;
        addons_xml = addons_xml.strip() + u(&amp;quot;\n&amp;lt;/addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # save file&lt;br /&gt;
        self._save_file( addons_xml.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml&amp;quot; )&lt;br /&gt;
    &lt;br /&gt;
    def _generate_md5_file( self ):&lt;br /&gt;
        # create a new md5 hash&lt;br /&gt;
        try:&lt;br /&gt;
            import md5&lt;br /&gt;
            m = md5.new( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot; ).read() ).hexdigest()&lt;br /&gt;
        except ImportError:&lt;br /&gt;
            import hashlib&lt;br /&gt;
            m = hashlib.md5( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot;, encoding=&amp;quot;UTF-8&amp;quot; ).read().encode( &amp;quot;UTF-8&amp;quot; ) ).hexdigest()&lt;br /&gt;
        &lt;br /&gt;
        # save file&lt;br /&gt;
        try:&lt;br /&gt;
            self._save_file( m.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml.md5&amp;quot; )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred creating addons.xml.md5 file!\n%s&amp;quot; % e)&lt;br /&gt;
    &lt;br /&gt;
    def _save_file( self, data, file ):&lt;br /&gt;
        try:&lt;br /&gt;
            # write data to the file (use b for Python 3)&lt;br /&gt;
            open( file, &amp;quot;wb&amp;quot; ).write( data )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred saving %s file!\n%s&amp;quot; % ( file, e ))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if ( __name__ == &amp;quot;__main__&amp;quot; ):&lt;br /&gt;
    # start&lt;br /&gt;
    Generator()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Repository Files ==&lt;br /&gt;
Repositories are distributed just like any other add-on. In order for you to browse one in XBMC, you&#039;ll need to [[Add-ons_for_XBMC_(Developement)|create an add-on]] and install it. The repository addon extends the xbmc.addon.repository extension point, so in addition to the general XML structure and icons required for an icon, you&#039;ll need an &amp;lt;extension&amp;gt; block specfically pointing to your repository.&lt;br /&gt;
Use the addon.xml of any of the [[3rd party add-on repositories]] as a template.&lt;br /&gt;
Online repositories should always have zip set to true, both for efficiency of download and for the protection that .zip offers by way of verifying the download (i.e. can we unzip it).&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
=== Using your repo to host images ===&lt;br /&gt;
You may as a developer need to host images from time to time.&lt;br /&gt;
Something like photobucket or flickr may work, but you can also use your repo.&lt;br /&gt;
Commit an image to it, and then form the url to it as you would if you were accessing the image via git or svn (like below):&lt;br /&gt;
&lt;br /&gt;
http://xbmc-adult.googlecode.com/svn/trunk/repository.xbmc-adult/icon.png&lt;br /&gt;
&lt;br /&gt;
This can then be accessed easily from python code, or even embedded on the XBMC forums.&lt;br /&gt;
&lt;br /&gt;
=== How to make an add-on self-updating without distributing a repository file ===&lt;br /&gt;
This is optional.&lt;br /&gt;
You still need a repository for this, you just distribute the actual zipped plugin or script, as opposed to the repository file.&lt;br /&gt;
First you need to have a working repository file.&lt;br /&gt;
Copy the equivalent of this code from the addon.xml of your repository file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;extension point=&amp;quot;xbmc.addon.repository&amp;quot;&lt;br /&gt;
              name=&amp;quot;Official XBMC.org Add-on Repository&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;info compressed=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml&amp;lt;/info&amp;gt;&lt;br /&gt;
    &amp;lt;checksum&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml.md5&amp;lt;/checksum&amp;gt;&lt;br /&gt;
    &amp;lt;datadir zip=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre&amp;lt;/datadir&amp;gt;&lt;br /&gt;
  &amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Then simply add it under the other &amp;lt;extension point&amp;gt; entries of your add-on&#039;s addon.xml&lt;br /&gt;
The name= part of this repository extension must never be the same as your add-on.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[3rd party add-on repositories]]&lt;br /&gt;
&#039;&#039;&#039;Development:&#039;&#039;&#039;&lt;br /&gt;
* [[Add-on development]]&lt;br /&gt;
* [[Add-on repositories]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Add-on development]]&lt;br /&gt;
[[Category:Skin development]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=107887</id>
		<title>Archive:Create a repository for add-ons</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=107887"/>
		<updated>2015-12-10T06:10:55Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav|[[Development]]|[[Add-on development]]|[[Add-on repositories]]}}&lt;br /&gt;
&lt;br /&gt;
When you have created your repository, feel free to add it to the [[3rd party add-on repositories]] list.&lt;br /&gt;
&lt;br /&gt;
==Video Tutorial==&lt;br /&gt;
{{youtube|A5scCJ3OnmM}}&lt;br /&gt;
*This video will help you create a Repository for Kodi. The video&#039;s steps are different from the written tutorial.&lt;br /&gt;
&lt;br /&gt;
== Things you will require ==&lt;br /&gt;
* Any HTTP server. A popular method is to use the svn or git source code servers of googlecode, gitorious and github.&lt;br /&gt;
  - In your code project page, make sure you set up the correct version control system (source tab). Most skins use SVN.&lt;br /&gt;
  - This will get you the right checkout address (link) and folder structure.&lt;br /&gt;
* A folder containing one or more add-on.&lt;br /&gt;
  - Start by installing an svn program (like Tortoisesvn).&lt;br /&gt;
  - Right click the empty folder, choose &#039;SVN Checkout&#039; to let it build a folder structure inside.&lt;br /&gt;
  - Make sure you get asked for authentication (!), the folders look like your source code server.&lt;br /&gt;
  - If you don&#039;t get asked for authentication check your server settings and http vs https links.&lt;br /&gt;
  - Make a test.txt file in the trunk, right click to mark it as &#039;add&#039; and use and use &#039;SVN Commit&#039; on top folder.&lt;br /&gt;
* Make the following two files using the python code below. These 2 files are made from the addon.xml files in the folders below (from the addons). Where you can have your addon unzipped (or zipped as long as there is an addon.xml file next to it, that is always up to date with the one in the zip).&lt;br /&gt;
  - A master addon&#039;&#039;&#039;s&#039;&#039;&#039;.xml file. This file contains metadata about all available add-ons.&lt;br /&gt;
  - A checksum of the above file (this file only contains a hash of addons.xml).&lt;br /&gt;
* A zipped repository add-on for distribution. This allows you to share your repository with others.&lt;br /&gt;
  - Easiest way is to have a look at another repository file and change the name, info and links.&lt;br /&gt;
  - You can also have a look at how other repos set up their folder structure.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;[https://raw.github.com/garbear/unqlocked/master/addons_xml_generator.py] to generate the master xml and the MD5. Put it in the folder with all your add-ons (it needs to see addon.xml files in a folder below) and run it from your Python interpreter. If using a source code server, you can now upload your add-on folder via svn or git to your repository. Every time you update an add-on run the addons_xml_generator.py before uploading the add-ons folder.&lt;br /&gt;
&lt;br /&gt;
* For Windows users. Install the latest version of Python.msi (from their website) in it&#039;s default directory. Python (.py) files should now be associated with python.exe and can be run like a program.&lt;br /&gt;
* Make a new text file and name it &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;. Open it with Notepad++ (or equivalent) and paste the following code inside.&lt;br /&gt;
&lt;br /&gt;
addons_xml_generator.py&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# *&lt;br /&gt;
# *  Copyright (C) 2012-2013 Garrett Brown&lt;br /&gt;
# *  Copyright (C) 2010      j48antialias&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is free software; you can redistribute it and/or modify&lt;br /&gt;
# *  it under the terms of the GNU General Public License as published by&lt;br /&gt;
# *  the Free Software Foundation; either version 2, or (at your option)&lt;br /&gt;
# *  any later version.&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is distributed in the hope that it will be useful,&lt;br /&gt;
# *  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;br /&gt;
# *  GNU General Public License for more details.&lt;br /&gt;
# *&lt;br /&gt;
# *  You should have received a copy of the GNU General Public License&lt;br /&gt;
# *  along with XBMC; see the file COPYING.  If not, write to&lt;br /&gt;
# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.&lt;br /&gt;
# *  http://www.gnu.org/copyleft/gpl.html&lt;br /&gt;
# *&lt;br /&gt;
# *  Based on code by j48antialias:&lt;br /&gt;
# *  https://anarchintosh-projects.googlecode.com/files/addons_xml_generator.py&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; addons.xml generator &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Compatibility with 3.0, 3.1 and 3.2 not supporting u&amp;quot;&amp;quot; literals&lt;br /&gt;
if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
    import codecs&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return codecs.unicode_escape_decode(x)[0]&lt;br /&gt;
else:&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return x&lt;br /&gt;
&lt;br /&gt;
class Generator:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Generates a new addons.xml file from each addons addon.xml file&lt;br /&gt;
        and a new addons.xml.md5 hash file. Must be run from the root of&lt;br /&gt;
        the checked-out repo. Only handles single depth folder structure.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __init__( self ):&lt;br /&gt;
        # generate files&lt;br /&gt;
        self._generate_addons_file()&lt;br /&gt;
        self._generate_md5_file()&lt;br /&gt;
        # notify user&lt;br /&gt;
        print(&amp;quot;Finished updating addons xml and md5 files&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    def _generate_addons_file( self ):&lt;br /&gt;
        # addon list&lt;br /&gt;
        addons = os.listdir( &amp;quot;.&amp;quot; )&lt;br /&gt;
        # final addons text&lt;br /&gt;
        addons_xml = u(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot; encoding=\&amp;quot;UTF-8\&amp;quot; standalone=\&amp;quot;yes\&amp;quot;?&amp;gt;\n&amp;lt;addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # loop thru and add each addons addon.xml file&lt;br /&gt;
        for addon in addons:&lt;br /&gt;
            try:&lt;br /&gt;
                # skip any file or .svn folder or .git folder&lt;br /&gt;
                if ( not os.path.isdir( addon ) or addon == &amp;quot;.svn&amp;quot; or addon == &amp;quot;.git&amp;quot; ): continue&lt;br /&gt;
                # create path&lt;br /&gt;
                _path = os.path.join( addon, &amp;quot;addon.xml&amp;quot; )&lt;br /&gt;
                # split lines for stripping&lt;br /&gt;
                xml_lines = open( _path, &amp;quot;r&amp;quot; , encoding=&amp;quot;UTF-8&amp;quot;).read().splitlines()&lt;br /&gt;
                # new addon&lt;br /&gt;
                addon_xml = &amp;quot;&amp;quot;&lt;br /&gt;
                # loop thru cleaning each line&lt;br /&gt;
                for line in xml_lines:&lt;br /&gt;
                    # skip encoding format line&lt;br /&gt;
                    if ( line.find( &amp;quot;&amp;lt;?xml&amp;quot; ) &amp;gt;= 0 ): continue&lt;br /&gt;
                    # add line&lt;br /&gt;
                    if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
                        addon_xml += unicode( line.rstrip() + &amp;quot;\n&amp;quot;, &amp;quot;UTF-8&amp;quot; )&lt;br /&gt;
                    else:&lt;br /&gt;
                        addon_xml += line.rstrip() + &amp;quot;\n&amp;quot;&lt;br /&gt;
                # we succeeded so add to our final addons.xml text&lt;br /&gt;
                addons_xml += addon_xml.rstrip() + &amp;quot;\n\n&amp;quot;&lt;br /&gt;
            except Exception as e:&lt;br /&gt;
                # missing or poorly formatted addon.xml&lt;br /&gt;
                print(&amp;quot;Excluding %s for %s&amp;quot; % ( _path, e ))&lt;br /&gt;
        # clean and add closing tag&lt;br /&gt;
        addons_xml = addons_xml.strip() + u(&amp;quot;\n&amp;lt;/addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # save file&lt;br /&gt;
        self._save_file( addons_xml.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml&amp;quot; )&lt;br /&gt;
    &lt;br /&gt;
    def _generate_md5_file( self ):&lt;br /&gt;
        # create a new md5 hash&lt;br /&gt;
        try:&lt;br /&gt;
            import md5&lt;br /&gt;
            m = md5.new( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot; ).read() ).hexdigest()&lt;br /&gt;
        except ImportError:&lt;br /&gt;
            import hashlib&lt;br /&gt;
            m = hashlib.md5( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot;, encoding=&amp;quot;UTF-8&amp;quot; ).read().encode( &amp;quot;UTF-8&amp;quot; ) ).hexdigest()&lt;br /&gt;
        &lt;br /&gt;
        # save file&lt;br /&gt;
        try:&lt;br /&gt;
            self._save_file( m.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml.md5&amp;quot; )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred creating addons.xml.md5 file!\n%s&amp;quot; % e)&lt;br /&gt;
    &lt;br /&gt;
    def _save_file( self, data, file ):&lt;br /&gt;
        try:&lt;br /&gt;
            # write data to the file (use b for Python 3)&lt;br /&gt;
            open( file, &amp;quot;wb&amp;quot; ).write( data )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred saving %s file!\n%s&amp;quot; % ( file, e ))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if ( __name__ == &amp;quot;__main__&amp;quot; ):&lt;br /&gt;
    # start&lt;br /&gt;
    Generator()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Repository Files ==&lt;br /&gt;
Repositories are distributed just like any other add-on. In order for you to browse one in XBMC, you&#039;ll need to [[Add-ons_for_XBMC_(Developement)|create an add-on]] and install it. The repository addon extends the xbmc.addon.repository extension point, so in addition to the general XML structure and icons required for an icon, you&#039;ll need an &amp;lt;extension&amp;gt; block specfically pointing to your repository.&lt;br /&gt;
Use the addon.xml of any of the [[3rd party add-on repositories]] as a template.&lt;br /&gt;
Online repositories should always have zip set to true, both for efficiency of download and for the protection that .zip offers by way of verifying the download (i.e. can we unzip it).&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
=== Using your repo to host images ===&lt;br /&gt;
You may as a developer need to host images from time to time.&lt;br /&gt;
Something like photobucket or flickr may work, but you can also use your repo.&lt;br /&gt;
Commit an image to it, and then form the url to it as you would if you were accessing the image via git or svn (like below):&lt;br /&gt;
&lt;br /&gt;
http://xbmc-adult.googlecode.com/svn/trunk/repository.xbmc-adult/icon.png&lt;br /&gt;
&lt;br /&gt;
This can then be accessed easily from python code, or even embedded on the XBMC forums.&lt;br /&gt;
&lt;br /&gt;
=== How to make an add-on self-updating without distributing a repository file ===&lt;br /&gt;
This is optional.&lt;br /&gt;
You still need a repository for this, you just distribute the actual zipped plugin or script, as opposed to the repository file.&lt;br /&gt;
First you need to have a working repository file.&lt;br /&gt;
Copy the equivalent of this code from the addon.xml of your repository file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;extension point=&amp;quot;xbmc.addon.repository&amp;quot;&lt;br /&gt;
              name=&amp;quot;Official XBMC.org Add-on Repository&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;info compressed=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml&amp;lt;/info&amp;gt;&lt;br /&gt;
    &amp;lt;checksum&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml.md5&amp;lt;/checksum&amp;gt;&lt;br /&gt;
    &amp;lt;datadir zip=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre&amp;lt;/datadir&amp;gt;&lt;br /&gt;
  &amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Then simply add it under the other &amp;lt;extension point&amp;gt; entries of your add-on&#039;s addon.xml&lt;br /&gt;
The name= part of this repository extension must never be the same as your add-on.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[3rd party add-on repositories]]&lt;br /&gt;
&#039;&#039;&#039;Development:&#039;&#039;&#039;&lt;br /&gt;
* [[Add-on development]]&lt;br /&gt;
* [[Add-on repositories]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Add-on development]]&lt;br /&gt;
[[Category:Skin development]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
	<entry>
		<id>https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=107886</id>
		<title>Archive:Create a repository for add-ons</title>
		<link rel="alternate" type="text/html" href="https://kodi.wiki/index.php?title=Archive:Create_a_repository_for_add-ons&amp;diff=107886"/>
		<updated>2015-12-10T06:08:49Z</updated>

		<summary type="html">&lt;p&gt;SimpleKodi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mininav|[[Development]]|[[Add-on development]]|[[Add-on repositories]]}}&lt;br /&gt;
&lt;br /&gt;
When you have created your repository, feel free to add it to the [[3rd party add-on repositories]] list.&lt;br /&gt;
&lt;br /&gt;
==Video Tutorial==&lt;br /&gt;
{{youtube|A5scCJ3OnmM}}&lt;br /&gt;
&lt;br /&gt;
== Things you will require ==&lt;br /&gt;
* Any HTTP server. A popular method is to use the svn or git source code servers of googlecode, gitorious and github.&lt;br /&gt;
  - In your code project page, make sure you set up the correct version control system (source tab). Most skins use SVN.&lt;br /&gt;
  - This will get you the right checkout address (link) and folder structure.&lt;br /&gt;
* A folder containing one or more add-on.&lt;br /&gt;
  - Start by installing an svn program (like Tortoisesvn).&lt;br /&gt;
  - Right click the empty folder, choose &#039;SVN Checkout&#039; to let it build a folder structure inside.&lt;br /&gt;
  - Make sure you get asked for authentication (!), the folders look like your source code server.&lt;br /&gt;
  - If you don&#039;t get asked for authentication check your server settings and http vs https links.&lt;br /&gt;
  - Make a test.txt file in the trunk, right click to mark it as &#039;add&#039; and use and use &#039;SVN Commit&#039; on top folder.&lt;br /&gt;
* Make the following two files using the python code below. These 2 files are made from the addon.xml files in the folders below (from the addons). Where you can have your addon unzipped (or zipped as long as there is an addon.xml file next to it, that is always up to date with the one in the zip).&lt;br /&gt;
  - A master addon&#039;&#039;&#039;s&#039;&#039;&#039;.xml file. This file contains metadata about all available add-ons.&lt;br /&gt;
  - A checksum of the above file (this file only contains a hash of addons.xml).&lt;br /&gt;
* A zipped repository add-on for distribution. This allows you to share your repository with others.&lt;br /&gt;
  - Easiest way is to have a look at another repository file and change the name, info and links.&lt;br /&gt;
  - You can also have a look at how other repos set up their folder structure.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;[https://raw.github.com/garbear/unqlocked/master/addons_xml_generator.py] to generate the master xml and the MD5. Put it in the folder with all your add-ons (it needs to see addon.xml files in a folder below) and run it from your Python interpreter. If using a source code server, you can now upload your add-on folder via svn or git to your repository. Every time you update an add-on run the addons_xml_generator.py before uploading the add-ons folder.&lt;br /&gt;
&lt;br /&gt;
* For Windows users. Install the latest version of Python.msi (from their website) in it&#039;s default directory. Python (.py) files should now be associated with python.exe and can be run like a program.&lt;br /&gt;
* Make a new text file and name it &amp;lt;tt&amp;gt;addons_xml_generator.py&amp;lt;/tt&amp;gt;. Open it with Notepad++ (or equivalent) and paste the following code inside.&lt;br /&gt;
&lt;br /&gt;
addons_xml_generator.py&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# *&lt;br /&gt;
# *  Copyright (C) 2012-2013 Garrett Brown&lt;br /&gt;
# *  Copyright (C) 2010      j48antialias&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is free software; you can redistribute it and/or modify&lt;br /&gt;
# *  it under the terms of the GNU General Public License as published by&lt;br /&gt;
# *  the Free Software Foundation; either version 2, or (at your option)&lt;br /&gt;
# *  any later version.&lt;br /&gt;
# *&lt;br /&gt;
# *  This Program is distributed in the hope that it will be useful,&lt;br /&gt;
# *  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
# *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;br /&gt;
# *  GNU General Public License for more details.&lt;br /&gt;
# *&lt;br /&gt;
# *  You should have received a copy of the GNU General Public License&lt;br /&gt;
# *  along with XBMC; see the file COPYING.  If not, write to&lt;br /&gt;
# *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.&lt;br /&gt;
# *  http://www.gnu.org/copyleft/gpl.html&lt;br /&gt;
# *&lt;br /&gt;
# *  Based on code by j48antialias:&lt;br /&gt;
# *  https://anarchintosh-projects.googlecode.com/files/addons_xml_generator.py&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; addons.xml generator &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# Compatibility with 3.0, 3.1 and 3.2 not supporting u&amp;quot;&amp;quot; literals&lt;br /&gt;
if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
    import codecs&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return codecs.unicode_escape_decode(x)[0]&lt;br /&gt;
else:&lt;br /&gt;
    def u(x):&lt;br /&gt;
        return x&lt;br /&gt;
&lt;br /&gt;
class Generator:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Generates a new addons.xml file from each addons addon.xml file&lt;br /&gt;
        and a new addons.xml.md5 hash file. Must be run from the root of&lt;br /&gt;
        the checked-out repo. Only handles single depth folder structure.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __init__( self ):&lt;br /&gt;
        # generate files&lt;br /&gt;
        self._generate_addons_file()&lt;br /&gt;
        self._generate_md5_file()&lt;br /&gt;
        # notify user&lt;br /&gt;
        print(&amp;quot;Finished updating addons xml and md5 files&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    def _generate_addons_file( self ):&lt;br /&gt;
        # addon list&lt;br /&gt;
        addons = os.listdir( &amp;quot;.&amp;quot; )&lt;br /&gt;
        # final addons text&lt;br /&gt;
        addons_xml = u(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot; encoding=\&amp;quot;UTF-8\&amp;quot; standalone=\&amp;quot;yes\&amp;quot;?&amp;gt;\n&amp;lt;addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # loop thru and add each addons addon.xml file&lt;br /&gt;
        for addon in addons:&lt;br /&gt;
            try:&lt;br /&gt;
                # skip any file or .svn folder or .git folder&lt;br /&gt;
                if ( not os.path.isdir( addon ) or addon == &amp;quot;.svn&amp;quot; or addon == &amp;quot;.git&amp;quot; ): continue&lt;br /&gt;
                # create path&lt;br /&gt;
                _path = os.path.join( addon, &amp;quot;addon.xml&amp;quot; )&lt;br /&gt;
                # split lines for stripping&lt;br /&gt;
                xml_lines = open( _path, &amp;quot;r&amp;quot; , encoding=&amp;quot;UTF-8&amp;quot;).read().splitlines()&lt;br /&gt;
                # new addon&lt;br /&gt;
                addon_xml = &amp;quot;&amp;quot;&lt;br /&gt;
                # loop thru cleaning each line&lt;br /&gt;
                for line in xml_lines:&lt;br /&gt;
                    # skip encoding format line&lt;br /&gt;
                    if ( line.find( &amp;quot;&amp;lt;?xml&amp;quot; ) &amp;gt;= 0 ): continue&lt;br /&gt;
                    # add line&lt;br /&gt;
                    if sys.version &amp;lt; &#039;3&#039;:&lt;br /&gt;
                        addon_xml += unicode( line.rstrip() + &amp;quot;\n&amp;quot;, &amp;quot;UTF-8&amp;quot; )&lt;br /&gt;
                    else:&lt;br /&gt;
                        addon_xml += line.rstrip() + &amp;quot;\n&amp;quot;&lt;br /&gt;
                # we succeeded so add to our final addons.xml text&lt;br /&gt;
                addons_xml += addon_xml.rstrip() + &amp;quot;\n\n&amp;quot;&lt;br /&gt;
            except Exception as e:&lt;br /&gt;
                # missing or poorly formatted addon.xml&lt;br /&gt;
                print(&amp;quot;Excluding %s for %s&amp;quot; % ( _path, e ))&lt;br /&gt;
        # clean and add closing tag&lt;br /&gt;
        addons_xml = addons_xml.strip() + u(&amp;quot;\n&amp;lt;/addons&amp;gt;\n&amp;quot;)&lt;br /&gt;
        # save file&lt;br /&gt;
        self._save_file( addons_xml.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml&amp;quot; )&lt;br /&gt;
    &lt;br /&gt;
    def _generate_md5_file( self ):&lt;br /&gt;
        # create a new md5 hash&lt;br /&gt;
        try:&lt;br /&gt;
            import md5&lt;br /&gt;
            m = md5.new( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot; ).read() ).hexdigest()&lt;br /&gt;
        except ImportError:&lt;br /&gt;
            import hashlib&lt;br /&gt;
            m = hashlib.md5( open( &amp;quot;addons.xml&amp;quot;, &amp;quot;r&amp;quot;, encoding=&amp;quot;UTF-8&amp;quot; ).read().encode( &amp;quot;UTF-8&amp;quot; ) ).hexdigest()&lt;br /&gt;
        &lt;br /&gt;
        # save file&lt;br /&gt;
        try:&lt;br /&gt;
            self._save_file( m.encode( &amp;quot;UTF-8&amp;quot; ), file=&amp;quot;addons.xml.md5&amp;quot; )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred creating addons.xml.md5 file!\n%s&amp;quot; % e)&lt;br /&gt;
    &lt;br /&gt;
    def _save_file( self, data, file ):&lt;br /&gt;
        try:&lt;br /&gt;
            # write data to the file (use b for Python 3)&lt;br /&gt;
            open( file, &amp;quot;wb&amp;quot; ).write( data )&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            # oops&lt;br /&gt;
            print(&amp;quot;An error occurred saving %s file!\n%s&amp;quot; % ( file, e ))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if ( __name__ == &amp;quot;__main__&amp;quot; ):&lt;br /&gt;
    # start&lt;br /&gt;
    Generator()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Repository Files ==&lt;br /&gt;
Repositories are distributed just like any other add-on. In order for you to browse one in XBMC, you&#039;ll need to [[Add-ons_for_XBMC_(Developement)|create an add-on]] and install it. The repository addon extends the xbmc.addon.repository extension point, so in addition to the general XML structure and icons required for an icon, you&#039;ll need an &amp;lt;extension&amp;gt; block specfically pointing to your repository.&lt;br /&gt;
Use the addon.xml of any of the [[3rd party add-on repositories]] as a template.&lt;br /&gt;
Online repositories should always have zip set to true, both for efficiency of download and for the protection that .zip offers by way of verifying the download (i.e. can we unzip it).&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
=== Using your repo to host images ===&lt;br /&gt;
You may as a developer need to host images from time to time.&lt;br /&gt;
Something like photobucket or flickr may work, but you can also use your repo.&lt;br /&gt;
Commit an image to it, and then form the url to it as you would if you were accessing the image via git or svn (like below):&lt;br /&gt;
&lt;br /&gt;
http://xbmc-adult.googlecode.com/svn/trunk/repository.xbmc-adult/icon.png&lt;br /&gt;
&lt;br /&gt;
This can then be accessed easily from python code, or even embedded on the XBMC forums.&lt;br /&gt;
&lt;br /&gt;
=== How to make an add-on self-updating without distributing a repository file ===&lt;br /&gt;
This is optional.&lt;br /&gt;
You still need a repository for this, you just distribute the actual zipped plugin or script, as opposed to the repository file.&lt;br /&gt;
First you need to have a working repository file.&lt;br /&gt;
Copy the equivalent of this code from the addon.xml of your repository file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;extension point=&amp;quot;xbmc.addon.repository&amp;quot;&lt;br /&gt;
              name=&amp;quot;Official XBMC.org Add-on Repository&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;info compressed=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml&amp;lt;/info&amp;gt;&lt;br /&gt;
    &amp;lt;checksum&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre/addons.xml.md5&amp;lt;/checksum&amp;gt;&lt;br /&gt;
    &amp;lt;datadir zip=&amp;quot;true&amp;quot;&amp;gt;http://mirrors.xbmc.org/addons/dharma-pre&amp;lt;/datadir&amp;gt;&lt;br /&gt;
  &amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Then simply add it under the other &amp;lt;extension point&amp;gt; entries of your add-on&#039;s addon.xml&lt;br /&gt;
The name= part of this repository extension must never be the same as your add-on.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[3rd party add-on repositories]]&lt;br /&gt;
&#039;&#039;&#039;Development:&#039;&#039;&#039;&lt;br /&gt;
* [[Add-on development]]&lt;br /&gt;
* [[Add-on repositories]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Add-on development]]&lt;br /&gt;
[[Category:Skin development]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>SimpleKodi</name></author>
	</entry>
</feed>