aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Carroll <thecarrolls@jiminger.com>2011-04-10 20:04:26 -0400
committerJim Carroll <thecarrolls@jiminger.com>2011-04-14 10:04:46 -0400
commitcd2c9beccae22cbb1b7a4f43599a1a6f7eb8c094 (patch)
tree15eb85758b671170db2b43b3c54bcdce6516f1cd
parent6391cc510f4bba95fab79575246aa83003cdacaa (diff)
The Addon constructor will now check the version of the xbmc python api that the script is dependent upon and will only apply the backward compatibility hack if the version is 1.0 or less. Otherwise it will assume the script has been updated for eden and will not try to get the id from the addon.xml file as a recovery from a failed Addon instantiation.
-rw-r--r--xbmc/Application.cpp2
-rw-r--r--xbmc/ApplicationMessenger.cpp2
-rw-r--r--xbmc/addons/Service.cpp2
-rw-r--r--xbmc/filesystem/PluginDirectory.cpp4
-rw-r--r--xbmc/interfaces/Builtins.cpp2
-rw-r--r--xbmc/interfaces/python/XBPyThread.cpp28
-rw-r--r--xbmc/interfaces/python/XBPyThread.h5
-rw-r--r--xbmc/interfaces/python/XBPython.cpp10
-rw-r--r--xbmc/interfaces/python/XBPython.h5
-rw-r--r--xbmc/interfaces/python/xbmcmodule/PythonAddon.cpp55
-rw-r--r--xbmc/windows/GUIMediaWindow.cpp2
-rw-r--r--xbmc/windows/GUIWindowFileManager.cpp2
-rw-r--r--xbmc/windows/GUIWindowWeather.cpp2
13 files changed, 93 insertions, 28 deletions
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 07ef456876..4c24c0e89a 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -4651,7 +4651,7 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr)
#ifdef HAS_PYTHON
if (item.IsPythonScript())
{ // a python script
- g_pythonParser.evalFile(item.m_strPath.c_str(),NULL);
+ g_pythonParser.evalFile(item.m_strPath.c_str(),ADDON::AddonPtr());
}
else
#endif
diff --git a/xbmc/ApplicationMessenger.cpp b/xbmc/ApplicationMessenger.cpp
index 0f700a752a..cb90cf8892 100644
--- a/xbmc/ApplicationMessenger.cpp
+++ b/xbmc/ApplicationMessenger.cpp
@@ -505,7 +505,7 @@ case TMSG_POWERDOWN:
case TMSG_EXECUTE_SCRIPT:
#ifdef HAS_PYTHON
- g_pythonParser.evalFile(pMsg->strParam.c_str(),NULL);
+ g_pythonParser.evalFile(pMsg->strParam.c_str(),ADDON::AddonPtr());
#endif
break;
diff --git a/xbmc/addons/Service.cpp b/xbmc/addons/Service.cpp
index 0f61d8fe03..d054be1a1c 100644
--- a/xbmc/addons/Service.cpp
+++ b/xbmc/addons/Service.cpp
@@ -50,7 +50,7 @@ bool CService::Start()
{
#ifdef HAS_PYTHON
case PYTHON:
- ret = (g_pythonParser.evalFile(LibPath(),ID()) != -1);
+ ret = (g_pythonParser.evalFile(LibPath(),ADDON::AddonPtr(this)) != -1);
break;
#endif
diff --git a/xbmc/filesystem/PluginDirectory.cpp b/xbmc/filesystem/PluginDirectory.cpp
index 9638b1adad..53e025e0ae 100644
--- a/xbmc/filesystem/PluginDirectory.cpp
+++ b/xbmc/filesystem/PluginDirectory.cpp
@@ -117,7 +117,7 @@ bool CPluginDirectory::StartScript(const CStdString& strPath, bool retrievingDir
bool success = false;
#ifdef HAS_PYTHON
CStdString file = m_addon->LibPath();
- if (g_pythonParser.evalFile(file, argv,m_addon->ID().c_str()) >= 0)
+ if (g_pythonParser.evalFile(file, argv,m_addon) >= 0)
{ // wait for our script to finish
CStdString scriptName = m_addon->Name();
success = WaitOnScriptResult(file, scriptName, retrievingDir);
@@ -434,7 +434,7 @@ bool CPluginDirectory::RunScriptWithParams(const CStdString& strPath)
// run the script
#ifdef HAS_PYTHON
CLog::Log(LOGDEBUG, "%s - calling plugin %s('%s','%s','%s')", __FUNCTION__, addon->Name().c_str(), argv[0].c_str(), argv[1].c_str(), argv[2].c_str());
- if (g_pythonParser.evalFile(addon->LibPath(), argv,addon->ID().c_str()) >= 0)
+ if (g_pythonParser.evalFile(addon->LibPath(), argv,addon) >= 0)
return true;
else
#endif
diff --git a/xbmc/interfaces/Builtins.cpp b/xbmc/interfaces/Builtins.cpp
index 33bcc3a833..99738e434d 100644
--- a/xbmc/interfaces/Builtins.cpp
+++ b/xbmc/interfaces/Builtins.cpp
@@ -375,7 +375,7 @@ int CBuiltins::Execute(const CStdString& execString)
if (CAddonMgr::Get().GetAddon(params[0], script))
scriptpath = script->LibPath();
- g_pythonParser.evalFile(scriptpath, argv,script->ID());
+ g_pythonParser.evalFile(scriptpath, argv,script);
}
}
#endif
diff --git a/xbmc/interfaces/python/XBPyThread.cpp b/xbmc/interfaces/python/XBPyThread.cpp
index ef01e0c19c..0d4f0b8162 100644
--- a/xbmc/interfaces/python/XBPyThread.cpp
+++ b/xbmc/interfaces/python/XBPyThread.cpp
@@ -36,6 +36,7 @@
#include "threads/SingleLock.h"
#include "utils/URIUtils.h"
#include "addons/AddonManager.h"
+#include "addons/Addon.h"
#include "XBPyThread.h"
#include "XBPython.h"
@@ -127,6 +128,22 @@ void XBPyThread::OnStartup()
CThread::SetName("Python Thread");
}
+static CStdString getXbmcApiVersionDependency(ADDON::AddonPtr addon)
+{
+ const ADDON::ADDONDEPS &deps = addon->GetDeps();
+ ADDON::ADDONDEPS::const_iterator it;
+ CStdString key("xbmc.python");
+ CStdString version("1.0");
+ it = deps.find(key);
+ if (!(it == deps.end()))
+ {
+ const ADDON::AddonVersion * xbmcApiVersion = &(it->second.first);
+ version = xbmcApiVersion->c_str();
+ }
+
+ return version;
+}
+
void XBPyThread::Process()
{
CLog::Log(LOGDEBUG,"Python thread: start processing");
@@ -233,11 +250,16 @@ void XBPyThread::Process()
{
PyObject *f = PyString_FromString(_P(m_source).c_str());
PyDict_SetItemString(moduleDict, "__file__", f);
- if (addonid)
+ if (addon.get() != NULL)
{
- PyObject *pyaddonid = PyString_FromString(addonid.c_str());
+ PyObject *pyaddonid = PyString_FromString(addon->ID().c_str());
PyDict_SetItemString(moduleDict, "__xbmcaddonid__", pyaddonid);
- CLog::Log(LOGDEBUG,"Instantiating addon using automatically obtained id of \"%s\"",addonid.c_str());
+
+ CStdString version = getXbmcApiVersionDependency(addon);
+ PyObject *pyxbmcapiversion = PyString_FromString(version.c_str());
+ PyDict_SetItemString(moduleDict, "__xbmcapiversion__", pyxbmcapiversion);
+
+ CLog::Log(LOGDEBUG,"Instantiating addon using automatically obtained id of \"%s\" dependent on version %s of the xbmc.python api",addon->ID().c_str(),version.c_str());
}
Py_DECREF(f);
PyRun_FileExFlags(fp, _P(m_source).c_str(), m_Py_file_input, moduleDict, moduleDict,1,NULL);
diff --git a/xbmc/interfaces/python/XBPyThread.h b/xbmc/interfaces/python/XBPyThread.h
index cacb9236df..630ac27738 100644
--- a/xbmc/interfaces/python/XBPyThread.h
+++ b/xbmc/interfaces/python/XBPyThread.h
@@ -23,6 +23,7 @@
#define XBPYTHREAD_H_
#include "threads/Thread.h"
+#include "addons/IAddon.h"
class XBPython;
@@ -37,7 +38,7 @@ public:
bool isStopping();
void stop();
- void setAddonId(const char* _addonid) { addonid = _addonid; }
+ void setAddon(ADDON::AddonPtr _addon) { addon = _addon; }
protected:
XBPython *m_pExecuter;
@@ -49,7 +50,7 @@ protected:
unsigned int m_argc;
bool m_stopping;
int m_id;
- CStdString addonid;
+ ADDON::AddonPtr addon;
virtual void OnStartup();
virtual void Process();
diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp
index 008eae9fe4..e44e7ad7a6 100644
--- a/xbmc/interfaces/python/XBPython.cpp
+++ b/xbmc/interfaces/python/XBPython.cpp
@@ -429,7 +429,7 @@ void XBPython::Process()
CStdString strAutoExecPy = _P("special://profile/autoexec.py");
if ( XFILE::CFile::Exists(strAutoExecPy) )
- evalFile(strAutoExecPy,NULL);
+ evalFile(strAutoExecPy,ADDON::AddonPtr());
else
CLog::Log(LOGDEBUG, "%s - no profile autoexec.py (%s) found, skipping", __FUNCTION__, strAutoExecPy.c_str());
}
@@ -473,13 +473,13 @@ bool XBPython::StopScript(const CStdString &path)
return false;
}
-int XBPython::evalFile(const CStdString &src, const char* addonId)
+int XBPython::evalFile(const CStdString &src, ADDON::AddonPtr addon)
{
std::vector<CStdString> argv;
- return evalFile(src, argv, addonId);
+ return evalFile(src, argv, addon);
}
// execute script, returns -1 if script doesn't exist
-int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &argv, const char* addonId)
+int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &argv, ADDON::AddonPtr addon)
{
CSingleExit ex(g_graphicsContext);
CSingleLock lock(m_critSection);
@@ -501,7 +501,7 @@ int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &arg
m_nextid++;
XBPyThread *pyThread = new XBPyThread(this, m_nextid);
pyThread->setArgv(argv);
- pyThread->setAddonId(addonId);
+ pyThread->setAddon(addon);
pyThread->evalFile(src);
PyElem inf;
inf.id = m_nextid;
diff --git a/xbmc/interfaces/python/XBPython.h b/xbmc/interfaces/python/XBPython.h
index 1e9a5033f6..50125053e5 100644
--- a/xbmc/interfaces/python/XBPython.h
+++ b/xbmc/interfaces/python/XBPython.h
@@ -24,6 +24,7 @@
#include "XBPyThread.h"
#include "cores/IPlayer.h"
#include "threads/CriticalSection.h"
+#include "addons/IAddon.h"
#include <vector>
@@ -64,8 +65,8 @@ public:
int ScriptsSize();
int GetPythonScriptId(int scriptPosition);
- int evalFile(const CStdString &src, const char* addonId);
- int evalFile(const CStdString &src, const std::vector<CStdString> &argv, const char* addonId);
+ int evalFile(const CStdString &src, ADDON::AddonPtr addon);
+ int evalFile(const CStdString &src, const std::vector<CStdString> &argv, ADDON::AddonPtr addon);
int evalString(const CStdString &src, const std::vector<CStdString> &argv);
bool isRunning(int scriptId);
diff --git a/xbmc/interfaces/python/xbmcmodule/PythonAddon.cpp b/xbmc/interfaces/python/xbmcmodule/PythonAddon.cpp
index 517a620e9f..446fa87b66 100644
--- a/xbmc/interfaces/python/xbmcmodule/PythonAddon.cpp
+++ b/xbmc/interfaces/python/xbmcmodule/PythonAddon.cpp
@@ -58,6 +58,19 @@ namespace PYXBMC
return id;
}
+ static CStdString getAddonVersion()
+ {
+ // Get a reference to the main module
+ // and global dictionary
+ PyObject* main_module = PyImport_AddModule((char*)"__main__");
+ PyObject* global_dict = PyModule_GetDict(main_module);
+ // Extract a reference to the function "func_name"
+ // from the global dictionary
+ PyObject* pyversion = PyDict_GetItemString(global_dict, "__xbmcapiversion__");
+ CStdString version(PyString_AsString(pyversion));
+ return version;
+ }
+
PyObject* Addon_New(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
Addon *self;
@@ -83,18 +96,46 @@ namespace PYXBMC
// if the id wasn't passed then get the id from
// the global dictionary
- if (!id || !CAddonMgr::Get().GetAddon(id, self->pAddon))
- {
- // try the default ...
+ if (!id)
id = getDefaultId();
- if (!CAddonMgr::Get().GetAddon(id, self->pAddon))
- {
- PyErr_SetString(PyExc_Exception, "Could not get AddonPtr!");
+ // if we still don't have an id then bail
+ if (!id)
+ {
+ PyErr_SetString(PyExc_Exception, "No valid addon id could be obtained. None was passed and the script wasn't executed in a normal xbmc manner.");
return NULL;
+ }
+
+ // if we still fail we MAY be able to recover.
+ if (!CAddonMgr::Get().GetAddon(id, self->pAddon))
+ {
+ // we need to check the version prior to trying a bw compatibility trick
+ ADDON::AddonVersion version(getAddonVersion());
+ ADDON::AddonVersion allowable("1.0");
+
+ if (version <= allowable)
+ {
+ // try the default ...
+ id = getDefaultId();
+
+ if (!CAddonMgr::Get().GetAddon(id, self->pAddon))
+ {
+ PyErr_SetString(PyExc_Exception, "Could not get AddonPtr!");
+ return NULL;
+ }
+ else
+ CLog::Log(LOGERROR,"Use of deprecated functionality. Please to not assume that \"os.getcwd\" will return the script directory.");
}
else
- CLog::Log(LOGERROR,"Use of deprecated functionality. Please to not assume that \"os.getcwd\" will return the script directory.");
+ {
+ CStdString errorMessage ("Could not get AddonPtr given a script id of ");
+ errorMessage += id;
+ errorMessage += ". If you are trying to use 'os.getcwd' to set the path, you cannot do that in a ";
+ errorMessage += version.Print();
+ errorMessage += " plugin.";
+ PyErr_SetString(PyExc_Exception, errorMessage.c_str());
+ return NULL;
+ }
}
return (PyObject*)self;
diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp
index 37772d7096..a1a3dc5086 100644
--- a/xbmc/windows/GUIMediaWindow.cpp
+++ b/xbmc/windows/GUIMediaWindow.cpp
@@ -882,7 +882,7 @@ bool CGUIMediaWindow::OnClick(int iItem)
{
#ifdef HAS_PYTHON
if (!g_pythonParser.StopScript(addon->LibPath()))
- g_pythonParser.evalFile(addon->LibPath(),addon->ID());
+ g_pythonParser.evalFile(addon->LibPath(),addon);
#endif
return true;
}
diff --git a/xbmc/windows/GUIWindowFileManager.cpp b/xbmc/windows/GUIWindowFileManager.cpp
index 9f08e5a08a..a058be4a33 100644
--- a/xbmc/windows/GUIWindowFileManager.cpp
+++ b/xbmc/windows/GUIWindowFileManager.cpp
@@ -621,7 +621,7 @@ void CGUIWindowFileManager::OnStart(CFileItem *pItem)
#ifdef HAS_PYTHON
if (pItem->IsPythonScript())
{
- g_pythonParser.evalFile(pItem->m_strPath.c_str(),NULL);
+ g_pythonParser.evalFile(pItem->m_strPath.c_str(),ADDON::AddonPtr());
return ;
}
#endif
diff --git a/xbmc/windows/GUIWindowWeather.cpp b/xbmc/windows/GUIWindowWeather.cpp
index 6ca10a1b81..402c7e0eb8 100644
--- a/xbmc/windows/GUIWindowWeather.cpp
+++ b/xbmc/windows/GUIWindowWeather.cpp
@@ -332,7 +332,7 @@ void CGUIWindowWeather::CallScript()
argv.push_back(CWeather::GetAreaCode(g_guiSettings.GetString(strSetting)));
// call our script, passing the areacode
- g_pythonParser.evalFile(argv[0], argv,addon->ID());
+ g_pythonParser.evalFile(argv[0], argv,addon);
CLog::Log(LOGDEBUG, "%s - Weather script called: %s (%s)", __FUNCTION__, argv[0].c_str(), argv[1].c_str());
}