Skip to content

Commit

Permalink
This applies elupus' os.getcwd override but only for scripts that are…
Browse files Browse the repository at this point in the history
… dependent on the xbmc.python version 1.0 (or less) interface.
  • Loading branch information
Jim Carroll committed Apr 14, 2011
1 parent 21e35e0 commit 304bf0d
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 35 deletions.
20 changes: 20 additions & 0 deletions xbmc/addons/Addon.cpp
Expand Up @@ -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()))

This comment has been minimized.

Copy link
@garbear

garbear Apr 6, 2012

Member

Is this faster than != ?

{
const ADDON::AddonVersion * xbmcApiVersion = &(it->second.first);
version = xbmcApiVersion->c_str();
}
}

return version;
}


} /* namespace ADDON */

10 changes: 10 additions & 0 deletions xbmc/addons/IAddon.h
Expand Up @@ -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);

};

20 changes: 2 additions & 18 deletions xbmc/interfaces/python/XBPyThread.cpp
Expand Up @@ -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");
Expand All @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
72 changes: 56 additions & 16 deletions xbmc/interfaces/python/XBPython.cpp
Expand Up @@ -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);

Expand Down Expand Up @@ -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");
}
Expand Down
2 changes: 1 addition & 1 deletion xbmc/interfaces/python/XBPython.h
Expand Up @@ -81,7 +81,7 @@ class XBPython : public IPlayerCallback

// 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();
Expand Down

0 comments on commit 304bf0d

Please sign in to comment.