GAEPhotos V0.4 发布了

2010年12月23日 gully 3 条评论

下载地址: http://code.google.com/p/gaephotos/downloads/list

演示地址: http://gaephotos.deepgully.com

  1. 支持拖拽上传.
  2. 优化cache, 最高达80%的性能提升.
  3. 增加计划任务(corn task)和代码缓存.
  4. 修复相册管理中的javascript bug.

Update 2011-7-6: 更新到V0.42, 解决appspot.com被GFW的问题. http://code.google.com/p/gaephotos/issues/detail?id=7

分类: Google, Web/Django/GAE 标签:

javascript实现拖拽多文件上传(支持firefox/chrome)

2010年12月17日 gully 没有评论

利用DragAndDrop事件实现拖拽处理,利用FileReader和XMLHttpRequest实现多文件读取和上传,还可以监控上传进度.

1. 实现拖拽主要是利用了dragenter,dragover,dragleave和drop这几个事件.

var ddupload = ddupload || function(){};  

container = document.getElementsByName("album");
savedBackColor = container.style.backgroundColor;
container.addEventListener("dragenter", function(event){
    event.stopPropagation();event.preventDefault();  //跳过浏览器的默认处理
    container.style.backgroundColor = "red";
}, false);
container.addEventListener("dragover", function(event){
//理论上不需要处理这个事件,但实际上不行,否则浏览器还是会调用默认事件
    event.stopPropagation();event.preventDefault();
    container.style.backgroundColor = "red";
}, false);
container.addEventListener("dragleave", function(event){
    event.stopPropagation();event.preventDefault();
    container.style.backgroundColor = savedBackColor;
}, false);
container.addEventListener("drop", function(event){
    event.stopPropagation();event.preventDefault();
    container.style.backgroundColor = savedBackColor;
    //drop事件,在这里处理拖进来的文件
        // files = event.dataTransfer.files; 可以得到文件列表
        ddupload.processdroppedfile(event);
}, false);

2. 通过FileReader读取文件内容, 请参考 http://developer.mozilla.org/en/DOM/FileReader
例子中是读取并显示图片

