- 浏览: 333450 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
zhengqiweiyi:
请问这里的客户端和服务器是指同一台电脑上的吗?
JSP动态显示服务器时间和客户端时间 -
18101095336:
一语道破天机[color=blue][/c ...
restlet使用中遇到的一些问题 -
jjjssh:
废话一大堆,就是没说到少了那个jar包
The hierarchy of the type is inconsistent -
junjielee:
重点还没说啊~~~~~~~~
The hierarchy of the type is inconsistent -
幽绿琵琶:
太棒了
loadrunner 9.5 9.0 8.1下载地址 和license
1.log.conf,python的日志模块,详见:http://www.red-dove.com/python_logging.html
[loggers] keys=root,upload,resize [handlers] keys=consoleHandler,uploadFileHandler,resizeFileHandler [formatters] keys=simpleFormatter [formatter_simpleFormatter] format=%(asctime)s %(levelname)s %(message)s [logger_root] level=DEBUG handlers=consoleHandler [logger_upload] level=DEBUG handlers=uploadFileHandler qualname=upload [logger_resize] level=DEBUG handlers=resizeFileHandler qualname=resize [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [handler_uploadFileHandler] class=handlers.TimedRotatingFileHandler level=DEBUG formatter=simpleFormatter args=('upload.log',"midnight", 1) [handler_resizeFileHandler] class=handlers.TimedRotatingFileHandler level=DEBUG formatter=simpleFormatter args=('resize.log',"midnight", 1)
跟java中的log4j很类似,定义三个logger对象:root,upload,resize,其中root是StreamHandler类型,使用sys.out;upload和resize是TimedRotatingFileHandler,每天生成一个日志文件的方式。
2.conf.py配置文件
FILE_BIG_PATH = '/data/hiluofilev2/big/' FILE_SMALL_PATH = '/data/hiluofilev2/small/' HEAD_BIG_PATH = '/data/hiluohead/big/' HEAD_SMALL_PATH = '/data/hiluohead/small/' GEARMAN_SERVER = '127.0.0.1:4730' RESIZE_WORKER = 'resize' FILE_RESIZE = '140x160!' HEAD_RESIZE = '86x86!' IMAGE_FILE = ['jpg','png','gif','jpeg'] AUDIO_FILE = ['amr'] HTTP_FILE = 'http://192.168.0.181:9999/file/' HTTP_HEAD = 'http://192.168.0.181:9999/head/' import logging import logging.config import os logging.config.fileConfig(os.path.join(os.path.dirname(os.path.abspath(__file__)), "log.conf"))
FILE_BIG_PATH:这几个PATH表示原图和缩略图保存路径,根据业务区分,用户头像和用户上传的文件分开存放。
GEARMAN_SERVER:gearman Server端的地址。
RESIZE_WORKER:执行图片缩放的worker的名字。
FILE_RESIZE和HEAD_RESIZE:普通图片和头像的缩放尺寸。
IMAGE_FILE和AUDIO_FILE:系统支持的图片格式和音频文件格式,业务上仅支持两种类型。
HTTP_FILE和HTTP_HEAD:文件下载的HTTP前缀。
然后是初始化logging的功能。
3.worker_resize.py 生成缩略图的worker
#!/usr/bin/env python import os import gearman import math import conf import logging import pickle from pgmagick import Image, FilterTypes log_resize = logging.getLogger("resize") class CustomGearmanWorker(gearman.GearmanWorker): def on_job_execute(self, current_job): log_resize.info("Resize Worker started") return super(CustomGearmanWorker, self).on_job_execute(current_job) def resize_task_callback(gearman_worker, job): filein = job.data.split('-')[0] fileout = job.data.split('-')[1] fileresize = job.data.split('-')[2] log_resize.info('start filein:%s -> fileout:%s' % (filein,fileout)) im = Image(filein) im.quality(80) im.filterType(FilterTypes.SincFilter) im.scale(fileresize) im.sharpen(1.0) im.write(fileout) log_resize.info('end filein:%s -> fileout:%s' % (filein,fileout)) return job.data new_worker = CustomGearmanWorker([conf.GEARMAN_SERVER]) new_worker.register_task("resize", resize_task_callback) new_worker.work()
jobdata是string,filein代表原图路径,fileout代表缩略图路径,fileresize代表缩放尺寸
4.upload.py 用于上传文件和测试上传文件,使用web.py实现
#!/usr/bin/env python # coding: utf-8 import web import conf import logging import gearman urls = ( '/', 'Index', '/upload', 'FileUpload' ) app = web.application(urls, globals()) log_upload = logging.getLogger("upload") # get some directories in conf file filebigdir = conf.FILE_BIG_PATH filesmalldir = conf.FILE_SMALL_PATH headbigdir = conf.HEAD_BIG_PATH headsmalldir = conf.HEAD_SMALL_PATH resize_client = gearman.GearmanClient([conf.GEARMAN_SERVER]) class Index: def GET(self): web.header("Content-Type","text/html; charset=utf-8") return """<html><head></head><body>this hiluofileV2</body></html>""" class FileUpload: def GET(self): web.header("Content-Type","text/html; charset=utf-8") return """<html><head></head><body> <form method="POST" enctype="multipart/form-data" action=""> username:<input type="text" name="username" size="20" /><br/> md5 or sha1:<input type="text" name="md5orsha1" size="80"/><br/> <input type="file" name="myfile" /> <br/> <input type="submit" /> </form> </body></html>""" def POST(self): client = web.ctx.environ['REMOTE_ADDR'] x = web.input(myfile={},username="",md5orsha1="") username = x.username.encode('utf-8') intusername = 0 try: intusername = int(username) # check if the username is right except ValueError: log_upload.error('ip:%s username:%s username not right!' % (client,username)) return 'error[username]' md5orsha1 = x.md5orsha1.encode('utf-8') # check if the md5orsha1 is right if len(md5orsha1)==32 or len(md5orsha1)==40: if 'myfile' in x: # check if the file-object is created filepath = x.myfile.filename.replace('\\','/') filename = filepath.split('/')[-1] filesuffix = filename.split('.')[-1].lower() filename = md5orsha1.lower() + '.' + filesuffix # get saved filename(md5orsha1+‘.’+suffix) filebig = filebigdir + filename if filesuffix in conf.AUDIO_FILE: # audio file just save no need to resize fout = open(filebig,'w') # creates the file where the uploaded file should be stored fout.write(x.myfile.file.read()) # writes the uploaded file to the newly created file. fout.close() # closes the file, upload complete. log_upload.info('ip:%s username: %d upload: %s ok!' % (client,intusername,filename)) fileurl = conf.HTTP_FILE + 'big/' + filename # file download url return fileurl elif filesuffix in conf.IMAGE_FILE: filesmall = filesmalldir + filename # thumbnail file fileresize = conf.FILE_RESIZE # default FILE_RESIZE fileurl = conf.HTTP_FILE + 'small/' + filename if len(md5orsha1)==40: # user upload head filebig = headbigdir + filename filesmall = headsmalldir + filename # thumbnail head fileresize = conf.HEAD_RESIZE # thumbnail head HEAD_RESIZE fileurl = conf.HTTP_HEAD + 'small/' + filename fout = open(filebig,'w') # creates the file where the uploaded file should be stored fout.write(x.myfile.file.read()) # writes the uploaded file to the newly created file. fout.close() # closes the file, upload complete. log_upload.info('ip:%s username:%d upload:%s ok!' % (client,intusername,filename)) jobdata = ('%s-%s-%s' % (filebig,filesmall,fileresize)) resize_client.submit_job(conf.RESIZE_WORKER, jobdata) # submit_job resize and ignore job result log_upload.info('submit resize:%s ok!' % (jobdata)) return fileurl else: log_upload.error('ip:%s username:%d upload:%s unsupport file type' % (client,intusername,filename)) return 'error[filetype]' else: log_upload.error('ip:%s username:%d upload no myfile' % (client,intusername)) return 'error[myfile]' else: log_upload.error('ip:%s username:%d upload:%s unsupport md5orsha1' % (client,intusername,md5orsha1)) return 'error[filemd5orsha1]' if __name__ == "__main__": #app = web.application(urls, globals()) web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr) app.run()
这里业务上定义传头像的key是40位的sha1编码,普通图像文件是32位的md5编码。
5.nginx的nginx.conf修改,使用fastCGI方式运行,
在http节点下增加:
proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; #获取真实IP client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;
增加fastCGI静态图片的下载location,nginx开启8099端口代理fastCGI,9999端口用来下载文件
server{ listen 8099; server_name fast; charset utf-8; location / { fastcgi_param REQUEST_METHOD $request_method; fastcgi_param QUERY_STRING $query_string; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_pass 127.0.0.1:8091; } } server { listen 9999; server_name file.hiluo.cn; location /file/ { alias /data/hiluofilev2/; } location /head/ { alias /data/hiluohead/; } }
注意,在配置nginx的fastcgi时可能会报错如下:
5.1.child exited with 2
解决方法: insert #!/usr/bin/env python into header of main.py
5.2.spawn-fcgi child exited with 126
解决方法: chmod +x upload.py
5.3.child exited with1
这时可以先修改upload.py,屏蔽web.wsgi.runwsgi行,打开app = web.application(urls, globals())行,用python upload.py 8091方式启动测试。
6.hiluo-file-http.sh,runwsgi的启动停止管理脚本
#!/bin/sh # # hiluo-file-http control # $Date: 2012-07-04 willzhai $ # # If pid file path is not set elsewhere, set to /tmp/hiluo-file-http.pid [ -z "$PIDFILE" ] && PIDFILE="/tmp/hiluo-file-http.pid" dir=/root/test-file-v2 start() { echo "Starting hiluo-file-http..." exec_result=`spawn-fcgi -d $dir -f $dir/upload.py -a 127.0.0.1 -p 8091` echo $exec_result if [ ! -z "$PIDFILE" ]; then echo $exec_result|awk -F ':' '{print $4}' > $PIDFILE fi } stop() { # Stop daemons. echo "Shutting down hiluo-file-http..." kill `pgrep -f "python $dir/upload.py"` rm -f $PIDFILE } restart() { stop sleep 3 # give it a few moments to shut down start } status() { pid=`cat $PIDFILE 2>&1` if [ "$?" = "1" ]; then echo "hiluo-file-http is not running" RETVAL=0 else ps -p $pid > /dev/null 2>&1 if [ "$?" = "0" ]; then echo "hiluo-file-http is running" RETVAL=0 else echo "hiluo-file-http is not running" RETVAL=0 fi fi } case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) echo "Usage $0 {start|stop|restart|status}" RETVAL=1 esac exit $?
注意将dir改成实际的部署路径。这个可以再改进,自动识别当前路径。
7.hiluo-file-resize.sh ,resize worker的启动停止管理脚本
#!/bin/sh # # hiluo-file-resize control # $Date: 2012-07-04 willzhai $ # # If pid file path is not set elsewhere, set to /tmp/hiluo-file-resize.pid [ -z "$PIDFILE" ] && PIDFILE="/tmp/hiluo-file-resize.pid" dir=/root/test-file-v2 start() { echo "Starting hiluo-file-resize..." exec_command="exec python $dir/worker_resize.py 2>&1 &" eval $exec_command RETVAL=$? if [ $RETVAL -eq 0 -a ! -z "$PIDFILE" ]; then echo $! > $PIDFILE fi echo "hiluo-file-resize new pid: "`cat $PIDFILE` } stop() { # Stop daemons. echo "Shutting down hiluo-file-resize..." kill `pgrep -f "python $dir/worker_resize.py"` rm -f $PIDFILE } restart() { stop sleep 3 # give it a few moments to shut down start } status() { pid=`cat $PIDFILE 2>&1` if [ "$?" = "1" ]; then echo "hiluo-file-resize is not running" RETVAL=0 else ps -p $pid > /dev/null 2>&1 if [ "$?" = "0" ]; then echo "hiluo-file-resize is running" RETVAL=0 else echo "hiluo-file-resize is not running" RETVAL=0 fi fi } case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) echo "Usage $0 {start|stop|restart|status}" RETVAL=1 esac exit $?
注意将dir改成实际的部署路径。这个可以再改进,自动识别当前路径。
8.效果如下
8.1上传页面
8.2上传成功页面
8.3缩略图页面
文件打包下载见附件!
参考:
http://webpy.org/cookbook/storeupload/
http://webpy.org/cookbook/fastcgi-nginx
http://www.pythonclub.org/python-basic/string
http://hi.baidu.com/thinkinginlamp/blog/item/4b61e9241f08820f4c088d95.html
相关推荐
4. **保存缩略图**:使用`ImageIO.write()`方法将缩略图保存为新的文件或写入输出流,供网络传输。 除了基本的缩放,我们还可以添加其他功能,比如裁剪、旋转、添加边框等。如果需要处理大量图像,可以考虑使用多...
5. 存储与展示:生成的缩略图可以存储在服务器的特定目录,数据库中记录其路径,以便在网页上展示。在前端,使用HTML和JavaScript加载并显示这些缩略图,如在`<img>`标签的`src`属性中引用。 总之,实现C#视频上传...
在IT领域,文件上传、生成缩略图以及生成水印是常见的操作,广泛应用于网站开发、图像处理和数字媒体管理中。以下是对这些知识点的详细解释: 1. 文件上传: 文件上传是用户通过Web界面将本地计算机上的文件传输到...
对于大型网站或应用,为了提高效率,还可以采用异步处理,即先将原始图片存储,然后在后台生成缩略图。 文件名"myupload"可能指的是一个与多图片上传相关的文件,可能包含了实现上述功能的代码示例、配置文件或测试...
一个优秀的图片缩略图上传类能够极大地提升用户体验,节省服务器资源,同时保持图片展示的清晰度和美观性。本文将深入探讨“好用的图片缩略图上传类”,并基于给出的标签“源码”和“工具”进行详细的分析。 首先,...
文件的存储路径、缩略图路径、水印图路径都是通过此方法生成的。 7. **文件上传**:如果文件存在且满足条件,`FileUpload1.SaveAs(webFilePath)`将上传的文件保存到服务器指定位置。 8. **缩略图生成**:生成缩略...
本篇将详细讲解如何使用ASP.NET中的FileUpload控件来实现图片上传,并结合C#后端代码自动生成带有文字和图片水印的缩略图。 首先,`FileUpload`控件是ASP.NET提供的一种用于上传文件的服务器控件。在HTML页面中,...
- 保存新生成的缩略图到服务器。 4. 安全措施: 在处理图片上传时,还需要考虑安全方面,例如: - 防止文件覆盖:确保新上传的文件不会覆盖现有文件。 - 检查文件大小:限制上传文件的最大大小,防止服务器被...
焦点/幻灯图通常指的是自动播放并循环显示的图片展示效果,与“带左右按钮和缩略图”的焦点图类似,但可能不包含手动切换的按钮。 从【压缩包子文件的文件名称列表】来看,只有一个名为“带左右按钮和缩略图的焦点...
本篇文章将详细解析如何使用C#语言实现图片的上传及自动生成缩略图的功能。 #### 二、核心知识点 ##### 1. 图片上传流程 - **接收用户上传的文件**:通过HTML表单提交文件,服务器端使用`HtmlInputFile`类接收文件...
在提供的文件列表中,`uploadC.php`可能是包含图片上传和处理逻辑的类文件,它可能封装了上述提到的功能,如接收上传文件、验证、生成缩略图和加水印。`index.php`很可能是前端页面,负责展示上传界面,用户通过这个...
5. **异步处理**:对于大尺寸图片或者需要生成多张缩略图的情况,可以考虑使用异步操作,避免阻塞主线程,提升服务器响应速度。 6. **安全性**:在处理用户上传的图片时,需要注意安全问题,如防止图片注入攻击,...
在这个场景下,批量生成缩略图意味着程序会自动读取指定目录下的所有图片,根据预设的参数(如宽度、高度、保持比例等)生成缩略图,并保存到目标位置。 4. **缩略图生成**: 缩略图生成通常包括以下几个步骤: -...
此外,使用队列处理或异步任务来分批生成缩略图,可以防止服务器过载。 6. **错误处理**:在实际应用中,可能会遇到各种问题,比如文件不存在、格式不支持、权限不足等,因此代码应该有良好的错误处理机制,记录并...
C#(Asp.net)作为Microsoft开发的服务器端编程语言,提供了丰富的库和功能来处理图像操作,包括生成缩略图。以下是对"生成缩略图"这一知识点的详细讲解。 1. **基本概念**: - **缩略图**:缩略图是指较小尺寸的...
本教程将详细介绍如何整合`Uploadify`与`ThinkPHP`实现图片上传并自动生成缩略图。 1. **Uploadify介绍** `Uploadify`允许用户批量上传文件,支持多浏览器兼容,包括IE6。其特点在于异步上传,无需刷新页面即可...
这个处理程序检查是否有文件上传,然后保存文件到服务器,并调用`GenerateThumbnail`方法生成缩略图。 **生成缩略图** 生成缩略图通常涉及到图像处理库,如ImageMagick或System.Drawing。以下是一个使用System....
这段代码中,`-i`参数指定输入的视频文件,`-vf 'scale=640:-2'`用来调整缩略图的尺寸,这里设置为640像素宽,高度自动保持比例。`-vframes 1`表示只抽取一帧作为缩略图,最后`$thumbnailPath`是保存缩略图的路径。 ...
使用缩略图或按需加载来减少网络请求;使用GIF或WebP格式来降低图片大小。 9. **生命周期管理**:确保在Activity或Fragment的生命周期方法中正确管理和释放资源,防止内存泄漏。 10. **代码示例**:提供的"Android...