소스 검색

Added DB and table creation. Started working on getting the functionality working.

Adam Day 2 년 전
부모
커밋
39df214742
4개의 변경된 파일174개의 추가작업 그리고 4개의 파일을 삭제
  1. 87 4
      app.py
  2. 3 0
      templates/auth_layout.html
  3. 2 0
      templates/password_reset_log.html
  4. 82 0
      templates/schedule.html

+ 87 - 4
app.py

@@ -6,7 +6,7 @@ from flask import Flask, render_template, request, redirect, url_for, session, s
 from gevent.pywsgi import WSGIServer
 import socket
 import logging
-from peewee import Model, CharField, DateTimeField, SqliteDatabase, BooleanField
+from peewee import Model, CharField, DateTimeField, SqliteDatabase, BooleanField, fn
 import hashlib
 import os
 import csv
@@ -43,7 +43,7 @@ class Settings(Model):
 
 
 class Schedule(Model):
-    days = CharField()
+    interval = CharField()
 
     class Meta:
         database = db
@@ -195,6 +195,36 @@ app = Flask(__name__)
 app.secret_key = os.urandom(24)
 
 
+def format_time_ago(timestamp):
+    """Calculate the time passed since a datetime stamp and format it as a human-readable string."""
+    now = datetime.datetime.utcnow()
+    diff = now - timestamp
+
+    if diff.days > 365:
+        years = diff.days // 365
+        return f"{years} year{'s' if years > 1 else ''} ago"
+
+    if diff.days > 30:
+        months = diff.days // 30
+        return f"{months} month{'s' if months > 1 else ''} ago"
+
+    if diff.days > 0:
+        return f"{diff.days} day{'s' if diff.days > 1 else ''} ago"
+
+    if diff.seconds > 3600:
+        hours = diff.seconds // 3600
+        return f"{hours} hour{'s' if hours > 1 else ''} ago"
+
+    if diff.seconds > 60:
+        minutes = diff.seconds // 60
+        return f"{minutes} minute{'s' if minutes > 1 else ''} ago"
+
+    return "just now"
+
+
+app.jinja_env.filters['time_since'] = format_time_ago
+
+
 @app.before_request
 def before_request():
     db.connect()
@@ -345,7 +375,7 @@ def admin_ils_users():
 
             IlsUser.create(username=username, email=email, reset_datetime=datetime.datetime.now()).save()
             message = 'ILS User: %s created successfully' % username
-            Log.create(username=session['username'], action='Created ILS User: %s' % username,).save()
+            Log.create(username=session['username'], action='Created ILS User: %s' % username, ).save()
 
     # Get all admin users from the DB
     users = IlsUser.select().execute()
@@ -480,6 +510,59 @@ def settings():
     return render_template('settings.html', context=context)
 
 
+@app.route('/admin/schedule', methods=['GET', 'POST'])
+def schedule():
+    # Check to see if user is logged in
+    if not requires_auth():
+        return redirect(url_for('login'))
+
+    message = None
+
+    # add schedule
+    if request.method == 'POST':
+        # Assign form values to variables
+        interval = request.form.get('interval')
+
+        # Check if the schedule already exists
+        try:
+            schedule = Schedule.get(Schedule.interval == interval)
+        except Exception as e:
+            print(e)
+            schedule = None
+
+        if schedule:
+            message = 'Schedule already exists'
+        else:
+            # Create the schedule
+            Schedule.create(interval=interval).save()
+            Log.create(username=session['username'], action='Created schedule for %s day interval.' % interval).save()
+            message = 'Schedule: %s created successfully' % interval
+
+    # Get all schedules from the DB
+    schedules = Schedule.select().order_by(Schedule.interval.cast("INTEGER")).execute()
+
+    context = {
+        'schedules': schedules,
+        'message': message,
+    }
+
+    return render_template('schedule.html', context=context)
+
+
+# remove schedule
+@app.route('/admin/schedule/remove/<int:id>', methods=['GET', 'POST'])
+def schedule_remove(id):
+    # Check to see if user is logged in
+    if not requires_auth():
+        return redirect(url_for('login'))
+
+    # Get the schedule from the DB
+    schedule = Schedule.get(Schedule.id == id)
+    schedule.delete_instance()
+    Log.create(username=session['username'], action='Removed schedule for a %s day reminder.' % schedule.interval).save()
+    return redirect(url_for('schedule'))
+
+
 @app.route('/admin/system/log')
 def system_log():
     # Check to see if user is logged in
