ProjectDjango/Project.py

changeset 125
d280acf98fb5
parent 122
eb1311184f6f
child 132
576cb5a3b035
--- a/ProjectDjango/Project.py	Sat Jan 27 11:46:33 2018 +0100
+++ b/ProjectDjango/Project.py	Sat Mar 24 19:11:39 2018 +0100
@@ -97,6 +97,7 @@
     Class implementing the Django project support.
     """
     RecentApplicationsKey = "Django/RecentApplications"
+    RecentDatabaseNamesKey = "Django/RecentDatabaseNames"
     
     def __init__(self, plugin, parent=None):
         """
@@ -120,6 +121,9 @@
         self.__recentApplications = []
         self.__loadRecentApplications()
         
+        self.__recentDatabaseNames = []
+        self.__loadRecentDatabaseNames()
+        
         self.__recentTestData = {
             "RecentTestLabels": [],
             "RecentTestTags": [],
@@ -321,6 +325,23 @@
         """
         Private method to define the database related actions.
         """
+        self.selectDatabaseNameAct = E5Action(
+            self.tr('Current Database'),
+            "",
+            0, 0,
+            self, 'django_current_database')
+        self.selectDatabaseNameAct.setStatusTip(self.tr(
+            'Selects the current database'))
+        self.selectDatabaseNameAct.setWhatsThis(self.tr(
+            """<b>Current Database</b>"""
+            """<p>Selects the database name to be used by all database"""
+            """ actions. An empty database name indicates to use the default"""
+            """ name.</p>"""
+        ))
+        self.selectDatabaseNameAct.triggered.connect(self.__selectDatabaseName)
+        self.actions.append(self.selectDatabaseNameAct)
+        self.__setCurrentDatabase(None)
+        
         self.inspectDatabaseAct = E5Action(
             self.tr('Introspect'),
             self.tr('&Introspect'),
@@ -573,6 +594,21 @@
         self.runPythonShellAct.triggered.connect(self.__runPythonShell)
         self.actions.append(self.runPythonShellAct)
     
+        self.testEmailAct = E5Action(
+            self.tr('Send Test Email'),
+            self.tr('Send Test &Email'),
+            0, 0,
+            self, 'django_tools_sendtestemail')
+        self.testEmailAct.setStatusTip(self.tr(
+            'Send a test email through Django'))
+        self.testEmailAct.setWhatsThis(self.tr(
+            """<b>Send Test Email</b>"""
+            """<p>Sends a test email to confirm email sending through Django"""
+            """ is working.</p>"""
+        ))
+        self.testEmailAct.triggered.connect(self.__sendTestEmail)
+        self.actions.append(self.testEmailAct)
+    
     def __initTestingActions(self):
         """
         Private method to define the testing actions.
@@ -863,6 +899,8 @@
         menu = QMenu(self.tr("&Database"), self.__ui)
         menu.setTearOffEnabled(True)
         
+        menu.addAction(self.selectDatabaseNameAct)
+        menu.addSeparator()
         menu.addAction(self.inspectDatabaseAct)
         menu.addSeparator()
         menu.addAction(self.flushDatabaseAct)
@@ -943,6 +981,9 @@
         menu.addAction(self.diffSettingsAct)
         menu.addSeparator()
         menu.addAction(self.runPythonShellAct)
+        if self.getDjangoVersion() >= (1, 9, 0):
+            menu.addSeparator()
+            menu.addAction(self.testEmailAct)
         
         self.__menus["tools"] = menu
         
@@ -1360,12 +1401,14 @@
             else:
                 if language == "Python2":
                     cmds = ["django-admin2.py", "django-admin2",
-                            "django-admin.py-2.7", "django-admin.py-2.6"]
+                            "django-admin.py-2.7", "django-admin.py-2.6"
+                            ]
                 elif language == "Python3":
                     cmds = ["django-admin3.py", "django-admin3",
-                            "django-admin.py-3.6", "django-admin.py-3.5",
-                            "django-admin.py-3.4", "django-admin.py-3.3",
-                            "django-admin.py-3.2"]
+                            "django-admin.py-3.7", "django-admin.py-3.6",
+                            "django-admin.py-3.5", "django-admin.py-3.4",
+                            "django-admin.py-3.3", "django-admin.py-3.2",
+                            ]
                 else:
                     cmds = []
                 cmds.extend(["django-admin.py", "django-admin"])
@@ -2028,7 +2071,8 @@
             args.append("runserver")
             if self.__plugin.getPreferences("UseIPv6"):
                 args.append("--ipv6")
-            # TODO: add support for --nothreading
+            if not self.__plugin.getPreferences("UseThreading"):
+                args.append("--nothreading")
             addr = self.__plugin.getPreferences("ServerAddress")
             if addr:
                 args.append(addr)
@@ -2103,6 +2147,105 @@
             self.__ui.launchHelpViewer(url)
 
     ##################################################################
+    ## slots below implement functions to save and load recently used
+    ## database names
+    ##################################################################
+    
+    def __loadRecentDatabaseNames(self):
+        """
+        Private method to load the list of recently used database names.
+        """
+        self.__recentDatabaseNames = [""]
+        Preferences.Prefs.rsettings.sync()
+        rdb = Preferences.Prefs.rsettings.value(self.RecentDatabaseNamesKey)
+        if rdb is not None:
+            maxRecentDatabaseNames = \
+                self.__plugin.getPreferences("RecentNumberDatabaseNames")
+            self.__recentDatabaseNames = rdb[:maxRecentDatabaseNames]
+    
+    def __saveRecentDatabaseNames(self):
+        """
+        Private method to save the list of recently used database names.
+        """
+        Preferences.Prefs.rsettings.setValue(self.RecentDatabaseNamesKey,
+                                             self.__recentDatabaseNames)
+        Preferences.Prefs.rsettings.sync()
+    
+    def getRecentDatabaseNames(self):
+        """
+        Public method to get the list of recently used database names.
+        
+        @return list of recently used database names
+        @rtype list of str
+        """
+        self.__loadRecentDatabaseNames()
+        return self.__recentDatabaseNames
+    
+    def setMostRecentDatabaseNames(self, dbName):
+        """
+        Public method to set the most recently used database names.
+        
+        @param dbName database name
+        @type str
+        """
+        if dbName in self.__recentDatabaseNames:
+            self.__recentDatabaseNames.remove(dbName)
+        self.__recentDatabaseNames.insert(0, dbName)
+        
+        maxRecentDatabaseNames = \
+            self.__plugin.getPreferences("RecentNumberDatabaseNames")
+        if len(self.__recentDatabaseNames) > maxRecentDatabaseNames:
+            self.__recentDatabaseNames = \
+                self.__recentDatabaseNames[:maxRecentDatabaseNames]
+        self.__saveRecentDatabaseNames()
+    
+    def __selectDatabaseName(self):
+        """
+        Private method to select the name of the database to work with.
+        """
+        recentDatabases = self.getRecentDatabaseNames()[:]
+        if "" not in recentDatabases:
+            recentDatabases.insert(1, "")
+        
+        selectedDatabase, ok = QInputDialog.getItem(
+            self.__ui,
+            self.tr("Database Name"),
+            self.tr("Select a database name (leave empty for default):"),
+            recentDatabases,
+            0, True)
+        
+        if ok:
+            self.setMostRecentDatabaseNames(selectedDatabase)
+            self.__setCurrentDatabase(selectedDatabase)
+    
+    def __setCurrentDatabase(self, database):
+        """
+        Private method to set the database name to be used.
+        
+        @param database name of the database
+        @type str
+        """
+        if database is None:
+            database = self.getRecentDatabaseNames()[0]
+        
+        self.__currentDatabase = database
+        if database:
+            curDb = database
+        else:
+            curDb = self.tr("<default>")
+        self.selectDatabaseNameAct.setText(
+            self.tr('&Current Database ({0})').format(curDb))
+    
+    def currentDatabase(self):
+        """
+        Public method to get the database name to be used.
+        
+        @return database name
+        @rtype str
+        """
+        return self.__currentDatabase
+    
+    ##################################################################
     ## slots below implement database related functions
     ##################################################################
     
@@ -2117,7 +2260,8 @@
         args.append(self.__getPythonExecutable())
         args.append("manage.py")
         args.append("inspectdb")
-        # TODO: add support for --database DATABASE for Django 1.9.0+
+        if self.__currentDatabase:
+            args.append("--database={0}".format(self.__currentDatabase))
         
         try:
             path = self.__sitePath()
@@ -2152,7 +2296,8 @@
             args.append("manage.py")
             args.append("flush")
             args.append("--noinput")
-            # TODO: add support for --database DATABASE for Django 1.9.0+
+            if self.__currentDatabase:
+                args.append("--database={0}".format(self.__currentDatabase))
             
             dia = DjangoDialog(
                 title,
@@ -2174,7 +2319,8 @@
             args.append(self.__getPythonExecutable())
             args.append("manage.py")
             args.append("dbshell")
-            # TODO: add support for --database DATABASE for Django 1.9.0+
+            if self.__currentDatabase:
+                args.append("--database={0}".format(self.__currentDatabase))
             try:
                 wd = self.__sitePath()
                 self.__adjustWorkingDirectory(args, wd)
@@ -2216,7 +2362,8 @@
         args.append(self.__getPythonExecutable())
         args.append("manage.py")
         args.append(command)
-        # TODO: add support for --database DATABASE for Django 1.9.0+
+        if self.__currentDatabase:
+            args.append("--database={0}".format(self.__currentDatabase))
         args += apps
         
         fileFilter = self.tr("SQL Files (*.sql)")
@@ -2330,9 +2477,10 @@
             args.append(self.__getPythonExecutable())
             args.append("manage.py")
             args.append("sqlmigrate")
+            if self.__currentDatabase:
+                args.append("--database={0}".format(self.__currentDatabase))
             if backwards:
                 args.append("--backwards")
-            # TODO: add support for --database DATABASE for Django 1.9.0+
             args.append(app)
             args.append(migration)
             
@@ -2361,7 +2509,8 @@
         self.__migrationsListDialog = DjangoMigrationsListDialog(
             DjangoMigrationsListDialog.MigrationsListMode, self, self.__ui)
         self.__migrationsListDialog.show()
-        self.__migrationsListDialog.start(self.__getPythonExecutable(), path)
+        self.__migrationsListDialog.start(self.__getPythonExecutable(), path,
+                                          self.__currentDatabase)
     
     def __showMigrationsPlan(self):
         """
@@ -2376,7 +2525,8 @@
         self.__migrationsPlanDialog = DjangoMigrationsListDialog(
             DjangoMigrationsListDialog.MigrationsPlanMode, self, self.__ui)
         self.__migrationsPlanDialog.show()
-        self.__migrationsPlanDialog.start(self.__getPythonExecutable(), path)
+        self.__migrationsPlanDialog.start(self.__getPythonExecutable(), path,
+                                          self.__currentDatabase)
     
     def __applyAllMigrations(self):
         """
@@ -2475,7 +2625,9 @@
         args.append("manage.py")
         args.append("showmigrations")
         args.append("--list")
-        # TODO: add support for --database DATABASE for Django 1.9.0+
+        if self.getDjangoVersion() >= (1, 9, 0):
+            if self.__currentDatabase:
+                args.append("--database={0}".format(self.__currentDatabase))
         
         migrations = {}
         proc = QProcess()
@@ -2509,13 +2661,14 @@
         from .DjangoMakeMigrationsDialog import DjangoMakeMigrationsDialog
         dlg = DjangoMakeMigrationsDialog(self.getRecentApplications())
         if dlg.exec_() == QDialog.Accepted:
-            apps, migration, dryRun, empty = dlg.getData()
+            apps, migration, dryRun, empty, merge = dlg.getData()
             if apps:
                 self.setMostRecentApplication(apps)
             apps = apps.split()
-            self.makeMigrations(apps, migration, dryRun, empty)
+            self.makeMigrations(apps, migration, dryRun, empty, merge)
     
-    def makeMigrations(self, apps, migration=None, dryRun=False, empty=False):
+    def makeMigrations(self, apps, migration=None, dryRun=False, empty=False,
+                       merge=False):
         """
         Public method to generate migrations.
         
@@ -2527,6 +2680,8 @@
         @type bool
         @param empty flag indicating the creation of an empty migration
         @type bool
+        @param merge flag indicating to fix migration conflicts
+        @type bool
         """
         title = self.tr("Make Migrations")
         
@@ -2546,7 +2701,8 @@
             args.append("--dry-run")
         if empty:
             args.append("--empty")
-        # TODO: add support for --merge (Enables fixing of migration conflicts.)
+        if merge:
+            args.append("--merge")
         if apps:
             args += apps
         
@@ -2570,34 +2726,35 @@
         from .DjangoSquashMigrationSelectionDialog import \
             DjangoSquashMigrationSelectionDialog
         dlg = DjangoSquashMigrationSelectionDialog(
-            migrations, self.getDjangoVersion() >= (1, 9, 0))
+            migrations, self)
         if dlg.exec_() == QDialog.Accepted:
-            app, start, end, noOptimize = dlg.getData()
-        
-        title = self.tr("Squash Migrations")
-        
-        try:
-            path = self.__sitePath()
-        except DjangoNoSiteSelectedException:
-            return
-        
-        args = []
-        args.append(self.__getPythonExecutable())
-        args.append("manage.py")
-        args.append("squashmigrations")
-        args.append("--noinput")
-        if noOptimize:
-            args.append("--no-optimize")
-        # TODO: add --squashed-name SQUASHED_NAME for Django 2.0.0+
-        args.append(app)
-        if start:
-            args.append(start)
-        args.append(end)
-        
-        dia = DjangoDialog(title)
-        res = dia.startProcess(args, path)
-        if res:
-            dia.exec_()
+            app, start, end, noOptimize, name = dlg.getData()
+            
+            title = self.tr("Squash Migrations")
+            
+            try:
+                path = self.__sitePath()
+            except DjangoNoSiteSelectedException:
+                return
+            
+            args = []
+            args.append(self.__getPythonExecutable())
+            args.append("manage.py")
+            args.append("squashmigrations")
+            args.append("--noinput")
+            if noOptimize:
+                args.append("--no-optimize")
+            if name:
+                args.append("--squashed-name={0}".format(name))
+            args.append(app)
+            if start:
+                args.append(start)
+            args.append(end)
+            
+            dia = DjangoDialog(title)
+            res = dia.startProcess(args, path)
+            if res:
+                dia.exec_()
     
     ##################################################################
     ## slots below implement some tool functions
@@ -2609,23 +2766,31 @@
         """
         title = self.tr("Diff Settings")
         
-        args = []
-        args.append(self.__getPythonExecutable())
-        args.append("manage.py")
-        args.append("diffsettings")
-        # TODO: add support for --default MODULE as of Django 1.11.0
-        # TODO: add support for --output {hash,unified} as of Django 2.0.0
-        #       with hash being the default
-        
-        try:
-            path = self.__sitePath()
-        except DjangoNoSiteSelectedException:
-            return
-        
-        dia = DjangoDialog(title, fixed=True, linewrap=False)
-        res = dia.startProcess(args, path, False)
-        if res:
-            dia.exec_()
+        from .DjangoDiffsettingsDataDialog import DjangoDiffsettingsDataDialog
+        dlg = DjangoDiffsettingsDataDialog(self, self.__ui)
+        if dlg.exec_() == QDialog.Accepted:
+            showAll, defaultModule, outputFormat = dlg.getData()
+            
+            args = []
+            args.append(self.__getPythonExecutable())
+            args.append("manage.py")
+            args.append("diffsettings")
+            if showAll:
+                args.append("--all")
+            if defaultModule:
+                args.append("--default={0}".format(defaultModule))
+            if outputFormat:
+                args.append("--output={0}".format(outputFormat))
+            
+            try:
+                path = self.__sitePath()
+            except DjangoNoSiteSelectedException:
+                return
+            
+            dia = DjangoDialog(title, fixed=True, linewrap=False)
+            res = dia.startProcess(args, path, False)
+            if res:
+                dia.exec_()
     
     def __runPythonShell(self):
         """
@@ -2640,14 +2805,22 @@
             args.append("manage.py")
             args.append("shell")
             language = self.__e5project.getProjectLanguage()
-            # TODO: add support for --interface {ipython,bpython,python} as of Djanngo 1.10.0
-            # TODO: don't use this for Django 1.10.0+
             if language == "Python2":
-                if self.__plugin.getPreferences("UsePlainPythonPy2"):
-                    args.append("--plain")
+                if self.getDjangoVersion() < (1, 10, 0):
+                    if (self.__plugin.getPreferences("Python2ConsoleType") ==
+                            "python"):
+                        args.append("--plain")
+                else:
+                    args.append("--interface={0}".format(
+                        self.__plugin.getPreferences("Python2ConsoleType")))
             else:
-                if self.__plugin.getPreferences("UsePlainPythonPy3"):
-                    args.append("--plain")
+                if self.getDjangoVersion() < (1, 10, 0):
+                    if (self.__plugin.getPreferences("Python3ConsoleType") ==
+                            "python"):
+                        args.append("--plain")
+                else:
+                    args.append("--interface={0}".format(
+                        self.__plugin.getPreferences("Python3ConsoleType")))
             try:
                 wd = self.__sitePath()
                 self.__adjustWorkingDirectory(args, wd)
@@ -2660,6 +2833,46 @@
             except DjangoNoSiteSelectedException:
                 pass
     
+    def __sendTestEmail(self):
+        """
+        Private slot to send a test email through Django.
+        """
+        if self.getDjangoVersion() < (1, 9, 0):
+            return
+        
+        title = self.tr("Send Test Email")
+        
+        from .DjangoSendTestEmailDataDialog import \
+            DjangoSendTestEmailDataDialog
+        dlg = DjangoSendTestEmailDataDialog(self.__ui)
+        if dlg.exec_() == QDialog.Accepted:
+            managers, admins, recipients = dlg.getData()
+            
+            args = []
+            args.append(self.__getPythonExecutable())
+            args.append("manage.py")
+            args.append("sendtestemail")
+            if managers:
+                args.append("--managers")
+            if admins:
+                args.append("--admins")
+            args.extend(recipients)
+            
+            try:
+                path = self.__sitePath()
+            except DjangoNoSiteSelectedException:
+                return
+            
+            dia = DjangoDialog(
+                title,
+                linewrap=False,
+                msgSuccess=self.tr("Test Email sent successfully."),
+                msgError=self.tr("Test Email could not be sent.")
+            )
+            res = dia.startProcess(args, path, False)
+            if res:
+                dia.exec_()
+    
     ##################################################################
     ## slots below implement caching functions
     ##################################################################
@@ -2668,8 +2881,6 @@
         """
         Private slot to create the tables for the SQL caching backend.
         """
-        # TODO: this doesn't need the tables anymore
-        # TODO: add support for the --database DATABASE option for Django 1.9.0+
         title = self.tr("Create Cache Tables")
         
         try:
@@ -2677,27 +2888,19 @@
         except DjangoNoSiteSelectedException:
             return
         
-        tblStr, ok = QInputDialog.getText(
-            self.__ui,
+        args = []
+        args.append(self.__getPythonExecutable())
+        args.append("manage.py")
+        args.append("createcachetable")
+        if self.__currentDatabase:
+            args.append("--database={0}".format(self.__currentDatabase))
+        
+        dia = DjangoDialog(
             title,
-            self.tr("Enter the names of the cache tables separated by"
-                    " spaces."),
-            QLineEdit.Normal)
-        if ok and tblStr != "":
-            tableNames = tblStr.split()
-            
-            args = []
-            args.append(self.__getPythonExecutable())
-            args.append("manage.py")
-            args.append("createcachetable")
-            args += tableNames
-            
-            dia = DjangoDialog(
-                title,
-                msgSuccess=self.tr("Cache tables created successfully."))
-            res = dia.startProcess(args, wd)
-            if res:
-                dia.exec_()
+            msgSuccess=self.tr("Cache tables created successfully."))
+        res = dia.startProcess(args, wd)
+        if res:
+            dia.exec_()
     
     ##################################################################
     ## slots below implement testing functions
@@ -2727,7 +2930,10 @@
             args.append("--indent={0}".format(indent))
             for excl in excls:
                 args.append("--exclude={0}".format(excl))
-            # TODO: add support for --database DATABASE for Django 1.9.0+
+            if self.getDjangoVersion() >= (1, 9, 0):
+                if self.__currentDatabase:
+                    args.append("--database={0}".format(
+                        self.__currentDatabase))
             args += appls
             
             if dumpFormat == "json":
@@ -2754,20 +2960,24 @@
         except DjangoNoSiteSelectedException:
             return
         
-        # TODO: use the old DjangoLoaddataDataDialog for __runTestServer before modifying this
         from .DjangoLoaddataDataDialog import DjangoLoaddataDataDialog
         dlg = DjangoLoaddataDataDialog(self, self.__ui)
         if dlg.exec_() == QDialog.Accepted:
-            fixtures = dlg.getData()
+            fixtures, excludes, appLabel, ignore = dlg.getData()
             
             args = []
             args.append(self.__getPythonExecutable())
             args.append("manage.py")
             args.append("loaddata")
-            # TODO: add support for --exclude EXCLUDE as of Django 1.11.0
-            # TODO: add support for --ignorenonexistent
-            # TODO: add support for --database DATABASE for Django 1.9.0+
-            # TODO: add support for --app APP_LABEL
+            if self.getDjangoVersion() >= (1, 11, 0):
+                for excl in excludes:
+                    args.append("--exclude={0}".format(excl))
+            if ignore:
+                args.append("--ignorenonexistent")
+            if appLabel:
+                args.append("--app={0}".format(appLabel))
+            if self.__currentDatabase:
+                args.append("--database={0}".format(self.__currentDatabase))
             args += fixtures
             
             dia = DjangoDialog(title)
@@ -2835,9 +3045,9 @@
         consoleCmd = self.__isSpawningConsole(
             self.__plugin.getPreferences("ConsoleCommand"))[1]
         if consoleCmd:
-            # TODO: use the old DjangoLoaddataDataDialog for this
-            from .DjangoLoaddataDataDialog import DjangoLoaddataDataDialog
-            dlg = DjangoLoaddataDataDialog(self, self.__ui)
+            from .DjangoRunTestServerDataDialog import \
+                DjangoRunTestServerDataDialog
+            dlg = DjangoRunTestServerDataDialog(self, self.__ui)
             if dlg.exec_() == QDialog.Accepted:
                 fixtures = dlg.getData()
                 
@@ -3046,9 +3256,7 @@
         args.append(self.__getPythonExecutable())
         args.append("manage.py")
         args.append("makemessages")
-        # TODO: rename this --locale
-        args.append("-l")
-        args.append(code)
+        args.append("--locale={0}".format(code))
         
         try:
             wd = self.__sitePath()
@@ -3100,11 +3308,8 @@
                 args.append(self.__getPythonExecutable())
                 args.append("manage.py")
                 args.append("makemessages")
-                # TODO: this seems to be not supported anymore
                 args.append("--no-obsolete")
-                # TODO: rename this --locale
-                args.append("-l")
-                args.append(locale)
+                args.append("--locale={0}".format(locale))
                 argsLists.append(args)
         
         if len(argsLists) == 0:
@@ -3150,9 +3355,7 @@
                 args.append(self.__getPythonExecutable())
                 args.append("manage.py")
                 args.append("makemessages")
-                # TODO: rename this --locale
-                args.append("-l")
-                args.append(locale)
+                args.append("--locale={0}".format(locale))
                 argsLists.append(args)
         
         if len(argsLists) == 0:
@@ -3181,8 +3384,7 @@
         args.append(self.__getPythonExecutable())
         args.append("manage.py")
         args.append("makemessages")
-        args.append("-a")
-        # TODO: this seems to be not supported anymore
+        args.append("--all")
         args.append("--no-obsolete")
         
         try:
@@ -3215,7 +3417,7 @@
         args.append(self.__getPythonExecutable())
         args.append("manage.py")
         args.append("makemessages")
-        args.append("-a")
+        args.append("--all")
         
         try:
             wd = self.__sitePath()
@@ -3262,9 +3464,10 @@
                 args.append(self.__getPythonExecutable())
                 args.append("manage.py")
                 args.append("compilemessages")
-                args.append("-l")
-                args.append(locale)
-                # TODO: add support for --use-fuzzy per Preferences
+                args.append("--locale={0}".format(locale))
+                if self.getDjangoVersion() >= (1, 8, 0):
+                    if self.__plugin.getPreferences("FuzzyTranslations"):
+                        args.append("--use-fuzzy")
                 argsLists.append(args)
         
         if len(argsLists) == 0:
@@ -3300,7 +3503,9 @@
         args.append(self.__getPythonExecutable())
         args.append("manage.py")
         args.append("compilemessages")
-        # TODO: add support for --use-fuzzy per Preferences
+        if self.getDjangoVersion() >= (1, 8, 0):
+            if self.__plugin.getPreferences("FuzzyTranslations"):
+                args.append("--use-fuzzy")
         
         try:
             wd = self.__sitePath()
@@ -3389,8 +3594,3 @@
             res = dia.startProcess(args, path, mergedOutput=True)
             if res:
                 dia.exec_()
-    
-    # TODO: add support for sendtestemail for Django 1.9.0+
-    #       sendtestemail [email [email ...]]
-    #       --managers      Mails the email addresses specified in MANAGERS using mail_managers().
-    #       --admins        Mails the email addresses specified in ADMINS using mail_admins().

eric ide

mercurial