Esempio n. 1
0
// version 0: title formatting v1
// version 1: title formatting v2
void
plt_sort_internal (playlist_t *playlist, int iter, int id, const char *format, int order, int version) {
    if (order == DDB_SORT_RANDOM) {
        plt_sort_random (playlist, iter);
        return;
    }
    int ascending = order == DDB_SORT_DESCENDING ? 0 : 1;

    if (format == NULL || id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) {
        return;
    }
    pl_lock ();
    struct timeval tm1;
    gettimeofday (&tm1, NULL);
    pl_sort_ascending = ascending;
    trace ("ascending: %d\n", ascending);
    pl_sort_id = id;

    pl_sort_version = version;
    if (version == 0) {
        pl_sort_format = format;
        pl_sort_tf_bytecode = NULL;
    }
    else {
        pl_sort_format = NULL;
        pl_sort_tf_bytecode = tf_compile (format);
        pl_sort_tf_ctx._size = sizeof (pl_sort_tf_ctx);
        pl_sort_tf_ctx.it = NULL;
        pl_sort_tf_ctx.plt = (ddb_playlist_t *)playlist;
        pl_sort_tf_ctx.idx = -1;
        pl_sort_tf_ctx.id = id;
    }

    if (format && id == -1
        && ((version == 0 && !strcmp (format, "%l"))
            || (version == 1 && !strcmp (format, "%length%")))
        ) {
        pl_sort_is_duration = 1;
    }
    else {
        pl_sort_is_duration = 0;
    }
    if (format && id == -1
        && ((version == 0 && !strcmp (format, "%n"))
            || (version == 1 && (!strcmp (format, "%track number%") || !strcmp (format, "%tracknumber%"))))
        ) {
        pl_sort_is_track = 1;
    }
    else {
        pl_sort_is_track = 0;
    }

    playItem_t **array = malloc (playlist->count[iter] * sizeof (playItem_t *));
    int idx = 0;
    for (playItem_t *it = playlist->head[iter]; it; it = it->next[iter], idx++) {
        array[idx] = it;
    }
    qsort (array, playlist->count[iter], sizeof (playItem_t *), qsort_cmp_func);
    playItem_t *prev = NULL;
    playlist->head[iter] = 0;
    for (idx = 0; idx < playlist->count[iter]; idx++) {
        playItem_t *it = array[idx];
        it->prev[iter] = prev;
        it->next[iter] = NULL;
        if (!prev) {
            playlist->head[iter] = it;
        }
        else {
            prev->next[iter] = it;
        }
        prev = it;
    }

    playlist->tail[iter] = array[playlist->count[iter]-1];

    free (array);

    struct timeval tm2;
    gettimeofday (&tm2, NULL);
    int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
    trace ("sort time: %f seconds\n", ms / 1000.f);

    plt_modified (playlist);

    if (version == 0) {
        pl_sort_format = NULL;
    }

    if (version == 1) {
        tf_free (pl_sort_tf_bytecode);
        pl_sort_tf_bytecode = NULL;
        memset (&pl_sort_tf_ctx, 0, sizeof (pl_sort_tf_ctx));
    }

    pl_unlock ();
}
Esempio n. 2
0
// this function executes server-side commands only
// must be called only from within server
// -1 error, program must exit with error code -1
//  0 proceed normally as nothing happened
//  1 no error, but program must exit with error code 0
//  2 don't load playlist on startup
//  when executed in remote server -- error code will be ignored
int
server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsize) {
    if (sendback) {
        sendback[0] = 0;
    }
    const char *parg = cmdline;
    const char *pend = cmdline + len;
    int queue = 0;
    while (parg < pend) {
        if (strlen (parg) >= 2 && parg[0] == '-' && parg[1] != '-') {
            parg += strlen (parg);
            parg++;
            return 0; // running under osx debugger?
        }
        else if (!strcmp (parg, "--nowplaying")) {
            parg += strlen (parg);
            parg++;
            if (parg >= pend) {
                const char *errtext = "--nowplaying expects format argument";
                if (sendback) {
                    snprintf (sendback, sbsize, "error %s\n", errtext);
                    return 0;
                }
                else {
                    trace_err ("%s\n", errtext);
                    return -1;
                }
            }
            char out[2048];
            playItem_t *curr = streamer_get_playing_track ();
            if (curr) {
                pl_format_title (curr, -1, out, sizeof (out), -1, parg);
                pl_item_unref (curr);
            }
            else {
                strcpy (out, "nothing");
            }
            if (sendback) {
                snprintf (sendback, sbsize, "nowplaying %s", out);
            }
            else {
                fwrite (out, 1, strlen (out), stdout);
                return 1; // exit
            }
        }
        else if (!strcmp (parg, "--nowplaying-tf")) {
            parg += strlen (parg);
            parg++;
            if (parg >= pend) {
                const char *errtext = "--nowplaying-tf expects format argument";
                if (sendback) {
                    snprintf (sendback, sbsize, "error %s\n", errtext);
                    return 0;
                }
                else {
                    trace_err ("%s\n", errtext);
                    return -1;
                }
            }
            char out[2048];
            playItem_t *curr = streamer_get_playing_track ();
            char *script = tf_compile (parg);
            if (script) {
                ddb_tf_context_t ctx = {
                    ._size = sizeof (ddb_tf_context_t),
                    .it = (DB_playItem_t *)curr,
                };
                tf_eval (&ctx, script, out, sizeof (out));
                tf_free (script);
            }
            else {
                *out = 0;
            }
            if (curr) {
                pl_item_unref (curr);
            }
            if (sendback) {
                snprintf (sendback, sbsize, "nowplaying %s", out);
            }
            else {
                fwrite (out, 1, strlen (out), stdout);
                return 1; // exit
            }
        }
        else if (!strcmp (parg, "--next")) {