A lightweight and simple file download server written in Flask
1from flask import Flask, jsonify, request, Response, send_file, render_template
2from pathlib import Path
3from markupsafe import escape
4import json, sys, os
5from sys import platform
6from datetime import datetime
7from flask_cors import CORS
8import argparse
9
10home = str(Path.home())
11
12app = Flask(__name__)
13CORS(app)
14
15parser=argparse.ArgumentParser()
16
17parser.add_argument("--ip", help="The ip to run the server on")
18parser.add_argument("--port", help="The port of the server")
19parser.add_argument("--dir", help="The folder that the server points to")
20
21args=parser.parse_args()
22
23if args.dir == None:
24 print("No directory was provided")
25 sys.exit(1)
26
27if args.ip == None:
28 print("No ip was provided. Defaulting to 'localhost'")
29
30if args.port == None:
31 print("No port provided. Defaulting to 8000")
32
33def sizeof_fmt(num, suffix="B"):
34 for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
35 if abs(num) < 1024.0:
36 return f"{num:3.1f}{unit}{suffix}"
37 num /= 1024.0
38 return f"{num:.1f}Yi{suffix}"
39
40@app.route("/img/parentdir")
41def getimgparentdir():
42 return send_file("./public/parentdir.png")
43
44@app.route("/img/folder")
45def getimgfolder():
46 return send_file("./public/folder.png")
47
48@app.route("/img/file")
49def getimgfile():
50 return send_file("./public/file.png")
51
52@app.route("/<path:subpath>")
53def getdirectory(subpath):
54 directory = args.dir + subpath + "/"
55 if os.path.isdir(directory):
56 files_and_directories = os.listdir(directory)
57
58 data = {}
59 parentdir = "Parent Directory"
60 data["parentdir"] = "/".join(("/" + subpath).split("/")[0:-1])
61 if data["parentdir"] == "":
62 data["parentdir"] = "/"
63 print(data["parentdir"])
64
65 for file in files_and_directories:
66 data[file] = {}
67 data[file]["type"] = "dir" if os.path.isdir(directory + file) else "file"
68 data[file]["sizebytes"] = "0" if os.path.isdir(directory + file) else os.path.getsize(directory + file)
69 data[file]["size"] = "0" if os.path.isdir(directory + file) else sizeof_fmt(data[file]["sizebytes"])
70 data[file]["modifiedunix"] = os.path.getmtime(directory + file)
71 data[file]["modified"] = datetime.utcfromtimestamp(os.path.getmtime(directory + file)).strftime('%Y-%m-%d %H:%M')
72 data[file]["created"] = os.path.getctime(directory + file)
73
74 return render_template("index.html", data=data, subpath=subpath)
75 #return data
76
77
78 return Response(json.dumps("Provided path is not a directory"), status=400, mimetype='application/json')
79
80@app.route("/")
81def getrootdir():
82 directory = args.dir
83 files_and_directories = os.listdir(directory)
84
85 data = {}
86
87 for file in files_and_directories:
88 data[file] = {}
89 data[file]["type"] = "dir" if os.path.isdir(directory + file) else "file"
90 data[file]["sizebytes"] = os.path.getsize(directory + file)
91 data[file]["size"] = sizeof_fmt(data[file]["sizebytes"])
92 data[file]["modifiedunix"] = os.path.getmtime(directory + file)
93 data[file]["modified"] = datetime.utcfromtimestamp(os.path.getmtime(directory + file)).strftime('%Y-%m-%d %H:%M')
94 data[file]["created"] = os.path.getctime(directory + file)
95
96 #return Response(json.dumps(data), status=200, mimetype='application/json')
97 return render_template("index.html", data=data, subpath=None)
98
99@app.route("/json/<path:subpath>")
100def getdirectoryjson(subpath):
101 directory = args.dir + subpath + "/"
102 if os.path.isdir(directory):
103 files_and_directories = os.listdir(directory)
104
105 data = {}
106
107 parentdir = "Parent Directory"
108 data["parentdir"] = "/".join((directory).split("/")[0:-2])
109
110 for file in files_and_directories:
111 data[file] = {}
112 data[file]["type"] = "dir" if os.path.isdir(directory + file) else "file"
113 data[file]["sizebytes"] = "0" if os.path.isdir(directory + file) else os.path.getsize(directory + file)
114 data[file]["size"] = "0" if os.path.isdir(directory + file) else sizeof_fmt(data[file]["sizebytes"])
115 data[file]["modifiedunix"] = os.path.getmtime(directory + file)
116 data[file]["modified"] = datetime.utcfromtimestamp(os.path.getmtime(directory + file)).strftime('%Y-%m-%d %H:%M')
117 data[file]["created"] = os.path.getctime(directory + file)
118
119 return Response(json.dumps(data), status=200, mimetype='application/json')
120 return Response(json.dumps("Provided path is not a directory"), status=400, mimetype='application/json')
121
122@app.route("/json")
123def getrootdirjson():
124 directory = args.dir
125 files_and_directories = os.listdir(directory)
126
127 data = {}
128
129 for file in files_and_directories:
130 data[file] = {}
131 data[file]["type"] = "dir" if os.path.isdir(directory + file) else "file"
132 data[file]["sizebytes"] = os.path.getsize(directory + file)
133 data[file]["size"] = sizeof_fmt(data[file]["sizebytes"])
134 data[file]["modifiedunix"] = os.path.getmtime(directory + file)
135 data[file]["modified"] = datetime.utcfromtimestamp(os.path.getmtime(directory + file)).strftime('%Y-%m-%d %H:%M')
136 data[file]["created"] = os.path.getctime(directory + file)
137
138 return Response(json.dumps(data), status=200, mimetype='application/json')
139
140@app.route("/download/<path:subpath>")
141def downloadfile(subpath):
142 directory = args.dir + subpath
143 if os.path.isdir(directory):
144 return Response(json.dumps("Directory is not a file"), status=400, mimetype='application/json')
145
146 return send_file(directory, as_attachment=True)
147
148@app.route("/favicon.ico")
149def favicon():
150 return send_file("./public/favicon.ico")
151
152if __name__ == '__main__':
153 app.run(host=args.ip if args.ip != None else "localhost", port=args.port if args.port != None else 8000, debug=True)
154