Пример #1
0
rstr_t *
backend_prop_make(prop_t *model, const char *suggest)
{
  proppage_t *pp;
  rstr_t *r;
  hts_mutex_lock(&pp_mutex);

  pp = calloc(1, sizeof(proppage_t));

  if(suggest == NULL) {
    char url[50];
    pp_tally++;
    snprintf(url, sizeof(url), "prop:%d", pp_tally);
    r = rstr_alloc(url);
  } else {
    r = rstr_alloc(suggest);
  }
  pp->pp_url = rstr_dup(r);

  pp->pp_model = prop_ref_inc(model);

  pp->pp_model_sub = 
    prop_subscribe(PROP_SUB_TRACK_DESTROY,
		   PROP_TAG_CALLBACK, pp_cb, pp,
		   PROP_TAG_MUTEX, &pp_mutex,
		   PROP_TAG_ROOT, model,
		   NULL);

  LIST_INSERT_HEAD(&proppages, pp, pp_link);
  hts_mutex_unlock(&pp_mutex);
  return r;
}
Пример #2
0
static int
sidfile_scandir(fa_dir_t *fd, const char *url, char *errbuf, size_t errlen)
{
  void *fh = NULL;
  char *p, *fpath = mystrdupa(url);
  char buf[128];
  char name[32];
  char turl[URL_MAX];
  int tracks, i;
  fa_dir_entry_t *fde;
  rstr_t *album, *artist;
 

  if((p = strrchr(fpath, '/')) == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return -1;
  }

  *p = 0;
  if((fh = fa_open(fpath, errbuf, errlen)) == NULL)
    return -1;

  if(fa_read(fh, buf, 128) != 128) {
    snprintf(errbuf, errlen, "Unable to read file");
    fa_close(fh);
    return -1;
  }

  album = rstr_alloc(utf8_from_bytes((char *)buf + 0x16, 32, NULL));
  artist = rstr_alloc(utf8_from_bytes((char *)buf + 0x36, 32, NULL));

  tracks = buf[0xf];
  for(i = 0; i < tracks; i++) {

    snprintf(name, sizeof(name), "Track %02d", i + 1);
    snprintf(turl, sizeof(turl), "sidplayer:%s/%d", fpath, i + 1);
    fde = fa_dir_add(fd, turl, name, CONTENT_AUDIO);

    fde->fde_probestatus = FDE_PROBE_DEEP;

    fde->fde_metadata = prop_create_root("metadata");
    prop_set_string(prop_create(fde->fde_metadata, "title"), name);
    prop_set_rstring(prop_create(fde->fde_metadata, "album"), album);
    prop_set_rstring(prop_create(fde->fde_metadata, "artist"), artist);
  }

  rstr_release(album);
  rstr_release(artist);

  fa_close(fh);
  return 0;
}
Пример #3
0
static nls_string_t *
nls_string_find(const char *key)
{
  nls_string_t *ns;

  unsigned int hash = mystrhash(key) % NLS_STRING_HASH_WIDTH;

  hts_mutex_lock(&nls_mutex);

  LIST_FOREACH(ns, &nls_strings[hash], ns_link)
    if(!strcmp(rstr_get(ns->ns_key), key))
      break;

  if(ns == NULL) {
    ns = calloc(1, sizeof(nls_string_t));
    ns->ns_key = rstr_alloc(key);
    ns->ns_prop = prop_create_root(NULL);
    prop_set_rstring(ns->ns_prop, ns->ns_key);

  } else {
    LIST_REMOVE(ns, ns_link);
  }
  LIST_INSERT_HEAD(&nls_strings[hash], ns, ns_link);

  hts_mutex_unlock(&nls_mutex);
  return ns;
}
Пример #4
0
static void
video_query(bmdb_t *b, void *db)
{
    sqlite3_stmt *stmt;

    int rc = db_prepare(db, &stmt,
                        "SELECT i.url, p.url, i.contenttype "
                        "FROM item AS i, item AS p "
                        "WHERE i.url LIKE ?1 "
                        "AND (i.contenttype == 5 OR i.contenttype == 7) "
                        "AND i.parent = p.id"
                       );

    if(rc != SQLITE_OK)
        return;

    char q[PATH_MAX];
    db_escape_path_query(q, sizeof(q), b->b_query);
    sqlite3_bind_text(stmt, 1, q, -1, SQLITE_STATIC);

    while((rc = db_step(stmt)) == SQLITE_ROW) {
        const char *url = (const char *)sqlite3_column_text(stmt, 0);
        const char *parent = (const char *)sqlite3_column_text(stmt, 1);
        rstr_t *ct = rstr_alloc(content2type(sqlite3_column_int(stmt, 2)));
        add_item(b, url, parent, ct, NULL, 0, NULL, 0);
        rstr_release(ct);
    }
    sqlite3_finalize(stmt);
}
Пример #5
0
static void
set_source(glw_t *w, rstr_t *filename)
{
  glw_image_t *gi = (glw_image_t *)w;
  
  const rstr_t *curname;

  if(gi->gi_pending_url != NULL)
    curname = gi->gi_pending_url;
  else if(gi->gi_pending != NULL) 
    curname = gi->gi_pending->glt_url;
  else if(gi->gi_current != NULL) 
    curname = gi->gi_current->glt_url;
  else 
    curname = NULL;
  
  if(curname != NULL && filename != NULL && !strcmp(rstr_get(filename),
						    rstr_get(curname)))
    return;
  
  if(gi->gi_pending_url != NULL)
    rstr_release(gi->gi_pending_url);
  
  gi->gi_pending_url = filename ? rstr_dup(filename) : rstr_alloc("");
}
Пример #6
0
void
metadata_filename_to_title(const char *filename, int *yearp, rstr_t **titlep)
{
  int year = 0;

  char *s = mystrdupa(filename);

  url_deescape(s);

  int i = strlen(s);

  while(i > 0) {
    
    if(i > 5 && s[i-5] == '.' &&
       isnum(s[i-4]) && isnum(s[i-3]) && isnum(s[i-2]) && isnum(s[i-1])) {
      year = atoi(s + i - 4);
      i -= 5;
      s[i] = 0;
      continue;
    }

    if(i > 7 && s[i-7] == ' ' && s[i-6] == '(' && 
       isnum(s[i-5]) && isnum(s[i-4]) && isnum(s[i-3]) && isnum(s[i-2]) &&
       s[i-1] == ')') {
      year = atoi(s + i - 5);
      i -= 7;
      s[i] = 0;
      continue;
    }

    int j;
    for(j = 0; stopstrings[j] != NULL; j++) {
      int len = strlen(stopstrings[j]);
      if(i > len+1 && (s[i-len-1] == '.' || s[i-len-1] == ' ') &&
	 !strncasecmp(s+i-len, stopstrings[j], len) &&
	 (s[i] == '.' || s[i] == ' ' || s[i] == '-' || s[i] == 0)) {
	i -= len+1;
	s[i] = 0;
	break;
      }
    }
    
    if(stopstrings[j] != NULL)
      continue;

    i--;
  }

  for(i = 0; s[i]; i++) {
    if(s[i] == '.') {
      s[i] = ' ';
    }
  }
 
  if(yearp != NULL)
    *yearp = year;

  if(titlep != NULL)
    *titlep = rstr_alloc(s);
}
Пример #7
0
static void
artists_query(bmdb_t *b, void *db)
{
    sqlite3_stmt *stmt;

    int rc = db_prepare(db, &stmt,
                        "SELECT artist.id, artist.title "
                        "FROM artist,item,audioitem "
                        "WHERE audioitem.item_id = item.id "
                        "AND audioitem.artist_id = artist.id "
                        "AND item.url like ?1 "
                        "AND audioitem.ds_id = 1 "
                        "GROUP by artist_id");

    if(rc != SQLITE_OK)
        return;

    char q[PATH_MAX];
    db_escape_path_query(q, sizeof(q), b->b_query);
    sqlite3_bind_text(stmt, 1, q, -1, SQLITE_STATIC);

    rstr_t *ct = rstr_alloc("artist");

    while((rc = db_step(stmt)) == SQLITE_ROW) {
        char url[PATH_MAX];
        snprintf(url, sizeof(url), "library:artist:%d",
                 sqlite3_column_int(stmt, 0));
        add_item(b, url, NULL, ct,
                 (const char *)sqlite3_column_text(stmt, 1), 0, NULL, 0);
    }
    rstr_release(ct);
    sqlite3_finalize(stmt);
}
Пример #8
0
static int
is_plugin_blacklisted(const char *id, const char *version, rstr_t **reason)
{
  char tmp[512];
  int verint = parse_version_int(version);
  if(!strcmp(id, "custombg")) {
    if(reason != NULL) {
      *reason =
        _("Custom backgrounds can now be set in Settings -> Look and Feel");
    }
    return 1;
  }

  for(int i = 0; i < ARRAYSIZE(blacklist); i++) {
    if(strcmp(id, blacklist[i].id))
      continue;

    if(verint >= blacklist[i].version)
      continue;

    if(reason != NULL) {
      rstr_t *f = _("Version %s is no longer compatible with Movian");
      snprintf(tmp, sizeof(tmp), rstr_get(f), version);
      rstr_release(f);
      *reason = rstr_alloc(tmp);
    }
    return 1;
  }
  return 0;
}
Пример #9
0
static void
set_torrent_cache_path(void *opaque, const char *str)
{
  rstr_release(btg.btg_cache_path);
  btg.btg_cache_path = rstr_alloc(str);
  if(allow_update)
    torrent_diskio_scan(0);
}
Пример #10
0
static rstr_t *
title_from_url(const char *url)
{
  char tmp[1024];
  fa_url_get_last_component(tmp, sizeof(tmp), url);
  rstr_t *r = rstr_alloc(tmp);
  return r;
}
Пример #11
0
rstr_t *
htsmsg_store_get_str(const char *store, const char *key)
{
  hts_mutex_lock(&loaded_msg_mutex);
  loaded_msg_t *lm = htsmsg_store_obtain(store, 1);
  rstr_t *r = rstr_alloc(htsmsg_get_str(lm->lm_msg, key));
  hts_mutex_unlock(&loaded_msg_mutex);
  return r;
}
Пример #12
0
static int
set_rstring(glw_view_eval_context_t *ec, const token_attrib_t *a,
            struct token *t)
{
  rstr_t *rstr;
  char buf[30];
  void (*fn)(struct glw *w, rstr_t *str) = a->fn;

