Răsfoiți Sursa

Adjusted the system to use a different DB for the schedule email reminders. Also working on methods to prevent the DB locking issue.

Adam Day 2 ani în urmă
părinte
comite
d0c3c8758a
2 a modificat fișierele cu 91 adăugiri și 44 ștergeri
  1. 77 41
      app.py
  2. 14 3
      templates/admin_ils_users.html

+ 77 - 41
app.py

@@ -15,7 +15,10 @@ import threading
 import atexit
 
 db_name = 'app.db'
-db = SqliteDatabase(db_name, check_same_thread=False)
+db = SqliteDatabase(db_name, check_same_thread=False, timeout=5)
+
+schedule_db_name = 'schedule.db'
+schedule_db = SqliteDatabase(schedule_db_name, check_same_thread=False, timeout=5)
 
 
 class User(Model):
@@ -78,7 +81,7 @@ class EmailReminderLog(Model):
     ignore = BooleanField(default=False)
 
     class Meta:
-        database = db
+        database = schedule_db
 
 
 def reminder_cleanup():
@@ -90,11 +93,6 @@ def reminder_cleanup():
 def scheduler(stop_event):
     while not stop_event.is_set():
         try:
-            #db.connect()
-            # Get all scheduled intervals from the DB
-            intervals = Schedule.select().execute()
-            users = IlsUser.select().execute()
-
             # Get settings
             domain_name_setting = Settings.get(Settings.name == 'Domain Name')
             domain_name = domain_name_setting.value
@@ -125,7 +123,22 @@ def scheduler(stop_event):
             # expires based on the password_reset_interval value.
             # Loop through all users
 
-            if suspend is False:
+            if suspend.lower() == "false":
+                # Get all scheduled intervals from the DB
+                intervals = Schedule.select().execute()
+                users = IlsUser.select().execute()
+
+                # Remove reminders of users that doesn't exists
+                current_users = list()
+                for user in users:
+                    current_users.append(user.username)
+
+                current_reminders = EmailReminderLog.select().execute()
+
+                for reminder in current_reminders:
+                    if reminder.username not in current_users:
+                        reminder.delete_instance()
+
                 # Schedule emails to be sent for each user and interval
                 for user in users:
                     # get the scheduled intervals
@@ -147,33 +160,35 @@ def scheduler(stop_event):
                         else:
                             # Store the date in the DB
                             EmailReminderLog.create(date=email_date.strftime('%Y-%m-%d'), email=user.email, username=user.username, interval=interval.interval).save()
-
-                # Get all email reminders from the DB
-                # if today's date matches the EmailReminderLog date then send the email and mark the reminder as sent
-                reminders = EmailReminderLog.select().where(EmailReminderLog.date == datetime.datetime.now().strftime('%Y-%m-%d'), EmailReminderLog.ignore == 0, EmailReminderLog.sent == 0).execute()
-                for reminder in reminders:
-                    # Send the email
-                    emailer = Emailer(smtp_host, smtp_port, smtp_username, smtp_password)
-                    if reminder.interval == 1:
-                        # 1 day reminder email
-                        emailer.send_email(reminder.email, 'ILS Password Reset Reminder',
-                                           'The password for ILS account with the username "'
-                                           + reminder.username + '" will expire in ' + reminder.interval +
-                                           ' day.  To reset your password, please click the following link: ' + reset_link + '. If the password is not reset today the account will be locked.')
-                    else:
-                        # more than a day reminder email
-                        emailer.send_email(reminder.email, 'ILS Password Reset Reminder',
-                                           'The password for ILS account with the username "'
-                                           + reminder.username + '" will expire in ' + reminder.interval +
-                                           ' days.  To reset your password, please click the following link: ' + reset_link)
-                    # Mark the reminder as sent
-                    reminder.sent = True
-                    reminder.save()
+            else:
+                print("scheduler suspended")
+
+
+            # Get all email reminders from the DB
+            # if today's date matches the EmailReminderLog date then send the email and mark the reminder as sent
+            reminders = EmailReminderLog.select().where(EmailReminderLog.date == datetime.datetime.now().strftime('%Y-%m-%d'), EmailReminderLog.ignore == 0, EmailReminderLog.sent == 0).execute()
+            for reminder in reminders:
+                # Send the email
+                emailer = Emailer(smtp_host, smtp_port, smtp_username, smtp_password)
+                if reminder.interval == 1:
+                    # 1 day reminder email
+                    emailer.send_email(reminder.email, 'ILS Password Reset Reminder',
+                                       'The password for ILS account with the username "'
+                                       + reminder.username + '" will expire in ' + reminder.interval +
+                                       ' day.  To reset your password, please click the following link: ' + reset_link + '. If the password is not reset today the account will be locked.')
+                else:
+                    # more than a day reminder email
+                    emailer.send_email(reminder.email, 'ILS Password Reset Reminder',
+                                       'The password for ILS account with the username "'
+                                       + reminder.username + '" will expire in ' + reminder.interval +
+                                       ' days.  To reset your password, please click the following link: ' + reset_link)
+                # Mark the reminder as sent
+                reminder.sent = True
+                reminder.save()
                 # Remove all reminders from the DB that are older than today's date
                 reminder_cleanup()
-                #db.close()
         except Exception as e:
-            pass
+            print(e)
 
         time.sleep(1)  # Sleep for 5 seconds
 
@@ -207,20 +222,20 @@ if db.table_exists('settings') is False:
     Settings.create(name='Domain Name', value="lynx").save()
     Settings.create(name='Password Reset URL', value="https://terminal.idaho-lynx.org").save()
     Settings.create(name='Password Reset Interval', value="90").save()
