/* * Copyright (c) 2003, 2004 Jean-Yves Lefort * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #define NO_IMPORT_PYGOBJECT #include #include #include "streamtuner.h" #include "pst-category.h" #include "pst-handler-config.h" #include "pst-handler-field.h" #include "pst-handler.h" #include "pst-helpers.h" #include "pst-stream.h" #include "pst-transfer-session.h" #define PST_API_MAJOR_VERSION 2 #define PST_API_MINOR_VERSION 0 /*** st-action-api.h *********************************************************/ static PyObject *pst_action_register (PyObject *dummy, PyObject *args); static PyObject *pst_action_run (PyObject *dummy, PyObject *args); /*** st-dialog-api.h *********************************************************/ static PyObject *pst_notice (PyObject *dummy, PyObject *args); static PyObject *pst_info_dialog (PyObject *dummy, PyObject *args); static PyObject *pst_error_dialog (PyObject *dummy, PyObject *args); static PyObject *pst_search_dialog (PyObject *dummy, PyObject *args); /*** st-handlers-api.h *******************************************************/ static PyObject *pst_handlers_add (PyObject *dummy, PyObject *args); /*** st-m3u-api.h ************************************************************/ static PyObject *pst_m3u_mktemp (PyObject *dummy, PyObject *args); /*** st-pls-api.h ************************************************************/ static PyObject *pst_pls_parse (PyObject *dummy, PyObject *args); /*** st-state-api.h **********************************************************/ static PyObject *pst_is_aborted (PyObject *dummy, PyObject *args); /*** st-settings-api.h *******************************************************/ static PyObject *pst_settings_get_private_dir (PyObject *dummy, PyObject *args); static PyObject *pst_settings_get_music_dir (PyObject *dummy, PyObject *args); /*** st-sgml-ref-api.h *******************************************************/ static PyObject *pst_sgml_ref_expand (PyObject *dummy, PyObject *args); /*** st-transfer-api.h *******************************************************/ static PyObject *pst_transfer_escape (PyObject *dummy, PyObject *args); /*** st-util-api.h ***********************************************************/ static PyObject *pst_format_bitrate (PyObject *dummy, PyObject *args); static PyObject *pst_format_samplerate (PyObject *dummy, PyObject *args); static PyObject *pst_format_channels (PyObject *dummy, PyObject *args); static PyObject *pst_format_audio_properties (PyObject *dummy, PyObject *args); static PyObject *pst_hig_section_new (PyObject *dummy, PyObject *args); static PyObject *pst_set_tooltip (PyObject *dummy, PyObject *args); /*** st-version-api.h ********************************************************/ static PyObject *pst_check_api_version (PyObject *dummy, PyObject *args); /*** Python-specific API *****************************************************/ static PyObject *pst_find_icon (PyObject *dummy, PyObject *args); static PyObject *pst_gettext (PyObject *dummy, PyObject *args); static PyObject *pst_ngettext (PyObject *dummy, PyObject *args); static PyMethodDef methods[] = { { "action_register", pst_action_register, METH_VARARGS }, { "action_run", pst_action_run, METH_VARARGS }, { "notice", pst_notice, METH_VARARGS }, { "info_dialog", pst_info_dialog, METH_VARARGS }, { "error_dialog", pst_error_dialog, METH_VARARGS }, { "search_dialog", pst_search_dialog, METH_NOARGS }, { "handlers_add", pst_handlers_add, METH_VARARGS }, { "m3u_mktemp", pst_m3u_mktemp, METH_VARARGS }, { "pls_parse", pst_pls_parse, METH_VARARGS }, { "is_aborted", pst_is_aborted, METH_NOARGS }, { "settings_get_private_dir", pst_settings_get_private_dir, METH_NOARGS }, { "settings_get_music_dir", pst_settings_get_music_dir, METH_NOARGS }, { "sgml_ref_expand", pst_sgml_ref_expand, METH_VARARGS }, { "transfer_escape", pst_transfer_escape, METH_VARARGS }, { "format_bitrate", pst_format_bitrate, METH_VARARGS }, { "format_samplerate", pst_format_samplerate, METH_VARARGS }, { "format_channels", pst_format_channels, METH_VARARGS }, { "format_audio_properties", pst_format_audio_properties, METH_VARARGS }, { "HIGSection", pst_hig_section_new, METH_VARARGS }, { "set_tooltip", pst_set_tooltip, METH_VARARGS }, { "check_api_version", pst_check_api_version, METH_VARARGS }, { "find_icon", pst_find_icon, METH_VARARGS }, { "_", pst_gettext, METH_VARARGS }, { "gettext", pst_gettext, METH_VARARGS }, { "ngettext", pst_ngettext, METH_VARARGS }, { NULL, NULL, 0, NULL }, }; static char *private_icons_dir = NULL; gboolean pst_init (void) { PyObject *module; if (! private_icons_dir) private_icons_dir = g_build_filename(st_settings_get_private_dir(), "streamtuner-python", "icons", NULL); module = Py_InitModule("ST", methods); PyModule_AddIntConstant(module, "MAJOR_VERSION", st_major_version); PyModule_AddIntConstant(module, "MINOR_VERSION", st_minor_version); PyModule_AddIntConstant(module, "MICRO_VERSION", st_micro_version); PyModule_AddIntConstant(module, "API_MAJOR_VERSION", PST_API_MAJOR_VERSION); PyModule_AddIntConstant(module, "API_MINOR_VERSION", PST_API_MINOR_VERSION); return pst_category_register(module) && pst_handler_config_register(module) && pst_handler_field_register(module) && pst_handler_register(module) && pst_stream_register(module) && pst_transfer_session_register(module); } /*** st-action-api.h *********************************************************/ static PyObject * pst_action_register (PyObject *dummy, PyObject *args) { const char *id; const char *label; const char *command = NULL; if (! PyArg_ParseTuple(args, "ss|z", &id, &label, &command)) return NULL; st_action_register(id, label, command); return pst_none(); } static PyObject * pst_action_run (PyObject *dummy, PyObject *args) { const char *id; const char *uri; gboolean status; GError *err = NULL; if (! PyArg_ParseTuple(args, "ss", &id, &uri)) return NULL; Py_BEGIN_ALLOW_THREADS status = st_action_run(id, uri, &err); Py_END_ALLOW_THREADS if (! status) { PyErr_SetString(PyExc_RuntimeError, err->message); g_error_free(err); return NULL; } return pst_none(); } /*** st-dialog-api.h *********************************************************/ static PyObject * pst_notice (PyObject *dummy, PyObject *args) { const char *message; if (! PyArg_ParseTuple(args, "s", &message)) return NULL; st_notice("%s", message); return pst_none(); } static PyObject * pst_info_dialog (PyObject *dummy, PyObject *args) { const char *primary; const char *secondary; const char *fmt; if (! PyArg_ParseTuple(args, "zz", &primary, &secondary)) return NULL; Py_BEGIN_ALLOW_THREADS fmt = secondary ? "%s" : NULL; /* work around GCC warning for null format string */ st_info_dialog(primary, fmt, secondary); Py_END_ALLOW_THREADS return pst_none(); } static PyObject * pst_error_dialog (PyObject *dummy, PyObject *args) { const char *primary; const char *secondary; const char *fmt; if (! PyArg_ParseTuple(args, "zz", &primary, &secondary)) return NULL; Py_BEGIN_ALLOW_THREADS fmt = secondary ? "%s" : NULL; /* work around GCC warning for null format string */ st_error_dialog(primary, fmt, secondary); Py_END_ALLOW_THREADS return pst_none(); } static PyObject * pst_search_dialog (PyObject *dummy, PyObject *args) { char *str; Py_BEGIN_ALLOW_THREADS str = st_search_dialog(); Py_END_ALLOW_THREADS return pst_string_take_string_or_null(str); } /*** st-handlers-api.h *******************************************************/ static PyObject * pst_handlers_add (PyObject *dummy, PyObject *args) { PSTHandler *phandler; if (! PyArg_ParseTuple(args, "O!", &PSTHandler_Type, &phandler)) return NULL; st_handlers_add(phandler->handler); return pst_none(); } /*** st-m3u-api.h ************************************************************/ static PyObject * pst_m3u_mktemp (PyObject *dummy, PyObject *args) { const char *prefix; GSList *uri_list; GError *err = NULL; char *filename; if (! PyArg_ParseTuple(args, "sO&", &prefix, pst_strings_as_gslist, &uri_list)) return NULL; Py_BEGIN_ALLOW_THREADS filename = st_m3u_mktemp(prefix, uri_list, &err); Py_END_ALLOW_THREADS /* free the list */ g_slist_foreach(uri_list, (GFunc) g_free, NULL); g_slist_free(uri_list); if (! filename) { PyErr_SetString(PyExc_RuntimeError, err->message); g_error_free(err); return NULL; } return pst_string_take_string(filename); } /*** st-pls-api.h ************************************************************/ static PyObject * pst_pls_parse (PyObject *dummy, PyObject *args) { const char *playlist; GSList *url_list; PyObject *tuple; if (! PyArg_ParseTuple(args, "s", &playlist)) return NULL; url_list = st_pls_parse(playlist); tuple = pst_strings_from_gslist(url_list); /* free the list */ g_slist_foreach(url_list, (GFunc) g_free, NULL); g_slist_free(url_list); return tuple; } /*** st-state-api.h **********************************************************/ static PyObject * pst_is_aborted (PyObject *dummy, PyObject *args) { return PyBool_FromLong(st_is_aborted()); } /*** st-settings-api.h *******************************************************/ static PyObject * pst_settings_get_private_dir (PyObject *dummy, PyObject *args) { return PyString_FromString(st_settings_get_private_dir()); } static PyObject * pst_settings_get_music_dir (PyObject *dummy, PyObject *args) { return pst_string_take_string_or_null(st_settings_get_music_dir()); } /*** st-sgml-ref-api.h *******************************************************/ static PyObject * pst_sgml_ref_expand (PyObject *dummy, PyObject *args) { const char *str; if (! PyArg_ParseTuple(args, "s", &str)) return NULL; return pst_string_take_string(st_sgml_ref_expand(str)); } /*** st-transfer-api.h *******************************************************/ static PyObject * pst_transfer_escape (PyObject *dummy, PyObject *args) { const char *url; if (! PyArg_ParseTuple(args, "s", &url)) return NULL; return pst_string_take_string(st_transfer_escape(url)); } /*** st-util-api.h ***********************************************************/ static PyObject * pst_format_bitrate (PyObject *dummy, PyObject *args) { int bitrate; if (! PyArg_ParseTuple(args, "i", &bitrate)) return NULL; return pst_string_take_string(st_format_bitrate(bitrate)); } static PyObject * pst_format_samplerate (PyObject *dummy, PyObject *args) { int samplerate; if (! PyArg_ParseTuple(args, "i", &samplerate)) return NULL; return pst_string_take_string(st_format_samplerate(samplerate)); } static PyObject * pst_format_channels (PyObject *dummy, PyObject *args) { int channels; if (! PyArg_ParseTuple(args, "i", &channels)) return NULL; return pst_string_take_string(st_format_channels(channels)); } static PyObject * pst_format_audio_properties (PyObject *dummy, PyObject *args) { int bitrate; int samplerate; int channels; if (! PyArg_ParseTuple(args, "iii", &bitrate, &samplerate, &channels)) return NULL; return pst_string_take_string(st_format_audio_properties(bitrate, samplerate, channels)); } static PyObject * pst_hig_section_new (PyObject *dummy, PyObject *args) { const char *title; GtkWidget *widget; if (! PyArg_ParseTuple(args, "sO&", &title, pst_convert_widget, &widget)) return NULL; return pygobject_new(G_OBJECT(st_hig_section_new(title, widget))); } static PyObject * pst_set_tooltip (PyObject *dummy, PyObject *args) { GtkWidget *widget; const char *tooltip; if (! PyArg_ParseTuple(args, "O&z", pst_convert_widget, &widget, &tooltip)) return NULL; st_set_tooltip(widget, tooltip); return pst_none(); } /*** st-version-api.h ********************************************************/ static PyObject * pst_check_api_version (PyObject *dummy, PyObject *args) { unsigned int required_major_version; unsigned int minimum_minor_version; if (! PyArg_ParseTuple(args, "ii", &required_major_version, &minimum_minor_version)) return NULL; /* we check against the streamtuner/python API version */ return PyBool_FromLong(PST_API_MAJOR_VERSION == required_major_version && PST_API_MINOR_VERSION >= minimum_minor_version); } /*** Python-specific API *****************************************************/ static PyObject * pst_find_icon (PyObject *dummy, PyObject *args) { const char *filename; char *pathname; if (! PyArg_ParseTuple(args, "s", &filename)) return NULL; g_assert(private_icons_dir != NULL); Py_BEGIN_ALLOW_THREADS pathname = g_build_filename(ICONS_DIR, filename, NULL); if (! g_file_test(pathname, G_FILE_TEST_EXISTS)) { g_free(pathname); pathname = g_build_filename(private_icons_dir, filename, NULL); if (! g_file_test(pathname, G_FILE_TEST_EXISTS)) { g_free(pathname); pathname = NULL; } } Py_END_ALLOW_THREADS if (pathname) return pst_string_take_string(pathname); else { PyErr_Format(PyExc_RuntimeError, _("unable to find %s"), filename); return NULL; } } static PyObject * pst_gettext (PyObject *dummy, PyObject *args) { const char *msgid; if (! PyArg_ParseTuple(args, "s", &msgid)) return NULL; return PyString_FromString(gettext(msgid)); } static PyObject * pst_ngettext (PyObject *dummy, PyObject *args) { const char *msgid; const char *msgid_plural; long n; if (! PyArg_ParseTuple(args, "ssl", &msgid, &msgid_plural, &n)) return NULL; return PyString_FromString(ngettext(msgid, msgid_plural, n)); }