  switch(t->type) {
  case TOKEN_VOID:
    buf[0] = 0;
    break;

  case TOKEN_CSTRING:
    rstr = rstr_alloc(t->t_cstring);
    fn(ec->w, rstr);
    rstr_release(rstr);
    return 0;

  case TOKEN_RSTRING:
  case TOKEN_LINK:
    fn(ec->w, t->t_rstring);
    return 0;

  case TOKEN_INT:
    snprintf(buf, sizeof(buf), "%d", t->t_int);
    break;

  case TOKEN_FLOAT:
    snprintf(buf, sizeof(buf), "%f", t->t_float);
    break;

  default:
    return glw_view_seterr(ec->ei, t, 
			   "Attribute '%s' expects a string or scalar, got %s",
			   a->name, token2name(t));
  }

  rstr = rstr_alloc(buf);
  fn(ec->w, rstr);
  rstr_release(rstr);
  return 0;
}
Пример #13
0
static void
artist_query(bmdb_t *b, void *db)
{
    sqlite3_stmt *stmt;
    int rc;
    int artist_id = atoi(b->b_query);

    rc = db_prepare(db, &stmt,
                    "SELECT title "
                    "FROM artist "
                    "WHERE ds_id = 1 "
                    "AND id = ?1");

    if(rc != SQLITE_OK)
        return;

    sqlite3_bind_int(stmt, 1, artist_id);

    if(db_step(stmt) == SQLITE_ROW) {
        rstr_t *artist = db_rstr(stmt, 0);
        prop_set(b->b_metadata, "title",       PROP_SET_RSTRING, artist);

        prop_t *p = prop_create_r(b->b_metadata, "artist_images");
        metadata_bind_artistpics(p, artist);
        prop_ref_dec(p);

        rstr_release(artist);
    }

    sqlite3_finalize(stmt);

    rc = db_prepare(db, &stmt,
                    "SELECT id,title "
                    "FROM album "
                    "WHERE ds_id = 1 "
                    "AND artist_id = ?1");

    if(rc != SQLITE_OK)
        return;

    sqlite3_bind_int(stmt, 1, artist_id);

    rstr_t *ct = rstr_alloc("album");

    while((rc = db_step(stmt)) == SQLITE_ROW) {
        char url[PATH_MAX];
        snprintf(url, sizeof(url), "library:album:%d",
                 sqlite3_column_int(stmt, 0));

        add_item(b, url, NULL, ct,
                 (const char *)sqlite3_column_text(stmt, 1), 0, NULL, 0);
    }
    rstr_release(ct);
    sqlite3_finalize(stmt);
}
Пример #14
0
rstr_t *
js_prop_rstr(JSContext *cx, JSObject *o, const char *prop)
{
  jsval val;
  if(!JS_GetProperty(cx, o, prop, &val))
    return NULL;
  if(!JSVAL_IS_STRING(val))
    return NULL;
  JSString *s = JS_ValueToString(cx, val);
  return s ? rstr_alloc(JS_GetStringBytes(s)) : NULL;
}
Пример #15
0
/**
 * Probe SPC files
 */
