示例#1
0
static void
rsp_reply_browse(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
{
  struct query_params qp;
  char *browse_item;
  mxml_node_t *reply;
  mxml_node_t *status;
  mxml_node_t *items;
  mxml_node_t *node;
  int records;
  int ret;

  memset(&qp, 0, sizeof(struct query_params));

  if (strcmp(uri[3], "artist") == 0)
    qp.type = Q_BROWSE_ARTISTS;
  else if (strcmp(uri[3], "genre") == 0)
    qp.type = Q_BROWSE_GENRES;
  else if (strcmp(uri[3], "album") == 0)
    qp.type = Q_BROWSE_ALBUMS;
  else if (strcmp(uri[3], "composer") == 0)
    qp.type = Q_BROWSE_COMPOSERS;
  else
    {
      DPRINTF(E_LOG, L_RSP, "Unsupported browse type '%s'\n", uri[3]);

      rsp_send_error(req, "Unsupported browse type");
      return;
    }

  ret = safe_atoi32(uri[2], &qp.id);
  if (ret < 0)
    {
      rsp_send_error(req, "Invalid playlist ID");
      return;
    }

  ret = get_query_params(req, query, &qp);
  if (ret < 0)
    return;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_RSP, "Could not start query\n");

      rsp_send_error(req, "Could not start query");

      if (qp.filter)
	free(qp.filter);
      return;
    }

  if (qp.offset > qp.results)
    records = 0;
  else if (qp.limit > (qp.results - qp.offset))
    records = qp.results - qp.offset;
  else
    records = qp.limit;

  /* We'd use mxmlNewXML(), but then we can't put any attributes
   * on the root node and we need some.
   */
  reply = mxmlNewElement(MXML_NO_PARENT, RSP_XML_ROOT);

  node = mxmlNewElement(reply, "response");
  status = mxmlNewElement(node, "status");
  items = mxmlNewElement(node, "items");

  /* Status block */
  node = mxmlNewElement(status, "errorcode");
  mxmlNewText(node, 0, "0");

  node = mxmlNewElement(status, "errorstring");
  mxmlNewText(node, 0, "");

  node = mxmlNewElement(status, "records");
  mxmlNewTextf(node, 0, "%d", records);

  node = mxmlNewElement(status, "totalrecords");
  mxmlNewTextf(node, 0, "%d", qp.results);

  /* Items block (all items) */
  while (((ret = db_query_fetch_string(&qp, &browse_item)) == 0) && (browse_item))
    {
      node = mxmlNewElement(items, "item");
      mxmlNewText(node, 0, browse_item);
    }

  if (qp.filter)
    free(qp.filter);

  if (ret < 0)
    {
      DPRINTF(E_LOG, L_RSP, "Error fetching results\n");

      mxmlDelete(reply);
      db_query_end(&qp);
      rsp_send_error(req, "Error fetching query results");
      return;
    }

  /* HACK
   * Add a dummy empty string to the items element if there is no data
   * to return - this prevents mxml from sending out an empty <items/>
   * tag that the SoundBridge does not handle. It's hackish, but it works.
   */
  if (qp.results == 0)
    mxmlNewText(items, 0, "");

  db_query_end(&qp);

  rsp_send_reply(req, reply);
}
static int
mfi_id_find(const char *path)
{
  struct query_params qp;
  char filter[PATH_MAX];
  const char *a;
  const char *b;
  char *dbpath;
  char *winner;
  int score;
  int i;
  int ret;

  ret = db_snprintf(filter, sizeof(filter), "f.fname = '%q' COLLATE NOCASE", filename_from_path(path));
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_SCAN, "Location in iTunes XML is too long: '%s'\n", path);
      return -1;
    }

  memset(&qp, 0, sizeof(struct query_params));

  qp.type = Q_BROWSE_PATH;
  qp.sort = S_NONE;
  qp.filter = filter;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      db_query_end(&qp);
      return -1;
    }

  winner = NULL;
  score = 0;
  while ((db_query_fetch_string(&qp, &dbpath) == 0) && dbpath)
    {
      if (qp.results == 1)
	{
	  winner = strdup(dbpath);
	  break;
	}

      for (i = 0, a = NULL, b = NULL; (parent_dir(&a, path) == 0) && (parent_dir(&b, dbpath) == 0) && (strcasecmp(a, b) == 0); i++)
	;

      DPRINTF(E_SPAM, L_SCAN, "Comparison of '%s' and '%s' gave score %d\n", dbpath, path, i);

      if (i > score)
	{
	  free(winner);
	  winner = strdup(dbpath);
	  score = i;
	}
      else if (i == score)
	{
	  free(winner);
	  winner = NULL;
	}
    }

  db_query_end(&qp);

  if (!winner)
    {
      DPRINTF(E_LOG, L_SCAN, "No file matches iTunes XML entry '%s'\n", path);
      return -1;
    }

  DPRINTF(E_DBG, L_SCAN, "Found '%s' from iTunes XML (results %d)\n", path, qp.results);

  ret = db_file_id_bypath(winner);
  free(winner);

  return ret;
}
static int
process_regular_file(int pl_id, char *path)
{
  struct query_params qp;
  char filter[PATH_MAX];
  const char *a;
  const char *b;
  char *dbpath;
  char *winner;
  int score;
  int i;
  int ret;

  // Playlist might be from Windows so we change backslash to forward slash
  for (i = 0; i < strlen(path); i++)
    {
      if (path[i] == '\\')
	path[i] = '/';
    }

  ret = db_snprintf(filter, sizeof(filter), "f.fname = '%q' COLLATE NOCASE", filename_from_path(path));
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_SCAN, "Path in playlist is too long: '%s'\n", path);
      return -1;
    }

  memset(&qp, 0, sizeof(struct query_params));

  qp.type = Q_BROWSE_PATH;
  qp.sort = S_NONE;
  qp.filter = filter;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      db_query_end(&qp);
      return -1;
    }

  winner = NULL;
  score = 0;
  while ((db_query_fetch_string(&qp, &dbpath) == 0) && dbpath)
    {
      if (qp.results == 1)
	{
	  winner = strdup(dbpath);
	  break;
	}

      for (i = 0, a = NULL, b = NULL; (parent_dir(&a, path) == 0) && (parent_dir(&b, dbpath) == 0) && (strcasecmp(a, b) == 0); i++)
	;

      DPRINTF(E_SPAM, L_SCAN, "Comparison of '%s' and '%s' gave score %d\n", dbpath, path, i);

      if (i > score)
	{
	  free(winner);
	  winner = strdup(dbpath);
	  score = i;
	}
      else if (i == score)
	{
	  free(winner);
	  winner = NULL;
	}
    }

  db_query_end(&qp);

  if (!winner)
    {
      DPRINTF(E_LOG, L_SCAN, "No file in the library matches playlist entry '%s'\n", path);
      return -1;
    }

  DPRINTF(E_DBG, L_SCAN, "Adding '%s' to playlist %d (results %d)\n", winner, pl_id, qp.results);

  db_pl_add_item_bypath(pl_id, winner);
  free(winner);

  return 0;
}
示例#4
0
int
artwork_get_group(int id, int max_w, int max_h, int format, struct evbuffer *evbuf)
{
  struct query_params qp;
  struct db_media_file_info dbmfi;
  char *dir;
  int got_art;
  int ret;

  DPRINTF(E_DBG, L_ART, "Artwork request for group %d\n", id);

  /* Try directory artwork first */
  memset(&qp, 0, sizeof(struct query_params));

  qp.type = Q_GROUP_DIRS;
  qp.id = id;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_ART, "Could not start Q_GROUP_DIRS query\n");

      /* Skip to invidual files artwork */
      goto files_art;
    }

  got_art = -1;
  while ((got_art < 0) && ((ret = db_query_fetch_string(&qp, &dir)) == 0) && (dir))
    {
      got_art = artwork_get_dir_image(dir, 1, max_w, max_h, format, evbuf);
      if (got_art < 0)
        got_art = artwork_get_parentdir_image(dir, 1, max_w, max_h, format, evbuf);
    }

  db_query_end(&qp);

  if (ret < 0)
    DPRINTF(E_LOG, L_ART, "Error fetching Q_GROUP_DIRS results\n");
  else if (got_art > 0)
    return got_art;


  /* Then try individual files */
 files_art:
  memset(&qp, 0, sizeof(struct query_params));

  qp.type = Q_GROUP_ITEMS;
  qp.id = id;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_ART, "Could not start Q_GROUP_ITEMS query\n");

      return -1;
    }

  got_art = -1;
  while ((got_art < 0) && ((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
    {
      got_art = artwork_get_own_image(dbmfi.path, max_w, max_h, format, evbuf);
    }

  db_query_end(&qp);

  if (ret < 0)
    DPRINTF(E_LOG, L_ART, "Error fetching Q_GROUP_ITEMS results\n");
  else if (got_art > 0)
    return got_art;

  return -1;
}