]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
webui/api: add possibility to remove dead services (maintenance button in the service...
authorJaroslav Kysela <perex@perex.cz>
Thu, 8 Dec 2016 17:10:55 +0000 (18:10 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 8 Dec 2016 17:11:01 +0000 (18:11 +0100)
src/api/api_service.c
src/input/mpegts/mpegts_service.c
src/service.c
src/service.h
src/webui/static/app/mpegts.js

index d5d6c709fb0858fddfbf683d30194ad7bfb15a0e..a4d7d2cbdc01a363dbcc3d1ef91ac486357013df 100644 (file)
@@ -160,6 +160,19 @@ api_service_streams
   return 0;
 }
 
+static int
+api_service_remove_unseen
+  ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
+{
+  int days = htsmsg_get_s32_or_default(args, "days", 7);
+  const char *type = htsmsg_get_str(args, "type");
+
+  pthread_mutex_lock(&global_lock);
+  service_remove_unseen(type, days);
+  pthread_mutex_unlock(&global_lock);
+  return 0;
+}
+
 void api_service_init ( void )
 {
   extern const idclass_t service_class;
@@ -170,6 +183,7 @@ void api_service_init ( void )
     { "service/mapper/status",  ACCESS_ADMIN, api_mapper_status, NULL },
     { "service/list",           ACCESS_ADMIN, api_idnode_load_by_class, (void*)&service_class },
     { "service/streams",        ACCESS_ADMIN, api_service_streams, NULL },
+    { "service/removeunseen",   ACCESS_ADMIN, api_service_remove_unseen, NULL },
     { NULL },
   };
 
index b7381e51b2fa23d66d58819fac47ad32ab6566f7..e426dd1d390bd44c1bae35bcabb75b078d62242c 100644 (file)
@@ -736,6 +736,15 @@ mpegts_service_memoryinfo ( service_t *t, int64_t *size )
   *size += tvh_strlen(ms->s_dvb_charset);
 }
 
+static int
+mpegts_service_unseen( service_t *t, const char *type, time_t before )
+{
+  mpegts_service_t *ms = (mpegts_service_t*)t;
+  int pat = type && strcasecmp(type, "pat") == 0;
+  if (pat && ms->s_auto != SERVICE_AUTO_PAT_MISSING) return 0;
+  return ms->s_dvb_last_seen < before;
+}
+
 /* **************************************************************************
  * Creation/Location
  * *************************************************************************/
@@ -790,6 +799,7 @@ mpegts_service_create0
   s->s_mapped         = mpegts_service_mapped;
   s->s_satip_source   = mpegts_service_satip_source;
   s->s_memoryinfo     = mpegts_service_memoryinfo;
+  s->s_unseen         = mpegts_service_unseen;
 
   pthread_mutex_lock(&s->s_stream_mutex);
   service_make_nicename((service_t*)s);
index 39f054782e9a05956682dd9521cf1566d5922516..49defee122c2c12ce545c702e5e83be618bbac25 100644 (file)
@@ -2014,6 +2014,23 @@ void service_save ( service_t *t, htsmsg_t *m )
   htsmsg_add_msg(m, "stream", list);
 }
 
+/**
+ *
+ */
+void
+service_remove_unseen(const char *type, int days)
+{
+  service_t *s, *sn;
+  time_t before = gclk() - MAX(days, 5) * 24 * 3600;
+
+  lock_assert(&global_lock);
+  for (s = TAILQ_FIRST(&service_all); s; s = sn) {
+    sn = TAILQ_NEXT(s, s_all_link);
+    if (s->s_unseen && s->s_unseen(s, type, before))
+      service_destroy(s, 1);
+  }
+}
+
 /**
  *
  */
index 7d15bb68947b83c7ee62736d0c66d546766b4d71..390adf0d7617228edbace92d0c3ae309e2e5ac02 100644 (file)
@@ -333,6 +333,8 @@ typedef struct service {
 
   void (*s_memoryinfo)(struct service *t, int64_t *size);
 
+  int (*s_unseen)(struct service *t, const char *type, time_t before);
+
   /**
    * Channel info
    */
@@ -619,6 +621,8 @@ void service_load ( service_t *s, htsmsg_t *c );
 
 void service_save ( service_t *s, htsmsg_t *c );
 
+void service_remove_unseen(const char *type, int days);
+
 void sort_elementary_streams(service_t *t);
 
 const char *service_get_channel_name (service_t *s);
index cbcd460c05ec169dad1f18bc291aecfb2efe7d50..51d4d0e821bda27523a9d3d295eeffd687f15591 100644 (file)
@@ -271,6 +271,48 @@ tvheadend.services = function(panel, index)
                 abuttons.map.setText(_('Map All'));
         };
 
+        var unseencb = function(type) {
+            tvheadend.Ajax({
+                url: 'api/service/removeunseen',
+                params: {
+                    type: type,
+                },    
+                success: function(d) {
+                    store.reload();
+                }
+            });
+        };
+
+        var maintenanceButton = {
+            name: 'misc',
+            builder: function() {
+                var m = new Ext.menu.Menu()
+                m.add({
+                    name: 'rmunsnpat',
+                    tooltip: _('Remove old services marked as missing in PAT/SDT which were not detected more than 7 days (last seen column)'),
+                    iconCls: 'remove',
+                    text: _('Remove unseen services (PAT/SDT) (7 days+)'),
+                });
+                m.add({
+                    name: 'rmunsn',
+                    tooltip: _('Remove old services which were not detected more than 7 days (last seen column)'),
+                    iconCls: 'remove',
+                    text: _('Remove all unseen services (7 days+)'),
+                });
+                return new Ext.Toolbar.Button({
+                    tooltip: _('Maintenance operations'),
+                    iconCls: 'wrench',
+                    text: _('Maintenance'),
+                    menu: m,
+                    disabled: false
+                });
+            },
+            callback: {
+                rmunsnpat: function() { unseencb('pat'); },
+                rmunsn: function() { unseencb(''); }
+            }
+        };
+
         var actions = new Ext.ux.grid.RowActions({
             header: _('Details'),
             width: 10,
@@ -293,7 +335,7 @@ tvheadend.services = function(panel, index)
             destroy: function() {
             }
         });
-        conf.tbar = [mapButton];
+        conf.tbar = [mapButton, maintenanceButton];
         conf.selected = selected;
         conf.lcol[1] = actions;
         conf.plugins = [actions];