diff options
author | Jim Carroll <thecarrolls@jiminger.com> | 2011-04-11 12:58:59 -0400 |
---|---|---|
committer | Jim Carroll <thecarrolls@jiminger.com> | 2011-04-14 10:04:46 -0400 |
commit | 304bf0d4dbd61a9824587439f90e22e4fa0a5c19 (patch) | |
tree | 193b504e342b0628d6e26b1890567584afa397cf | |
parent | 21e35e03081aebfde5051a57016f7bf63248441e (diff) |
This applies elupus' os.getcwd override but only for scripts that are dependent on the xbmc.python version 1.0 (or less) interface.
-rw-r--r-- | xbmc/addons/Addon.cpp | 20 | ||||
-rw-r--r-- | xbmc/addons/IAddon.h | 10 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPyThread.cpp | 20 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPython.cpp | 72 | ||||
-rw-r--r-- | xbmc/interfaces/python/XBPython.h | 2 |
5 files changed, 89 insertions, 35 deletions
diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp index 6a202c632e..f37a385cab 100644 --- a/xbmc/addons/Addon.cpp +++ b/xbmc/addons/Addon.cpp @@ -666,5 +666,25 @@ TYPE CAddonLibrary::SetAddonType() return ADDON_UNKNOWN; } +CStdString getXbmcApiVersionDependency(ADDON::AddonPtr addon) +{ + CStdString version("1.0"); + if (addon.get() != NULL) + { + const ADDON::ADDONDEPS &deps = addon->GetDeps(); + ADDON::ADDONDEPS::const_iterator it; + CStdString key("xbmc.python"); + it = deps.find(key); + if (!(it == deps.end())) + { + const ADDON::AddonVersion * xbmcApiVersion = &(it->second.first); + version = xbmcApiVersion->c_str(); + } + } + + return version; +} + + } /* namespace ADDON */ diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h index 31ee5b1031..12fe0ecc3c 100644 --- a/xbmc/addons/IAddon.h +++ b/xbmc/addons/IAddon.h @@ -121,5 +121,15 @@ namespace ADDON virtual bool LoadStrings() =0; virtual void ClearStrings() =0; }; + + // some utilitiy methods + + /** + * This function will extract the Addon's currently assigned xbmc.python + * API version. If addon is NULL, or there is no xbmc.python dependency defined, + * then the version is assumed to be "1.0" + */ + CStdString getXbmcApiVersionDependency(ADDON::AddonPtr addon); + }; diff --git a/xbmc/interfaces/python/XBPyThread.cpp b/xbmc/interfaces/python/XBPyThread.cpp index 0d4f0b8162..b76db0c8d7 100644 --- a/xbmc/interfaces/python/XBPyThread.cpp +++ b/xbmc/interfaces/python/XBPyThread.cpp @@ -128,22 +128,6 @@ 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"); @@ -162,7 +146,7 @@ void XBPyThread::Process() // swap in my thread state PyThreadState_Swap(state); - m_pExecuter->InitializeInterpreter(); + m_pExecuter->InitializeInterpreter(addon); CLog::Log(LOGDEBUG, "%s - The source file to load is %s", __FUNCTION__, m_source); @@ -255,7 +239,7 @@ void XBPyThread::Process() PyObject *pyaddonid = PyString_FromString(addon->ID().c_str()); PyDict_SetItemString(moduleDict, "__xbmcaddonid__", pyaddonid); - CStdString version = getXbmcApiVersionDependency(addon); + CStdString version = ADDON::getXbmcApiVersionDependency(addon); PyObject *pyxbmcapiversion = PyString_FromString(version.c_str()); PyDict_SetItemString(moduleDict, "__xbmcapiversion__", pyxbmcapiversion); diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp index e44e7ad7a6..e274208992 100644 --- a/xbmc/interfaces/python/XBPython.cpp +++ b/xbmc/interfaces/python/XBPython.cpp @@ -39,6 +39,8 @@ #include "utils/TimeUtils.h" #include "Util.h" +#include "addons/Addon.h" + extern "C" HMODULE __stdcall dllLoadLibraryA(LPCSTR file); extern "C" BOOL __stdcall dllFreeLibrary(HINSTANCE hLibModule); @@ -229,29 +231,67 @@ void XBPython::UnloadExtensionLibs() m_extensions.clear(); } -void XBPython::InitializeInterpreter() +#define RUNSCRIPT_PRAMBLE \ + "" \ + "import xbmc\n" \ + "class xbmcout:\n" \ + "\tdef __init__(self, loglevel=xbmc.LOGNOTICE):\n" \ + "\t\tself.ll=loglevel\n" \ + "\tdef write(self, data):\n" \ + "\t\txbmc.output(data,self.ll)\n" \ + "\tdef close(self):\n" \ + "\t\txbmc.output('.')\n" \ + "\tdef flush(self):\n" \ + "\t\txbmc.output('.')\n" \ + "import sys\n" \ + "sys.stdout = xbmcout()\n" \ + "sys.stderr = xbmcout(xbmc.LOGERROR)\n" + +#define RUNSCRIPT_OVERRIDE_HACK \ + "" \ + "import os\n" \ + "def getcwd_xbmc():\n" \ + " import __main__\n" \ + " import warnings\n" \ + " if hasattr(__main__, \"__file__\"):\n" \ + " warnings.warn(\"os.getcwd() currently lies to you so please use addon.getAddonInfo('path') to find the script's root directory and DO NOT make relative path accesses based on the results of 'os.getcwd.' \", DeprecationWarning, stacklevel=2)\n" \ + " return os.path.dirname(__main__.__file__)\n" \ + " else:\n" \ + " return os.getcwd_original()\n" \ + "" \ + "def chdir_xbmc(dir):\n" \ + " raise RuntimeError(\"os.chdir not supported in xbmc\")\n" \ + "" \ + "os_getcwd_original = os.getcwd\n" \ + "os.getcwd = getcwd_xbmc\n" \ + "os.chdir_orignal = os.chdir\n" \ + "os.chdir = chdir_xbmc\n" \ + "" + +#define RUNSCRIPT_POSTSCRIPT \ + "print '-->Python Interpreter Initialized<--'\n" \ + "" + +#define RUNSCRIPT_BWCOMPATIBLE \ + RUNSCRIPT_PRAMBLE RUNSCRIPT_OVERRIDE_HACK RUNSCRIPT_POSTSCRIPT + +#define RUNSCRIPT_COMPLIANT \ + RUNSCRIPT_PRAMBLE RUNSCRIPT_POSTSCRIPT + +void XBPython::InitializeInterpreter(ADDON::AddonPtr addon) { InitXBMCModule(); // init xbmc modules InitPluginModule(); // init xbmcplugin modules InitGUIModule(); // init xbmcgui modules InitAddonModule(); // init xbmcaddon modules InitVFSModule(); // init xbmcvfs modules - + + CStdString addonVer = ADDON::getXbmcApiVersionDependency(addon); + bool bwcompatMode = (addon.get() == NULL || (ADDON::AddonVersion(addonVer) <= ADDON::AddonVersion("1.0"))); + const char* runscript = bwcompatMode ? RUNSCRIPT_BWCOMPATIBLE : RUNSCRIPT_COMPLIANT; + // redirecting default output to debug console - if (PyRun_SimpleString("" - "import xbmc\n" - "class xbmcout:\n" - "\tdef write(self, data):\n" - "\t\txbmc.output(data)\n" - "\tdef close(self):\n" - "\t\txbmc.output('.')\n" - "\tdef flush(self):\n" - "\t\txbmc.output('.')\n" - "import sys\n" - "sys.stdout = xbmcout()\n" - "sys.stderr = xbmcout()\n" - "print '-->Python Interpreter Initialized<--'\n" - "") == -1) + if (PyRun_SimpleString(runscript) == -1) { CLog::Log(LOGFATAL, "Python Initialize Error"); } diff --git a/xbmc/interfaces/python/XBPython.h b/xbmc/interfaces/python/XBPython.h index 50125053e5..c46039d069 100644 --- a/xbmc/interfaces/python/XBPython.h +++ b/xbmc/interfaces/python/XBPython.h @@ -81,7 +81,7 @@ public: // inject xbmc stuff into the interpreter. // should be called for every new interpreter - void InitializeInterpreter(); + void InitializeInterpreter(ADDON::AddonPtr addon); // remove modules and references when interpreter done void DeInitializeInterpreter(); |