Source

sa3album / models.py

#!/usr/bin/env python
# coding:utf-8

"""
Created by ben on 2010/10/26 .
Copyright (c) 2010 http://sa3.org All rights reserved. 
"""
import re
import logging
import random
import string
import os

from google.appengine.ext import db
from util.b36 import Base36
from util.base import filter_url
from google.appengine.api import images
from google.appengine.api import memcache

class Album(db.Model):
    '''
    sa3album Album Model
    '''
    slug = db.StringProperty()
    name = db.StringProperty()
    description = db.StringProperty()
    created = db.DateTimeProperty(auto_now_add=True)
    last_updated = db.DateTimeProperty(auto_now=True)
    cover_url = db.StringProperty()

    def put(self):
        self.slug = self.key().name()
        super(Album,self).put()
    
    @property
    def url(self):
        return "/b/%s/" % (self.slug)
    
    @property
    def m_url(self):
        return "/a/album/manage/%s/" % (self.slug)
    
    @property
    def count(self):
        return Image.all().filter('album =',self).count()
    
    @classmethod
    def add(cls,name):
        album = Album(name = name,key_name = Counter.get_max('album'))
        album.put()
        return album
    
class Image(db.Model):
    '''
    sa3album Photo Model
    '''
    album = db.ReferenceProperty(Album)
    name = db.StringProperty()
    mime = db.StringProperty()
    size = db.IntegerProperty()
    created = db.DateTimeProperty(auto_now_add=True)
    description = db.StringProperty()
    width = db.IntegerProperty()
    height =db.IntegerProperty()
    bf = db.BlobProperty()
    
    view_count = db.IntegerProperty(default=0) #view count
    
    def delete(self):
        memcache.delete("s::%s" % self.key().name())
        memcache.delete("f::%s" % self.key().name())
        super(Image,self).delete()
    
    @property
    def url(self):
        return "/d/%s/" %(self.key().name())
    
    @property
    def s(self):
        ''' small image url '''
        return "/s/%s/" %(self.key().name())
    
    @property
    def download_url(self):
        '''downlaod url'''
        return "/e/%s/" % (self.key().name())
    
    @property
    def f(self):
        return "/f/%s/" %(self.key().name())
    
    @property
    def copyurl(self):
        return "http://%s/f/%s/" %(os.environ['HTTP_HOST'],self.key().name())
    
    @property
    def next(self):
        '''return next image'''
        return Image.all().filter('album =',self.album).order('created').filter('created >', self.created).get()
    
    @property
    def prev(self):
        '''return  prev image'''
        return Image.all().filter('album =',self.album).order('-created').filter('created <', self.created).get()
    
    @property
    def small(self):
        '''
        return 120 images
        '''
        key = "s::%s" % (self.key().name())
        data = memcache.get(key)
        if data is None:
            logging.info("get data from db : %s " % key)
            img = images.Image(image_data=self.bf)
            img.resize(width = 120) if img.height > img.width else img.resize(height = 120)
            tmp = 120 * max(img.height,img.width) / min(img.height,img.width)
            if tmp > 120:
                img.crop(0.0,0.0,1.0,1.0*120/tmp) if img.height > img.width else \
                   img.crop(0.0,0.0,1.0*120/tmp,1.0)
                
            data = img.execute_transforms(output_encoding=images.JPEG)
            memcache.set(key,data,3600*24)
        return data
    
    @classmethod
    def add(cls,album,name,mime,bf,**kwargs):
        key_name = Counter.get_max('image')
        img = Image(album=album,name=name,mime=mime,bf=bf,key_name = key_name,**kwargs)
        img.size = len(img.bf)
        t = images.Image(image_data=bf)
        img.width = t.width
        img.height = t.height
        img.put()
        return img
    @classmethod
    def get_by_key_name_with_cache(cls,key_name):
        key = "f::%s" % key_name
        data = memcache.get(key)
        if data is None:
            data =Image.get_by_key_name(key_name)
            memcache.set(key,data,3600*24)
        return data
            
    
class Counter(db.Model):
    '''
    sa3album Counter Model
    '''
    name = db.StringProperty(required=False)
    value = db.StringProperty(default ='0') #use base36
    created = db.DateTimeProperty(auto_now_add =True)
    last_updated = db.DateTimeProperty(auto_now = True)
    
    def put(self):
        self.name = self.key().name()
        super(Counter,self).put()
        
    @classmethod
    def get_count(cls,key_name):
        obj = Counter.get_by_key_name(key_name)
        if obj is None:
            obj = Counter(key_name = key_name)
            obj.value = '0'
            obj.put()
        return obj
    
    @classmethod
    def get_max(cls,key_name):
        '''
        return max value +1
        '''
        obj = Counter.get_count(key_name)
        obj.value = Base36(obj.value)+1
        obj.put()
        return obj.value
       
    
class Setting(db.Model):
    name = db.StringProperty()
    theme = db.StringProperty()
    skey = db.StringProperty()
    is_anti_leech = db.BooleanProperty(default=False)
    allow_list = db.StringListProperty()
    anti_leech_img = db.StringProperty()
    copy_txt = db.StringProperty()
    api_keys = db.StringListProperty()

    version = '0.1.0'
    
    @classmethod
    def get_s(cls):
        s = Setting.get_by_key_name('s')
        if s is None:
            skey = ''.join(random.sample(string.ascii_letters,16))
            s = Setting(key_name = 's',name ='sa3album',theme='default',skey=skey)
            s.put()
            #add default album
            Album.add('default')
        return s
    

if __name__=='__main__':
    pass