import logging
log = logging.getLogger("dataproviders.Image")
import conduit
import conduit.Exceptions as Exceptions
import conduit.datatypes.File as File
import conduit.dataproviders.DataProvider as DataProvider
from conduit.datatypes import Rid
00010 class UploadInfo:
"""
Upload information container, this way we can add info
and keep the _upload_info method on the ImageSink retain
its api
"""
def __init__ (self, url, mimeType, name="", tags=(), caption=""):
self.url = url
self.mimeType = mimeType
self.name = name
self.tags = tags
self.caption = caption
00023 class ImageSink(DataProvider.DataSink):
"""
Abstract Base class for Image DataSinks
"""
_category_ = conduit.dataproviders.CATEGORY_PHOTOS
_module_type_ = "sink"
_in_type_ = "file/photo"
_out_type_ = "file/photo"
IMAGE_SIZES = ["640x480", "800x600", "1024x768"]
NO_RESIZE = "None"
00035 def __init__(self, *args):
DataProvider.DataSink.__init__(self)
00038 def initialize(self):
return True
def _resize_combobox_build(self, combobox, selected):
import gtk
store = gtk.ListStore(str)
cell = gtk.CellRendererText()
combobox.pack_start(cell, True)
combobox.add_attribute(cell, 'text', 0)
combobox.set_model(store)
for s in [self.NO_RESIZE] + self.IMAGE_SIZES:
rowref = store.append( (s,) )
if s == selected:
combobox.set_active_iter(rowref)
def _resize_combobox_get_active(self, combobox):
model = combobox.get_model()
active = combobox.get_active()
if active < 0:
return self.NO_RESIZE
size = model[active][0]
if size not in self.IMAGE_SIZES:
return self.NO_RESIZE
return size
00066 def _get_photo_info(self, photoID):
"""
This should return the info for a given photo id,
If this returns anything different from None, it will be
passed onto _get_raw_photo_url
"""
return None
00074 def _get_raw_photo_url(self, photoInfo):
"""
This should return the url of the online photo
"""
return None
00080 def _upload_photo (self, uploadInfo):
"""
Upload a photo
"""
return None
00086 def _replace_photo (self, id, uploadInfo):
"""
Replace a photo with a new version
"""
return Rid(uid=id)
00092 def _get_photo_formats (self):
"""
This should return the allowed photo mimetypes
"""
return ("image/jpeg", "image/png")
00098 def _get_default_format (self):
"""
This should return the preferred format of images the sink accepts
"""
return "image/jpeg"
00104 def _get_photo_size (self):
"""
Return the preferred photo size string for rescaling, or None
"""
return None
00110 def put(self, photo, overwrite, LUID=None):
"""
Accepts a vfs file. Must be made local.
I also store a md5 of the photos uri to check for duplicates
"""
DataProvider.DataSink.put(self, photo, overwrite, LUID)
originalName = photo.get_filename()
photoURI = photo.get_local_uri()
mimeType = photo.get_mimetype()
tags = photo.get_tags ()
caption = photo.get_caption()
uploadInfo = UploadInfo(photoURI, mimeType, originalName, tags, caption)
if LUID != None:
info = self._get_photo_info(LUID)
if info != None:
if overwrite == True:
return self._replace_photo(LUID, uploadInfo)
else:
url = self._get_raw_photo_url(info)
remoteFile = File.File(url)
comp = photo.compare(remoteFile,True)
log.debug("Compared %s with %s to check if they are the same (size). Result = %s" %
(photo.get_filename(),remoteFile.get_filename(),comp))
if comp != conduit.datatypes.COMPARISON_EQUAL:
raise Exceptions.SynchronizeConflictError(comp, photo, remoteFile)
else:
return conduit.datatypes.Rid(uid=LUID)
log.debug("Uploading Photo URI = %s, Mimetype = %s, Original Name = %s" % (photoURI, mimeType, originalName))
return self._upload_photo (uploadInfo)
00154 def delete(self, LUID):
pass
00157 def get_input_conversion_args(self):
args = {
"formats" : ','.join(self._get_photo_formats()),
"default-format" : self._get_default_format(),
"size" : self._get_photo_size(),
}
return args
00165 class ImageTwoWay(DataProvider.DataSource, ImageSink):
"""
Abstract Base Class for ImageTwoWay dataproviders
"""
_module_type_ = "twoway"
def __init__(self):
DataProvider.DataSource.__init__(self)
ImageSink.__init__(self)
00176 def put(self, photo, overwrite, LUID=None):
"""
Accepts a vfs file. Must be made local.
I also store a md5 of the photos uri to check for duplicates
"""
DataProvider.DataSink.put(self, photo, overwrite, LUID)
originalName = photo.get_filename()
photoURI = photo.get_local_uri()
mimeType = photo.get_mimetype()
tags = photo.get_tags ()
caption = photo.get_caption()
uploadInfo = UploadInfo(photoURI, mimeType, originalName, tags, caption)
if overwrite and LUID:
rid = self._replace_photo(LUID, uploadInfo)
else:
if LUID and self._get_photo_info(LUID):
remotePhoto = self.get(LUID)
comp = photo.compare(remotePhoto, False)
log.debug("Compared %s with %s. Result = %s" %
(photo.get_filename(),remotePhoto.get_filename(),comp))
if LUID != None and comp == conduit.datatypes.COMPARISON_NEWER:
rid = self._replace_photo(LUID, uploadInfo)
elif comp == conduit.datatypes.COMPARISON_EQUAL:
rid = remotePhoto.get_rid()
else:
raise Exceptions.SynchronizeConflictError(comp, photo, remotePhoto)
else:
log.debug("Uploading Photo URI = %s, Mimetype = %s, Original Name = %s" %
(photoURI, mimeType, originalName))
rid = self._upload_photo (uploadInfo)
if not rid:
raise Exceptions.SyncronizeError("Error putting/updating photo")
else:
return rid