Ivars 6 years ago
parent
commit
42d237d2a8
9 changed files with 805 additions and 456 deletions
  1. 194
    55
      addon.py
  2. 1
    1
      addon.xml
  3. 6
    2
      changelog.md
  4. 5
    2
      kmake.bat
  5. 1
    1
      kodiswift/plugin.py
  6. 379
    355
      project.wpr
  7. 2
    0
      resources/language/English/strings.xml
  8. 213
    37
      resources/lib/photostation_api.py
  9. 4
    3
      resources/settings.xml

+ 194
- 55
addon.py View File

@@ -1,16 +1,18 @@
1
-import os,os.path,sys, urllib, urlparse
2
-from kodiswift import Plugin, ListItem, storage
3
-from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon, CLI_MODE, SortMethod
4
-from resources.lib import photostation_api
1
+# -*- coding: utf-8 -*-
5 2
 try:
6 3
     import wingdbstub
7 4
 except:
8 5
     pass
6
+import os,os.path,sys, urllib, urlparse
7
+#import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon
8
+from kodiswift import Plugin, ListItem, storage
9
+from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon, CLI_MODE, SortMethod
10
+from resources.lib import photostation_api
9 11
 
10 12
 plugin = Plugin()
13
+handle = sys.argv[1]
11 14
 
12 15
 view_mode = plugin.get_setting("view_mode",str)
13
-
14 16
 server = plugin.get_setting("server", str)
15 17
 user = plugin.get_setting("user", str)
16 18
 password = plugin.get_setting("password", str)
@@ -20,6 +22,9 @@ sorting = plugin.get_setting("sorting", str)
20 22
 order = plugin.get_setting("order", str)
21 23
 video_quality = plugin.get_setting("video_quality", str)
22 24
 picture_quality = plugin.get_setting("picture_quality", str)
25
+thumbnail_quality = plugin.get_setting("thumbnail_quality", str)
26
+play_next = plugin.get_setting("play_next", bool)
27
+start_page = plugin.get_setting("start_page", str)
23 28
 
24 29
 ps = photostation_api.PhotoStationAPI("http://home.blue.lv/photo")
25 30
 try:
@@ -38,7 +43,7 @@ def main():
38 43
     data = plugin.request.url.replace(prefix,"")
39 44
     data = urllib.unquote(data)
40 45
     #default_oid = "album_323031372f323031372d30312d313320536c69646f73616e61"
41
-    default_oid = ""
46
+    default_oid = ""  #start_page
42 47
     if not data:
43 48
         data = default_oid
44 49
     oid = plugin.request.path[1:]
@@ -50,70 +55,131 @@ def main():
50 55
     else:
51 56
         page = int(qs["page"])
52 57
 
53
-    if not oid or oid.startswith("album"):
58
+    if not oid or oid.startswith("album") or oid.startswith("category"):
54 59
         plugin.set_content("images")
55 60
 
61
+        content = []
62
+        if not oid:
63
+            categories = ps.get_categories()["categories"]
64
+            for cat in categories:
65
+                if cat["hidden"]:
66
+                    continue
67
+                data2 = prefix + cat["id"]
68
+                label = cat["name"]
69
+                item = xbmcgui.ListItem(label, "", "", "", data2)
70
+                item.setInfo("Image", {"title":label})
71
+                item.setProperty("is_folder", "true")
72
+                item.setProperty("url", data2)
73
+                #items.append(item)
74
+                xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=True)
75
+
56 76
         offset = 0 if page_size == -1 else (page - 1) * page_size
57 77
         limit = -1 if page_size == -1 else page_size
58
-        content = ps.get_album_list(oid, offset=offset, limit=limit, sort_by=sorting, sort_direction=order )
78
+        if "category" in oid:
79
+            content = ps.get_category_list(oid)
80
+        else:
81
+            content = ps.get_album_list(oid, offset=offset, limit=limit, sort_by=sorting, sort_direction=order )
59 82
         items = []
60 83
         for f in content["items"]:
61
-            title = f["info"]["name"]
84
+            label = f["info"]["title"]
85
+            label2 = f["additional"]["file_location"] if "file_location" in f["additional"] else ""
62 86
             type = f["type"]
63 87
             oid2 = f["id"]
64
-            #is_playable = True if type in ("video","photo") else False
65
-            is_folder = False if type in ("video","photo") else True
66
-            thumb_url = ps.get_thumb_url(f["id"],"small")
88
+            is_playable = "true" if type in ("video","photo") else ""
89
+            is_folder = "" if type in ("video","photo") else "true"
90
+            thumb_quality = thumbnail_quality if thumbnail_quality in  f["thumbnail_status"] else "small"
91
+            thumb_url = ps.get_thumb_url(f["id"],thumb_quality)
92
+            #thumb_url = urllib.quote(thumb_url, ":/")
67 93
             data2 = prefix+f["id"]
68
-            #item = ListItem(title, icon=thumb_url, thumbnail=thumb_url, path=data2)
69
-            #item.is_folder = False if type in ("video","photo") else True
70 94
 
71 95
             if type=="album":
72
-                label2 = "%s photos, %s videos"%(f["additional"]["item_count"]["photo"],f["additional"]["item_count"]["video"])
73
-                item = xbmcgui.ListItem(title, label2, thumb_url, thumb_url, path=data2)
74
-                item.setInfo(
75
-                    "Image",
76
-                    {"title":f["info"]["title"],"picturepath":f["additional"]["file_location"]}
77
-                    )
96
+                nfiles = int(f["additional"]["item_count"]["photo"]) + int(f["additional"]["item_count"]["video"]) if "item_count" in f["additional"] else None
97
+                suf = "\n(%s)" % nfiles if nfiles else ""
98
+                label2 = "%s photos, %s videos"%(f["additional"]["item_count"]["photo"],f["additional"]["item_count"]["video"]) if "item_count" in f["additional"] else ""
99
+                label = label + suf
100
+                li_type = "video"  # pictures
101
+                tags = {
102
+                    #"title":f["info"]["title"],
103
+                    "title": label,
104
+                    #"picturepath":f["additional"]["file_location"]
105
+                    "label": label,
106
+                    "plotline":f["additional"]["file_location"] + "\n" + label2 if "file_location" in f["additional"] else "",
107
+                    "plot":f["additional"]["file_location"] + "\n" + label2 if "file_location" in f["additional"] else "",
108
+                    "path": f["info"]["sharepath"] if "sharepath" in f["additional"] else "",
109
+                }
78 110
 
79 111
             elif type == "photo":
112
+                label = label + "\n" + f["info"]["takendate"]
80 113
                 label2 = f["info"]["takendate"]
81
-                image_url = ps.get_thumb_url(oid2,"large")
114
+                image_url = ps.get_photo_url(oid2) if picture_quality == "original" else ps.get_thumb_url(oid2, picture_quality)
82 115
                 data2 = image_url
83
-                item = xbmcgui.ListItem(title, label2, thumb_url, thumb_url, path=data2)
84
-                item.setInfo(
85
-                    "pictures",
86
-                    {"title":f["info"]["title"],
87
-                     "picturepath":f["additional"]["file_location"],
88
-                     "exif:resolution": "720,480" ,}
89
-                    )
116
+                #print "image_url=", data2
117
+                #data2 = urllib.quote(data2, ":/")
118
+                li_type = "pictures"
119
+                tags = {
120
+                    "title": label2,  #f["info"]["title"],
121
+                     "date": f["info"]["takendate"],
122
+                     "picturepath": f["additional"]["file_location"],
123
+                     "exif:resolution": "%s,%s" % (f["info"]["resolutionx"], f["info"]["resolutiony"]),
124
+                     #"exif:path": f["additional"]["file_location"],
125
+                     #"exif:name": f["info"]["name"],
126
+                     #"exif:filename": f["additional"]["file_location"],
127
+                     #"exif:"
128
+                     # TODO pārejie EXIF u.c. dati
129
+                }
90 130
 
91 131
             elif type=="video":
132
+                label = label + "\n" + f["info"]["takendate"]
92 133
                 label2 = f["info"]["takendate"]
93
-                item = xbmcgui.ListItem(title, label2, thumb_url, thumb_url, path=data2)
94
-                item.setInfo(
95
-                    'video', {
96
-                        "title": title,
134
+                li_type =  'video'
135
+                tags = {
136
+                        "title":  label ,
97 137
                         "plot": f["additional"]["file_location"],
138
+                        #TODO
98 139
                     }
99
-                )
100
-            item.setProperty("is_folder", "true" if is_folder else "")
140
+                if play_next:
141
+                    data2 = data2 + "&album=" + oid if "?" in data2 else data2 + "?album=" + oid
142
+                    #data2 = urllib.quote(data2, ":/")
143
+                    is_playable = ""
144
+                else:
145
+                    if video_quality == "original":
146
+                        quality_id = ""
147
+                    else:
148
+                        quality_id = f["additional"]["video_quality"][0]["id"]
149
+                    data2 = ps.get_video_url(oid2, quality_id)
150
+                    #data2 = urllib.quote(data2, ":/")
151
+
152
+            item = xbmcgui.ListItem(label=label, label2=label2, path=data2)
153
+            item.setArt({
154
+                "thumb": thumb_url,
155
+                "icon": thumb_url,
156
+                "fanart": thumb_url,
157
+            })
158
+            item.setInfo(li_type, tags)
159
+            item.setProperty("is_folder", is_folder)
160
+            item.setProperty('IsPlayable', is_playable)
101 161
             item.setProperty("url", data2)
102
-            items.append(item)
103
-            #xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=is_folder,
104
-                                        #totalItems=len(content["items"]))
162
+            #items.append(item)
163
+            xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=True if is_folder=="true" else False,
164
+                                        totalItems=len(content["items"]))
165
+
105 166
         if page_size <> -1 and len(content["items"]) == page_size:
