static void parse_browse_album(ezxml_t top, struct album_browse* a) { xmlstrncpy(a->name, sizeof a->name, top, "name", -1); xmlstrncpy(a->id, sizeof a->id, top, "id", -1); xmlstrncpy(a->cover_id, sizeof a->cover_id, top, "cover", -1); xmlatoi(&a->year, top, "year", -1); xmlatof(&a->popularity, top, "popularity", -1); xmlstrncpy(a->artist, sizeof a->artist, top, "artist", -1); xmlstrncpy(a->artist_id, sizeof a->artist_id, top, "artist-id", -1); ezxml_t x = ezxml_get(top, "review",-1); if (x) { int len = strlen(x->txt); a->review = malloc(len + 1); memcpy(a->review, x->txt, len+1); } /* TODO: support multiple discs per album */ a->tracks = calloc(1, sizeof(struct track)); ezxml_t disc = ezxml_get(top, "discs",0,"disc", -1); a->num_tracks = parse_tracks(disc, a->tracks, false); /* Copy missing metadata from album to tracks */ int count = 0; for (struct track *t = a->tracks; t; t = t->next) { DSFYstrncpy(t->album, a->name, sizeof t->album); DSFYstrncpy(t->album_id, a->id, sizeof t->album_id); DSFYstrncpy(t->cover_id, a->cover_id, sizeof t->cover_id); t->year = a->year; count++; } }
int xml_parse_tracklist(struct track* firsttrack, unsigned char* xml, int len, bool ordered) { ezxml_t top = ezxml_parse_str(xml, len); ezxml_t tracks = ezxml_get(top, "tracks",-1); int num_tracks = parse_tracks(tracks, firsttrack, ordered); ezxml_free(top); return num_tracks; }
static void parse_browse_album(ezxml_t top, struct album_browse* a, bool high_bitrate) { xmlstrncpy(a->name, sizeof a->name, top, "name", -1); xmlstrncpy(a->id, sizeof a->id, top, "id", -1); xmlstrncpy(a->artist, sizeof a->artist, top, "artist", -1); xmlstrncpy(a->artist_id, sizeof a->artist_id, top, "artist-id", -1); xmlstrncpy(a->cover_id, sizeof a->cover_id, top, "cover", -1); xmlatoi(&a->year, top, "year", -1); xmlatof(&a->popularity, top, "popularity", -1); a->tracks = calloc(1, sizeof(struct track)); ezxml_t disc = ezxml_get(top, "discs",0,"disc", -1); a->num_tracks = parse_tracks(disc, a->tracks, false, high_bitrate); /* Append extra discs to album */ struct track *last = a->tracks; while (last->next) last = last->next; while ((disc = disc->next)) { int offset = last->tracknumber; last->next = calloc(1, sizeof(struct track)); a->num_tracks += parse_tracks(disc, last->next, false, high_bitrate); do { last = last->next; last->tracknumber += offset; } while (last->next); } /* Copy missing metadata from album to tracks */ int count = 0; for (struct track *t = a->tracks; t; t = t->next) { DSFYstrncpy(t->album, a->name, sizeof t->album); DSFYstrncpy(t->album_id, a->id, sizeof t->album_id); DSFYstrncpy(t->cover_id, a->cover_id, sizeof t->cover_id); t->year = a->year; count++; } }
int xml_parse_search(struct search_result* search, struct track* firsttrack, unsigned char* xml, int len, bool high_bitrate) { ezxml_t top = ezxml_parse_str(xml, len); xmlstrncpy(search->suggestion, sizeof search->suggestion, top, "did-you-mean", -1); xmlatoi(&search->total_artists, top, "total-artists", -1); xmlatoi(&search->total_albums, top, "total-albums", -1); xmlatoi(&search->total_tracks, top, "total-tracks", -1); ezxml_t artists = ezxml_get(top, "artists",-1); struct artist *prev = NULL; struct artist *artist = calloc(1, sizeof(struct artist)); search->artists = artist; ezxml_t xa; for (xa = ezxml_get(artists, "artist", -1); xa; xa = xa->next) { if(prev) { artist = calloc(1, sizeof(struct artist)); prev->next = artist; } parse_artist(xa, artist); prev = artist; } ezxml_t albums = ezxml_get(top, "albums",-1); struct album *aprev = NULL; struct album *album = calloc(1, sizeof(struct album)); search->albums = album; for (xa = ezxml_get(albums, "album", -1); xa; xa = xa->next) { if(aprev) { album = calloc(1, sizeof(struct album)); aprev->next = album; } parse_album(xa, album); aprev = album; } ezxml_t tracks = ezxml_get(top, "tracks",-1); int num_tracks = parse_tracks(tracks, firsttrack, false, high_bitrate); ezxml_free(top); return num_tracks; }
static void parse_browse_album(ezxml_t top, struct album_browse* a, bool high_bitrate) { xmlstrncpy(a->name, sizeof a->name, top, "name", -1); xmlstrncpy(a->id, sizeof a->id, top, "id", -1); xmlstrncpy(a->cover_id, sizeof a->cover_id, top, "cover", -1); xmlatoi(&a->year, top, "year", -1); xmlatof(&a->popularity, top, "popularity", -1); /* TODO: support multiple discs per album */ a->tracks = calloc(1, sizeof(struct track)); ezxml_t disc = ezxml_get(top, "discs",0,"disc", -1); a->num_tracks = parse_tracks(disc, a->tracks, false, high_bitrate); /* Copy missing metadata from album to tracks */ int count = 0; for (struct track *t = a->tracks; t; t = t->next) { DSFYstrncpy(t->album, a->name, sizeof t->album); DSFYstrncpy(t->album_id, a->id, sizeof t->album_id); DSFYstrncpy(t->cover_id, a->cover_id, sizeof t->cover_id); t->year = a->year; count++; } }
static void parse_cmdline(ripncode_t *r, int argc, char **argv, char **envp) { # define OPTIONS "d:c:t:f:m:L:T:v::d:nh" struct option options[] = { { "device" , required_argument, NULL, 'd' }, { "driver" , required_argument, NULL, 'c' }, { "tracks" , required_argument, NULL, 't' }, { "format" , required_argument, NULL, 'f' }, { "metadata" , required_argument, NULL, 'm' }, { "log-level" , required_argument, NULL, 'L' }, { "log-target" , required_argument, NULL, 'T' }, { "verbose" , optional_argument, NULL, 'v' }, { "debug" , required_argument, NULL, 'd' }, { "dry-run" , no_argument , NULL, 'n' }, { "help" , no_argument , NULL, 'h' }, { NULL , 0, NULL, 0 } }; int opt, help; MRP_UNUSED(envp); help = FALSE; while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) { switch (opt) { case 'D': r->device = optarg; if (access(r->device, R_OK) < 0) ripncode_fatal(r, "can't access '%s' (%d: %s).", r->device, errno, strerror(errno)); break; case 'c': r->driver = optarg; break; case 't': r->rip = optarg; parse_tracks(r); break; case 'f': r->format = optarg; break; case 'm': r->metadata = optarg; if (access(r->metadata, R_OK) < 0) ripncode_fatal(r, "can't access '%s' (%d: %s).", r->metadata, errno, strerror(errno)); break; case 'L': r->log_mask = mrp_log_parse_levels(optarg); mrp_log_set_mask(r->log_mask); break; case 'v': r->log_mask <<= 1; r->log_mask |= 1; mrp_log_set_mask(r->log_mask); break; case 'T': r->log_target = optarg; mrp_log_set_target(r->log_target); break; case 'd': r->log_mask |= MRP_LOG_MASK_DEBUG; mrp_log_set_mask(r->log_mask); mrp_debug_set_config(optarg); mrp_debug_enable(TRUE); break; case 'n': r->dryrun = 1; break; case 'h': help++; break; default: print_usage(r, EINVAL, "invalid option '%c'", opt); } } if (help) { print_usage(r, -1, ""); exit(0); } }