ProjectFlask/FlaskMigrateExtension/MigrateProjectExtension.py

branch
eric7
changeset 64
0ee58185b8df
parent 61
fe1e8783a95f
child 66
0d3168d0e310
equal deleted inserted replaced
63:7c05cbc8b3e5 64:0ee58185b8df
8 """ 8 """
9 9
10 import os 10 import os
11 import glob 11 import glob
12 12
13 from PyQt5.QtCore import pyqtSlot, QObject, QProcess 13 from PyQt6.QtCore import pyqtSlot, QObject, QProcess
14 from PyQt5.QtWidgets import QMenu, QDialog, QInputDialog, QLineEdit 14 from PyQt6.QtWidgets import QMenu, QDialog, QInputDialog, QLineEdit
15 15
16 from E5Gui import E5MessageBox 16 from EricWidgets import EricMessageBox
17 from E5Gui.E5Application import e5App 17 from EricWidgets.EricApplication import ericApp
18 from E5Gui.E5Action import E5Action 18 from EricGui.EricAction import EricAction
19 19
20 import Utilities 20 import Utilities
21 21
22 from ..FlaskCommandDialog import FlaskCommandDialog 22 from ..FlaskCommandDialog import FlaskCommandDialog
23 23
41 super().__init__(parent) 41 super().__init__(parent)
42 42
43 self.__plugin = plugin 43 self.__plugin = plugin
44 self.__project = project 44 self.__project = project
45 45
46 self.__e5project = e5App().getObject("Project") 46 self.__ericProject = ericApp().getObject("Project")
47 47
48 self.__migrationSummaryDialog = None 48 self.__migrationSummaryDialog = None
49 49
50 def initActions(self): 50 def initActions(self):
51 """ 51 """
52 Public method to define the flask-migrate actions. 52 Public method to define the flask-migrate actions.
53 """ 53 """
54 self.actions = [] 54 self.actions = []
55 55
56 self.migrateConfigAct = E5Action( 56 self.migrateConfigAct = EricAction(
57 self.tr('Configure Migrate'), 57 self.tr('Configure Migrate'),
58 self.tr('C&onfigure Migrate'), 58 self.tr('C&onfigure Migrate'),
59 0, 0, 59 0, 0,
60 self, 'flask_config_migrate') 60 self, 'flask_config_migrate')
61 self.migrateConfigAct.setStatusTip(self.tr( 61 self.migrateConfigAct.setStatusTip(self.tr(
67 )) 67 ))
68 self.migrateConfigAct.triggered.connect( 68 self.migrateConfigAct.triggered.connect(
69 self.__configureMigrate) 69 self.__configureMigrate)
70 self.actions.append(self.migrateConfigAct) 70 self.actions.append(self.migrateConfigAct)
71 71
72 self.migrateInstallAct = E5Action( 72 self.migrateInstallAct = EricAction(
73 self.tr('Install flask-migrate'), 73 self.tr('Install flask-migrate'),
74 self.tr('Install &flask-migrate'), 74 self.tr('Install &flask-migrate'),
75 0, 0, 75 0, 0,
76 self, 'flask_install_migrate') 76 self, 'flask_install_migrate')
77 self.migrateInstallAct.setStatusTip(self.tr( 77 self.migrateInstallAct.setStatusTip(self.tr(
84 )) 84 ))
85 self.migrateInstallAct.triggered.connect( 85 self.migrateInstallAct.triggered.connect(
86 self.__installFlaskMigrate) 86 self.__installFlaskMigrate)
87 self.actions.append(self.migrateInstallAct) 87 self.actions.append(self.migrateInstallAct)
88 88
89 self.migrateAvailabilityAct = E5Action( 89 self.migrateAvailabilityAct = EricAction(
90 self.tr('Check flask-migrate Availability'), 90 self.tr('Check flask-migrate Availability'),
91 self.tr('Check flask-migrate &Availability'), 91 self.tr('Check flask-migrate &Availability'),
92 0, 0, 92 0, 0,
93 self, 'flask_check_migrate') 93 self, 'flask_check_migrate')
94 self.migrateAvailabilityAct.setStatusTip(self.tr( 94 self.migrateAvailabilityAct.setStatusTip(self.tr(
103 103
104 ######################################################### 104 #########################################################
105 ## action to initialize the database migration system 105 ## action to initialize the database migration system
106 ######################################################### 106 #########################################################
107 107
108 self.migrateInitAct = E5Action( 108 self.migrateInitAct = EricAction(
109 self.tr('Initialize Migrations'), 109 self.tr('Initialize Migrations'),
110 self.tr('&Initialize Migrations'), 110 self.tr('&Initialize Migrations'),
111 0, 0, 111 0, 0,
112 self, 'flask_init_migrations') 112 self, 'flask_init_migrations')
113 self.migrateInitAct.setStatusTip(self.tr( 113 self.migrateInitAct.setStatusTip(self.tr(
123 123
124 ######################################################### 124 #########################################################
125 ## action to create a new database migration 125 ## action to create a new database migration
126 ######################################################### 126 #########################################################
127 127
128 self.migrateCreateAct = E5Action( 128 self.migrateCreateAct = EricAction(
129 self.tr('Create Migration'), 129 self.tr('Create Migration'),
130 self.tr('&Create Migration'), 130 self.tr('&Create Migration'),
131 0, 0, 131 0, 0,
132 self, 'flask_create_migration') 132 self, 'flask_create_migration')
133 self.migrateCreateAct.setStatusTip(self.tr( 133 self.migrateCreateAct.setStatusTip(self.tr(
143 143
144 ######################################################### 144 #########################################################
145 ## action to up- and downgrade a databse 145 ## action to up- and downgrade a databse
146 ######################################################### 146 #########################################################
147 147
148 self.upgradeDatabaseAct = E5Action( 148 self.upgradeDatabaseAct = EricAction(
149 self.tr('Upgrade Database'), 149 self.tr('Upgrade Database'),
150 self.tr('&Upgrade Database'), 150 self.tr('&Upgrade Database'),
151 0, 0, 151 0, 0,
152 self, 'flask_upgrade_database') 152 self, 'flask_upgrade_database')
153 self.upgradeDatabaseAct.setStatusTip(self.tr( 153 self.upgradeDatabaseAct.setStatusTip(self.tr(
158 )) 158 ))
159 self.upgradeDatabaseAct.triggered.connect( 159 self.upgradeDatabaseAct.triggered.connect(
160 self.upgradeDatabase) 160 self.upgradeDatabase)
161 self.actions.append(self.upgradeDatabaseAct) 161 self.actions.append(self.upgradeDatabaseAct)
162 162
163 self.downgradeDatabaseAct = E5Action( 163 self.downgradeDatabaseAct = EricAction(
164 self.tr('Downgrade Database'), 164 self.tr('Downgrade Database'),
165 self.tr('&Downgrade Database'), 165 self.tr('&Downgrade Database'),
166 0, 0, 166 0, 0,
167 self, 'flask_downgrade_database') 167 self, 'flask_downgrade_database')
168 self.downgradeDatabaseAct.setStatusTip(self.tr( 168 self.downgradeDatabaseAct.setStatusTip(self.tr(
177 177
178 ######################################################### 178 #########################################################
179 ## actions to show migrations history information 179 ## actions to show migrations history information
180 ######################################################### 180 #########################################################
181 181
182 self.migrationSummaryAct = E5Action( 182 self.migrationSummaryAct = EricAction(
183 self.tr('Show Migrations Summary'), 183 self.tr('Show Migrations Summary'),
184 self.tr('Show Migrations &Summary'), 184 self.tr('Show Migrations &Summary'),
185 0, 0, 185 0, 0,
186 self, 'flask_show_migrations_summary') 186 self, 'flask_show_migrations_summary')
187 self.migrationSummaryAct.setStatusTip(self.tr( 187 self.migrationSummaryAct.setStatusTip(self.tr(
193 )) 193 ))
194 self.migrationSummaryAct.triggered.connect( 194 self.migrationSummaryAct.triggered.connect(
195 self.__showMigrationsSummary) 195 self.__showMigrationsSummary)
196 self.actions.append(self.migrationSummaryAct) 196 self.actions.append(self.migrationSummaryAct)
197 197
198 self.migrationHistoryAct = E5Action( 198 self.migrationHistoryAct = EricAction(
199 self.tr('Show Migrations History'), 199 self.tr('Show Migrations History'),
200 self.tr('Show Migrations &History'), 200 self.tr('Show Migrations &History'),
201 0, 0, 201 0, 0,
202 self, 'flask_show_migrations_history') 202 self, 'flask_show_migrations_history')
203 self.migrationHistoryAct.setStatusTip(self.tr( 203 self.migrationHistoryAct.setStatusTip(self.tr(
269 interpreter = self.__project.getVirtualenvInterpreter() 269 interpreter = self.__project.getVirtualenvInterpreter()
270 if interpreter and Utilities.isinpath(interpreter): 270 if interpreter and Utilities.isinpath(interpreter):
271 detector = os.path.join( 271 detector = os.path.join(
272 os.path.dirname(__file__), "FlaskMigrateDetector.py") 272 os.path.dirname(__file__), "FlaskMigrateDetector.py")
273 proc = QProcess() 273 proc = QProcess()
274 proc.setProcessChannelMode(QProcess.MergedChannels) 274 proc.setProcessChannelMode(
275 QProcess.ProcessChannelMode.MergedChannels)
275 proc.start(interpreter, [detector]) 276 proc.start(interpreter, [detector])
276 finished = proc.waitForFinished(30000) 277 finished = proc.waitForFinished(30000)
277 if finished and proc.exitCode() == 0: 278 if finished and proc.exitCode() == 0:
278 return True 279 return True
279 280
295 296
296 migrations = self.__project.getData("flask-migrate", 297 migrations = self.__project.getData("flask-migrate",
297 "migrationsDirectory") 298 "migrationsDirectory")
298 if migrations: 299 if migrations:
299 if abspath: 300 if abspath:
300 migrations = self.__e5project.getAbsoluteUniversalPath( 301 migrations = self.__ericProject.getAbsoluteUniversalPath(
301 migrations) 302 migrations)
302 else: 303 else:
303 workdir = self.__project.getApplication()[0] 304 workdir = self.__project.getApplication()[0]
304 migrations = os.path.relpath( 305 migrations = os.path.relpath(
305 self.__e5project.getAbsoluteUniversalPath(migrations), 306 self.__ericProject.getAbsoluteUniversalPath(migrations),
306 workdir 307 workdir
307 ) 308 )
308 else: 309 else:
309 if abspath: 310 if abspath:
310 migrations = self.__e5project.getAbsoluteUniversalPath( 311 migrations = self.__ericProject.getAbsoluteUniversalPath(
311 "migrations") 312 "migrations")
312 313
313 return migrations 314 return migrations
314 315
315 def projectClosed(self): 316 def projectClosed(self):
331 """ 332 """
332 from .MigrateConfigDialog import MigrateConfigDialog 333 from .MigrateConfigDialog import MigrateConfigDialog
333 334
334 config = self.__project.getData("flask-migrate", "") 335 config = self.__project.getData("flask-migrate", "")
335 dlg = MigrateConfigDialog(config) 336 dlg = MigrateConfigDialog(config)
336 if dlg.exec() == QDialog.Accepted: 337 if dlg.exec() == QDialog.DialogCode.Accepted:
337 config = dlg.getConfiguration() 338 config = dlg.getConfiguration()
338 self.__project.setData("flask-migrate", "", config) 339 self.__project.setData("flask-migrate", "", config)
339 340
340 def __ensureMigrateConfigured(self): 341 def __ensureMigrateConfigured(self):
341 """ 342 """
352 environment. 353 environment.
353 """ 354 """
354 venvName = self.__project.getVirtualEnvironment() 355 venvName = self.__project.getVirtualEnvironment()
355 if venvName: 356 if venvName:
356 interpreter = self.__project.getFullCommand("python") 357 interpreter = self.__project.getFullCommand("python")
357 pip = e5App().getObject("Pip") 358 pip = ericApp().getObject("Pip")
358 pip.installPackages(["flask-migrate"], interpreter=interpreter) 359 pip.installPackages(["flask-migrate"], interpreter=interpreter)
359 self.determineCapability() 360 self.determineCapability()
360 else: 361 else:
361 E5MessageBox.critical( 362 EricMessageBox.critical(
362 None, 363 None,
363 self.tr("Install flask-migrate"), 364 self.tr("Install flask-migrate"),
364 self.tr("The 'flask-migrate' extension could not be installed" 365 self.tr("The 'flask-migrate' extension could not be installed"
365 " because no virtual environment has been" 366 " because no virtual environment has been"
366 " configured.")) 367 " configured."))
374 msg = ( 375 msg = (
375 self.tr("The 'flask-migrate' extension is installed.") 376 self.tr("The 'flask-migrate' extension is installed.")
376 if self.__project.hasCapability("flask-migrate") else 377 if self.__project.hasCapability("flask-migrate") else
377 self.tr("The 'flask-migrate' extension is not installed.") 378 self.tr("The 'flask-migrate' extension is not installed.")
378 ) 379 )
379 E5MessageBox.information( 380 EricMessageBox.information(
380 None, 381 None,
381 self.tr("flask-migrate Availability"), 382 self.tr("flask-migrate Availability"),
382 msg) 383 msg)
383 384
384 ######################################################### 385 #########################################################
397 398
398 args = ["init"] 399 args = ["init"]
399 if migrations: 400 if migrations:
400 args += ["--directory", migrations] 401 args += ["--directory", migrations]
401 402
402 multidb = E5MessageBox.yesNo( 403 multidb = EricMessageBox.yesNo(
403 None, 404 None,
404 self.tr("Multiple Databases"), 405 self.tr("Multiple Databases"),
405 self.tr("""Shall the support for multiple databases be""" 406 self.tr("""Shall the support for multiple databases be"""
406 """ activated?""")) 407 """ activated?"""))
407 if multidb: 408 if multidb:
417 for root, _dirs, files in os.walk( 418 for root, _dirs, files in os.walk(
418 self.__migrationsDirectory(abspath=True) 419 self.__migrationsDirectory(abspath=True)
419 ): 420 ):
420 for fileName in files: 421 for fileName in files:
421 fullName = os.path.join(root, fileName) 422 fullName = os.path.join(root, fileName)
422 self.__e5project.appendFile(fullName) 423 self.__ericProject.appendFile(fullName)
423 424
424 browser = (e5App().getObject("ProjectBrowser") 425 browser = (ericApp().getObject("ProjectBrowser")
425 .getProjectBrowser("others")) 426 .getProjectBrowser("others"))
426 alembic = os.path.join( 427 alembic = os.path.join(
427 self.__migrationsDirectory(abspath=True), 428 self.__migrationsDirectory(abspath=True),
428 "alembic.ini" 429 "alembic.ini"
429 ) 430 )
445 446
446 message, ok = QInputDialog.getText( 447 message, ok = QInputDialog.getText(
447 None, 448 None,
448 title, 449 title,
449 self.tr("Enter a short message for the migration:"), 450 self.tr("Enter a short message for the migration:"),
450 QLineEdit.Normal) 451 QLineEdit.EchoMode.Normal)
451 if ok: 452 if ok:
452 args = ["migrate"] 453 args = ["migrate"]
453 if migrations: 454 if migrations:
454 args += ["--directory", migrations] 455 args += ["--directory", migrations]
455 if message: 456 if message:
464 if dlg.normalExit(): 465 if dlg.normalExit():
465 versionsPattern = os.path.join( 466 versionsPattern = os.path.join(
466 self.__migrationsDirectory(abspath=True), 467 self.__migrationsDirectory(abspath=True),
467 "versions", "*.py") 468 "versions", "*.py")
468 for fileName in glob.iglob(versionsPattern): 469 for fileName in glob.iglob(versionsPattern):
469 self.__e5project.appendFile(fileName) 470 self.__ericProject.appendFile(fileName)
470 471
471 ######################################################### 472 #########################################################
472 ## slots to up- and downgrade a databse 473 ## slots to up- and downgrade a databse
473 ######################################################### 474 #########################################################
474 475

eric ide

mercurial