Exemple #1
0
static int
xmlrpc_parse_value(htsmsg_t *dst, htsmsg_field_t *g, const char *name,
		   char *errbuf, size_t errlen)
{
  const char *cdata;
  htsmsg_t *c;
  htsmsg_t *sub;

  if(!strcmp(g->hmf_name, "struct") &&
     (c = htsmsg_get_map_by_field(g)) != NULL) {

    sub = htsmsg_create_map();
    if(xmlrpc_parse_struct(sub, c, errbuf, errlen)) {
      htsmsg_release(sub);
      return -1;
    }
    htsmsg_add_msg(dst, name, sub);
    return 0;

  } else if(!strcmp(g->hmf_name, "array") &&
	    (c = htsmsg_get_map_by_field(g)) != NULL) {

    sub = htsmsg_create_list();
    if(xmlrpc_parse_array(sub, c, errbuf, errlen)) {
      htsmsg_release(sub);
      return -1;
    }
    htsmsg_add_msg(dst, name, sub);
    return 0;
  }

  cdata = g->hmf_type == HMF_STR ? g->hmf_str : NULL;

  if(!strcmp(g->hmf_name, "string")) {
    if(cdata != NULL)
      htsmsg_add_str(dst, name, cdata);

  } else if(!strcmp(g->hmf_name, "boolean")) {
    if(cdata != NULL)
      htsmsg_add_u32(dst, name, atoi(cdata));

  } else if(!strcmp(g->hmf_name, "double")) {
    if(cdata != NULL)
      htsmsg_add_dbl(dst, name, my_str2double(cdata, NULL));

  } else if(!strcmp(g->hmf_name, "int")) {
    if(cdata != NULL)
      htsmsg_add_s64(dst, name, atoll(cdata));

  } else {
    snprintf(errbuf, errlen, "Unknown field type \"%s\" %s = %s",
             g->hmf_name, name, cdata);
    return -1;
  }
  return 0;
}
Exemple #2
0
static void
keyring_clear(void *opaque, prop_event_t event, ...)
{
  hts_mutex_lock(&keyring_mutex);
  htsmsg_release(persistent_keyring);
  htsmsg_release(temporary_keyring);

  persistent_keyring = htsmsg_create_map();
  temporary_keyring = htsmsg_create_map();

  htsmsg_store_save(persistent_keyring, "keyring");
  hts_mutex_unlock(&keyring_mutex);

  notify_add(NULL, NOTIFY_WARNING, NULL, 3, _("Rembered passwords erased"));
}
Exemple #3
0
static htsmsg_t *
xmlrpc_convert_response(htsmsg_t *xml, char *errbuf, size_t errlen)
{
  htsmsg_t *dst, *params;
  htsmsg_field_t *f, *g;
  htsmsg_t *c;


  if((params = htsmsg_get_map_multi(xml, "methodResponse",  "params",
				    NULL)) == NULL) {
    snprintf(errbuf, errlen, "No params in reply found");
    return NULL;
  }


  dst = htsmsg_create_list();

  HTSMSG_FOREACH(f, params) {
    if(strcmp(f->hmf_name, "param") || (c = htsmsg_get_map_by_field(f)) == NULL)
      continue;

    if((c = htsmsg_get_map(c, "value")) == NULL)
      continue;

    g = TAILQ_FIRST(&c->hm_fields);
    if(g == NULL || g->hmf_type != HMF_MAP)
      continue;

    if(xmlrpc_parse_value(dst, g, NULL, errbuf, errlen)) {
      htsmsg_release(dst);
      return NULL;
    }
  }
  return dst;
}
Exemple #4
0
static htsmsg_t *
avt_SetAVTransportURI(http_connection_t *hc, htsmsg_t *args,
		      const char *myhost, int myport)
{
  const char *uri = htsmsg_get_str(args, "CurrentURI");
  const char *metaxml = htsmsg_get_str(args, "CurrentURIMetaData");
  char errbuf[200];
  htsmsg_t *meta;

  if(uri == NULL)
    return NULL;

  if(metaxml == NULL) {
    playqueue_play(uri, prop_create_root(NULL), 1);
    return NULL;
  }

  meta = htsmsg_xml_deserialize_cstr(metaxml, errbuf, sizeof(errbuf));
  if(meta == NULL) {
    TRACE(TRACE_ERROR, "UPNP", 
	  "SetAVTransportURI: Unable to parse metadata -- %s", errbuf);
    return NULL;
  }
  
  if(play_with_context(uri, meta)) {
    // Failed to play from context
    // TODO: Fix metadata here
    playqueue_play(uri, prop_create_root(NULL), 1);
  }
  htsmsg_release(meta);
  return NULL;
}
Exemple #5
0
void
htsmsg_store_save(htsmsg_t *record, const char *key)
{
  loaded_msg_t *lm;

  hts_mutex_lock(&loaded_msg_mutex);

  LIST_FOREACH(lm, &loaded_msgs, lm_link)
    if(!strcmp(lm->lm_key, key))
      break;

  if(lm == NULL) {
    lm = calloc(1, sizeof(loaded_msg_t));
    atomic_set(&lm->lm_refcount, 1);
    lm->lm_key = strdup(key);
    LIST_INSERT_HEAD(&loaded_msgs, lm, lm_link);
  } else {
    htsmsg_release(lm->lm_msg);
  }

  lm->lm_msg = htsmsg_copy(record);

  lm->lm_dirty = 1;
  callout_arm_managed(&lm->lm_timer, htsmsg_store_timer_cb, lm,
                      SETTINGS_CACHE_DELAY, htsmsg_store_lockmgr);

  hts_mutex_unlock(&loaded_msg_mutex);
}
Exemple #6
0
static void
audio_mastervol_init(void)
{
  htsmsg_t *m = htsmsg_store_load("audiomixer");
  int32_t i32;
  prop_t *pa, *mv, *mm;

  pa = prop_create(prop_get_global(), "audio");
  mv = prop_create(pa, "mastervolume");
  mm = prop_create(pa, "mastermute");

  prop_set_float_clipping_range(mv, -75, 12);

  if(m != NULL && !htsmsg_get_s32(m, "master-volume", &i32))
    prop_set_float(mv, (float)i32 / 1000);

  prop_set_int(mm, 0);
  
  htsmsg_release(m);

  prop_subscribe(PROP_SUB_NO_INITIAL_UPDATE,
		 PROP_TAG_CALLBACK_FLOAT, save_matervol, NULL,
		 PROP_TAG_ROOT, mv,
		 NULL);

  prop_subscribe(PROP_SUB_NO_INITIAL_UPDATE,
		 PROP_TAG_SET_INT, &audio_master_mute,
		 PROP_TAG_ROOT, mm,
		 NULL);
}
Exemple #7
0
void
notifications_fini(void)
{
  hts_mutex_lock(&news_mutex);
  htsmsg_store_save(dismissed_news_out, "dismissed_news");
  htsmsg_release(dismissed_news_out);
  dismissed_news_out = NULL;
  hts_mutex_unlock(&news_mutex);
}
Exemple #8
0
void
glw_settings_fini(void)
{
  setting_destroy(glw_settings.gs_setting_screensaver);
  setting_destroy(glw_settings.gs_setting_underscan_v);
  setting_destroy(glw_settings.gs_setting_underscan_h);
  setting_destroy(glw_settings.gs_setting_size);
  setting_destroy(glw_settings.gs_setting_wrap);
  prop_destroy(glw_settings.gs_settings);
  htsmsg_release(glw_settings.gs_settings_store);
}
Exemple #9
0
static void
save_matervol(void *opaque, float value)
{
  audio_master_volume = pow(10, (value / 20));

  htsmsg_t *m = htsmsg_create_map();
  TRACE(TRACE_DEBUG, "audio", "Master volume set to %f dB", value);

  htsmsg_add_s32(m, "master-volume", value * 1000);
  htsmsg_store_save(m, "audiomixer");
  htsmsg_release(m);
}
Exemple #10
0
static void
save_order(prop_reorder_t *pr)
{
  htsmsg_t *out = htsmsg_create_list();
  prop_t *p;

  if(pr->pr_dst->hp_type == PROP_DIR)
    TAILQ_FOREACH(p, &pr->pr_dst->hp_childs, hp_parent_link)
      htsmsg_add_str(out, NULL, get_id(p));

  htsmsg_store_save(out, pr->pr_store);

  if(pr->pr_order)
    htsmsg_release(pr->pr_order);
  pr->pr_order = out;
}
Exemple #11
0
/**
 * TTML docs here: http://www.w3.org/TR/ttaf1-dfxp/
 */
