[关闭]
@skyway 2015-06-10T03:39:59.000000Z 字数 6788 阅读 1633

图床——基于七牛JS-SDK和KVDB

python kvdb 七牛 JS

原文链接:图床——基于七牛JS-SDK和KVDB

浏览

上传

服务端获取token

  1. # -*- coding: utf-8 -*-
  2. __author__ = 'Sky'
  3. import qiniu
  4. from datetime import datetime
  5. import config
  6. def get_token():
  7. q = qiniu.Auth(config.QINIU_ACCESS_KEY, config.QINIU_SECRET_KEY)
  8. # print str(datetime.now())
  9. token = q.upload_token(config.PIC_BUCKET)
  10. return token

JS上传到七牛

详细使用可参考七牛JS-SDK

  1. var uploader = Qiniu.uploader({
  2. runtimes: 'html5,flash,html4',
  3. browse_button: 'pickfiles',
  4. container: 'container',
  5. drop_element: 'container',
  6. max_file_size: '100mb',
  7. filters: {
  8. mime_types: [
  9. { title: "图片文件", extensions: "jpg,gif,png,bmp" }
  10. ],
  11. prevent_duplicates: true //不允许队列中存在重复文件
  12. },
  13. flash_swf_url: '/static/js/plupload/Moxie.swf',
  14. dragdrop: true,
  15. chunk_size: '4mb',
  16. uptoken_url: $('#uptoken_url').val(),
  17. domain: $('#domain').val(),
  18. auto_start: true,
  19. init: {
  20. 'FilesAdded': function(up, files) {
  21. $('table').show();
  22. $('#success').hide();
  23. plupload.each(files, function(file) {
  24. var progress = new FileProgress(file, 'fsUploadProgress');
  25. progress.setStatus("等待...");
  26. });
  27. },
  28. 'BeforeUpload': function(up, file) {
  29. var progress = new FileProgress(file, 'fsUploadProgress');
  30. var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
  31. if (up.runtime === 'html5' && chunk_size) {
  32. progress.setChunkProgess(chunk_size);
  33. }
  34. },
  35. 'UploadProgress': function(up, file) {
  36. var progress = new FileProgress(file, 'fsUploadProgress');
  37. var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
  38. progress.setProgress(file.percent + "%", up.total.bytesPerSec, chunk_size);
  39. },
  40. 'UploadComplete': function() {
  41. $('#success').show();
  42. },
  43. 'FileUploaded': function(up, file, info) {
  44. var progress = new FileProgress(file, 'fsUploadProgress');
  45. progress.setComplete(up, info);
  46. var res = $.parseJSON(info);
  47. // 请求后台存储
  48. var domain = up.getOption('domain');
  49. //url = domain + encodeURI(res.key);
  50. var link = domain + res.key;
  51. var key = res.key;
  52. $.ajax({
  53. url:"/upQiniu",
  54. type: "POST",
  55. data: { key: key, url: link}
  56. })
  57. .done(function(data){
  58. if(data === 'error') {
  59. alert('上传失败');
  60. location.reload(true);
  61. }
  62. });
  63. },
  64. 'Error': function(up, err, errTip) {
  65. $('table').show();
  66. var progress = new FileProgress(err.file, 'fsUploadProgress');
  67. progress.setError();
  68. progress.setStatus(errTip);
  69. }
  70. ,
  71. 'Key': function(up, file) {
  72. //当前时间戳
  73. var key = new Date();
  74. return key.getTime()
  75. }
  76. }
  77. });

保存信息到KVDB

  1. # -*- coding: utf-8 -*-
  2. __author__ = 'Sky'
  3. import sae
  4. import json
  5. import sae.kvdb
  6. class KvdbStorage():
  7. # 初始化kvdb
  8. def __init__(self):
  9. self.kv = sae.kvdb.KVClient()
  10. # 获取value
  11. def get_value(self, key):
  12. return self.kv.get(key)
  13. # 获取dict_value
  14. def get(self, key):
  15. string_value = self.kv.get(key)
  16. if string_value is None:
  17. return None
  18. return decode_dict(string_value)
  19. # 设置value
  20. def set_value(self, key, value):
  21. self.kv.set(key, value)
  22. # 设置dict_value
  23. def set(self, key, dict_value):
  24. string_value = encode_dict(dict_value)
  25. self.kv.set(key, string_value)
  26. # 批量获取key
  27. def getkeys_by_prefix(self, prefix, limit=100, marker=None):
  28. return list(self.kv.getkeys_by_prefix(prefix, limit=limit, marker=marker))
  29. # 批量获取key/value
  30. def get_by_prefix(self, prefix, limit=100, marker=None):
  31. return self.kv.get_by_prefix(prefix, limit=limit, marker=marker)
  32. # 删除key
  33. def delete(self, key):
  34. self.kv.delete(key)
  35. # 编码字典
  36. def encode_dict(my_dict):
  37. return "\x1e".join("%s\x1f%s" % x for x in my_dict.iteritems())
  38. # 解码字典
  39. def decode_dict(my_string):
  40. return dict(x.split("\x1f") for x in my_string.split("\x1e"))
  1. # 上传文件到七牛
  2. @app.route('/upQiniu', methods=['POST', 'GET'])
  3. def upQiniu():
  4. if request.form.get('key'):
  5. url = request.form.get('url')
  6. upkey = request.form.get('key')
  7. # 时间差,用于加载排序
  8. import time
  9. future_time = int(time.mktime(datetime.strptime('3000-01-01 00:00:00.000', "%Y-%m-%d %H:%M:%S.%f").timetuple()) * 1000)
  10. uid = future_time - int(upkey)
  11. # 存入DB
  12. key = 'picbed_%s' % uid
  13. object = 'Sunset Lake'
  14. words = 'A peaceful sunset view...'
  15. author = 'skyway'
  16. # print key
  17. data = {'upkey': upkey, 'object': object, 'words': words, 'author': author, 'url': url}
  18. kv.set(str(key), data)
  19. # kv.set_value(str(key), url)
  20. return 'success'

