时间:2021-07-01 10:21:17 帮助过:18人阅读
前期准备 通过 pip 或 easy_install 安装了 pymongo 之后, 就能通过 Python 调教 mongodb 了. 接着安装个 flask 用来当 web 服务器. 当然 mongo 也是得安装的. 对于 Ubuntu 用户, 特别是使用 Server 12.04 的同学, 安装最新版要略费些周折, 具体说是 sudoapt
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
sudo apt-get update
sudo apt-get install mongodb-10gen
pip install Pillow
easy_install Pillow
import flask
app = flask.Flask(__name__)
app.debug = True
@app.route('/upload', methods=['POST'])
def upload():
f = flask.request.files['uploaded_file']
print f.read()
return flask.redirect('/')
@app.route('/')
def index():
return '''
'''
if __name__ == '__main__':
app.run(port=7777)
upload
函数中, 使用 flask.request.files[KEY]
获取上传文件对象, KEY 为页面 form 中 input 的 name 值import pymongo
import bson.binary
from cStringIO import StringIO
app = flask.Flask(__name__)
app.debug = True
db = pymongo.MongoClient('localhost', 27017).test
def save_file(f):
content = StringIO(f.read())
db.files.save(dict(
content=bson.binary.Binary(content.getvalue()),
))
@app.route('/upload', methods=['POST'])
def upload():
f = flask.request.files['uploaded_file']
save_file(f)
return flask.redirect('/')
bson.binary.Binary
对象, 再把它扔进 mongodb 就可以了.db.files.find()
content
这个域几乎肉眼无法分辨出什么东西, 即使是纯文本文件, mongo 也会显示为 Base64 编码.def save_file(f):
content = StringIO(f.read())
c = dict(content=bson.binary.Binary(content.getvalue()))
db.files.save(c)
return c['_id']
@app.route('/f/
def serve_file(fid):
f = db.files.find_one(bson.objectid.ObjectId(fid))
return f['content']
@app.route('/upload', methods=['POST'])
def upload():
f = flask.request.files['uploaded_file']
fid = save_file(f)
return flask.redirect('/f/' + str(fid))
upload
函数会跳转到对应的文件浏览页. 这样一来, 文本文件内容就可以正常预览了, 如果不是那么挑剔换行符跟连续空格都被浏览器吃掉的话.bson.errors.InvalidId
; 其二, 找不到对象 (!), 这时 pymongo 会返回 None
.@app.route('/f/
def serve_file(fid):
import bson.errors
try:
f = db.files.find_one(bson.objectid.ObjectId(fid))
if f is None:
raise bson.errors.InvalidId()
return f['content']
except bson.errors.InvalidId:
flask.abort(404)
from PIL import Image
allow_formats = set(['jpeg', 'png', 'gif'])
def save_file(f):
content = StringIO(f.read())
try:
mime = Image.open(content).format.lower()
if mime not in allow_formats:
raise IOError()
except IOError:
flask.abort(400)
c = dict(content=bson.binary.Binary(content.getvalue()))
db.files.save(c)
return c['_id']
def save_file(f):
content = StringIO(f.read())
try:
mime = Image.open(content).format.lower()
if mime not in allow_formats:
raise IOError()
except IOError:
flask.abort(400)
c = dict(content=bson.binary.Binary(content.getvalue()), mime=mime)
db.files.save(c)
return c['_id']
@app.route('/f/
def serve_file(fid):
try:
f = db.files.find_one(bson.objectid.ObjectId(fid))
if f is None:
raise bson.errors.InvalidId()
return flask.Response(f['content'], mimetype='image/' + f['mime'])
except bson.errors.InvalidId:
flask.abort(404)
db.files.drop()
清掉原来的数据.import datetime
def save_file(f):
content = StringIO(f.read())
try:
mime = Image.open(content).format.lower()
if mime not in allow_formats:
raise IOError()
except IOError:
flask.abort(400)
c = dict(
content=bson.binary.Binary(content.getvalue()),
mime=mime,
time=datetime.datetime.utcnow(),
)
db.files.save(c)
return c['_id']
@app.route('/f/
def serve_file(fid):
try:
f = db.files.find_one(bson.objectid.ObjectId(fid))
if f is None:
raise bson.errors.InvalidId()
if flask.request.headers.get('If-Modified-Since') == f['time'].ctime():
return flask.Response(status=304)
resp = flask.Response(f['content'], mimetype='image/' + f['mime'])
resp.headers['Last-Modified'] = f['time'].ctime()
return resp
except bson.errors.InvalidId:
flask.abort(404)
db.files.ensureIndex({sha1: 1}, {unique: true})
import hashlib
def save_file(f):
content = StringIO(f.read())
try:
mime = Image.open(content).format.lower()
if mime not in allow_formats:
raise IOError()
except IOError:
flask.abort(400)
sha1 = hashlib.sha1(content.getvalue()).hexdigest()
c = dict(
content=bson.binary.Binary(content.getvalue()),
mime=mime,
time=datetime.datetime.utcnow(),
sha1=sha1,
)
try:
db.files.save(c)
except pymongo.errors.DuplicateKeyError:
pass
return c['_id']
c['_id']
将会是一个不存在的数据 ID. 修正这个问题, 最好是返回 sha1
, 另外, 在访问文件时, 相应地修改为用文件 SHA-1 访问, 而不是用 ID.import hashlib
import datetime
import flask
import pymongo
import bson.binary
import bson.objectid
import bson.errors
from cStringIO import StringIO
from PIL import Image
app = flask.Flask(__name__)
app.debug = True
db = pymongo.MongoClient('localhost', 27017).test
allow_formats = set(['jpeg', 'png', 'gif'])
def save_file(f):
content = StringIO(f.read())
try:
mime = Image.open(content).format.lower()
if mime not in allow_formats:
raise IOError()
except IOError:
flask.abort(400)
sha1 = hashlib.sha1(content.getvalue()).hexdigest()
c = dict(
content=bson.binary.Binary(content.getvalue()),
mime=mime,
time=datetime.datetime.utcnow(),
sha1=sha1,
)
try:
db.files.save(c)
except pymongo.errors.DuplicateKeyError:
pass
return sha1
@app.route('/f/
def serve_file(sha1):
try:
f = db.files.find_one({'sha1': sha1})
if f is None:
raise bson.errors.InvalidId()
if flask.request.headers.get('If-Modified-Since') == f['time'].ctime():
return flask.Response(status=304)
resp = flask.Response(f['content'], mimetype='image/' + f['mime'])
resp.headers['Last-Modified'] = f['time'].ctime()
return resp
except bson.errors.InvalidId:
flask.abort(404)
@app.route('/upload', methods=['POST'])
def upload():
f = flask.request.files['uploaded_file']
sha1 = save_file(f)
return flask.redirect('/f/' + str(sha1))
@app.route('/')
def index():
return '''
'''
if __name__ == '__main__':
app.run(port=7777)
原文地址:Flask / MongoDB 搭建简易图片服务器, 感谢原作者分享。