├── README.md
├── .gitignore
├── addon.xml
├── default.py
├── simplexbmc.py
└── gallery3.py
/README.md:
--------------------------------------------------------------------------------
1 | plugin.picture.gallery3
2 | =======================
3 |
4 | A Gallery3 Addon für XBMC
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[co]
2 |
3 | # Packages
4 | *.egg
5 | *.egg-info
6 | dist
7 | build
8 | eggs
9 | parts
10 | bin
11 | var
12 | sdist
13 | develop-eggs
14 | .installed.cfg
15 |
16 | # Installer logs
17 | pip-log.txt
18 |
19 | # Unit test / coverage reports
20 | .coverage
21 | .tox
22 |
23 | #Translations
24 | *.mo
25 |
26 | #Mr Developer
27 | .mr.developer.cfg
28 |
--------------------------------------------------------------------------------
/addon.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
14 | image
15 |
16 |
17 |
18 |
19 |
20 |
21 | all
22 |
23 |
24 |
--------------------------------------------------------------------------------
/default.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #-------------LicenseHeader--------------
3 | # plugin.image.gallery3 -
4 | # Copyright (C) 2010 Raptor 2101 [raptor2101@gmx.de]
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 | from gallery3 import Gallery3
19 | from simplexbmc import SimpleXbmcGui
20 |
21 | import os,xbmcaddon;
22 | #data = 'user=Raptor 2101&password=Pyi2SZxdtvRV-mjYUeMD'
23 |
24 | __settings__ = xbmcaddon.Addon(id='plugin.image.gallery3')
25 |
26 | def get_params():
27 | """ extract params from argv[2] to make a dict (key=value) """
28 | paramDict = {}
29 | print "get_params() argv=", sys.argv
30 | if sys.argv[2]:
31 | paramPairs=sys.argv[2][1:].split( "&" )
32 | for paramsPair in paramPairs:
33 | paramSplits = paramsPair.split('=')
34 | if (len(paramSplits))==2:
35 | paramDict[paramSplits[0]] = paramSplits[1]
36 | return paramDict
37 |
38 | params = get_params();
39 | itemId = params.get("itemId","1");
40 | DIR_HOME = xbmc.translatePath(__settings__.getAddonInfo("profile"))
41 |
42 | if not os.path.exists(DIR_HOME):
43 | os.mkdir(DIR_HOME);
44 |
45 | DIR_CACHE_ROOT = os.path.join(DIR_HOME, 'cache')
46 | if not os.path.exists(DIR_CACHE_ROOT):
47 | os.mkdir(DIR_CACHE_ROOT);
48 |
49 | DIR_CACHE_THUMPS = os.path.join(DIR_CACHE_ROOT, 'thumbs')
50 | if not os.path.exists(DIR_CACHE_THUMPS):
51 | os.mkdir(DIR_CACHE_THUMPS);
52 |
53 | gui = SimpleXbmcGui();
54 | gallery = Gallery3("","",gui,DIR_CACHE_ROOT,DIR_CACHE_THUMPS);
55 | gui.openMenuContext();
56 |
57 |
58 |
59 | gallery.displayChildItems(itemId);
60 |
61 | gui.closeMenuContext()
62 | #imdbJson = json.loads(results.read().decode('utf-8'))
63 |
--------------------------------------------------------------------------------
/simplexbmc.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #-------------LicenseHeader--------------
3 | #
4 | # Copyright (C) 2010 Raptor 2101 [raptor2101@gmx.de]
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 | import xbmc, xbmcgui, xbmcplugin,xbmcaddon, sys, urllib, urllib2, os,re
19 | __plugin__ = "Gallery3"
20 |
21 | class SimpleXbmcGui(object):
22 | def log(self, msg):
23 | if type(msg) not in (str, unicode):
24 | xbmc.output("[%s]: %s" % (__plugin__, type(msg)))
25 | else:
26 | xbmc.output("[%s]: %s" % (__plugin__, msg.encode('utf8')))
27 |
28 | def addImage(self,galleryItem, itemCount):
29 | print "Thumb:"+galleryItem.thumbnail;
30 | print "Image:"+galleryItem.imageLink;
31 | listItem=xbmcgui.ListItem(galleryItem.title, iconImage="DefaultImage.png", thumbnailImage=galleryItem.thumbnail)
32 | listItem.setInfo(type="image", infoLabels={ "Title": galleryItem.title } )
33 | return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=galleryItem.imageLink,listitem=listItem,isFolder=False,totalItems = itemCount)
34 |
35 |
36 | def addDir(self,galleryItem, itemCount):
37 | print galleryItem.thumbnail;
38 | listItem=xbmcgui.ListItem(galleryItem.title, iconImage="DefaultFolder.png", thumbnailImage=galleryItem.thumbnail)
39 |
40 | link = "%s?itemId=%s" % (sys.argv[0], galleryItem.itemId)
41 | print galleryItem.childCount;
42 | xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=link,listitem=listItem,isFolder=True,totalItems = itemCount)
43 |
44 | def openMenuContext(self):
45 | self.dialogProgress = xbmcgui.DialogProgress();
46 |
47 | def closeMenuContext(self):
48 | xbmcplugin.endOfDirectory(int(sys.argv[1]));
49 |
50 | def refresh(self):
51 | xbmc.executebuiltin("Container.Refresh");
52 |
53 | def errorOK(self,title="", msg=""):
54 | e = str( sys.exc_info()[ 1 ] )
55 | self.log(e)
56 | if not title:
57 | title = __plugin__
58 | if not msg:
59 | msg = "ERROR!"
60 | if(e == None):
61 | xbmcgui.Dialog().ok( title, msg, e )
62 | else:
63 | xbmcgui.Dialog().ok( title, msg)
64 |
--------------------------------------------------------------------------------
/gallery3.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import urllib,urllib2,re,os,pickle
4 | try:
5 | import json
6 | except:
7 | import simplejson as json
8 |
9 | regex_itemId = re.compile("\\d+$");
10 | regex_thumbId = re.compile("/(\\d+)\\?");
11 | regex_number = re.compile("\\d+");
12 |
13 | class GalleryAlbum:
14 | def __init__(self,itemId,title,thumbnail, childCount = 0):
15 | self.itemId = itemId;
16 | self.title = title;
17 | self.thumbnail = thumbnail;
18 | self.childCount = childCount;
19 | self.isBrowsable = True;
20 |
21 | class GalleryImage:
22 | def __init__(self,itemId,title,thumbnail, imageLink):
23 | self.itemId = itemId;
24 | self.title = title;
25 | self.thumbnail = thumbnail;
26 | self.imageLink = imageLink;
27 | self.isBrowsable = False;
28 |
29 | class Gallery3(object):
30 | def __init__(self,rootUrl,apiKey,gui, imageCache, thumbCache):
31 | self.restLink = rootUrl + "index.php/rest/item/%s"
32 | self.apiKey = apiKey;
33 | self.imageCache = imageCache;
34 | self.thumbCache = thumbCache;
35 | self.gui = gui
36 |
37 |
38 | def getHTTPSocket(self, link):
39 | request = urllib2.Request(link)
40 | request.add_header('X-Gallery-Request-Key', self.apiKey)
41 | return urllib2.urlopen(request);
42 |
43 | def doJSONRequest(self, link):
44 |
45 | sock = self.getHTTPSocket(link);
46 | jsonResponse = json.loads(sock.read().decode('utf-8'))
47 |
48 | sock.close();
49 | return jsonResponse;
50 |
51 | def displayChildItems(self,itemId):
52 | jsonResponse = self.doJSONRequest(self.restLink%(itemId));
53 | children = [];
54 | updateDate = jsonResponse['entity']['updated'];
55 | membersCount = len(jsonResponse["members"]);
56 | archiveFile = os.path.join(self.imageCache,"%s.bin"%itemId);
57 | counter = 0;
58 | #if not os.path.exists(archiveFile) or os.stat(archiveFile)[8] < int(updateDate):
59 | for item in jsonResponse["members"]:
60 | try:
61 | itemId = regex_itemId.search(item).group();
62 | galleryChild = self.getGalleryItem(itemId);
63 | self.display(galleryChild, membersCount)
64 | children.append(galleryChild);
65 | if(counter > 10):
66 | break;
67 | counter = counter + 1
68 | except:
69 | pass;
70 | #output = open(archiveFile, 'wb')
71 | #pickle.dump(children, output);
72 | #output.close();
73 | #else:
74 | # input = open(archiveFile, 'rb')
75 | # children = pickle.load(input);
76 | # input.close();
77 | # childCount = len(children);
78 | # for child in children:
79 | # self.display(child, childCount);
80 |
81 | def display(self, item, totalItemCount):
82 | if(item.isBrowsable):
83 | self.gui.addDir(item, totalItemCount);
84 | else:
85 | self.gui.addImage(item, totalItemCount);
86 |
87 | def downloadThumbnail(self, link):
88 | thumbId = regex_thumbId.search(link).group();
89 | thumbId = regex_number.search(thumbId).group();
90 | targetLink = os.path.join(self.thumbCache,"%s.jpeg"%thumbId);
91 | if not os.path.exists(targetLink):
92 | sock = self.getHTTPSocket(link);
93 |
94 | thumbFile = open(targetLink,'w');
95 | thumbFile.write(sock.read());
96 | thumbFile.close();
97 | sock.close();
98 |
99 | return targetLink;
100 |
101 | def downloadImage(self, link, updateDate):
102 | imageId = regex_thumbId.search(link).group();
103 | imageId = regex_number.search(imageId).group();
104 | targetLink = os.path.join(self.imageCache,"%s.jpeg"%imageId);
105 |
106 | if not os.path.exists(targetLink) or os.stat(targetLink)[8] < int(updateDate):
107 | sock = self.getHTTPSocket(link);
108 | imageFile = open(targetLink,'w');
109 | imageFile.write(sock.read());
110 | imageFile.close();
111 | sock.close();
112 |
113 | return targetLink;
114 |
115 | def getGalleryItem(self,itemId):
116 | response = self.doJSONRequest(self.restLink%(itemId));
117 |
118 | entity = response['entity'];
119 |
120 | itemId = entity['id'];
121 | title = entity['title'];
122 | itemType = entity['type'];
123 |
124 | thumbLink = "%s|X-Gallery-Request-Key=%s&X-Gallery-Request-Method=get"%(entity['thumb_url'],self.apiKey)
125 | #thumbLink = self.downloadThumbnail(thumbLink);
126 | print thumbLink
127 |
128 | if(itemType == "album"):
129 | childCount = len(response['members'])
130 | return GalleryAlbum(itemId,title,thumbLink,childCount);
131 | if(itemType == "photo"):
132 |
133 | imageLink = "%s|X-Gallery-Request-Key=%s&X-Gallery-Request-Method=get"%(entity['file_url'],self.apiKey);
134 | changeDate = entity['updated'];
135 | #imageLink = self.downloadImage(imageLink,changeDate);
136 | print imageLink
137 | return GalleryImage(itemId, title, thumbLink, thumbLink);
138 |
--------------------------------------------------------------------------------