浏览

访问获取key

  1. # 初始加载
  2. key_values = kv.get_by_prefix('picbed_', 20, None)
  3. # print sorted(kv.getkeys_by_prefix('picbed', 3, None))
  4. data = tuple(key_values)
  5. json_data = []
  6. for item in data:
  7. tmp = {}
  8. tmp['key'] = item[0]
  9. if '\x1e' in item[1]:
  10. content = decode_dict(item[1])
  11. # print content
  12. tmp['url'] = content['url'] + "?imageView2/2/w/400/format/jpg"
  13. tmp['object'] = content['object']
  14. tmp['words'] = content['words']
  15. tmp['upkey'] = content['upkey']
  16. tmp['author'] = content['author']
  17. else:
  18. tmp['url'] = item[1] + "?imageView2/2/w/400/format/jpg"
  19. tmp['object'] = 'Sunset Lake'
  20. tmp['words'] = 'A peaceful sunset view...'
  21. tmp['upkey'] = item[1][-13:]
  22. tmp['author'] = 'skyway'
  23. json_data.append(tmp)
  24. # data = sorted(data, reverse=True)
  25. # print data
  26. return render_template('PicBed.html', data=json_data, domain=config.PIC_DOMAIN)

瀑布流和数据加载

  1. # 加载更多
  2. if request.form.get('key'):
  3. key = request.form.get('key')
  4. # print key
  5. key_values = kv.get_by_prefix('picbed_', 10, key)
  6. # print sorted(kv.getkeys_by_prefix('picbed', 3, key))
  7. data = tuple(key_values)
  8. # data = sorted(data, reverse=True)
  9. print data
  10. json_data = []
  11. for item in data:
  12. tmp = {}
  13. tmp['key'] = item[0]
  14. if '\x1e' in item[1]:
  15. content = decode_dict(item[1])
  16. # print content
  17. tmp['url'] = content['url'] + "?imageView2/2/w/400/format/jpg"
  18. tmp['object'] = content['object']
  19. tmp['words'] = content['words']
  20. tmp['upkey'] = content['upkey']
  21. tmp['author'] = content['author']
  22. else:
  23. tmp['url'] = item[1] + "?imageView2/2/w/400/format/jpg"
  24. tmp['object'] = 'Sunset Lake'
  25. tmp['words'] = 'A peaceful sunset view...'
  26. tmp['upkey'] = item[1][-13:]
  27. tmp['author'] = 'skyway'
  28. json_data.append(tmp)
  29. json_str = json.dumps(json_data)
  30. return json_str
  1. $(window).scroll(function () {
  2. var clientHeight = $(window).height(),
  3. scrollTop = $(window).scrollTop(),
  4. scrollHeight = $(document).height();
  5. if (!isScroll && (scrollHeight - clientHeight - scrollTop < 500)) {
  6. isScroll = 1;
  7. $('#loading').show();
  8. // 获取最后一个块的key
  9. var key = $('.grid:last-child').data('key');
  10. // 请求数据
  11. $.ajax({
  12. url:"/picbed",
  13. type: "POST",
  14. data: { key: key}
  15. })
  16. .done(function(data){
  17. if(data === 'error') {
  18. alert('加载失败');
  19. location.reload(true);
  20. return false;
  21. }
  22. var pics = JSON.parse(data);
  23. //没有更多了
  24. if(jQuery.isEmptyObject(pics)){
  25. $('#load_img').hide();
  26. $('#load_text').text('没有更多了!');
  27. $('#contain').BlocksIt('reload');
  28. return false;
  29. }
  30. $.each(pics, function(index, val){
  31. var add =
  32. "<div class='grid' data-key='" + this.key +"'>" +
  33. "<div class='imgholder'>" +
  34. "<a class='fopLink' data-key='"+ this.upkey + "'>" +
  35. "<img class='img_load' src='" + this.url +"' />" +
  36. "</a>" +
  37. "</div>" +
  38. "<span class='stop'></span>" +
  39. "<strong>"+ this.object +"</strong>" +
  40. "<div class='description'>" +
  41. "<p>"+ this.words +"</p>" +
  42. "<div class='meta'>by " + this.author +"</div>" +
  43. "</div>"+
  44. "</div>";
  45. $("#contain").append(add);
  46. // 动态加载渲染图片
  47. img_stop();
  48. });
  49. $('#contain').BlocksIt('reload');
  50. });
  51. }
  52. });

长图渲染

对于过长的图片,影响整个浏览的体验,于是超过一定长度的图片,超出部分隐藏,并在图片尾部添加波浪表示图片未展示完全。

  1. // 渲染图片函数
  2. var img_stop = function(){
  3. var height = 800;
  4. $('.img_load').each(function() {
  5. $(this).load(function(){
  6. if( $(this).height() > height){
  7. $(this).parent().parent().next().css('display', 'block');
  8. }
  9. });
  10. });
  11. };
  12. // 初始加载渲染图片
  13. $(function(){
  14. img_stop();
  15. });
  16. var img_load = function(url, key) {
  17. var img = new Image();
  18. img.src = url;
  19. img.onload = load_img(img, key);
  20. function load_img(img, key){
  21. var height = img.height;
  22. if( height > 500){
  23. var str = 'div[data-key=' + key + ']';
  24. $(str).find('.stop').css('display', 'block');
  25. }
  26. }
  27. };

效果

GitHub源码

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注