Extended the Python variant detection to only offer the Django project type, if it is found for the respective Python.

Sun, 31 Mar 2013 17:07:43 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 31 Mar 2013 17:07:43 +0200
changeset 12
430932e3094c
parent 11
5eda53fad138
child 14
f2d7863cf573

Extended the Python variant detection to only offer the Django project type, if it is found for the respective Python.

PluginProjectDjango.py file | annotate | diff | comparison | revisions
PluginProjectDjango.zip file | annotate | diff | comparison | revisions
ProjectDjango/Documentation/source/Plugin_Project_Django.PluginProjectDjango.html file | annotate | diff | comparison | revisions
ProjectDjango/Documentation/source/Plugin_Project_Django.ProjectDjango.Project.html file | annotate | diff | comparison | revisions
ProjectDjango/Project.py file | annotate | diff | comparison | revisions
--- a/PluginProjectDjango.py	Wed Mar 27 09:22:59 2013 +0100
+++ b/PluginProjectDjango.py	Sun Mar 31 17:07:43 2013 +0200
@@ -149,6 +149,8 @@
         self.__mainMenu = None
         
         self.__e5project = e5App().getObject("Project")
+        
+        self.__supportedVariants = []
     
     def __checkVersions(self):
         """
@@ -185,18 +187,21 @@
         
         self.__mainMenu = self.__object.initMenu()
         
-        try:
-            self.__e5project.registerProjectType("Django", self.trUtf8("Django"),
-                self.fileTypesCallback,
-                lexerAssociationCallback=self.lexerAssociationCallback,
-                binaryTranslationsCallback=self.binaryTranslationsCallback,
-                progLanguages=["Python2", "Python3"])
-        except TypeError:
-            # for backward compatibility
-            self.__e5project.registerProjectType("Django", self.trUtf8("Django"),
-                self.fileTypesCallback,
-                lexerAssociationCallback=self.lexerAssociationCallback,
-                binaryTranslationsCallback=self.binaryTranslationsCallback)
+        self.__supportedVariants = self.__object.supportedPythonVariants()
+        
+        if self.__supportedVariants:
+            try:
+                self.__e5project.registerProjectType("Django", self.trUtf8("Django"),
+                    self.fileTypesCallback,
+                    lexerAssociationCallback=self.lexerAssociationCallback,
+                    binaryTranslationsCallback=self.binaryTranslationsCallback,
+                    progLanguages=self.__supportedVariants[:])
+            except TypeError:
+                # for backward compatibility
+                self.__e5project.registerProjectType("Django", self.trUtf8("Django"),
+                    self.fileTypesCallback,
+                    lexerAssociationCallback=self.lexerAssociationCallback,
+                    binaryTranslationsCallback=self.binaryTranslationsCallback)
         
         from Project.ProjectBrowser import SourcesBrowserFlag, FormsBrowserFlag, \
             TranslationsBrowserFlag, OthersBrowserFlag
@@ -366,3 +371,31 @@
         @param prefClass preferences class used as the storage area
         """
         Preferences.Prefs.settings.setValue(self.PreferencesKey + "/" + key, value)
+        
+        if key in ["VirtualEnvironmentPy2", "VirtualEnvironmentPy3"]:
+            self.__reregisterProjectType()
+    
+    def __reregisterProjectType(self):
+        """
+        Private method to re-register the project type.
+        """
+        supportedVariants = self.__object.supportedPythonVariants()
+        if supportedVariants != self.__supportedVariants:
+            # step 1: unregister
+            self.__e5project.unregisterProjectType("Django")
+            
+            # step 2: register again with new language settings
+            self.__supportedVariants = supportedVariants
+            if self.__supportedVariants:
+                try:
+                    self.__e5project.registerProjectType("Django", self.trUtf8("Django"),
+                        self.fileTypesCallback,
+                        lexerAssociationCallback=self.lexerAssociationCallback,
+                        binaryTranslationsCallback=self.binaryTranslationsCallback,
+                        progLanguages=self.__supportedVariants[:])
+                except TypeError:
+                    # for backward compatibility
+                    self.__e5project.registerProjectType("Django", self.trUtf8("Django"),
+                        self.fileTypesCallback,
+                        lexerAssociationCallback=self.lexerAssociationCallback,
+                        binaryTranslationsCallback=self.binaryTranslationsCallback)
Binary file PluginProjectDjango.zip has changed
--- a/ProjectDjango/Documentation/source/Plugin_Project_Django.PluginProjectDjango.html	Wed Mar 27 09:22:59 2013 +0100
+++ b/ProjectDjango/Documentation/source/Plugin_Project_Django.PluginProjectDjango.html	Sun Mar 31 17:07:43 2013 +0200
@@ -31,7 +31,7 @@
 <table>
 <tr>
 <td><a href="#ProjectDjangoPlugin">ProjectDjangoPlugin</a></td>
