Don't create a separate interpreter for each script (it's not very well supported), instead create a module for each one. Redirect sys.stdout and sys.stderr to the clementine console.

This commit is contained in:
David Sansome 2011-01-02 01:07:19 +00:00
parent 11f4157f6f
commit c8d8ef208d
64 changed files with 750 additions and 168 deletions

View File

@ -294,5 +294,6 @@
<file>schema/jamendo.sql</file> <file>schema/jamendo.sql</file>
<file>schema/schema-23.sql</file> <file>schema/schema-23.sql</file>
<file>schema/schema-24.sql</file> <file>schema/schema-24.sql</file>
<file>pythonstartup.py</file>
</qresource> </qresource>
</RCC> </RCC>

20
data/pythonstartup.py Normal file
View File

@ -0,0 +1,20 @@
import clementine
import sys
class __ClementineLogger__:
def __init__(self, error):
self._error = error
self._buffer = ''
def write(self, data):
self._buffer = self._buffer + data
i = self._buffer.find('\n')
while i != -1:
line = self._buffer[0:i]
self._buffer = self._buffer[i+1:]
i = self._buffer.find('\n')
clementine.pythonengine.AddLogLine(line, self._error)
sys.stdout = __ClementineLogger__(False)
sys.stderr = __ClementineLogger__(True)

View File

@ -16,3 +16,8 @@
*/ */
#include "languageengine.h" #include "languageengine.h"
LanguageEngine::LanguageEngine(ScriptManager* manager)
: manager_(manager)
{
}

View File

@ -24,14 +24,19 @@ class Script;
class LanguageEngine { class LanguageEngine {
public: public:
LanguageEngine(ScriptManager* manager);
virtual ~LanguageEngine() {} virtual ~LanguageEngine() {}
ScriptManager* manager() const { return manager_; }
virtual ScriptManager::Language language() const = 0; virtual ScriptManager::Language language() const = 0;
virtual QString name() const = 0; virtual QString name() const = 0;
virtual void Init(const ScriptManager::GlobalData& data) = 0; virtual Script* CreateScript(const QString& path, const QString& script_file,
const QString& id) = 0;
virtual Script* CreateScript(const QString& path, const QString& script_file) = 0; private:
ScriptManager* manager_;
}; };
#endif // LANGUAGEENGINE_H #endif // LANGUAGEENGINE_H

View File

@ -6,5 +6,6 @@
%Include engine_fwd.sip %Include engine_fwd.sip
%Include player.sip %Include player.sip
%Include playlistitem.sip %Include playlistitem.sip
%Include pythonengine.sip
%Include scriptinterface.sip %Include scriptinterface.sip
%Include song.sip %Include song.sip

View File

