コード例 #1
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def update_gift_cache(op,gid,uid=None):
    gs = from_cache('BD_GIFTS_ALL')
    if gs and not gid in gs:
        if op == 'add':
            gs.append(gid)
        elif op == 'del':
            gs.remove(gid)
        to_cache('BD_GIFTS_ALL', gs)
    gs = from_cache('BD_GIFTS_%s'%uid)
    if gs and not gid in gs:
        if op == 'add':
            gs.append(gid)
        elif op == 'del':
            gs.remove(gid)
        to_cache('BD_GIFTS_%s'%uid)
コード例 #2
0
def update_gift_cache(op, gid, uid=None):
    gs = from_cache('BD_GIFTS_ALL')
    if gs and not gid in gs:
        if op == 'add':
            gs.append(gid)
        elif op == 'del':
            gs.remove(gid)
        to_cache('BD_GIFTS_ALL', gs)
    gs = from_cache('BD_GIFTS_%s' % uid)
    if gs and not gid in gs:
        if op == 'add':
            gs.append(gid)
        elif op == 'del':
            gs.remove(gid)
        to_cache('BD_GIFTS_%s' % uid)
コード例 #3
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def load_stories(game='all',cursor='',pagesize=50,sortorder='-postime'):
    """ Return a page of stories.
        This function makes use of cursor mechanism to fetch pages and cache them for efficient repeated queries.
        Once a page of SuiStory entities are loaded, they are memcached with the cursor.
        If not enough entities are loaded, cursor is None meaning no more pages.
        Stories are sorted for display by postime in descending order.
        Pages are always in memcache of 'Stories', invalidated when a new story is added.
        @param game : game key or all
        @param cursor : from which cursor to fetch, '' = first page
        @param pagesize : how many for a page, default 30
        @param sortorder : postime in descending by default, can be 'title', 'author'
        @return : ([SuiStory,...],cursor) tuple of a list of SuiStory entities or None
    """
    cachekey = 'Stories_%s_%s'%(game,cursor)
    stories = from_cache(cachekey)
    if stories is None:
        if game != 'all':
            query = SuiStory.all().filter('game =',game).order(sortorder)
        else:
            query = SuiStory.all().order(sortorder)
        if cursor != '':
            query.with_cursor(cursor)
        mstories = query.fetch(pagesize)
        if len(mstories) > 0:
            c = None
            if len(mstories) >= pagesize:
                c = query.cursor()
            stories = (mstories,c or '')
            to_cache(cachekey,stories)
        else:
            stories = ([],'')
    return stories
コード例 #4
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def add_story(me,title,content,game):
    """ save a story in my name.
    """
    if title is None or title == '':
        logging.warning('title is empty')
        raise Exception('No title')
    if content is None or content == '':
        logging.warning('content is empty')
        raise Exception('No content')
    s = SuiStory()
    s.title = title.replace('<','&lt;')
    #s.text = content.replace('<','&lt;').replace('\n','<br/>').replace('\r','')
    s.game = game
    s.author = me.key().name()
    s.aname = me.name
    s.postime = datetime.utcnow()
    s.put()
    #save content text into SuiContent
    c = SuiContent(parent=s)
    if content.find('\n')>=0:
        content = content.replace('\r\n','<br>').replace('\n','<br>');
    c.text = XML_REPTN.sub(filter_tag, content)
    c.length = len(c.text)
    c.put()
    pages = from_cache('Stories_all')
    if pages is not None:
        page1 = pages[0]
        if len(page1[0]) > 40:
            decaches(['Stories_all','NewStories'])
        else:
            page1[0].insert(0,s)
            to_cache('Stories_all',pages)
            decache('NewStories')
コード例 #5
0
def add_comment(me, story, comment):
    """ Add a comment """
    if isinstance(story, basestring):
        skey = db.Key(story)
    else:
        skey = story
    if not comment:
        return
    elif comment.find('\n'):
        comment = comment.replace('\r\n', '<br>').replace('\n', '<br>')
    mckey = str(skey) + '_cms'
    content = from_cache(mckey)
    if content is None:
        content = SuiContent.all().ancestor(skey).fetch(10)
        if not content:
            raise Exception('Story not found')
    c = content[-1]
    cp = 'c%d' % c.count
    c.count += 1
    pfx = '[%s:%s@%s]' % (me.key().name(), me.name,
                          datetime.strftime(datetime.utcnow(),
                                            '%Y-%m-%d %H:%M:%S'))
    setattr(c, cp, '%s%s' % (pfx, XML_REPTN.sub(filter_tag, comment)))
    c.put()
    to_cache(mckey, content)