static void
fa_probe_spc(metadata_t *md, uint8_t *pb)
{
  char buf[33];
  buf[32] = 0;

  if(memcmp("v0.30", pb + 0x1c, 4))
    return;

  if(pb[0x23] != 0x1a)
    return;

  memcpy(buf, pb + 0x2e, 32);
  md->md_title = rstr_alloc(buf);

  memcpy(buf, pb + 0x4e, 32);
  md->md_album = rstr_alloc(buf);

  memcpy(buf, pb + 0xa9, 3);
  buf[3] = 0;

  md->md_duration = atoi(buf);
}
Пример #16
0
static int
hc_image(http_connection_t *hc, const char *remain, void *opaque,
         http_cmd_t method)
{
    htsbuf_queue_t out;
    pixmap_t *pm;
    char errbuf[200];
    const char *content;
    image_meta_t im = {0};
    im.im_no_decoding = 1;

    rstr_t *url = rstr_alloc(remain);

    pm = backend_imageloader(url, &im, NULL, errbuf, sizeof(errbuf), NULL,
                             NULL, NULL);
    rstr_release(url);
    if(pm == NULL)
        return http_error(hc, 404, "Unable to load image %s : %s",
                          remain, errbuf);

    if(!pixmap_is_coded(pm)) {
        pixmap_release(pm);
        return http_error(hc, 404,
                          "Unable to load image %s : Original data not available",
                          remain);
    }

    htsbuf_queue_init(&out, 0);
    htsbuf_append(&out, pm->pm_data, pm->pm_size);

    switch(pm->pm_type) {
    case PIXMAP_JPEG:
        content = "image/jpeg";
        break;
    case PIXMAP_PNG:
        content = "image/png";
        break;
    case PIXMAP_GIF:
        content = "image/gif";
        break;
    default:
        content = "image";
        break;
    }

    pixmap_release(pm);

    return http_send_reply(hc, 0, content, NULL, NULL, 0, &out);
}
Пример #17
0
static void
ns_val_set(nls_string_t *ns, int idx, const char *value)
{
  if(ns->ns_values == 0 && idx == 0) {
    ns->ns_values = 1;
    ns->ns_u.rstr = rstr_alloc(value);
    return;
  }
  if(ns->ns_values == 1 && idx == 0) {
    rstr_release(ns->ns_u.rstr);
    ns->ns_u.rstr = rstr_alloc(value);
    return;
  }

  if(idx < ns->ns_values) {
    assert(ns->ns_values > 1);
    rstr_release(ns->ns_u.vec[idx]);
    ns->ns_u.vec[idx] = rstr_alloc(value);
    return;
  }


  rstr_t *p = NULL;
  if(ns->ns_values == 1) {
    p = ns->ns_u.rstr;
    ns->ns_values = 0;
    assert(idx > 0);
  }
  ns->ns_u.vec = realloc(ns->ns_values ? ns->ns_u.vec : NULL,
			 (1+idx) * sizeof(rstr_t *));
  if(p)
    ns->ns_u.vec[0] = p;

  ns->ns_u.vec[idx] = rstr_alloc(value);
  ns->ns_values = idx + 1;
}
Пример #18
0
static JSBool 
js_notify(JSContext *cx, JSObject *obj,
		uintN argc, jsval *argv, jsval *rval)
{
  const char *text;
  int delay;
  const char *icon = NULL;

  if(!JS_ConvertArguments(cx, argc, argv, "si/s", &text, &delay, &icon))
    return JS_FALSE;

  notify_add(NULL, NOTIFY_INFO, icon, delay, rstr_alloc("%s"), text);

  return JS_TRUE;
}
Пример #19
0
int
metadata_filename_to_episode(const char *s,
			     int *seasonp, int *episodep,
			     rstr_t **titlep)
{
  int i, j;
  int len = strlen(s);
  int season = -1;
  int episode = -1;
  for(i = 0; i < len; i++) {
    if((s[i] == 's' || s[i] == 'S') && isnum(s[i+1]) && isnum(s[i+2])) {
      int o = 3+i;
      if(s[o] == '.')
	o++;
  
      if((s[o] == 'e' || s[o] == 'E') && isnum(s[o+1]) && isnum(s[o+2])) {
	season = atoi(s+i+1);
	episode = atoi(s+o+1);
	break;
      }
    }
  }
  

  if(season == -1 || episode == -1)
    return -1;

  *seasonp = season;
  *episodep = episode;

  char *t = mystrdupa(s);
  url_deescape(t);

  for(j= 0; j < i; j++) {
    if(t[j] == '.') {
      t[j] = ' ';
    }
  }
  t[j] = 0;

  if(titlep != NULL) {
    if(j)
      *titlep = rstr_alloc(t);
    else
      *titlep = NULL;
  }
  return 0;
}
Пример #20
0
void
glw_load_universe(glw_root_t *gr)
{
  prop_t *page = prop_create(gr->gr_prop_ui, "root");
  glw_unload_universe(gr);

  rstr_t *universe = rstr_alloc("skin://universe.view");

  gr->gr_universe = glw_view_create(gr,
				    universe, NULL, page,
				    NULL, NULL, NULL, 0, 1);

  rstr_release(universe);

  glw_signal_handler_register(gr->gr_universe, top_event_handler, gr, 1000);
}
Пример #21
0
static int
xmp_probe(metadata_t *md, const char *url, fa_handle_t *fh)
{
  struct xmp_test_info info;
  FILE *f = fa_fopen(fh, 0);
  if(f == NULL)
    return 0;

  int r = xmp_test_modulef(f, &info);
  fclose(f);
  if(r < 0)
    return 0;

  md->md_title  = rstr_alloc(info.name);
  md->md_contenttype = CONTENT_AUDIO;
  return 1;
}
Пример #22
0
/**
 * Check if file is an iso image
 * pb is guaranteed to point at 128 byts
 * of data starting 0x8000 of start of file
 */