-<td>Class implementing the Pyramid project plugin.</td>
+<td>Class implementing the Django project plugin.</td>
 </tr>
 </table>
 <h3>Functions</h3>
@@ -54,7 +54,7 @@
 <a NAME="ProjectDjangoPlugin" ID="ProjectDjangoPlugin"></a>
 <h2>ProjectDjangoPlugin</h2>
 <p>
-    Class implementing the Pyramid project plugin.
+    Class implementing the Django project plugin.
 </p>
 <h3>Derived from</h3>
 QObject
@@ -87,6 +87,9 @@
 <td><a href="#ProjectDjangoPlugin.__projectOpened">__projectOpened</a></td>
 <td>Private slot to handle the projectOpened signal.</td>
 </tr><tr>
+<td><a href="#ProjectDjangoPlugin.__reregisterProjectType">__reregisterProjectType</a></td>
+<td>Private method to re-register the project type.</td>
+</tr><tr>
 <td><a href="#ProjectDjangoPlugin.activate">activate</a></td>
 <td>Public method to activate this plugin.</td>
 </tr><tr>
@@ -153,6 +156,11 @@
 <b>__projectOpened</b>(<i></i>)
 <p>
         Private slot to handle the projectOpened signal.
+</p><a NAME="ProjectDjangoPlugin.__reregisterProjectType" ID="ProjectDjangoPlugin.__reregisterProjectType"></a>
+<h4>ProjectDjangoPlugin.__reregisterProjectType</h4>
+<b>__reregisterProjectType</b>(<i></i>)
+<p>
+        Private method to re-register the project type.
 </p><a NAME="ProjectDjangoPlugin.activate" ID="ProjectDjangoPlugin.activate"></a>
 <h4>ProjectDjangoPlugin.activate</h4>
 <b>activate</b>(<i></i>)
--- a/ProjectDjango/Documentation/source/Plugin_Project_Django.ProjectDjango.Project.html	Wed Mar 27 09:22:59 2013 +0100
+++ b/ProjectDjango/Documentation/source/Plugin_Project_Django.ProjectDjango.Project.html	Sun Mar 31 17:07:43 2013 +0200
@@ -156,7 +156,10 @@
 <td>Private method to ask the user for a list of application names.</td>
 </tr><tr>
 <td><a href="#Project.__getDjangoAdminCommand">__getDjangoAdminCommand</a></td>
-<td>Public method to build a django-admin.py command.</td>
+<td>Private method to build a django-admin.py command.</td>
+</tr><tr>
+<td><a href="#Project.__getExecutablePaths">__getExecutablePaths</a></td>
+<td>Private method to build all full path of an executable file from the environment.</td>
 </tr><tr>
 <td><a href="#Project.__getLocale">__getLocale</a></td>
 <td>Private method to extract the locale out of a file name.</td>
@@ -294,7 +297,7 @@
 <td>Public method to get the list of recent applications.</td>
 </tr><tr>
 <td><a href="#Project.initActions">initActions</a></td>
-<td>Public method to define the Pyramid actions.</td>
+<td>Public method to define the Django actions.</td>
 </tr><tr>
 <td><a href="#Project.initMenu">initMenu</a></td>
 <td>Public slot to initialize the Django menu.</td>