コード例 #6
0
def load_comments0(story, page=0, pagesize=50):
    """ Load a page of comments for a story. Page of comments are also memcached until a new comment is added.
    """
    if isinstance(story, SuiStory):
        skey = story.key()
    elif isinstance(story, basestring):
        skey = db.Key(story)
    else:
        skey = story
    mckey = str(skey) + '_cms'
    comments = from_cache(mckey)
    if comments is None:
        query = SuiComment.all().filter('story =', skey).order('-postime')
        cmts = query.fetch(pagesize)
        if len(cmts) > 0:
            c = None
            if len(cmts) >= pagesize:
                c = query.cursor()
            comments = [(cmts, c)]
            to_cache(mckey, comments)
        else:
            return [([], None)]
    elif page >= len(comments) and comments[-1][1] is not None:
        query = SuiComment.all().filter('story =', skey).order('-postime')
        query.with_cursor(comments[-1][1])
        cmts = query.fetch(pagesize)
        if len(cmts) >= pagesize:
            comments.append((cmts, query.cursor()))
        else:
            comments.append((cmts, None))
        to_cache(mckey, comments)
    return comments[page]
コード例 #7
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def load_comments0(story,page=0,pagesize=50):
    """ Load a page of comments for a story. Page of comments are also memcached until a new comment is added.
    """
    if isinstance(story,SuiStory):
        skey = story.key()
    elif isinstance(story,basestring):
        skey = db.Key(story)
    else:
        skey = story
    mckey = str(skey)+'_cms'
    comments = from_cache(mckey)
    if comments is None:
        query = SuiComment.all().filter('story =',skey).order('-postime')
        cmts = query.fetch(pagesize)
        if len(cmts) > 0:
            c = None
            if len(cmts) >= pagesize:
                c = query.cursor()
            comments = [(cmts,c)]
            to_cache(mckey, comments)
        else:
            return [([],None)]
    elif page >= len(comments) and comments[-1][1] is not None:
        query = SuiComment.all().filter('story =',skey).order('-postime')
        query.with_cursor(comments[-1][1])
        cmts = query.fetch(pagesize)
        if len(cmts) >= pagesize:
            comments.append((cmts,query.cursor()))
        else:
            comments.append((cmts,None))
        to_cache(mckey,comments)
    return comments[page]
コード例 #8
0
def add_story(me, title, content, game):
    """ save a story in my name.
    """
    if title is None or title == '':
        logging.warning('title is empty')
        raise Exception('No title')
    if content is None or content == '':
        logging.warning('content is empty')
        raise Exception('No content')
    s = SuiStory()
    s.title = title.replace('<', '&lt;')
    #s.text = content.replace('<','&lt;').replace('\n','<br/>').replace('\r','')
    s.game = game
    s.author = me.key().name()
    s.aname = me.name
    s.postime = datetime.utcnow()
    s.put()
    #save content text into SuiContent
    c = SuiContent(parent=s)
    if content.find('\n') >= 0:
        content = content.replace('\r\n', '<br>').replace('\n', '<br>')
    c.text = XML_REPTN.sub(filter_tag, content)
    c.length = len(c.text)
    c.put()
    pages = from_cache('Stories_all')
    if pages is not None:
        page1 = pages[0]
        if len(page1[0]) > 40:
            decaches(['Stories_all', 'NewStories'])
        else:
            page1[0].insert(0, s)
            to_cache('Stories_all', pages)
            decache('NewStories')
コード例 #9
0
def load_stories(game='all', cursor='', pagesize=50, sortorder='-postime'):
    """ Return a page of stories.
        This function makes use of cursor mechanism to fetch pages and cache them for efficient repeated queries.
        Once a page of SuiStory entities are loaded, they are memcached with the cursor.
        If not enough entities are loaded, cursor is None meaning no more pages.
        Stories are sorted for display by postime in descending order.
        Pages are always in memcache of 'Stories', invalidated when a new story is added.
        @param game : game key or all
        @param cursor : from which cursor to fetch, '' = first page
        @param pagesize : how many for a page, default 30
        @param sortorder : postime in descending by default, can be 'title', 'author'
        @return : ([SuiStory,...],cursor) tuple of a list of SuiStory entities or None
    """
    cachekey = 'Stories_%s_%s' % (game, cursor)
    stories = from_cache(cachekey)
    if stories is None:
        if game != 'all':
            query = SuiStory.all().filter('game =', game).order(sortorder)
        else:
            query = SuiStory.all().order(sortorder)
        if cursor != '':
            query.with_cursor(cursor)
        mstories = query.fetch(pagesize)
        if len(mstories) > 0:
            c = None
            if len(mstories) >= pagesize:
                c = query.cursor()
            stories = (mstories, c or '')
            to_cache(cachekey, stories)
        else:
            stories = ([], '')
    return stories