static int
fa_probe_iso0(metadata_t *md, uint8_t *pb)
{
  uint8_t *p;

  if(memcmp(pb, isosig, 8))
    return -1;

  p = &pb[40];
  while(*p > 32 && p != &pb[72])
    p++;

  *p = 0;

  if(md != NULL) {
    md->md_title = rstr_alloc((const char *)pb + 40);
    md->md_contenttype = CONTENT_DVD;
  }
  return 0;
}
Пример #23
0
static void
handle_method_call(GDBusConnection *connection, const gchar *sender,
		   const gchar *object_path, const gchar *interface_name,
		   const gchar *method_name, GVariant *param,
		   GDBusMethodInvocation *inv, gpointer user_data)
{
  TRACE(TRACE_DEBUG, "CONNMAN", "agent method call: %s", method_name);

  if(!strcmp(method_name, "ReportError")) {
    connman_service_t *cs = connman_service_from_params(param);

    const char *msg =
      g_variant_get_string(g_variant_get_child_value(param, 1), NULL);

    notify_add(NULL, NOTIFY_ERROR, NULL, 3,
	       rstr_alloc("%s\n%s"), cs ? cs->cs_name : "Unknown network", msg);
    g_dbus_method_invocation_return_value(inv, NULL);

  } else if(!strcmp(method_name, "RequestInput")) {
    connman_service_t *cs = connman_service_from_params(param);

    if(cs == NULL) {
      g_dbus_method_invocation_return_error_literal(inv,
						    G_DBUS_ERROR,
						    G_DBUS_ERROR_INVALID_ARGS,
						    "Unknown service");
      return;
    }

    agent_request_input(cs, g_variant_get_child_value(param, 1), inv);

  } else {
    g_dbus_method_invocation_return_error(inv,
					  G_DBUS_ERROR,
					  G_DBUS_ERROR_INVALID_ARGS,
					  "Unknown method %s",
					  method_name);
    return;
  }
}
Пример #24
0
static nls_string_t *
nls_string_find(const char *key)
{
  nls_string_t *ns;

  LIST_FOREACH(ns, &nls_strings, ns_link)
    if(!strcmp(rstr_get(ns->ns_key), key))
      break;

  if(ns == NULL) {

    ns = calloc(1, sizeof(nls_string_t));
    ns->ns_key = rstr_alloc(key);
    ns->ns_prop = prop_create_root(NULL);
    prop_set_rstring(ns->ns_prop, ns->ns_key);

  } else {
    LIST_REMOVE(ns, ns_link);
  }
  LIST_INSERT_HEAD(&nls_strings, ns, ns_link);
  return ns;
}
Пример #25
0
/**
 * Obtain details from playlist
 */