@@ -317,6 +320,9 @@
 <td><a href="#Project.startProjectOrApplication">startProjectOrApplication</a></td>
 <td>Public slot to start a new Django project or application.</td>
 </tr><tr>
+<td><a href="#Project.supportedPythonVariants">supportedPythonVariants</a></td>
+<td>Public method to get the supported Python variants.</td>
+</tr><tr>
 <td><a href="#Project.updateCatalogs">updateCatalogs</a></td>
 <td>Public method to update the message catalogs.</td>
 </tr><tr>
@@ -508,18 +514,37 @@
 </dd>
 </dl><a NAME="Project.__getDjangoAdminCommand" ID="Project.__getDjangoAdminCommand"></a>
 <h4>Project.__getDjangoAdminCommand</h4>
-<b>__getDjangoAdminCommand</b>(<i></i>)
+<b>__getDjangoAdminCommand</b>(<i>language=""</i>)
 <p>
-        Public method to build a django-admin.py command.
+        Private method to build a django-admin.py command.
 </p><dl>
-<dt><i>cmd</i></dt>
+<dt><i>language</i></dt>
 <dd>
-command (string)
+Python variant to get the django-admin.py
+            command for (string, one of '', 'Python2' or 'Python3')
 </dd>
 </dl><dl>
 <dt>Returns:</dt>
 <dd>
-full pyramid command (string)
+full django-admin.py command (string)
+</dd>
+</dl><a NAME="Project.__getExecutablePaths" ID="Project.__getExecutablePaths"></a>
+<h4>Project.__getExecutablePaths</h4>
+<b>__getExecutablePaths</b>(<i>file</i>)
+<p>
+        Private method to build all full path of an executable file from
+        the environment.
+</p><dl>
+<dt><i>file</i></dt>
+<dd>
+filename of the executable (string)
+</dd>
+</dl><dl>
+<dt>Returns:</dt>
+<dd>
+list of full executable names, if the executable file is accessible
+            via the searchpath defined by the PATH environment variable, or an
+            empty list otherwise.
 </dd>
 </dl><a NAME="Project.__getLocale" ID="Project.__getLocale"></a>
 <h4>Project.__getLocale</h4>
@@ -548,10 +573,16 @@
 </dd>
 </dl><a NAME="Project.__getVirtualEnvironment" ID="Project.__getVirtualEnvironment"></a>
 <h4>Project.__getVirtualEnvironment</h4>
-<b>__getVirtualEnvironment</b>(<i></i>)
+<b>__getVirtualEnvironment</b>(<i>language=""</i>)
 <p>
         Private method to get the path of the virtual environment.
 </p><dl>
+<dt><i>language</i></dt>
+<dd>
+Python variant to get the virtual environment
+            for (string, one of '', 'Python2' or 'Python3')
+</dd>
+</dl><dl>
 <dt>Returns:</dt>
 <dd>
 path of the virtual environment (string)
@@ -904,7 +935,7 @@
 <h4>Project.initActions</h4>
 <b>initActions</b>(<i></i>)
 <p>
-        Public method to define the Pyramid actions.
+        Public method to define the Django actions.
 </p><a NAME="Project.initMenu" ID="Project.initMenu"></a>
 <h4>Project.initMenu</h4>
 <b>initMenu</b>(<i></i>)
@@ -955,7 +986,17 @@
 <b>startProjectOrApplication</b>(<i></i>)
 <p>
         Public slot to start a new Django project or application.
-</p><a NAME="Project.updateCatalogs" ID="Project.updateCatalogs"></a>
+</p><a NAME="Project.supportedPythonVariants" ID="Project.supportedPythonVariants"></a>
+<h4>Project.supportedPythonVariants</h4>
+<b>supportedPythonVariants</b>(<i></i>)
+<p>
+        Public method to get the supported Python variants.
+</p><dl>
+<dt>Returns:</dt>
+<dd>
+list of supported Python variants (list of strings)
+</dd>
+</dl><a NAME="Project.updateCatalogs" ID="Project.updateCatalogs"></a>
 <h4>Project.updateCatalogs</h4>
 <b>updateCatalogs</b>(<i>filenames</i>)
 <p>
