ProjectPyramid/Project.py

Tue, 28 Aug 2012 17:15:21 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 28 Aug 2012 17:15:21 +0200
changeset 2
e691c51ab655
child 3
76c45d31d462
permissions
-rw-r--r--

Implemented the required command actions for supporting development of Pyramid projects.

# -*- coding: utf-8 -*-

# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the Pyramid project support.
"""

import os
import configparser

from PyQt4.QtCore import QObject, QFileInfo, QProcess, QTimer, QUrl
from PyQt4.QtGui import QMenu, QDialog, QInputDialog, QDesktopServices

from E5Gui.E5Application import e5App
from E5Gui import E5MessageBox, E5FileDialog
from E5Gui.E5Action import E5Action

from .FormSelectionDialog import FormSelectionDialog
from .CreateParametersDialog import CreateParametersDialog
from .PyramidDialog import PyramidDialog
from .DistributionTypeSelectionDialog import DistributionTypeSelectionDialog

import Utilities
from Globals import isWindowsPlatform
import UI.PixmapCache


class PyramidNoProjectSelectedException(Exception):
    """
    Exception thrown to signal, that there is no current Pyramid project.
    """
    pass


class Project(QObject):
    """
    Class implementing the Pyramid project support.
    """
    def __init__(self, plugin, parent = None):
        """
        Constructor
        
        @param plugin reference to the plugin object
        @param parent parent (QObject)
        """
        super().__init__(parent)
        
        self.__plugin = plugin
        self.__ui = parent
        self.__e5project = e5App().getObject("Project")
        self.__hooksInstalled = False
        
        self.__mainMenu = None
        
        self.__serverProc = None
    
    def initActions(self):
        """
        Public method to define the Pyramid actions.
        """
        self.actions = []
    
        self.selectProjectAct = E5Action(self.trUtf8('Current Pyramid Project'),
                "",
                0, 0,
                self,'pyramid_current_project')
        self.selectProjectAct.setStatusTip(self.trUtf8(
            'Selects the current Pyramid project'))
        self.selectProjectAct.setWhatsThis(self.trUtf8(
            """<b>Current Pyramid Project</b>"""
            """<p>Selects the Pyramid project. Used for multi-project """
            """Pyramid projects to switch between the projects.</p>"""
        ))
        self.selectProjectAct.triggered[()].connect(self.__selectProject)
        self.actions.append(self.selectProjectAct)
        self.__setCurrentProject(None)
        
        ###############################
        ## create actions below      ##
        ###############################
        
        self.createProjectAct = E5Action(self.trUtf8('Create Pyramid Project'),
                self.trUtf8('Create Pyramid &Project'), 
                0, 0,
                self,'pyramid_create_project')
        self.createProjectAct.setStatusTip(self.trUtf8(
            'Creates a new Pyramid project'))
        self.createProjectAct.setWhatsThis(self.trUtf8(
            """<b>Create Pyramid Project</b>"""
            """<p>Creates a new Pyramid project using "pcreate".</p>"""
        ))
        self.createProjectAct.triggered[()].connect(self.__createProject)
        self.actions.append(self.createProjectAct)
        
        ##############################
        ## run actions below        ##
        ##############################
        
        self.runServerAct = E5Action(self.trUtf8('Run Server'),
                self.trUtf8('Run &Server'), 
                0, 0,
                self,'pyramid_run_server')
        self.runServerAct.setStatusTip(self.trUtf8(
            'Starts the Pyramid Web server'))
        self.runServerAct.setWhatsThis(self.trUtf8(
            """<b>Run Server</b>"""
            """<p>Starts the Pyramid Web server using"""
            """ "pserve --reload development.ini".</p>"""
        ))
        self.runServerAct.triggered[()].connect(self.__runServer)
        self.actions.append(self.runServerAct)
        
        self.runLoggingServerAct = E5Action(self.trUtf8('Run Server with Logging'),
                self.trUtf8('Run Server with &Logging'), 
                0, 0,
                self,'pyramid_run_logging_server')
        self.runLoggingServerAct.setStatusTip(self.trUtf8(
            'Starts the Pyramid Web server with logging'))
        self.runLoggingServerAct.setWhatsThis(self.trUtf8(
            """<b>Run Server with Logging</b>"""
            """<p>Starts the Pyramid Web server with logging using"""
            """ "pserve --log-file=server.log --reload development.ini".</p>"""
        ))
        self.runLoggingServerAct.triggered[()].connect(self.__runLoggingServer)
        self.actions.append(self.runLoggingServerAct)
        
        self.runBrowserAct = E5Action(self.trUtf8('Run Web-Browser'),
                self.trUtf8('Run &Web-Browser'), 
                0, 0,
                self,'pyramid_run_browser')
        self.runBrowserAct.setStatusTip(self.trUtf8(
            'Starts the default Web-Browser with the URL of the Pyramid Web server'))
        self.runBrowserAct.setWhatsThis(self.trUtf8(
            """<b>Run Web-Browser</b>"""
            """<p>Starts the default Web-Browser with the URL of the """
            """Pyramid Web server.</p>"""
        ))
        self.runBrowserAct.triggered[()].connect(self.__runBrowser)
        self.actions.append(self.runBrowserAct)
    
        self.runPythonShellAct = E5Action(self.trUtf8('Start Pyramid Python Console'),
                self.trUtf8('Start Pyramid &Python Console'), 
                0, 0,
                self,'pyramid_python_console')
        self.runPythonShellAct.setStatusTip(self.trUtf8(
            'Starts an interactive Python interpreter'))
        self.runPythonShellAct.setWhatsThis(self.trUtf8(
            """<b>Start Pyramid Python Console</b>"""
            """<p>Starts an interactive Python interpreter.</p>"""
        ))
        self.runPythonShellAct.triggered[()].connect(self.__runPythonShell)
        self.actions.append(self.runPythonShellAct)
        
        ##############################
        ## setup actions below      ##
        ##############################
        
        self.setupDevelopAct = E5Action(self.trUtf8('Setup Development Environment'),
                self.trUtf8('Setup &Development Environment'), 
                0, 0,
                self,'pyramid_setup_development')
        self.setupDevelopAct.setStatusTip(self.trUtf8(
            'Setup the Pyramid project in development mode'))
        self.setupDevelopAct.setWhatsThis(self.trUtf8(
            """<b>Setup Development Environment</b>"""
            """<p>Setup the Pyramid project in development mode using"""
            """ "python setup.py develop".</p>"""
        ))
        self.setupDevelopAct.triggered[()].connect(self.__setupDevelop)
        self.actions.append(self.setupDevelopAct)
         
        ##################################
        ## distribution actions below   ##
        ##################################
        
        self.buildDistroAct = E5Action(self.trUtf8('Build Distribution'),
                self.trUtf8('Build &Distribution'), 
                0, 0,
                self,'pyramid_build_distribution')
        self.buildDistroAct.setStatusTip(self.trUtf8(
            'Builds a distribution file for the Pyramid project'))
        self.buildDistroAct.setWhatsThis(self.trUtf8(
            """<b>Build Distribution</b>"""
            """<p>Builds a distribution file for the Pyramid project using"""
            """ "python setup.py sdist".</p>"""
        ))
        self.buildDistroAct.triggered[()].connect(self.__buildDistribution)
        self.actions.append(self.buildDistroAct)
        
        ##################################
        ## documentation action below   ##
        ##################################
        
        self.documentationAct = E5Action(self.trUtf8('Documentation'),
                self.trUtf8('D&ocumentation'), 
                0, 0,
                self,'pyramid_documentation')
        self.documentationAct.setStatusTip(self.trUtf8(
            'Shows the help viewer with the Pyramid documentation'))
        self.documentationAct.setWhatsThis(self.trUtf8(
            """<b>Documentation</b>"""
            """<p>Shows the help viewer with the Pyramid documentation.</p>"""
        ))
        self.documentationAct.triggered[()].connect(self.__showDocumentation)
        self.actions.append(self.documentationAct)
       
        ##############################
        ## about action below       ##
        ##############################
        
        self.aboutPyramidAct = E5Action(self.trUtf8('About Pyramid'),
                self.trUtf8('About P&yramid'), 
                0, 0,
                self,'pyramid_about')
        self.aboutPyramidAct.setStatusTip(self.trUtf8(
            'Shows some information about Pyramid'))
        self.aboutPyramidAct.setWhatsThis(self.trUtf8(
            """<b>About Pyramid</b>"""
            """<p>Shows some information about Pyramid.</p>"""
        ))
        self.aboutPyramidAct.triggered[()].connect(self.__pyramidInfo)
        self.actions.append(self.aboutPyramidAct)
    
    def initMenu(self):
        """
        Public slot to initialize the Pyramid menu.
        
        @return the menu generated (QMenu)
        """
        menu = QMenu(self.trUtf8('P&yramid'), self.__ui)
        menu.setTearOffEnabled(True)
        
        menu.addAction(self.selectProjectAct)
        menu.addSeparator()
        menu.addAction(self.runServerAct)
        menu.addAction(self.runLoggingServerAct)
        menu.addAction(self.runBrowserAct)
        menu.addSeparator()
        menu.addAction(self.createProjectAct)
        menu.addSeparator()
        menu.addAction(self.setupDevelopAct)
        menu.addSeparator()
        menu.addAction(self.runPythonShellAct)
        menu.addSeparator()
        menu.addAction(self.buildDistroAct)
        menu.addSeparator()
        menu.addAction(self.documentationAct)
        menu.addSeparator()
        menu.addAction(self.aboutPyramidAct)
        
        self.__mainMenu = menu
        return menu
    
    def projectOpenedHooks(self):
        """
        Public method to add our hook methods.
        """
        if self.__e5project.getProjectType() == "Pyramid":
            self.__formsBrowser = \
                e5App().getObject("ProjectBrowser").getProjectBrowser("forms")
            self.__formsBrowser.addHookMethodAndMenuEntry("newForm", 
                self.newForm, self.trUtf8("New template..."))
            
##            self.__e5project.projectLanguageAddedByCode.connect(
##                self.__projectLanguageAdded)
##            self.__translationsBrowser = \
##                e5App().getObject("ProjectBrowser").getProjectBrowser("translations")
##            self.__translationsBrowser.addHookMethodAndMenuEntry("extractMessages", 
##                self.extractMessages, self.trUtf8("Extract messages"))
##            self.__translationsBrowser.addHookMethodAndMenuEntry("releaseAll", 
##                self.compileCatalogs, self.trUtf8("Compile all catalogs"))
##            self.__translationsBrowser.addHookMethodAndMenuEntry("releaseSelected", 
##                self.compileSelectedCatalogs, 
##                self.trUtf8("Compile selected catalogs"))
##            self.__translationsBrowser.addHookMethodAndMenuEntry("generateAll", 
##                self.updateCatalogs, self.trUtf8("Update all catalogs"))
##            self.__translationsBrowser.addHookMethodAndMenuEntry("generateSelected", 
##                self.updateSelectedCatalogs, self.trUtf8("Update selected catalogs"))
            
            self.__hooksInstalled = True
    
    def projectClosedHooks(self):
        """
        Public method to remove our hook methods.
        """
        if self.__hooksInstalled:
            self.__formsBrowser.removeHookMethod("newForm")
            self.__formsBrowser = None
            
##            self.__e5project.projectLanguageAddedByCode.disconnect(
##                self.__projectLanguageAdded)
##            self.__translationsBrowser.removeHookMethod("extractMessages")
##            self.__translationsBrowser.removeHookMethod("releaseAll")
##            self.__translationsBrowser.removeHookMethod("releaseSelected")
##            self.__translationsBrowser.removeHookMethod("generateAll")
##            self.__translationsBrowser.removeHookMethod("generateSelected")
##            self.__translationsBrowser = None
            
            self.__hooksInstalled = False
    
    def newForm(self, path):
        """
        Public method to create a new form.
        
        @param path full directory path for the new form file (string)
        """
        dlg = FormSelectionDialog()
        if dlg.exec_() == QDialog.Accepted:
            template = dlg.getTemplateText()
            
            filter = self.trUtf8(
                "Chameleon Templates (*.pt);;"
                "Chameleon Text Templates (*.txt);;"
                "Mako Templates (*.mako);;"
                "Mako Templates (*.mak);;"
                "HTML Files (*.html);;"
                "HTML Files (*.htm);;"
                "All Files (*)")
            fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
                self.__ui,
                self.trUtf8("New Form"),
                path,
                filter,
                None,
                E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite))
            if fname:
                ext = QFileInfo(fname).suffix()
                if not ext:
                    ex = selectedFilter.split("(*")[1].split(")")[0]
                    if ex:
                        fname += ex
            
                if os.path.exists(fname):
                    res = E5MessageBox.yesNo(self.__ui,
                        self.trUtf8("New Form"),
                        self.trUtf8("""The file already exists! Overwrite it?"""),
                        icon = E5MessageBox.Warning)
                    if not res:
                        # user selected to not overwrite
                        return
                
                try:
                    f = open(fname, "w", encoding="utf-8")
                    f.write(template)
                    f.close()
                except IOError as e:
                    E5MessageBox.critical(self,
                        self.trUtf8("New Form"),
                        self.trUtf8("<p>The new form file <b>{0}</b> could not be"
                            " created.<br/>"
                            "Problem: {1}</p>").format(fname, e))
                    return
                
                self.__e5project.appendFile(fname)
                self.__formsBrowser.sourceFile.emit(fname)

    ##################################################################
    ## methods below implement general functionality
    ##################################################################
    
    def projectClosed(self):
        """
        Public method to handle the closing of a project.
        """
        if self.__serverProc is not None:
            self.__serverProcFinished()
        self.__setCurrentProject(None)
    
    def __getVirtualEnvironment(self):
        """
        Private method to get the path of the virtual environment.
        
        @return path of the virtual environment (string)
        """
        language = self.__e5project.getProjectLanguage()
        if language == "Python3":
            virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy3")
        elif language == "Python2":
            virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy2")
        else:
            virtEnv = ""
        if virtEnv and not os.path.exists(virtEnv):
            virtEnv = ""
        return virtEnv
    
    def getPyramidCommand(self, cmd):
        """
        Public method to build a Pyramid command.
        
        @param cmd command (string)
        @return full pyramid command (string)
        """
        virtualEnv = self.__getVirtualEnvironment()
        if virtualEnv:
            if isWindowsPlatform():
                cmd = os.path.join(virtualEnv, "Scripts", cmd)
            else:
                cmd = os.path.join(virtualEnv, "bin", cmd)
        return cmd
    
    def getPythonCommand(self):
        """
        Public method to build the Python command.
        
        @return python command (string)
        """
        python = "python"
        if isWindowsPlatform():
            python += ".exe"
        virtualEnv = self.__getVirtualEnvironment()
        if virtualEnv:
            if isWindowsPlatform():
                python = os.path.join(virtualEnv, "Scripts", python)
            else:
                python = os.path.join(virtualEnv, "bin", python)
        return python
    
    def __pyramidInfo(self):
        """
        Private slot to show some info about Pyramid.
        """
        url = "http://www.pylonsproject.org/projects/pyramid/about"
        msgBox = E5MessageBox.E5MessageBox(E5MessageBox.Question,
            self.trUtf8("About Pyramid"),
            self.trUtf8(
                "<p>Pyramid is a high-level Python Web framework that encourages rapid "
                "development and clean, pragmatic design.</p>"
                "<p>URL: <a href=\"{0}\">{0}</a></p>"
            ).format(url),
            modal=True,
            buttons=E5MessageBox.Ok)
        msgBox.setIconPixmap(UI.PixmapCache.getPixmap(
            os.path.join("ProjectPyramid", "icons", "pyramid64.png")))
        msgBox.exec_()
    
    def isSpawningConsole(self, consoleCmd):
        """
        Public method to check, if the given console is a spawning console.
        
        @param consoleCmd console command (string)
        @return tuple of two entries giving an indication, if the console
            is spawning (boolean) and the (possibly) cleaned console command
            (string)
        """
        if consoleCmd and consoleCmd[0] == '@':
            return (True, consoleCmd[1:])
        else:
            return (False, consoleCmd)

    ##################################################################
    ## slots below implement creation functions
    ##################################################################
    
    def __createProject(self):
        """
        Private slot to create a new Pyramid project.
        """
        dlg = CreateParametersDialog(self)
        if dlg.exec_() == QDialog.Accepted:
            scaffold, project, overwrite, simulate = dlg.getData()
            
            cmd = self.getPyramidCommand("pcreate")
            args = []
            if overwrite:
                args.append("--overwrite")
            else:
                args.append("--interactive")
            if simulate:
                args.append("--simulate")
            args.append("--scaffold={0}".format(scaffold))
            args.append(project)
            dlg = PyramidDialog(self.trUtf8("Create Pyramid Project"),
                linewrap=False, parent=self.__ui)
            if dlg.startProcess(cmd, args, self.__e5project.getProjectPath()):
                dlg.exec_()
                if dlg.normalExit() and not simulate:
                    # search for files created by pcreate and add them to the project
                    projectPath = os.path.join(self.__e5project.getProjectPath(), project)
                    for entry in os.walk(projectPath):
                        for fileName in entry[2]:
                            fullName = os.path.join(entry[0], fileName)
                            self.__e5project.appendFile(fullName)
                    
                    # create the base directory for translations
                    i18nPath = os.path.join(projectPath, project.lower(), "i18n")
                    if not os.path.exists(i18nPath):
                        os.makedirs(i18nPath)
                    self.__e5project.setDirty(True)
                    
                    self.__setCurrentProject(project)
    
    ##################################################################
    ## methods below implement site related functions
    ##################################################################
    
    def __findProjects(self):
        """
        Private method to determine the relative path of all Pyramid 
        projects (= top level dirs).
        
        @return list of projects (list of string)
        """
        projects = []
        ppath = self.__e5project.getProjectPath()
        for entry in os.listdir(ppath):
            if entry[0] not in "._" and \
               os.path.isdir(os.path.join(ppath, entry)):
                projects.append(entry)
        return projects
    
    def __selectProject(self):
        """
        Private method to select a Pyramid project to work with.
        
        @return selected project (string)
        """
        projects = self.__findProjects()
        if len(projects) == 0:
            project = None
        elif len(projects) == 1:
            project = projects[0]
        else:
            if self.__currentProject is not None:
                try:
                    cur = projects.index(self.__currentProject)
                except ValueError:
                    cur = 0
            else:
                cur = 0
            project, ok = QInputDialog.getItem(
                self.__ui,
                self.trUtf8("Select Pyramid Project"),
                self.trUtf8("Select the Pyramid project to work with."),
                projects,
                cur, False)
            if not ok:
                projects = None
        self.__setCurrentProject(project)
    
    def __projectPath(self):
        """
        Private method to calculate the full path of the Pyramid project.
        
        @exception PyramidNoProjectSelectedException raised, if no project is selected
        @return path of the project (string)
        """
        if self.__currentProject is None:
            self.__selectProject()
        
        if self.__currentProject is None:
            raise PyramidNoProjectSelectedException
        else:
            return os.path.join(self.__e5project.getProjectPath(), 
                                self.__currentProject)
    
    def __setCurrentProject(self, project):
        """
        Private slot to set the current project.
        
        @param project name of the project (string)
        """
        if project is not None and len(project) == 0:
            self.__currentProject = None
        else:
            self.__currentProject = project
        
        if self.__currentProject is None:
            curProject = self.trUtf8("None")
        else:
            curProject = self.__currentProject
        self.selectProjectAct.setText(
            self.trUtf8('&Current Pyramid Project ({0})').format(curProject))
        
        if self.__currentProject is None:
            self.__e5project.pdata["TRANSLATIONPATTERN"] = []
        else:
            # TODO: adjust this to the Pyramid docu
            self.__e5project.pdata["TRANSLATIONPATTERN"] = [
                os.path.join(project, project.lower(), "i18n", "%language%", 
                    "LC_MESSAGES", "%s.po" % project.lower())
            ]
    
    def __project(self):
        """
        Private method to get the name of the current Pyramid project.
        
        @exception PyramidNoProjectSelectedException raised, if no project is selected
        @return name of the project (string)
        """
        if self.__currentProject is None:
            self.__selectProject()
        
        if self.__currentProject is None:
            raise PyramidNoProjectSelectedException
        else:
            return self.__currentProject
    
    ##################################################################
    ## slots below implement run functions
    ##################################################################
    
    def __runServer(self, logging = False):
        """
        Private slot to start the Pyramid Web server.
        
        @param logging flag indicating to enable logging (boolean)
        """
        consoleCmd = self.isSpawningConsole(
            self.__plugin.getPreferences("ConsoleCommand"))[1]
        if consoleCmd:
            try:
                projectPath = self.__projectPath()
            except PyramidNoProjectSelectedException:
                E5MessageBox.warning(self.__ui,
                    self.trUtf8('Run Server'),
                    self.trUtf8('No current Pyramid project selected or no Pyramid '
                                'project created yet. Aborting...'))
                return
            
            args = Utilities.parseOptionString(consoleCmd)
            args[0] = Utilities.getExecutablePath(args[0])
            args.append(self.getPyramidCommand("pserve"))
            if logging:
                args.append("--log-file=server.log")
            args.append("--reload")
            args.append(os.path.join(projectPath, "development.ini"))
            
            if isWindowsPlatform():
                serverProcStarted, pid = \
                    QProcess.startDetached(args[0], args[1:], projectPath)
            else:
                if self.__serverProc is not None:
                    self.__serverProcFinished()
                
                self.__serverProc = QProcess()
                self.__serverProc.finished.connect(self.__serverProcFinished)
                self.__serverProc.setWorkingDirectory(projectPath)
                self.__serverProc.start(args[0], args[1:])
                serverProcStarted = self.__serverProc.waitForStarted()
            if not serverProcStarted:
                E5MessageBox.critical(self.__ui,
                    self.trUtf8('Process Generation Error'),
                    self.trUtf8('The Pyramid server could not be started.'))
    
    def __runLoggingServer(self):
        """
        Private slot to start the Pyramid Web server with logging.
        """
        self.__runServer(True)
    
    def __serverProcFinished(self):
        """
        Private slot connected to the finished signal.
        """
        if self.__serverProc is not None and \
           self.__serverProc.state() != QProcess.NotRunning:
            self.__serverProc.terminate()
            QTimer.singleShot(2000, self.__serverProc.kill)
            self.__serverProc.waitForFinished(3000)
        self.__serverProc = None
    
    def __runBrowser(self):
        """
        Private slot to start the default web browser with the server URL.
        """
        try:
            projectPath = self.__projectPath()
        except PyramidNoProjectSelectedException:
            E5MessageBox.warning(self.__ui,
                self.trUtf8('Run Web-Browser'),
                self.trUtf8('No current Pyramid project selected or no Pyramid project'
                            ' created yet. Aborting...'))
            return
        
        config = configparser.ConfigParser()
        config.read(os.path.join(projectPath, "development.ini"))
        port = config.get("server:main", "port", fallback="6543")
        url = QUrl("http://localhost:{0}".format(port))
        res = QDesktopServices.openUrl(url)
        if not res:
            E5MessageBox.critical(self.__ui,
                self.trUtf8('Run Web-Browser'),
                self.trUtf8('Could not start the web-browser for the URL "{0}".')\
                    .format(url.toString()))
    
    def __runPythonShell(self):
        """
        Private slot to start a Python console for a Pyramid project.
        """
        consoleCmd = self.isSpawningConsole(
            self.__plugin.getPreferences("ConsoleCommand"))[1]
        if consoleCmd:
            try:
                projectPath = self.__projectPath()
            except PyramidNoProjectSelectedException:
                E5MessageBox.warning(self.__ui,
                    self.trUtf8('Start Pyramid Python Console'),
                    self.trUtf8('No current Pyramid project selected or no Pyramid '
                                'project created yet. Aborting...'))
                return
            
            args = Utilities.parseOptionString(consoleCmd)
            args[0] = Utilities.getExecutablePath(args[0])
            args.append(self.getPyramidCommand("pshell"))
            language = self.__e5project.getProjectLanguage()
            if language == "Python2":
                consoleType = self.__plugin.getPreferences("Python2ConsoleType")
            else:
                consoleType = self.__plugin.getPreferences("Python3ConsoleType")
            args.append("--python-shell={0}".format(consoleType))
            args.append(os.path.join(projectPath, "development.ini"))
            
            started, pid = QProcess.startDetached(args[0], args[1:], projectPath)
            if not started:
                E5MessageBox.critical(self.__ui,
                    self.trUtf8('Process Generation Error'),
                    self.trUtf8('The Pyramid Shell process could not be started.'))

    ##################################################################
    ## slots below implement setup functions
    ##################################################################
    
    def __setupDevelop(self):
        """
        Private slot to set up the development environment for the current project.
        """
        title = self.trUtf8("Setup Development Environment")
        
        cmd = self.getPythonCommand()
        args = []
        args.append("setup.py")
        args.append("develop")
        
        try:
            wd = self.__projectPath()
        except PyramidNoProjectSelectedException:
            E5MessageBox.warning(self.__ui,
                title,
                self.trUtf8('No current Pyramid project selected or no Pyramid project'
                            ' created yet. Aborting...'))
            return
        
        dia = PyramidDialog(title, 
            msgSuccess = \
                self.trUtf8("Pyramid development environment setup successfully."))
        res = dia.startProcess(cmd, args, wd)
        if res:
            dia.exec_()
    
    ##################################################################
    ## slots below implement distribution functions
    ##################################################################
    
    def __buildDistribution(self):
        """
        Private slot to build a distribution file for the current Pyramid project.
        """
        title = self.trUtf8("Build Distribution File")
        try:
            projectPath = self.__projectPath()
        except PyramidNoProjectSelectedException:
            E5MessageBox.warning(self.__ui,
                title,
                self.trUtf8('No current Pyramid project selected or no Pyramid project'
                            ' created yet. Aborting...'))
            return
        
        dlg = DistributionTypeSelectionDialog(self, projectPath, self.__ui)
        if dlg.exec_() == QDialog.Accepted:
            formats = dlg.getFormats()
            cmd = self.getPythonCommand()
            args = []
            args.append("setup.py")
            args.append("sdist")
            if formats:
                args.append("--formats={0}".format(','.join(formats)))
            
            dia = PyramidDialog(title, 
                msgSuccess = \
                    self.trUtf8("Python distribution file built successfully."))
            res = dia.startProcess(cmd, args, projectPath)
            if res:
                dia.exec_()
    
    ##################################################################
    ## slots below implement documentation functions
    ##################################################################
    
    def __showDocumentation(self):
        """
        Private slot to show the helpviewer with the Pylons documentation.
        """
        page = self.__plugin.getPreferences("PyramidDocUrl")
        self.__ui.launchHelpViewer(page)

eric ide

mercurial