-    Settings.create(name='Suspend Scheduler', value=False).save()
+    Settings.create(name='Suspend Scheduler', value="True").save()
 
 
 if db.table_exists('log') is False:
     db.create_tables([Log, ])
 
-if db.table_exists('password_reset_log') is False:
+if schedule_db.table_exists('password_reset_log') is False:
     db.create_tables([PasswordResetLog, ])
 
 if db.table_exists('schedule') is False:
     db.create_tables([Schedule, ])
 
 if db.table_exists('email_reminder_log') is False:
-    db.create_tables([EmailReminderLog, ])
+    schedule_db.create_tables([EmailReminderLog, ])
 
 settings = Settings.select().execute()
 
@@ -299,8 +314,12 @@ def admin_password_check():
 
 # Start the scheduler loop in another thread
 shutdown_scheduler = threading.Event()
+#scheduler_thread = threading.Thread(target=scheduler, args=(shutdown_scheduler,))
+#scheduler_thread.start()
+
 scheduler_thread = threading.Thread(target=scheduler, args=(shutdown_scheduler,))
 scheduler_thread.start()
+#scheduler_thread.join()
 
 # Start the HTTP Server
 app = Flask(__name__)
@@ -657,9 +676,15 @@ def admin_ils_users():
     # Get all admin users from the DB
     users = IlsUser.select().execute()
 
+    # Suspend setting
+    suspend_setting_setting = Settings.get(Settings.name == 'Suspend Scheduler')
+    suspend_setting = str(suspend_setting_setting.value).lower()
+    print(suspend_setting)
+
     context = {
         'users': users,
         'message': message,
+        'suspend_setting': suspend_setting,
     }
 
     return render_template('admin_ils_users.html', context=context)
@@ -693,13 +718,16 @@ def admin_ils_users_delete_all():
     if not requires_auth():
         return redirect(url_for('login'))
 
+    '''
     # Set the suspend scheduler to True
     settings = Settings.select().execute()
     for setting in settings:
         if setting.name == 'Suspend Scheduler':
             setting.value = 'True'
             setting.save()
+    '''
 
+    '''
     # Remove scheduled email reminders
     try:
         email_reminders = EmailReminderLog.select().execute()
@@ -707,18 +735,25 @@ def admin_ils_users_delete_all():
             reminder.delete_instance()
     except Exception as e:
         pass
+    '''
+    try:
+        # Remove all ILS users
+        users = IlsUser.select().execute()
+        for user in users:
+            user.delete_instance()
+    except Exception as e:
+        print('Database is locked')
+    finally:
+        db.close()
 
-    # Remove all ILS users
-    users = IlsUser.select().execute()
-    for user in users:
-        user.delete_instance()
-
+    '''
     # Set the suspend scheduler to False
     settings = Settings.select().execute()
     for setting in settings:
         if setting.name == 'Suspend Scheduler':
             setting.value = 'True'
             setting.save()
+    '''
 
     return redirect(url_for('admin_ils_users'))
 
@@ -1138,8 +1173,8 @@ def clean_up():
     shutdown_scheduler.set()
     http_server.stop()
 
-
 if __name__ == "__main__":
+
     print("------------------------- Start up -----------------------------")
     print("Starting HTTP Service on port %s..." % http_port)
 
@@ -1160,3 +1195,4 @@ if __name__ == "__main__":
     print("---------------------------------------------------------------")
     http_server.serve_forever()
     atexit.register(clean_up)
+

+ 14 - 3
templates/admin_ils_users.html

@@ -7,12 +7,23 @@
         </div>
     </div>
 {% endif %}
+
+{% if context.suspend_setting == "false" %}
+<div class="alert alert-warning" role="alert">
+  The scheduler is currently running. To make changes, you must first disable the scheduler. <a href="">Click here to disable the scheduler.</a>
+</div>
+{% else %}
+<div class="alert alert-primary" role="alert">
+  The scheduler is currently disabled. <a href="">Click here to enable the scheduler.</a>
+</div>
+{% endif %}
+
 <div class="row">
     <div class="col">
-        <a href="#!" data-bs-toggle="modal" data-bs-target="#remove-all-users" class="btn btn-danger float-end"><i class="ri-delete-bin-line"></i> Remove all ILS Users</a>
-        <a href="#!" data-bs-toggle="modal" data-bs-target="#add-user" class="btn btn-primary float-end me-2"><i class="ri-user-add-line"></i> Add ILS User</a>
+        <a href="#!" data-bs-toggle="modal" data-bs-target="#remove-all-users" class="btn btn-danger float-end {% if context.suspend_setting == "false" %} disabled {% endif %}"><i class="ri-delete-bin-line"></i> Remove all ILS Users</a>
+        <a href="#!" data-bs-toggle="modal" data-bs-target="#add-user" class="btn btn-primary float-end me-2 {% if context.suspend_setting == "false" %} disabled {% endif %}"><i class="ri-user-add-line"></i> Add ILS User</a>
         <a href="{{ url_for('admin_ils_users_csv_download') }}" class="btn btn-dark float-end me-2"><i class="ri-file-download-fill"></i> CSV Export</a>
-        <a href="{{ url_for('admin_ils_users_csv_import') }}" class="btn btn-dark float-end me-2"><i class="ri-file-upload-fill"></i> CSV Import</a>
+        <a href="{{ url_for('admin_ils_users_csv_import') }}" class="btn btn-dark float-end me-2 {% if context.suspend_setting == "false" %} disabled {% endif %}"><i class="ri-file-upload-fill"></i> CSV Import</a>
         <h3><i class="ri-shield-user-fill"></i> ILS Users</h3>
         <p class="lead">ILS users accounts establish with the ILS system.</p>
     </div>