博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
6 网站架构---mongo使用
阅读量:2771 次
发布时间:2019-05-13

本文共 12531 字,大约阅读时间需要 41 分钟。

models_mongo.py:创建数据库、集合、model

# coding=utf-8import osimport uuidimport magicimport urllibfrom datetime import datetimeimport cropresize2import short_urlfrom PIL import Imagefrom flask import abort, requestfrom werkzeug.utils import cached_propertyfrom mongoengine import (    Document as BaseDocument, connect, ValidationError, DoesNotExist,    QuerySet, MultipleObjectsReturned, IntField, DateTimeField, StringField,    SequenceField)from app.ik_global import ik_globalfrom app.utils.mimes import IMAGE_MIMES, AUDIO_MIMES, VIDEO_MIMESfrom app.utils.ik_util import get_file_md5, get_file_pathfrom config import Config# ik_global.Logger.info("MONGO_DB_HOST-------------> {}".format(Config.MONGO_DB_HOST))connect(Config.MONGO_DB_NAME, host=Config.MONGO_DB_HOST, port=int(Config.MONGO_DB_PORT))class BaseQuerySet(QuerySet):    def get_or_404(self, *args, **kwargs):        try:            return self.get(*args, **kwargs)        except (MultipleObjectsReturned, DoesNotExist, ValidationError):            abort(404)class Document(BaseDocument):    meta = {'abstract': True,            'queryset_class': BaseQuerySet            }class PasteFile(Document):    id = SequenceField(primary_key=True)    filename = StringField(max_length=5000, null=False)    filehash = StringField(max_length=128, null=False, unique=True)    filemd5 = StringField(max_length=128, null=False, unique=True)    uploadtime = DateTimeField(null=False)    mimetype = StringField(max_length=128, null=False)    size = IntField(null=False)    meta = {'collection': 'paste_file'}  # 自定义集合的名字    def __init__(self, filename='', mimetype='application/octet-stream',                 size=0, filehash=None, filemd5=None, *args, **kwargs):        # 初始化父类的__init__方法        super(PasteFile, self).__init__(filename=filename, mimetype=mimetype,                                        size=size, filehash=filehash,                                        filemd5=filemd5, *args, **kwargs)        self.uploadtime = datetime.now()        self.mimetype = mimetype        self.size = int(size)        self.filehash = filehash if filehash else self._hash_filename(filename)        self.filename = filename if filename else self.filehash        self.filemd5 = filemd5    @staticmethod    def _hash_filename(filename):        _, _, suffix = filename.rpartition('.')        return '%s.%s' % (uuid.uuid4().hex, suffix)    @cached_property    def symlink(self):        return short_url.encode_url(self.id)    @classmethod    def get_by_symlink(cls, symlink, code=404):        id = short_url.decode_url(symlink)        return cls.objects.get_or_404(id=id)    @classmethod    def get_by_filehash(cls, filehash, code=404):        return cls.objects.get_or_404(filehash=filehash)    @classmethod    def get_by_md5(cls, filemd5):        rs = cls.objects(filemd5=filemd5)        return rs[0] if rs else None    @classmethod    def create_by_upload_file(cls, uploaded_file):        ik_global.Logger.info("uploaded_file----> {} {} {}".format(uploaded_file,                                                   uploaded_file.filename, uploaded_file.mimetype))        rst = cls(uploaded_file.filename, uploaded_file.mimetype, 0)        ik_global.Logger.info("rst.path----> {}".format(rst.path))        uploaded_file.save(rst.path)        with open(rst.path, "rb") as f:            filemd5 = get_file_md5(f)            uploaded_file = cls.get_by_md5(filemd5)            if uploaded_file:                os.remove(rst.path)                return uploaded_file        filestat = os.stat(rst.path)        rst.size = filestat.st_size        rst.filemd5 = filemd5        return rst    @classmethod    def create_by_old_paste(cls, filehash):        filepath = get_file_path(filehash)        mimetype = magic.from_file(filepath, mime=True)        filestat = os.stat(filepath)        size = filestat.st_size        rst = cls(filehash, mimetype, size, filehash=filehash)        return rst    @property    def path(self):        return get_file_path(self.filehash)    def get_url(self, subtype, is_symlink=False):        hash_or_link = self.symlink if is_symlink else self.filehash        return 'http://{host}/{subtype}/{hash_or_link}'.format(            subtype=subtype, host=request.host, hash_or_link=hash_or_link)    @property    def url_i(self):        return self.get_url('i')    @property    def url_p(self):        return self.get_url('p')    @property    def url_s(self):        return self.get_url('s', is_symlink=True)    @property    def url_d(self):        return self.get_url('d')    @property    def image_size(self):        if self.is_image:            im = Image.open(self.path)            return im.size        return (0, 0)    @property    def quoteurl(self):        return urllib.parse.quote(self.url_i)    @classmethod    def rsize(cls, old_paste, weight, height):        assert old_paste.is_image, TypeError('Unsupported Image Type.')        img = cropresize2.crop_resize(            Image.open(old_paste.path), (int(weight), int(height)))        rst = cls(old_paste.filename, old_paste.mimetype, 0)        img.save(rst.path)        filestat = os.stat(rst.path)        rst.size = filestat.st_size        return rst    @property    def is_image(self):        return self.mimetype in IMAGE_MIMES    @property    def is_audio(self):        return self.mimetype in AUDIO_MIMES    @property    def is_video(self):        return self.mimetype in VIDEO_MIMES    @property    def is_pdf(self):        return self.mimetype == 'application/pdf'    @property    def type(self):        for t in ('image', 'pdf', 'video', 'audio'):            if getattr(self, 'is_' + t):                return t        return 'binary'

