| 701 | } // AppInstance::load |
| 702 | |
| 703 | bool |
| 704 | AppInstance::loadPythonScript(const QFileInfo& file) |
| 705 | { |
| 706 | std::string addToPythonPath("sys.path.append(\""); |
| 707 | |
| 708 | addToPythonPath += file.path().toStdString(); |
| 709 | addToPythonPath += "\")\n"; |
| 710 | |
| 711 | std::string err; |
| 712 | bool ok = NATRON_PYTHON_NAMESPACE::interpretPythonScript(addToPythonPath, &err, 0); |
| 713 | assert(ok); |
| 714 | if (!ok) { |
| 715 | throw std::runtime_error("AppInstance::loadPythonScript(" + file.path().toStdString() + "): interpretPythonScript(" + addToPythonPath + " failed!"); |
| 716 | } |
| 717 | |
| 718 | std::string s = "app = app1\n"; |
| 719 | ok = NATRON_PYTHON_NAMESPACE::interpretPythonScript(s, &err, 0); |
| 720 | assert(ok); |
| 721 | if (!ok) { |
| 722 | throw std::runtime_error("AppInstance::loadPythonScript(" + file.path().toStdString() + "): interpretPythonScript(" + s + " failed!"); |
| 723 | } |
| 724 | |
| 725 | QFile f( file.absoluteFilePath() ); |
| 726 | if ( !f.open(QIODevice::ReadOnly) ) { |
| 727 | return false; |
| 728 | } |
| 729 | QTextStream ts(&f); |
| 730 | QString content = ts.readAll(); |
| 731 | bool hasCreateInstance = content.contains( QString::fromUtf8("def createInstance") ); |
| 732 | /* |
| 733 | The old way of doing it was |
| 734 | |
| 735 | QString hasCreateInstanceScript = QString("import sys\n" |
| 736 | "import %1\n" |
| 737 | "ret = True\n" |
| 738 | "if not hasattr(%1,\"createInstance\") or not hasattr(%1.createInstance,\"__call__\"):\n" |
| 739 | " ret = False\n").arg(filename); |
| 740 | |
| 741 | |
| 742 | ok = interpretPythonScript(hasCreateInstanceScript.toStdString(), &err, 0); |
| 743 | |
| 744 | |
| 745 | which is wrong because it will try to import the script first. |
| 746 | But we in the case of regular scripts, we allow the user to access externally declared variables such as "app", "app1" etc... |
| 747 | and this would not be possible if the script was imported. Importing the module would then fail because it could not |
| 748 | find the variables and the script could not be executed. |
| 749 | */ |
| 750 | |
| 751 | if (hasCreateInstance) { |
| 752 | QString moduleName = file.fileName(); |
| 753 | int lastDotPos = moduleName.lastIndexOf( QChar::fromLatin1('.') ); |
| 754 | if (lastDotPos != -1) { |
| 755 | moduleName = moduleName.left(lastDotPos); |
| 756 | } |
| 757 | |
| 758 | std::stringstream ss; |
| 759 | ss << "import " << moduleName.toStdString() << '\n'; |
| 760 | ss << moduleName.toStdString() << ".createInstance(app,app)"; |
nothing calls this directly
no test coverage detected