--- a/ProjectDjango/Project.py	Wed Mar 27 09:22:59 2013 +0100
+++ b/ProjectDjango/Project.py	Sun Mar 31 17:07:43 2013 +0200
@@ -827,13 +827,90 @@
             self.__serverProcFinished()
         self.__setCurrentSite(None)
     
-    def __getVirtualEnvironment(self):
+    def __getExecutablePaths(self, file):
+        """
+        Private method to build all full path of an executable file from
+        the environment.
+        
+        @param file filename of the executable (string)
+        @return list of full executable names, if the executable file is accessible
+            via the searchpath defined by the PATH environment variable, or an
+            empty list otherwise.
+        """
+        paths = []
+        
+        if os.path.isabs(file):
+            if os.access(file, os.X_OK):
+                return [file]
+            else:
+                return []
+            
+        cur_path = os.path.join(os.curdir, file)
+        if os.path.exists(cur_path):
+            if os.access(cur_path, os.X_OK):
+                paths.append(cur_path)
+
+        path = os.getenv('PATH')
+        
+        # environment variable not defined
+        if path is not None:
+            dirs = path.split(os.pathsep)
+            for dir in dirs:
+                exe = os.path.join(dir, file)
+                if os.access(exe, os.X_OK) and exe not in paths:
+                    paths.append(exe)
+        
+        return paths
+    
+    def supportedPythonVariants(self):
+        """
+        Public method to get the supported Python variants.
+        
+        @return list of supported Python variants (list of strings)
+        """
+        variants = []
+        for variant in 'Python2', 'Python3':
+            virtEnv = self.__getVirtualEnvironment(variant)
+            if virtEnv:
+                if self.__getDjangoAdminCommand(variant):
+                    variants.append(variant)
+            else:
+                cmd = self.__getDjangoAdminCommand()
+                if isWindowsPlatform():
+                    if variant.lower() in cmd.lower():
+                        variants.append(variant)
+                else:
+                    try:
+                        fullCmds = Utilities.getExecutablePaths(cmd)
+                    except AttributeError:
+                        fullCmds = self.__getExecutablePaths(cmd)
+                    for fullCmd in fullCmds:
+                        try:
+                            f = open(fullCmd, 'r', encoding='utf-8')
+                            l0 = f.readline()
+                            f.close()
+                        except (IOError, OSError):
+                            l0 = ""
+                        if variant.lower() in l0.lower() or \
+                           "{0}.".format(variant[-1]) in l0 or \
+                           (variant == "Python2" and \
+                            "python3" not in l0.lower() and \
+                            "python" in l0.lower()):
+                            variants.append(variant)
+                            break
+        
+        return variants
+    
+    def __getVirtualEnvironment(self, language=""):
         """
         Private method to get the path of the virtual environment.
         
+        @param language Python variant to get the virtual environment
+            for (string, one of '', 'Python2' or 'Python3')
         @return path of the virtual environment (string)
         """
-        language = self.__e5project.getProjectLanguage()
+        if not language:
+            language = self.__e5project.getProjectLanguage()
         if language == "Python3":
             virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy3")
         elif language == "Python2":
@@ -844,14 +921,15 @@
             virtEnv = ""
         return virtEnv
     
-    def __getDjangoAdminCommand(self):
+    def __getDjangoAdminCommand(self, language=""):
         """
-        Public method to build a django-admin.py command.
+        Private method to build a django-admin.py command.
         
-        @param cmd command (string)
+        @param language Python variant to get the django-admin.py
+            command for (string, one of '', 'Python2' or 'Python3')
         @return full django-admin.py command (string)
         """
-        virtualEnv = self.__getVirtualEnvironment()
+        virtualEnv = self.__getVirtualEnvironment(language)
         if virtualEnv:
             if isWindowsPlatform():
                 cmd = os.path.join(virtualEnv, "Scripts", "django-admin.py")
@@ -878,6 +956,7 @@
                 else:
                     # fall back
                     cmd = "django-admin.py"
+        
         return cmd
     
     def __getPythonExecutable(self):

eric ide

mercurial