def currentRemoteChanged(self):
     remote = self.remoteCombo.currentText()
     repo = Repository(self.remotes[remote])
     #TODO handle case of remote not being available
     branches = repo.branches()
     self.branchesCombo.clear()
     self.branchesCombo.addItems(branches)
 def currentRemoteChanged(self):
     self.branchCombo.clear()
     remote = self.remoteCombo.currentText()
     try:
         repo = Repository(self.remotes[remote])
         branches = repo.branches()
         self.branchCombo.addItems(branches)
     except:
         QMessageBox.warning(self, "Wrong connection", "The selected remote connection is not available or not supported.\n"
                                 "Only http-based connections are supported")
         return
 def currentRemoteChanged(self):
     self.branchCombo.clear()
     remote = self.remoteCombo.currentText()
     try:
         repo = Repository(self.remotes[remote])
         branches = repo.branches()
         self.branchCombo.addItems(branches)
     except:
         QMessageBox.warning(
             self, "Wrong connection",
             "The selected remote connection is not available or not supported.\n"
             "Only http-based connections are supported")
         return
Exemple #4
0
def _createMultilayerTestRepo(modifiesRepo=True):
    conf.update([(k, os.getenv(k)) for k in conf if k in os.environ])

    if modifiesRepo:
        repo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test",
                               "severallayers_%s" % str(time.time()))
    else:
        global multilayerTestRepo
        if multilayerTestRepo is not None:
            return multilayerTestRepo
        try:
            multilayerTestRepo = createRepoAtUrl(conf['REPOS_SERVER_URL'],
                                                 "test",
                                                 "original_severallayers")
        except GeoGigException:
            multilayerTestRepo = Repository(
                conf['REPOS_SERVER_URL'] + "repos/original_severallayers/",
                "test", "original_severallayers")
            return multilayerTestRepo
        repo = multilayerTestRepo
    _importLayerToRepo(repo, "first")
    _importLayerToRepo(repo, "second")
    _importLayerToRepo(repo, "third")
    _importLayerToRepo(repo, "lines")
    repo.createbranch(repo.HEAD, "mybranch")
    global _lastRepo
    _lastRepo = repo
    return _lastRepo
 def localChanges(self, layer):
     filename, layername = namesFromLayer(layer)
     con = sqlite3.connect(filename)
     cursor = con.cursor()
     attributes = [v[1] for v in cursor.execute("PRAGMA table_info('%s');" % layername)]
     attrnames = [a for a in attributes if a != "fid"]
     cursor.execute("SELECT * FROM %s_audit;" % layername)
     changes = cursor.fetchall()
     changesdict = {}
     tracking = getTrackingInfo(layer)
     repo = Repository(tracking.repoUrl)
     commitid = cursor.execute("SELECT commit_id FROM geogig_audited_tables WHERE table_name='%s';" % layername).fetchone()[0]
     geomField = cursor.execute("SELECT column_name FROM gpkg_geometry_columns WHERE table_name='%s';" % layername).fetchone()[0]
     for c in changes:
         featurechanges = {}
         path = str(c[attributes.index("fid")])
         for attr in attrnames:
             if c[-1] == LOCAL_FEATURE_REMOVED:
                 value = None
             else:
                 if attr != geomField:
                     value = c[attributes.index(attr)]
                 else:
                     request = QgsFeatureRequest().setFilterExpression("fid=%s" % path)
                     features = list(layer.getFeatures(request))
                     if len(features) == 0:
                         continue
                     value = features[0].geometry().exportToWkt().upper()
             featurechanges[attr] = value
         path = geogigFidFromGpkgFid(tracking, path)
         changesdict[path] = LocalDiff(layername, path, repo, featurechanges, commitid, c[-1])
     return changesdict
Exemple #6
0
def _createSimpleTestRepo(modifiesRepo=True, group=None, name=None):
    conf.update([(k, os.getenv(k)) for k in conf if k in os.environ])

    if modifiesRepo:
        repo = createRepoAtUrl(conf['REPOS_SERVER_URL'], group or "test", name
                               or "simple_%s" % str(time.time()))
    else:
        global simpleTestRepo
        if simpleTestRepo is not None:
            return simpleTestRepo
        try:
            simpleTestRepo = createRepoAtUrl(conf['REPOS_SERVER_URL'], group
                                             or "test", name
                                             or "original_simple")
        except GeoGigException:
            simpleTestRepo = Repository(
                conf['REPOS_SERVER_URL'] + "repos/original_simple/", group
                or "test", name or "original_simple")
            return simpleTestRepo
        repo = simpleTestRepo
    _importLayerToRepo(repo, "first")

    log = repo.log()
    filename = tempFilename("gpkg")
    repo.checkoutlayer(filename, "points", ref=log[0].commitid)
    layer = loadLayerNoCrsDialog(filename, "points", "ogr")
    with edit(layer):
        feat = QgsFeature()
        feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
        feat.setAttributes([3, 2])
        layer.addFeatures([feat])
    repo.importgeopkg(layer, "master", "second", "tester", "*****@*****.**",
                      True)
    log = repo.log()
    filename = tempFilename("gpkg")
    repo.checkoutlayer(filename, "points", ref=log[0].commitid)
    layer = loadLayerNoCrsDialog(filename, "points", "ogr")
    features = list(layer.getFeatures())
    for feature in features:
        pt = feature.geometry().asPoint()
        if pt.x() == 10 and pt.y() == 10:
            featureid = feature.id()
            break
    with edit(layer):
        layer.changeGeometry(featureid, QgsGeometry.fromPoint(QgsPoint(5, 5)))
    repo.importgeopkg(layer, "master", "third", "tester", "*****@*****.**",
                      True)
    repo.createbranch(repo.HEAD, "mybranch")
    repo.createtag(repo.HEAD, "mytag")
    global _lastRepo
    _lastRepo = repo
    return _lastRepo