static ext_subtitles_t *
load_ttml(const char *url, buf_t *buf)
{
  char errbuf[256];
  htsmsg_t *subs;
  htsmsg_field_t *f;
  htsmsg_t *xml = htsmsg_xml_deserialize_buf(buf, errbuf, sizeof(errbuf));

  if(xml == NULL) {
    TRACE(TRACE_INFO, "Subtitles", "Unable to load TTML: %s", errbuf);
    return NULL;
  }

  subs = htsmsg_get_map_multi(xml, "tt", "body", "div", NULL);

  if(subs == NULL) {
    htsmsg_release(xml);
    return NULL;
  }

  ext_subtitles_t *es = calloc(1, sizeof(ext_subtitles_t));
  TAILQ_INIT(&es->es_entries);

  HTSMSG_FOREACH(f, subs) {
    if(f->hmf_type == HMF_STR && f->hmf_childs != NULL) {
      htsmsg_t *n = f->hmf_childs;
      const char *str, *txt;
      int64_t start, end;

      txt = f->hmf_str;

      if((str = htsmsg_get_str(n, "begin")) == NULL)
	continue;
      if((start = ttml_time_expression(str)) == -1)
	continue;

      if((str = htsmsg_get_str(n, "end")) == NULL)
	continue;
      if((end = ttml_time_expression(str)) == -1)
	continue;

      es_insert_text(es, txt, start, end, 0);
    }
  }
  return es;
}
Exemple #12
0
int
cfg_load(const char *filename, const char *defconf)
{
  int err;
  static char *lastfilename;

  if(filename == NULL) {
    filename = lastfilename;

  } else {

    free(lastfilename);
    lastfilename = strdup(filename);
  }

  if(filename == NULL)
    filename = defconf;

  trace(LOG_NOTICE, "About to load config form %s", filename);

  char *cfgtxt = readfile(filename, &err, NULL);
  if(cfgtxt == NULL) {
    trace(LOG_ERR, "Unable to read file %s -- %s", filename, strerror(err));
    trace(LOG_ERR, "Config not updated");
    return -1;
  }

  char errbuf[256];
  htsmsg_t *m = htsmsg_json_deserialize(cfgtxt, errbuf, sizeof(errbuf));
  free(cfgtxt);
  if(m == NULL) {
    trace(LOG_ERR, "Unable to parse file %s -- %s", filename, errbuf);
    trace(LOG_ERR, "Config not updated");
    return -1;
  }

  pthread_mutex_lock(&cfg_mutex);
  if(cfgroot != NULL)
    htsmsg_release(cfgroot);

  cfgroot = m;
  htsmsg_retain(m);
  pthread_mutex_unlock(&cfg_mutex);
  trace(LOG_NOTICE, "Config updated");
  return 0;
}
Exemple #13
0
void
usage_fini(void)
{
  if(gconf.device_id[0] == 0)
    return;

  hts_mutex_lock(&usage_mutex);

  int runtime = arch_get_ts() / 1000000LL - usage_time_base;
  htsmsg_s32_inc(usage_counters, "runtime", runtime);

  htsmsg_t *r = make_usage_report();

  hts_mutex_unlock(&usage_mutex);

  htsmsg_store_save(r, "usage");
  htsmsg_release(r);
}
Exemple #14
0
static void
jsg_release(js_setting_group_t *jsg)
{
  if(atomic_dec(&jsg->jsg_refcount))
    return;

  if(jsg->jsg_root_owner)
    if(jsg->jsg_root != NULL)
      prop_destroy(jsg->jsg_root);

  if(jsg->jsg_store != NULL)
    htsmsg_release(jsg->jsg_store);
  
  free(jsg->jsg_spath);
  prop_ref_dec(jsg->jsg_root);
  free(jsg->jsg_kv_url);
  free(jsg);
}
Exemple #15
0
static int
lm_destroy(loaded_msg_t *lm, int dosync)
{
  int x = 0;
  if(lm->lm_dirty) {
    loaded_msg_write(lm);
    if(dosync)
      persistent_store_sync();
    else
      x = 1;
  }
  htsmsg_release(lm->lm_msg);
  lm->lm_msg = NULL;
  LIST_REMOVE(lm, lm_link);
  callout_disarm(&lm->lm_timer);
  loaded_msg_release(lm);
  return x;
}
Exemple #16
0
static ext_subtitles_t *
load_timedtext(const char *url, buf_t *buf)
{
  char errbuf[256];
  htsmsg_field_t *f;
  htsmsg_t *xml = htsmsg_xml_deserialize_buf(buf, errbuf, sizeof(errbuf));

  if(xml == NULL) {
    TRACE(TRACE_INFO, "Subtitles", "Unable to load timed text: %s", errbuf);
    return NULL;
  }

  htsmsg_t *transcript = htsmsg_get_map_multi(xml, "transcript", NULL);

  if(transcript == NULL) {
    htsmsg_release(xml);
    return NULL;
  }

  ext_subtitles_t *es = calloc(1, sizeof(ext_subtitles_t));
  TAILQ_INIT(&es->es_entries);

  HTSMSG_FOREACH(f, transcript) {
    if(f->hmf_type == HMF_STR && f->hmf_childs != NULL) {
      htsmsg_t *n = f->hmf_childs;
      const char *str;
      int64_t start, end;

      if((str = htsmsg_get_str(n, "start")) == NULL)
	continue;
      start = my_str2double(str, NULL) * 1000000.0;

      if((str = htsmsg_get_str(n, "dur")) == NULL)
	continue;
      end = start + my_str2double(str, NULL) * 1000000.0;

      char *txt = strdup(f->hmf_str);
      html_entities_decode(txt);
      es_insert_text(es, txt, start, end, 0);
      free(txt);
    }
  }
  return es;
}
Exemple #17
0
static void *
send_report(void *aux)
{
  htsmsg_t *m = aux;
  htsbuf_queue_t hq;

  htsbuf_queue_init(&hq, 0);

  htsmsg_add_msg(m, "plugins", plugins_get_installed_list());

  htsmsg_json_serialize(m, &hq, 0);

  http_req("https://movian.tv/movian/status/v1/usage",
           HTTP_POSTDATA(&hq, "application/json"),
           NULL);

  htsmsg_release(m);
  return NULL;
}
Exemple #18
0
void
htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f)
{
  TAILQ_REMOVE(&msg->hm_fields, f, hmf_link);

  htsmsg_release(f->hmf_childs);

  switch(f->hmf_type) {
  case HMF_STR:
  case HMF_BIN:
    if(f->hmf_flags & HMF_ALLOCED)
      free(f->hmf_str);
    break;

  default:
    break;
  }
  if(f->hmf_flags & HMF_NAME_ALLOCED)
    free(f->hmf_name);
  rstr_release(f->hmf_namespace);
  free(f);
}
Exemple #19
0
static int
tmdb_configure(void)
{
  hts_mutex_lock(&tmdb_mutex);

  if(!tmdb_configured) {

    buf_t *result;
    char errbuf[256];
    result = fa_load("http://api.themoviedb.org/3/configuration",
                     FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)),
                     FA_LOAD_QUERY_ARG("api_key", TMDB_APIKEY),
                     FA_LOAD_QUERY_ARG("language", getlang()),
                     FA_LOAD_FLAGS(FA_COMPRESSION | FA_IMPORTANT),
                     NULL);

    if(result == NULL) {
      TRACE(TRACE_INFO, "TMDB", "Unable to get configuration -- %s", errbuf);
      goto done;
    }

    htsmsg_t *doc = htsmsg_json_deserialize2(buf_cstr(result),
                                             errbuf, sizeof(errbuf));
    buf_release(result);

    if(doc == NULL) {
      TRACE(TRACE_ERROR, "TMDB", "Got bad JSON from config -- %s", errbuf);
      goto done;
    }
    
    tmdb_parse_config(doc);
    htsmsg_release(doc);
    tmdb_configured = 1;
  }
 done:
  hts_mutex_unlock(&tmdb_mutex);
  return !tmdb_configured;
}
Exemple #20
0
static void
screenshot_process(void *task)
{
  pixmap_t *pm = task;

  if(pm == NULL) {
    screenshot_response(NULL, "Screenshot not supported on this platform");
    return;
  }

  TRACE(TRACE_DEBUG, "Screenshot", "Processing image %d x %d",
        pm->pm_width, pm->pm_height);

  int codecid = AV_CODEC_ID_PNG;
  if(screenshot_connection)
    codecid = AV_CODEC_ID_MJPEG;

  buf_t *b = screenshot_compress(pm, codecid);
  pixmap_release(pm);
  if(b == NULL) {
    screenshot_response(NULL, "Unable to compress image");
    return;
  }

  if(!screenshot_connection) {
    char path[512];
    char errbuf[512];
    snprintf(path, sizeof(path), "%s/screenshot.png",
             gconf.cache_path);
    fa_handle_t *fa = fa_open_ex(path, errbuf, sizeof(errbuf),
                                 FA_WRITE, NULL);
    if(fa == NULL) {
      TRACE(TRACE_ERROR, "SCREENSHOT", "Unable to open %s -- %s",
            path, errbuf);
      buf_release(b);
      return;
    }
    fa_write(fa, buf_data(b), buf_len(b));
    fa_close(fa);
    TRACE(TRACE_INFO, "SCREENSHOT", "Written to %s", path);
    buf_release(b);
    return;
  }

  buf_t *result = NULL;
  htsbuf_queue_t hq;
  htsbuf_queue_init(&hq, 0);

  htsbuf_append(&hq, "image=", 6);
  htsbuf_append_and_escape_url_len(&hq, buf_cstr(b), buf_len(b));

  char errbuf[256];

  int ret = http_req("https://api.imgur.com/3/upload",
                     HTTP_FLAGS(FA_CONTENT_ON_ERROR),
                     HTTP_REQUEST_HEADER("Authorization",
                                         "Client-ID 7c79b311d4797ed"),
                     HTTP_RESULT_PTR(&result),
                     HTTP_POSTDATA(&hq, "application/x-www-form-urlencoded"),
                     HTTP_ERRBUF(errbuf, sizeof(errbuf)),
                     NULL);


  if(ret) {
    screenshot_response(NULL, errbuf);
  } else {

    htsmsg_t *response = htsmsg_json_deserialize(buf_cstr(result));
    if(response == NULL) {
      screenshot_response(NULL, "Unable to parse imgur response");
    } else {

      if(htsmsg_get_u32_or_default(response, "success", 0)) {
        const char *url = htsmsg_get_str_multi(response, "data", "link", NULL);
        screenshot_response(url, "No link in imgur response");
      } else {
        const char *msg = htsmsg_get_str_multi(response, "data", "error", NULL);
        if(msg == NULL) {
          screenshot_response(NULL, "Unkown imgur error");
        } else {
          snprintf(errbuf, sizeof(errbuf), "Imgur error: %s", msg);
          screenshot_response(NULL, errbuf);
        }
      }
      htsmsg_release(response);
    }
    buf_release(result);
  }
  buf_release(b);
}
Exemple #21
0
void
cfg_releasep(cfg_t **p)
{
  if(*p)
    htsmsg_release(*p);
}
Exemple #22
0
void
load_site_news(void)
{
#if ENABLE_WEBPOPUP
  struct http_header_list response_headers;
  buf_t *b;
  char errbuf[512];
  b = fa_load("https://movian.tv/projects/movian/news.json",
              FA_LOAD_FLAGS(FA_DISABLE_AUTH | FA_COMPRESSION),
              FA_LOAD_RESPONSE_HEADERS(&response_headers),
              FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)),
              NULL);
  if(b == NULL) {
    TRACE(TRACE_DEBUG, "News", "Unable to load news -- %s", errbuf);
    return;
  }

  const char *dateheader = http_header_get(&response_headers, "date");
  if(dateheader == NULL) {
    buf_release(b);
    http_headers_free(&response_headers);
    return;
  }
  dateheader = mystrdupa(dateheader);
  http_headers_free(&response_headers);


  htsmsg_t *newsinfo = htsmsg_store_load("sitenews");
  time_t no_news_before;

  if(newsinfo == NULL)
    newsinfo = htsmsg_create_map();

  no_news_before = htsmsg_get_u32_or_default(newsinfo, "nothingbefore", 0);

  if(no_news_before == 0) {
    if(http_ctime(&no_news_before, dateheader)) {
      buf_release(b);
      htsmsg_release(newsinfo);
      return;
    }

    htsmsg_add_u32(newsinfo, "nothingbefore", no_news_before);
    htsmsg_store_save(newsinfo, "sitenews");
    htsmsg_release(newsinfo);
  }

  htsmsg_t *doc = htsmsg_json_deserialize(buf_cstr(b));
  buf_release(b);
  if(doc == NULL) {
    return;
  }

  hts_mutex_lock(&news_mutex);

  htsmsg_t *news = htsmsg_get_list(doc, "news");
  if(news != NULL) {
    htsmsg_field_t *f;
    HTSMSG_FOREACH(f, news) {
      htsmsg_t *entry;
      if((entry = htsmsg_get_map_by_field(f)) == NULL)
        continue;

      const char *title = htsmsg_get_str(entry, "title");
      const char *created_on = htsmsg_get_str(entry, "created_on");
      int id = htsmsg_get_u32_or_default(entry, "id", 0);
      if(created_on == NULL || title == NULL || id == 0)
        continue;

      time_t t;

      if(parse_created_on_time(&t, created_on))
        continue;

      if(t < no_news_before)
        continue;

      char idstr[64];
      snprintf(idstr, sizeof(idstr), "sitenews:%d", id);
      prop_t *p = add_news_locked(idstr, title, NULL, "Read more", idstr);
      if(p != NULL) {
        prop_subscribe(PROP_SUB_TRACK_DESTROY,
                       PROP_TAG_CALLBACK, open_news, p,
                       PROP_TAG_ROOT, prop_create(p, "eventSink"),
                       PROP_TAG_MUTEX, &news_mutex,
                       NULL);
      }
    }