1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2014 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing the largefiles extension interface. 8""" 9 10import os 11 12from PyQt5.QtCore import QTimer 13from PyQt5.QtWidgets import QDialog 14 15from E5Gui.E5Application import e5App 16from E5Gui import E5MessageBox 17 18from ..HgExtension import HgExtension 19from ..HgDialog import HgDialog 20from ..HgClient import HgClient 21 22 23class Largefiles(HgExtension): 24 """ 25 Class implementing the largefiles extension interface. 26 """ 27 def __init__(self, vcs): 28 """ 29 Constructor 30 31 @param vcs reference to the Mercurial vcs object 32 """ 33 super().__init__(vcs) 34 35 def hgLfconvert(self, direction, projectFile): 36 """ 37 Public slot to convert the repository format of the current project. 38 39 @param direction direction of the conversion (string, one of 40 'largefiles' or 'normal') 41 @param projectFile file name of the current project file (string) 42 @exception ValueError raised to indicate a bad value for the 43 'direction' parameter. 44 """ 45 if direction not in ["largefiles", "normal"]: 46 raise ValueError("Bad value for 'direction' parameter.") 47 48 projectDir = os.path.dirname(projectFile) 49 50 from .LfConvertDataDialog import LfConvertDataDialog 51 dlg = LfConvertDataDialog(projectDir, direction) 52 if dlg.exec() == QDialog.DialogCode.Accepted: 53 newName, minSize, patterns = dlg.getData() 54 newProjectFile = os.path.join( 55 newName, os.path.basename(projectFile)) 56 57 # step 1: convert the current project to new project 58 args = self.vcs.initCommand("lfconvert") 59 if direction == 'normal': 60 args.append('--to-normal') 61 else: 62 args.append("--size") 63 args.append(str(minSize)) 64 args.append(projectDir) 65 args.append(newName) 66 if direction == 'largefiles' and patterns: 67 args.extend(patterns) 68 69 dia = HgDialog(self.tr('Convert Project - Converting'), self.vcs) 70 res = dia.startProcess(args) 71 if res: 72 dia.exec() 73 res = dia.normalExit() and os.path.isdir( 74 os.path.join(newName, self.vcs.adminDir)) 75 76 # step 2: create working directory contents 77 if res: 78 # step 2.1: start a command server client for the new repo 79 client = HgClient(newName, "utf-8", self.vcs) 80 ok, err = client.startServer() 81 if not ok: 82 E5MessageBox.warning( 83 None, 84 self.tr("Mercurial Command Server"), 85 self.tr( 86 """<p>The Mercurial Command Server could not be""" 87 """ started.</p><p>Reason: {0}</p>""").format(err)) 88 return 89 90 # step 2.2: create working directory contents 91 args = self.vcs.initCommand("update") 92 args.append("--verbose") 93 dia = HgDialog(self.tr('Convert Project - Extracting'), 94 self.vcs, client=client) 95 res = dia.startProcess(args) 96 if res: 97 dia.exec() 98 res = dia.normalExit() and os.path.isfile(newProjectFile) 99 100 # step 2.3: stop the command server client for the new repo 101 client.stopServer() 102 103 # step 3: close current project and open new one 104 if res: 105 if direction == 'largefiles': 106 self.vcs.hgEditConfig( 107 repoName=newName, 108 largefilesData={"minsize": minSize, 109 "pattern": patterns} 110 ) 111 else: 112 self.vcs.hgEditConfig( 113 repoName=newName, 114 withLargefiles=False 115 ) 116 QTimer.singleShot( 117 0, lambda: e5App().getObject("Project").openProject( 118 newProjectFile)) 119 120 def hgAdd(self, names, mode): 121 """ 122 Public method used to add a file to the Mercurial repository. 123 124 @param names file name(s) to be added (string or list of string) 125 @param mode add mode (string one of 'normal' or 'large') 126 """ 127 args = self.vcs.initCommand("add") 128 args.append("-v") 129 if mode == "large": 130 args.append("--large") 131 else: 132 args.append("--normal") 133 134 if isinstance(names, list): 135 self.vcs.addArguments(args, names) 136 else: 137 args.append(names) 138 139 dia = HgDialog( 140 self.tr('Adding files to the Mercurial repository'), 141 self.vcs) 142 res = dia.startProcess(args) 143 if res: 144 dia.exec() 145 146 def hgLfPull(self, revisions=None): 147 """ 148 Public method to pull missing large files into the local repository. 149 150 @param revisions list of revisions to pull (list of string) 151 """ 152 revs = [] 153 if revisions: 154 revs = revisions 155 else: 156 from .LfRevisionsInputDialog import LfRevisionsInputDialog 157 dlg = LfRevisionsInputDialog() 158 if dlg.exec() == QDialog.DialogCode.Accepted: 159 revs = dlg.getRevisions() 160 161 if revs: 162 args = self.vcs.initCommand("lfpull") 163 args.append("-v") 164 for rev in revs: 165 args.append("--rev") 166 args.append(rev) 167 168 dia = HgDialog(self.tr("Pulling large files"), self.vcs) 169 res = dia.startProcess(args) 170 if res: 171 dia.exec() 172 173 def hgLfVerify(self, mode): 174 """ 175 Public method to verify large files integrity. 176 177 @param mode verify mode (string; one of 'large', 'lfa' or 'lfc') 178 """ 179 args = self.vcs.initCommand("verify") 180 if mode == "large": 181 args.append("--large") 182 elif mode == "lfa": 183 args.append("--lfa") 184 elif mode == "lfc": 185 args.append("--lfc") 186 else: 187 return 188 189 dia = HgDialog( 190 self.tr('Verifying the integrity of large files'), 191 self.vcs) 192 res = dia.startProcess(args) 193 if res: 194 dia.exec() 195