1
# Copyright (C) 2008 Jean-Michel Sizun <jm.sizun AT gmail>
3
# Copyright (C) 2008 Brent Woodruff
4
# http://www.fprimex.com
6
# Copyright (C) 2004 John Sutherland <garion@twcny.rr.com>
7
# http://garion.tzo.com/python/
9
# This library is free software; you can redistribute it and/or
10
# modify it under the terms of the GNU Lesser General Public
11
# License as published by the Free Software Foundation; either
12
# version 2.1 of the License, or (at your option) any later version.
14
# This library is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
# Lesser General Public License for more details.
19
# You should have received a copy of the GNU Lesser General Public
20
# License along with this library; if not, write to the Free Software
21
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
# 16-Nov-08 - Migrated from urllib to coherence infrastructure
28
# 04-Aug-08 - Added Gallery2 compatibility
29
# Changed fetch_albums and fetch_albums_prune to return dicts
31
# Created package and registered with Pypi
33
# 09-Jun-04 - Removed self.cookie='' from _doRequest to allow multiple
34
# transactions for each login.
35
# Fixed cut paste error in newAlbum.
36
# (both patches from Yuti Takhteyev
39
from coherence.upnp.core.utils import getPage
46
The Gallery class implements the Gallery Remote protocol as documented
48
http://codex.gallery2.org/Gallery_Remote:Protocol
50
The Gallery project is an open source web based photo album organizer
51
written in php. Gallery's web site is:
52
http://gallery.menalto.com/
54
This class is a 3rd party product which is not maintained by the
55
creators of the Gallery project.
58
from galleryremote import Gallery
59
my_gallery = Gallery('http://www.yoursite.com/gallery2', 2)
60
my_gallery.login('username','password')
61
albums = my_gallery.fetch_albums()
64
def __init__(self, url, version=2):
66
Create a Gallery for remote access.
67
url - base address of the gallery
68
version - version of the gallery being connected to (default 2),
69
either 1 for Gallery1 or 2 for Gallery2
71
self.version = version # Gallery1 or Gallery2
73
self.url = url + '/gallery_remote2.php'
76
self.url = url + '/main.php'
77
self.auth_token = None
80
self.protocol_version = '2.5'
82
def _do_request(self, request):
84
Send a request, encoded as described in the Gallery Remote protocol.
85
request - a dictionary of protocol parameters and values
87
if self.auth_token != None:
88
request['g2_authToken'] = self.auth_token
91
if (len(request) > 0) :
93
for key,value in request.iteritems():
94
url += '%s=%s&' % (key,value)
97
headers = {'Cookie' : self.cookie}
100
data,headers = result
101
response = self._parse_response( data )
102
if response['status'] != '0':
103
raise response['status_text']
105
self.auth_token = response['auth_token']
109
if headers.has_key('set-cookie'):
110
cookie_info = headers['set-cookie'][-1]
111
self.cookie = cookie_info.split(';')[0]
116
print "Unable to process Gallery2 request: %s" % url
117
print "Error: %s" % error
120
d = getPage(url, headers=headers)
121
d.addCallback(gotPage)
122
d.addErrback(gotError)
126
def _parse_response(self, response):
128
Decode the response from a request, returning a request dict
129
response - The response from a gallery request, encoded according
130
to the gallery remote protocol
132
myStr = StringIO.StringIO(response)
135
if string.find( line, '#__GR2PROTO__' ) != -1:
138
# make sure the 1st line is #__GR2PROTO__
139
if string.find( line, '#__GR2PROTO__' ) == -1:
140
raise "Bad response: \r\n" + response
146
strList = string.split(myS, '=', 2)
149
resDict[strList[0]] = strList[1]
151
resDict[strList[0]] = ''
155
def _get(self, response, kwd):
159
retval = response[kwd]
165
def login(self, username, password):
167
Establish an authenticated session to the remote gallery.
168
username - A valid gallery user's username
169
password - That valid user's password
171
if self.version == 1:
173
'protocol_version': self.protocol_version,
180
'g2_controller' : 'remote:GalleryRemote',
181
'g2_form[protocol_version]' : self.protocol_version,
182
'g2_form[cmd]' : 'login',
183
'g2_form[uname]': username,
184
'g2_form[password]': password
189
print "Unable to login as %s to gallery2 server (%s)" % (username, self.url)
194
d = self._do_request(request)
195
d.addCallbacks(gotPage)
199
def fetch_albums(self):
201
Obtain a dict of albums contained in the gallery keyed by
202
album name. In Gallery1, the name is alphanumeric. In Gallery2,
203
the name is the unique identifying number for that album.
205
if self.version == 1:
207
'protocol_version' : self.protocol_version,
208
'cmd' : 'fetch-albums'
212
'g2_controller' : 'remote:GalleryRemote',
213
'g2_form[protocol_version]' : self.protocol_version,
214
'g2_form[cmd]' : 'fetch-albums'
217
d = self._do_request(request)
219
def gotResponse(response):
221
print "Unable to retrieve list of albums!"
225
for x in range(1, int(response['album_count']) + 1):
227
album['name'] = self._get(response,'album.name.' + str(x))
228
album['title'] = self._get(response,'album.title.' + str(x))
229
album['summary'] = self._get(response,'album.summary.' + str(x))
230
album['parent'] = self._get(response,'album.parent.' + str(x))
231
album['resize_size'] = self._get(response,'album.resize_size.' + str(x))
232
album['perms.add'] = self._get(response,'album.perms.add.' + str(x))
233
album['perms.write'] = self._get(response,'album.perms.write.' + str(x))
234
album['perms.del_item'] = self._get(response,'album.perms.del_item.' + str(x))
235
album['perms.del_alb'] = self._get(response,'album.perms.del_alb.' + str(x))
236
album['perms.create_sub'] = self._get(response,'album.perms.create_sub.' + str(x))
237
album['perms.info.extrafields'] = self._get(response,'album.info.extrafields' + str(x))
239
albums[album['name']] = album
242
d.addCallback(gotResponse)
245
def fetch_albums_prune(self):
247
Obtain a dict of albums contained in the gallery keyed by
248
album name. In Gallery1, the name is alphanumeric. In Gallery2,
249
the name is the unique identifying number for that album.
251
From the protocol docs:
252
"The fetch_albums_prune command asks the server to return a list
253
of all albums that the user can either write to, or that are
254
visible to the user and contain a sub-album that is writable
255
(including sub-albums several times removed)."
257
if self.version == 1:
259
'protocol_version' : self.protocol_version,
260
'cmd' : 'fetch-albums-prune'
264
'g2_controller' : 'remote:GalleryRemote',
265
'g2_form[protocol_version]' : self.protocol_version,
266
'g2_form[cmd]' : 'fetch-albums-prune'
269
response = self._do_request(request)
271
def gotResponse(response):
272
# as long as it comes back here without an exception, we're ok.
275
for x in range(1, int(response['album_count']) + 1):
277
album['name'] = self._get(response,'album.name.' + str(x))
278
album['title'] = self._get(response,'album.title.' + str(x))
279
album['summary'] = self._get(response,'album.summary.' + str(x))
280
album['parent'] = self._get(response,'album.parent.' + str(x))
281
album['resize_size'] = self._get(response,'album.resize_size.' + str(x))
282
album['perms.add'] = self._get(response,'album.perms.add.' + str(x))
283
album['perms.write'] = self._get(response,'album.perms.write.' + str(x))
284
album['perms.del_item'] = self._get(response,'album.perms.del_item.' + str(x))
285
album['perms.del_alb'] = self._get(response,'album.perms.del_alb.' + str(x))
286
album['perms.create_sub'] = self._get(response,'album.perms.create_sub.' + str(x))
287
album['perms.info.extrafields'] = self._get(response,'album.info.extrafields' + str(x))
289
albums[album['name']] = album
293
d.addCallback(gotResponse)
297
def add_item(self, album, filename, caption, description):
299
Add a photo to the specified album.
300
album - album name / identifier
301
filename - image to upload
302
caption - string caption to add to the image
303
description - string description to add to the image
305
if self.version == 1:
307
'protocol_version' : self.protocol_version,
309
'set_albumName' : album,
311
'userfile_name' : filename,
313
'extrafield.Description' : description
317
'g2_form[protocol_version]' : self.protocol_version,
318
'g2_form[cmd]' : 'add-item',
319
'g2_form[set_albumName]' : album,
320
'g2_form[userfile]' : file,
321
'g2_form[userfile_name]' : filename,
322
'g2_form[caption]' : caption,
323
'g2_form[extrafield.Description]' : description
326
file = open(filename)
327
d = self._do_request(request)
328
# if we get here, everything went ok.
332
def album_properties(self, album):
334
Obtain album property information for the specified album.
335
album - the album name / identifier to obtain information for
337
if self.version == 1:
339
'protocol_version' : self.protocol_version,
340
'cmd' : 'album-properties',
341
'set_albumName' : album
345
'g2_controller' : 'remote:GalleryRemote',
346
'g2_form[protocol_version]' : self.protocol_version,
347
'g2_form[cmd]' : 'album-properties',
348
'g2_form[set_albumName]' : album
351
d = self._do_request(request)
353
def gotResponse(response):
356
if response.has_key('auto_resize'):
357
res_dict['auto_resize'] = response['auto_resize']
358
if response.has_key('add_to_beginning'):
359
res_dict['add_to_beginning'] = response['add_to_beginning']
363
d.addCallback(gotResponse)
367
def new_album(self, parent, name=None, title=None, description=None):
369
Add an album to the specified parent album.
370
parent - album name / identifier to contain the new album
371
name - unique string name of the new album
372
title - string title of the album
373
description - string description to add to the image
375
if self.version == 1:
377
'g2_controller' : 'remote:GalleryRemote',
378
'protocol_version' : self.protocol_version,
380
'set_albumName' : parent
383
request['newAlbumName'] = name
385
request['newAlbumTitle'] = title
386
if description != None:
387
request['newAlbumDesc'] = description
390
'g2_controller' : 'remote:GalleryRemote',
391
'g2_form[protocol_version]' : self.protocol_version,
392
'g2_form[cmd]' : 'new-album',
393
'g2_form[set_albumName]' : parent
396
request['g2_form[newAlbumName]'] = name
398
request['g2_form[newAlbumTitle]'] = title
399
if description != None:
400
request['g2_form[newAlbumDesc]'] = description
402
d = self._do_request(request)
404
def gotResponse(response):
405
return response['album_name']
411
def fetch_album_images(self, album):
413
Get the image information for all images in the specified album.
414
album - specifies the album from which to obtain image information
416
if self.version == 1:
418
'protocol_version' : self.protocol_version,
419
'cmd' : 'fetch-album-images',
420
'set_albumName' : album,
422
'extrafields' : 'yes'
426
'g2_controller' : 'remote:GalleryRemote',
427
'g2_form[protocol_version]' : self.protocol_version,
428
'g2_form[cmd]' : 'fetch-album-images',
429
'g2_form[set_albumName]' : album,
430
'g2_form[albums_too]' : 'no',
431
'g2_form[extrafields]' : 'yes'
434
d = self._do_request(request)
436
def gotResponse (response):
438
print "Unable to retrieve list of item for album %s." % album
443
for x in range(1, int(response['image_count']) + 1):
445
image['name'] = self._get(response, 'image.name.' + str(x))
446
image['title'] = self._get(response, 'image.title.' + str(x))
447
image['raw_width'] = self._get(response, 'image.raw_width.' + str(x))
448
image['raw_height'] = self._get(response, 'image.raw_height.' + str(x))
449
image['resizedName'] = self._get(response, 'image.resizedName.' + str(x))
450
image['resized_width'] = self._get(response, 'image.resized_width.' + str(x))
451
image['resized_height'] = self._get(response, 'image.resized_height.' + str(x))
452
image['thumbName'] = self._get(response, 'image.thumbName.' + str(x))
453
image['thumb_width'] = self._get(response, 'image.thumb_width.' + str(x))
454
image['thumb_height'] = self._get(response, 'image.thumb_height.' + str(x))
455
image['raw_filesize'] = self._get(response, 'image.raw_filesize.' + str(x))
456
image['caption'] = self._get(response, 'image.caption.' + str(x))
457
image['clicks'] = self._get(response, 'image.clicks.' + str(x))
458
image['capturedate.year'] = self._get(response, 'image.capturedate.year' + str(x))
459
image['capturedate.mon'] = self._get(response, 'image.capturedate.mon' + str(x))
460
image['capturedate.mday'] = self._get(response, 'image.capturedate.mday' + str(x))
461
image['capturedate.hours'] = self._get(response, 'image.capturedate.hours' + str(x))
462
image['capturedate.minutes'] = self._get(response, 'image.capturedate.minutes' + str(x))
463
image['capturedate.seconds'] = self._get(response, 'image.capturedate.seconds' + str(x))
464
image['description'] = self._get(response, 'image.extrafield.Description.' + str(x))
470
d.addCallback(gotResponse)
474
def get_URL_for_image(self, gallery2_id):
475
url = '%s/main.php?g2_view=core.DownloadItem&g2_itemId=%s' % (self.url, gallery2_id)
b'\\ No newline at end of file'