コード例 #10
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def load_gifts(uid=None):
    """ Load gift ids from SuiBirthdayGift entities and store in memcache by BD_GIFTS_ALL or BD_GIFTS_creatorID
        Maximum number of gifts in use for all is 10000, while any creator can have no more than 20
    """
    if uid:
        gs = from_cache('BD_GIFTS_%s'%uid)
        if not gs:
            es = SuiBirthdayGift.all(keys_only=True).filter('creator =',uid).fetch(50)
            gs = [e.id_or_name() for e in es]
            to_cache('BD_GIFTS_%s'%uid, gs)
    else:
        gs = from_cache('BD_GIFTS_ALL')
        if not gs:
            es = SuiBirthdayGift.all(keys_only=True).fetch(10000)
            gs = [e.id_or_name() for e in es]
            to_cache('BD_GIFTS_ALL', gs)
    return gs
コード例 #11
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def get_new_stories(N=10):
    """ Load N latest stories, return [[key,title],..] """
    stories = from_cache('NewStories')
    if stories is None:
        qs = SuiStory.all().order('-postime').fetch(N)
        stories = [[str(q.key()),q.title] for q in qs]
        to_cache('NewStories',stories)  #only when new stories added, invalidate this cache
    return stories
コード例 #12
0
def load_gifts(uid=None):
    """ Load gift ids from SuiBirthdayGift entities and store in memcache by BD_GIFTS_ALL or BD_GIFTS_creatorID
        Maximum number of gifts in use for all is 10000, while any creator can have no more than 20
    """
    if uid:
        gs = from_cache('BD_GIFTS_%s' % uid)
        if not gs:
            es = SuiBirthdayGift.all(keys_only=True).filter('creator =',
                                                            uid).fetch(50)
            gs = [e.id_or_name() for e in es]
            to_cache('BD_GIFTS_%s' % uid, gs)
    else:
        gs = from_cache('BD_GIFTS_ALL')
        if not gs:
            es = SuiBirthdayGift.all(keys_only=True).fetch(10000)
            gs = [e.id_or_name() for e in es]
            to_cache('BD_GIFTS_ALL', gs)
    return gs
コード例 #13
0
def get_new_stories(N=10):
    """ Load N latest stories, return [[key,title],..] """
    stories = from_cache('NewStories')
    if stories is None:
        qs = SuiStory.all().order('-postime').fetch(N)
        stories = [[str(q.key()), q.title] for q in qs]
        to_cache('NewStories',
                 stories)  #only when new stories added, invalidate this cache
    return stories
コード例 #14
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def get_news():
    """ read system news if any """
    news = from_cache(gGameNewsCacheKey)
    if news is None:
        return '[]'
    newsbuf = []
    td = datetime.utcnow()
    for ns in news:
        if ns[1] > td:
            newsbuf.append(ns[0])
    return newsbuf
コード例 #15
0
def get_news():
    """ read system news if any """
    news = from_cache(gGameNewsCacheKey)
    if news is None:
        return '[]'
    newsbuf = []
    td = datetime.utcnow()
    for ns in news:
        if ns[1] > td:
            newsbuf.append(ns[0])
    return newsbuf
コード例 #16
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def lock_process(lock_key):
    """ Emulate a lock to stop the code going on if the process is still going on.
        This can happen when a user repeatedly clicks on buy button that causes invalid transaction.
        If memcache is not available, this will definately raise an exception and causes the routine to fail.
        Algorithm: check whether a memcache is available, if not, add it for 30 seconds, and return, if yet, raises ServerBusy exception.
    """
    lock = from_cache(lock_key)
    if lock is None:
        if to_cache(lock_key,lock_key,30) == False:
            raise Exception('Server Error, try later')
    else:
        raise Exception('Server Busy, try later')
コード例 #17
0
def lock_process(lock_key):
    """ Emulate a lock to stop the code going on if the process is still going on.
        This can happen when a user repeatedly clicks on buy button that causes invalid transaction.
        If memcache is not available, this will definately raise an exception and causes the routine to fail.
        Algorithm: check whether a memcache is available, if not, add it for 30 seconds, and return, if yet, raises ServerBusy exception.
    """
    lock = from_cache(lock_key)
    if lock is None:
        if to_cache(lock_key, lock_key, 30) == False:
            raise Exception('Server Error, try later')
    else:
        raise Exception('Server Busy, try later')
コード例 #18
0
def add_comment0(me, story, content):
    """ Add a comment to a story. """
    c = SuiComment()
    c.story = db.Key(story)
    logging.debug(story)
    c.text = content
    c.author = '%s[%s]' % (me.name, me.key().name())
    c.postime = datetime.utcnow()
    c.put()
    mckey = str(story) + '_cms'
    if mckey is not None:
        pages = from_cache(mckey)
        if pages is not None:
            page1 = pages[0][0]
            if len(page1) > 60:
                decache(mckey)
            else:
                page1.insert(0, c)
                to_cache(mckey, pages)