static void
fa_probe_playlist(metadata_t *md, const char *url, uint8_t *pb, size_t pbsize)
{
  const char *t;
  char tmp1[300];
  int i;

  t = strrchr(url, '/');
  t = t ? t + 1 : url;

  i = 0;
  while(*t && *t != '.')
    tmp1[i++] = *t++;
  tmp1[i] = 0;
  
  md->md_title = rstr_alloc(tmp1);
  
  t = strstr((char *)pb, "NumberOfEntries=");
  
  if(t != NULL)
    md->md_tracks = atoi(t + 16);
}
Пример #26
0
/**
 * Load a file using the 'glw_rawloader' method
 *
 * Returns pointer to last token, or NULL if an error occured.
 * If an error occured 'ei' will be filled with data
 *
 */
token_t *
glw_view_load1(glw_root_t *gr, const char *filename, 
		errorinfo_t *ei, token_t *prev)
{
  char *src;
  rstr_t *f;
  token_t *last;
  char errbuf[256];

  if((src = fa_quickload(filename, NULL, gr->gr_vpaths, 
			 errbuf, sizeof(errbuf))) == NULL) {
    snprintf(ei->error, sizeof(ei->error), "Unable to open \"%s\" -- %s",
	     filename, errbuf);
    snprintf(ei->file,  sizeof(ei->file),  "%s", rstr_get(prev->file));
    ei->line = prev->line;
    return NULL;
  }

  f = rstr_alloc(filename);
  last = lexer(src, ei, f, prev);
  rstr_release(f);
  free(src);
  return last;
}
Пример #27
0
static JSBool 
js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent,
	       const char *url, const char *type, JSObject *metaobj,
	       jsval *data, jsval *rval, int enabled,
	       const char *metabind)
{
  install_nodesub(model);

  prop_t *item = prop_create_root(NULL);

  rstr_t *rurl = url ? rstr_alloc(url) : NULL;

  if(url != NULL)
    prop_set(item, "url", PROP_SET_RSTRING, rurl);

  if(data != NULL)
    js_prop_set_from_jsval(cx, prop_create(item, "data"), *data);

  *rval = JSVAL_VOID;

  if(metabind != NULL)
    playinfo_bind_url_to_prop(metabind, item);

  if(type != NULL) {
    prop_set_string(prop_create(item, "type"), type);

    if(metaobj)
      js_prop_from_object(cx, metaobj, prop_create(item, "metadata"));

  } else if(url != NULL) {

    if(backend_resolve_item(url, item)) {
      prop_destroy(item);
      rstr_release(rurl);
      return JS_TRUE;
    }
  }

  prop_set_int(prop_create(item, "enabled"), enabled);

  prop_t *p = prop_ref_inc(item);

  if(prop_set_parent(item, parent)) {
    prop_destroy(item);
    prop_ref_dec(p);
  } else {
    JSObject *robj =
      JS_NewObjectWithGivenProto(cx, &item_class,
				 JSVAL_TO_OBJECT(model->jm_item_proto), NULL);

    *rval =  OBJECT_TO_JSVAL(robj);
    js_item_t *ji = calloc(1, sizeof(js_item_t));
    atomic_add(&model->jm_refcount, 1);
    ji->ji_url = rstr_dup(rurl);
    ji->ji_model = model;
    ji->ji_root =  p;
    TAILQ_INSERT_TAIL(&model->jm_items, ji, ji_link);
    JS_SetPrivate(cx, robj, ji);
    ji->ji_enable_set_property = 1; 

    ji->ji_eventsub = 
      prop_subscribe(PROP_SUB_TRACK_DESTROY,
		     PROP_TAG_CALLBACK, js_item_eventsub, ji,
		     PROP_TAG_ROOT, ji->ji_root,
		     PROP_TAG_COURIER, model->jm_pc,
		     NULL);
    model->jm_subs++;
    ji->ji_this = OBJECT_TO_JSVAL(robj);
    JS_AddNamedRoot(cx, &ji->ji_this, "item_this");
    prop_tag_set(ji->ji_root, model, ji);
  }
  rstr_release(rurl);
  return JS_TRUE;
}
Пример #28
0
static int
hc_image(http_connection_t *hc, const char *remain, void *opaque,
	http_cmd_t method)
{
  htsbuf_queue_t out;
  image_t *img;
  char errbuf[200];
  const char *content;
  image_meta_t im = {0};
  im.im_no_decoding = 1;
  rstr_t *url;
  const char *u = http_arg_get_req(hc, "url");
  
  if(u != NULL) {
    url = rstr_alloc(u);
    url_deescape(rstr_data(url));
  } else {
    if(remain == NULL) {
      return 404;
    }
    url = rstr_alloc(remain);
  }

  img = backend_imageloader(url, &im, NULL, errbuf, sizeof(errbuf), NULL,
                            NULL);
  rstr_release(url);
  if(img == NULL)
    return http_error(hc, 404, "Unable to load image %s : %s",
		      remain, errbuf);

  const image_component_t *ic = image_find_component(img, IMAGE_CODED);
  if(ic == NULL) {
    image_release(img);
    return http_error(hc, 404,
		      "Unable to load image %s : Original data not available",
		      remain);
  }
  const image_component_coded_t *icc = &ic->coded;

  htsbuf_queue_init(&out, 0);
  htsbuf_append(&out, buf_cstr(icc->icc_buf), buf_len(icc->icc_buf));

  switch(icc->icc_type) {
  case IMAGE_JPEG:
    content = "image/jpeg";
    break;
  case IMAGE_PNG:
    content = "image/png";
    break;
  case IMAGE_GIF:
    content = "image/gif";
    break;
  default:
    content = "image";
    break;
  }

  image_release(img);

  return http_send_reply(hc, 0, content, NULL, NULL, 0, &out);
}
Пример #29
0
static void
album_query(bmdb_t *b, void *db)
{
    sqlite3_stmt *stmt;
    int rc;
    int album_id = atoi(b->b_query);

    rc = db_prepare(db, &stmt,
                    "SELECT album.title, artist.title "
                    "FROM album, artist "
                    "WHERE album.id = ?1 "
                    "AND artist.id = album.artist_id "
                    "AND album.ds_id = 1");

    if(rc != SQLITE_OK)
        return;

    sqlite3_bind_int(stmt, 1, album_id);

    if(db_step(stmt) == SQLITE_ROW) {
        rstr_t *album  = db_rstr(stmt, 0);
        rstr_t *artist = db_rstr(stmt, 1);

        prop_set(b->b_metadata, "title",       PROP_SET_RSTRING, album);
        prop_set(b->b_metadata, "artist_name", PROP_SET_RSTRING, artist);

        prop_t *p = prop_create_r(b->b_metadata, "album_art");
        metadata_bind_albumart(p, artist, album);
        prop_ref_dec(p);

        rstr_release(album);
        rstr_release(artist);
    }

    sqlite3_finalize(stmt);

    rc = db_prepare(db, &stmt,
                    "SELECT url, audioitem.title, track, duration, "
                    "artist.title "
                    "FROM audioitem,item,artist "
                    "WHERE audioitem.item_id = item.id "
                    "AND audioitem.artist_id = artist.id "
                    "AND album_id = ?1 "
                    "AND audioitem.ds_id = 1");

    if(rc != SQLITE_OK)
        return;

    sqlite3_bind_int(stmt, 1, album_id);

    rstr_t *ct = rstr_alloc("audio");

    while((rc = db_step(stmt)) == SQLITE_ROW) {
        add_item(b, (const char *)sqlite3_column_text(stmt, 0),
                 NULL, ct,
                 (const char *)sqlite3_column_text(stmt, 1),
                 sqlite3_column_int(stmt, 2),
                 (const char *)sqlite3_column_text(stmt, 4),
                 sqlite3_column_int(stmt, 3));

    }
    rstr_release(ct);
    sqlite3_finalize(stmt);
}
Пример #30
0
static int
parse_app1(jpeginfo_t *ji, const uint8_t *buf, size_t len, int flags)
{
  int bigendian;
  int ifdbase;
  int ifd = 0;


  int thumbnail_jpeg_offset = -1;
  int thumbnail_jpeg_size   = -1;

#define EXIF8(off) buf[off]

#define EXIF16(off) (bigendian ? \
 ((buf[off] << 8) | buf[off + 1]) : (buf[off + 1] << 8 | buf[off]))