@@ -560,7 +643,7 @@ def login():
 
 
 # on exit of the program make sure the http server is stopped
-#@app.teardown_appcontext
+# @app.teardown_appcontext
 
 
 if __name__ == "__main__":

+ 3 - 0
templates/auth_layout.html

@@ -29,6 +29,9 @@
                     <li class="nav-item">
                         <a class="nav-link bg-light text-dark border-bottom" href="{{ url_for('settings') }}"><i class="ri-settings-5-line"></i> Settings</a>
                     </li>
+                    <li class="nav-item">
+                        <a class="nav-link bg-light text-dark border-bottom" href="{{ url_for('schedule') }}"><i class="ri-time-line"></i> Schedule</a>
+                    </li>
                     <li class="nav-item">
                         <a class="nav-link bg-light text-dark border-bottom" href="{{ url_for('system_log') }}"><i class="ri-file-list-3-line"></i> System Log</a>
                     </li>

+ 2 - 0
templates/password_reset_log.html

@@ -13,6 +13,7 @@
                 <tr>
                     <th scope="col">ILS User</th>
                     <th scope="col">Reset Date/Time</th>
+                    <th></th>
                 </tr>
             </thead>
             <tbody>
@@ -20,6 +21,7 @@
                 <tr>
                     <td>{{ log.username }}</td>
                     <td>{{ log.date }}</td>
+                    <td>{{ log.date|time_since }}</td>
                 </tr>
                 {% endfor %}
             </tbody>

+ 82 - 0
templates/schedule.html

@@ -0,0 +1,82 @@
+{% extends 'auth_layout.html' %}
+{% block content %}
+{% if context.message %}
+    <div class="row">
+        <div class="col text-center text-primary">
+            <i class="ri-error-warning-fill"></i> {{ context.message }}
+        </div>
+    </div>
+{% endif %}
+<div class="row">
+    <div class="col">
+        <a href="#!" data-bs-toggle="modal" data-bs-target="#add-schedule" class="btn btn-primary float-end me-2"><i class="ri-add-line"></i> Schedule</a>
+        <h3><i class="ri-time-line"></i> Schedule</h3>
+        <p class="lead">The following schedule rules will schedule and send email reminders to staff.</p>
+    </div>
+</div>
+<div class="row">
+    <div class="col">
+        <table class="table table-flush">
+            <thead>
+                <tr>
+                    <th scope="col">Interval</th>
+                    <th scope="col"></th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for schedule in context.schedules %}
+                <tr>
+                    <td>Send email reminder {{ schedule.interval }} day{% if schedule.interval > "1" %}s{% endif %} before password expires.</td>
+                    <td class="text-end">
+                        <a href="#!" data-bs-toggle="modal" data-bs-target="#setting-{{ loop.index0 }}" class="btn btn-danger">Delete</a>
+                    </td>
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+</div>
+
+<div class="modal fade" id="add-schedule" tabindex="-1">
+    <div class="modal-dialog modal-dialog-centered">
+        <div class="modal-content">
+            <div class="modal-header bg-light">
+                <h1 class="modal-title fs-5"><i class="ri-add-line"></i> Add Schedule</h1>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <form action="" method="post">
+                <div class="modal-body">
+                    <div class="mb-3">
+                        <input type="text" class="form-control" id="interval" name="interval" placeholder="Interval in days" required>
+                    </div>
+                </div>
+                <div class="modal-footer bg-light">
+                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
+                    <input type="submit" class="btn btn-primary" value="Save">
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+
+{% for schedule in context.schedules %}
+<div class="modal fade" id="setting-{{ loop.index0 }}" tabindex="-1">
+    <div class="modal-dialog modal-dialog-centered">
+        <div class="modal-content">
+            <div class="modal-header bg-light">
+                <h1 class="modal-title fs-5">Confirmation </h1>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+                <p class="lead">Are you sure you want to delete this schedule?</p>
+            </div>
+            <div class="modal-footer bg-light">
+                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
+                <a class="btn btn-danger" href="{{ url_for('schedule_remove', id=schedule.id) }}">Yes, remove the schedule</a>
+            </div>
+        </div>
+    </div>
+</div>
+{% endfor %}
+
+{% endblock %}