ik_file_view.py:定义http接口

import loggingimport osimport timefrom datetime import datetimefrom app.comm import ik_commimport ipaddressfrom flask import abort, request, jsonify, redirect, send_filefrom flask_jwt import jwt_required, current_identityfrom werkzeug.contrib.cache import SimpleCachefrom flask import jsonifyimport jsonfrom app.ikdb.model.models_mongo import PasteFilefrom app.utils.ik_util import get_file_path, humanize_bytesfrom app.utils.status_code import err_resp_json_make, FAIL, succ_resp_json_make# from app.vpp.vpp import Pttoolfrom flask import BlueprintONE_MONTH = 60 * 60 * 24 * 30bp = Blueprint('file', __name__,url_prefix="/file")@bp.route('/rsize/
')def rsize(img_hash): w = request.args['w'] h = request.args['h'] old_paste = PasteFile.get_by_filehash(img_hash) new_paste = PasteFile.rsize(old_paste, w, h) return new_paste.url_i@bp.route('/download/
', methods=['GET'])def download(filehash): paste_file = PasteFile.get_by_filehash(filehash) return send_file(open(paste_file.path, 'rb'), mimetype='application/octet-stream', cache_timeout=ONE_MONTH, as_attachment=True, attachment_filename=paste_file.filename)@bp.route('/upload', methods=['POST'])def index(): if request.method == 'POST': uploaded_file = request.files['file'] # werkzeug.datastructures.FileStorage w = request.form.get('w') h = request.form.get('h') if not uploaded_file: return abort(400) if w and h: paste_file = PasteFile.rsize(uploaded_file, w, h) else: paste_file = PasteFile.create_by_upload_file(uploaded_file) paste_file.save() #保存到db return jsonify({ 'url_d': paste_file.url_d, 'url_i': paste_file.url_i, 'url_s': paste_file.url_s, 'url_p': paste_file.url_p, 'filename': paste_file.filename, 'size': humanize_bytes(paste_file.size), 'time': str(paste_file.uploadtime), 'type': paste_file.type, 'quoteurl': paste_file.quoteurl }) # return render_template('index.html', **locals()) return err_resp_json_make(FAIL, extra_errmsg="upload fail")@bp.route('/j', methods=['POST'])def j(): uploaded_file = request.files['file'] if uploaded_file: paste_file = PasteFile.create_by_upload_file(uploaded_file) paste_file.save() width, height = paste_file.image_size return jsonify({ 'url': paste_file.url_i, 'short_url': paste_file.url_s, 'origin_filename': paste_file.filename, 'hash': paste_file.filehash, 'width': width, 'height': height }) return abort(400)@bp.route('/preview/
')def preview(filehash): paste_file = PasteFile.get_by_filehash(filehash) if not paste_file: filepath = get_file_path(filehash) if not(os.path.exists(filepath) and (not os.path.islink(filepath))): return abort(404) paste_file = PasteFile.create_by_old_paste(filehash) paste_file.save() # return render_template('success.html', p=paste_file) return succ_resp_json_make(extra_errmsg="preview success")@bp.route('/s/
')def s(symlink): paste_file = PasteFile.get_by_symlink(symlink) return redirect(paste_file.url_p)

app/__init__.py: flask启动时,初始化mongodb,注册蓝图