Exemple #7
0
def _createWithMergeTestRepo(modifiesRepo=True):
    conf.update([(k, os.getenv(k)) for k in conf if k in os.environ])

    if modifiesRepo:
        repo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test",
                               "withmerge_%s" % str(time.time()))
    else:
        global withMergeTestRepo
        if withMergeTestRepo is not None:
            return withMergeTestRepo
        try:
            withMergeTestRepo = createRepoAtUrl(conf['REPOS_SERVER_URL'],
                                                "test", "original_withmerge")
        except GeoGigException:
            withMergeTestRepo = Repository(
                conf['REPOS_SERVER_URL'] + "repos/original_withmerge/", "test",
                "original_withmerge")
            return withMergeTestRepo
        repo = withMergeTestRepo
    _importLayerToRepo(repo, "first")

    repo.createbranch(repo.HEAD, "mybranch")
    filename = tempFilename("gpkg")
    repo.checkoutlayer(filename, "points", ref=repo.HEAD)
    layer = loadLayerNoCrsDialog(filename, "points", "ogr")
    with edit(layer):
        feat = QgsFeature()
        feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
        feat.setAttributes([3, 2])
        layer.addFeatures([feat])
    repo.importgeopkg(layer, "mybranch", "second", "tester", "*****@*****.**",
                      True)

    filename = tempFilename("gpkg")
    repo.checkoutlayer(filename, "points", ref=repo.HEAD)
    layer = loadLayerNoCrsDialog(filename, "points", "ogr")
    with edit(layer):
        feat = QgsFeature()
        feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(9, 9)))
        feat.setAttributes([9, 9])
        layer.addFeatures([feat])
    repo.importgeopkg(layer, "master", "second", "tester", "*****@*****.**",
                      True)

    repo.merge("mybranch", "master")
    global _lastRepo
    _lastRepo = repo
    return _lastRepo
Exemple #8
0
def _createEmptyTestRepo(modifiesRepo = False):
    conf.update([(k, os.getenv(k)) for k in conf if k in os.environ])

    if modifiesRepo:
        repo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test", "empty_%s" %  str(time.time()))
    else:
        global emptyTestRepo
        if emptyTestRepo is not None:
            return emptyTestRepo
        try:
            emptyTestRepo = createRepoAtUrl(conf['REPOS_SERVER_URL'], "test", "original_empty")
        except GeoGigException:
            emptyTestRepo = Repository(conf['REPOS_SERVER_URL'] + "repos/original_empty/", "test", "original_empty")
            return emptyTestRepo
        repo = emptyTestRepo
    global _lastRepo
    _lastRepo = repo
    return _lastRepo
Exemple #9
0
    def canvasPressEvent(self, e):
        layer = config.iface.activeLayer()
        if layer is None or not isinstance(layer, QgsVectorLayer):
            config.iface.messageBar().pushMessage("No layer selected or the current active layer is not a valid vector layer",
                                                  level = QgsMessageBar.WARNING, duration = 5)
            return
        if not layertracking.isRepoLayer(layer):
            config.iface.messageBar().pushMessage("The current active layer is not being tracked as part of a GeoGig repo",
                                                  level = QgsMessageBar.WARNING, duration = 5)
            return

        trackedlayer = layertracking.getTrackingInfo(layer)
        point = self.toMapCoordinates(e.pos())
        searchRadius = self.canvas().extent().width() * .01;
        r = QgsRectangle()
        r.setXMinimum(point.x() - searchRadius);
        r.setXMaximum(point.x() + searchRadius);
        r.setYMinimum(point.y() - searchRadius);
        r.setYMaximum(point.y() + searchRadius);

        r = self.toLayerCoordinates(layer, r);

        fit = layer.getFeatures(QgsFeatureRequest().setFilterRect(r).setFlags(QgsFeatureRequest.ExactIntersect));
        fid = None
        try:
            feature = next(fit)
            fid = feature.id()
            fid = geogigFidFromGpkgFid(trackedlayer, fid)
            if fid is None:
                return
        except StopIteration as e:
            return
        repo = Repository(trackedlayer.repoUrl)

        menu = QMenu()
        versionsAction = QAction("Show all versions of this feature...", None)
        versionsAction.triggered.connect(lambda: self.versions(repo, trackedlayer.layername, fid))
        menu.addAction(versionsAction)
        blameAction = QAction("Show authorship...", None)
        blameAction.triggered.connect(lambda: self.blame(repo, trackedlayer.layername, fid))
        menu.addAction(blameAction)
        point = config.iface.mapCanvas().mapToGlobal(e.pos())
        menu.exec_(point)