コード例 #19
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def add_comment0(me,story,content):
    """ Add a comment to a story. """
    c = SuiComment()
    c.story = db.Key(story)
    logging.debug(story)
    c.text = content
    c.author = '%s[%s]'%(me.name,me.key().name())
    c.postime = datetime.utcnow()
    c.put()
    mckey = str(story)+'_cms'
    if mckey is not None:
        pages = from_cache(mckey)
        if pages is not None:
            page1 = pages[0][0]
            if len(page1) > 60:
                decache(mckey)
            else:
                page1.insert(0,c)
                to_cache(mckey,pages)
コード例 #20
0
def load_comments(story, page=0):
    """ Load all SuiContent entities for story and return text and comments of first entity.
        @param story - key string of SuiStory
        @param page - which entity of SuiContent for this story, 0 first by default, can be 10 pages maximum.
    """
    if isinstance(story, basestring):
        skey = db.Key(story)
    else:
        skey = story
    mckey = str(skey) + '_cms'
    content = from_cache(mckey)
    if content is None:
        content = SuiContent.all().ancestor(skey).fetch(10)
        if content:
            to_cache(mckey, content)
        else:
            return None
    if len(content) > page:
        return content[page]
    else:
        return content[-1]
コード例 #21
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def load_comments(story,page=0):
    """ Load all SuiContent entities for story and return text and comments of first entity.
        @param story - key string of SuiStory
        @param page - which entity of SuiContent for this story, 0 first by default, can be 10 pages maximum.
    """
    if isinstance(story,basestring):
        skey = db.Key(story)
    else:
        skey = story
    mckey = str(skey)+'_cms'
    content = from_cache(mckey)
    if content is None:
        content = SuiContent.all().ancestor(skey).fetch(10)
        if content:
            to_cache(mckey, content)
        else:
            return None
    if len(content) > page:
        return content[page]
    else:
        return content[-1]
コード例 #22
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def get_user_by_key(uid,usecache=True):
    """ Get SuiUser entity from datastore by key_name, return None if not existent. 
    @param uid: fb_1234 like
    @param usecache: if True, Get from memcache first, and Put in memcache or not, default is True.
    """
    if usecache:
        u = from_cache(uid)
    else:
        u = None
    if not u:
        logging.debug('UID %s not in memcache'%uid)
        try:
            u = SuiUser.get_by_key_name(uid)
            if u is None:
                logging.debug('User not in SuiUser')
                return u
            if usecache:
                u._cache_time = datetime.utcnow()
                to_cache(uid, u, PLAYER_CACHE_SECS)
        except Exception,e:
            logging.error('helper.get_user_by_key(%s) error:%s' % (uid,e))
            raise
コード例 #23
0
def get_user_by_key(uid, usecache=True):
    """ Get SuiUser entity from datastore by key_name, return None if not existent. 
    @param uid: fb_1234 like
    @param usecache: if True, Get from memcache first, and Put in memcache or not, default is True.
    """
    if usecache:
        u = from_cache(uid)
    else:
        u = None
    if not u:
        logging.debug('UID %s not in memcache' % uid)
        try:
            u = SuiUser.get_by_key_name(uid)
            if u is None:
                logging.debug('User not in SuiUser')
                return u
            if usecache:
                u._cache_time = datetime.utcnow()
                to_cache(uid, u, PLAYER_CACHE_SECS)
        except Exception, e:
            logging.error('helper.get_user_by_key(%s) error:%s' % (uid, e))
            raise
コード例 #24
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def add_comment(me,story,comment):
    """ Add a comment """
    if isinstance(story,basestring):
        skey = db.Key(story)
    else:
        skey = story
    if not comment:
        return
    elif comment.find('\n'):
        comment = comment.replace('\r\n','<br>').replace('\n','<br>')
    mckey = str(skey)+'_cms'
    content = from_cache(mckey)
    if content is None:
        content = SuiContent.all().ancestor(skey).fetch(10)
        if not content:
            raise Exception('Story not found')
    c = content[-1]
    cp = 'c%d' % c.count
    c.count += 1
    pfx = '[%s:%s@%s]'%(me.key().name(),me.name,datetime.strftime(datetime.utcnow(),'%Y-%m-%d %H:%M:%S'))
    setattr(c, cp, '%s%s'%(pfx, XML_REPTN.sub(filter_tag, comment)))
    c.put()
    to_cache(mckey, content)
コード例 #25
0
def query_user_by_key(uid):
    u = from_cache(uid)
    if not u:
        u = SuiUser.get_by_key_name(uid)
    return u
コード例 #26
0
ファイル: helper.py プロジェクト: abelenki/suicomics
def query_user_by_key(uid):
    u = from_cache(uid)
    if not u:
        u = SuiUser.get_by_key_name(uid)
    return u