ProjectPyramid/Project.py

branch
eric7
changeset 147
eb28b4b6f7f5
parent 144
5c3684ee818e
child 148
dcbd3a96f03c
equal deleted inserted replaced
146:7d955b1995d5 147:eb28b4b6f7f5
10 import os 10 import os
11 import re 11 import re
12 import configparser 12 import configparser
13 import contextlib 13 import contextlib
14 14
15 from PyQt5.QtCore import QObject, QFileInfo, QTimer, QUrl 15 from PyQt6.QtCore import QObject, QFileInfo, QTimer, QUrl, QIODeviceBase
16 from PyQt5.QtGui import QDesktopServices 16 from PyQt6.QtGui import QDesktopServices
17 from PyQt5.QtWidgets import QMenu, QDialog, QInputDialog, QLineEdit 17 from PyQt6.QtWidgets import QMenu, QDialog, QInputDialog, QLineEdit
18 from PyQt5.QtCore import QProcess as QProcessPyQt 18 from PyQt6.QtCore import QProcess as QProcessPyQt
19 19
20 from E5Gui.E5Application import e5App 20 from EricWidgets.EricApplication import ericApp
21 from E5Gui import E5MessageBox, E5FileDialog 21 from EricWidgets import EricMessageBox, EricFileDialog
22 from E5Gui.E5Action import E5Action 22 from EricGui.EricAction import EricAction
23 23
24 from .PyramidDialog import PyramidDialog 24 from .PyramidDialog import PyramidDialog
25 25
26 import Preferences 26 import Preferences
27 import Utilities 27 import Utilities
38 38
39 class QProcess(QProcessPyQt): 39 class QProcess(QProcessPyQt):
40 """ 40 """
41 Class transforming the call arguments in case of gnome-terminal. 41 Class transforming the call arguments in case of gnome-terminal.
42 """ 42 """
43 def start(self, cmd, args=None, mode=QProcessPyQt.ReadWrite): 43 def start(self, cmd, args=None, mode=QIODeviceBase.OpenModeFlag.ReadWrite):
44 """ 44 """
45 Public method to start the given program (cmd) in a new process, if 45 Public method to start the given program (cmd) in a new process, if
46 none is already running, passing the command line arguments in args. 46 none is already running, passing the command line arguments in args.
47 47
48 @param cmd start the given program cmd (string) 48 @param cmd start the given program cmd
49 @keyparam args list of parameters (list of strings) 49 @type str
50 @keyparam mode access mode (QIODevice.OpenMode) 50 @param args list of parameters
51 @type list of str
52 @param mode access mode
53 @type QIODeviceBase.OpenMode
51 """ 54 """
52 if args is None: 55 if args is None:
53 args = [] 56 args = []
54 57
55 if ( 58 if (
67 def startDetached(cmd, args=None, path=''): 70 def startDetached(cmd, args=None, path=''):
68 """ 71 """
69 Public static method to start the given program (cmd) in a new process, 72 Public static method to start the given program (cmd) in a new process,
70 if none is already running, passing the command line arguments in args. 73 if none is already running, passing the command line arguments in args.
71 74
72 @param cmd start the given program cmd (string) 75 @param cmd start the given program cmd
73 @keyparam args list of parameters (list of strings) 76 @type str
74 @keyparam path new working directory (string) 77 @param args list of parameters
75 @return tuple of successful start and process id (boolean, integer) 78 @type list of str
79 @param path new working directory
80 @type str
81 @return tuple of successful start and process id
82 @rtype tuple of (bool, int)
76 """ 83 """
77 if args is None: 84 if args is None:
78 args = [] 85 args = []
79 86
80 if ( 87 if (
107 super().__init__(parent) 114 super().__init__(parent)
108 115
109 self.__plugin = plugin 116 self.__plugin = plugin
110 self.__iconSuffix = iconSuffix 117 self.__iconSuffix = iconSuffix
111 self.__ui = parent 118 self.__ui = parent
112 self.__e5project = e5App().getObject("Project") 119 self.__ericProject = ericApp().getObject("Project")
113 try: 120 self.__virtualEnvManager = ericApp().getObject("VirtualEnvManager")
114 self.__virtualEnvManager = e5App().getObject("VirtualEnvManager")
115 except KeyError:
116 self.__virtualEnvManager = None
117 self.__hooksInstalled = False 121 self.__hooksInstalled = False
118 122
119 self.__menus = {} # dictionary with references to menus 123 self.__menus = {} # dictionary with references to menus
120 124
121 self.__serverProc = None 125 self.__serverProc = None
126 """ 130 """
127 Public method to define the Pyramid actions. 131 Public method to define the Pyramid actions.
128 """ 132 """
129 self.actions = [] 133 self.actions = []
130 134
131 self.selectProjectAct = E5Action( 135 self.selectProjectAct = EricAction(
132 self.tr('Current Pyramid Project'), 136 self.tr('Current Pyramid Project'),
133 "", 137 "",
134 0, 0, 138 0, 0,
135 self, 'pyramid_current_project') 139 self, 'pyramid_current_project')
136 self.selectProjectAct.setStatusTip(self.tr( 140 self.selectProjectAct.setStatusTip(self.tr(
145 149
146 ############################### 150 ###############################
147 ## create actions below ## 151 ## create actions below ##
148 ############################### 152 ###############################
149 153
150 self.createProjectAct = E5Action( 154 self.createProjectAct = EricAction(
151 self.tr('Create Pyramid Project'), 155 self.tr('Create Pyramid Project'),
152 self.tr('Create Pyramid &Project'), 156 self.tr('Create Pyramid &Project'),
153 0, 0, 157 0, 0,
154 self, 'pyramid_create_project') 158 self, 'pyramid_create_project')
155 self.createProjectAct.setStatusTip(self.tr( 159 self.createProjectAct.setStatusTip(self.tr(
163 167
164 ############################## 168 ##############################
165 ## run actions below ## 169 ## run actions below ##
166 ############################## 170 ##############################
167 171
168 self.runServerAct = E5Action( 172 self.runServerAct = EricAction(
169 self.tr('Run Server'), 173 self.tr('Run Server'),
170 self.tr('Run &Server'), 174 self.tr('Run &Server'),
171 0, 0, 175 0, 0,
172 self, 'pyramid_run_server') 176 self, 'pyramid_run_server')
173 self.runServerAct.setStatusTip(self.tr( 177 self.runServerAct.setStatusTip(self.tr(
178 """ "pserve --reload development.ini".</p>""" 182 """ "pserve --reload development.ini".</p>"""
179 )) 183 ))
180 self.runServerAct.triggered.connect(self.__runServer) 184 self.runServerAct.triggered.connect(self.__runServer)
181 self.actions.append(self.runServerAct) 185 self.actions.append(self.runServerAct)
182 186
183 self.runLoggingServerAct = E5Action( 187 self.runLoggingServerAct = EricAction(
184 self.tr('Run Server with Logging'), 188 self.tr('Run Server with Logging'),
185 self.tr('Run Server with &Logging'), 189 self.tr('Run Server with &Logging'),
186 0, 0, 190 0, 0,
187 self, 'pyramid_run_logging_server') 191 self, 'pyramid_run_logging_server')
188 self.runLoggingServerAct.setStatusTip(self.tr( 192 self.runLoggingServerAct.setStatusTip(self.tr(
193 """ "pserve --log-file=server.log --reload development.ini".</p>""" 197 """ "pserve --log-file=server.log --reload development.ini".</p>"""
194 )) 198 ))
195 self.runLoggingServerAct.triggered.connect(self.__runLoggingServer) 199 self.runLoggingServerAct.triggered.connect(self.__runLoggingServer)
196 self.actions.append(self.runLoggingServerAct) 200 self.actions.append(self.runLoggingServerAct)
197 201
198 self.runBrowserAct = E5Action( 202 self.runBrowserAct = EricAction(
199 self.tr('Run Web-Browser'), 203 self.tr('Run Web-Browser'),
200 self.tr('Run &Web-Browser'), 204 self.tr('Run &Web-Browser'),
201 0, 0, 205 0, 0,
202 self, 'pyramid_run_browser') 206 self, 'pyramid_run_browser')
203 self.runBrowserAct.setStatusTip(self.tr( 207 self.runBrowserAct.setStatusTip(self.tr(
209 """Pyramid Web server.</p>""" 213 """Pyramid Web server.</p>"""
210 )) 214 ))
211 self.runBrowserAct.triggered.connect(self.__runBrowser) 215 self.runBrowserAct.triggered.connect(self.__runBrowser)
212 self.actions.append(self.runBrowserAct) 216 self.actions.append(self.runBrowserAct)
213 217
214 self.runPythonShellAct = E5Action( 218 self.runPythonShellAct = EricAction(
215 self.tr('Start Pyramid Python Console'), 219 self.tr('Start Pyramid Python Console'),
216 self.tr('Start Pyramid &Python Console'), 220 self.tr('Start Pyramid &Python Console'),
217 0, 0, 221 0, 0,
218 self, 'pyramid_python_console') 222 self, 'pyramid_python_console')
219 self.runPythonShellAct.setStatusTip(self.tr( 223 self.runPythonShellAct.setStatusTip(self.tr(
227 231
228 ############################## 232 ##############################
229 ## setup actions below ## 233 ## setup actions below ##
230 ############################## 234 ##############################
231 235
232 self.setupDevelopAct = E5Action( 236 self.setupDevelopAct = EricAction(
233 self.tr('Setup Development Environment'), 237 self.tr('Setup Development Environment'),
234 self.tr('Setup &Development Environment'), 238 self.tr('Setup &Development Environment'),
235 0, 0, 239 0, 0,
236 self, 'pyramid_setup_development') 240 self, 'pyramid_setup_development')
237 self.setupDevelopAct.setStatusTip(self.tr( 241 self.setupDevelopAct.setStatusTip(self.tr(
246 250
247 ############################### 251 ###############################
248 ## database actions below ## 252 ## database actions below ##
249 ############################### 253 ###############################
250 254
251 self.initializeDbAct = E5Action( 255 self.initializeDbAct = EricAction(
252 self.tr('Initialize Database'), 256 self.tr('Initialize Database'),
253 self.tr('Initialize &Database'), 257 self.tr('Initialize &Database'),
254 0, 0, 258 0, 0,
255 self, 'pyramid_initialize_database') 259 self, 'pyramid_initialize_database')
256 self.initializeDbAct.setStatusTip(self.tr( 260 self.initializeDbAct.setStatusTip(self.tr(
266 270
267 ############################### 271 ###############################
268 ## show actions below ## 272 ## show actions below ##
269 ############################### 273 ###############################
270 274
271 self.showViewsAct = E5Action( 275 self.showViewsAct = EricAction(
272 self.tr('Show Matching Views'), 276 self.tr('Show Matching Views'),
273 self.tr('Show Matching &Views'), 277 self.tr('Show Matching &Views'),
274 0, 0, 278 0, 0,
275 self, 'pyramid_show_views') 279 self, 'pyramid_show_views')
276 self.showViewsAct.setStatusTip(self.tr( 280 self.showViewsAct.setStatusTip(self.tr(
280 """<p>Show views matching a given URL.</p>""" 284 """<p>Show views matching a given URL.</p>"""
281 )) 285 ))
282 self.showViewsAct.triggered.connect(self.__showMatchingViews) 286 self.showViewsAct.triggered.connect(self.__showMatchingViews)
283 self.actions.append(self.showViewsAct) 287 self.actions.append(self.showViewsAct)
284 288
285 self.showRoutesAct = E5Action( 289 self.showRoutesAct = EricAction(
286 self.tr('Show Routes'), 290 self.tr('Show Routes'),
287 self.tr('Show &Routes'), 291 self.tr('Show &Routes'),
288 0, 0, 292 0, 0,
289 self, 'pyramid_show_routes') 293 self, 'pyramid_show_routes')
290 self.showRoutesAct.setStatusTip(self.tr( 294 self.showRoutesAct.setStatusTip(self.tr(
295 """ in the order in which they are evaluated.</p>""" 299 """ in the order in which they are evaluated.</p>"""
296 )) 300 ))
297 self.showRoutesAct.triggered.connect(self.__showRoutes) 301 self.showRoutesAct.triggered.connect(self.__showRoutes)
298 self.actions.append(self.showRoutesAct) 302 self.actions.append(self.showRoutesAct)
299 303
300 self.showTweensAct = E5Action( 304 self.showTweensAct = EricAction(
301 self.tr('Show Tween Objects'), 305 self.tr('Show Tween Objects'),
302 self.tr('Show &Tween Objects'), 306 self.tr('Show &Tween Objects'),
303 0, 0, 307 0, 0,
304 self, 'pyramid_show_routes') 308 self, 'pyramid_show_routes')
305 self.showTweensAct.setStatusTip(self.tr( 309 self.showTweensAct.setStatusTip(self.tr(
315 319
316 ################################## 320 ##################################
317 ## distribution actions below ## 321 ## distribution actions below ##
318 ################################## 322 ##################################
319 323
320 self.buildDistroAct = E5Action( 324 self.buildDistroAct = EricAction(
321 self.tr('Build Distribution'), 325 self.tr('Build Distribution'),
322 self.tr('Build &Distribution'), 326 self.tr('Build &Distribution'),
323 0, 0, 327 0, 0,
324 self, 'pyramid_build_distribution') 328 self, 'pyramid_build_distribution')
325 self.buildDistroAct.setStatusTip(self.tr( 329 self.buildDistroAct.setStatusTip(self.tr(
334 338
335 ################################## 339 ##################################
336 ## documentation action below ## 340 ## documentation action below ##
337 ################################## 341 ##################################
338 342
339 self.documentationAct = E5Action( 343 self.documentationAct = EricAction(
340 self.tr('Documentation'), 344 self.tr('Documentation'),
341 self.tr('D&ocumentation'), 345 self.tr('D&ocumentation'),
342 0, 0, 346 0, 0,
343 self, 'pyramid_documentation') 347 self, 'pyramid_documentation')
344 self.documentationAct.setStatusTip(self.tr( 348 self.documentationAct.setStatusTip(self.tr(
352 356
353 ############################## 357 ##############################
354 ## about action below ## 358 ## about action below ##
355 ############################## 359 ##############################
356 360
357 self.aboutPyramidAct = E5Action( 361 self.aboutPyramidAct = EricAction(
358 self.tr('About Pyramid'), 362 self.tr('About Pyramid'),
359 self.tr('About P&yramid'), 363 self.tr('About P&yramid'),
360 0, 0, 364 0, 0,
361 self, 'pyramid_about') 365 self, 'pyramid_about')
362 self.aboutPyramidAct.setStatusTip(self.tr( 366 self.aboutPyramidAct.setStatusTip(self.tr(
372 376
373 def initMenu(self): 377 def initMenu(self):
374 """ 378 """
375 Public slot to initialize the Pyramid menu. 379 Public slot to initialize the Pyramid menu.
376 380
377 @return the menu generated (QMenu) 381 @return the menu generated
382 @rtype QMenu
378 """ 383 """
379 self.__menus = {} # clear menus references 384 self.__menus = {} # clear menus references
380 385
381 menu = QMenu(self.tr('P&yramid'), self.__ui) 386 menu = QMenu(self.tr('P&yramid'), self.__ui)
382 menu.setTearOffEnabled(True) 387 menu.setTearOffEnabled(True)
411 416
412 def getMenu(self, name): 417 def getMenu(self, name):
413 """ 418 """
414 Public method to get a reference to the requested menu. 419 Public method to get a reference to the requested menu.
415 420
416 @param name name of the menu (string) 421 @param name name of the menu
417 @return reference to the menu (QMenu) or None, if no 422 @type str
418 menu with the given name exists 423 @return reference to the menu or None, if no menu with the given
424 name exists
425 @rtype QMenu
419 """ 426 """
420 if name in self.__menus: 427 if name in self.__menus:
421 return self.__menus[name] 428 return self.__menus[name]
422 else: 429 else:
423 return None 430 return None
424 431
425 def getMenuNames(self): 432 def getMenuNames(self):
426 """ 433 """
427 Public method to get the names of all menus. 434 Public method to get the names of all menus.
428 435
429 @return menu names (list of string) 436 @return menu names
437 @rtype list of str
430 """ 438 """
431 return list(self.__menus.keys()) 439 return list(self.__menus.keys())
432 440
433 def registerOpenHook(self): 441 def registerOpenHook(self):
434 """ 442 """
447 455
448 def projectOpenedHooks(self): 456 def projectOpenedHooks(self):
449 """ 457 """
450 Public method to add our hook methods. 458 Public method to add our hook methods.
451 """ 459 """
452 if self.__e5project.getProjectType() == "Pyramid": 460 if self.__ericProject.getProjectType() == "Pyramid":
453 self.__formsBrowser = ( 461 self.__formsBrowser = (
454 e5App().getObject("ProjectBrowser") 462 ericApp().getObject("ProjectBrowser")
455 .getProjectBrowser("forms")) 463 .getProjectBrowser("forms"))
456 self.__formsBrowser.addHookMethodAndMenuEntry( 464 self.__formsBrowser.addHookMethodAndMenuEntry(
457 "newForm", self.newForm, self.tr("New template...")) 465 "newForm", self.newForm, self.tr("New template..."))
458 466
459 self.__e5project.projectLanguageAddedByCode.connect( 467 self.__ericProject.projectLanguageAddedByCode.connect(
460 self.__projectLanguageAdded) 468 self.__projectLanguageAdded)
461 self.__translationsBrowser = ( 469 self.__translationsBrowser = (
462 e5App().getObject("ProjectBrowser") 470 ericApp().getObject("ProjectBrowser")
463 .getProjectBrowser("translations")) 471 .getProjectBrowser("translations"))
464 self.__translationsBrowser.addHookMethodAndMenuEntry( 472 self.__translationsBrowser.addHookMethodAndMenuEntry(
465 "extractMessages", self.extractMessages, 473 "extractMessages", self.extractMessages,
466 self.tr("Extract Messages")) 474 self.tr("Extract Messages"))
467 self.__translationsBrowser.addHookMethodAndMenuEntry( 475 self.__translationsBrowser.addHookMethodAndMenuEntry(
487 """ 495 """
488 if self.__hooksInstalled: 496 if self.__hooksInstalled:
489 self.__formsBrowser.removeHookMethod("newForm") 497 self.__formsBrowser.removeHookMethod("newForm")
490 self.__formsBrowser = None 498 self.__formsBrowser = None
491 499
492 self.__e5project.projectLanguageAddedByCode.disconnect( 500 self.__ericProject.projectLanguageAddedByCode.disconnect(
493 self.__projectLanguageAdded) 501 self.__projectLanguageAdded)
494 self.__translationsBrowser.removeHookMethod("extractMessages") 502 self.__translationsBrowser.removeHookMethod("extractMessages")
495 self.__translationsBrowser.removeHookMethod("releaseAll") 503 self.__translationsBrowser.removeHookMethod("releaseAll")
496 self.__translationsBrowser.removeHookMethod("releaseSelected") 504 self.__translationsBrowser.removeHookMethod("releaseSelected")
497 self.__translationsBrowser.removeHookMethod("generateAll") 505 self.__translationsBrowser.removeHookMethod("generateAll")
503 511
504 def newForm(self, path): 512 def newForm(self, path):
505 """ 513 """
506 Public method to create a new form. 514 Public method to create a new form.
507 515
508 @param path full directory path for the new form file (string) 516 @param path full directory path for the new form file
517 @type str
509 """ 518 """
510 from .FormSelectionDialog import FormSelectionDialog 519 from .FormSelectionDialog import FormSelectionDialog
511 520
512 dlg = FormSelectionDialog() 521 dlg = FormSelectionDialog()
513 if dlg.exec() == QDialog.Accepted: 522 if dlg.exec() == QDialog.DialogCode.Accepted:
514 template = dlg.getTemplateText() 523 template = dlg.getTemplateText()
515 524
516 fileFilters = self.tr( 525 fileFilters = self.tr(
517 "Chameleon Templates (*.pt);;" 526 "Chameleon Templates (*.pt);;"
518 "Chameleon Text Templates (*.txt);;" 527 "Chameleon Text Templates (*.txt);;"
519 "Mako Templates (*.mako);;" 528 "Mako Templates (*.mako);;"
520 "Mako Templates (*.mak);;" 529 "Mako Templates (*.mak);;"
521 "HTML Files (*.html);;" 530 "HTML Files (*.html);;"
522 "HTML Files (*.htm);;" 531 "HTML Files (*.htm);;"
523 "All Files (*)") 532 "All Files (*)")
524 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( 533 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
525 self.__ui, 534 self.__ui,
526 self.tr("New Form"), 535 self.tr("New Form"),
527 path, 536 path,
528 fileFilters, 537 fileFilters,
529 None, 538 None,
530 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) 539 EricFileDialog.DontConfirmOverwrite)
531 if fname: 540 if fname:
532 ext = QFileInfo(fname).suffix() 541 ext = QFileInfo(fname).suffix()
533 if not ext: 542 if not ext:
534 ex = selectedFilter.split("(*")[1].split(")")[0] 543 ex = selectedFilter.split("(*")[1].split(")")[0]
535 if ex: 544 if ex:
536 fname += ex 545 fname += ex
537 546
538 if os.path.exists(fname): 547 if os.path.exists(fname):
539 res = E5MessageBox.yesNo( 548 res = EricMessageBox.yesNo(
540 self.__ui, 549 self.__ui,
541 self.tr("New Form"), 550 self.tr("New Form"),
542 self.tr("""The file already exists! Overwrite""" 551 self.tr("""The file already exists! Overwrite"""
543 """ it?"""), 552 """ it?"""),
544 icon=E5MessageBox.Warning) 553 icon=EricMessageBox.Warning)
545 if not res: 554 if not res:
546 # user selected to not overwrite 555 # user selected to not overwrite
547 return 556 return
548 557
549 try: 558 try:
550 with open(fname, "w", encoding="utf-8") as f: 559 with open(fname, "w", encoding="utf-8") as f:
551 f.write(template) 560 f.write(template)
552 except OSError as e: 561 except OSError as e:
553 E5MessageBox.critical( 562 EricMessageBox.critical(
554 self.__ui, 563 self.__ui,
555 self.tr("New Form"), 564 self.tr("New Form"),
556 self.tr("<p>The new form file <b>{0}</b> could" 565 self.tr("<p>The new form file <b>{0}</b> could"
557 " not be created.<br/> Problem: {1}</p>") 566 " not be created.<br/> Problem: {1}</p>")
558 .format(fname, e)) 567 .format(fname, e))
559 return 568 return
560 569
561 self.__e5project.appendFile(fname) 570 self.__ericProject.appendFile(fname)
562 self.__formsBrowser.sourceFile.emit(fname) 571 self.__formsBrowser.sourceFile.emit(fname)
563 572
564 ################################################################## 573 ##################################################################
565 ## methods below implement general functionality 574 ## methods below implement general functionality
566 ################################################################## 575 ##################################################################
576 def __getExecutablePaths(self, file): 585 def __getExecutablePaths(self, file):
577 """ 586 """
578 Private method to build all full paths of an executable file from 587 Private method to build all full paths of an executable file from
579 the environment. 588 the environment.
580 589
581 @param file filename of the executable (string) 590 @param file filename of the executable
591 @type str
582 @return list of full executable names, if the executable file is 592 @return list of full executable names, if the executable file is
583 accessible via the searchpath defined by the PATH environment 593 accessible via the searchpath defined by the PATH environment
584 variable, or an empty list otherwise. 594 variable, or an empty list otherwise.
595 @rtype list of str
585 """ 596 """
586 paths = [] 597 paths = []
587 598
588 if os.path.isabs(file): 599 if os.path.isabs(file):
589 if os.access(file, os.X_OK): 600 if os.access(file, os.X_OK):
609 620
610 def supportedPythonVariants(self): 621 def supportedPythonVariants(self):
611 """ 622 """
612 Public method to get the supported Python variants. 623 Public method to get the supported Python variants.
613 624
614 @return list of supported Python variants (list of strings) 625 @return list of supported Python variants
626 @rtype list of str
615 """ 627 """
616 variants = [] 628 variants = []
629 # TODO: that doesn't exist anymore
617 cmd = "pcreate" 630 cmd = "pcreate"
618 631
619 for variant in ['Python3']: 632 for variant in ['Python3']:
620 virtEnv = self.__getVirtualEnvironment(variant) 633 virtEnv = self.__getVirtualEnvironment(variant)
621 if virtEnv: 634 if virtEnv:
667 def __getVirtualEnvironment(self, language=""): 680 def __getVirtualEnvironment(self, language=""):
668 """ 681 """
669 Private method to get the path of the virtual environment. 682 Private method to get the path of the virtual environment.
670 683
671 @param language Python variant to get the virtual environment 684 @param language Python variant to get the virtual environment
672 for (string, one of '' or 'Python3') 685 for (one of '' or 'Python3')
673 @return path of the virtual environment (string) 686 @type str
687 @return path of the virtual environment
688 @rtype str
674 """ 689 """
675 if not language: 690 if not language:
676 language = self.__e5project.getProjectLanguage() 691 language = self.__ericProject.getProjectLanguage()
677 if self.__virtualEnvManager: 692 if self.__virtualEnvManager:
678 if language == "Python3": 693 if language == "Python3":
679 venvName = self.__plugin.getPreferences( 694 venvName = self.__plugin.getPreferences(
680 "VirtualEnvironmentNamePy3") 695 "VirtualEnvironmentNamePy3")
681 else: 696 else:
699 def __getDebugEnvironment(self, language=""): 714 def __getDebugEnvironment(self, language=""):
700 """ 715 """
701 Private method to get the path of the debugger environment. 716 Private method to get the path of the debugger environment.
702 717
703 @param language Python variant to get the debugger environment 718 @param language Python variant to get the debugger environment
704 for (string, one of '' or 'Python3') 719 for (one of '' or 'Python3')
705 @return path of the debugger environment (string) 720 @type str
721 @return path of the debugger environment
722 @rtype str
706 """ 723 """
707 if not language: 724 if not language:
708 language = self.__e5project.getProjectLanguage() 725 language = self.__ericProject.getProjectLanguage()
709 if self.__virtualEnvManager: 726 if self.__virtualEnvManager:
710 debugEnv = self.__getVirtualEnvironment(language) 727 debugEnv = self.__getVirtualEnvironment(language)
711 if not debugEnv: 728 if not debugEnv:
712 if language == "Python3": 729 if language == "Python3":
713 venvName = Preferences.getDebugger("Python3VirtualEnv") 730 venvName = Preferences.getDebugger("Python3VirtualEnv")
722 739
723 def getPyramidCommand(self, cmd, language=""): 740 def getPyramidCommand(self, cmd, language=""):
724 """ 741 """
725 Public method to build a Pyramid command. 742 Public method to build a Pyramid command.
726 743
727 @param cmd command (string) 744 @param cmd command
745 @type str
728 @param language Python variant to get the virtual environment 746 @param language Python variant to get the virtual environment
729 for (string, one of '' or 'Python3') 747 for (one of '' or 'Python3')
730 @return full pyramid command (string) 748 @type str
749 @return full pyramid command
750 @rtype str
731 """ 751 """
732 if not language: 752 if not language:
733 language = self.__e5project.getProjectLanguage() 753 language = self.__ericProject.getProjectLanguage()
734 754
735 virtualEnv = self.__getVirtualEnvironment(language) 755 virtualEnv = self.__getVirtualEnvironment(language)
736 if isWindowsPlatform() and not virtualEnv: 756 if isWindowsPlatform() and not virtualEnv:
737 virtualEnv = self.__getDebugEnvironment(language) 757 virtualEnv = self.__getDebugEnvironment(language)
738 if isWindowsPlatform(): 758 if isWindowsPlatform():
758 778
759 def getPythonCommand(self): 779 def getPythonCommand(self):
760 """ 780 """
761 Public method to build the Python command. 781 Public method to build the Python command.
762 782
763 @return python command (string) 783 @return python command
764 """ 784 @rtype str
765 language = self.__e5project.getProjectLanguage() 785 """
786 language = self.__ericProject.getProjectLanguage()
766 if self.__virtualEnvManager: 787 if self.__virtualEnvManager:
767 if language == "Python3": 788 if language == "Python3":
768 venvName = self.__plugin.getPreferences( 789 venvName = self.__plugin.getPreferences(
769 "VirtualEnvironmentNamePy3") 790 "VirtualEnvironmentNamePy3")
770 if not venvName: 791 if not venvName:
783 Private slot to show some info about Pyramid. 804 Private slot to show some info about Pyramid.
784 """ 805 """
785 version = self.getPyramidVersionString() 806 version = self.getPyramidVersionString()
786 url = "http://www.pylonsproject.org/projects/pyramid/about" 807 url = "http://www.pylonsproject.org/projects/pyramid/about"
787 808
788 msgBox = E5MessageBox.E5MessageBox( 809 msgBox = EricMessageBox.EricMessageBox(
789 E5MessageBox.Question, 810 EricMessageBox.Question,
790 self.tr("About Pyramid"), 811 self.tr("About Pyramid"),
791 self.tr( 812 self.tr(
792 "<p>Pyramid is a high-level Python Web framework that" 813 "<p>Pyramid is a high-level Python Web framework that"
793 " encourages rapid development and clean, pragmatic" 814 " encourages rapid development and clean, pragmatic"
794 " design.</p>" 815 " design.</p>"
797 "<tr><td>URL:</td><td><a href=\"{1}\">" 818 "<tr><td>URL:</td><td><a href=\"{1}\">"
798 "{1}</a></td></tr>" 819 "{1}</a></td></tr>"
799 "</table></p>" 820 "</table></p>"
800 ).format(version, url), 821 ).format(version, url),
801 modal=True, 822 modal=True,
802 buttons=E5MessageBox.Ok) 823 buttons=EricMessageBox.Ok)
803 msgBox.setIconPixmap(UI.PixmapCache.getPixmap( 824 msgBox.setIconPixmap(UI.PixmapCache.getPixmap(
804 os.path.join("ProjectPyramid", "icons", 825 os.path.join("ProjectPyramid", "icons",
805 "pyramid64-{0}".format(self.__iconSuffix)) 826 "pyramid64-{0}".format(self.__iconSuffix))
806 )) 827 ))
807 msgBox.exec() 828 msgBox.exec()
812 833
813 @return Pyramid version 834 @return Pyramid version
814 @rtype str 835 @rtype str
815 """ 836 """
816 if not self.__pyramidVersion: 837 if not self.__pyramidVersion:
838 # TODO: that doesn't exist anymore
817 cmd = self.getPyramidCommand("pcreate") 839 cmd = self.getPyramidCommand("pcreate")
818 if isWindowsPlatform(): 840 if isWindowsPlatform():
819 cmd = os.path.join(os.path.dirname(cmd), "pcreate-script.py") 841 cmd = os.path.join(os.path.dirname(cmd), "pcreate-script.py")
820 try: 842 try:
821 with open(cmd, 'r', encoding="utf-8") as f: 843 with open(cmd, 'r', encoding="utf-8") as f:
850 872
851 def isSpawningConsole(self, consoleCmd): 873 def isSpawningConsole(self, consoleCmd):
852 """ 874 """
853 Public method to check, if the given console is a spawning console. 875 Public method to check, if the given console is a spawning console.
854 876
855 @param consoleCmd console command (string) 877 @param consoleCmd console command
878 @type str
856 @return tuple of two entries giving an indication, if the console 879 @return tuple of two entries giving an indication, if the console
857 is spawning (boolean) and the (possibly) cleaned console command 880 is spawning (boolean) and the (possibly) cleaned console command
858 (string) 881 @rtype str
859 """ 882 """
860 if consoleCmd and consoleCmd[0] == '@': 883 if consoleCmd and consoleCmd[0] == '@':
861 return (True, consoleCmd[1:]) 884 return (True, consoleCmd[1:])
862 else: 885 else:
863 return (False, consoleCmd) 886 return (False, consoleCmd)
889 Private slot to create a new Pyramid project. 912 Private slot to create a new Pyramid project.
890 """ 913 """
891 from .CreateParametersDialog import CreateParametersDialog 914 from .CreateParametersDialog import CreateParametersDialog
892 915
893 dlg = CreateParametersDialog(self) 916 dlg = CreateParametersDialog(self)
894 if dlg.exec() == QDialog.Accepted: 917 if dlg.exec() == QDialog.DialogCode.Accepted:
895 scaffold, project, overwrite, simulate = dlg.getData() 918 scaffold, project, overwrite, simulate = dlg.getData()
896 919
920 # TODO: that doesn't exist anymore
897 cmd = self.getPyramidCommand("pcreate") 921 cmd = self.getPyramidCommand("pcreate")
898 args = [] 922 args = []
899 if overwrite: 923 if overwrite:
900 args.append("--overwrite") 924 args.append("--overwrite")
901 else: 925 else:
904 args.append("--simulate") 928 args.append("--simulate")
905 args.append("--scaffold={0}".format(scaffold)) 929 args.append("--scaffold={0}".format(scaffold))
906 args.append(project) 930 args.append(project)
907 dlg = PyramidDialog(self.tr("Create Pyramid Project"), 931 dlg = PyramidDialog(self.tr("Create Pyramid Project"),
908 linewrap=False, parent=self.__ui) 932 linewrap=False, parent=self.__ui)
909 if dlg.startProcess(cmd, args, self.__e5project.getProjectPath()): 933 if dlg.startProcess(
934 cmd, args, self.__ericProject.getProjectPath()
935 ):
910 dlg.exec() 936 dlg.exec()
911 if dlg.normalExit() and not simulate: 937 if dlg.normalExit() and not simulate:
912 # search for files created by pcreate and add them to the 938 # search for files created by pcreate and add them to the
913 # project 939 # project
914 projectPath = os.path.join( 940 projectPath = os.path.join(
915 self.__e5project.getProjectPath(), project) 941 self.__ericProject.getProjectPath(), project)
916 for entry in os.walk(projectPath): 942 for entry in os.walk(projectPath):
917 for fileName in entry[2]: 943 for fileName in entry[2]:
918 fullName = os.path.join(entry[0], fileName) 944 fullName = os.path.join(entry[0], fileName)
919 self.__e5project.appendFile(fullName) 945 self.__ericProject.appendFile(fullName)
920 946
921 # create the base directory for translations 947 # create the base directory for translations
922 i18nPath = os.path.join( 948 i18nPath = os.path.join(
923 projectPath, project.lower(), "i18n") 949 projectPath, project.lower(), "i18n")
924 if not os.path.exists(i18nPath): 950 if not os.path.exists(i18nPath):
925 os.makedirs(i18nPath) 951 os.makedirs(i18nPath)
926 self.__e5project.setDirty(True) 952 self.__ericProject.setDirty(True)
927 953
928 self.__setCurrentProject(project) 954 self.__setCurrentProject(project)
929 955
930 ################################################################## 956 ##################################################################
931 ## methods below implement site related functions 957 ## methods below implement site related functions
934 def __findProjects(self): 960 def __findProjects(self):
935 """ 961 """
936 Private method to determine the relative path of all Pyramid 962 Private method to determine the relative path of all Pyramid
937 projects (= top level dirs). 963 projects (= top level dirs).
938 964
939 @return list of projects (list of string) 965 @return list of projects
966 @rtype list of str
940 """ 967 """
941 projects = [] 968 projects = []
942 ppath = self.__e5project.getProjectPath() 969 ppath = self.__ericProject.getProjectPath()
943 for entry in os.listdir(ppath): 970 for entry in os.listdir(ppath):
944 if ( 971 if (
945 entry[0] not in "._" and 972 entry[0] not in "._" and
946 os.path.isdir(os.path.join(ppath, entry)) 973 os.path.isdir(os.path.join(ppath, entry))
947 ): 974 ):
977 1004
978 def __projectPath(self): 1005 def __projectPath(self):
979 """ 1006 """
980 Private method to calculate the full path of the Pyramid project. 1007 Private method to calculate the full path of the Pyramid project.
981 1008
1009 @return path of the project
1010 @rtype str
982 @exception PyramidNoProjectSelectedException raised, if no project is 1011 @exception PyramidNoProjectSelectedException raised, if no project is
983 selected 1012 selected
984 @return path of the project (string)
985 """ 1013 """
986 if self.__currentProject is None: 1014 if self.__currentProject is None:
987 self.__selectProject() 1015 self.__selectProject()
988 1016
989 if self.__currentProject is None: 1017 if self.__currentProject is None:
990 raise PyramidNoProjectSelectedException 1018 raise PyramidNoProjectSelectedException
991 else: 1019 else:
992 return os.path.join(self.__e5project.getProjectPath(), 1020 return os.path.join(self.__ericProject.getProjectPath(),
993 self.__currentProject) 1021 self.__currentProject)
994 1022
995 def __setCurrentProject(self, project): 1023 def __setCurrentProject(self, project):
996 """ 1024 """
997 Private slot to set the current project. 1025 Private slot to set the current project.
998 1026
999 @param project name of the project (string) 1027 @param project name of the project
1028 @type str
1000 """ 1029 """
1001 if project is not None and len(project) == 0: 1030 if project is not None and len(project) == 0:
1002 self.__currentProject = None 1031 self.__currentProject = None
1003 else: 1032 else:
1004 self.__currentProject = project 1033 self.__currentProject = project
1010 ) 1039 )
1011 self.selectProjectAct.setText( 1040 self.selectProjectAct.setText(
1012 self.tr('&Current Pyramid Project ({0})').format(curProject)) 1041 self.tr('&Current Pyramid Project ({0})').format(curProject))
1013 1042
1014 if self.__currentProject is None: 1043 if self.__currentProject is None:
1015 self.__e5project.setTranslationPattern("") 1044 self.__ericProject.setTranslationPattern("")
1016 else: 1045 else:
1017 lowerProject = self.__project().lower() 1046 lowerProject = self.__project().lower()
1018 config = configparser.ConfigParser() 1047 config = configparser.ConfigParser()
1019 config.read(os.path.join(self.__projectPath(), "setup.cfg")) 1048 config.read(os.path.join(self.__projectPath(), "setup.cfg"))
1020 try: 1049 try:
1023 outputDir = '{0}/locale'.format(lowerProject) 1052 outputDir = '{0}/locale'.format(lowerProject)
1024 try: 1053 try:
1025 domain = config.get("init_catalog", "domain") 1054 domain = config.get("init_catalog", "domain")
1026 except (configparser.NoOptionError, configparser.NoSectionError): 1055 except (configparser.NoOptionError, configparser.NoSectionError):
1027 domain = lowerProject 1056 domain = lowerProject
1028 self.__e5project.setTranslationPattern( 1057 self.__ericProject.setTranslationPattern(
1029 os.path.join(project, outputDir, "%language%", 1058 os.path.join(project, outputDir, "%language%",
1030 "LC_MESSAGES", "{0}.po".format(domain)) 1059 "LC_MESSAGES", "{0}.po".format(domain))
1031 ) 1060 )
1032 1061
1033 if self.__currentProject is None: 1062 if self.__currentProject is None:
1038 1067
1039 def __project(self): 1068 def __project(self):
1040 """ 1069 """
1041 Private method to get the name of the current Pyramid project. 1070 Private method to get the name of the current Pyramid project.
1042 1071
1072 @return name of the project
1073 @rtype str
1043 @exception PyramidNoProjectSelectedException raised, if no project is 1074 @exception PyramidNoProjectSelectedException raised, if no project is
1044 selected 1075 selected
1045 @return name of the project (string)
1046 """ 1076 """
1047 if self.__currentProject is None: 1077 if self.__currentProject is None:
1048 self.__selectProject() 1078 self.__selectProject()
1049 1079
1050 if self.__currentProject is None: 1080 if self.__currentProject is None:
1058 1088
1059 def __runServer(self, logging=False): 1089 def __runServer(self, logging=False):
1060 """ 1090 """
1061 Private slot to start the Pyramid Web server. 1091 Private slot to start the Pyramid Web server.
1062 1092
1063 @param logging flag indicating to enable logging (boolean) 1093 @param logging flag indicating to enable logging
1094 @type bool
1064 """ 1095 """
1065 consoleCmd = self.isSpawningConsole( 1096 consoleCmd = self.isSpawningConsole(
1066 self.__plugin.getPreferences("ConsoleCommand"))[1] 1097 self.__plugin.getPreferences("ConsoleCommand"))[1]
1067 if consoleCmd: 1098 if consoleCmd:
1068 try: 1099 try:
1069 projectPath = self.__projectPath() 1100 projectPath = self.__projectPath()
1070 except PyramidNoProjectSelectedException: 1101 except PyramidNoProjectSelectedException:
1071 E5MessageBox.warning( 1102 EricMessageBox.warning(
1072 self.__ui, 1103 self.__ui,
1073 self.tr('Run Server'), 1104 self.tr('Run Server'),
1074 self.tr('No current Pyramid project selected or no' 1105 self.tr('No current Pyramid project selected or no'
1075 ' Pyramid project created yet. Aborting...')) 1106 ' Pyramid project created yet. Aborting...'))
1076 return 1107 return
1094 self.__serverProc.finished.connect(self.__serverProcFinished) 1125 self.__serverProc.finished.connect(self.__serverProcFinished)
1095 self.__serverProc.setWorkingDirectory(projectPath) 1126 self.__serverProc.setWorkingDirectory(projectPath)
1096 self.__serverProc.start(args[0], args[1:]) 1127 self.__serverProc.start(args[0], args[1:])
1097 serverProcStarted = self.__serverProc.waitForStarted() 1128 serverProcStarted = self.__serverProc.waitForStarted()
1098 if not serverProcStarted: 1129 if not serverProcStarted:
1099 E5MessageBox.critical( 1130 EricMessageBox.critical(
1100 self.__ui, 1131 self.__ui,
1101 self.tr('Process Generation Error'), 1132 self.tr('Process Generation Error'),
1102 self.tr('The Pyramid server could not be started.')) 1133 self.tr('The Pyramid server could not be started.'))
1103 1134
1104 def __runLoggingServer(self): 1135 def __runLoggingServer(self):
1111 """ 1142 """
1112 Private slot connected to the finished signal. 1143 Private slot connected to the finished signal.
1113 """ 1144 """
1114 if ( 1145 if (
1115 self.__serverProc is not None and 1146 self.__serverProc is not None and
1116 self.__serverProc.state() != QProcess.NotRunning 1147 self.__serverProc.state() != QProcess.ProcessState.NotRunning
1117 ): 1148 ):
1118 self.__serverProc.terminate() 1149 self.__serverProc.terminate()
1119 QTimer.singleShot(2000, self.__serverProc.kill) 1150 QTimer.singleShot(2000, self.__serverProc.kill)
1120 self.__serverProc.waitForFinished(3000) 1151 self.__serverProc.waitForFinished(3000)
1121 self.__serverProc = None 1152 self.__serverProc = None
1125 Private slot to start the default web browser with the server URL. 1156 Private slot to start the default web browser with the server URL.
1126 """ 1157 """
1127 try: 1158 try:
1128 projectPath = self.__projectPath() 1159 projectPath = self.__projectPath()
1129 except PyramidNoProjectSelectedException: 1160 except PyramidNoProjectSelectedException:
1130 E5MessageBox.warning( 1161 EricMessageBox.warning(
1131 self.__ui, 1162 self.__ui,
1132 self.tr('Run Web-Browser'), 1163 self.tr('Run Web-Browser'),
1133 self.tr('No current Pyramid project selected or no Pyramid' 1164 self.tr('No current Pyramid project selected or no Pyramid'
1134 ' project created yet. Aborting...')) 1165 ' project created yet. Aborting...'))
1135 return 1166 return
1142 port = "8080" 1173 port = "8080"
1143 url = "http://localhost:{0}".format(port) 1174 url = "http://localhost:{0}".format(port)
1144 if self.__plugin.getPreferences("UseExternalBrowser"): 1175 if self.__plugin.getPreferences("UseExternalBrowser"):
1145 res = QDesktopServices.openUrl(QUrl(url)) 1176 res = QDesktopServices.openUrl(QUrl(url))
1146 if not res: 1177 if not res:
1147 E5MessageBox.critical( 1178 EricMessageBox.critical(
1148 self.__ui, 1179 self.__ui,
1149 self.tr('Run Web-Browser'), 1180 self.tr('Run Web-Browser'),
1150 self.tr('Could not start the web-browser for the URL' 1181 self.tr('Could not start the web-browser for the URL'
1151 ' "{0}".').format(url.toString())) 1182 ' "{0}".').format(url.toString()))
1152 else: 1183 else:
1160 self.__plugin.getPreferences("ConsoleCommand"))[1] 1191 self.__plugin.getPreferences("ConsoleCommand"))[1]
1161 if consoleCmd: 1192 if consoleCmd:
1162 try: 1193 try:
1163 projectPath = self.__projectPath() 1194 projectPath = self.__projectPath()
1164 except PyramidNoProjectSelectedException: 1195 except PyramidNoProjectSelectedException:
1165 E5MessageBox.warning( 1196 EricMessageBox.warning(
1166 self.__ui, 1197 self.__ui,
1167 self.tr('Start Pyramid Python Console'), 1198 self.tr('Start Pyramid Python Console'),
1168 self.tr('No current Pyramid project selected or no' 1199 self.tr('No current Pyramid project selected or no'
1169 ' Pyramid project created yet. Aborting...')) 1200 ' Pyramid project created yet. Aborting...'))
1170 return 1201 return
1178 1209
1179 self.__adjustWorkingDirectory(args, projectPath) 1210 self.__adjustWorkingDirectory(args, projectPath)
1180 started, pid = QProcess.startDetached( 1211 started, pid = QProcess.startDetached(
1181 args[0], args[1:], projectPath) 1212 args[0], args[1:], projectPath)
1182 if not started: 1213 if not started:
1183 E5MessageBox.critical( 1214 EricMessageBox.critical(
1184 self.__ui, 1215 self.__ui,
1185 self.tr('Process Generation Error'), 1216 self.tr('Process Generation Error'),
1186 self.tr('The Pyramid Shell process could not be' 1217 self.tr('The Pyramid Shell process could not be'
1187 ' started.')) 1218 ' started.'))
1188 1219
1197 """ 1228 """
1198 title = self.tr("Setup Development Environment") 1229 title = self.tr("Setup Development Environment")
1199 try: 1230 try:
1200 wd = self.__projectPath() 1231 wd = self.__projectPath()
1201 except PyramidNoProjectSelectedException: 1232 except PyramidNoProjectSelectedException:
1202 E5MessageBox.warning( 1233 EricMessageBox.warning(
1203 self.__ui, 1234 self.__ui,
1204 title, 1235 title,
1205 self.tr('No current Pyramid project selected or no Pyramid' 1236 self.tr('No current Pyramid project selected or no Pyramid'
1206 ' project created yet. Aborting...')) 1237 ' project created yet. Aborting...'))
1207 return 1238 return
1232 """ 1263 """
1233 title = self.tr("Build Distribution File") 1264 title = self.tr("Build Distribution File")
1234 try: 1265 try:
1235 projectPath = self.__projectPath() 1266 projectPath = self.__projectPath()
1236 except PyramidNoProjectSelectedException: 1267 except PyramidNoProjectSelectedException:
1237 E5MessageBox.warning( 1268 EricMessageBox.warning(
1238 self.__ui, 1269 self.__ui,
1239 title, 1270 title,
1240 self.tr('No current Pyramid project selected or no Pyramid' 1271 self.tr('No current Pyramid project selected or no Pyramid'
1241 ' project created yet. Aborting...')) 1272 ' project created yet. Aborting...'))
1242 return 1273 return
1244 from .DistributionTypeSelectionDialog import ( 1275 from .DistributionTypeSelectionDialog import (
1245 DistributionTypeSelectionDialog 1276 DistributionTypeSelectionDialog
1246 ) 1277 )
1247 1278
1248 dlg = DistributionTypeSelectionDialog(self, projectPath, self.__ui) 1279 dlg = DistributionTypeSelectionDialog(self, projectPath, self.__ui)
1249 if dlg.exec() == QDialog.Accepted: 1280 if dlg.exec() == QDialog.DialogCode.Accepted:
1250 formats = dlg.getFormats() 1281 formats = dlg.getFormats()
1251 cmd = self.getPythonCommand() 1282 cmd = self.getPythonCommand()
1252 args = [] 1283 args = []
1253 args.append("setup.py") 1284 args.append("setup.py")
1254 args.append("sdist") 1285 args.append("sdist")
1269 1300
1270 def __getInitDbCommand(self): 1301 def __getInitDbCommand(self):
1271 """ 1302 """
1272 Private method to create the path to the initialization script. 1303 Private method to create the path to the initialization script.
1273 1304
1274 @return path to the initialization script (string) 1305 @return path to the initialization script
1306 @rtype str
1275 """ 1307 """
1276 try: 1308 try:
1277 cmd = "initialize_{0}_db".format(self.__project()) 1309 cmd = "initialize_{0}_db".format(self.__project())
1278 return self.getPyramidCommand(cmd) 1310 return self.getPyramidCommand(cmd)
1279 except PyramidNoProjectSelectedException: 1311 except PyramidNoProjectSelectedException:
1280 E5MessageBox.warning( 1312 EricMessageBox.warning(
1281 self.__ui, 1313 self.__ui,
1282 self.tr("Initialize Database"), 1314 self.tr("Initialize Database"),
1283 self.tr('No current Pyramid project selected or no Pyramid' 1315 self.tr('No current Pyramid project selected or no Pyramid'
1284 ' project created yet. Aborting...')) 1316 ' project created yet. Aborting...'))
1285 return "" 1317 return ""
1290 """ 1322 """
1291 title = self.tr("Initialize Database") 1323 title = self.tr("Initialize Database")
1292 try: 1324 try:
1293 projectPath = self.__projectPath() 1325 projectPath = self.__projectPath()
1294 except PyramidNoProjectSelectedException: 1326 except PyramidNoProjectSelectedException:
1295 E5MessageBox.warning( 1327 EricMessageBox.warning(
1296 self.__ui, 1328 self.__ui,
1297 title, 1329 title,
1298 self.tr('No current Pyramid project selected or no Pyramid' 1330 self.tr('No current Pyramid project selected or no Pyramid'
1299 ' project created yet. Aborting...')) 1331 ' project created yet. Aborting...'))
1300 return 1332 return
1320 """ 1352 """
1321 title = self.tr("Show Matching Views") 1353 title = self.tr("Show Matching Views")
1322 try: 1354 try:
1323 projectPath = self.__projectPath() 1355 projectPath = self.__projectPath()
1324 except PyramidNoProjectSelectedException: 1356 except PyramidNoProjectSelectedException:
1325 E5MessageBox.warning( 1357 EricMessageBox.warning(
1326 self.__ui, 1358 self.__ui,
1327 title, 1359 title,
1328 self.tr('No current Pyramid project selected or no Pyramid' 1360 self.tr('No current Pyramid project selected or no Pyramid'
1329 ' project created yet. Aborting...')) 1361 ' project created yet. Aborting...'))
1330 return 1362 return
1331 1363
1332 url, ok = QInputDialog.getText( 1364 url, ok = QInputDialog.getText(
1333 self.__ui, 1365 self.__ui,
1334 self.tr("Show Matching Views"), 1366 self.tr("Show Matching Views"),
1335 self.tr("Enter the URL to be matched:"), 1367 self.tr("Enter the URL to be matched:"),
1336 QLineEdit.Normal, 1368 QLineEdit.EchoMode.Normal,
1337 "/") 1369 "/")
1338 if not ok or url == "": 1370 if not ok or url == "":
1339 return 1371 return
1340 1372
1341 cmd = self.getPyramidCommand("pviews") 1373 cmd = self.getPyramidCommand("pviews")
1354 """ 1386 """
1355 title = self.tr("Show Routes") 1387 title = self.tr("Show Routes")
1356 try: 1388 try:
1357 projectPath = self.__projectPath() 1389 projectPath = self.__projectPath()
1358 except PyramidNoProjectSelectedException: 1390 except PyramidNoProjectSelectedException:
1359 E5MessageBox.warning( 1391 EricMessageBox.warning(
1360 self.__ui, 1392 self.__ui,
1361 title, 1393 title,
1362 self.tr('No current Pyramid project selected or no Pyramid' 1394 self.tr('No current Pyramid project selected or no Pyramid'
1363 ' project created yet. Aborting...')) 1395 ' project created yet. Aborting...'))
1364 return 1396 return
1376 """ 1408 """
1377 title = self.tr("Show Tween Objects") 1409 title = self.tr("Show Tween Objects")
1378 try: 1410 try:
1379 projectPath = self.__projectPath() 1411 projectPath = self.__projectPath()
1380 except PyramidNoProjectSelectedException: 1412 except PyramidNoProjectSelectedException:
1381 E5MessageBox.warning( 1413 EricMessageBox.warning(
1382 self.__ui, 1414 self.__ui,
1383 title, 1415 title,
1384 self.tr('No current Pyramid project selected or no Pyramid' 1416 self.tr('No current Pyramid project selected or no Pyramid'
1385 ' project created yet. Aborting...')) 1417 ' project created yet. Aborting...'))
1386 return 1418 return
1411 1443
1412 def __getLocale(self, filename): 1444 def __getLocale(self, filename):
1413 """ 1445 """
1414 Private method to extract the locale out of a file name. 1446 Private method to extract the locale out of a file name.
1415 1447
1416 @param filename name of the file used for extraction (string) 1448 @param filename name of the file used for extraction
1417 @return extracted locale (string) or None 1449 @type str
1418 """ 1450 @return extracted locale or None
1419 if self.__e5project.getTranslationPattern(): 1451 @rtype str
1452 """
1453 if self.__ericProject.getTranslationPattern():
1420 # On Windows, path typically contains backslashes. This leads 1454 # On Windows, path typically contains backslashes. This leads
1421 # to an invalid search pattern '...\(' because the opening bracket 1455 # to an invalid search pattern '...\(' because the opening bracket
1422 # will be escaped. 1456 # will be escaped.
1423 pattern = self.__e5project.getTranslationPattern() 1457 pattern = self.__ericProject.getTranslationPattern()
1424 pattern = os.path.normpath(pattern) 1458 pattern = os.path.normpath(pattern)
1425 pattern = pattern.replace("%language%", "(.*?)") 1459 pattern = pattern.replace("%language%", "(.*?)")
1426 pattern = pattern.replace('\\', '\\\\') 1460 pattern = pattern.replace('\\', '\\\\')
1427 match = re.search(pattern, filename) 1461 match = re.search(pattern, filename)
1428 if match is not None: 1462 if match is not None:
1432 1466
1433 def __normalizeList(self, filenames): 1467 def __normalizeList(self, filenames):
1434 """ 1468 """
1435 Private method to normalize a list of file names. 1469 Private method to normalize a list of file names.
1436 1470
1437 @param filenames list of file names to normalize (list of string) 1471 @param filenames list of file names to normalize
1438 @return normalized file names (list of string) 1472 @type list of str
1473 @return normalized file names
1474 @rtype list of str
1439 """ 1475 """
1440 nfilenames = [] 1476 nfilenames = []
1441 for filename in filenames: 1477 for filename in filenames:
1442 if filename.endswith(".mo"): 1478 if filename.endswith(".mo"):
1443 filename = filename.replace(".mo", ".po") 1479 filename = filename.replace(".mo", ".po")
1448 1484
1449 def __projectFilteredList(self, filenames): 1485 def __projectFilteredList(self, filenames):
1450 """ 1486 """
1451 Private method to filter a list of file names by Pyramid project. 1487 Private method to filter a list of file names by Pyramid project.
1452 1488
1453 @param filenames list of file names to be filtered (list of string) 1489 @param filenames list of file names to be filtered
1454 @return file names belonging to the current site (list of string) 1490 @type list of str
1491 @return file names belonging to the current site
1492 @rtype list of str
1455 """ 1493 """
1456 project = self.__project() 1494 project = self.__project()
1457 nfilenames = [] 1495 nfilenames = []
1458 for filename in filenames: 1496 for filename in filenames:
1459 if filename.startswith(project + os.sep): 1497 if filename.startswith(project + os.sep):
1467 """ 1505 """
1468 title = self.tr("Extract messages") 1506 title = self.tr("Extract messages")
1469 try: 1507 try:
1470 projectPath = self.__projectPath() 1508 projectPath = self.__projectPath()
1471 except PyramidNoProjectSelectedException: 1509 except PyramidNoProjectSelectedException:
1472 E5MessageBox.warning( 1510 EricMessageBox.warning(
1473 self.__ui, 1511 self.__ui,
1474 title, 1512 title,
1475 self.tr('No current Pyramid project selected or no Pyramid' 1513 self.tr('No current Pyramid project selected or no Pyramid'
1476 ' project created yet. Aborting...')) 1514 ' project created yet. Aborting...'))
1477 return 1515 return
1479 config = configparser.ConfigParser() 1517 config = configparser.ConfigParser()
1480 config.read(os.path.join(projectPath, "setup.cfg")) 1518 config.read(os.path.join(projectPath, "setup.cfg"))
1481 try: 1519 try:
1482 potFile = config.get("extract_messages", "output_file") 1520 potFile = config.get("extract_messages", "output_file")
1483 except configparser.NoSectionError: 1521 except configparser.NoSectionError:
1484 E5MessageBox.warning( 1522 EricMessageBox.warning(
1485 self.__ui, 1523 self.__ui,
1486 title, 1524 title,
1487 self.tr('No setup.cfg found or no "extract_messages"' 1525 self.tr('No setup.cfg found or no "extract_messages"'
1488 ' section found in setup.cfg.')) 1526 ' section found in setup.cfg.'))
1489 return 1527 return
1490 except configparser.NoOptionError: 1528 except configparser.NoOptionError:
1491 E5MessageBox.warning( 1529 EricMessageBox.warning(
1492 self.__ui, 1530 self.__ui,
1493 title, 1531 title,
1494 self.tr('No "output_file" option found in setup.cfg.')) 1532 self.tr('No "output_file" option found in setup.cfg.'))
1495 return 1533 return
1496 1534
1507 title, 1545 title,
1508 msgSuccess=self.tr("\nMessages extracted successfully.")) 1546 msgSuccess=self.tr("\nMessages extracted successfully."))
1509 res = dia.startProcess(cmd, args, projectPath) 1547 res = dia.startProcess(cmd, args, projectPath)
1510 if res: 1548 if res:
1511 dia.exec() 1549 dia.exec()
1512 self.__e5project.appendFile(os.path.join(projectPath, potFile)) 1550 self.__ericProject.appendFile(os.path.join(projectPath, potFile))
1513 1551
1514 def __projectLanguageAdded(self, code): 1552 def __projectLanguageAdded(self, code):
1515 """ 1553 """
1516 Private slot handling the addition of a new language. 1554 Private slot handling the addition of a new language.
1517 1555
1518 @param code language code of the new language (string) 1556 @param code language code of the new language
1557 @type str
1519 """ 1558 """
1520 title = self.tr( 1559 title = self.tr(
1521 "Initializing message catalog for '{0}'").format(code) 1560 "Initializing message catalog for '{0}'").format(code)
1522 try: 1561 try:
1523 projectPath = self.__projectPath() 1562 projectPath = self.__projectPath()
1524 except PyramidNoProjectSelectedException: 1563 except PyramidNoProjectSelectedException:
1525 E5MessageBox.warning( 1564 EricMessageBox.warning(
1526 self.__ui, 1565 self.__ui,
1527 title, 1566 title,
1528 self.tr('No current Pyramid project selected or no Pyramid' 1567 self.tr('No current Pyramid project selected or no Pyramid'
1529 ' project created yet. Aborting...')) 1568 ' project created yet. Aborting...'))
1530 return 1569 return
1542 " successfully.")) 1581 " successfully."))
1543 res = dia.startProcess(cmd, args, projectPath) 1582 res = dia.startProcess(cmd, args, projectPath)
1544 if res: 1583 if res:
1545 dia.exec() 1584 dia.exec()
1546 1585
1547 langFile = self.__e5project.getTranslationPattern().replace( 1586 langFile = self.__ericProject.getTranslationPattern().replace(
1548 "%language%", code) 1587 "%language%", code)
1549 self.__e5project.appendFile(langFile) 1588 self.__ericProject.appendFile(langFile)
1550 1589
1551 def compileCatalogs(self, filenames): 1590 def compileCatalogs(self, filenames):
1552 """ 1591 """
1553 Public method to compile the message catalogs. 1592 Public method to compile the message catalogs.
1554 1593
1555 @param filenames list of filenames (not used) 1594 @param filenames list of filenames (not used)
1595 @type list of str
1556 """ 1596 """
1557 title = self.tr("Compiling message catalogs") 1597 title = self.tr("Compiling message catalogs")
1558 try: 1598 try:
1559 projectPath = self.__projectPath() 1599 projectPath = self.__projectPath()
1560 except PyramidNoProjectSelectedException: 1600 except PyramidNoProjectSelectedException:
1561 E5MessageBox.warning( 1601 EricMessageBox.warning(
1562 self.__ui, 1602 self.__ui,
1563 title, 1603 title,
1564 self.tr('No current Pyramid project selected or no Pyramid' 1604 self.tr('No current Pyramid project selected or no Pyramid'
1565 ' project created yet. Aborting...')) 1605 ' project created yet. Aborting...'))
1566 return 1606 return
1580 1620
1581 for entry in os.walk(projectPath): 1621 for entry in os.walk(projectPath):
1582 for fileName in entry[2]: 1622 for fileName in entry[2]:
1583 fullName = os.path.join(entry[0], fileName) 1623 fullName = os.path.join(entry[0], fileName)
1584 if fullName.endswith('.mo'): 1624 if fullName.endswith('.mo'):
1585 self.__e5project.appendFile(fullName) 1625 self.__ericProject.appendFile(fullName)
1586 1626
1587 def compileSelectedCatalogs(self, filenames): 1627 def compileSelectedCatalogs(self, filenames):
1588 """ 1628 """
1589 Public method to update the message catalogs. 1629 Public method to update the message catalogs.
1590 1630
1591 @param filenames list of file names (list of string) 1631 @param filenames list of file names
1632 @type list of str
1592 """ 1633 """
1593 title = self.tr("Compiling message catalogs") 1634 title = self.tr("Compiling message catalogs")
1594 try: 1635 try:
1595 projectPath = self.__projectPath() 1636 projectPath = self.__projectPath()
1596 except PyramidNoProjectSelectedException: 1637 except PyramidNoProjectSelectedException:
1597 E5MessageBox.warning( 1638 EricMessageBox.warning(
1598 self.__ui, 1639 self.__ui,
1599 title, 1640 title,
1600 self.tr('No current Pyramid project selected or no Pyramid' 1641 self.tr('No current Pyramid project selected or no Pyramid'
1601 ' project created yet. Aborting...')) 1642 ' project created yet. Aborting...'))
1602 return 1643 return
1614 args.append("-l") 1655 args.append("-l")
1615 args.append(locale) 1656 args.append(locale)
1616 argsLists.append(args) 1657 argsLists.append(args)
1617 1658
1618 if len(argsLists) == 0: 1659 if len(argsLists) == 0:
1619 E5MessageBox.warning( 1660 EricMessageBox.warning(
1620 self.__ui, 1661 self.__ui,
1621 title, 1662 title,
1622 self.tr('No locales detected. Aborting...')) 1663 self.tr('No locales detected. Aborting...'))
1623 return 1664 return
1624 1665
1632 1673
1633 for entry in os.walk(self.__sitePath()): 1674 for entry in os.walk(self.__sitePath()):
1634 for fileName in entry[2]: 1675 for fileName in entry[2]:
1635 fullName = os.path.join(entry[0], fileName) 1676 fullName = os.path.join(entry[0], fileName)
1636 if fullName.endswith('.mo'): 1677 if fullName.endswith('.mo'):
1637 self.__e5project.appendFile(fullName) 1678 self.__ericProject.appendFile(fullName)
1638 1679
1639 def updateCatalogs(self, filenames): 1680 def updateCatalogs(self, filenames):
1640 """ 1681 """
1641 Public method to update the message catalogs. 1682 Public method to update the message catalogs.
1642 1683
1643 @param filenames list of filenames (not used) 1684 @param filenames list of filenames (not used)
1685 @type list of str
1644 """ 1686 """
1645 title = self.tr("Updating message catalogs") 1687 title = self.tr("Updating message catalogs")
1646 try: 1688 try:
1647 projectPath = self.__projectPath() 1689 projectPath = self.__projectPath()
1648 except PyramidNoProjectSelectedException: 1690 except PyramidNoProjectSelectedException:
1649 E5MessageBox.warning( 1691 EricMessageBox.warning(
1650 self.__ui, 1692 self.__ui,
1651 title, 1693 title,
1652 self.tr('No current Pyramid project selected or no Pyramid' 1694 self.tr('No current Pyramid project selected or no Pyramid'
1653 ' project created yet. Aborting...')) 1695 ' project created yet. Aborting...'))
1654 return 1696 return
1668 def updateSelectedCatalogs(self, filenames): 1710 def updateSelectedCatalogs(self, filenames):
1669 """ 1711 """
1670 Public method to update the message catalogs. 1712 Public method to update the message catalogs.
1671 1713
1672 @param filenames list of filenames 1714 @param filenames list of filenames
1715 @type list of str
1673 """ 1716 """
1674 title = self.tr("Updating message catalogs") 1717 title = self.tr("Updating message catalogs")
1675 try: 1718 try:
1676 projectPath = self.__projectPath() 1719 projectPath = self.__projectPath()
1677 except PyramidNoProjectSelectedException: 1720 except PyramidNoProjectSelectedException:
1678 E5MessageBox.warning( 1721 EricMessageBox.warning(
1679 self.__ui, 1722 self.__ui,
1680 title, 1723 title,
1681 self.tr('No current Pyramid project selected or no Pyramid' 1724 self.tr('No current Pyramid project selected or no Pyramid'
1682 ' project created yet. Aborting...')) 1725 ' project created yet. Aborting...'))
1683 return 1726 return
1695 args.append("-l") 1738 args.append("-l")
1696 args.append(locale) 1739 args.append(locale)
1697 argsLists.append(args) 1740 argsLists.append(args)
1698 1741
1699 if len(argsLists) == 0: 1742 if len(argsLists) == 0:
1700 E5MessageBox.warning( 1743 EricMessageBox.warning(
1701 self.__ui, 1744 self.__ui,
1702 title, 1745 title,
1703 self.tr('No locales detected. Aborting...')) 1746 self.tr('No locales detected. Aborting...'))
1704 return 1747 return
1705 1748
1712 1755
1713 def openPOEditor(self, poFile): 1756 def openPOEditor(self, poFile):
1714 """ 1757 """
1715 Public method to edit the given file in an external .po editor. 1758 Public method to edit the given file in an external .po editor.
1716 1759
1717 @param poFile name of the .po file (string) 1760 @param poFile name of the .po file
1761 @type str
1718 """ 1762 """
1719 editor = self.__plugin.getPreferences("TranslationsEditor") 1763 editor = self.__plugin.getPreferences("TranslationsEditor")
1720 if poFile.endswith(".po") and editor: 1764 if poFile.endswith(".po") and editor:
1721 try: 1765 try:
1722 wd = self.__projectPath() 1766 wd = self.__projectPath()
1723 except PyramidNoProjectSelectedException: 1767 except PyramidNoProjectSelectedException:
1724 wd = "" 1768 wd = ""
1725 started, pid = QProcess.startDetached(editor, [poFile], wd) 1769 started, pid = QProcess.startDetached(editor, [poFile], wd)
1726 if not started: 1770 if not started:
1727 E5MessageBox.critical( 1771 EricMessageBox.critical(
1728 None, 1772 None,
1729 self.tr('Process Generation Error'), 1773 self.tr('Process Generation Error'),
1730 self.tr('The translations editor process ({0}) could' 1774 self.tr('The translations editor process ({0}) could'
1731 ' not be started.').format( 1775 ' not be started.').format(
1732 os.path.basename(editor))) 1776 os.path.basename(editor)))

eric ide

mercurial