diff options
Diffstat (limited to 'app/photos/retriever.py')
-rw-r--r-- | app/photos/retriever.py | 231 |
1 files changed, 121 insertions, 110 deletions
diff --git a/app/photos/retriever.py b/app/photos/retriever.py index 4dfbc49..1a0757e 100644 --- a/app/photos/retriever.py +++ b/app/photos/retriever.py @@ -1,88 +1,90 @@ -from __future__ import division import datetime import os -import cStringIO # *much* faster than StringIO -import urllib +import io +import urllib.request +import urllib.parse +import urllib.error - -from django.contrib.contenttypes.models import ContentType from django.template.defaultfilters import slugify from django.core.exceptions import ObjectDoesNotExist -from django.utils.encoding import force_unicode,smart_unicode +from django.utils.encoding import force_text from django.conf import settings +from photos.models import Photo, PhotoGallery + +# from https://github.com/alexis-mignon/python-flickr-api +# terribly documented, but offers a good clean OOP approach if you're willing to figure it out... +import flickr_api + # Required PIL classes may or may not be available from the root namespace # depending on the installation try: import Image import ImageFile - import ImageFilter - import ImageEnhance except ImportError: try: from PIL import Image from PIL import ImageFile - from PIL import ImageFilter - from PIL import ImageEnhance except ImportError: raise ImportError("Could not import the Python Imaging Library.") - -ImageFile.MAXBLOCK = 1000000 -from utils.strutils import safestr -from photos.models import Photo,PhotoGallery - -# from https://github.com/alexis-mignon/python-flickr-api -# terribly documented, but offers a good clean OOP approach if you're willing to figure it out... -import flickr_api +ImageFile.MAXBLOCK = 1000000 +EXIF_PARAMS = { + "FNumber": 'f/2.8', + "Make": 'Apple', + "Model": 'iPhone', + "ExposureTime": '', + "ISO": '', + "FocalLength": '', + "LensModel": '', + 'DateTimeOriginal': '2013:09:03 22:44:25' +} -EXIF_PARAMS = {"FNumber":'f/2.8',"Make":'Apple',"Model":'iPhone',"ExposureTime":'',"ISO":'',"FocalLength":'', "LensModel":'','DateTimeOriginal':'2013:09:03 22:44:25'} def sync_flickr_photos(*args, **kwargs): - flickr_api.set_keys(api_key =settings.FLICKR_API_KEY, api_secret=settings.FLICKR_API_SECRET) + flickr_api.set_keys(api_key=settings.FLICKR_API_KEY, api_secret=settings.FLICKR_API_SECRET) flickr_api.set_auth_handler("app/photos/flickrauth") user = flickr_api.test.login() - photos = user.getPhotos(extras="date_upload,date_taken,geo") - #reverse! reverse! + photos = user.getPhotos(extras="date_upload,date_taken,geo") + # reverse! reverse! photos.reverse() for photo in photos: info = photo.getInfo() try: row = Photo.objects.get(flickr_id=info['id'], flickr_secret=info['secret']) - # If the row exists already, set the dupe flag - dupe = True - print 'already have '+info['id']+' moving on' + print(('already have ' + info['id'] + ' moving on')) except ObjectDoesNotExist: get_photo(photo) + def get_photo(photo): info = photo.getInfo() geo = photo.getLocation() - location, region = get_geo(float(geo['latitude']),float(geo['longitude'])) + location, region = get_geo(float(geo['latitude']), float(geo['longitude'])) exif = exif_handler(photo.getExif()) p, created = Photo.objects.get_or_create( - title = info['title'], - flickr_id = info['id'], - flickr_owner = info['owner']['id'], - flickr_server = info['server'], - flickr_secret = info['secret'], - flickr_originalsecret = info['originalsecret'], - flickr_farm = info['farm'], - pub_date = flickr_datetime_to_datetime(info['taken']), - description = info['description'], - exif_aperture = exif['FNumber'], - exif_make = exif['Make'], - exif_model = exif['Model'], - exif_exposure = exif['ExposureTime'], - exif_iso = exif['ISO'], - exif_lens = exif['LensModel'], - exif_focal_length = exif['FocalLength'], - exif_date = flickr_datetime_to_datetime(exif["DateTimeOriginal"].replace(':', '-', 2)), - lat = float(geo['latitude']), - lon = float(geo['longitude']), - region = region, - location = location, + title=info['title'], + flickr_id=info['id'], + flickr_owner=info['owner']['id'], + flickr_server=info['server'], + flickr_secret=info['secret'], + flickr_originalsecret=info['originalsecret'], + flickr_farm=info['farm'], + pub_date=flickr_datetime_to_datetime(info['taken']), + description=info['description'], + exif_aperture=exif['FNumber'], + exif_make=exif['Make'], + exif_model=exif['Model'], + exif_exposure=exif['ExposureTime'], + exif_iso=exif['ISO'], + exif_lens=exif['LensModel'], + exif_focal_length=exif['FocalLength'], + exif_date=flickr_datetime_to_datetime(exif["DateTimeOriginal"].replace(':', '-', 2)), + lat=float(geo['latitude']), + lon=float(geo['longitude']), + region=region, + location=location, ) if created: for tag in info['tags']: @@ -92,53 +94,63 @@ def get_photo(photo): #retina image: #slideshow_image(p, 2000, 1600, 75) #normal image - print p.title + print((p.title)) return p - -def sync_sets(*args, **kwargs): - flickr_api.set_keys(api_key =settings.FLICKR_API_KEY, api_secret=settings.FLICKR_API_SECRET) + +def sync_sets(*args, **kwargs): + flickr_api.set_keys(api_key=settings.FLICKR_API_KEY, api_secret=settings.FLICKR_API_SECRET) flickr_api.set_auth_handler("app/photos/flickrauth") user = flickr_api.test.login() - photosets = user.getPhotosets() - #reverse! reverse! + photosets = user.getPhotosets() + # reverse! reverse! photosets.reverse() - disregard = ['POTD 2008','Snow Day','Wedding','Some random stuff','Lilah & Olivia', '6 months+', '6-9 months','9-18 months'] + disregard = [ + 'POTD 2008', + 'Snow Day', + 'Wedding', + 'Some random stuff', + 'Lilah & Olivia', + '6 months+', + '6-9 months', + '9-18 months', + ] for photoset in photosets: if photoset['title'] in disregard: pass else: try: row = PhotoGallery.objects.get(set_id__exact=photoset['id']) - print '%s %s %s' %('already have', row.set_title, 'moving on...') + print(('%s %s %s' % ('already have', row.set_title, 'moving on...'))) # okay it already exists, but is it up-to-date? #get_photos_in_set(row,set.id) - except ObjectDoesNotExist: - s = PhotoGallery.objects.create ( - set_id = force_unicode(photoset['id']), - set_title = force_unicode(photoset['title']), - set_desc = force_unicode(photoset['description']), - set_slug = slugify(force_unicode(photoset['title'])), - primary = force_unicode(photoset['primary']), - pub_date = datetime.datetime.fromtimestamp(float(photoset['date_create'])) + except ObjectDoesNotExist: + s = PhotoGallery.objects.create( + set_id=force_text(photoset['id']), + set_title=force_text(photoset['title']), + set_desc=force_text(photoset['description']), + set_slug=slugify(force_text(photoset['title'])), + primary=force_text(photoset['primary']), + pub_date=datetime.datetime.fromtimestamp(float(photoset['date_create'])) ) get_photos_in_set(photoset, s) #create the gallery thumbnail image: photo = Photo.objects.get(flickr_id__exact=str(photoset['primary'])) - make_gallery_thumb(photo,s) - + make_gallery_thumb(photo, s) + + def get_photos_in_set(flickr_photoset, photoset): for photo in flickr_photoset.getPhotos(): try: p = Photo.objects.get(flickr_id__exact=str(photo['id'])) except ObjectDoesNotExist: p = get_photo(photo) - if p.is_public == True: + if p.is_public: photoset.photos.add(p) slideshow_image(p, 1000, 800, 95) - + ################################################ ## Various meta data and geo helper functions ## ################################################ @@ -151,19 +163,20 @@ def exif_handler(data): converted[t['tag']] = t['raw'] except: pass - for k,v in EXIF_PARAMS.items(): - if not converted.has_key(k): + for k, v in list(EXIF_PARAMS.items()): + if k not in converted: converted[k] = v return converted - + def flickr_datetime_to_datetime(fdt): from datetime import datetime from time import strptime date_parts = strptime(fdt, '%Y-%m-%d %H:%M:%S') return datetime(*date_parts[0:6]) -def get_geo(lat,lon): + +def get_geo(lat, lon): from locations.models import Location, Region from django.contrib.gis.geos import Point pnt_wkt = Point(lon, lat) @@ -177,24 +190,26 @@ def get_geo(lat,lon): region = None return location, region + ####################################################################### ## Photo retrieval functions to pull down images from Flickr servers ## ####################################################################### -def slideshow_image(photo,max_width, max_height, quality): - slide_dir = settings.IMAGES_ROOT + '/slideshow/'+ photo.pub_date.strftime("%Y") + +def slideshow_image(photo, max_width, max_height, quality): + slide_dir = settings.IMAGES_ROOT + '/slideshow/' + photo.pub_date.strftime("%Y") if not os.path.isdir(slide_dir): os.makedirs(slide_dir) # Is it a retina image or not? if max_width >= 1001 or max_height >= 801: - filename = '%s/%sx2.jpg' %(slide_dir, photo.flickr_id) + filename = '%s/%sx2.jpg' % (slide_dir, photo.flickr_id) else: - filename = '%s/%s.jpg' %(slide_dir, photo.flickr_id) - + filename = '%s/%s.jpg' % (slide_dir, photo.flickr_id) + flickr_photo = photo.get_original_url() - fname = urllib.urlopen(flickr_photo) - im = cStringIO.StringIO(fname.read()) # constructs a StringIO holding the image + fname = urllib.request.urlopen(flickr_photo) + im = io.StringIO(fname.read()) # constructs a StringIO holding the image img = Image.open(im) cur_width, cur_height = img.size #if image landscape @@ -202,19 +217,19 @@ def slideshow_image(photo,max_width, max_height, quality): new_width = max_width #check to make sure we aren't upsizing if cur_width > new_width: - ratio = float(new_width)/cur_width + ratio = float(new_width) / cur_width x = (cur_width * ratio) y = (cur_height * ratio) resized = img.resize((int(x), int(y)), Image.ANTIALIAS) resized.save(filename, 'JPEG', quality=quality, optimize=True) else: img.save(filename) - else: + else: #image portrait new_height = max_height #check to make sure we aren't upsizing if cur_height > new_height: - ratio = float(new_height)/cur_height + ratio = float(new_height) / cur_height x = (cur_width * ratio) y = (cur_height * ratio) resized = img.resize((int(x), int(y)), Image.ANTIALIAS) @@ -227,77 +242,73 @@ def slideshow_image(photo,max_width, max_height, quality): photo.slideshowimage_marginleft = photo.get_margin_left photo.save() #now resize the local copy - def make_local_copies(photo): - orig_dir = settings.IMAGES_ROOT + '/flickr/full/'+ photo.pub_date.strftime("%Y") + orig_dir = settings.IMAGES_ROOT + '/flickr/full/' + photo.pub_date.strftime("%Y") if not os.path.isdir(orig_dir): os.makedirs(orig_dir) full = photo.get_original_url() - fname = urllib.urlopen(full) - im = cStringIO.StringIO(fname.read()) # constructs a StringIO holding the image + fname = urllib.request.urlopen(full) + im = io.StringIO(fname.read()) # constructs a StringIO holding the image img = Image.open(im) - local_full = '%s/%s.jpg' %(orig_dir, photo.flickr_id) + local_full = '%s/%s.jpg' % (orig_dir, photo.flickr_id) img.save(local_full) #save large size - large_dir = settings.IMAGES_ROOT + '/flickr/large/'+ photo.pub_date.strftime("%Y") + large_dir = settings.IMAGES_ROOT + '/flickr/large/' + photo.pub_date.strftime("%Y") if not os.path.isdir(large_dir): os.makedirs(large_dir) large = photo.get_large_url() - fname = urllib.urlopen(large) - im = cStringIO.StringIO(fname.read()) # constructs a StringIO holding the image + fname = urllib.request.urlopen(large) + im = io.StringIO(fname.read()) # constructs a StringIO holding the image img = Image.open(im) - local_large = '%s/%s.jpg' %(large_dir, photo.flickr_id) + local_large = '%s/%s.jpg' % (large_dir, photo.flickr_id) if img.format == 'JPEG': img.save(local_large) #save medium size - med_dir = settings.IMAGES_ROOT + '/flickr/med/'+ photo.pub_date.strftime("%Y") + med_dir = settings.IMAGES_ROOT + '/flickr/med/' + photo.pub_date.strftime("%Y") if not os.path.isdir(med_dir): os.makedirs(med_dir) med = photo.get_medium_url() - fname = urllib.urlopen(med) - im = cStringIO.StringIO(fname.read()) # constructs a StringIO holding the image + fname = urllib.request.urlopen(med) + im = io.StringIO(fname.read()) # constructs a StringIO holding the image img = Image.open(im) - local_med = '%s/%s.jpg' %(med_dir, photo.flickr_id) + local_med = '%s/%s.jpg' % (med_dir, photo.flickr_id) img.save(local_med) - -def make_gallery_thumb(photo,set): + + +def make_gallery_thumb(photo, set): crop_dir = settings.IMAGES_ROOT + '/gallery_thumbs/' if not os.path.isdir(crop_dir): os.makedirs(crop_dir) remote = photo.get_original_url() - print remote - fname = urllib.urlopen(remote) - im = cStringIO.StringIO(fname.read()) # constructs a StringIO holding the image + print(remote) + fname = urllib.request.urlopen(remote) + im = io.StringIO(fname.read()) # constructs a StringIO holding the image img = Image.open(im) - #calculate crop: cur_width, cur_height = img.size new_width, new_height = 291, 350 - ratio = max(float(new_width)/cur_width,float(new_height)/cur_height) + ratio = max(float(new_width) / cur_width, float(new_height) / cur_height) x = (cur_width * ratio) y = (cur_height * ratio) xd = abs(new_width - x) yd = abs(new_height - y) x_diff = int(xd / 2) y_diff = int(yd / 2) - box = (int(x_diff), int(y_diff), int(x_diff+new_width), int(y_diff+new_height)) - - #create resized file + box = (int(x_diff), int(y_diff), int(x_diff + new_width), int(y_diff + new_height)) + + # create resized file resized = img.resize((int(x), int(y)), Image.ANTIALIAS).crop(box) # save resized file - resized_filename = '%s/%s.jpg' %(crop_dir, set.id) + resized_filename = '%s/%s.jpg' % (crop_dir, set.id) try: if img.format == 'JPEG': resized.save(resized_filename, 'JPEG', quality=95, optimize=True) else: resized.save(resized_filename) - except IOError, e: + except IOError as e: if os.path.isfile(resized_filename): os.unlink(resized_filename) raise e - #os.unlink(img) - - - + # os.unlink(img) |