From bef28cb377e8997979e9bec4d286c791e812125f Mon Sep 17 00:00:00 2001 From: Santosh Chejarla <santosh8@illinois.edu> Date: Mon, 8 May 2023 02:21:42 +0100 Subject: [PATCH] updating code --- .gitignore | 0 access_data.json | 1 + app.py | 57 +++++- cache_validator.sh | 2 +- constants.py | 0 index.html | 358 ------------------------------------- lfu_checker.py | 3 +- pi_logo.png | Bin save_mode.json | 1 + static/images/pi_logo.png | Bin static/styles/styles.css | 15 ++ templates/delete.html | 26 +++ templates/index.html | 21 ++- templates/login.html | 2 +- templates/more_files.html | 10 +- templates/upload.html | 6 +- templates/upload_fail.html | 9 - upload.py | 0 utils.py | 11 +- 19 files changed, 134 insertions(+), 388 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 access_data.json mode change 100644 => 100755 app.py mode change 100644 => 100755 constants.py delete mode 100755 index.html mode change 100644 => 100755 lfu_checker.py mode change 100644 => 100755 pi_logo.png mode change 100644 => 100755 save_mode.json mode change 100644 => 100755 static/images/pi_logo.png mode change 100644 => 100755 static/styles/styles.css create mode 100644 templates/delete.html mode change 100644 => 100755 templates/index.html mode change 100644 => 100755 templates/login.html mode change 100644 => 100755 templates/more_files.html mode change 100644 => 100755 templates/upload.html delete mode 100644 templates/upload_fail.html delete mode 100644 upload.py mode change 100644 => 100755 utils.py diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/access_data.json b/access_data.json old mode 100644 new mode 100755 index e69de29..9e26dfe --- a/access_data.json +++ b/access_data.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/app.py b/app.py old mode 100644 new mode 100755 index d19fb8c..91b126c --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from flask import Flask, render_template, request, redirect, url_for, flash, session, send_file, abort +from flask import Flask, render_template, request, redirect, url_for, flash, session, send_file, abort, send_from_directory import os import boto3 import json @@ -27,6 +27,10 @@ def download_file(filename): except FileNotFoundError: abort(404) +@app.route('/thumb/<path:filename>') +def serve_thumb(filename): + return send_from_directory('./thumb', filename) + # check if user is logged in else redirect to login page def check_login(): @@ -94,7 +98,6 @@ def upload(): if tot_size + file_size <= CACHE_SIZE: break file.save(os.path.join(directory, filename)) - return redirect(url_for('index')) elif location == "s3": with open("creds.json", "r") as f: creds = json.load(f) @@ -110,18 +113,23 @@ def upload(): lfu_obj = LFUChecker(CACHE_SIZE) lfu_files = lfu_obj.get_lfu() for _file in lfu_files: + if lfu_files[_file] > 0: continue if _file == filename: continue if _file in files_with_auto_mode: os.remove(os.path.join(os.getcwd(), 'cache', _file)) tot_size = get_total_files_size() if tot_size + file_size <= CACHE_SIZE: break - file.save(file_path) - file.seek(0) + tot_size = get_total_files_size() + if tot_size + file_size <= CACHE_SIZE: + file.save(file_path) + file.seek(0) with open("creds.json", "r") as f: creds = json.load(f) s3 = boto3.client('s3',aws_access_key_id=creds["access_key"], aws_secret_access_key=creds["secret"]) - s3.upload_fileobj(file, "hnas", filename) + s3.upload_fileobj(file, "hnas", filename) + if "jpeg" in filename or "jpg" in filename or "png" in filename or "JPG" in filename: + generate_thumb(filename) return redirect(url_for('index')) return render_template('upload.html') @@ -169,13 +177,46 @@ def logout(): def upload_fail(): return render_template('upload_fail.html') -@app.route('/delete/<path:filename>', methods=['GET']) -def delete_file(filename): + +@app.route('/delete_page') +def delete_page(): if not check_login(): return redirect(url_for('login')) - os.remove(os.path.join(os.getcwd(), 'cache', filename)) + files = set(get_local_files() + get_s3_files()) + return render_template('delete.html', files=files) + +@app.route('/delete', methods=['POST']) +def delete_file(): + if not check_login(): + return redirect(url_for('login')) + + filename = request.form.get('delete-file') + if filename: + local_file_path = os.path.join(os.getcwd(), 'cache', filename) + s3_file_path = filename + if os.path.exists(local_file_path): + os.remove(local_file_path) + else: + with open("creds.json", "r") as f: + creds = json.load(f) + s3 = boto3.client('s3', aws_access_key_id=creds["access_key"], aws_secret_access_key=creds["secret"]) + s3.delete_object(Bucket="hnas", Key=s3_file_path) + with open("access_data.json", "r+") as f: + access_data = json.load(f) + access_data.pop(filename, None) + f.seek(0) + json.dump(access_data, f) + f.truncate() + with open("save_mode.json", "r+") as f: + save_mode_data = json.load(f) + save_mode_data.pop(filename, None) + f.seek(0) + json.dump(save_mode_data, f) + f.truncate() + return redirect(url_for('index')) + # index page @app.route('/') def index(): diff --git a/cache_validator.sh b/cache_validator.sh index 92aa48e..0078e47 100755 --- a/cache_validator.sh +++ b/cache_validator.sh @@ -1,2 +1,2 @@ -cd /var/www/html +cd /home/pi/iot_project python3 lfu_checker.py \ No newline at end of file diff --git a/constants.py b/constants.py old mode 100644 new mode 100755 diff --git a/index.html b/index.html deleted file mode 100755 index 20b6d62..0000000 --- a/index.html +++ /dev/null @@ -1,358 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <title>Apache2 Ubuntu Default Page: It works</title> - <style type="text/css" media="screen"> - * { - margin: 0px 0px 0px 0px; - padding: 0px 0px 0px 0px; - } - - body, html { - padding: 3px 3px 3px 3px; - - background-color: #D8DBE2; - - font-family: Ubuntu, Verdana, sans-serif; - font-size: 11pt; - text-align: center; - } - - div.main_page { - position: relative; - display: table; - - width: 800px; - - margin-bottom: 3px; - margin-left: auto; - margin-right: auto; - padding: 0px 0px 0px 0px; - - border-width: 2px; - border-color: #212738; - border-style: solid; - - background-color: #FFFFFF; - - text-align: center; - } - - div.page_header { - height: 180px; - width: 100%; - - background-color: #F5F6F7; - } - - div.page_header span { - margin: 15px 0px 0px 50px; - - font-size: 180%; - font-weight: bold; - } - - div.page_header img { - margin: 3px 0px 0px 40px; - - border: 0px 0px 0px; - } - - div.banner { - padding: 9px 6px 9px 6px; - background-color: #E9510E; - color: #FFFFFF; - font-weight: bold; - font-size: 112%; - text-align: center; - position: absolute; - left: 40%; - bottom: 30px; - width: 20%; - } - - div.table_of_contents { - clear: left; - - min-width: 200px; - - margin: 3px 3px 3px 3px; - - background-color: #FFFFFF; - - text-align: left; - } - - div.table_of_contents_item { - clear: left; - - width: 100%; - - margin: 4px 0px 0px 0px; - - background-color: #FFFFFF; - - color: #000000; - text-align: left; - } - - div.table_of_contents_item a { - margin: 6px 0px 0px 6px; - } - - div.content_section { - margin: 3px 3px 3px 3px; - - background-color: #FFFFFF; - - text-align: left; - } - - div.content_section_text { - padding: 4px 8px 4px 8px; - - color: #000000; - font-size: 100%; - } - - div.content_section_text pre { - margin: 8px 0px 8px 0px; - padding: 8px 8px 8px 8px; - - border-width: 1px; - border-style: dotted; - border-color: #000000; - - background-color: #F5F6F7; - - font-style: italic; - } - - div.content_section_text p { - margin-bottom: 6px; - } - - div.content_section_text ul, div.content_section_text li { - padding: 4px 8px 4px 16px; - } - - div.section_header { - padding: 3px 6px 3px 6px; - - background-color: #8E9CB2; - - color: #FFFFFF; - font-weight: bold; - font-size: 112%; - text-align: center; - } - - div.section_header_grey { - background-color: #9F9386; - } - - .floating_element { - position: relative; - float: left; - } - - div.table_of_contents_item a, - div.content_section_text a { - text-decoration: none; - font-weight: bold; - } - - div.table_of_contents_item a:link, - div.table_of_contents_item a:visited, - div.table_of_contents_item a:active { - color: #000000; - } - - div.table_of_contents_item a:hover { - background-color: #000000; - - color: #FFFFFF; - } - - div.content_section_text a:link, - div.content_section_text a:visited, - div.content_section_text a:active { - background-color: #DCDFE6; - - color: #000000; - } - - div.content_section_text a:hover { - background-color: #000000; - - color: #DCDFE6; - } - - div.validator { - } - </style> - </head> - <body> - <div class="main_page"> - <div class="page_header floating_element"> - <img src="icons/ubuntu-logo.png" alt="Ubuntu Logo" - style="width:184px;height:146px;" class="floating_element" /> - <div> - <span style="margin-top: 1.5em;" class="floating_element"> - Apache2 Default Page - </span> - </div> - <div class="banner"> - <div id="about"></div> - It works! - </div> - - </div> - <div class="content_section floating_element"> - <div class="content_section_text"> - <p> - This is the default welcome page used to test the correct - operation of the Apache2 server after installation on Ubuntu systems. - It is based on the equivalent page on Debian, from which the Ubuntu Apache - packaging is derived. - If you can read this page, it means that the Apache HTTP server installed at - this site is working properly. You should <b>replace this file</b> (located at - <tt>/var/www/html/index.html</tt>) before continuing to operate your HTTP server. - </p> - - <p> - If you are a normal user of this web site and don't know what this page is - about, this probably means that the site is currently unavailable due to - maintenance. - If the problem persists, please contact the site's administrator. - </p> - - </div> - <div class="section_header"> - <div id="changes"></div> - Configuration Overview - </div> - <div class="content_section_text"> - <p> - Ubuntu's Apache2 default configuration is different from the - upstream default configuration, and split into several files optimized for - interaction with Ubuntu tools. The configuration system is - <b>fully documented in - /usr/share/doc/apache2/README.Debian.gz</b>. Refer to this for the full - documentation. Documentation for the web server itself can be - found by accessing the <a href="/manual">manual</a> if the <tt>apache2-doc</tt> - package was installed on this server. - </p> - <p> - The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows: - </p> - <pre> -/etc/apache2/ -|-- apache2.conf -| `-- ports.conf -|-- mods-enabled -| |-- *.load -| `-- *.conf -|-- conf-enabled -| `-- *.conf -|-- sites-enabled -| `-- *.conf - </pre> - <ul> - <li> - <tt>apache2.conf</tt> is the main configuration - file. It puts the pieces together by including all remaining configuration - files when starting up the web server. - </li> - - <li> - <tt>ports.conf</tt> is always included from the - main configuration file. It is used to determine the listening ports for - incoming connections, and this file can be customized anytime. - </li> - - <li> - Configuration files in the <tt>mods-enabled/</tt>, - <tt>conf-enabled/</tt> and <tt>sites-enabled/</tt> directories contain - particular configuration snippets which manage modules, global configuration - fragments, or virtual host configurations, respectively. - </li> - - <li> - They are activated by symlinking available - configuration files from their respective - *-available/ counterparts. These should be managed - by using our helpers - <tt> - a2enmod, - a2dismod, - </tt> - <tt> - a2ensite, - a2dissite, - </tt> - and - <tt> - a2enconf, - a2disconf - </tt>. See their respective man pages for detailed information. - </li> - - <li> - The binary is called apache2 and is managed using systemd, so to - start/stop the service use <tt>systemctl start apache2</tt> and - <tt>systemctl stop apache2</tt>, and use <tt>systemctl status apache2</tt> - and <tt>journalctl -u apache2</tt> to check status. <tt>system</tt> - and <tt>apache2ctl</tt> can also be used for service management if - desired. - <b>Calling <tt>/usr/bin/apache2</tt> directly will not work</b> with the - default configuration. - </li> - </ul> - </div> - - <div class="section_header"> - <div id="docroot"></div> - Document Roots - </div> - - <div class="content_section_text"> - <p> - By default, Ubuntu does not allow access through the web browser to - <em>any</em> file outside of those located in <tt>/var/www</tt>, - <a href="http://httpd.apache.org/docs/2.4/mod/mod_userdir.html" rel="nofollow">public_html</a> - directories (when enabled) and <tt>/usr/share</tt> (for web - applications). If your site is using a web document root - located elsewhere (such as in <tt>/srv</tt>) you may need to whitelist your - document root directory in <tt>/etc/apache2/apache2.conf</tt>. - </p> - <p> - The default Ubuntu document root is <tt>/var/www/html</tt>. You - can make your own virtual hosts under /var/www. - </p> - </div> - - <div class="section_header"> - <div id="bugs"></div> - Reporting Problems - </div> - <div class="content_section_text"> - <p> - Please use the <tt>ubuntu-bug</tt> tool to report bugs in the - Apache2 package with Ubuntu. However, check <a - href="https://bugs.launchpad.net/ubuntu/+source/apache2" - rel="nofollow">existing bug reports</a> before reporting a new bug. - </p> - <p> - Please report bugs specific to modules (such as PHP and others) - to their respective packages, not to the web server itself. - </p> - </div> - - </div> - </div> - <div class="validator"> - </div> - </body> -</html> diff --git a/lfu_checker.py b/lfu_checker.py old mode 100644 new mode 100755 index a0135d7..7af3e23 --- a/lfu_checker.py +++ b/lfu_checker.py @@ -54,7 +54,8 @@ class LFUChecker: continue else: if curr_size + get_file_size(file) > self.cache: - os.remove(os.path.join(os.getcwd(), 'cache', file)) + if file in local_files: + os.remove(os.path.join(os.getcwd(), 'cache', file)) fill = True else: curr_size += get_file_size(file) diff --git a/pi_logo.png b/pi_logo.png old mode 100644 new mode 100755 diff --git a/save_mode.json b/save_mode.json old mode 100644 new mode 100755 index e69de29..9e26dfe --- a/save_mode.json +++ b/save_mode.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/static/images/pi_logo.png b/static/images/pi_logo.png old mode 100644 new mode 100755 diff --git a/static/styles/styles.css b/static/styles/styles.css old mode 100644 new mode 100755 index e21903f..5c2957b --- a/static/styles/styles.css +++ b/static/styles/styles.css @@ -54,4 +54,19 @@ body { ul.dashed > li:before { content: "-"; text-indent: -5px; +} + +.file-container-img li { + content: none; +} + +.delete-btn { + position: absolute; + bottom: -50%; + right: 2%; + background: #363636; + border-radius: 10px; + padding: 0.5vw; + color: #fff; + text-decoration: none; } \ No newline at end of file diff --git a/templates/delete.html b/templates/delete.html new file mode 100644 index 0000000..b85e4a9 --- /dev/null +++ b/templates/delete.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> + <title>File Delete</title> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/styles.css') }}"> +</head> +<body> + <div class="logo-container"> + <a href="/"> + <img src="{{ url_for('static', filename='images/pi_logo.png') }}" alt="logo" width="100" height="100"> + </a> + <h1>File Delete</h1> + </div> + <div class="container" style="display: flex; justify-content: center; align-items: center;"> + <form method="POST" action="{{ url_for('delete_file') }}"> + <label for="delete-file">Delete file:</label> + <select name="delete-file" id="delete-file"> + {% for file in files %} + <option value="{{ file }}">{{ file }}</option> + {% endfor %} + </select> + <button type="submit" class="btn btn-danger">Delete</button> + </form> + </div> +</body> +</html> diff --git a/templates/index.html b/templates/index.html old mode 100644 new mode 100755 index 3ed4165..1a31abf --- a/templates/index.html +++ b/templates/index.html @@ -19,18 +19,23 @@ <h2><i class="icon-camera"> </i>Image Files</i></h2> <hr> {% if imgfiles %} - <ul> + <ul> {% for file in imgfiles %} - <li><a href="{{ url_for('download_file', filename=file) }}">{{ file }}</a></li> + <li> + <a href="{{ url_for('download_file', filename=file) }}"> + <img src="{{ url_for('serve_thumb', filename=file) }}" width="100"> + <!-- {{ file }} --> + </a> + </li> {% endfor %} - </ul> + </ul> {% else %} - <p>No image files found.</p> + <p>No image files found.</p> {% endif %} {% if mimages %} - <a href="/images">see more...</a> + <a href="/images">see more...</a> {% endif %} - </div> + </div> <div class="file-container"> <h2><i class="icon-facetime-video"></i> Video Files</h2><hr> {% if videofiles %} @@ -77,5 +82,9 @@ {% endif %} </div> </div> + <div class="container"> + <a href="/delete_page" class="delete-btn">Delete</a> + </div> + </body> </html> diff --git a/templates/login.html b/templates/login.html old mode 100644 new mode 100755 index d5e2b11..fa3493f --- a/templates/login.html +++ b/templates/login.html @@ -9,7 +9,7 @@ <img src="{{ url_for('static',filename='images/pi_logo.png') }}" alt="logo" width="100" height="100"> <h1>Welcome to H-NAS!</h1> </div> - <div class="container"> + <div class="container" style="display: flex; justify-content: center; align-items: center;"> <form method="POST" action="/login"> <label for="username">Username:</label> <input type="text" id="username" name="username"><br><br> diff --git a/templates/more_files.html b/templates/more_files.html old mode 100644 new mode 100755 index 4be89d1..9448988 --- a/templates/more_files.html +++ b/templates/more_files.html @@ -14,11 +14,19 @@ </div> <!--print all elements from parameter files passed from flask--> <div class="container" style="height: 90vh;"> - <div class="file-container"> + <div class="file-container-img"> <h2><i class="{{ fa_content }}"></i> {{ content }} Files</h2> <ul> {% for file in files %} + {% if content=="Image" %} + <li> + <a href="{{ url_for('download_file', filename=file) }}"> + <img src="{{ url_for('serve_thumb', filename=file) }}" width="100"> + </a> + </li> + {% else %} <li><a href="{{ url_for('download_file', filename=file) }}">{{ file }}</a></li> + {% endif %} {% endfor %} </ul> </div> diff --git a/templates/upload.html b/templates/upload.html old mode 100644 new mode 100755 index 13cf4d7..831b204 --- a/templates/upload.html +++ b/templates/upload.html @@ -5,11 +5,13 @@ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/styles.css') }}"> </head> <body> - <div class="logo-container" style="height: 10vh;"> + <div class="logo-container"> + <a href="/"> <img src="{{ url_for('static', filename='images/pi_logo.png') }}" alt="logo" width="100" height="100"> + </a> <h1>File Upload</h1> </div> - <div class="container" style="height: 90vh;"> + <div class="container" style="display: flex; justify-content: center; align-items: center;"> <form method="POST" action="{{ url_for('upload') }}" enctype="multipart/form-data"> <label for="file">Select a file:</label> <input type="file" name="file"><br><br> diff --git a/templates/upload_fail.html b/templates/upload_fail.html deleted file mode 100644 index 7be4b6e..0000000 --- a/templates/upload_fail.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>Dashboard</title> - <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/styles.css') }}"> -</head> -<body> - <h1>Upload failed</h1> -</body> \ No newline at end of file diff --git a/upload.py b/upload.py deleted file mode 100644 index e69de29..0000000 diff --git a/utils.py b/utils.py old mode 100644 new mode 100755 index 6fff3ec..219078a --- a/utils.py +++ b/utils.py @@ -1,6 +1,7 @@ import boto3 import json import os +from PIL import Image def get_total_files_size(): directory = os.path.join(os.getcwd(), 'cache') @@ -26,7 +27,7 @@ def categorize_files(files): for file in files: if file.endswith(".pdf"): pdfs.append(file) - elif file.endswith(".jpg") or file.endswith(".png"): + elif file.endswith(".jpg") or file.endswith(".png") or file.endswith("JPG") or file.endswith("jpeg"): images.append(file) elif file.endswith(".mp4"): videos.append(file) @@ -83,3 +84,11 @@ def get_file_with_auto_mode(): if save_mode_data[key] == "auto": auto_files.append(key) return auto_files + + +def generate_thumb(filename): + """generate thumbnail for image and save in /thubmnails folder""" + directory = os.path.join(os.getcwd(), 'cache') + im = Image.open(os.path.join(directory, filename)) + im.thumbnail((128, 128)) + im.save(os.path.join('thumb', filename)) \ No newline at end of file -- GitLab