Browse Source

activate scheduler

Davide Alberani 6 years ago
parent
commit
c48f4a10b1
3 changed files with 96 additions and 17 deletions
  1. 49 10
      diffido.py
  2. 1 1
      dist/index.html
  3. 46 6
      dist/schedule.html

+ 49 - 10
diffido.py

@@ -48,13 +48,48 @@ def next_id(schedules):
     return str(max([int(i) for i in ids]) + 1)
 
 
-def get_schedule(id_):
+def get_schedule(id_, addID=True):
     schedules = read_schedules()
     data = schedules.get('schedules', {}).get(id_, {})
-    data['id'] = str(id_)
+    if addID:
+        data['id'] = str(id_)
     return data
 
 
+def run_job(id_=None, *args, **kwargs):
+    schedule = get_schedule(id_, addID=False)
+    url = schedule.get('url')
+    if not url:
+        return
+    print('Running job id:%s title:%s url: %s' % (id_, schedule.get('title', ''), url))
+
+
+def scheduler_update(scheduler, id_):
+    schedule = get_schedule(id_, addID=False)
+    if not schedule:
+        return
+    trigger = schedule.get('trigger')
+    if trigger not in ('interval', 'cron'):
+        return
+    args = {'trigger': trigger}
+    if trigger == 'interval':
+        for unit in 'weeks', 'days', 'hours', 'minutes', 'seconds':
+            if 'interval_%s' % unit not in schedule:
+                continue
+            args[unit] = int(schedule['interval_%s' % unit])
+    scheduler.add_job(run_job, id=id_, replace_existing=True, kwargs={'id_': id_}, **args)
+
+
+def scheduler_delete(scheduler, id_):
+    scheduler.remove_job(job_id=id_)
+
+
+def reset_from_schedules(scheduler):
+    scheduler.remove_all_jobs()
+    for key in read_schedules().get('schedules', {}).keys():
+        scheduler_update(scheduler, id_=key)
+
+
 class DiffidoBaseException(Exception):
     """Base class for diffido custom exceptions.
 
@@ -150,6 +185,7 @@ class SchedulesHandler(BaseHandler):
             return self.build_error(message='schedule %s not found' % id_)
         schedules['schedules'][id_] = data
         write_schedules(schedules)
+        scheduler_update(scheduler=self.scheduler, id_=id_)
         self.write(get_schedule(id_=id_))
 
     @gen.coroutine
@@ -159,6 +195,7 @@ class SchedulesHandler(BaseHandler):
         id_ = next_id(schedules)
         schedules['schedules'][id_] = data
         write_schedules(schedules)
+        scheduler_update(scheduler=self.scheduler, id_=id_)
         self.write(get_schedule(id_=id_))
 
     @gen.coroutine
@@ -169,9 +206,16 @@ class SchedulesHandler(BaseHandler):
         if id_ in schedules.get('schedules', {}):
             del schedules['schedules'][id_]
             write_schedules(schedules)
+        scheduler_delete(scheduler=self.scheduler, id_=id_)
         self.build_success(message='removed schedule %s' % id_)
 
 
+class ResetSchedulesHandler(BaseHandler):
+    @gen.coroutine
+    def post(self, *args, **kwargs):
+        reset_from_schedules(self.scheduler)
+
+
 class TemplateHandler(BaseHandler):
     """Handler for the / path."""
     app_path = os.path.join(os.path.dirname(__file__), "dist")
@@ -185,18 +229,10 @@ class TemplateHandler(BaseHandler):
         self.render(page, **arguments)
 
 
-def run_scheduled(id_=None, *args, **kwargs):
-    print('RUNNING %d' % id_)
-
-def run():
-    print('runno!')
-
 def serve():
     jobstores = {'default': SQLAlchemyJobStore(url=JOBS_STORE)}
     scheduler = TornadoScheduler(jobstores=jobstores)
     scheduler.start()
-    #scheduler.remove_job('run')
-    #scheduler.add_job(run, 'interval', minutes=1)
 
     define('port', default=3210, help='run on the given port', type=int)
     define('address', default='', help='bind the server at the given address', type=str)
@@ -219,8 +255,11 @@ def serve():
     init_params = dict(listen_port=options.port, logger=logger, ssl_options=ssl_options,
                        scheduler=scheduler)
 
+    _reset_schedules_path = r'schedules/reset'
     _schedules_path = r'schedules/?(?P<id_>\d+)?'
     application = tornado.web.Application([
+            ('/api/%s' % _reset_schedules_path, ResetSchedulesHandler, init_params),
+            (r'/api/v%s/%s' % (API_VERSION, _reset_schedules_path), ResetSchedulesHandler, init_params),
             ('/api/%s' % _schedules_path, SchedulesHandler, init_params),
             (r'/api/v%s/%s' % (API_VERSION, _schedules_path), SchedulesHandler, init_params),
             (r'/?(.*)', TemplateHandler, init_params),

+ 1 - 1
dist/index.html

@@ -9,7 +9,7 @@
                     <h1 class="md-title">Schedules <a href="schedule.html">add new</a></h1>
                 </md-table-toolbar>
                 <md-table-row slot="md-table-row" slot-scope="{item}">
-                    <md-table-cell md-label="#" md-sort-by="id" md-numeric>${ item.id }</md-table-cell>
+                    <md-table-cell md-label="#" md-sort-by="id" md-numeric><a :href="settingsUrl(item)">${ item.id }</a></md-table-cell>
                     <md-table-cell md-label="title" md-sort-by="title"><a :href="settingsUrl(item)">${ item.title }</a></md-table-cell>
                     <md-table-cell md-label="url" md-sort-by="email">${ item.url }</md-table-cell>
                 </md-table-row>

+ 46 - 6
dist/schedule.html

@@ -12,9 +12,48 @@
                 <label>url</label>
                 <md-input v-model="schedule.url"></md-input>
             </md-field>
+
+            <md-field>
+                <label>trigger</label>
+                <md-select v-model="schedule.trigger">
+                    <md-option value="interval">interval</md-option>
+                    <md-option value="cron">cron</md-option>
+                </md-select>
+            </md-field>
+
+            <div v-if="schedule.trigger == 'interval'">
+                <md-field>
+                    <label>weeks</label>
+                    <md-input v-model="schedule.interval_weeks" type="number"></md-input>
+                </md-field>
+                <md-field>
+                    <label>days</label>
+                    <md-input v-model="schedule.interval_days" type="number"></md-input>
+                </md-field>
+                <md-field>
+                    <label>hours</label>
+                    <md-input v-model="schedule.interval_hours" type="number"></md-input>
+                </md-field>
+                <md-field>
+                    <label>minutes</label>
+                    <md-input v-model="schedule.interval_minutes" type="number"></md-input>
+                </md-field>
+                <md-field>
+                    <label>seconds</label>
+                    <md-input v-model="schedule.interval_seconds" type="number"></md-input>
+                </md-field>
+            </div>
+
+            <div v-if="schedule.trigger == 'cron'">
+                <md-field>
+                    <label>crontab</label>
+                    <md-input v-model="schedule.cron_crontab"></md-input>
+                </md-field>
+            </div>
+
             <md-field>
                 <label>notify email</label>
-                <md-input v-model="schedule.email"></md-input>
+                <md-input v-model="schedule.email" type="email"></md-input>
             </md-field>
             <md-field>
                 <label>XPath selector</label>
@@ -28,8 +67,8 @@
             
             <br />
             <md-button class="md-raised md-primary" @click="saveSchedule()">save</md-button>
-            <md-button class="md-accent" :disabled="!hasID()" @click="deleteSchedule()">delete</md-button>
-            <md-button href="/">cancel</md-button>
+            <md-button class="md-raised md-accent" :disabled="!hasID()" @click="deleteSchedule()">delete</md-button>
+            <md-button href="/">back</md-button>
         </div>
     </div>
 </div>
@@ -47,7 +86,8 @@ var app = new Vue({
         {% else %}
         id: null,
         {% end %}
-        schedule: {}
+        schedule: {},
+        empty_schedule: {enabled: true, trigger: 'interval'}
     },
     mounted: function() {
         this.getSchedule(this.id);
@@ -60,12 +100,12 @@ var app = new Vue({
         },
         getSchedule: function() {
             if (!this.hasID()) {
-                this.schedule = {enabled: true};
+                this.schedule = this.empty_schedule;
                 return;
             }
             self = this;
             var data = axios.get('/api/schedules/' + this.id).then(function(response) {
-                self.schedule = response.data.schedule || {};
+                self.schedule = response.data.schedule || self.empty_schedule;
             });
         },
         saveSchedule: function() {