2021년 4월 15일 목요일

[Python] Flask Example

1. File Server

fileserver.py

import logging
import time
import os

import requests
from flask import Flask, url_for, render_template, request, redirect, session
from flask_sqlalchemy import SQLAlchemy
from flask import send_from_directory

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
home_dir = r"D:\Temp"
app = Flask(__name__, instance_path=home_dir)
db = SQLAlchemy(app)

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

def strip_root(filename):
    if len(filename) == 0: return ""
    elif len(filename) == 1: return "" if filename[0] == '/' else filename
    else: return filename[1:] if filename[0] == '/' else filename
        
def send_list_directory(file_path):
    dirs  = []
    files = []
    abs_path = os.path.join( home_dir, file_path )
    if len(file_path) > 0:
        if file_path[0] != '/':  file_path = "/" + file_path
        if file_path[-1] != '/': file_path = file_path + "/"
    else:
        file_path = "/"
    dirs.append( ("..", 0) ) 
    for f in os.listdir( abs_path ):
        full_name = os.path.join( abs_path, f )
        size = os.path.getsize( full_name )
        date = time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime(os.path.getctime( full_name )))
        if os.path.isdir(full_name): dirs.append( (f, size, date) )
        else: files.append( (f, size, date) )
    print('send_list_directory [', file_path, ']', dirs, files)
    return render_template("fileserver.html", folder=file_path, dirs=dirs, files=files)

@app.route('/home', methods=['GET', 'POST'])
@app.route('/', methods=['GET', 'POST'])
def Home():
    if not session.get('logged_in'):
        return render_template('login.html')
    if request.method == 'GET':
        return send_list_directory("")
 
@app.route('/upload', methods=['POST'])
def Upload():
    if not session.get('logged_in'):
        return render_template('login.html')
    file = request.files['file']
    folder = strip_root(request.form['folder'])
    if file and allowed_file(file.filename):
        file.save(os.path.join( home_dir, folder, file.filename))
    return send_list_directory(folder)
        
@app.route('/delete', methods=['GET'])
def Delete():
    if not session.get('logged_in'):
        return render_template('login.html')
    file = strip_root(request.args['file'])
    folder = strip_root(os.path.dirname(file))
    full_path = os.path.join( home_dir, file)
    if file and allowed_file(file):
        print( full_path, home_dir, file )
        os.remove(full_path)
    else:
        print(f"permission error : delete {full_path}")
    return send_list_directory(folder)
 
@app.route('/<path:filePath>', methods=['GET'])
def ServeFile(filePath):
    if not session.get('logged_in'):
        return render_template('login.html')
    print('ServeFile()', filePath)
    if os.path.isdir(os.path.join(home_dir,filePath)):
        return send_list_directory(filePath)
    else:
        return send_from_directory(home_dir, filePath)

def warning(text):
    logger.warning(text)


#
# SESSION
#

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    password = db.Column(db.String(80))
    def __init__(self, username, password):
        self.username = username
        self.password = password

def create_user(username,password):
    new_user = User(username=username, password=password)
    db.session.add(new_user)
    db.session.commit()
    print(User.query.filter_by(username=username, password=password).first())
      
@app.route('/login', methods=['GET', 'POST'])
def login():
    if not session.get('logged_in'):
        if request.method == 'GET':
            return render_template('login.html')
        username = request.form['username']
        password = request.form['password']
        print( '/login', username, password )
        try:
            data = User.query.filter_by(username=username, password=password).first()
            if data is not None:
                #if username == 'admin' and password == 'admin1234':
                session['logged_in'] = True
                return redirect(url_for('Home'))
            else:
                return  render_template('login.html', message="Login Fail [1] !")
        except:
            return  render_template('login.html', message="Login Fail [2] !")
    else:
        return send_list_directory("")

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        new_user = User(username=request.form['username'], password=request.form['password'])
        db.session.add(new_user)
        db.session.commit()
        return render_template('login.html')
    return render_template('register.html')

@app.route("/logout")
def logout():
    session['logged_in'] = False
    return redirect(url_for('Home'))

#
# Application
#
    
