summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
825f60a)
check_suitable() now rejects tracks that don't belong to any
collection. This situation can arise if you remove a collection from
the configuration.
A remaining bug is that even reproducible data for the tracks remains
in the database long after the collection has been removed.
is now built into the server, where it can be done much more
efficiently.
is now built into the server, where it can be done much more
efficiently.
+A bug where removing a collection (from the configuration) could cause a
+crash when random play was enabled has been fixed.
+
** disorderfm
There is a new command line tool called 'disorderfm' which is designed
** disorderfm
There is a new command line tool called 'disorderfm' which is designed
for(n = 0; n < config->collection.n; ++n)
fn(&config->collection.s[n]);
for(n = 0; n < config->collection.n; ++n)
fn(&config->collection.s[n]);
+ /* TODO: we need to tidy up tracks from collections now removed. We could do
+ * this two ways: either remember collections we think there are and spot
+ * their disappearance, or iterate over all tracks and gc any that don't fit
+ * into some collection.
+ *
+ * Having a way to rename collections would be rather convenient too but
+ * that's another kettle of monkeys.
+ */
}
int main(int argc, char **argv) {
}
int main(int argc, char **argv) {
int c, used_db = 0, slash_prefix, err;
struct kvp *at;
int c, used_db = 0, slash_prefix, err;
struct kvp *at;
- if(strstr(track, "Troggs"))
- D(("computing alias for %s", track));
dynstr_init(&d);
dynstr_append_string(&d, find_track_root(track));
while((c = (unsigned char)*s++)) {
dynstr_init(&d);
dynstr_append_string(&d, find_track_root(track));
while((c = (unsigned char)*s++)) {
* an alias) */
switch(err = trackdb_getdata(trackdb_tracksdb, d.vec, &at, tid)) {
case 0:
* an alias) */
switch(err = trackdb_getdata(trackdb_tracksdb, d.vec, &at, tid)) {
case 0:
- if(strstr(track, "Troggs"))
- D(("found a hit for alias"));
if((s = kvp_get(at, "_alias_for"))
&& !strcmp(s, track)) {
case DB_NOTFOUND:
if((s = kvp_get(at, "_alias_for"))
&& !strcmp(s, track)) {
case DB_NOTFOUND:
- if(strstr(track, "Troggs"))
- D(("accepting anyway"));
*aliasp = d.vec;
} else {
*aliasp = d.vec;
} else {
- if(strstr(track, "Troggs")) {
- D(("rejecting"));
- D(("%s", track));
- D(("%s", s ? s : "(null)"));
- }
}
/* Check whether a track is suitable for random play. Returns 0 if it is,
}
/* Check whether a track is suitable for random play. Returns 0 if it is,
- * DB_NOTFOUND if it or DB_LOCK_DEADLOCK. */
+ * DB_NOTFOUND if it is not or DB_LOCK_DEADLOCK if the database gave us
+ * that. */
static int check_suitable(const char *track,
DB_TXN *tid,
char **required_tags,
static int check_suitable(const char *track,
DB_TXN *tid,
char **required_tags,
struct kvp *p, *t;
const char *pick_at_random, *played_time;
struct kvp *p, *t;
const char *pick_at_random, *played_time;
+ /* don't pick tracks that aren't in any surviving collection (for instance
+ * you've edited the config but the rescan hasn't done its job yet) */
+ if(!find_track_root(track)) {
+ info("found track not in any collection: %s", track);
+ return DB_NOTFOUND;
+ }
/* don't pick aliases - only pick the canonical form */
if(gettrackdata(track, &t, &p, 0, 0, tid) == DB_LOCK_DEADLOCK)
return DB_LOCK_DEADLOCK;
/* don't pick aliases - only pick the canonical form */
if(gettrackdata(track, &t, &p, 0, 0, tid) == DB_LOCK_DEADLOCK)
return DB_LOCK_DEADLOCK;