Flaskで画像アップローダー

#簡易的な画像アップローダーを作成する

前回Twitter投稿クライアントを作成したので、Flaskのインストールとかは省略します。
　http://qiita.com/Gen6/items/ff1d163acf0fa7687454

#テンプレートを作る

```index.html
{% extends "base.html" %}
{% block content %}
<form method="post" action="/send" enctype="multipart/form-data">
  <input type="file" id="img_file" name="img_file" class="col-sm-4">
  <input type="submit" value="送信" class="btn">
</form>
  {% if img_url %}
<p><img src="{{ img_url }}"></p>
  {% endif %}
{% endblock %}
```

enctype="multipart/form-data" が重要です。

```base.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/css/style.css">
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <title>File</title>
</head>
<body>
  <div class="container">
    <div class="row">
        {% block content %}
        {% endblock %}
    </div>
  </div>
</body>
</html>
```

#アプリケーションを作成する

後はファイルアップロードを作っていきます。SQlite3は今後使うかもしれないのでインポートしてるだけです。

```upload.py
import os
import sqlite3
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session
from werkzeug import secure_filename
app = Flask(__name__)

UPLOAD_FOLDER = './uploads'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'gif'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['SECRET_KEY'] = os.urandom(24)

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

@app.route('/')
def index():
    if 'username' in session:
        return render_template('index.html')
    return '''
        <p>ログインしてください</p>
    '''

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        if username == 'admin':
            session['username'] = request.form['username']
            return redirect(url_for('index'))
        else:
            return '''<p>ユーザー名が違います</p>'''
    return '''
        <form action="" method="post">
            <p><input type="text" name="username">
            <p><input type="submit" value="Login">
        </form>
    '''

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

@app.route('/send', methods=['GET', 'POST'])
def send():
    if request.method == 'POST':
        img_file = request.files['img_file']
        if img_file and allowed_file(img_file.filename):
            filename = secure_filename(img_file.filename)
            img_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            img_url = '/uploads/' + filename
            return render_template('index.html', img_url=img_url)
        else:
            return ''' <p>許可されていない拡張子です</p> '''
    else:
        return redirect(url_for('index'))

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
    app.debug = True
    app.run()
```

前回同様ログインしないとアップロードできない仕様にしてみました。アップロードを許可するファイルは

```
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'gif'])
```

こんな感じで、.txtとかそこらを許可することも出来ますから結果として画像以外のアップローダーにもカスタマイズは容易です。シークレットキーがないと駄目ぽなので、

```
app.config['SECRET_KEY'] = os.urandom(24)
```

生成してます。

今回はたちまち、画像のアップロード結果だけ見たいので

```
img_url = '/uploads/' + filename
```

ダサい書き方をしてますのであしからず。

#実行結果

<img width="411" alt="スクリーンショット 2017-05-18 15.23.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/71585/dee13ba3-0918-c3a4-d351-a8da0b694106.png">

完成です。