106 167
             data2 = prefix+oid+"?page=%s" % (page+1)
168
+            #data2 = urllib.quote(data2, ":/")
107 169
             item = xbmcgui.ListItem("Next", "", "", "", data2)
108 170
             item.setInfo("Image", {"title":"Next"})
109 171
             item.setProperty("is_folder", "false")
110 172
             item.setProperty("url", data2)
111
-            items.append(item)
173
+            #items.append(item)
174
+            xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=True,
175
+                                                totalItems=len(content["items"]))
112 176
 
113
-        sort_methods = [SortMethod.FILE, SortMethod.DATE, SortMethod.DATE_TAKEN]
114 177
         view_mode_id =  get_view_mode(view_mode)
115
-        return plugin.finish(items, sort_methods=None, view_mode=view_mode_id, cache_to_disc=True, update_listing=False)
116
-        #xbmcplugin.endOfDirectory(plugin.handle, succeeded=True, updateListing=False, cacheToDisc=True)
178
+        xbmc.executebuiltin('Container.SetViewMode(%s)' % view_mode_id)
179
+        #sort_methods = [SortMethod.FILE, SortMethod.DATE, SortMethod.DATE_TAKEN]
180
+        #xbmcplugin.addSortMethod( plugin.handle, sortMethod=xbmcplugin.SORT_METHOD_GENRE )
181
+        xbmcplugin.endOfDirectory(plugin.handle, succeeded=True, updateListing=False, cacheToDisc=True)
182
+        #return plugin.finish(items, sort_methods=None, view_mode=view_mode_id, cache_to_disc=True, update_listing=False)
117 183
 
118 184
     elif oid.startswith("photo"):
119 185
         print "play_photo ", oid
@@ -129,17 +195,34 @@ def main():
129 195
         plugin.set_resolved_url(url)
130 196
 
131 197
     elif oid.startswith("video"):
132
-        try:
133
-            streams = ps.get_video_streams(oid)
134
-            js = ps.get_photo_info(oid)
135
-        except Exception,e:
136
-            plugin.notify(str(e),"",10000)
137
-            return None
138
-        if streams:
139
-            return play_video(streams)
140
-        else:
141
-            plugin.notify("No streams found!",10000)
142
-            return None
198
+        if play_next and "album" in qs:  # play playlist
199
+            print "play_playlist", data, qs
200
+            album_id = qs["album"]
201
+            try:
202
+                items = ps.get_album_list(album_id)
203
+            except Exception,e:
204
+                plugin.notify(str(e),"",10000)
205
+                return None
206
+            if items:
207
+                play_playlist(items["items"], oid)
208
+                return None
209
+            else:
210
+                plugin.notify("No items found!",10000)
211
+                return None
212
+        else:  # play one video
213
+            print "play_video"
214
+            try:
215
+                streams = ps.get_video_streams(oid)
216
+                js = ps.get_photo_info(oid)
217
+            except Exception,e:
218
+                plugin.notify(str(e),"",10000)
219
+                return None
220
+            if streams:
221
+                play_video(streams)
222
+                return None
223
+            else:
224
+                plugin.notify("No streams found!",10000)
225
+                return None
143 226
 
144 227
 def get_view_mode(vm):
