Skip to content

Commit

Permalink
support license-expiring-notices
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexCXC committed Oct 18, 2023
1 parent e8fc869 commit f32bd5e
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
3 changes: 3 additions & 0 deletions dtable_events/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from dtable_events.tasks.dtable_real_time_rows_counter import DTableRealTimeRowsCounter
from dtable_events.tasks.ldap_syncer import LDAPSyncer
from dtable_events.tasks.dtable_asset_trash_cleaner import DTableAssetTrashCleaner
from dtable_events.tasks.license_expiring_notices_sender import LicenseExpiringNoticesSender
from dtable_events.notification_rules.handler import NotificationRuleHandler
from dtable_events.notification_rules.dtable_notification_rules_scanner import DTableNofiticationRulesScanner
from dtable_events.automations.handler import AutomationRuleHandler
Expand Down Expand Up @@ -51,6 +52,7 @@ def __init__(self, config, task_mode):
self._data_syncr = DataSyncer(config)
self._workflow_schedule_scanner = WorkflowSchedulesScanner(config)
self._dtable_asset_trash_cleaner = DTableAssetTrashCleaner(config)
self._license_expiring_notices_sender = LicenseExpiringNoticesSender(config)

def serve_forever(self):
if self._enable_foreground_tasks:
Expand Down Expand Up @@ -78,3 +80,4 @@ def serve_forever(self):
self._data_syncr.start() # default True
self._workflow_schedule_scanner.start() # default True
self._dtable_asset_trash_cleaner.start() # always True
self._license_expiring_notices_sender.start() # always True
109 changes: 109 additions & 0 deletions dtable_events/tasks/license_expiring_notices_sender.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import logging
import os
import re
from datetime import date
from threading import Thread

from apscheduler.schedulers.blocking import BlockingScheduler
from dateutil import parser

from seaserv import ccnet_api

from dtable_events.app.config import dtable_web_dir
from dtable_events.db import init_db_session_class
from dtable_events.utils import get_opt_from_conf_or_env, get_python_executable, run


class LicenseExpiringNoticesSender:

def __init__(self, config):
self._db_session_class = init_db_session_class(config)
self.days = [35, 15, 7, 6, 5, 4, 3, 2, 1]
self.license_path = '/shared/seatable-license.txt'
self._parse_config(config)
logdir = os.path.join(os.environ.get('LOG_DIR', ''))
self._logfile = os.path.join(logdir, 'license_expiring_notices_sender.log')

def _parse_config(self, config):
section_name = 'LICENSE-EXPIRING-NOTICES-SENDER'
key_days = 'days'
key_license_path = 'license_path'
if not config.has_section(section_name):
return

days_str = get_opt_from_conf_or_env(config, section_name, key_days, default='30,15,7,6,5,4,3,2,1')
days = []
for day_str in days_str.split(','):
try:
day = int(day_str.strip())
if day > 0 and day not in days:
days.append(day)
except:
pass
if days:
self.days = days
self.license_path = get_opt_from_conf_or_env(config, section_name, key_license_path, default='/shared/seatable-license.txt')

def start(self):
timer = LicenseExpiringNoticesSenderTimer(self._db_session_class, self.days, self.license_path, self._logfile)
logging.info('Start license notices sender...')
timer.start()


class LicenseExpiringNoticesSenderTimer(Thread):

def __init__(self, db_session_class, days, license_path, _log_file):
super(LicenseExpiringNoticesSenderTimer, self).__init__()
self.daemon = True
self.db_session_class = db_session_class
self.days = days
self.license_path = license_path
self._logfile = _log_file

def run(self):
sched = BlockingScheduler()

@sched.scheduled_job('cron', day_of_week='*', hour='*', minute='44')
def check():
logging.info('start to check license...')
if not os.path.isfile(self.license_path):
logging.warning('No license file found')
return
expire_str = ''
with open(self.license_path, 'r') as f:
for line in f.readlines():
line = line.strip()
logging.info('line: %s', line)
if line.startswith('Expiration'):
expire_str = line
break
if not expire_str:
logging.warning('No license expiration found')
return
date_strs = re.findall(r'\d{4}-\d{1,2}-\d{1,2}', expire_str)
if not date_strs:
logging.warning('No expire date found: %s', expire_str)
return
try:
expire_date = parser.parse(date_strs[0]).date()
except Exception as e:
logging.warning('No expire date found: %s error: %s', expire_str, e)
return
days = (expire_date - date.today()).days
days = 30
if days in self.days:
try:
python_exec = get_python_executable()
manage_py = os.path.join(dtable_web_dir, 'manage.py')
cmd = [
python_exec,
manage_py,
'send_license_expiring_notices',
str(days),
]
with open(self._logfile, 'a') as fp:
run(cmd, cwd=dtable_web_dir, output=fp)
except Exception as e:
logging.exception('error when cleaning trash dtables: %s', e)

sched.start()

0 comments on commit f32bd5e

Please sign in to comment.