summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Viktor Semykin <thesame.ml@gmail.com>2010-05-25 03:37:44 +0300
committerGravatar Viktor Semykin <thesame.ml@gmail.com>2010-05-25 03:37:44 +0300
commit8c012917f5530d947c1a31adfc6aba4b0cf3853c (patch)
treef9183ee845fd497006dde0c5f80049714a15d9a4 /plugins
parentbe0f4b1926f7e77c7e03eae7b70ec12f1b905025 (diff)
Misc plugin actions
Diffstat (limited to 'plugins')
-rw-r--r--plugins/gtkui/plcommon.c48
-rw-r--r--plugins/lastfm/lastfm.c62
-rw-r--r--plugins/shellexec/Makefile.am9
-rw-r--r--plugins/shellexec/shellexec.c125
4 files changed, 238 insertions, 6 deletions
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index 96ddff69..3b72b901 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -346,6 +346,14 @@ on_remove_from_disk_activate (GtkMenuItem *menuitem,
}
void
+actionitem_activate (GtkMenuItem *menuitem,
+ DB_single_action_t *action)
+{
+ DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (clicked_idx, PL_MAIN);
+ action->callback (it, action->data);
+}
+
+void
list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
clicked_idx = deadbeef->pl_get_idx_of (it);
int inqueue = deadbeef->pl_playqueue_test (it);
@@ -399,6 +407,46 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
gtk_container_add (GTK_CONTAINER (playlist_menu), separator8);
gtk_widget_set_sensitive (separator8, FALSE);
+ ///
+ int count;
+ int i, j;
+ GtkWidget *actionitem;
+ DB_single_action_t *actions[4];
+ DB_plugin_t **plugins = deadbeef->plug_get_list();
+ for (i = 0; plugins[i]; i++)
+ {
+ if (plugins[i]->type != DB_PLUGIN_MISC)
+ continue;
+
+ DB_misc_t *misc = (DB_misc_t*)plugins[i];
+ if (!misc->get_single_actions)
+ continue;
+
+ count = 4;
+ if (!misc->get_single_actions (it, actions, &count))
+ continue;
+
+ if (count == 0)
+ continue;
+
+ for (j = 0; j < count; j++)
+ {
+ actionitem = gtk_menu_item_new_with_mnemonic (actions[j]->title);
+ gtk_widget_show (actionitem);
+ gtk_container_add (GTK_CONTAINER (playlist_menu), actionitem);
+ g_object_set_data (G_OBJECT (actionitem), "ps", listview);
+
+ g_signal_connect ((gpointer) actionitem, "activate",
+ G_CALLBACK (actionitem_activate),
+ actions[j]);
+ }
+ separator8 = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator8);
+ gtk_container_add (GTK_CONTAINER (playlist_menu), separator8);
+ gtk_widget_set_sensitive (separator8, FALSE);
+ }
+ ///
+
properties1 = gtk_menu_item_new_with_mnemonic ("Properties");
gtk_widget_show (properties1);
gtk_container_add (GTK_CONTAINER (playlist_menu), properties1);
diff --git a/plugins/lastfm/lastfm.c b/plugins/lastfm/lastfm.c
index 3ba8def8..02dff618 100644
--- a/plugins/lastfm/lastfm.c
+++ b/plugins/lastfm/lastfm.c
@@ -334,26 +334,31 @@ lfm_fetch_song_info (DB_playItem_t *song, const char **a, const char **t, const
static int
lfm_uri_encode (char *out, int outl, const char *str) {
int l = outl;
- static const char echars[] = " ;/?:@=#&+";
//trace ("lfm_uri_encode %p %d %s\n", out, outl, str);
while (*str) {
if (outl <= 1) {
//trace ("no space left for 1 byte in buffer\n");
return -1;
}
- if (strchr (echars, *str)) {
+
+ if (!(
+ (*str >= '0' && *str <= '9') ||
+ (*str >= 'a' && *str <= 'z') ||
+ (*str >= 'A' && *str <= 'Z') ||
+ (*str == ' ')
+ ))
+ {
if (outl <= 3) {
//trace ("no space left for 3 bytes in the buffer\n");
return -1;
}
- //trace ("adding escaped value for %c\n", *str);
- snprintf (out, outl, "%%%02x", (int)*str);
+ snprintf (out, outl, "%%%02x", (uint8_t)*str);
outl -= 3;
str++;
out += 3;
}
else {
- *out = *str;
+ *out = *str == ' ' ? '+' : *str;
out++;
str++;
outl--;
@@ -819,6 +824,50 @@ lastfm_stop (void) {
return 0;
}
+static int
+lfm_action_lookup (DB_playItem_t *it, void *data)
+{
+ const char *artist = deadbeef->pl_find_meta (it, "artist");
+ const char *title = deadbeef->pl_find_meta (it, "title");
+
+ if (!title || !artist)
+ return 0;
+
+ char eartist [strlen (artist) * 3 + 1];
+ char etitle [strlen (title) * 3 + 1];
+
+ if (-1 == lfm_uri_encode (eartist, sizeof (eartist), artist))
+ return 0;
+
+ if (-1 == lfm_uri_encode (etitle, sizeof (etitle), title))
+ return 0;
+
+ char *command = NULL;
+ if (-1 == asprintf (&command, "xdg-open http://www.last.fm/music/%s/_/%s", eartist, etitle))
+ return 0;
+ system (command);
+ free (command);
+}
+
+static DB_single_action_t lookup_action = {
+ .title = "Lookup at Last.fm",
+ .callback = lfm_action_lookup
+};
+
+static int
+lfm_get_single_actions (DB_playItem_t *it, DB_single_action_t *actions[], int *size)
+{
+ if (deadbeef->pl_find_meta (it, "artist") &&
+ deadbeef->pl_find_meta (it, "title"))
+ {
+ actions[0] = &lookup_action;
+ *size = 1;
+ }
+ else
+ *size = 0;
+ return 1;
+}
+
static const char settings_dlg[] =
"property \"Enable scrobbler\" checkbox lastfm.enable 0;"
"property \"Disable nowplaying\" checkbox lastfm.disable_np 0;"
@@ -840,5 +889,6 @@ static DB_misc_t plugin = {
.plugin.website = "http://deadbeef.sf.net",
.plugin.start = lastfm_start,
.plugin.stop = lastfm_stop,
- .plugin.configdialog = settings_dlg
+ .plugin.configdialog = settings_dlg,
+ .get_single_actions = lfm_get_single_actions
};
diff --git a/plugins/shellexec/Makefile.am b/plugins/shellexec/Makefile.am
new file mode 100644
index 00000000..65d6a5b8
--- /dev/null
+++ b/plugins/shellexec/Makefile.am
@@ -0,0 +1,9 @@
+if HAVE_SHELLEXEC
+shxdir = $(libdir)/$(PACKAGE)
+pkglib_LTLIBRARIES = shellexec.la
+shellexec_la_SOURCES = shellexec.c
+shellexec_la_LDFLAGS = -module
+
+shellexec_la_LIBADD = $(LDADD) $(HOTKEYS_LIBS)
+AM_CFLAGS = $(CFLAGS) -std=c99
+endif
diff --git a/plugins/shellexec/shellexec.c b/plugins/shellexec/shellexec.c
new file mode 100644
index 00000000..39e7f4da
--- /dev/null
+++ b/plugins/shellexec/shellexec.c
@@ -0,0 +1,125 @@
+/*
+ Shellexec plugin for DeaDBeeF
+ Copyright (C) 2009 Viktor Semykin <thesame.ml@gmail.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "../../deadbeef.h"
+
+#define MAX_COMMANDS 128
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+static DB_misc_t plugin;
+static DB_functions_t *deadbeef;
+
+DB_single_action_t shx_actions [MAX_COMMANDS];
+static int single_action_count;
+
+DB_plugin_t *
+shellexec_load (DB_functions_t *api) {
+ deadbeef = api;
+ return DB_PLUGIN (&plugin);
+}
+
+static int
+shx_get_single_actions (DB_playItem_t *it, DB_single_action_t *actions[], int *size)
+{
+ if (*size < single_action_count)
+ return 0;
+
+ int i;
+ *size = single_action_count;
+ trace ("Shellexec: %d actions\n", single_action_count);
+ for (i=0; i < single_action_count; i++)
+ actions[i] = &shx_actions[i];
+ return 1;
+}
+
+static int
+shx_callback (DB_playItem_t *it, void *data)
+{
+ char fmt[1024]; //FIXME: possible stack corruption
+ deadbeef->pl_format_title (it, -1, fmt, sizeof (fmt), -1, data);
+ printf ("%s\n", fmt);
+ return 0;
+}
+
+static char*
+trim (char* s)
+{
+ char *h, *t;
+
+ for (h = s; *h == ' ' || *h == '\t'; h++);
+ for (t = s + strlen (s); *t == ' ' || *t == '\t'; t--);
+ * (t+1) = 0;
+ return h;
+}
+
+static int
+shellexec_start (void)
+{
+ trace ("Starting shellexec\n");
+ single_action_count = 0;
+ DB_conf_item_t *item = deadbeef->conf_find ("shellexec.", NULL);
+ while (item)
+ {
+ if (single_action_count == MAX_COMMANDS)
+ {
+ fprintf (stdout, "Shellexec: max number of commands (%d) exceeded\n", MAX_COMMANDS);
+ break;
+ }
+ size_t l = strlen (item->value) + 1;
+ char tmp[l];
+ strcpy (tmp, item->value);
+ trace ("Shellexec: %s\n", tmp);
+
+ char *semicolon = strchr (tmp, ':');
+ if (!semicolon)
+ {
+ fprintf (stdout, "Shellexec: wrong option <%s>\n", tmp);
+ continue;
+ }
+
+ *semicolon = 0;
+
+ shx_actions[single_action_count].title = strdup (trim (semicolon + 1));
+ shx_actions[single_action_count].callback = shx_callback;
+ shx_actions[single_action_count].data = strdup (trim (tmp));
+
+ item = deadbeef->conf_find ("shellexec.", item);
+ single_action_count++;
+ }
+}
+
+// define plugin interface
+static DB_misc_t plugin = {
+ .plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .plugin.api_vminor = DB_API_VERSION_MINOR,
+ .plugin.type = DB_PLUGIN_MISC,
+ .plugin.id = "shellexec",
+ .plugin.name = "Shell commands for tracks",
+ .plugin.descr = "Executes configurable shell commands for tracks",
+ .plugin.author = "Viktor Semykin",
+ .plugin.email = "thesame.ml@gmail.com",
+ .plugin.website = "http://deadbeef.sf.net",
+ .plugin.start = shellexec_start,
+
+ .get_single_actions = shx_get_single_actions
+};
+