145 228
     modes = {
@@ -160,10 +243,61 @@ def get_view_mode(vm):
160 243
     if skin in modes and vm in modes[skin]:
161 244
         view_mode = modes[skin][vm]
162 245
     else:
163
-        view_mode = 50
246
+        view_mode = 500
164 247
     return view_mode
165 248
 
166 249
 
250
+def play_playlist(items, oid):
251
+    playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
252
+    playlist.clear()
253
+    pos = -1
254
+    i = 0
255
+    for f in items:
256
+        if f["type"] in ("album","photo"):
257
+            continue
258
+
259
+        label = f["info"]["name"] + "\n" + f["info"]["takendate"]
260
+        label2 = f["additional"]["file_location"]
261
+        type = f["type"]
262
+        oid2 = f["id"]
263
+        if oid == oid2:
264
+            pos = i
265
+        #is_playable = True if type in ("video","photo") else False
266
+        is_folder = False if type in ("video","photo") else True
267
+        thumb_quality = thumbnail_quality if thumbnail_quality in  f["thumbnail_status"] else "small"
268
+        thumb_url = ps.get_thumb_url(f["id"],thumb_quality)
269
+        data2 = prefix+f["id"]
270
+        item = xbmcgui.ListItem(label, label2, path=data2)
271
+        item.setArt({
272
+            "thumb": thumb_url,
273
+            "icon": thumb_url,
274
+            "fanart": thumb_url,
275
+        })
276
+        item.setLabel2(label2)
277
+        item.setInfo(
278
+            'video', {
279
+                "title": label,
280
+                "plot": f["additional"]["file_location"],
281
+                #TODO
282
+            }
283
+        )
284
+        if video_quality == "original":
285
+            quality_id = ""
286
+        else:
287
+            quality_id = f["additional"]["video_quality"][0]["id"]
288
+        data2 = ps.get_video_url(oid2, quality_id)
289
+        #data2 = urllib.quote(data2, ":/")
290
+        item.setProperty("is_folder", "")
291
+        item.setProperty('IsPlayable', 'true')
292
+
293
+        #item.setPath(data2)
294
+        item.setProperty("url", data2)
295
+        playlist.add(data2, item)
296
+        i += 1
297
+
298
+    xbmc.Player().play(playlist, startpos=pos)
299
+
300
+
167 301
 def play_video(streams):
168 302
     stream = streams[0]
169 303
     subfiles = []
@@ -171,8 +305,13 @@ def play_video(streams):
171 305
     item = ListItem(label=stream["name"], thumbnail=stream["img"], path=stream["url"])
172 306
     item.set_info("video",{"plot":stream["desc"]})
173 307
     item.is_folder = False
174
-    item.set_is_playable(True)
175
-    plugin.play_video(item)
308
+    #item.set_is_playable(True)
309
+    #plugin.play_video(item)
310
+    item2 = xbmcgui.ListItem("label", "label2", path=stream["url"])
311
+    item2.setProperty('IsPlayable', 'true')
312
+    xbmc.Player().play(item=stream["url"], listitem=item2)
313
+    #xbmcplugin.setResolvedUrl(plugin.handle, True, listitem=item2)
314
+
176 315
 
177 316
 
178 317
 if __name__ == '__main__':

+ 1
- 1
addon.xml View File

@@ -1,5 +1,5 @@
1 1
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
-<addon version="0.1.7" id="plugin.image.photostation" name="PhotoStation" provider-name="ivars777"  >
2
+<addon version="0.1.15" id="plugin.image.photostation" name="PhotoStation" provider-name="ivars777"  >
3 3
   <requires>
4 4
     <import addon="xbmc.python" version="2.1.0"/>
5 5
     <import addon="script.module.requests" />

+ 6
- 2
changelog.md View File

@@ -1,5 +1,9 @@
1
+**0.1.8** (20.05.2018):
2
+- addon settings added
3
+
4
+**0.1.5** (14.02.2017):
5
+- addon settings added
6
+
1 7
 **0.1.1** (12.02.2017):
2 8
 - initial exprerimental version
3 9
 
4
-**0.1.5** (14.02.2016):
5
-- addon settings added

+ 5
- 2
kmake.bat View File

@@ -19,7 +19,7 @@ set desc=Play Synology PhotoStation media
19 19
 set ipk_dir=ipkg\
20 20
 set release_dir=release\
21 21
 set repo_dir=..\repo\
22
-set feed_dir=w:\repo\
22
+set feed_dir=q:\web\repo\
23 23
 
24 24
 set AR=\MinGW\bin\ar.exe
25 25
 set TAR=\MinGW\msys\1.0\bin\tar.exe
@@ -56,6 +56,7 @@ copy  %release_dir%%pack_name%-%ver%.zip  %repo_dir%%pack_name%\%pack_name%-%ver
56 56
 python -c "import hashlib; print hashlib.md5(open(r'%repo_dir%%pack_name%\%pack_name%-%ver%.zip','r').read()).hexdigest()" >%repo_dir%%pack_name%\%pack_name%-%ver%.zip.md5
57 57
 
58 58
 git add %release_dir%%pack_name%-%ver%.zip
59
+rm -r -f "%pack_name%"
59 60
 
60 61
 if not ()==(%1%) (
61 62
     git commit -m %ver%
@@ -65,7 +66,9 @@ if not ()==(%1%) (
65 66
 
66 67
     pushd  %repo_dir%..
67 68
     call update_repo.bat
68
-    xcopy /s /y repo %feed_dir%
69
+    rem xcopy /s /y /u repo %feed_dir%
70
+    robocopy repo %feed_dir%  addons.* /copy:dat
71
+    robocopy repo\%pack_name% q:\web\repo\%pack_name% /copy:DAT /xo
69 72
     popd
70 73
 )
71 74
 pause

+ 1
- 1
kodiswift/plugin.py View File

@@ -350,7 +350,7 @@ class Plugin(XBMCMixin):
350 350
         # url as well
351 351
         if url is None:
352 352
             url = sys.argv[0]
353
-            if len(sys.argv) == 3:
353
+            if len(sys.argv) >= 3:
354 354
                 url += sys.argv[2]
355 355
         if handle is None:
356 356
             handle = sys.argv[1]

+ 379
- 355
project.wpr View File

@@ -52,11 +52,27 @@ proj.launch-config = {loc('../../../../Python27/Lib/site-packages/xbmcswift2/plu
52 52
                                        (u'run interactive',
53 53
         ''))}
54 54
 [user attributes]
55
-debug.breakpoints = {loc('addon.py'): {3L: (0,
55
+debug.breakpoints = {loc('addon.py'): {15L: (0,
56 56
         None,
57 57
         1,
58 58
         0),
59
-                                       120L: (0,
59
+                                       131L: (0,
60
+        None,
61
+        1,
62
+        0),
63
+                                       140L: (0,
64
+        None,
65
+        1,
66
+        0),
67
+                                       185L: (0,
68
+        None,
69
+        1,
70
+        0),
71
+                                       302L: (0,
72
+        None,
73
+        1,
74
+        0),
75
+                                       307L: (0,
60 76
         None,
61 77
         1,
62 78
         0)},
@@ -84,27 +100,11 @@ debug.breakpoints = {loc('addon.py'): {3L: (0,
84 100
         None,
85 101
         1,
86 102
         0)},
87
-                     loc('kodiswift/xbmcmixin.py'): {357L: (0,
88
-        None,
89
-        1,
90
-        0),
91
-        373L: (0,
92
-               None,
93
-               1,
94
-               0),
95
-        375L: (0,
96
-               None,
97
-               1,
98
-               0)},
99
-                     loc('resources/lib/photostation_api.py'): {200L: (0,
103
+                     loc('resources/lib/photostation_api.py'): {380L: (0,
100 104
         None,
101 105
         1,
102 106
         0),
103
-        216: (0,
104
-              None,
105
-              1,
106
-              0),
107
-        228L: (0,
107
+        403L: (0,
108 108
                None,
109 109
                1,
110 110
                0)},
@@ -132,11 +132,11 @@ debug.breakpoints = {loc('addon.py'): {3L: (0,
132 132
             None,
133 133
             1,
134 134
             0)},
135
-                     loc('unknown:<untitled> #1'): {2: (0,
135
+                     loc('unknown:<untitled> #1'): {10: (0,
136 136
         None,
137 137
         1,
138 138
         0)},
139
-                     loc('unknown:<untitled> #2'): {10: (0,
139
+                     loc('unknown:<untitled> #2'): {2: (0,
140 140
         None,
141 141
         1,
142 142
         0)}}
@@ -199,19 +199,19 @@ debug.recent-run-args = {loc('../../../../Python27/Lib/site-packages/xbmcswift2/
199 199
                          loc('run.py'): [u'run interactive'],
200 200
                          loc('run2.py'): [u'run interactive']}
201 201
 debug.run-args = {}
202
-debug.var-col-widths = [0.41872791519434627,
203
-                        0.5812720848056537]
202
+debug.var-col-widths = [0.5823244552058111,
203
+                        0.4176755447941889]
204 204
 guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
205 205
                             'windows': [{'name': 'F8FpRDICw7YHXG3HV2rBc63asU'\
206 206
         'LBT7JH',
207
-        'size-state': 'maximized',
207
+        'size-state': '',
208 208
         'type': 'dock',
209 209
         'view': {'area': 'tall',
210 210
                  'constraint': None,
211 211
                  'current_pages': [0,
212 212
                                    1],
213 213
                  'full-screen': False,
214
-                 'notebook_display': 'normal',
214
+                 'notebook_display': 'tabs only',
215 215
                  'notebook_percent': 0.2797173732335827,
216 216
                  'override_title': None,
217 217
                  'pagelist': [('project',
@@ -220,18 +220,8 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
220 220
                                {'tree-state': {'file-sort-method': 'by name',
221 221
         'list-files-first': 0,
222 222
         'tree-states': {'deep': {'expanded-nodes': [(0,),
223
-        (5,),
224
-        (5,
225
-         0),
226
-        (5,
227
-         0,
228
-         0),
229
-        (5,
230
-         1)],
231
-                                 'selected-nodes': [(5,
232
-        0,
233
-        0,
234
-        0)],
223
+        (7,)],
224
+                                 'selected-nodes': [],
235 225
                                  'top-node': (0,)}},
236 226
         'tree-style': 'deep'}}),
237 227
                               ('snippets',
@@ -637,18 +627,18 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
637 627
         'top-node': [('generic attribute',
638 628
                       loc('../../../Python27/Lib/site-packages/win32com/client/dynamic.py'),
639 629
                       'ALL_INVOKE_TYPES')]},
640
-        loc('unknown:<untitled> #5'): {'column-widths': [1.0],
641
-                                       'expanded-nodes': [],
630
+        loc('unknown:<untitled> #3'): {'expanded-nodes': [],
642 631
                                        'selected-nodes': [],
643 632
                                        'top-node': None},
644
-        loc('unknown:<untitled> #6'): {'expanded-nodes': [],
633
+        loc('unknown:<untitled> #4'): {'column-widths': [1.0],
634
+                                       'expanded-nodes': [],
645 635
                                        'selected-nodes': [],
646 636
                                        'top-node': None},
647
-        loc('unknown:<untitled> #4'): {'column-widths': [1.0],
637
+        loc('unknown:<untitled> #6'): {'column-widths': [1.0],
648 638
                                        'expanded-nodes': [],
649 639
                                        'selected-nodes': [],
650 640
                                        'top-node': None},
651
-        loc('unknown:<untitled> #3'): {'expanded-nodes': [],
641
+        loc('unknown:<untitled> #5'): {'expanded-nodes': [],
652 642
                                        'selected-nodes': [],
653 643
                                        'top-node': None}},
654 644
                                 'browse_mode': u'Current Module',
@@ -678,7 +668,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
678 668
         'current_pages': [3,
679 669
                           1],
680 670
         'notebook_display': 'normal',
681
-        'notebook_percent': 0.4243394715772618,
671
+        'notebook_percent': 0.40883534136546185,
682 672
         'override_title': None,
683 673
         'pagelist': [('debug-breakpoints',
684 674
                       'wide',
@@ -707,7 +697,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
707 697
                                        'fRegexFlags': 46,
708 698
                                        'fReplaceText': '',
709 699
                                        'fReverse': False,
710
-                                       'fSearchText': u'next',
700
+                                       'fSearchText': u'page',
711 701
                                        'fStartPos': 0,
712 702
                                        'fStyle': 'text',
713 703
                                        'fWholeWords': False,
@@ -777,18 +767,21 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
777 767
         -1,
778 768
         -1),
779 769
                        'attrib-starts': [],
780
-                       'first-line': 6L,
770
+                       'first-line': 22L,
781 771
                        'folded-linenos': [],
782
-                       'history': {None: ['plugin.get_setting("picture_quali'\
783
-        'ty", str)\n',
784
-        'plugin.get_setting("video_quality")\n',
785
-        'plugin.get_setting("picture_quality")\n',
786
-        'len(content)\n']},
772
+                       'history': {None: ['plugin.request\n',
773
+        'plugin.request.url\n',
774
+        'plugin.request.path\n',
775
+        'plugin.request.query_string\n',
776
+        'sys.argv\n',
777
+        'sys.argv[0]\n',
778
+        'sys.argv[2]\n',
779
+        'len(sys.argv)\n']},
787 780
                        'launch-id': None,
788
-                       'sel-line': 16L,
789
-                       'sel-line-start': 320L,
790
-                       'selection_end': 320L,
791
-                       'selection_start': 320L,
781
+                       'sel-line': 31L,
782
+                       'sel-line-start': 866L,
783
+                       'selection_end': 866L,
784
+                       'selection_start': 866L,
792 785
                        'zoom': 0L}),
793 786
                      ('debug-watch',
794 787
                       'wide',
@@ -796,26 +789,20 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
796 789
                       {'node-states': [('eval',
797 790
         u'js'),
798 791
                                        ('eval',
799
-        u'item2'),
792
+        u'ps'),
800 793
                                        ('eval',
801
-        u'f')],
794
+        u'f'),
795
+                                       ('eval',
796
+        u'content'),
797
+                                       ('eval',
798
+        u'items')],
802 799
                        'tree-state': {'expanded-nodes': [],
803
-                                      'selected-nodes': [(0,)],
800
+                                      'selected-nodes': [(4,)],
804 801
                                       'top-node': (0,)}}),
805 802
                      ('messages',
806 803
                       'wide',
807 804
                       2,
808 805
                       {'current-domain': 0}),
809
-                     ('debug-modules',
810
-                      'wide',
811
-                      1,
812
-                      {}),
813
-                     ('os-command',
814
-                      'wide',
815
-                      1,
816
-                      {'last-percent': 0.8,
817
-                       'toolbox-percent': 1.0,
818
-                       'toolbox-tree-sel': ''}),
819 806
                      ('python-shell',
820 807
                       'wide',
821 808
                       2,
@@ -831,266 +818,276 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
831 818
                        'sel-line-start': 174L,
832 819
                        'selection_end': 174L,
833 820
                        'selection_start': 174L,
834
-                       'zoom': 0L})],
821
+                       'zoom': 0L}),
822
+                     ('debug-modules',
823
+                      'wide',
824
+                      1,
825
+                      {}),
826
+                     ('os-command',
827
+                      'wide',
828
+                      1,
829
+                      {'last-percent': 0.8,
830
+                       'toolbox-percent': 1.0,
831
+                       'toolbox-tree-sel': ''})],
835 832
         'primary_view_state': {'editor_states': ('horizontal',
836 833
         1.0,
837
-        ({'bookmarks': ([[loc('resources/lib/photostation_api.py'),
838
-                          {'attrib-starts': [('PhotoStationAPI',
839
-        7),
840
-        ('PhotoStationAPI._check_url',
841
-         198)],
842
-                           'first-line': 192L,
843
-                           'folded-linenos': [],
844
-                           'sel-line': 203L,
845
-                           'sel-line-start': 9529L,
846
-                           'selection_end': 9529L,
847
-                           'selection_start': 9529L,
834
+        ({'bookmarks': ([[loc('addon.py'),
835
+                          {'attrib-starts': [('main',
836
+        37)],
837
+                           'first-line': 43L,
838
+                           'folded-linenos': [228L],
839
+                           'sel-line': 52L,
840
+                           'sel-line-start': 1782L,
841
+                           'selection_end': 1798L,
842
+                           'selection_start': 1794L,
848 843
                            'zoom': 0L},
849
-                          1516922377.77],
844
+                          1531953967.139],
850 845
                          [loc('addon.py'),
851
-                          {'attrib-starts': [],
852
-                           'first-line': 18L,
853
-                           'folded-linenos': [134L],
854
-                           'sel-line': 21L,
855
-                           'sel-line-start': 685L,
856
-                           'selection_end': 745L,
857
-                           'selection_start': 703L,
858
-                           'zoom': 0L},
859
-                          1516922637.041],
860
-                         [loc('resources/settings.xml'),
861
-                          {'attrib-starts': [],
862
-                           'first-line': 0L,
863
-                           'folded-linenos': [],
864
-                           'sel-line': 10L,
865
-                           'sel-line-start': 849L,
866
-                           'selection_end': 878L,
867
-                           'selection_start': 873L,
846
+                          {'attrib-starts': [('main',
847
+        37)],
848
+                           'first-line': 43L,
849
+                           'folded-linenos': [228L],
850
+                           'sel-line': 53L,
851
+                           'sel-line-start': 1807L,
852
+                           'selection_end': 1819L,
853
+                           'selection_start': 1815L,
868 854
                            'zoom': 0L},
869
-                          1516922728.157],
870
-                         [loc('resources/settings.xml'),
871
-                          {'attrib-starts': [],
872
-                           'first-line': 2L,
873
-                           'folded-linenos': [],
874
-                           'sel-line': 10L,
875
-                           'sel-line-start': 849L,
876
-                           'selection_end': 899L,
877
-                           'selection_start': 884L,
855
+                          1531953967.755],
856
+                         [loc('addon.py'),
857
+                          {'attrib-starts': [('main',
858
+        37)],
859
+                           'first-line': 43L,
860
+                           'folded-linenos': [228L],
861
+                           'sel-line': 55L,
862
+                           'sel-line-start': 1834L,
863
+                           'selection_end': 1846L,
864
+                           'selection_start': 1842L,
878 865
                            'zoom': 0L},
879
-                          1516922737.378],
880
-                         [loc('resources/settings.xml'),
881
-                          {'attrib-starts': [],
882
-                           'first-line': 2L,
883
-                           'folded-linenos': [],
884
-                           'sel-line': 11L,
885
-                           'sel-line-start': 966L,
886
-                           'selection_end': 1017L,
887
-                           'selection_start': 1017L,
866
+                          1531953968.128],
867
+                         [loc('addon.py'),
868
+                          {'attrib-starts': [('main',
869
+        37)],
870
+                           'first-line': 43L,
871
+                           'folded-linenos': [228L],
872
+                           'sel-line': 55L,
873
+                           'sel-line-start': 1834L,
874
+                           'selection_end': 1861L,
875
+                           'selection_start': 1857L,
888 876
                            'zoom': 0L},
889
-                          1516923005.027],
877
+                          1531953968.496],
890 878
                          [loc('addon.py'),
891
-                          {'attrib-starts': [],
892
-                           'first-line': 13L,
893
-                           'folded-linenos': [134L],
894
-                           'sel-line': 23L,
895
-                           'sel-line-start': 749L,
896
-                           'selection_end': 749L,
897
-                           'selection_start': 749L,
879
+                          {'attrib-starts': [('main',
880
+        37)],
881
+                           'first-line': 66L,
882
+                           'folded-linenos': [228L],
883
+                           'sel-line': 75L,
884
+                           'sel-line-start': 2620L,
885
+                           'selection_end': 2634L,
886
+                           'selection_start': 2628L,
898 887
                            'zoom': 0L},
899
-                          1516923078.023],
900
-                         [loc('resources/settings.xml'),
901
-                          {'attrib-starts': [],
902
-                           'first-line': 2L,
903
-                           'folded-linenos': [],
904
-                           'sel-line': 10L,
905
-                           'sel-line-start': 849L,
906
-                           'selection_end': 899L,
907
-                           'selection_start': 899L,
888
+                          1531953988.159],
889
+                         [loc('addon.py'),
890
+                          {'attrib-starts': [('main',
891
+        37)],
892
+                           'first-line': 66L,
893
+                           'folded-linenos': [228L],
894
+                           'sel-line': 75L,
895
+                           'sel-line-start': 2620L,
896
+                           'selection_end': 2646L,
897
+                           'selection_start': 2642L,
908 898
                            'zoom': 0L},
909
-                          1516923107.786],
899
+                          1531953988.55],
910 900
                          [loc('addon.py'),
911 901
                           {'attrib-starts': [('main',
912
-        32)],
913
-                           'first-line': 49L,
914
-                           'folded-linenos': [134L],
915
-                           'sel-line': 57L,
916
-                           'sel-line-start': 1733L,
917
-                           'selection_end': 1768L,
918
-                           'selection_start': 1754L,
902
+        37)],
903
+                           'first-line': 66L,
904
+                           'folded-linenos': [228L],
905
+                           'sel-line': 75L,
906
+                           'sel-line-start': 2620L,
907
+                           'selection_end': 2668L,
908
+                           'selection_start': 2664L,
919 909
                            'zoom': 0L},
920
-                          1516923380.562],
921
-                         [loc('resources/lib/photostation_api.py'),
922
-                          {'attrib-starts': [('PhotoStationAPI',
923
-        7),
924
-        ('PhotoStationAPI.get_album_list',
925
-         33)],
926
-                           'first-line': 27L,
927
-                           'folded-linenos': [],
928
-                           'sel-line': 33L,
929
-                           'sel-line-start': 988L,
930
-                           'selection_end': 1026L,
931
-                           'selection_start': 1018L,
910
+                          1531953988.847],
911
+                         [loc('addon.py'),
912
+                          {'attrib-starts': [('main',
913
+        37)],
914
+                           'first-line': 66L,
915
+                           'folded-linenos': [228L],
916
+                           'sel-line': 75L,
917
+                           'sel-line-start': 2620L,
918
+                           'selection_end': 2680L,
919
+                           'selection_start': 2676L,
932 920
                            'zoom': 0L},
933
-                          1516923420.879],
921
+                          1531953989.142],
934 922
                          [loc('addon.py'),
935 923
                           {'attrib-starts': [('main',
936
-        32)],
937
-                           'first-line': 49L,
938
-                           'folded-linenos': [134L],
939
-                           'sel-line': 57L,
940
-                           'sel-line-start': 1733L,
941
-                           'selection_end': 1773L,
942
-                           'selection_start': 1769L,
924
+        37)],
925
+                           'first-line': 66L,
926
+                           'folded-linenos': [228L],
927
+                           'sel-line': 76L,
928
+                           'sel-line-start': 2686L,
929
+                           'selection_end': 2712L,
930
+                           'selection_start': 2708L,
943 931
                            'zoom': 0L},
944
-                          1516923434.323],
945
-                         [loc('resources/lib/photostation_api.py'),
946
-                          {'attrib-starts': [('PhotoStationAPI',
947
-        7),
948
-        ('PhotoStationAPI.get_album_list',
949
-         33)],
950
-                           'first-line': 27L,
951
-                           'folded-linenos': [],
952
-                           'sel-line': 34L,
953
-                           'sel-line-start': 1032L,
954
-                           'selection_end': 1070L,
955
-                           'selection_start': 1065L,
932
+                          1531953989.451],
933
+                         [loc('addon.py'),
934
+                          {'attrib-starts': [('main',
935
+        37)],
936
+                           'first-line': 66L,
937
+                           'folded-linenos': [228L],
938
+                           'sel-line': 76L,
939
+                           'sel-line-start': 2686L,
940
+                           'selection_end': 2733L,
941
+                           'selection_start': 2729L,
956 942
                            'zoom': 0L},
957
-                          1516923476.237],
943
+                          1531953989.779],
958 944
                          [loc('addon.py'),
959 945
                           {'attrib-starts': [('main',
960
-        32)],
961
-                           'first-line': 49L,
962
-                           'folded-linenos': [133L],
963
-                           'sel-line': 55L,
964
-                           'sel-line-start': 1677L,
965
-                           'selection_end': 1694L,
966
-                           'selection_start': 1694L,
946
+        37)],
947
+                           'first-line': 153L,
948
+                           'folded-linenos': [228L],
949
+                           'sel-line': 165L,
950
+                           'sel-line-start': 7294L,
951
+                           'selection_end': 7309L,
952
+                           'selection_start': 7305L,
967 953
                            'zoom': 0L},
968
-                          1516923530.207],
969
-                         [loc('resources/settings.xml'),
954
+                          1531953991.372],
955
+                         [loc('addon.py'),
970 956
                           {'attrib-starts': [],
971
-                           'first-line': 2L,
972
-                           'folded-linenos': [],
973
-                           'sel-line': 2L,
974
-                           'sel-line-start': 69L,
975
-                           'selection_end': 71L,
976
-                           'selection_start': 69L,
957
+                           'first-line': 310L,
958
+                           'folded-linenos': [228L],
959
+                           'sel-line': 321L,
960
+                           'sel-line-start': 12716L,
961
+                           'selection_end': 12716L,
962
+                           'selection_start': 12716L,
977 963
                            'zoom': 0L},
978
-                          1516923564.218],
979
-                         [loc('addon.py'),
980
-                          {'attrib-starts': [('main',
981
-        33)],
982
-                           'first-line': 41L,
983
-                           'folded-linenos': [134L],
984
-                           'sel-line': 56L,
985
-                           'sel-line-start': 1735L,
986
-                           'selection_end': 1748L,
987
-                           'selection_start': 1743L,
964
+                          1531954130.795],
965
+                         [loc('kodiswift/plugin.py'),
966
+                          {'attrib-starts': [('Plugin',
967
+        27),
968
+        ('Plugin._parse_request',
969
+         341)],
970
+                           'first-line': 347L,
971
+                           'folded-linenos': [],
972
+                           'sel-line': 356L,
973
+                           'sel-line-start': 13246L,
974
+                           'selection_end': 13246L,
975
+                           'selection_start': 13246L,
988 976
                            'zoom': 0L},
989
-                          1516924026.579],
990
-                         [loc('resources/lib/photostation_api.py'),
991
-                          {'attrib-starts': [('PhotoStationAPI',
992
-        7),
993
-        ('PhotoStationAPI.get_album_list',
994
-         33)],
995
-                           'first-line': 27L,
977
+                          1531954225.148],
978
+                         [loc('kodiswift/request.py'),
979
+                          {'attrib-starts': [('Request',
980
+        20),
981
+        ('Request.__init__',
982
+         22)],
983
+                           'first-line': 16L,
996 984
                            'folded-linenos': [],
997
-                           'sel-line': 34L,
998
-                           'sel-line-start': 1032L,
999
-                           'selection_end': 1070L,
1000
-                           'selection_start': 1065L,
985
+                           'sel-line': 37L,
986
+                           'sel-line-start': 1056L,
987
+                           'selection_end': 1056L,
988
+                           'selection_start': 1056L,
1001 989
                            'zoom': 0L},
1002
-                          1516924067.572],
990
+                          1531954245.475],
1003 991
                          [loc('addon.py'),
1004
-                          {'attrib-starts': [('main',
1005
-        32)],
1006
-                           'first-line': 62L,
1007
-                           'folded-linenos': [142L],
1008
-                           'sel-line': 118L,
1009
-                           'sel-line-start': 4962L,
1010
-                           'selection_end': 4962L,
1011
-                           'selection_start': 4962L,
992
+                          {'attrib-starts': [],
993
+                           'first-line': 309L,
994
+                           'folded-linenos': [228L],
995
+                           'sel-line': 321L,
996
+                           'sel-line-start': 12716L,
997
+                           'selection_end': 12716L,
998
+                           'selection_start': 12716L,
1012 999
                            'zoom': 0L},
1013
-                          1516926293.565],
1014
-                         [loc('kodiswift/xbmcmixin.py'),
1015
-                          {'attrib-starts': [('XBMCMixin',
1016
-        21),
1017
-        ('XBMCMixin.set_resolved_url',
1018
-         340)],
1019
-                           'first-line': 365L,
1000
+                          1531954266.378],
1001
+                         [loc('kodiswift/plugin.py'),
1002
+                          {'attrib-starts': [('Plugin',
1003
+        27),
1004
+        ('Plugin._parse_request',
1005
+         341)],
1006
+                           'first-line': 342L,
1020 1007
                            'folded-linenos': [],
1021
-                           'sel-line': 374L,
1022
-                           'sel-line-start': 15799L,
1023
-                           'selection_end': 15854L,
1024
-                           'selection_start': 15854L,
1008
+                           'sel-line': 352L,
1009
+                           'sel-line-start': 13112L,
1010
+                           'selection_end': 13143L,
1011
+                           'selection_start': 13143L,
1025 1012
                            'zoom': 0L},
1026
-                          1516926360.838],
1013
+                          1531954319.585],
1027 1014
                          [loc('addon.py'),
1028
-                          {'attrib-starts': [('main',
1029
-        32)],
1030
-                           'first-line': 42L,
1031
-                           'folded-linenos': [142L],
1032
-                           'sel-line': 47L,
1033
-                           'sel-line-start': 1560L,
1034
-                           'selection_end': 1584L,
1035
-                           'selection_start': 1584L,
1036
-                           'zoom': 0L},
1037
-                          1516927419.315],
1038
-                         [loc('addon.py'),
1039
-                          {'attrib-starts': [('main',
1040
-        32)],
1041
-                           'first-line': 107L,
1042
-                           'folded-linenos': [],
1043
-                           'sel-line': 113L,
1044
-                           'sel-line-start': 4646L,
1045
-                           'selection_end': 4646L,
1046
-                           'selection_start': 4646L,
1015
+                          {'attrib-starts': [],
1016
+                           'first-line': 309L,
1017
+                           'folded-linenos': [228L],
1018
+                           'sel-line': 321L,
1019
+                           'sel-line-start': 12716L,
1020
+                           'selection_end': 12716L,
1021
+                           'selection_start': 12716L,
1047 1022
                            'zoom': 0L},
1048
-                          1516927851.25],
1023
+                          1531954326.398],
1049 1024
                          [loc('kodiswift/plugin.py'),
1050 1025
                           {'attrib-starts': [('Plugin',
1051 1026
         27),
1052
-        ('Plugin._dispatch',
1053
-         318)],
1054
-                           'first-line': 305L,
1027
+        ('Plugin._parse_request',
1028
+         341)],
1029
+                           'first-line': 347L,
1030
+                           'folded-linenos': [],
1031
+                           'sel-line': 356L,
1032
+                           'sel-line-start': 13246L,
1033
+                           'selection_end': 13246L,
1034
+                           'selection_start': 13246L,
1035
+                           'zoom': 0L},
1036
+                          1531954347.816],
1037
+                         [loc('kodiswift/request.py'),
1038
+                          {'attrib-starts': [('Request',
1039
+        20),
1040
+        ('Request.__init__',
1041
+         22)],
1042
+                           'first-line': 33L,
1055 1043
                            'folded-linenos': [],
1056
-                           'sel-line': 325L,
1057
-                           'sel-line-start': 12001L,
1058
-                           'selection_end': 12040L,
1059
-                           'selection_start': 12040L,
1044
+                           'sel-line': 45L,
1045
+                           'sel-line-start': 1422L,
1046
+                           'selection_end': 1422L,
1047
+                           'selection_start': 1422L,
1048
+                           'zoom': 0L},
1049
+                          1531954379.77],
1050
+                         [loc('addon.py'),
1051
+                          {'attrib-starts': [],
1052
+                           'first-line': 9L,
1053
+                           'folded-linenos': [228L],
1054
+                           'sel-line': 14L,
1055
+                           'sel-line-start': 384L,
1056
+                           'selection_end': 384L,
1057
+                           'selection_start': 384L,
1060 1058
                            'zoom': 0L},
1061
-                          1516927872.463]],
1059
+                          1531954540.55]],
1062 1060
                         20),
1063
-          'current-loc': loc('addon.py'),
1061
+          'current-loc': loc('addon.xml'),
1064 1062
           'editor-state-list': [(loc('addon.xml'),
1065 1063
                                  {'attrib-starts': [],
1066 1064
                                   'first-line': 0L,
1067 1065
                                   'folded-linenos': [],
1068
-                                  'sel-line': 8L,
1069
-                                  'sel-line-start': 402L,
1070
-                                  'selection_end': 421L,
1071
-                                  'selection_start': 421L,
1066
+                                  'sel-line': 1L,
1067
+                                  'sel-line-start': 57L,
1068
+                                  'selection_end': 79L,
1069
+                                  'selection_start': 79L,
1072 1070
                                   'zoom': 0L}),
1073 1071
                                 (loc('addon.py'),
1074
-                                 {'attrib-starts': [('main',
1075
-        32)],
1076
-                                  'first-line': 106L,
1077
-                                  'folded-linenos': [],
1078
-                                  'sel-line': 114L,
1079
-                                  'sel-line-start': 4696L,
1080
-                                  'selection_end': 4696L,
1081
-                                  'selection_start': 4696L,
1072
+                                 {'attrib-starts': [],
1073
+                                  'first-line': 9L,
1074
+                                  'folded-linenos': [228L],
1075
+                                  'sel-line': 14L,
1076
+                                  'sel-line-start': 384L,
1077
+                                  'selection_end': 384L,
1078
+                                  'selection_start': 384L,
1082 1079
                                   'zoom': 0L}),
1083 1080
                                 (loc('resources/lib/photostation_api.py'),
1084 1081
                                  {'attrib-starts': [('PhotoStationAPI',
1085 1082
         7),
1086
-        ('PhotoStationAPI.get_album_list',
1087
-         33)],
1088
-                                  'first-line': 27L,
1083
+        ('PhotoStationAPI.get_category_list',
1084
+         98)],
1085
+                                  'first-line': 92L,
1089 1086
                                   'folded-linenos': [],
1090
-                                  'sel-line': 34L,
1091
-                                  'sel-line-start': 1032L,
1092
-                                  'selection_end': 1070L,
1093
-                                  'selection_start': 1065L,
1087
+                                  'sel-line': 104L,
1088
+                                  'sel-line-start': 5012L,
1089
+                                  'selection_end': 5012L,
1090
+                                  'selection_start': 5012L,
1094 1091
                                   'zoom': 0L}),
1095 1092
                                 (loc('changelog.md'),
1096 1093
                                  {'attrib-starts': [],
@@ -1103,36 +1100,33 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1103 1100
                                   'zoom': 0L}),
1104 1101
                                 (loc('resources/settings.xml'),
1105 1102
                                  {'attrib-starts': [],
1106
-                                  'first-line': 2L,
1103
+                                  'first-line': 0L,
1107 1104
                                   'folded-linenos': [],
1108
-                                  'sel-line': 2L,
1109
-                                  'sel-line-start': 69L,
1110
-                                  'selection_end': 71L,
1111
-                                  'selection_start': 69L,
1105
+                                  'sel-line': 13L,
1106
+                                  'sel-line-start': 1171L,
1107
+                                  'selection_end': 1171L,
1108
+                                  'selection_start': 1171L,
1112 1109
                                   'zoom': 0L}),
1113 1110
                                 (loc('kodiswift/listitem.py'),
1114
-                                 {'attrib-starts': [('ListItem',
1115
-        20),
1116
-        ('ListItem.__eq__',
1117
-         325)],
1118
-                                  'first-line': 310L,
1111
+                                 {'attrib-starts': [],
1112
+                                  'first-line': 0L,
1119 1113
                                   'folded-linenos': [],
1120
-                                  'sel-line': 327L,
1121
-                                  'sel-line-start': 10428L,
1122
-                                  'selection_end': 10428L,
1123
-                                  'selection_start': 10428L,
1114
+                                  'sel-line': 0L,
1115
+                                  'sel-line-start': 0L,
1116
+                                  'selection_end': 28L,
1117
+                                  'selection_start': 0L,
1124 1118
                                   'zoom': 0L}),
1125 1119
                                 (loc('kodiswift/xbmcmixin.py'),
1126 1120
                                  {'attrib-starts': [('XBMCMixin',
1127 1121
         21),
1128
-        ('XBMCMixin.set_resolved_url',
1129
-         340)],
1130
-                                  'first-line': 365L,
1122
+        ('XBMCMixin._listitemify',
1123
+         531)],
1124
+                                  'first-line': 532L,
1131 1125
                                   'folded-linenos': [],
1132
-                                  'sel-line': 374L,
1133
-                                  'sel-line-start': 15799L,
1134
-                                  'selection_end': 15854L,
1135
-                                  'selection_start': 15854L,
1126
+                                  'sel-line': 543L,
1127
+                                  'sel-line-start': 23072L,
1128
+                                  'selection_end': 23119L,
1129
+                                  'selection_start': 23110L,
1136 1130
                                   'zoom': 0L}),
1137 1131
                                 (loc('kodiswift/mockxbmc/xbmcgui.py'),
1138 1132
                                  {'attrib-starts': [('ListItem',
@@ -1158,24 +1152,24 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1158 1152
                                   'zoom': 0L}),
1159 1153
                                 (loc('resources/language/English/strings.xml'),
1160 1154
                                  {'attrib-starts': [],
1161
-                                  'first-line': 5L,
1155
+                                  'first-line': 15L,
1162 1156
                                   'folded-linenos': [],
1163
-                                  'sel-line': 18L,
1164
-                                  'sel-line-start': 647L,
1165
-                                  'selection_end': 666L,
1166
-                                  'selection_start': 661L,
1157
+                                  'sel-line': 21L,
1158
+                                  'sel-line-start': 785L,
1159
+                                  'selection_end': 785L,
1160
+                                  'selection_start': 785L,
1167 1161
                                   'zoom': 0L}),
1168 1162
                                 (loc('kodiswift/plugin.py'),
1169 1163
                                  {'attrib-starts': [('Plugin',
1170 1164
         27),
1171
-        ('Plugin._dispatch',
1172
-         318)],
1173
-                                  'first-line': 305L,
1165
+        ('Plugin._parse_request',
1166
+         341)],
1167
+                                  'first-line': 347L,
1174 1168
                                   'folded-linenos': [],
1175
-                                  'sel-line': 325L,
1176
-                                  'sel-line-start': 12001L,
1177
-                                  'selection_end': 12040L,
1178
-                                  'selection_start': 12040L,
1169
+                                  'sel-line': 356L,
1170
+                                  'sel-line-start': 13246L,
1171
+                                  'selection_end': 13246L,
1172
+                                  'selection_start': 13246L,
1179 1173
                                   'zoom': 0L})],
1180 1174
           'has-focus': True,
1181 1175
           'locked': False},
@@ -1426,16 +1420,17 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1426 1420
           loc('settings.xml'),
1427 1421
           loc('../../../../Python27/Lib/site-packages/xbmcswift2/mockxbmc/xbmcgui.py'),
1428 1422
           loc('../../../../Python27/Lib/site-packages/kodiswift/listitem.py')])),
1429
-                               'open_files': [u'addon.xml',
1430
-        u'changelog.md',
1423
+                               'open_files': [u'changelog.md',
1431 1424
         u'kodiswift/cli/app.py',
1432 1425
         u'kodiswift/listitem.py',
1433 1426
         u'kodiswift/mockxbmc/xbmcgui.py',
1427
+        u'kodiswift/xbmcmixin.py',
1434 1428
         u'resources/language/English/strings.xml',
1435
-        u'resources/settings.xml',
1436 1429
         u'resources/lib/photostation_api.py',
1437
-        u'kodiswift/xbmcmixin.py',
1430
+        u'resources/settings.xml',
1431
+        u'kodiswift/plugin.py',
1438 1432
         u'addon.py',
1433
+        u'addon.xml',
1439 1434
         u'../../../../Python27/Lib/site-packages/kodiswift/listitem.py',
1440 1435
         u'../../../../Python27/Lib/site-packages/xbmcswift2/mockxbmc/xbmcgui.py',
1441 1436
         u'addon.py',
@@ -1444,7 +1439,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1444 1439
         u'resources/settings.xml',
1445 1440
         u'settings.xml']},
1446 1441
         'saved_notebook_display': None,
1447
-        'split_percents': {0: 0.5200166805671392},
1442
+        'split_percents': {0: 0.3710232158211522},
1448 1443
         'splits': 2,
1449 1444
         'tab_location': 'top',
1450 1445
         'user_data': {}},
@@ -1453,21 +1448,20 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1453 1448
                  'splits': 2,
1454 1449
                  'tab_location': 'left',
1455 1450
                  'user_data': {}},
1456
-        'window-alloc': (146,
1451
+        'window-alloc': (167,
1457 1452
                          0,
1458
-                         2414,
1459
-                         1440)}]}
1460
-guimgr.recent-documents = [loc('addon.py'),
1453
+                         2417,
1454
+                         1462)}]}
1455
+guimgr.recent-documents = [loc('addon.xml'),
1456
+                           loc('addon.py'),
1457
+                           loc('kodiswift/request.py'),
1461 1458
                            loc('kodiswift/plugin.py'),
1462
-                           loc('kodiswift/xbmcmixin.py'),
1463
-                           loc('resources/lib/photostation_api.py'),
1464 1459
                            loc('resources/settings.xml'),
1460
+                           loc('resources/lib/photostation_api.py'),
1461
+                           loc('changelog.md'),
1462
+                           loc('kodiswift/xbmcmixin.py'),
1465 1463
                            loc('resources/language/English/strings.xml'),
1466
-                           loc('kodiswift/cli/app.py'),
1467
-                           loc('kodiswift/listitem.py'),
1468
-                           loc('kodiswift/mockxbmc/xbmcgui.py'),
1469
-                           loc('addon.xml'),
1470
-                           loc('changelog.md')]
1464
+                           loc('kodiswift/listitem.py')]
1471 1465
 guimgr.visual-state = {loc('../../../../Python27/Lib/site-packages/kodiswift/listitem.py'): {'a'\
1472 1466
         'ttrib-starts': [],
1473 1467
         'first-line': 0L,
@@ -1496,14 +1490,6 @@ guimgr.visual-state = {loc('../../../../Python27/Lib/site-packages/kodiswift/lis
1496 1490
         'sel-line-start': 17420L,
1497 1491
         'selection_end': 17420L,
1498 1492
         'selection_start': 17420L},
1499
-                       loc('../../../../Python27/Lib/site-packages/pkg_resources/__init__.py'): {'a'\
1500
-        'ttrib-starts': [],
1501
-        'first-line': 0L,
1502
-        'folded-linenos': [],
1503
-        'sel-line': 2L,
1504
-        'sel-line-start': 20L,
1505
-        'selection_end': 40L,
1506
-        'selection_start': 40L},
1507 1493
                        loc('../../../../Python27/Lib/site-packages/xbmcswift2/cli/app.py'): {'a'\
1508 1494
         'ttrib-starts': [('once',
1509 1495
                           146)],
@@ -1557,6 +1543,14 @@ guimgr.visual-state = {loc('../../../../Python27/Lib/site-packages/kodiswift/lis
1557 1543
         'sel-line-start': 29,
1558 1544
         'selection_end': 36,
1559 1545
         'selection_start': 36},
1546
+                       loc('../../../../Python27/lib/site-packages/pkg_resources/__init__.py'): {'a'\
1547
+        'ttrib-starts': [],
1548
+        'first-line': 0L,
1549
+        'folded-linenos': [],
1550
+        'sel-line': 2L,
1551
+        'sel-line-start': 20L,
1552
+        'selection_end': 40L,
1553
+        'selection_start': 40L},
1560 1554
                        loc('addon.py'): {'attrib-starts': [('main',
1561 1555
         23)],
1562 1556
         'first-line': 92L,
@@ -1658,6 +1652,18 @@ guimgr.visual-state = {loc('../../../../Python27/Lib/site-packages/kodiswift/lis
1658 1652
         'sel-line-start': 92L,
1659 1653
         'selection_end': 101L,
1660 1654
         'selection_start': 95L,
1655
+        'zoom': 0L},
1656
+                       loc('plugin.image.photostation/resources/lib/photostation_api.py'): {'a'\
1657
+        'ttrib-starts': [('PhotoStationAPI',
1658
+                          7),
1659
+                         ('PhotoStationAPI.__init__',
1660
+                          9)],
1661
+        'first-line': 0L,
1662
+        'folded-linenos': [],
1663
+        'sel-line': 10L,
1664
+        'sel-line-start': 246L,
1665
+        'selection_end': 246L,
1666
+        'selection_start': 246L,
1661 1667
         'zoom': 0L},
1662 1668
                        loc('plugin.video.playstream/resources/lib/ContentSources.py'): {'a'\
1663 1669
         'ttrib-starts': [],
@@ -1704,6 +1710,24 @@ guimgr.visual-state = {loc('../../../../Python27/Lib/site-packages/kodiswift/lis
1704 1710
         'sel-line-start': 0L,
1705 1711
         'selection_end': 0L,
1706 1712
         'selection_start': 0L,
1713
+        'zoom': 0L},
1714
+                       loc('../plugin.video.playstream/download_service.py'): {'a'\
1715
+        'ttrib-starts': [],
1716
+        'first-line': 0L,
1717
+        'folded-linenos': [],
1718
+        'sel-line': 10L,
1719
+        'sel-line-start': 314L,
1720
+        'selection_end': 337L,
1721
+        'selection_start': 337L,
1722
+        'zoom': 0L},
1723
+                       loc('../script.module.twisted/lib/twisted/internet/ssl.py'): {'a'\
1724
+        'ttrib-starts': [],
1725
+        'first-line': 49L,
1726
+        'folded-linenos': [],
1727
+        'sel-line': 58L,
1728
+        'sel-line-start': 2524L,
1729
+        'selection_end': 2524L,
1730
+        'selection_start': 2524L,
1707 1731
         'zoom': 0L},
1708 1732
                        loc('../untitled-1.py'): {'attrib-starts': [],
1709 1733
         'first-line': 0,
@@ -1922,25 +1946,25 @@ proj.vcs-system-config = ('prefs',
1922 1946
                                    'versioncontrol.svn.extra-global-args': '',
1923 1947
                                    'versioncontrol.svn.svnadmin-executable': u'svnadmin'}})
1924 1948
 search.search-history = [u'(o',
1925
-                         u'picture_quality',
1926
-                         u'sort',
1927
-                         u'played',
1928
-                         u'get_player',
1929
-                         u'get_played',
1930
-                         u'item.',
1931
-                         u'add_sort_method',
1932
-                         u'_settings',
1933
-                         u'"desc',
1934
-                         u'setContent',
1935
-                         u'as_tuple',
1936
-                         u'add_items',
1937
-                         u'folder',
1938
-                         u'_listitem',
1939
-                         u'pictures',
1940
-                         u'info_type',
1941
-                         u'infola',
1942
-                         u'ListItem',
1943
-                         u'item']
1949
+                         u'page',
1950
+                         u'quote',
1951
+                         u'unquote',
1952
+                         u'next',
1953
+                         u'"video"',
1954
+                         u'_url =',
1955
+                         u'_url=',
1956
+                         u'img =',
1957
+                         u'data2 =',
1958
+                         u'keep',
1959
+                         u'call2',
1960
+                         u'label2',
1961
+                         u'playlist',
1962
+                         u'oid',
1963
+                         u'path=',
1964
+                         u'path',
1965
+                         u'set_con',
1966
+                         u'label',
1967
+                         u'qs']
1944 1968
 testing.stored-results = (1,
1945 1969
                           [],
1946 1970
                           {})

+ 2
- 0
resources/language/English/strings.xml View File

@@ -17,6 +17,8 @@
17 17
   <string id="50008">Slideshow repet</string>
18 18
   <string id="50009">Slideshow random</string>
19 19
   <string id="50010">Start page</string>
20
+  <string id="50011">Play next video</string>
21
+  <string id="50012">Thumbnail quality</string>
20 22
 
21 23
   <string id="50101">PhotoStation server url</string>
22 24
   <string id="50102">Username</string>

+ 213
- 37
resources/lib/photostation_api.py View File

@@ -1,8 +1,8 @@
1
+# -*- coding: utf-8 -*-
1 2
 import os,os.path
2 3
 import requests, urllib, urlparse
3 4
 import json
4 5
 
5
-
6 6
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
7 7
 
8 8
 class PhotoStationAPI():
@@ -18,13 +18,12 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
18 18
 Accept-Language: en-US,en;q=0.5
19 19
 Referer: %s/photo/
20 20
 """%ps_url)
21
+        self.api = self._call2("query.php", "api=SYNO.API.Info&method=query&version=1&query=all")
21 22
 
22 23
     def login(self,user,password):
23 24
         data = "api=SYNO.PhotoStation.Auth&method=login&version=1&username=%s&password=%s&remember_me=on"%(user,password)
24 25
         js = self._call2("auth.php",data)
25
-        if not js["success"]:
26
-            raise Exception("Can not login")
27
-        self.sid=js["data"]["sid"]
26
+        self.sid=js["sid"]
28 27
         self.user = user
29 28
         return self.sid
30 29
 
@@ -39,12 +38,7 @@ Referer: %s/photo/
39 38
                         ):
40 39
         data = "api=SYNO.PhotoStation.Album&method=list&version=1&offset=%s&limit=%s&recursive=false&type=album,photo,video&additional=%s&sort_direction=%s&sort_by=%s&ignore=thumbnail&id=%s"%(
41 40
             offset,limit,additional,sort_direction,sort_by,album_id)
42
-        js = self._call2("album.php",data)
43
-        if js["success"] and "data" in js:
44
-            return js["data"]
45
-        else:
46
-            raise Exception("Error reading album list")
47
-
41
+        return self._call2("album.php",data)
48 42
 
49 43
     def get_album_list2( self, album_id="",
50 44
                     offset=0,limit=-1,
@@ -91,26 +85,24 @@ Referer: %s/photo/
91 85
             ])
92 86
         return lst
93 87
 
88
+    def get_categories(self):
89
+        return self.call_api("Category", "list", offset=0, limit=120)
90
+
94 91
     def get_album_info(self,album_id=""):
95 92
         data = "id=%s&additional=album_sorting,item_count&api=SYNO.PhotoStation.Album&method=getinfo&version=1&ps_username=%s"%(
96 93
             album_id,self.user)
97
-        js = self._call2("album.php",data)
98
-        if js["success"] and "data" in js:
99
-            return js["data"]
100
-        else:
101
-            raise Exception("Error reading album info")
94
+        return self._call2("album.php",data)
95
+
96
+    def get_category_list2(self):
97
+        return self.call_api("Category", "list", offset=0, limit=-1)
102 98
 
103
-    def get_category(self, category_id=""):
99
+    def get_category_list(self, category_id=""):
104 100
         if category_id:
105 101
         # api=SYNO.PhotoStation.Category&method=list&version=1&offset=0&limit=1000
106
-            data = "id=%s&api=SYNO.PhotoStation.Category&method=listitem&version=1&offset=0&limit=500&additional=album_permission,thumb_size" % category_id
102
+            data = "id=%s&api=SYNO.PhotoStation.Category&method=listitem&version=1&offset=0&limit=-1&additional=album_permission,photo_exif,video_codec,video_quality,thumb_size,file_location,item_count,album_sorting" % category_id
107 103
         else:
108
-            data = "api=SYNO.PhotoStation.Category&method=list&version=1&offset=0&limit=1000"
109
-        js = self._call2("category.php",data)
110
-        if js["success"] and "data" in js:
111
-            return js["data"]
112
-        else:
113
-            raise Exception("Error reading album info")
104
+            data = "api=SYNO.PhotoStation.Category&method=list&version=1&offset=0&limit=-1"
105
+        return self._call2("category.php",data)
114 106
 
115 107
     def get_smart_album(self, id=""):
116 108
         if id:
@@ -119,19 +111,15 @@ Referer: %s/photo/
119 111
         else:
120 112
             #sort_by=title&sort_direction=desc&api=SYNO.PhotoStation.SmartAlbum&method=list&version=1&offset=0&limit=500&additional=thumb_size
121 113
             data = "sort_by=title&sort_direction=desc&api=SYNO.PhotoStation.SmartAlbum&method=list&version=1&offset=0&limit=500&additional=thumb_size"
122
-        js = self._call2("smart_album.php",data)
123
-        if js["success"] and "data" in js:
124
-            return js["data"]
125
-        else:
126
-            raise Exception("Error reading album info")
114
+        return self._call2("smart_album.php",data)
127 115
 
128 116
     def get_photo_info(self,id):
129 117
         data = "id=%s&version=1&api=SYNO.PhotoStation.Photo&method=getinfo&ps_username=%s&additional=album_permission,photo_exif,video_codec,video_quality,thumb_size,file_location,item_count,album_sorting"%(id,self.user)
130 118
         js = self._call2("photo.php",data)
131
-        if js["success"] and "data" in js:
132
-            return js["data"][0]
119
+        if isinstance(js, list):
120
+            return js[0]
133 121
         else:
134
-            raise Exception("Error reading photo/video info")
122
+            return js
135 123
 
136 124
     def get_thumb(self,id,size="peview",rotate=0 ):
137 125
         # siz = preview|small|large
@@ -140,11 +128,28 @@ Referer: %s/photo/
140 128
         return content
141 129
 
142 130
     def get_thumb_url(self,id,size="small",rotate=0 ):
131
+        # small (M),preview (PREVIEW),large (XL)
143 132
         # http://home.blue.lv/photo/webapi/thumb.php?api=SYNO.PhotoStation.Thumb&method=get&version=1&size=large&id=photo_323031372f323031372d30312d787820537475626169_53353032303031372e4a5047&rotate_version=0&thumb_sig=&PHPSESSID=p51g2ssj3b2o3legsoqfqdc8r3
144 133
         url = "%sthumb.php?api=SYNO.PhotoStation.Thumb&method=get&version=1&size=%s&id=%s&rotate_version=%s&thumb_sig=&PHPSESSID=%s"%(
145 134
                 self.url, size, id, rotate, self.sid )
146 135
         return url
147 136
 
137
+    def get_photo_url(self,id):
138
+        url = "%sdownload.php?api=SYNO.PhotoStation.Download&method=getphoto&version=1&id=%s&PHPSESSID=%s" % (
139
+                self.url, id, self.sid )
140
+        return url
141
+
142
+
143
+    def get_video_url(self,id, quality_id=""):
144
+        if not quality_id:
145
+            url = "%sdownload.php?api=SYNO.PhotoStation.Download&method=getvideo&version=1&id=%s&PHPSESSID=%s" % (
146
+                self.url, id, self.sid )
147
+        else:
148
+            url = "%sdownload.php?api=SYNO.PhotoStation.Download&method=getvideo&version=1&id=%s&quality_id=%s&PHPSESSID=%s" % (
149
+                self.url, id, quality_id, self.sid )
150
+        return url
151
+
152
+
148 153
     def get_video_streams(self,id):
149 154
         urls = []
150 155
         js = self.get_photo_info(id)
@@ -175,9 +180,12 @@ Referer: %s/photo/
175 180
         try:
176 181
             r = requests.post(url,data,headers=self.headers)
177 182
             js = json.loads(r.content)
178
-            return js
179 183
         except Exception as e:
180
-            return {}
184
+            raise Exception(e)
185
+        if not (js["success"] and "data" in js):
186
+            raise Exception("PhotoStation API %s error %s\n%s" % ( path, js["error"]["code"], data))
187
+        else:
188
+            return js["data"]
181 189
 
182 190
     def _call2(self,path,data):
183 191
         "GET request to PhotoStation API"
@@ -192,9 +200,13 @@ Referer: %s/photo/
192 200
             print url
193 201
             r = requests.get(url,headers=self.headers)
194 202
             js = json.loads(r.content)
195
-            return js
196 203
         except Exception as e:
197
-            return {}
204
+            raise Exception(e)
205
+        if not (js["success"] and "data" in js):
206
+            raise Exception("PhotoStation API %s error %s\n%s" % ( path, js["error"]["code"], data))
207
+        else:
208
+            return js["data"]
209
+
198 210
 
199 211
     def _check_url(self,url):
200 212
         if self.sid:
@@ -207,15 +219,179 @@ Referer: %s/photo/
207 219
         else:
208 220
             return True
209 221
 
222
+    def call_api(self, obj, method, **kwargs):
223
+        proc = "SYNO.PhotoStation." + obj
224
+        if proc not in self.api:
225
+            raise Exception("Not valid API object name ", obj)
226
+        path = self.api[proc]["path"]
227
+        data = {}
228
+        data["api"] = proc
229
+        data["method"] = method
230
+        data["version"] = 1
231
+        data.update(kwargs)
232
+        return self._call2(path, data)
233
+
234
+API = {
235
+    "SYNO.PhotoStation.Auth": {
236
+        "path": "auth.php",
237
+        "methods": {
238
+            "1": ["login", "logout", "checkauth"]
239
+        }
240
+    },
241
+    "SYNO.PhotoStation.Info": {
242
+        "path": "info.php",
243
+        "methods": {
244
+            "1": ["getinfo"]
245
+        }
246
+    },
247
+    "SYNO.PhotoStation.Album": {
248
+        "path": "album.php",
249
+        "methods": {
250
+            "1": ["list", "getinfo", "create", "edit", "delete", "arrangeitem", "move", "cleararrangeitem", "cancel"]
251
+        }
252
+    },
253
+    "SYNO.PhotoStation.Permission": {
254
+        "path": "permission.php",
255
+        "methods": {
256
+            "1": ["getalbum", "editalbum", "editgroup", "list_public_share", "edit_public_share"]
257
+        }
258
+    },
259
+    "SYNO.PhotoStation.Photo": {
260
+        "path": "photo.php",
261
+        "methods": {
262
+            "1": ["list", "listexif", "listfeatureditem", "listgpsgroup", "listgpsgroupeditem", "getinfo", "getexif", "edit", "delete", "copy", "cancel"]
263
+        }
264
+    },
265
+    "SYNO.PhotoStation.Thumb": {
266
+        "path": "thumb.php",
267
+        "methods": {
268
+            "1": ["get", "get_dsm_thumb"]
269
+        }
270
+    },
271
+    "SYNO.PhotoStation.Cover": {
272
+        "path": "cover.php",
273
+        "methods": {
274
+            "1": ["set"]
275
+        }
276
+    },
277
+    "SYNO.PhotoStation.SmartAlbum": {
278
+        "path": "smart_album.php",
279
+        "methods": {
280
+            "1": ["list", "getinfo", "create", "edit", "delete"]
281
+        }
282
+    },
283
+    "SYNO.PhotoStation.File": {
284
+        "path": "file.php",
285
+        "methods": {
286
+            "1": ["uploadphoto", "uploadvideo"]
287
+        }
288
+    },
289
+    "SYNO.PhotoStation.Download": {
290
+        "path": "download.php",
291
+        "methods": {
292
+            "1": ["getphoto", "getvideo", "getitem"]
293
+        }
294
+    },
295
+    "SYNO.PhotoStation.ory": {
296
+        "path": "ory.php",
297
+        "methods": {
298
+            "1": ["list", "getinfo", "create", "edit", "delete", "arrangeory", "listitem", "additem", "removeitem", "arrangeitem"]
299
+        }
300
+    },
301
+    "SYNO.PhotoStation.About": {
302
+        "path": "about.php",
303
+        "methods": {
304
+            "1": ["get", "set", "set_visibility"]
305
+        }
306
+    },
307
+    "SYNO.PhotoStation.Tag": {
308
+        "path": "tag.php",
309
+        "methods": {
310
+            "1": ["list", "getinfo", "create", "edit", "delete", "searchplace", "delete_unconfirmed_tag"]
311
+        }
312
+    },
313
+    "SYNO.PhotoStation.PhotoTag": {
314
+        "path": "photo_tag.php",
315
+        "methods": {
316
+            "1": ["list", "people_tag", "geo_tag", "desc_tag", "delete", "people_tag_confirm"]
317
+        }
318
+    },
319
+    "SYNO.PhotoStation.Comment": {
320
+        "path": "comment.php",
321
+        "methods": {
322
+            "1": ["list", "create", "delete"]
323
+        }
324
+    },
325
+    "SYNO.PhotoStation.Timeline": {
326
+        "path": "timeline.php",
327
+        "methods": {
328
+            "1": ["getindex"]
329
+        }
330
+    },
331
+    "SYNO.PhotoStation.Group": {
332
+        "path": "group.php",
333
+        "methods": {
334
+            "1": ["list", "get", "get_dsm_group", "getmember", "create", "edit", "editmember", "delete"]
335
+        }
336
+    },
337
+    "SYNO.PhotoStation.Rotate": {
338
+        "path": "rotate.php",
339
+        "methods": {
340
+            "1": ["set"]
341
+        }
342
+    },
343
+    "SYNO.PhotoStation.SlideshowMusic": {
344
+        "path": "slideshow_music.php",
345
+        "methods": {
346
+            "1": ["list", "get", "add", "edit", "delete"]
347
+        }
348
+    },
349
+    "SYNO.PhotoStation.DsmShare": {
350
+        "path": "dsm_share.php",
351
+        "methods": {
352
+            "1": ["list", "copy", "copymusic"]
353
+        }
354
+    },
355
+    "SYNO.PhotoStation.SharedAlbum": {
356
+        "path": "shared_album.php",
357
+        "methods": {
358
+            "1": ["list", "getinfo", "getinfo_public", "create", "edit", "delete", "add_items", "remove_items", "edit_public_share", "get_single_item", "set_single_item"]
359
+        }
360
+    },
361
+    "SYNO.PhotoStation.PhotoLog": {
362
+        "path": "log.php",
363
+        "methods": {
364
+            "1": ["list", "clear", "export"]
365
+        }
366
+    },
367
+    "SYNO.PhotoStation.Path": {
368
+        "path": "path.php",
369
+        "methods": {
370
+            "1": ["	", "checkpath"]
371
+        }
372
+    }
373
+}
210 374
 
211 375
 if __name__ == "__main__":
212 376
     ps = PhotoStationAPI("http://home.blue.lv/photo")
213 377
     print ps.login("user","Kaskade7")
214 378
 
215
-    js = ps.get_category("category_1")
379
+    js = ps.call_api("Category", "list", offset=0, limit=120)
380
+    js = ps.get_category_list("category_1")
381
+
382
+
383
+    #js = ps.get_category("category_1")
384
+    video_id = "video_323031372f323031372d31322d3234205a69656d6173737665746b692f636c697073_30303133332e4d5453"
385
+    quality_id = "2f766f6c756d65312f70686f746f2f323031372f323031372d31322d3234205a69656d6173737665746b692f636c6970732f4065614469722f30303133332e4d54532f53594e4f50484f544f5f46494c4d5f4d2e6d7034"
386
+    url = ps.get_video_url(video_id, quality_id)
387
+    url0 =  ps.get_video_url(video_id, "")
388
+
389
+
216 390
     album_id = u'album_323031372f323031372d30312d313320536c69646f73616e61'
217 391
     js = ps.get_album_info(album_id)
218
-    js = ps.get_album_list2(album_id)
392
+    js = ps.get_album_list(album_id)
393
+    album_id = "album_323031372f323031372d30312d313320536c69646f73616e612f766964656f"
394
+    js = ps.get_album_list(album_id)
219 395
 
220 396
     photo_id = "photo_323031372f323031372d30312d787820537475626169_53353032303031372e4a5047"
221 397
     js = ps.get_photo_info(photo_id)

+ 4
- 3
resources/settings.xml View File

@@ -7,9 +7,10 @@
7 7
         <setting label="50010" id="start_page" type="select" default="Albums" values="Albums|Categories|category_1|category_2|category_3" />
8 8
         <setting label="50003" id="sorting" type="select" default="preference" values="preference|filename|takendate|createdate" />
9 9
         <setting label="50004" id="order" type="select" default="asc" values="asc|desc" />
10
-        <setting label="50005" id="video_quality" type="select" default="low" values="low|high" />
11
-        <setting label="50006" id="picture_quality" type="select" default="original" values="low|high|original" />
12
-        <setting label="50007" id="interval" type="number" default="3" />
10
+        <setting label="50011" id="play_next" type="bool" default="true" />
11
+        <setting label="50005" id="video_quality" type="select" default="low" values="medium|original" />
12
+        <setting label="50006" id="picture_quality" type="select" default="original" values="preview|large|original" />
13
+        <setting label="50012" id="thumbnail_quality" type="select" default="small" values="preview|small|large" />
13 14
         <setting label="50008" id="repeat" type="bool" default="false" />
14 15
         <setting label="50009" id="random" type="bool" default="false" />
15 16
         <setting type="sep" />