├── 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 | --------------------------------------------------------------------------------