abhicodes commited on
Commit
2ace788
1 Parent(s): 950048d

Upload 6 files

Browse files
Files changed (6) hide show
  1. Dockerfile +11 -0
  2. app.py +79 -0
  3. requirements.txt +6 -0
  4. templates/files.html +38 -0
  5. templates/index.html +140 -0
  6. templates/upload.html +99 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11
2
+
3
+ WORKDIR /code
4
+
5
+ COPY ./requirements.txt /code/requirements.txt
6
+
7
+ RUN pip install --upgrade -r requirements.txt
8
+
9
+ COPY . /code
10
+
11
+ CMD ["gunicorn", "app:app", "-b", "0.0.0.0:7860"]
app.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, redirect, url_for, send_file, render_template, flash
2
+ from flask_cors import CORS
3
+ from werkzeug.utils import secure_filename
4
+ from pymongo.mongo_client import MongoClient
5
+ from pymongo.server_api import ServerApi
6
+ import urllib.parse
7
+ import os
8
+ import io
9
+
10
+ app = Flask(__name__)
11
+ app.secret_key = os.getenv('SECRET_KEY')
12
+ CORS(app,resources={r"/*":{"origins":"*"}})
13
+
14
+ username = urllib.parse.quote_plus(os.getenv('MONGO_USERNAME'))
15
+ password = urllib.parse.quote_plus(os.getenv('MONGO_PASSWORD'))
16
+ restUri = os.getenv('REST_URI')
17
+ uri = f'mongodb+srv://{username}:{password}{restUri}'
18
+ client = MongoClient(uri, server_api=ServerApi('1'))
19
+ db = client['file_storage']
20
+ files_collection = db['files']
21
+
22
+ def allowed_file(filename):
23
+ return True
24
+
25
+ @app.route('/')
26
+ def index():
27
+ return render_template('index.html')
28
+
29
+ @app.route('/upload', methods=['GET', 'POST'])
30
+ def upload_file():
31
+ if request.method == 'POST':
32
+ if 'file' not in request.files:
33
+ flash('No file part')
34
+ return redirect(request.url)
35
+ files = request.files.getlist('file')
36
+ for file in files:
37
+ if file.filename == '':
38
+ flash('No selected file')
39
+ return redirect(request.url)
40
+ if file and allowed_file(file.filename):
41
+ filename = secure_filename(file.filename)
42
+ file_data = {
43
+ 'filename': filename,
44
+ 'data': file.read()
45
+ }
46
+ files_collection.insert_one(file_data)
47
+ flash('Files successfully uploaded')
48
+ return redirect(url_for('list_files'))
49
+ return render_template('upload.html')
50
+
51
+ @app.route('/uploads/<filename>')
52
+ def uploaded_file(filename):
53
+ file_data = files_collection.find_one({'filename': filename})
54
+ if file_data:
55
+ return send_file(
56
+ io.BytesIO(file_data['data']),
57
+ mimetype='application/octet-stream'
58
+ )
59
+ else:
60
+ return 'File not found'
61
+
62
+
63
+ @app.route('/files')
64
+ def list_files():
65
+ files = [file_data['filename'] for file_data in files_collection.find({}, {'_id': 1, 'filename': 1})]
66
+ return render_template('files.html', files=files)
67
+
68
+ @app.route('/delete/<filename>', methods=['POST'])
69
+ def delete_file(filename):
70
+ file_data = files_collection.find_one({'filename': filename})
71
+ if file_data:
72
+ files_collection.delete_one({'filename': filename})
73
+ flash('File successfully deleted')
74
+ else:
75
+ flash('File not found')
76
+ return redirect(url_for('list_files'))
77
+
78
+ if __name__ == '__main__':
79
+ app.run(debug=True, host='0.0.0.0')
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ flask
2
+ Flask-Cors
3
+ Werkzeug
4
+ gunicorn
5
+ pymongo[srv]
6
+ python-dotenv
templates/files.html ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <style>
7
+ body {
8
+ padding: 20px;
9
+ box-sizing: border-box;
10
+ }
11
+ </style>
12
+ <title>Uploaded Files</title>
13
+ </head>
14
+ <body>
15
+ <h2 style="text-align: center; font-family:system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-weight: bold;">Uploaded Files</h2>
16
+ {% with messages = get_flashed_messages() %}
17
+ {% if messages %}
18
+ <ul>
19
+ {% for message in messages %}
20
+ <li>{{ message }}</li>
21
+ {% endfor %}
22
+ </ul>
23
+ {% endif %}
24
+ {% endwith %}
25
+ <ol type="1">
26
+ {% for file in files %}
27
+ <li>
28
+ <div style="display: flex; justify-content: space-between;">
29
+ <a style="text-decoration: none; color: green; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-weight: bold;" href="{{ url_for('uploaded_file', filename=file) }}"> &nbsp;&nbsp;{{ file }} ⬇️</a>
30
+ <form action="{{ url_for('delete_file', filename=file) }}" method="post" style="display:inline;">
31
+ <input style="cursor: pointer; background-color: rgb(255, 0, 0); border: none; padding: 10px; color: aliceblue; font-weight: bold; border-radius: 12px;" type="submit" value="Delete 🗑️">
32
+ </form>
33
+ </div>
34
+ </li>
35
+ {% endfor %}
36
+ </ol>
37
+ </body>
38
+ </html>
templates/index.html ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <style>
7
+ @property --rotate {
8
+ syntax: "<angle>";
9
+ initial-value: 132deg;
10
+ inherits: false;
11
+ }
12
+
13
+ :root {
14
+ --card-height: 65vh;
15
+ --card-width: calc(var(--card-height) / 1.5);
16
+ }
17
+
18
+ body {
19
+ display: flex;
20
+ align-items: center;
21
+ flex-direction: column;
22
+ }
23
+
24
+ .card {
25
+ background: #6882f7;
26
+ width: var(--card-width);
27
+ height: var(--card-height);
28
+ padding: 3px;
29
+ position: relative;
30
+ border-radius: 6px;
31
+ justify-content: center;
32
+ align-items: center;
33
+ text-align: center;
34
+ display: flex;
35
+ font-size: 1.5em;
36
+ color: rgb(88 199 250 / 0%);
37
+ cursor: pointer;
38
+ font-family: cursive;
39
+ }
40
+
41
+ .card:hover {
42
+ color: rgb(0, 238, 255);
43
+ transition: color 1s;
44
+ }
45
+ .card:hover:before, .card:hover:after {
46
+ animation: none;
47
+ opacity: 0;
48
+ }
49
+
50
+
51
+ .card::before {
52
+ content: "";
53
+ width: 104%;
54
+ height: 102%;
55
+ border-radius: 8px;
56
+ background-image: linear-gradient(
57
+ var(--rotate)
58
+ , #5ddcff, #3c67e3 43%, #4e00c2);
59
+ position: absolute;
60
+ z-index: -1;
61
+ top: -1%;
62
+ left: -2%;
63
+ animation: spin 2.5s linear infinite;
64
+ }
65
+
66
+ .card::after {
67
+ position: absolute;
68
+ content: "";
69
+ top: calc(var(--card-height) / 6);
70
+ left: 0;
71
+ right: 0;
72
+ z-index: -1;
73
+ height: 100%;
74
+ width: 100%;
75
+ margin: 0 auto;
76
+ transform: scale(0.8);
77
+ filter: blur(calc(var(--card-height) / 6));
78
+ background-image: linear-gradient(
79
+ var(--rotate)
80
+ , #5ddcff, #3c67e3 43%, #4e00c2);
81
+ opacity: 1;
82
+ transition: opacity .5s;
83
+ animation: spin 2.5s linear infinite;
84
+ }
85
+
86
+ @keyframes spin {
87
+ 0% {
88
+ --rotate: 0deg;
89
+ }
90
+ 100% {
91
+ --rotate: 360deg;
92
+ }
93
+ }
94
+
95
+ a {
96
+ color: #212534;
97
+ text-decoration: none;
98
+ font-family: sans-serif;
99
+ font-weight: bold;
100
+ margin-top: 2rem;
101
+ }
102
+ .container {
103
+ display: flex;
104
+ flex-direction: row;
105
+ justify-content: space-around;
106
+ width: 80%;
107
+ }
108
+ @media only screen and (max-width: 600px) {
109
+ .container {
110
+ width: 100%;
111
+ }
112
+ .card::before {
113
+ content: "";
114
+ width: 104%;
115
+ height: 102%;
116
+ }
117
+ :root {
118
+ --card-height: 30vh;
119
+ --card-width: calc(var(--card-height) / 1.5);
120
+ }
121
+ }
122
+ </style>
123
+ <title>File Storage</title>
124
+ </head>
125
+ <body>
126
+ <h1 style="text-align: center; font-family:system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-weight: bold;">File Storage System</h1>
127
+ <div class="container">
128
+ <a href="{{ url_for('upload_file') }}">
129
+ <div class="card">
130
+ Upload a file
131
+ </div>
132
+ </a>
133
+ <a href="{{ url_for('list_files') }}">
134
+ <div class="card">
135
+ View uploaded files
136
+ </div>
137
+ </a>
138
+ </div>
139
+ </body>
140
+ </html>
templates/upload.html ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <style>
7
+ .container {
8
+ display: flex;
9
+ flex-direction: column;
10
+ justify-content: center;
11
+ align-items: center;
12
+ }
13
+ .button1 {
14
+ background-color: #00eaff;
15
+ border: none;
16
+ border-radius: 24px;
17
+ padding: 10px;
18
+ width: 100%;
19
+ margin: auto;
20
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
21
+ font-weight: bolder;
22
+ }
23
+ .form-control-file {
24
+ position: relative;
25
+ width: 100%;
26
+ margin: 10px;
27
+ height: 81dvh;
28
+ display: flex;
29
+ justify-content: center;
30
+ align-items: center;
31
+ justify-items: center;
32
+ outline: none;
33
+ visibility: hidden;
34
+ cursor: pointer;
35
+ background-color: blueviolet;
36
+ box-shadow: 0 0 5px solid blueviolet;
37
+ }
38
+ .form-control-file:before {
39
+ content: attr(data-title);
40
+ position: absolute;
41
+ display: flex;
42
+ justify-content: center;
43
+ align-items: center;
44
+ justify-items: center;
45
+ font-size: large;
46
+ font-weight: bolder;
47
+ top: 0;
48
+ left: 0;
49
+ width: 95%;
50
+ height: 80dvh;
51
+ opacity: 1;
52
+ visibility: visible;
53
+ text-align: center;
54
+ border: 0.25em blueviolet dashed;
55
+ border-radius: 24px;
56
+ transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
57
+ }
58
+ .form-control-file:hover:before {
59
+ border-style: solid;
60
+ box-shadow: inset blueviolet 0px 0px 0px 0.25em;
61
+ }
62
+ body {
63
+ background-color: #f7f7f9;
64
+ }
65
+ </style>
66
+ <title>Upload Files</title>
67
+ </head>
68
+ <body>
69
+ <h2 style="text-align: center; font-family:system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-weight: bold;">Upload New Files</h2>
70
+ {% with messages = get_flashed_messages() %}
71
+ {% if messages %}
72
+ <ul>
73
+ {% for message in messages %}
74
+ <li>{{ message }}</li>
75
+ {% endfor %}
76
+ </ul>
77
+ {% endif %}
78
+ {% endwith %}
79
+ <form method="post" class="container" enctype="multipart/form-data">
80
+ <input type="file" name="file" multiple class="form-control-file" id="inputFile" onchange="readUrl(this)" data-title="Drag and drop a file">
81
+ <input type="submit" class="button1" style="cursor: pointer;" value="Upload">
82
+ </form>
83
+
84
+ <script>
85
+ function readUrl(input) {
86
+ if (input.files && input.files[0]) {
87
+ let reader = new FileReader();
88
+ reader.onload = (e) => {
89
+ let imgData = e.target.result;
90
+ let imgName = input.files[0].name;
91
+ input.setAttribute("data-title", imgName);
92
+ console.log(e.target.result);
93
+ }
94
+ reader.readAsDataURL(input.files[0]);
95
+ }
96
+ }
97
+ </script>
98
+ </body>
99
+ </html>