if __name__ == "__main__":
    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024    
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///fileserver.db'
    app.secret_key = "3123"
    db.create_all()
    logger = logging.getLogger(__name__)
    #create_user(username='admin', password='admin1234')
    app.run(debug=True, host="0.0.0.0", port=8000) 


fileserver.html

<!DOCTYPE html>
<html>
    <head>
        <title>home</title>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">        
    </head>
    <body>
        <div style="margin-right:50px" width="600">
            <div style="float: right"><a href="/logout"> logout </a></div>
            <h1>UpLoad</h1>
            <!--div style="border: 3px solid gold; float: left; height: auto; width: 200px; margin: 15px 25px 15px 0px;"-->
            <table border='1' class="table table-dark" style="margin: 25px 25px 25px 25px; width:600px;" >
            {% autoescape false %}
              <form action = "/upload" method = "POST"
                  enctype = "multipart/form-data">
              <tr>
              <td><input type = "file" name = "file" />
              <input type = "hidden" name = "folder" value="{{folder}}" /></td>
              <td><input type = "submit"/></td>
              </tr>
            </form> 
            {% endautoescape %}
            </table>
        <h1>File List</h1>
        <div style="margin-left:25px"> <h4> {% block title %}  {{folder}}{% endblock %} </h4></div>
        <table border='1' class="table table-striped table-responsive" style="margin: 25px 25px 25px 25px;"> <!-- border='1'  -->
            <thead><tr> <th width="1%" style="text-align: center;"> File/Dir </th>
                 <th style="text-align: center;"> Filename </th> 
                 <th width="1%" style="text-align: center;"> Size </th> 
                 <th width="200px" style="text-align: center;"> Date </th>
                 <th width="1%" style="text-align: center;"> Operation </th>
             </tr></thead><tbody>
        {% if dirs %}
            {% for dirName in dirs %}
                <tr>
                <td>[DIR]</td> 
                <!--td onclick="window.location='{{folder}}{{dirName[0]}}';" style='cursor: pointer;'-->
                <td><a href="{{folder}}{{dirName[0]}}">[ {{ dirName[0] }} ]</a></td> 
                <td style="text-align: right;"> {{ dirName[1] }} </td>
                <td style="text-align: center;"> {{ dirName[2] }} </td>
                <td></td>
                </tr>
            {% endfor %}
        {% endif %}
        {% if files %}
            {% for fileName in files %}
                <tr>
                <td>[FILE]</td>
                <!--td onclick="window.location='{{folder}}{{fileName[0]}}';" style='cursor: pointer;'-->
                <td><a href="{{folder}}{{fileName[0]}}"> {{ fileName[0] }}</td> 
                <td style="text-align: right;">{{ fileName[1] }} </a></td>
                <td style="text-align: center;"> {{ fileName[2] }} </td>
                <td style="text-align: center;"> <a href="/delete?file={{folder}}{{fileName[0]}}">Delete</a></td>
                </tr>
            {% endfor %}
        {% endif %}
        </tbody></table>
        </div>
        <p />
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>        
    </body>
</html>

base.html

<html>
<head>
<title>home</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" >
</head>
<body>
{% block content %}{% endblock %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" ></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" ></script>
</body>
</html>

register.html

{% extends "base.html" %}
{% block content %}
{% if session['logged_in'] %}
<p>Oh no Dont show page</p>
{% else %}
<h2>Register</h2>
<form action="/register" method="POST">
  <input type="username" name="username" placeholder="Username">
  <input type="password" name="password" placeholder="Password">
  <input type="submit" value="Log in">
</form>
{% endif %}
{% endblock %}

login.html

{% extends "base.html" %}
{% block content %}
{% if session['logged_in'] %}
<script>window.location.href = "/"</script>
{% else %}
<center>
<h2>Login</h2>
<form action="/login" method="POST">
  <input type="username" name="username" placeholder="Username">
  <input type="password" name="password" placeholder="Password">
  <input type="submit" value="Log in">
</form>
<div><font color="red"> {{message}} </font></div>
</center>
{% endif %}
{% endblock %}

댓글 없음:

댓글 쓰기