diff options
author | Thorsten Behrens <tbehrens@suse.com> | 2013-04-15 03:33:49 +0200 |
---|---|---|
committer | Thorsten Behrens <tbehrens@suse.com> | 2013-04-15 03:33:49 +0200 |
commit | e11f6e4d9d2b4e17b9ae7be7611a66bfb810bca7 (patch) | |
tree | 74260d3af300a724f0209098edfd9f5301cb5cfe | |
parent | a5772fb74fbb0c2a8dbaa81449a76ee69fa20556 (diff) |
implement slide groups, ensuing rework
- slide thumbnail no longer bear slide number to ease symlinking
- split up tree between decks and groups (also for
preview/thumbnailing)
- some tweaks around ssl support
-rwxr-xr-x | convert_deck.sh | 2 | ||||
-rwxr-xr-x | slideapi.py | 185 | ||||
-rw-r--r-- | views/decksgroups.tpl | 21 | ||||
-rw-r--r-- | views/groups.tpl | 9 |
4 files changed, 153 insertions, 64 deletions
diff --git a/convert_deck.sh b/convert_deck.sh index e410b94..77d7fc7 100755 --- a/convert_deck.sh +++ b/convert_deck.sh @@ -14,6 +14,6 @@ for i in $1/deck-*.png; do rev1=${i/*deck-/} rev2=${rev1/.png/} mkdir -p $1/$rev2 - mv $i $1/$rev2/$rev2.png + mv $i $1/$rev2/thumbnail.png done diff --git a/slideapi.py b/slideapi.py index 7c78a0e..8e99410 100755 --- a/slideapi.py +++ b/slideapi.py @@ -18,10 +18,10 @@ from subprocess import call # we understand: # local_conf["users"], yielding {<username>: {"password": <password>, "description": <description>}, ... } # local_conf["thumbnails"], yielding {"soffice": <path>, "convert": <path>, "thumbnail_size": <128x128>} -# local_conf["tags"], yielding [ <tagname>, ... ] +# local_conf["tags"], yielding { <tagname>: <tag_desc, ... } # local_conf=json.loads(open('local.json').read()) if os.path.exists('local.json') else {} -root='filestore' +root=local_conf["filestore"] def validate_auth(user, password): if "users" in local_conf: @@ -51,7 +51,7 @@ def get_tags(): @get('/api/tags/') def tags(): - return json.dumps(get_tags()) + return get_tags() @get('/tags/') @view('tags') @@ -61,13 +61,19 @@ def tags(): # ------------------------------------------------------------------- def get_decks(user): - path = "%s/%s/" % (root,user) + path = "%s/%s/decks/" % (root,user) if not os.path.isdir(path): return [] return [deck for deck in os.listdir(path) if os.path.isdir(path+deck)] -def get_lastrev(user,deck): - path = "%s/%s/%s/" % (root,user,deck) +def get_groups(user): + path = "%s/%s/groups/" % (root,user) + if not os.path.isdir(path): + return [] + return [group for group in os.listdir(path) if os.path.isdir(path+group)] + +def get_lastrev(user,part,deck): + path = "%s/%s/%s/%s/" % (root,user,part,deck) if not os.path.isdir(path): return 0 # get last revision @@ -75,44 +81,62 @@ def get_lastrev(user,deck): @get('/api/users/<user>/') def list_decks(user): + return json.dumps(['decks/'+deck for deck in get_decks(user)] + ['groups/'+group for group in get_groups(user)]) + +@get('/api/users/<user>/decks/') +def list_decks(user): return json.dumps(get_decks(user)) +@get('/api/users/<user>/groups/') +def list_groups(user): + return json.dumps(get_groups(user)) + @get('/users/<user>/') +@view('decksgroups') +def list_decksgroups(user): + return dict(decks=get_decks(user), groups=get_groups(user)) + +@get('/users/<user>/decks/') @view('decks') def list_decks(user): return dict(decks=get_decks(user)) -@get('/users/<user>/<deck>/thumbnail.png') -@get('/api/users/<user>/<deck>/thumbnail.png') -def get_thumbnail(user, deck): - path = "%s/%s/%s/" % (root,user,deck) - last_rev = get_lastrev(user,deck) +@get('/users/<user>/groups/') +@view('groups') +def list_groups(user): + return dict(groups=get_groups(user)) + +@get('/users/<user>/<part>/<deck>/thumbnail.png') +@get('/api/users/<user>/<part>/<deck>/thumbnail.png') +def get_thumbnail(user, part, deck): + path = "%s/%s/%s/%s/" % (root,user,part,deck) + last_rev = get_lastrev(user,part,deck) # serve thumbnail from that rev, first slide - return static_file('0.png', root=path+str(last_rev)+'/0/', mimetype='image/png') + return static_file('thumbnail.png', root=path+str(last_rev)+'/0/', mimetype='image/png') # ------------------------------------------------------------------- -def get_revs(user,deck): - path = "%s/%s/%s/" % (root,user,deck) +def get_revs(user,part,deck): + path = "%s/%s/%s/%s/" % (root,user,part,deck) if not os.path.isdir(path): return [] return sorted([rev for rev in os.listdir(path) if os.path.isdir(path+rev)], key=int) -@get('/api/users/<user>/<deck>/') -def list_revs(user,deck): - return json.dumps(get_revs(user,deck)) +@get('/api/users/<user>/<part>/<deck>/') +def list_revs(user,part,deck): + return json.dumps(get_revs(user,part,deck)) -@get('/users/<user>/<deck>/') +@get('/users/<user>/<part>/<deck>/') @view('revs') -def list_revs(user,deck): - return dict(revs=get_revs(user,deck)) +def list_revs(user,part,deck): + return dict(revs=get_revs(user,part,deck)) -@post('/users/<user>/<deck>') -@post('/api/users/<user>/<deck>') +@post('/users/<user>/decks/<deck>') +@post('/api/users/<user>/decks/<deck>') @auth_basic(validate_auth, realm='upload') def upload_deck(user,deck): - path = "%s/%s/%s/" % (root,user,deck) - new_rev = get_lastrev(user,deck) + 1 + path = "%s/%s/decks/%s/" % (root,user,deck) + new_rev = get_lastrev(user,'decks',deck) + 1 new_path = path+str(new_rev) if os.path.isdir(new_path): @@ -145,30 +169,64 @@ def upload_deck(user,deck): # thumbnail generation happens asynchronously via updatedeck.py return 'Success:'+tag+':'+content.filename +@post('/users/<user>/groups/<deck>') +@post('/api/users/<user>/groups/<deck>') +@auth_basic(validate_auth, realm='upload') +def upload_group(user,deck): + path = "%s/%s/groups/%s/" % (root,user,deck) + new_rev = get_lastrev(user,'groups',deck) + 1 + new_path = path+str(new_rev) + + if os.path.isdir(new_path): + raise HTTPError(body='inconsistent repo, bailing out') + + if request.auth[0] != user: + raise HTTPError(body='invalid user or insufficient rights, bailing out') + + properties = request.json + if properties[u'name'] != deck: + raise HTTPError(body='Failue: url / name mismatch') + + os.makedirs(new_path) + upload_path = new_path + + # link slides/decks + for index, slide in enumerate(properties['slides']): + if not os.path.isdir(root+'/'+slide): + raise HTTPError(body='non-existing slide %d at path %s, bailing out' % (index, root+slide)) # todo: cleanup!! + os.symlink('../../../../'+slide, upload_path+'/'+str(index)) + + out = open(upload_path+'/meta.json', 'wb') + json.dump({'server_version': '1', + 'payload': properties}, + out) + + return 'Success' + -@get('/users/<user>/<deck>/<rev:int>/thumbnail.png') -@get('/api/users/<user>/<deck>/<rev:int>/thumbnail.png') -def get_thumbnail(user, deck, rev): - path = "%s/%s/%s/%d/" % (root,user,deck,rev) +@get('/users/<user>/<part>/<deck>/<rev:int>/thumbnail.png') +@get('/api/users/<user>/<part>/<deck>/<rev:int>/thumbnail.png') +def get_thumbnail(user, part, deck, rev): + path = "%s/%s/%s/%s/%d/" % (root,user,part,deck,rev) # serve thumbnail from that rev, first slide - return static_file('0.png', root=path+'/0/', mimetype='image/png') + return static_file('thumbnail.png', root=path+'/0/', mimetype='image/png') -@get('/users/<user>/<deck>/<rev:int>/deck.odp') -@get('/api/users/<user>/<deck>/<rev:int>/deck.odp') -def send_deck(user, deck, rev): - path = "%s/%s/%s/%d/" % (root,user,deck,rev) +@get('/users/<user>/<part>/<deck>/<rev:int>/deck.odp') +@get('/api/users/<user>/<part>/<deck>/<rev:int>/deck.odp') +def send_deck(user, part, deck, rev): + path = "%s/%s/%s/%s/%d/" % (root,user,part,deck,rev) return static_file(deck+'.odp', root=path, mimetype='text/xml') # ------------------------------------------------------------------- -def get_slides(user,deck,rev): - path = "%s/%s/%s/%d/" % (root,user,deck,rev) +def get_slides(user,part,deck,rev): + path = "%s/%s/%s/%s/%d/" % (root,user,part,deck,rev) if not os.path.isdir(path): return [] return sorted([slide for slide in os.listdir(path) if os.path.isdir(path+slide)], key=int) -def get_revmeta(user,deck,rev): - path = "%s/%s/%s/%d/" % (root,user,deck,rev) +def get_revmeta(user,part,deck,rev): + path = "%s/%s/%s/%s/%d/" % (root,user,part,deck,rev) comment = open(path+'comment').read() if os.path.exists(path+'comment') else '' meta = json.loads(open(path+'meta.json').read()) if os.path.exists(path+'meta.json') else {} return {'CreationDate': time.strftime("%a, %d %b %Y %H:%M:%S GMT", @@ -176,39 +234,40 @@ def get_revmeta(user,deck,rev): 'CommitComment': comment, 'Meta': meta} -@get('/api/users/<user>/<deck>/<rev:int>/') -def list_slides(user, deck, rev): - return json.dumps(get_slides(user,deck,rev)) +@get('/api/users/<user>/<part>/<deck>/<rev:int>/') +def list_slides(user, part, deck, rev): + return json.dumps(get_slides(user,part,deck,rev)) -@get('/users/<user>/<deck>/<rev:int>/') +@get('/users/<user>/<part>/<deck>/<rev:int>/') @view('slides') -def list_slides(user, deck, rev): - return dict(slides=get_slides(user,deck,rev), revmeta=get_revmeta(user,deck,rev)) +def list_slides(user, part, deck, rev): + return dict(slides=get_slides(user,part,deck,rev), revmeta=get_revmeta(user,part,deck,rev)) -@get('/users/<user>/<deck>/<rev:int>/<slide:int>/thumbnail.png') -@get('/api/users/<user>/<deck>/<rev:int>/<slide:int>/thumbnail.png') -def get_thumbnail(user, deck, rev, slide): - path = "%s/%s/%s/%d/%d/" % (root,user,deck,rev,slide) - return static_file(str(slide)+'.png', root=path, mimetype='image/png') +@get('/users/<user>/<part>/<deck>/<rev:int>/<slide:int>/thumbnail.png') +@get('/api/users/<user>/<part>/<deck>/<rev:int>/<slide:int>/thumbnail.png') +def get_thumbnail(user, part, deck, rev, slide): + path = "%s/%s/%s/%s/%d/%d/" % (root,user,part,deck,rev,slide) + print path + return static_file('thumbnail.png', root=path, mimetype='image/png') -@get('/api/users/<user>/<deck>/<rev:int>/meta.json') -def list_revmeta(user,deck,rev): - return get_revmeta(user,deck,rev) +@get('/api/users/<user>/<part>/<deck>/<rev:int>/meta.json') +def list_revmeta(user,part,deck,rev): + return get_revmeta(user,part,deck,rev) # ------------------------------------------------------------------- -def get_slidemeta(user,deck,rev,slide): - path = "%s/%s/%s/%d/%d/" % (root,user,deck,rev,slide) +def get_slidemeta(user,part,deck,rev,slide): + path = "%s/%s/%s/%s/%d/%d/" % (root,user,part,deck,rev,slide) return json.loads(open(path+'meta.json').read()) if os.path.exists(path+'meta.json') else {} -@get('/api/users/<user>/<deck>/<rev:int>/<slide:int>/meta.json') -def list_slidemeta(user, deck, rev, slide): - return get_slidemeta(user, deck, rev, slide) +@get('/api/users/<user>/<part>/<deck>/<rev:int>/<slide:int>/meta.json') +def list_slidemeta(user, part, deck, rev, slide): + return get_slidemeta(user, part, deck, rev, slide) -@get('/users/<user>/<deck>/<rev:int>/<slide:int>/slide.odp') -@get('/api/users/<user>/<deck>/<rev:int>/<slide:int>/slide.odp') -def send_slide(user, deck, rev, slide): - path = "%s/%s/%s/%d/%d/" % (root,user,deck,rev,slide) +@get('/users/<user>/<part>/<deck>/<rev:int>/<slide:int>/slide.odp') +@get('/api/users/<user>/<part>/<deck>/<rev:int>/<slide:int>/slide.odp') +def send_slide(user, part, deck, rev, slide): + path = "%s/%s/%s/%s/%d/%d/" % (root,user,part,deck,rev,slide) return static_file(str(slide)+'.odp', root=path, mimetype='text/xml') @get('/') @@ -220,9 +279,9 @@ def home_page(): class SSLInterface(ServerAdapter): def run(self, handler): server = _cpwsgiserver3.CherryPyWSGIServer((self.host, self.port), handler) - cert = 'server.pem' - server.ssl_certificate = cert - server.ssl_private_key = cert + #cert = 'server.pem' + #server.ssl_certificate = cert + #server.ssl_private_key = cert try: server.start() finally: diff --git a/views/decksgroups.tpl b/views/decksgroups.tpl new file mode 100644 index 0000000..87c66cb --- /dev/null +++ b/views/decksgroups.tpl @@ -0,0 +1,21 @@ +%#generate HTML table of all decks +<table border="1"> + <tr> + <th colspan=2><b>Decks</b></th> + </tr> +%for deckname in decks: + <tr> + <td><a href="decks/{{deckname}}/">{{deckname}}</a></td> + <td><a href="decks/{{deckname}}/"><img src="decks/{{deckname}}/thumbnail.png"></a></td> + </tr> +%end + <tr> + <th colspan=2><b>Groups</b></th> + </tr> +%for groupname in groups: + <tr> + <td><a href="groups/{{groupname}}/">{{groupname}}</a></td> + <td><a href="groups/{{groupname}}/"><img src="groups/{{groupname}}/thumbnail.png"></a></td> + </tr> +%end +</table> diff --git a/views/groups.tpl b/views/groups.tpl new file mode 100644 index 0000000..33c0df9 --- /dev/null +++ b/views/groups.tpl @@ -0,0 +1,9 @@ +%#generate HTML table of all decks +<table border="1"> +%for groupname in groups: + <tr> + <td><a href="{{groupname}}/">{{groupname}}</a></td> + <td><a href="{{groupname}}/"><img src="{{groupname}}/thumbnail.png"></a></td> + </tr> +%end +</table> |