@ -16,38 +16,97 @@
*/ */
#include <Python.h> #include <Python.h>
#include <sip.h>
#include "pythonengine.h" #include "pythonengine.h"
#include "pythonscript.h" #include "pythonscript.h"
#include "sipAPIclementine.h"
#include <QFile>
extern "C" { extern "C" {
void initclementine(); void initclementine();
} }
PythonEngine::PythonEngine() PythonEngine::PythonEngine(ScriptManager* manager)
: initialised_(false) : LanguageEngine(manager),
initialised_(false)
{ {
} }
void PythonEngine::Init(const ScriptManager::GlobalData& data) { const sipAPIDef* PythonEngine::GetSIPApi() {
data_ = data; #if defined(SIP_USE_PYCAPSULE)
return (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0);
#else
PyObject *sip_module;
PyObject *sip_module_dict;
PyObject *c_api;
/* Import the SIP module. */
sip_module = PyImport_ImportModule("sip");
if (sip_module == NULL)
return NULL;
/* Get the module's dictionary. */
sip_module_dict = PyModule_GetDict(sip_module);
/* Get the "_C_API" attribute. */
c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
if (c_api == NULL)
return NULL;
/* Sanity check that it is the right type. */
if (!PyCObject_Check(c_api))
return NULL;
/* Get the actual pointer from the object. */
return (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
#endif
} }
Script* PythonEngine::CreateScript(const QString& path, const QString& script_file) { Script* PythonEngine::CreateScript(const QString& path,
const QString& script_file,
const QString& id) {
// Initialise Python if it hasn't been done yet // Initialise Python if it hasn't been done yet
if (!initialised_) { if (!initialised_) {
AddLogLine("Initialising python...", false);
// Add the Clementine builtin module // Add the Clementine builtin module
PyImport_AppendInittab(const_cast<char*>("clementine"), initclementine); PyImport_AppendInittab(const_cast<char*>("clementine"), initclementine);
// Initialise python
Py_SetProgramName(const_cast<char*>("clementine")); Py_SetProgramName(const_cast<char*>("clementine"));
PyEval_InitThreads(); PyEval_InitThreads();
Py_InitializeEx(0); Py_InitializeEx(0);
// Get the clementine module so we can put stuff in it
clementine_module_ = PyImport_ImportModule("clementine");
sip_api_ = GetSIPApi();
// Add objects to the module
AddObject(manager()->data().player_, sipType_Player, "player");
AddObject(this, sipType_PythonEngine, "pythonengine");
// Run the startup script - this redirects sys.stdout and sys.stderr to our
// log handler.
QFile python_startup(":pythonstartup.py");
python_startup.open(QIODevice::ReadOnly);
QByteArray python_startup_script = python_startup.readAll();
if (PyRun_SimpleString(python_startup_script.constData()) != 0) {
AddLogLine("Could not execute startup code", true);
Py_Finalize();
return NULL;
}
PyEval_ReleaseLock(); PyEval_ReleaseLock();
initialised_ = true; initialised_ = true;
} }
Script* ret = new PythonScript(this, path, script_file); Script* ret = new PythonScript(this, path, script_file, id);
if (ret->Init()) { if (ret->Init()) {
return ret; return ret;
} }
@ -55,3 +114,13 @@ Script* PythonEngine::CreateScript(const QString& path, const QString& script_fi
delete ret; delete ret;
return NULL; return NULL;
} }
void PythonEngine::AddObject(void* object, const _sipTypeDef* type,
const char * name) const {
PyObject* python_object = sip_api_->api_convert_from_type(object, type, NULL);
PyModule_AddObject(clementine_module_, name, python_object);
}
void PythonEngine::AddLogLine(const QString& message, bool error) {
manager()->AddLogLine("Python", message, error);
}

View File

@ -20,22 +20,33 @@
#include "scripting/languageengine.h" #include "scripting/languageengine.h"
struct _object; // PyObject
struct _sipAPIDef;
struct _sipTypeDef;
class PythonEngine : public LanguageEngine { class PythonEngine : public LanguageEngine {
public: public:
PythonEngine(); PythonEngine(ScriptManager* manager);
ScriptManager::Language language() const { return ScriptManager::Language_Python; } ScriptManager::Language language() const { return ScriptManager::Language_Python; }
QString name() const { return "python"; } QString name() const { return "python"; }
const ScriptManager::GlobalData& data() const { return data_; } Script* CreateScript(const QString& path, const QString& script_file,
const QString& id);
void Init(const ScriptManager::GlobalData& data); const _sipAPIDef* sip_api() const { return sip_api_; }
Script* CreateScript(const QString& path, const QString& script_file);
void AddLogLine(const QString& message, bool error = false);
private: private:
ScriptManager::GlobalData data_; static const _sipAPIDef* GetSIPApi();
void AddObject(void* object, const _sipTypeDef* type, const char* name) const;
private:
bool initialised_; bool initialised_;
_object* clementine_module_;
const _sipAPIDef* sip_api_;
}; };
#endif // PYTHONENGINE_H #endif // PYTHONENGINE_H

View File

@ -0,0 +1,12 @@
class PythonEngine {
%TypeHeaderCode
#include "scripting/python/pythonengine.h"
%End
public:
void AddLogLine(const QString& message, bool error = false);
private:
PythonEngine();
};

View File

@ -26,97 +26,64 @@
#include <QtDebug> #include <QtDebug>
static const sipAPIDef* GetSIPApi() { PythonScript::PythonScript(PythonEngine* engine, const QString& path,
#if defined(SIP_USE_PYCAPSULE) const QString& script_file, const QString& id)
return (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0); : Script(engine, path, script_file, id),
#else engine_(engine)
PyObject *sip_module;
PyObject *sip_module_dict;
PyObject *c_api;
/* Import the SIP module. */
sip_module = PyImport_ImportModule("sip");
if (sip_module == NULL)
return NULL;
/* Get the module's dictionary. */
sip_module_dict = PyModule_GetDict(sip_module);
/* Get the "_C_API" attribute. */
c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
if (c_api == NULL)
return NULL;
/* Sanity check that it is the right type. */
if (!PyCObject_Check(c_api))
return NULL;
/* Get the actual pointer from the object. */
return (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
#endif
}
PythonScript::PythonScript(PythonEngine* engine,
const QString& path, const QString& script_file)
: Script(path, script_file),
engine_(engine),
interpreter_(NULL),
clementine_module_(NULL),
sip_api_(NULL)
{ {
} }
bool PythonScript::Init() { bool PythonScript::Init() {
engine_->AddLogLine("Loading script file \"" + script_file() + "\"", false);
// Open the file // Open the file
QFile file(script_file()); QFile file(script_file());
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Error opening file:" << script_file(); engine_->AddLogLine("Could not open file", true);
return false; return false;
} }
// Create a python interpreter
PyEval_AcquireLock(); PyEval_AcquireLock();
interpreter_ = Py_NewInterpreter();
// Get the clementine module so we can put stuff in it // Create a module for this script
clementine_module_ = PyImport_ImportModule("clementine"); // TODO: allowed characters?
sip_api_ = GetSIPApi(); PyObject* module = PyImport_AddModule(id().toAscii().constData());
PyObject* dict = PyModule_GetDict(module);
AddObject(engine_->data().player_, sipType_Player, "player"); // Add __builtins__
AddObject(interface(), sipType_ScriptInterface, "script"); PyObject* builtin_mod = PyImport_ImportModule("__builtin__");
PyModule_AddObject(module, "__builtins__", builtin_mod);
Py_DECREF(builtin_mod);
PyEval_ReleaseLock(); // Set __file__
PyModule_AddStringConstant(module, "__file__", script_file().toLocal8Bit().constData());
// Set script
PyObject* script = engine_->sip_api()->api_convert_from_type(
interface(), sipType_ScriptInterface, NULL);
PyModule_AddObject(module, "script", script);
// Get a file stream from the file handle // Get a file stream from the file handle
FILE* stream = fdopen(file.handle(), "r"); FILE* stream = fdopen(file.handle(), "r");
if (PyRun_SimpleFile(stream, script_file().toLocal8Bit().constData()) != 0) { // Run the script
PyEval_AcquireLock(); PyObject* result = PyRun_File(
Py_EndInterpreter(interpreter_); stream, script_file().toLocal8Bit().constData(), Py_file_input, dict, dict);
if (result == NULL) {
engine_->AddLogLine("Could not execute file", true);
PyErr_Print();
PyEval_ReleaseLock(); PyEval_ReleaseLock();
interpreter_ = NULL;
return false; return false;
} }
Py_DECREF(result);
PyEval_ReleaseLock();
return true; return true;
} }
void PythonScript::AddObject(void* object, const _sipTypeDef* type,
const char * name) const {
PyObject* python_object = sip_api_->api_convert_from_type(object, type, NULL);
PyModule_AddObject(clementine_module_, name, python_object);
}
bool PythonScript::Unload() { bool PythonScript::Unload() {
PyEval_AcquireLock(); // TODO: Actually do some cleanup
PyThreadState_Swap(interpreter_);
Py_EndInterpreter(interpreter_);
PyEval_ReleaseLock();
interpreter_ = NULL;
return true; return true;
} }

View File

@ -20,30 +20,18 @@
#include "scripting/script.h" #include "scripting/script.h"
struct _object; // PyObject
struct _sipAPIDef;
struct _sipTypeDef;
struct _ts; // PyThreadState
class PythonEngine; class PythonEngine;
class PythonScript : public Script { class PythonScript : public Script {
public: public:
PythonScript(PythonEngine* engine, PythonScript(PythonEngine* engine, const QString& path,
const QString& path, const QString& script_file); const QString& script_file, const QString& id);
bool Init(); bool Init();
bool Unload(); bool Unload();
private:
void AddObject(void* object, const _sipTypeDef* type, const char* name) const;
private: private:
PythonEngine* engine_; PythonEngine* engine_;
_ts* interpreter_;
_object* clementine_module_;
const _sipAPIDef* sip_api_;
}; };
#endif // PYTHONSCRIPT_H #endif // PYTHONSCRIPT_H

View File

@ -18,10 +18,13 @@
#include "script.h" #include "script.h"
#include "scriptinterface.h" #include "scriptinterface.h"
Script::Script(const QString& path, const QString& script_file) Script::Script(LanguageEngine* language, const QString& path,
: interface_(new ScriptInterface), const QString& script_file, const QString& id)
: interface_(new ScriptInterface(this)),
language_(language),
path_(path), path_(path),
script_file_(script_file) script_file_(script_file),
id_(id)
{ {
} }

View File

@ -22,16 +22,19 @@
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
class LanguageEngine;
class ScriptInterface; class ScriptInterface;
class Script { class Script {
public: public:
Script(const QString& path, const QString& script_file); Script(LanguageEngine* language, const QString& path,
const QString& script_file, const QString& id);
virtual ~Script(); virtual ~Script();
LanguageEngine* language() const { return language_; }
const QString& path() const { return path_; } const QString& path() const { return path_; }
const QString& script_file() const { return script_file_; } const QString& script_file() const { return script_file_; }
const QString& id() const { return id_; }
ScriptInterface* interface() const { return interface_.get(); } ScriptInterface* interface() const { return interface_.get(); }
virtual bool Init() = 0; virtual bool Init() = 0;
@ -43,8 +46,10 @@ protected:
private: private:
Q_DISABLE_COPY(Script); Q_DISABLE_COPY(Script);
LanguageEngine* language_;
QString path_; QString path_;
QString script_file_; QString script_file_;
QString id_;
}; };
#endif // SCRIPT_H #endif // SCRIPT_H

View File

@ -112,8 +112,13 @@ void ScriptDialog::SetManager(ScriptManager* manager) {
connect(manager, SIGNAL(dataChanged(QModelIndex,QModelIndex)), connect(manager, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
SLOT(DataChanged(QModelIndex,QModelIndex))); SLOT(DataChanged(QModelIndex,QModelIndex)));
connect(manager, SIGNAL(LogLineAdded(QString)), SLOT(LogLineAdded(QString)));
connect(ui_->list->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), connect(ui_->list->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
SLOT(CurrentChanged(QModelIndex))); SLOT(CurrentChanged(QModelIndex)));
foreach (const QString& html, manager->log_lines()) {
LogLineAdded(html);
}
} }
void ScriptDialog::CurrentChanged(const QModelIndex& index) { void ScriptDialog::CurrentChanged(const QModelIndex& index) {
@ -151,3 +156,7 @@ void ScriptDialog::Settings() {
void ScriptDialog::Details() { void ScriptDialog::Details() {
} }
void ScriptDialog::LogLineAdded(const QString& html) {
ui_->console->append(html);
}

View File

@ -59,6 +59,7 @@ public:
private slots: private slots:
void DataChanged(const QModelIndex& top_left, const QModelIndex& bottom_right); void DataChanged(const QModelIndex& top_left, const QModelIndex& bottom_right);
void CurrentChanged(const QModelIndex& index); void CurrentChanged(const QModelIndex& index);
void LogLineAdded(const QString& html);
void Enable(); void Enable();
void Disable(); void Disable();

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>645</width> <width>718</width>
<height>388</height> <height>447</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -15,68 +15,100 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <widget class="QTabWidget" name="tabWidget">
<item> <property name="currentIndex">
<widget class="QListView" name="list"/> <number>2</number>
</item> </property>
<item> <widget class="QWidget" name="tab">
<layout class="QVBoxLayout" name="verticalLayout"> <attribute name="title">
<string>My scripts</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QPushButton" name="enable"> <widget class="QListView" name="list"/>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Enable</string>
</property>
</widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="disable"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="enabled"> <item>
<bool>false</bool> <widget class="QPushButton" name="enable">
</property> <property name="enabled">
<property name="text"> <bool>false</bool>
<string>Disable</string> </property>
</property> <property name="text">
</widget> <string>Enable</string>
</item> </property>
<item> </widget>
<widget class="QPushButton" name="settings"> </item>
<property name="enabled"> <item>
<bool>false</bool> <widget class="QPushButton" name="disable">
</property> <property name="enabled">
<property name="text"> <bool>false</bool>
<string>Settings...</string> </property>
</property> <property name="text">
</widget> <string>Disable</string>
</item> </property>
<item> </widget>
<widget class="QPushButton" name="details"> </item>
<property name="enabled"> <item>
<bool>false</bool> <widget class="QPushButton" name="settings">
</property> <property name="enabled">
<property name="text"> <bool>false</bool>
<string>Details...</string> </property>
</property> <property name="text">
</widget> <string>Settings...</string>
</item> </property>
<item> </widget>
<spacer name="verticalSpacer"> </item>
<property name="orientation"> <item>
<enum>Qt::Vertical</enum> <widget class="QPushButton" name="details">
</property> <property name="enabled">
<property name="sizeHint" stdset="0"> <bool>false</bool>
<size> </property>
<width>20</width> <property name="text">
<height>40</height> <string>Details...</string>
</size> </property>
</property> </widget>
</spacer> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
</layout> </layout>
</item> </widget>
</layout> <widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Get new scripts</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Script console</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTextEdit" name="console">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item> </item>
<item> <item>
<widget class="QDialogButtonBox" name="button_box"> <widget class="QDialogButtonBox" name="button_box">

View File

@ -15,13 +15,20 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "languageengine.h"
#include "script.h"
#include "scriptinterface.h" #include "scriptinterface.h"
ScriptInterface::ScriptInterface(QObject* parent) ScriptInterface::ScriptInterface(Script* script, QObject* parent)
: QObject(parent) : QObject(parent),
script_(script)
{ {
} }
void ScriptInterface::ShowSettingsDialog() { void ScriptInterface::ShowSettingsDialog() {
emit SettingsDialogRequested(); emit SettingsDialogRequested();
} }
void ScriptInterface::AddLogLine(const QString& message, bool error) {
script_->language()->manager()->AddLogLine(script_->id(), message, error);
}

View File

@ -20,20 +20,30 @@
#include <QObject> #include <QObject>
#include <cstdlib>
class Script;
// An instance of this class is made available to each script // An instance of this class is made available to each script
class ScriptInterface : public QObject { class ScriptInterface : public QObject {
Q_OBJECT Q_OBJECT
public: public:
ScriptInterface(QObject* parent = 0); ScriptInterface(Script* script, QObject* parent = 0);
public slots: public slots:
// Callable by C++ // Callable by C++
void ShowSettingsDialog(); void ShowSettingsDialog();
// Callable by the script
void AddLogLine(const QString& message, bool error = false);
signals: signals:
// Scripts should connect to this and show a settings dialog // Scripts should connect to this and show a settings dialog
void SettingsDialogRequested(); void SettingsDialogRequested();
private:
Script* script_;
}; };
#endif // SCRIPTINTERFACE_H #endif // SCRIPTINTERFACE_H

View File

@ -28,6 +28,7 @@
#include <QDirIterator> #include <QDirIterator>
#include <QSettings> #include <QSettings>
#include <QTextDocument>
#include <QtDebug> #include <QtDebug>
const char* ScriptManager::kSettingsGroup = "Scripts"; const char* ScriptManager::kSettingsGroup = "Scripts";
@ -35,11 +36,10 @@ const char* ScriptManager::kIniFileName = "script.ini";
const char* ScriptManager::kIniSettingsGroup = "Script"; const char* ScriptManager::kIniSettingsGroup = "Script";
ScriptManager::ScriptManager(QObject* parent) ScriptManager::ScriptManager(QObject* parent)
: QAbstractListModel(parent), : QAbstractListModel(parent)
player_(NULL)
{ {
#ifdef HAVE_SCRIPTING_PYTHON #ifdef HAVE_SCRIPTING_PYTHON
engines_ << new PythonEngine; engines_ << new PythonEngine(this);
#endif #endif
search_paths_ << Utilities::GetConfigPath(Utilities::Path_Scripts); search_paths_ << Utilities::GetConfigPath(Utilities::Path_Scripts);
@ -57,9 +57,7 @@ ScriptManager::~ScriptManager() {
} }
void ScriptManager::Init(const GlobalData& data) { void ScriptManager::Init(const GlobalData& data) {
foreach (LanguageEngine* engine, engines_) { data_ = data;
engine->Init(data);
}
// Load settings // Load settings
LoadSettings(); LoadSettings();
@ -158,7 +156,7 @@ ScriptManager::ScriptInfo ScriptManager::LoadScriptInfo(const QString& path) {
if (enabled_scripts_.contains(id)) { if (enabled_scripts_.contains(id)) {
// Load the script if it's enabled // Load the script if it's enabled
ret.loaded_ = engine->CreateScript(path, ret.script_file_); ret.loaded_ = engine->CreateScript(path, ret.script_file_, ret.id_);
if (!ret.loaded_) { if (!ret.loaded_) {
// Failed to load? Disable it so we don't try again // Failed to load? Disable it so we don't try again
enabled_scripts_.remove(id); enabled_scripts_.remove(id);
@ -227,7 +225,7 @@ void ScriptManager::Enable(const QModelIndex& index) {
} }
// Load the script // Load the script
info->loaded_ = engine->CreateScript(info->path_, info->script_file_); info->loaded_ = engine->CreateScript(info->path_, info->script_file_, info->id_);
// If it loaded correctly then automatically load it in the future // If it loaded correctly then automatically load it in the future
if (info->loaded_) { if (info->loaded_) {
@ -266,3 +264,20 @@ void ScriptManager::ShowSettingsDialog(const QModelIndex& index) {
info->loaded_->interface()->ShowSettingsDialog(); info->loaded_->interface()->ShowSettingsDialog();
} }
void ScriptManager::AddLogLine(const QString& who, const QString& message, bool error) {
foreach (const QString& line, message.split("\n", QString::SkipEmptyParts)) {
QString plain = "[" + who + "] " + line;
QString html = "<b>[" + Qt::escape(who) + "]</b> " + Qt::escape(line);
html.replace(' ', "&nbsp;");
if (error) {
html = "<font color=\"red\">" + html + "</font>";
}
log_lines_ << html;
emit LogLineAdded(html);
qDebug() << plain.toLocal8Bit().constData();
}
}

View File

@ -62,15 +62,24 @@ public:
static const char* kIniSettingsGroup; static const char* kIniSettingsGroup;
void Init(const GlobalData& data); void Init(const GlobalData& data);
const GlobalData& data() const { return data_; }
void Enable(const QModelIndex& index); void Enable(const QModelIndex& index);
void Disable(const QModelIndex& index); void Disable(const QModelIndex& index);
void ShowSettingsDialog(const QModelIndex& index); void ShowSettingsDialog(const QModelIndex& index);
QStringList log_lines() const { return log_lines_; }
// QAbstractListModel // QAbstractListModel
int rowCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex& index, int role) const; QVariant data(const QModelIndex& index, int role) const;
public slots:
void AddLogLine(const QString& who, const QString& message, bool error);
signals:
void LogLineAdded(const QString& html);
private: private:
struct ScriptInfo { struct ScriptInfo {
ScriptInfo() : language_(Language_Unknown), loaded_(NULL) {} ScriptInfo() : language_(Language_Unknown), loaded_(NULL) {}
@ -101,14 +110,21 @@ private:
LanguageEngine* EngineForLanguage(Language language) const; LanguageEngine* EngineForLanguage(Language language) const;
private: private:
// Language engines
QList<LanguageEngine*> engines_; QList<LanguageEngine*> engines_;
// All scripts we know about
QStringList search_paths_; QStringList search_paths_;
QList<ScriptInfo> info_; QList<ScriptInfo> info_;
// Names of scripts that get loaded automatically
QSet<QString> enabled_scripts_; QSet<QString> enabled_scripts_;
Player* player_; // HTML log messages
QStringList log_lines_;
// Things available to scripts
GlobalData data_;
}; };
#endif // SCRIPTMANAGER_H #endif // SCRIPTMANAGER_H

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "النوع" msgstr "النوع"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1048,6 +1048,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1450,6 +1453,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1911,6 +1917,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1036,6 +1036,9 @@ msgstr "Общи настройки"
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1440,6 +1443,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Име" msgstr "Име"
@ -1901,6 +1907,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1065,6 +1065,9 @@ msgstr "Arranjaments generals"
msgid "Genre" msgid "Genre"
msgstr "Gènere" msgstr "Gènere"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Obtenint canals" msgstr "Obtenint canals"
@ -1472,6 +1475,9 @@ msgstr "La meva emissora de ràdio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Les meves recomanacions" msgstr "Les meves recomanacions"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
@ -1935,6 +1941,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1061,6 +1061,9 @@ msgstr "Obecná nastavení"
msgid "Genre" msgid "Genre"
msgstr "Žánr" msgstr "Žánr"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Získávají se kanály" msgstr "Získávají se kanály"
@ -1473,6 +1476,9 @@ msgstr "Moje rozhlasová stanice"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Má doporučení" msgstr "Má doporučení"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Název" msgstr "Název"
@ -1936,6 +1942,9 @@ msgstr "Výsledek"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Se skladbami, které poslouchám, dělat to, čemu se říká \"scrobble\"" msgstr "Se skladbami, které poslouchám, dělat to, čemu se říká \"scrobble\""

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1037,6 +1037,9 @@ msgstr "Generelle indstillinger"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Henter kanaler" msgstr "Henter kanaler"
@ -1441,6 +1444,9 @@ msgstr "Min radiostation"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Mine anbefalinger" msgstr "Mine anbefalinger"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Navn" msgstr "Navn"
@ -1902,6 +1908,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Scrobble-spor som jeg lytter til" msgstr "Scrobble-spor som jeg lytter til"

View File

@ -1064,6 +1064,9 @@ msgstr "Allgemeine Einstellungen"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Lade Channels" msgstr "Lade Channels"
@ -1476,6 +1479,9 @@ msgstr "Meine Radiostation"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Meine Empfehlungen" msgstr "Meine Empfehlungen"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
@ -1939,6 +1945,9 @@ msgstr "Bewertung"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Stücke die ich höre \"scrobbeln\"" msgstr "Stücke die ich höre \"scrobbeln\""

View File

@ -1071,6 +1071,9 @@ msgstr "Γενικές ρυθμίσεις"
msgid "Genre" msgid "Genre"
msgstr "Είδος" msgstr "Είδος"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Λήψη καναλιών" msgstr "Λήψη καναλιών"
@ -1481,6 +1484,9 @@ msgstr "Οι Σταθμοί μου"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Οι Προτάσεις μου" msgstr "Οι Προτάσεις μου"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Όνομα" msgstr "Όνομα"
@ -1946,6 +1952,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Κάνε \"srobble\" τα κομμάτια που ακούω" msgstr "Κάνε \"srobble\" τα κομμάτια που ακούω"

View File

@ -1023,6 +1023,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1425,6 +1428,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1886,6 +1892,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1037,6 +1037,9 @@ msgstr "General settings"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Getting channels" msgstr "Getting channels"
@ -1440,6 +1443,9 @@ msgstr "My Radio Station"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "My Recommendations" msgstr "My Recommendations"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
@ -1902,6 +1908,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Scrobble tracks that I listen to" msgstr "Scrobble tracks that I listen to"

View File

@ -1035,6 +1035,9 @@ msgstr "General settings"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Getting channels" msgstr "Getting channels"
@ -1438,6 +1441,9 @@ msgstr "My Radio Station"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "My Recommendations" msgstr "My Recommendations"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
@ -1899,6 +1905,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Scrobble tracks that I listen to" msgstr "Scrobble tracks that I listen to"

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1069,6 +1069,9 @@ msgstr "Preferencias generales"
msgid "Genre" msgid "Genre"
msgstr "Género" msgstr "Género"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Obteniendo canales" msgstr "Obteniendo canales"
@ -1482,6 +1485,9 @@ msgstr "Mi Estación de Radio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Mis Recomendaciones" msgstr "Mis Recomendaciones"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nombre" msgstr "Nombre"
@ -1947,6 +1953,9 @@ msgstr "Puntuación"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Enviar las pistas que reproduzco" msgstr "Enviar las pistas que reproduzco"

View File

@ -1035,6 +1035,9 @@ msgstr "Üldised seadistused"
msgid "Genre" msgid "Genre"
msgstr "Žanr" msgstr "Žanr"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1438,6 +1441,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nimi" msgstr "Nimi"
@ -1899,6 +1905,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1034,6 +1034,9 @@ msgstr "Yleiset asetukset"
msgid "Genre" msgid "Genre"
msgstr "Tyylilaji" msgstr "Tyylilaji"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1438,6 +1441,9 @@ msgstr "Oma radioasemani"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Omat suositukseni" msgstr "Omat suositukseni"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nimi" msgstr "Nimi"
@ -1899,6 +1905,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1073,6 +1073,9 @@ msgstr "Configuration générale"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Récupération des canaux" msgstr "Récupération des canaux"
@ -1487,6 +1490,9 @@ msgstr "Ma station de radio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Mes suggestions" msgstr "Mes suggestions"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
@ -1952,6 +1958,9 @@ msgstr "Score"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Envoyer les titres des pistes que j'écoute (scrobble)" msgstr "Envoyer les titres des pistes que j'écoute (scrobble)"

View File

@ -1038,6 +1038,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Xénero" msgstr "Xénero"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Obter canais" msgstr "Obter canais"
@ -1442,6 +1445,9 @@ msgstr "A Miña Emisora"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "As miñas recomendazóns" msgstr "As miñas recomendazóns"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nome" msgstr "Nome"
@ -1903,6 +1909,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1038,6 +1038,9 @@ msgstr "הגדרות כלליות"
msgid "Genre" msgid "Genre"
msgstr "סגנון" msgstr "סגנון"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "מקבל ערוצים" msgstr "מקבל ערוצים"
@ -1443,6 +1446,9 @@ msgstr "תחנת הרדיו שלי"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "ההמלצות שלי" msgstr "ההמלצות שלי"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "שם" msgstr "שם"
@ -1905,6 +1911,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1040,6 +1040,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1442,6 +1445,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1903,6 +1909,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1062,6 +1062,9 @@ msgstr "Általános beállítások"
msgid "Genre" msgid "Genre"
msgstr "Műfaj" msgstr "Műfaj"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Csatornák betöltése" msgstr "Csatornák betöltése"
@ -1472,6 +1475,9 @@ msgstr "A rádióadóm"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Ajánlásaim" msgstr "Ajánlásaim"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Név" msgstr "Név"
@ -1935,6 +1941,9 @@ msgstr "Pontszám"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Az általam hallgatott számok Scrobble funkcióval történő figyelése" msgstr "Az általam hallgatott számok Scrobble funkcióval történő figyelése"

View File

@ -1066,6 +1066,9 @@ msgstr "Impostazioni generali"
msgid "Genre" msgid "Genre"
msgstr "Genere" msgstr "Genere"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Recupero dei canali" msgstr "Recupero dei canali"
@ -1479,6 +1482,9 @@ msgstr "La mia stazione radio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "I miei consigli" msgstr "I miei consigli"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nome" msgstr "Nome"
@ -1943,6 +1949,9 @@ msgstr "Punteggio"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Scrobbling delle tracce ascoltate" msgstr "Scrobbling delle tracce ascoltate"

View File

@ -1055,6 +1055,9 @@ msgstr "全般設定"
msgid "Genre" msgid "Genre"
msgstr "ジャンル" msgstr "ジャンル"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "チャンネルの取得中" msgstr "チャンネルの取得中"
@ -1462,6 +1465,9 @@ msgstr "ラジオ局"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "おすすめ" msgstr "おすすめ"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "名前" msgstr "名前"
@ -1925,6 +1931,9 @@ msgstr "スコア"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "聴取するトラックを Scrobble する" msgstr "聴取するトラックを Scrobble する"

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "Жанры" msgstr "Жанры"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1438,6 +1441,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Аты" msgstr "Аты"
@ -1899,6 +1905,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1034,6 +1034,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1046,6 +1046,9 @@ msgstr "Generelle innstillinger"
msgid "Genre" msgid "Genre"
msgstr "Sjanger" msgstr "Sjanger"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Henter kanaler" msgstr "Henter kanaler"
@ -1450,6 +1453,9 @@ msgstr "Min radiostasjon"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Mine anbefalinger" msgstr "Mine anbefalinger"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Navn" msgstr "Navn"
@ -1911,6 +1917,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Fortell last.fm om sangene jeg har lyttet til" msgstr "Fortell last.fm om sangene jeg har lyttet til"

View File

@ -1057,6 +1057,9 @@ msgstr "Algemene instellingen"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Kanalen ophalen" msgstr "Kanalen ophalen"
@ -1465,6 +1468,9 @@ msgstr "Mijn radiostation"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Mijn aanbevelingen" msgstr "Mijn aanbevelingen"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Naam" msgstr "Naam"
@ -1930,6 +1936,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Scrobble de tracks waar ik naar luister" msgstr "Scrobble de tracks waar ik naar luister"

View File

@ -1034,6 +1034,9 @@ msgstr "Paramètres generals"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1436,6 +1439,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
@ -1897,6 +1903,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1059,6 +1059,9 @@ msgstr "Podstawowe ustawienia"
msgid "Genre" msgid "Genre"
msgstr "Gatunek" msgstr "Gatunek"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Pobieranie kanałów" msgstr "Pobieranie kanałów"
@ -1466,6 +1469,9 @@ msgstr "Moje stacje radiowe"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Moje rekomendacje" msgstr "Moje rekomendacje"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nazwa" msgstr "Nazwa"
@ -1930,6 +1936,9 @@ msgstr "Wynik"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Wysyłaj informacje o utworach których słucham" msgstr "Wysyłaj informacje o utworach których słucham"

View File

@ -1066,6 +1066,9 @@ msgstr "Definições gerais"
msgid "Genre" msgid "Genre"
msgstr "Género" msgstr "Género"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Obtendo canais" msgstr "Obtendo canais"
@ -1476,6 +1479,9 @@ msgstr "A minha estação de rádio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "As minhas recomendações" msgstr "As minhas recomendações"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nome" msgstr "Nome"
@ -1940,6 +1946,9 @@ msgstr "Pontuação"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Enviar as faixas que eu oiço" msgstr "Enviar as faixas que eu oiço"

View File

@ -1059,6 +1059,9 @@ msgstr "Configurações gerais"
msgid "Genre" msgid "Genre"
msgstr "Gênero" msgstr "Gênero"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Adquirindo canais" msgstr "Adquirindo canais"
@ -1471,6 +1474,9 @@ msgstr "Minha Estação de Rádio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Minhas Recomendações" msgstr "Minhas Recomendações"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nome" msgstr "Nome"
@ -1936,6 +1942,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Adicionar ao meu perfil os dados das músicas que eu ouvir" msgstr "Adicionar ao meu perfil os dados das músicas que eu ouvir"

View File

@ -1034,6 +1034,9 @@ msgstr "Setări generale"
msgid "Genre" msgid "Genre"
msgstr "Gen" msgstr "Gen"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Se preiau canalele" msgstr "Se preiau canalele"
@ -1437,6 +1440,9 @@ msgstr "Postul meu de radio"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Recomandările mele" msgstr "Recomandările mele"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Nume" msgstr "Nume"
@ -1898,6 +1904,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1057,6 +1057,9 @@ msgstr "Общие настройки"
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Получение каналов" msgstr "Получение каналов"
@ -1467,6 +1470,9 @@ msgstr "Моя радиостанция"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Мои рекомендации" msgstr "Мои рекомендации"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Имя" msgstr "Имя"
@ -1930,6 +1936,9 @@ msgstr "Счет"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Скробблить треки, которые я слушаю" msgstr "Скробблить треки, которые я слушаю"

View File

@ -1056,6 +1056,9 @@ msgstr "Všeobecné nastavenia"
msgid "Genre" msgid "Genre"
msgstr "Žáner" msgstr "Žáner"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Preberanie kanálov" msgstr "Preberanie kanálov"
@ -1464,6 +1467,9 @@ msgstr "Moje rádio stanice"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Moje odporúčania" msgstr "Moje odporúčania"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Názov" msgstr "Názov"
@ -1926,6 +1932,9 @@ msgstr "Skóre"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Skrobblovať skladby, ktoré počúvam" msgstr "Skrobblovať skladby, ktoré počúvam"

View File

@ -1058,6 +1058,9 @@ msgstr "Splošne nastavitve"
msgid "Genre" msgid "Genre"
msgstr "Zvrst" msgstr "Zvrst"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Pridobivanje kanalov" msgstr "Pridobivanje kanalov"
@ -1466,6 +1469,9 @@ msgstr "Moja radijska postaja"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Moja priporočila" msgstr "Moja priporočila"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Ime" msgstr "Ime"
@ -1929,6 +1935,9 @@ msgstr "Rezultat"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Pošlji podatke o predvajanih skladbah" msgstr "Pošlji podatke o predvajanih skladbah"

View File

@ -1037,6 +1037,9 @@ msgstr "Опште поставке"
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Добављање канала" msgstr "Добављање канала"
@ -1441,6 +1444,9 @@ msgstr "Моја радио станица"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Моје препоруке" msgstr "Моје препоруке"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Име" msgstr "Име"
@ -1902,6 +1908,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1062,6 +1062,9 @@ msgstr "Allmänna inställningar"
msgid "Genre" msgid "Genre"
msgstr "Genre" msgstr "Genre"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Hämtar kanaler" msgstr "Hämtar kanaler"
@ -1470,6 +1473,9 @@ msgstr "Min radiostation"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Mina rekommendationer" msgstr "Mina rekommendationer"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Namn" msgstr "Namn"
@ -1931,6 +1937,9 @@ msgstr "Poäng"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Skrobbla låtar som jag lyssnar på" msgstr "Skrobbla låtar som jag lyssnar på"

View File

@ -1055,6 +1055,9 @@ msgstr "Genel ayarlar"
msgid "Genre" msgid "Genre"
msgstr "Tür" msgstr "Tür"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Kanallar alınıyor" msgstr "Kanallar alınıyor"
@ -1466,6 +1469,9 @@ msgstr "Radyom"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Önerdiklerim" msgstr "Önerdiklerim"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "İsim" msgstr "İsim"
@ -1929,6 +1935,9 @@ msgstr "Puan"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Dinlediğim parçaları skropla" msgstr "Dinlediğim parçaları skropla"

View File

@ -1024,6 +1024,9 @@ msgstr ""
msgid "Genre" msgid "Genre"
msgstr "" msgstr ""
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1426,6 +1429,9 @@ msgstr ""
msgid "My Recommendations" msgid "My Recommendations"
msgstr "" msgstr ""
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1887,6 +1893,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1058,6 +1058,9 @@ msgstr "Загальні налаштування"
msgid "Genre" msgid "Genre"
msgstr "Жанр" msgstr "Жанр"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "Отримання каналів" msgstr "Отримання каналів"
@ -1468,6 +1471,9 @@ msgstr "Моя радіостанція"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "Мої рекомендації" msgstr "Мої рекомендації"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "Назва" msgstr "Назва"
@ -1931,6 +1937,9 @@ msgstr "Рахунок"
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "Скробблити доріжки, які я слухаю" msgstr "Скробблити доріжки, які я слухаю"

View File

@ -1036,6 +1036,9 @@ msgstr "常规设置"
msgid "Genre" msgid "Genre"
msgstr "流派" msgstr "流派"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1440,6 +1443,9 @@ msgstr "我的电台"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "我的推荐" msgstr "我的推荐"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -1901,6 +1907,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""

View File

@ -1038,6 +1038,9 @@ msgstr "一般設定"
msgid "Genre" msgid "Genre"
msgstr "風格" msgstr "風格"
msgid "Get new scripts"
msgstr ""
msgid "Getting channels" msgid "Getting channels"
msgstr "" msgstr ""
@ -1441,6 +1444,9 @@ msgstr "我的廣播站"
msgid "My Recommendations" msgid "My Recommendations"
msgstr "我推薦的電台" msgstr "我推薦的電台"
msgid "My scripts"
msgstr ""
msgid "Name" msgid "Name"
msgstr "名稱" msgstr "名稱"
@ -1902,6 +1908,9 @@ msgstr ""
msgid "Script Manager" msgid "Script Manager"
msgstr "" msgstr ""
msgid "Script console"
msgstr ""
msgid "Scrobble tracks that I listen to" msgid "Scrobble tracks that I listen to"
msgstr "" msgstr ""