diff options
author | Jim Carroll <thecarrolls@jiminger.com> | 2011-04-10 20:04:26 -0400 |
---|---|---|
committer | Jim Carroll <thecarrolls@jiminger.com> | 2011-04-14 10:04:46 -0400 |
commit | cd2c9beccae22cbb1b7a4f43599a1a6f7eb8c094 (patch) | |
tree | 15eb85758b671170db2b43b3c54bcdce6516f1cd | |
parent | 6391cc510f4bba95fab79575246aa83003cdacaa (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.cpp | 2 | ||||
-rw-r--r-- | xbmc/ApplicationMessenger.cpp | 2 | ||||
-rw-r--r-- | xbmc/addons/Service.cpp | 2 | ||||
-rw-r--r-- | xbmc/filesystem/PluginDirectory.cpp | 4 | ||||
-rw-r--r-- | xbmc/interfaces/Builtins.cpp | 2 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPyThread.cpp | 28 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPyThread.h | 5 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPython.cpp | 10 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPython.h | 5 | ||||
-rw-r--r-- | xbmc/interfaces/python/xbmcmodule/PythonAddon.cpp | 55 | ||||
-rw-r--r-- | xbmc/windows/GUIMediaWindow.cpp | 2 | ||||
-rw-r--r-- | xbmc/windows/GUIWindowFileManager.cpp | 2 | ||||
-rw-r--r-- | xbmc/windows/GUIWindowWeather.cpp | 2 |
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()); } |