#define EXIF32(off) (bigendian ? \
((buf[off  ] << 24) | (buf[off+1] << 16) | (buf[off+2] << 8) | (buf[off+3])):\
((buf[off+3] << 24) | (buf[off+2] << 16) | (buf[off+1] << 8) | (buf[off  ])))

#define IFDTAG(ifd, tag) (((ifd) << 16) | tag)

  // Exif Header
  if(len < 6 || memcmp(exifheader, buf, 6))
    return 0; // Don't fail here, just skip

  buf += 6;
  len -= 6;

  // TIFF header
  if(len < 8)
    return -1;

  if(buf[0] == 'M' && buf[1] == 'M')
    bigendian = 1;
  else if(buf[0] == 'I' && buf[1] == 'I')
    bigendian = 0;
  else
    return -1;

  //  printf(" EXIF/TIFF %s endian\n", bigendian ? "Big" : "Little");

  if(EXIF16(2) != 0x2a)
    return -1;

  ifdbase = EXIF32(4);

  while(ifdbase) {
    //    printf("  IDF Offset = %d\n", ifdbase);

    if(len < ifdbase + 2)
      return -1;

    int i, entries = EXIF16(ifdbase);
    //    printf("  %d entries\n", entries);

    if(len < ifdbase + 2 + entries * 12 + 4)
      return -1;

    for(i = 0; i < entries; i++) {
      uint16_t tag     = EXIF16(ifdbase + 2 + i * 12 + 0);
      uint16_t type    = EXIF16(ifdbase + 2 + i * 12 + 2);
      //      uint32_t c       = EXIF32(ifdbase + 2 + i * 12 + 4);

      int po = ifdbase + 2 + i * 12 + 8;
      int value = 0;
      const char *str = NULL;
      switch(type) {
      case 1:
	value = (uint8_t)  EXIF8(po);
	break;
      case 2:
	value = (uint32_t) EXIF32(po);
	str = (const char *)buf + value;
	break;
      case 3:
	value = (uint16_t) EXIF16(po);
	break;
      case 4:
	value = (uint32_t) EXIF32(po);
	break;
      case 6:
	value = (int8_t)   EXIF8(po);
	break;
      case 8:
	value = (int16_t)  EXIF8(po);
	break;
      }
      
      //      printf("  IFD%d  %04x (%d)  ==  %d\n",  ifd, tag, type, value);
      
      switch(IFDTAG(ifd, tag)) {
      case IFDTAG(1, 0x201):  // JPEG Thumbnail offset
	thumbnail_jpeg_offset = value;
	break;
      case IFDTAG(1, 0x202):  // JPEG Thumbnail size
	thumbnail_jpeg_size = value;
	break;
      case IFDTAG(0, 0x112):  // Orientation
	ji->ji_orientation = value;
	break;
      case IFDTAG(0, 0x132):  // Datetime
	ji->ji_time = jpeg_time(str);
	break;
      case IFDTAG(0, 0x10f):  // Manufacturer
	rstr_release(ji->ji_manufacturer);
	ji->ji_manufacturer = rstr_alloc(str);
	break;
      case IFDTAG(0, 0x110):  // Equipment
	rstr_release(ji->ji_equipment);
	ji->ji_equipment = rstr_alloc(str);
	break;

      default:
	break;
      }
    }

    ifd++;
    ifdbase = EXIF32(ifdbase + 2 + entries * 12);
  }

  if(flags & JPEG_INFO_THUMBNAIL && 
     thumbnail_jpeg_offset != -1 && thumbnail_jpeg_size != -1 &&
     thumbnail_jpeg_offset + thumbnail_jpeg_size <= len) {

    //    printf("  Thumbnail @ %d, %d bytes\n", thumbnail_jpeg_offset, thumbnail_jpeg_size);
    ji->ji_thumbnail = pixmap_alloc_coded(buf + thumbnail_jpeg_offset,
					  thumbnail_jpeg_size,
					  PIXMAP_JPEG);
    ji->ji_thumbnail->pm_flags |= PIXMAP_THUMBNAIL;
    ji->ji_thumbnail->pm_orientation = ji->ji_orientation;
  }
  return 0;
}