Jelajahi Sumber

added possibility to view or download uploaded files, and added in sample CSS formatting for review

jacob-kruger-work 1 bulan lalu
induk
melakukan
b8920f9fd4

+ 12 - 1
flask_app/app/main/routes.py

@@ -311,7 +311,10 @@ def download_upload(i_upload:int = 0, bl_download:bool = True):
             o_out = io.BytesIO(o_upload.b_file)
             s_mimetype = o_upload.v_mime_type
             s_filename = o_upload.v_filename
-            resp = send_file(o_out, mimetype=s_mimetype, as_attachment=bl_download, download_name=s_filename)
+            # resp = send_file(o_out, mimetype=s_mimetype, as_attachment=bl_download, download_name=s_filename)
+            resp = make_response(o_out)
+            resp.headers.set("Content-Disposition", f"attachment; filename=\"{s_filename}\"" if bl_download else "inline")
+            resp.headers.set("Content-Type", s_mimetype)
             return resp
         else:
             return make_response("No upload retrieved", 500)
@@ -776,6 +779,14 @@ def user_details(i_user_id:int = 0):
 # end of user_details view function for route /user_details/<int:i_user_id>/
 
 
+@bp.route("/css_sample", methods=["GET"])
+def css_sample():
+    """CSS sample page - purely testing"""
+    s_base = "base_bs.html" if Config.BOOTSTRAP else "base.html"
+    s_url = url_for("main.index")#, _external=True)
+    return render_template("css_sample.html", js=True, base=s_base, url=s_url)
+# end of css_sample view function for route /css_sample
+
 
 s_todo = """
     double-check both try-except across the board, along with then logging exceptions

TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams.ttf


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams.woff


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams_Bold.ttf


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams_Bold.woff


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams_BoldItalic.ttf


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams_BoldItalic.woff


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams_Italic.ttf


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/CaviarDreams_Italic.woff


TEMPAT SAMPAH
flask_app/app/static/cv_db/css/alteram/alteram1_1_600x197.png


+ 47 - 0
flask_app/app/static/cv_db/css/alteram/styles.css

@@ -0,0 +1,47 @@
+body {
+font-family: Arial;
+background-color: white;
+color: rgb(39, 37, 92);
+}
+h2 {
+font-family: caviardreams;
+font-size: 14pt;
+background-color: white;
+color: rgb(39, 37, 92);
+}
+a {
+color: rgb(250,122,30);
+}
+a.visited {
+color: rgb(250,122,30);
+}
+#tbl_layout {
+border: 0px solid transparent;
+}
+#tbl_layout td {
+text-align: left;
+}
+.td_nav {
+width: 20%;
+}
+.td_top {
+vertical-align: top;
+}
+div {
+line-height: 1.2;
+margin-bottom: 10px;
+}
+table.multirow {
+border: 2px solid DimGray;
+}
+table.multirow tr {
+vertical-align: top;
+}
+table.multirow th {
+text-align: left;
+border: 1px solid DimGray;
+}
+table.multirow td {
+text-align: left;
+border: 1px solid DimGray;
+}

+ 146 - 0
flask_app/app/templates/css_sample.html

@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=utf-8">
+<META http-equiv="Content-Style-Type" content="text/css">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<link rel="icon" type="image/x-icon" sizes="32x32" href="{{ url_for("static", filename="cv_db/favicon.ico") }}">
+{% if js %}
+<script type="text/javascript" src="{{ url_for("static", filename="cv_db/js/jquery.js") }}"></script>
+<script type="text/javascript">
+var do_alert;
+
+$(document).ready( function() {
+try {
+
+do_alert = function(s_in) {
+	s_in = String(s_in).replace("\n", "<br />");
+	$("#div_alert").show();
+	//document.getElementById("div_alert").innerHTML = s_in;
+	$("#div_alert").html(s_in);
+}//end of do_alert function
+
+$.fn.redraw =function(){
+	$(this).each(function(){var redraw =this.offsetHeight;});
+};//end of $.fn.redraw function
+
+var s_server_url = "{{ url }}";
+$.each($("ul.nav").find("a"), function(ix, a) {
+    if (s_server_url.endsWith($(a).attr("href"))) { $(a).attr("aria-current", "true"); } else { $(a).attr("aria-current", ""); }
+});// end of .each on nav links
+// alert([s_url, s_server_url]);
+
+var s_msg = "";
+{% with messages = get_flashed_messages() %}
+{% if messages %}
+s_msg = "{{ messages[-1] }}";
+{% endif %}
+{% endwith %}
+if (String(s_msg).length>0) {
+    window.setTimeout( function() {
+    $("#div_alert").toggleClass("warning");
+    do_alert(s_msg);
+    }, 300);
+}
+
+} catch(e) {
+    var s_err = String(e.name) + "\nmessage:" + String(e.message);
+    s_err = (typeof(e.lineNumber)!="undefined") ? s_err + "\nline:" + String(e.lineNumber) : s_err;
+    alert("Error! " + s_err);
+}//end of catch
+});//end of document ready
+</script>
+{% endif %}{# end of js check #}
+<title>C.V. Database - Style-sheet Sample Page</title>
+<link type="text/css" rel="stylesheet" href="{{ url_for("static", filename="cv_db/css/alteram/styles.css") }}" />
+<style>
+ul.nav {
+text-align: left;
+}
+ul.nav li {
+display: inline-block;
+}
+</style>
+{% block head_extra %}{% endblock head_extra %}
+<style>
+@font-face {
+font-family: CaviarDreams;
+src:
+local("CaviarDreams"),
+url("{{ url_for("static", filename="cv_db/css/alteram/CaviarDreams.woff") }}") format("woff"),
+url("{{ url_for("static", filename="cv_db/css/alteram/CaviarDreams.ttf") }}") format('truetype');
+font-weight: normal;
+}
+@font-face {
+font-family: CaviarDreams;
+src:
+local("CaviarDreams"),
+url("{{ url_for("static", filename="cv_db/css/alteram/CaviarDreams_Bold.woff") }}") format("woff"),
+url("{{ url_for("static", filename="cv_db/css/alteram/CaviarDreams_Bold.ttf") }}") format('truetype');
+font-weight: bold;
+font-style: normal;
+}
+body {
+background-image: url("{{ url_for("static", filename="cv_db/css/alteram/alteram1_1_600x197.png") }}"); /* Replace with the actual URL */
+background-repeat: no-repeat; /* Prevent the image from tiling */
+background-position: top center; /* Align the image to the top and center horizontally */
+background-attachment: fixed; /* Make the background image fixed relative to the viewport */
+background-size: auto; /* Maintain the image's original aspect ratio */
+font-family: CaviarDreams;
+background-color: white;
+color: rgb(39, 37, 92);
+}
+h2 {
+font-family: caviardreams;
+font-size: 14pt;
+background-color: white;
+color: rgb(39, 37, 92);
+}
+a {
+color: rgb(250,122,30);
+}
+a.visited {
+color: rgb(250,122,30);
+}
+</style>
+</head>
+<body>
+{% from "macros/console.html" import console_replacement %}
+{# {{ console_replacement() }} #}
+<div><ul class="nav" role="navigation">
+{% if current_user %}
+<li><a href="{{ url_for("main.index") }}">Landing page</a></li>
+{% if current_user.bl_admin %}
+<li><a href="{{ url_for("main.qualifications") }}">Qualifications</a></li>
+<li><a href="{{ url_for("main.roles") }}">Positions | Roles</a></li>
+<li><a href="{{ url_for("main.users") }}">Access User Profiles</a></li>
+{% endif %}{# end of checking for bl_admin #}
+{% if current_user.bl_capture or current_user.bl_admin %}
+<li><a href="{{ url_for("main.capture_record") }}">Capture record</a></li>
+{% endif %}{# end of checking if either bl_capture or bl_admin #}
+<li><a href="{{ url_for("auth.logout") }}">Logout</a></li>
+{% else %}
+<li><a href="{{ url_for("auth.login") }}">Login</a></li>
+{% endif %}
+</ul></div>
+<span class="title"><h2>Style-sheet Sample Page</h2></span>
+<div class="content">
+<div id="div_alert" style="text-align: center;" aria-live="assertive">&nbsp;</div>
+<table id="tbl_test" class="multirow">
+<thead>
+<tr>
+<th>Column 1</th><th>Column 2</th><th>Column 3</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Data value 1</td><td>Data value 2</td><td><td>Data value 3</td>
+</tr>
+<tr>
+<td>Data value 4</td><td>Data value 5</td><td><td>Data value 6</td>
+</tr>
+</tbody>
+</table>
+</div><!-- end of div.content -->
+</body>
+</html>

+ 3 - 2
flask_app/app/templates/index.html

@@ -296,8 +296,9 @@ try {
                 $.each(o_data.uploads, function(ix, u) {
                     s_html = s_html + "<li><ul>";
                     s_html = s_html + "<li><span class=\"label\">Document Type:</span>&nbsp;" + String(u.si_upload_type) + "</li>\n";
-                    s_url = "{{ url_for("main.download_upload", i_upload=99999, bl_download=True) }}".replace("99999", String(u["id"]));
-                    s_html = s_html + "<li><span class=\"label\">File Name:</span>&nbsp;<a href=\"" + s_url + "\" target=\"_blank\">" + String(u["v_filename"]) + "</a></li>\n";
+                    s_url_download = "{{ url_for("main.download_upload", i_upload=99999, bl_download=True) }}".replace("99999", String(u["id"]));
+                    s_url_view = "{{ url_for("main.download_upload", i_upload=99999, bl_download=False) }}".replace("99999", String(u["id"]));
+                    s_html = s_html + "<li><span class=\"label\">File Name:</span>&nbsp;<a href=\"" + s_url_download + "\" target=\"_blank\"> download - " + String(u["v_filename"]) + "</a>&nbsp;<a href=\"" + s_url_view + "\" target=\"_blank\"> view - " + String(u["v_filename"]) + "</a></li>\n";
                     s_html = s_html + "<li><span class=\"label\">Description:</span>&nbsp;" + String(u["v_description"]) + "</li>\n";
                     if (String(u["v_qualification_name"])!="null") { s_html = s_html + "<li><span class=\"label\">Matching Qualification:</span>&nbsp;" + String(u["v_qualification_name"]) + "</li>\n"; }
                     s_html = s_html + "</ul></li>\n";

+ 47 - 0
tatus

@@ -0,0 +1,47 @@
+diff --git a/flask_app/app/main/routes.py b/flask_app/app/main/routes.py
+index c36c90c..9e38594 100644
+--- a/flask_app/app/main/routes.py
++++ b/flask_app/app/main/routes.py
+@@ -311,7 +311,10 @@ def download_upload(i_upload:int = 0, bl_download:bool = True):
+             o_out = io.BytesIO(o_upload.b_file)
+             s_mimetype = o_upload.v_mime_type
+             s_filename = o_upload.v_filename
+-            resp = send_file(o_out, mimetype=s_mimetype, as_attachment=bl_download, download_name=s_filename)
++            # resp = send_file(o_out, mimetype=s_mimetype, as_attachment=bl_download, download_name=s_filename)
++            resp = make_response(o_out)
++            resp.headers.set("Content-Disposition", f"attachment; filename=\"{s_filename}\"" if bl_download else "inline")
++            resp.headers.set("Content-Type", s_mimetype)
+             return resp
+         else:
+             return make_response("No upload retrieved", 500)
+@@ -776,6 +779,14 @@ def user_details(i_user_id:int = 0):
+ # end of user_details view function for route /user_details/<int:i_user_id>/
+ 
+ 
++@bp.route("/css_sample", methods=["GET"])
++def css_sample():
++    """CSS sample page - purely testing"""
++    s_base = "base_bs.html" if Config.BOOTSTRAP else "base.html"
++    s_url = url_for("main.index")#, _external=True)
++    return render_template("css_sample.html", js=True, base=s_base, url=s_url)
++# end of css_sample view function for route /css_sample
++
+ 
+ s_todo = """
+     double-check both try-except across the board, along with then logging exceptions
+diff --git a/flask_app/app/templates/index.html b/flask_app/app/templates/index.html
+index 211713f..68aa33e 100644
+--- a/flask_app/app/templates/index.html
++++ b/flask_app/app/templates/index.html
+@@ -296,8 +296,9 @@ try {
+                 $.each(o_data.uploads, function(ix, u) {
+                     s_html = s_html + "<li><ul>";
+                     s_html = s_html + "<li><span class=\"label\">Document Type:</span>&nbsp;" + String(u.si_upload_type) + "</li>\n";
+-                    s_url = "{{ url_for("main.download_upload", i_upload=99999, bl_download=True) }}".replace("99999", String(u["id"]));
+-                    s_html = s_html + "<li><span class=\"label\">File Name:</span>&nbsp;<a href=\"" + s_url + "\" target=\"_blank\">" + String(u["v_filename"]) + "</a></li>\n";
++                    s_url_download = "{{ url_for("main.download_upload", i_upload=99999, bl_download=True) }}".replace("99999", String(u["id"]));
++                    s_url_view = "{{ url_for("main.download_upload", i_upload=99999, bl_download=False) }}".replace("99999", String(u["id"]));
++                    s_html = s_html + "<li><span class=\"label\">File Name:</span>&nbsp;<a href=\"" + s_url_download + "\" target=\"_blank\"> download - " + String(u["v_filename"]) + "</a>&nbsp;<a href=\"" + s_url_view + "\" target=\"_blank\"> view - " + String(u["v_filename"]) + "</a></li>\n";
+                     s_html = s_html + "<li><span class=\"label\">Description:</span>&nbsp;" + String(u["v_description"]) + "</li>\n";
+                     if (String(u["v_qualification_name"])!="null") { s_html = s_html + "<li><span class=\"label\">Matching Qualification:</span>&nbsp;" + String(u["v_qualification_name"]) + "</li>\n"; }
+                     s_html = s_html + "</ul></li>\n";