Github Pages的相册模块

1

status: ✘ ✔

目前已应用在 image

  • a.文件共享:由s3之类的中实现:图像存储是由一种与 blog 服务分离的文件共享服务处理的。
    • 1.功能:
      • ✔ create album
      • ✔ add photo to album
      • ✔ delete album
      • ✔ update albums.json -> create, delete album
      • ✔ update album_name.json -> add, delete photo
      • ✘ delete photo from album //需要web界面
      • ✔ thumbnail for albums
    • 2.数据
      • ✔ 相册集:/photos/ albums.json
        [
        { /* 相册1 */
          name: 'web-design',
          cover: 'http://xxx.com/d354dfgr.jpg', 
          intro: '相册描述',
          tags: ['design', 'website'],
          created: '2014-09-06',
          last_update: null,
        }, 
        ...
        ]
        
      • ✔ 相册:/photos/album/ album_name.json
        [
        { /* 图片1 */
          url: 'http://dafdfsa/dsfajl.jpg',
          intro: '截图1.jpg',
          tags: [],
        }, 
        ...
        ]
        
    • 3.实现: bi-fabfile.py
  • b.图片组织:由jeklly中实现:相册本质上是一种 blog 服务,为其 blog post提供了一种更加特定于域的视图。用户相册中的每张照片都由一个 blog 文章表示,这些照片(blog 文章)再被组织成各个相册(blog 类别)并用tags加以标记。

bi-fabfile.py

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

from fabric.api import local, lcd
from functools import wraps
from urllib2 import quote
from os import path
import json
import time

import osscmd


_bucket = 's-3'
_user = 'blog-photos'
_photos = 'oss://s-3/blog-photos'
_cdn = 'http://img3.url2io.com'


def check_res(res, msg=""):
    if res.status / 100 == 2:
        print '\n'
        print "%s OK" % msg
        print '\n'
    else:
        print '\n'
        print "%s FAIL" % msg
        print "ret:%s" % res.status
        print "request-id:%s" % res.getheader("x-oss-request-id")
        print "reason:%s" % res.read()
        print '\n'
        exit(-1)


def update(action=''):
    def deco(f):
        @wraps(f)
        def _(*args, **kwargs):
            f(*args, **kwargs)
            if action == 'albums':
                update_albums()
            else:
                update_album(args[0])
        return _
    return deco


@update('albums')
def create_album(name, local_dir=None):
    """create album <usage: create_album:name,local_dir[default=None]>
    """
    # create album
    # mkdir oss://bucket/dirname/name
    local("./osscmd mkdir oss://%s/%s/%s" % (_bucket, _user, name) )

    # add_photos to album
    if local_dir: add_photo(name, local_dir)


@update('albums')
def delete_album(name):
    """delete album <usage: delete_album:name>
    """
    # deleteallobject oss://bucket/[prefix]
    local("./osscmd deleteallobject oss://%s/%s/%s" % (_bucket, _user, name) )
    # delete album.json
    local("./osscmd deleteallobject oss://%s/%s_json/album/%.json" % (_bucket,_user, name) )


@update()
def add_photo(album_name, local_obj):
    """add photo to album <usage: add_photo:album_name, pic|dir>
    """
    # TODO 重复处理
    if path.isdir(local_obj):
        # uploadfromdir localdir oss://bucket/[prefix] --check_point=check_point_file
        local('./osscmd uploadfromdir "%s" oss://%s/%s/%s' %\
                (local_obj, _bucket,_user,album_name) )
    else:
        # upload localfile oss://bucket/object --content-type=[content_type]
        local('./osscmd multiupload "%s" oss://%s/%s/%s' % \
                (local_obj, _bucket,_user,album_name) )


#@update()
#def delete_photo(album, photo):
#    """delete photo from album //需要web界面
#    """
#    # rm oss://bucket/dirname
#    local("rm oss://%s/%s/%s/%s" % \
#            (_bucket, _user, album, photo) )
#
#
#@update()
#def delete_photos(album, photos):
#    """delete photo from album //需要web界面
#    """
#    pass
#
#@update()
#def delete_all_photos(album):
#    """delete photo from album //需要web界面
#    """
#    # deleteallobject oss://bucket/[prefix]
#    local("deleteallobject oss://%s/%s/%s" % \
#            (_bucket, _user, album) )


def update_albums():
    """<usage update_album>
    update albums.json -> create, delete album
    [
      { /* 相册1 */
        name: 'web-design',
        cover: 'http://xxx.com/d354dfgr.jpg', 
        intro: '相册描述',
        tags: ['design', 'website'],
        created: '2014-09-06',
        last_update: null,
      }, 
      ...
    ]
    """
    # listalldir oss://bucket/[prefix]
    albums_json = []
    oss = osscmd.get_oss()
    (object_list, dir_list, marker) = osscmd.GetAllObjects().get_object_dir_in_bucket(
            oss, _bucket, '', '%s/'%_user, '/') # unicode
    # TODO marker != ''
    for album in dir_list:
        print 'album: ',album
        albums_json.append({
            u'name': album.split('/')[1],
            u'cover': None,
            u'intro': '',
            u'tags': [],
            u'created': '',
            u'last_update': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()),
        })

    # upload name.json to oss
    res = oss.put_object_from_string(
        _bucket, 
        '%s_json/albums.json'%_user, 
        json.dumps(albums_json,ensure_ascii=False).encode('utf-8'),
        content_type='application/json; charset=utf-8',
        headers={'Expires':'max'}
    )
    check_res(res, 'update albums.json')


def update_album(name):
    """<usage update_album:name>
    update album.json -> add, delete photo
    [
      { /* 图片1 */
        url: 'http://dafdfsa/dsfajl.jpg',
        intro: '截图1.jpg',
        tags: [],
      }, 
      ...
    ]
    """
    # listallobject oss://bucket/[prefix]
    album_json = []
    oss = osscmd.get_oss()
    (object_list, marker) = osscmd.GetAllObjects().get_object_in_bucket(
            oss, _bucket, '', '/'.join([_user, name]))
    # TODO marker != ''
    for photo in object_list[1:]:
        album_json.append({
            'url': '%s/%s'%(_cdn, quote(photo)),
            'intro': '', 
            'tags': [],
        })

    # upload name.json to oss
    res = oss.put_object_from_string(
        _bucket, 
        '%s_json/album/%s.json'%(_user,name),
        json.dumps(album_json),
        content_type='application/json; charset=utf-8',
        headers={'Expires':'max'}
    )
    check_res(res, 'update %s.json'%name)
blog原型设计稿 aliyun first time
>