aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Carroll <thecarrolls@jiminger.com>2011-04-11 12:58:59 -0400
committerJim Carroll <thecarrolls@jiminger.com>2011-04-14 10:04:46 -0400
commit304bf0d4dbd61a9824587439f90e22e4fa0a5c19 (patch)
tree193b504e342b0628d6e26b1890567584afa397cf
parent21e35e03081aebfde5051a57016f7bf63248441e (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.cpp20
-rw-r--r--xbmc/addons/IAddon.h10
-rw-r--r--xbmc/interfaces/python/XBPyThread.cpp20
-rw-r--r--xbmc/interfaces/python/XBPython.cpp72
-rw-r--r--xbmc/interfaces/python/XBPython.h2
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();