Exemple #10
0
def syncLayer(layer):
    tracking = getTrackingInfo(layer)
    repo = Repository(tracking.repoUrl)
    filename, layername = namesFromLayer(layer)
    con = sqlite3.connect(filename)
    cursor = con.cursor()
    cursor.execute("SELECT * FROM %s_audit;" % layername)
    changes = bool(cursor.fetchall())
    cursor.close()
    con.close()
    if changes:
        con = sqlite3.connect(filename)
        cursor = con.cursor()
        beforeAttrs = set(v[1]
                          for v in cursor.execute("PRAGMA table_info('%s');" %
                                                  layername))
        afterAttrs = set(
            v[1] for v in cursor.execute("PRAGMA table_info('%s_audit');" %
                                         layername)
            if v[1] not in ["audit_timestamp", "audit_op"])
        cursor.close()
        con.close()
        if beforeAttrs != afterAttrs:
            ret = QMessageBox.warning(
                iface.mainWindow(), "Cannot commit changes to repository",
                "The structure of attributes table has been modified.\n"
                "This type of change is not supported by GeoGig.",
                QMessageBox.Yes)
            return

        user, email = config.getUserInfo()
        if user is None:
            return

        dlg = CommitDialog(repo, layername)
        dlg.exec_()
        if dlg.branch is None:
            return

        if dlg.branch not in repo.branches():
            commitId = getCommitId(layer)
            repo.createbranch(commitId, dlg.branch)
        mergeCommitId, importCommitId, conflicts, featureIds = repo.importgeopkg(
            layer, dlg.branch, dlg.message, user, email, True)

        if conflicts:
            ret = QMessageBox.warning(
                iface.mainWindow(), "Error while syncing",
                "There are conflicts between local and remote changes.\n"
                "Do you want to continue and fix them?",
                QMessageBox.Yes | QMessageBox.No)
            if ret == QMessageBox.No:
                repo.closeTransaction(conflicts[0].transactionId)
                return
            solved, resolvedConflicts = solveConflicts(conflicts)
            if not solved:
                repo.closeTransaction(conflicts[0].transactionId)
                return
            for conflict, resolution in zip(conflicts,
                                            list(resolvedConflicts.values())):
                if resolution == ConflictDialog.LOCAL:
                    conflict.resolveWithLocalVersion()
                elif resolution == ConflictDialog.REMOTE:
                    conflict.resolveWithRemoteVersion()
                elif resolution == ConflictDialog.DELETE:
                    conflict.resolveDeletingFeature()
                else:
                    conflict.resolveWithNewFeature(resolution)
            repo.commitAndCloseMergeAndTransaction(user, email,
                                                   "Resolved merge conflicts",
                                                   conflicts[0].transactionId)

        updateFeatureIds(repo, layer, featureIds)
        try:
            applyLayerChanges(repo, layer, importCommitId, mergeCommitId)
        except:
            QgsMessageLog.logMessage(
                "Database locked while syncing. Using full layer checkout instead",
                level=QgsMessageLog.CRITICAL)
            repo.checkoutlayer(tracking.geopkg, layername, None, mergeCommitId)

        commitdialog.suggestedMessage = ""
    else:
        branches = []
        for branch in repo.branches():
            trees = repo.trees(branch)
            if layername in trees:
                branches.append(branch)

        branch, ok = QInputDialog.getItem(iface.mainWindow(), "Sync",
                                          "Select branch to update from",
                                          branches, 0, False)
        if not ok:
            return
        commitId = getCommitId(layer)
        headCommitId = repo.revparse(branch)
        applyLayerChanges(repo, layer, commitId, headCommitId)

    layer.reload()
    layer.triggerRepaint()
    repoWatcher.repoChanged.emit(repo)

    iface.messageBar().pushMessage("GeoGig",
                                   "Layer has been correctly synchronized",
                                   level=QgsMessageBar.INFO,
                                   duration=5)
    repoWatcher.layerUpdated.emit(layer)