#!/usr/bin/env python# -*- coding:utf-8 -*-# File: ik_agent.pyimport sysfrom flask import Flask, jsonify# from flask_jwt import JWTfrom config import configimport multiprocessing as mpfrom app.ik_global import ik_global, vpp_sig_registerfrom werkzeug.contrib.cache import SimpleCache# from app.vpp.vpp import Pttoolfrom app.comm import ik_commfrom app.comm.agent_process import AgentProcessfrom app.log import logfrom app.ik_global.ik_global import MP_LIST# from app.vpp.vpp import Pttoolfrom app.utils.threads import DaemonThreadTimerfrom app.comm.ik_thread_work import monitor_vpp_instance_statusfrom app.utils.ik_util import show_memory_infofrom app.utils.auth import authenticate, identityfrom app.utils.threads import set_intervalfrom app.ikdb.exts import dbfrom flask_jwt import JWTfrom werkzeug.contrib.profiler import ProfilerMiddlewarefrom werkzeug.wsgi import DispatcherMiddlewarefrom collections import OrderedDict# from app.views import json_pagedef creat_child_processes():    # 这个函数用于创建并启动agent的子进程,    # 子进程处理一些不需要运行在主进程的任务,    # 以提升主进程对 web 请求的响应性能。    # miscellaneous_works_init()    # 子进程退出流程,详见函数 kill_all_child    # 1 主进程捕获 gunicorn 的退出信号;    # 2 在主进程信号处理函数中,向各个子进程发送 TERM 信号;    # 3 子进程收到 TERM 信号后,进程自动退出    # agent_process.start()    # p = mp.Process(target=vpp_sig_register, name="recv_vpp_signal_process")    p = AgentProcess(target=vpp_sig_register, name="recv_vpp_signal_process")    p.start()    MP_LIST.append(p)'''def check_vpp():        if vpp:        vpp = ik_comm.connect_vpp()        ik_global.VPP_INSTANCE = vpp        # ik_global.Logger.info(ik_global.VPP_INSTANCE)        ik_comm.trigger_config_restore()        return True    return False'''def create_app(config_name):    app = Flask(__name__)    app.config.from_object(config[config_name])    app.config.setdefault('JWT_SECRET_KEY', 'secret')    app.debug = True    # db init     # 方式一    db.init_app(app=app)# 初始化连接数据库    # 方式二    from app.ikdb.exts import connect_db    # init log    # log.init_log(app)    ik_global.Logger = log.create_logger()    # mongodb init    from app.ikdb.model import models_mongo        # blueprint regester    from app.views import ik_user_view    from app.views import ik_agent_view    from app.views import ik_vpp_view    from app.views import ik_file_view    app.register_blueprint(ik_user_view.bp)    app.register_blueprint(ik_agent_view.bp)    app.register_blueprint(ik_vpp_view.bp)    app.register_blueprint(ik_file_view.bp)    # ik_global.ik_agent_sig_register()    # app.register_blueprint(ik_auth_view)    # open profile    # app.wsgi_app = ProfilerMiddleware(app.wsgi_app, profile_dir="/tmp")    # 自动封装请求路由为/j/开头的地址为jsonify格式    app.wsgi_app = DispatcherMiddleware(app.wsgi_app, OrderedDict((('/j', views.json_page),)))    ik_global.Logger.info("性能测试工具节点--agent启动成功!")    ik_global.Logger.info("版本号: {}".format(ik_global.__version__))    ik_global.Logger.info("agent: {} port: {}".format(config[config_name].LISTEN_ADDR, config[config_name].VPP_AGENT_LISTEN_PORT))    # ik_global.Logger.info("controller_url: {}{}".format(    #     config[config_name].CONTROLLER_HOST, config[config_name].CONTROLLER_HOST_PATH))    # ik_global.Logger.info(    #     "VPP_CORE_DIR: {}".format(config[config_name].VPP_CORE_DIR))    # ik_global.Logger.info(    #     "VPP_PLUGINS_DIR: {}".format(config[config_name].VPP_PLUGINS_DIR))    ik_global.Logger.info(show_memory_info("after vpp started"))    return app

 

转载地址:http://vsfld.baihongyu.com/

你可能感兴趣的文章
Android 内存优化实践与总结
查看>>
成为优秀程序员,从谦虚做起
查看>>
Java面试相关-- Java类加载全过程
查看>>
Java高级特性之枚举学习总结
查看>>
Java中的“抽象接口”
查看>>
Java程序员最亲睐的Web框架
查看>>
什么时候学习编程都不晚
查看>>
编程技术面试的五大要点
查看>>
学习JavaScript的理由
查看>>
怎么学JavaScript?
查看>>
Java初学者的30个常见问题
查看>>
Java核心技术点之泛型
查看>>
Java 常见内存溢出异常与代码实现
查看>>
JavaScript里的await/async的作用和用法
查看>>
三种软件工程师——编码员、程序师和架构师
查看>>
Java异常处理-----抛出处理
查看>>
Android 杂知识总结
查看>>
高效程序员的 7 个共同特征
查看>>
JavaScript易错知识点整理
查看>>
使用关键帧做动画
查看>>