ddupload.filelimit = 8*1024*1024;
ddupload.filetypes = "jpg,png,gif,jpeg",
ddupload.processdroppedfile = function (event) {
    var files = event.dataTransfer.files;  //得到文件列表
    for (var i = 0; i < files.length; i++) {
        if(files[i].size < ddupload.filelimit) {
            var  file = files[i];
            /* check file ext */
            filename = file.name.split('.');
            ext = filename[filename.length-1];

            if ( ddupload.filetypes.indexOf(ext) >= 0 )
            {
                localreader = new FileReader();
                localreader.file = file;
                localreader.onload = function(event){
                     //文件读取完成的回调函数, 可以在这里处理上传
                     f = event.target.file; //得到文件对象
                     data = event.target.result; //得到文件内容(raw binary data )
                     //上传文件内容
                     ddupload.processXHR(f, data);
                };
                localreader.readAsBinaryString(file);
        }
        else {
            alert("file size exceed!");
        } /*end if*/
    } /*end for*/
};

3. 接下来终于到上传文件了, 利用XMLHttpRequest,
请参考 http://developer.mozilla.org/cn/XMLHttpRequest

//这个是状态回调函数,详细内容请看MDC的文档
ddupload.on_XHR_state_change_handler = function(xhr, evt) {
    if (xhr.readyState == 4) {
        if(xhr.status == 200) {
            //上传成功
        } else {
            //失败处理  :(
        }
    }
};

ddupload.processXHR = function (file, bin) {
    var xhr = new XMLHttpRequest(),
         xhrupload = xhr.upload;

        xhrupload.addEventListener("progress", function(event) {
            if (event.lengthComputable) {
                var percentage = Math.round((event.loaded * 100) / event.total);
                //处理上传进度
            }
        }, false);

    xhr.onreadystatechange = function (evt) {
        evt.file = file;
        ddupload.on_XHR_state_change_handler(xhr, evt);
    };
    xhr.open("POST", "http://localhost/upload/"); //指定POST的URL
    xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
    xhr.setRequestHeader('Content-Disposition',
                                  "{'filename':file.name}");  //附带一些自定义数据
    if(xhr.sendAsBinary) xhr.sendAsBinary(bin);  //firefox支持sendAsBinary
    else xhr.send(file);  //chrome(8.0.552.215 beta) 只支持send
};

下面是完整的包
ddupload.zip

使用方法:
1. 实现处理函数

<script src='ddupload.js'></script>
<script type='text/javascript'>
var postdata_handler = function(file, container)
{   /* post data in 'Content-Disposition' */
    return '{"albumid":"'+ container.id +'","filename":"'+file.name+'"}';
};
var loadedhandler = function(reader_event, container)
{   /* handler on local file loaded */
    console.log(reader_event.target.file.name);
};
var progresshandler = function(file, percentage, container)
{   /* handler on upload progress */
    console.log(percentage);
};
var onupload_success_handler = function(xhr, evt, container)
{   /* handler on success upload(status = 200) */
     console.log(xhr.responseText);
};
var onupload_success_handler = function(xhr, evt, container)
{   /* handler on failed upload(status != 200) */
    console.log(xhr.responseText);
};

window.onload = function(evt) {  //绑定onload
            ddupload.setup('dragtohere', { //这里是ddupload的配置
                    filetypes : "jpg,png,gif,jpeg",
                    filelimit : 8*1024*1024,
                    posturl : "http://localhost:8080/admin/uploadv2/",
                    postdata_handler : postdata_handler,
                    loadedhandler : loadedhandler,
                    progresshandler : progresshandler,
                    onupload_success_handler : onupload_success_handler,
                    onupload_failed_handler: onupload_failed_handler,
                    });
};
</script>

2. html代码

<style type='text/css'>
#dragtohere {
width:152px;
height: 152px;
margin: 20px auto;
border:2pt solid black;
}
</style>

<div id='display-area'>
<h2>Drag and Drop Upload Sample</h2>
<div id='dragtohere'>Drag and Drop to here</div>
<div id='progressbar'></div>
<div id='result'></div>
</div>
分类: Web/Django/GAE 标签:

嵌套的dict按对象方式操作

2010年12月17日 gully 没有评论

直接上代码:

class Struct(object):
    def __init__(self, d):
        self.__dict__ = d
       
def dict_to_struct(d):
    if isinstance(d, (list, tuple)): return map(dict_to_struct, d)
    elif not isinstance(d, dict): return d
    return Struct(dict((k, dict_to_struct(v)) for (k,v) in d.iteritems()))

d = {'a': 1,  'b': {'c': 2},  
     'd': [ [{'s':'s',  'l': [{"ss":"ss"},1]},],
            {'foo': "bar"}],
     }

x = dict_to_struct(d)
print(x.a)
print(x.b.c)
print(x.d[1].foo)

print(x.d[0][0].s)
print(x.d[0][0].l[0].ss)

x.d[0][0].l[0].ss = "CCC"
print(x.d[0][0].l[0].ss)
分类: Python 标签:

GAE Appspot.com貌似解封了

2010年12月13日 gully 没有评论

RT

测试   http://gaephotos.appspot.com

Update:

2010-10-13  正常

分类: Google, Web/Django/GAE 标签: ,

GAEPhotos v0.3发布了

2010年12月11日 gully 没有评论

下载地址:  http://code.google.com/p/gaephotos/downloads/list

演示地址: http://gaephotos.deepgully.com

  1. 突破GAE的1M文件限制,可以上传超过1M的图片了,最大到8M.
  2. 增加批量移动文件和删除文件的支持.
  3. 修复了相册不能删除和空相册不能保存信息的bug.
  4. 修复了上传文件中断导致相片列表不可用的bug.
分类: Google, Web/Django/GAE 标签:
本WordPress博客由爱写字提供技术支持