示例#1
0
    def run(self, gui):
        """Given a fresh empty master database in self.dbm, fill it from
        the open backup database file (self.dbs).
        """
        try:
            # Create tables
            t = u"config"
            gui.report(_("Creating table '%s'") % t)
            self.makeTable(t)
            self.restoreTable(t)
            gui.report(_("Creating table 'data'"))
            self.dbm.createDataTable()
            self.restoreDataTable()

            self.dbm.createInterfaceTable()
            gui.report(_("Created interface table"))

            # Copy reports
            gui.report(_("Creating teacher report tables ..."))
            t = u"reports"
            # Get list of teachers from configuration data
            for tch in self.dbs.listAllFiles(u"teachers/"):
                self.makeTable(teacher2user(tch[9:]))

            # Parse all class configuration data, to determine
            # ownership of reports
            reports = makeReportsDict(self.dbs)

            for id, value in self.dbs.read(u"SELECT * FROM %s" % t):
                table = teacher2user(reports[id])
                sqlins = u"INSERT INTO %s VALUES(?, ?)" % table
                self.dbm.send(sqlins, (id, value))

#********* This was just an idea, but it may never be used.
#            # Copy comments
#            gui.report(_("Copying comments ..."))
#            t = "comments"
#            self.makeTable(t)
#            self.restoreTable(t)

            gui.report(_("DONE!"))

        except:
            print_exc()
            message(_("Couldn't restore database"))

            self.dbm = None

        self.close()
示例#2
0
    def run(self, gui):
        """Given a fresh empty master database in self.dbm, fill it from
        the open backup database file (self.dbs).
        """
        try:
            # Create tables
            t = u"config"
            gui.report(_("Creating table '%s'") % t)
            self.makeTable(t)
            self.restoreTable(t)
            gui.report(_("Creating table 'data'"))
            self.dbm.createDataTable()
            self.restoreDataTable()

            self.dbm.createInterfaceTable()
            gui.report(_("Created interface table"))

            # Copy reports
            gui.report(_("Creating teacher report tables ..."))
            t = u"reports"
            # Get list of teachers from configuration data
            for tch in self.dbs.listAllFiles(u"teachers/"):
                self.makeTable(teacher2user(tch[9:]))

            # Parse all class configuration data, to determine
            # ownership of reports
            reports = makeReportsDict(self.dbs)

            for id, value in self.dbs.read(u"SELECT * FROM %s" % t):
                table = teacher2user(reports[id])
                sqlins = u"INSERT INTO %s VALUES(?, ?)" % table
                self.dbm.send(sqlins, (id, value))

#********* This was just an idea, but it may never be used.
#            # Copy comments
#            gui.report(_("Copying comments ..."))
#            t = "comments"
#            self.makeTable(t)
#            self.restoreTable(t)

            gui.report(_("DONE!"))

        except:
            print_exc()
            message(_("Couldn't restore database"))

            self.dbm = None

        self.close()
示例#3
0
    def init(self, gui, filepath, forceDialog=False):
        self.gui = gui
        self.filepath = filepath

        # Get the path to the user database file
        self.dbs = None
        dbDir = None
        dbPath = self.settings.getSetting("dbFile")
        while True:
            if not self.filepath:
                if dbPath:
                    dbd = os.path.dirname(dbPath)
                    if os.path.isdir(dbd):
                        dbDir = dbd
                    if os.path.isfile(dbPath):
                        self.filepath = dbPath
                    dbPath = None

                if forceDialog or not self.filepath:
                    self.filepath = getFile(_("User Database File"),
                            startDir=dbDir,
                            defaultSuffix=u".zga",
                            filter=(_("Database Files"), (u"*.zga",)))
                    if not self.filepath: return

            self.dbs = DBs(self.filepath)
            if self.dbs.isOpen():
                break
            dbDir = os.path.dirname(self.filepath)
            self.filepath = None

        self.settings.setSetting("dbFile", self.filepath)

        # Set window title
        self.gui.setTitle(_("Synchronize %s") % self.filepath)

        self.dbm = None
        # Get the default host name from the 'base' data
        self.dbhost = self.dbs.baseDict[u"masterHost"]

        # Get information from the 'config' table
        self.dbname = self.dbs.getConfig(u"dbname")
        teacher = self.dbs.getConfig(u"me")
        if not teacher:
            error(_("'%s' is not a teacher's database file") % self.filepath)
        self.dbuser = teacher2user(teacher)

        # Close user database file
        self.closeFile()

        # set gui lineEdits
        self.gui.setDBinfo(self.dbhost, self.dbname, self.dbuser,
                self.filepath)
示例#4
0
    def makeReports(self):
        """Update the teachers' report tables, adding and removing
        tables and records where demanded by the configuration changes.
        """
        # Get a list of existing teacher tables
        ttables = self.db.getTeacherTables()
        # Get an updated list of teachers from the config data
        teachers = self.source.listFiles("teachers")

        # Create any new tables needed, and check for reports which
        # must be added or deleted
        allReports = makeReportsDict(self.source)
        for teacher in teachers:
            tbname = teacher2user(teacher)
            if tbname in ttables:
                ttables.remove(tbname)
                for rep in self.db.listIds(tbname):
                    if allReports.has_key(rep):
                        # Mark this report as already existing
                        allReports[rep] = None
                    else:
                        self.report(_("Deleting report %1"), (rep, ))
                        sqldel = u"DELETE FROM %s WHERE id = ?" % tbname
                        self.db.send(sqldel, (rep, ))
            else:
                self.db.createIVTable(tbname)
                self.report(_("... made %1"), (tbname, ))

        self.report(_("Creating initial reports"))
        for key, t in allReports.items():
            if t:
                sqlins = u"INSERT INTO %s VALUES(?, ?)" % teacher2user(t)
                self.db.send(sqlins, (key, makeReportValue(u"", u"")))

        # Remove unneeded tables
        for tbname in ttables:
            self.report(_("... removing %1"), (tbname, ))
            self.db.send(u"DROP TABLE %s" % tbname)
示例#5
0
    def makeReports(self):
        """Update the teachers' report tables, adding and removing
        tables and records where demanded by the configuration changes.
        """
        # Get a list of existing teacher tables
        ttables = self.db.getTeacherTables()
        # Get an updated list of teachers from the config data
        teachers = self.source.listFiles("teachers")

        # Create any new tables needed, and check for reports which
        # must be added or deleted
        allReports = makeReportsDict(self.source)
        for teacher in teachers:
            tbname = teacher2user(teacher)
            if tbname in ttables:
                ttables.remove(tbname)
                for rep in self.db.listIds(tbname):
                    if allReports.has_key(rep):
                        # Mark this report as already existing
                        allReports[rep] = None
                    else:
                        self.report(_("Deleting report %1"), (rep,))
                        sqldel = u"DELETE FROM %s WHERE id = ?" % tbname
                        self.db.send(sqldel, (rep,))
            else:
                self.db.createIVTable(tbname)
                self.report(_("... made %1"), (tbname,))

        self.report(_("Creating initial reports"))
        for key, t in allReports.items():
            if t:
                sqlins = u"INSERT INTO %s VALUES(?, ?)" % teacher2user(t)
                self.db.send(sqlins, (key, makeReportValue(u"", u"")))

        # Remove unneeded tables
        for tbname in ttables:
            self.report(_("... removing %1"), (tbname,))
            self.db.send(u"DROP TABLE %s" % tbname)
示例#6
0
    def run(self, gui):
        """Copy the master database to the slave.
        """
        try:
            # Create tables
            table = u"config"
            gui.report(_("Creating table '%s'") % table)
            self.makeTable(table)
            self.dumpTable(table)

            gui.report(_("Creating table 'data'"))
            self.dbs.createDataTable()
            if self.teacher:
                # Don't dump the image files, just that for the current teacher
                self.dumpDataTable(
                    r"(?!imagefiles/)|imagefiles/teachers/%s\." % self.teacher)
            else:
                self.dumpDataTable()

            # Copy reports
            gui.report(_("Copying reports ..."))
            table = u"reports"
            self.makeTable(table)
            if self.teacher:
                # Database user for self.teacher (also report table name)
                user = teacher2user(self.teacher)

                # Only copy the owner's reports
                self.dumpTable(user, table)

            else:
                for tm in self.dbm.getTeacherTables():
                    self.dumpTable(tm, table)


#********* This was just an idea, but it may never be used.
#            # Copy comments
#            gui.report(_("Copying comments ..."))
#            table = u"comments"
#            self.makeTable(table)
#            if self.teacher:
#                # Only copy comments pertaining to the owner's reports
#                okIds = self.dbm.listIds(user)
#                for c in self.dbm.listIds(table):
#                    if c in okIds:
#                        for v in self.dbm.read(u"""SELECT value FROM comments
#                                WHERE id = ?""", (c,)):
#                            self.dbs.send(u"""INSERT INTO comments
#                                    VALUES(?, ?)""", (c, v[0]))
#
#            else:
#                self.dumpTable(table)

            if self.teacher:
                # Set creation time
                self.dbs.send(
                    u"""INSERT INTO config
                        VALUES('createtime', ?)""", (self.ctime, ))

                # Set db-file 'owner'
                self.dbs.send(
                    u"""UPDATE config SET value = ?
                    WHERE id = 'me'""", (self.teacher, ))

            else:
                # Set the last backup time
                self.dbs.send(
                    u"""UPDATE config SET value = ?
                        WHERE id = 'backuptime'""", (self.ctime, ))
                self.dbm.send(
                    u"""UPDATE config SET value = ?
                    WHERE id = 'backuptime'""", (self.ctime, ))

            self.dbs.close()
            self.dbs = None
            gui.report(_("DONE!"))

        except:
            print_exc()

            message(
                _("Couldn't create database file."
                  " Removing incomplete file (%1)"), (self.filepath, ))
            if self.dbs.isOpen():
                self.dbs.close()
            os.remove(self.filepath)
            self.dbs = None
            self.filepath = None
示例#7
0
    def run(self, gui):
        """Copy the master database to the slave.
        """
        try:
            # Create tables
            table = u"config"
            gui.report(_("Creating table '%s'") % table)
            self.makeTable(table)
            self.dumpTable(table)

            gui.report(_("Creating table 'data'"))
            self.dbs.createDataTable()
            if self.teacher:
                # Don't dump the image files, just that for the current teacher
                self.dumpDataTable(r"(?!imagefiles/)|imagefiles/teachers/%s\."
                        % self.teacher)
            else:
                self.dumpDataTable()

            # Copy reports
            gui.report(_("Copying reports ..."))
            table = u"reports"
            self.makeTable(table)
            if self.teacher:
                # Database user for self.teacher (also report table name)
                user = teacher2user(self.teacher)

                # Only copy the owner's reports
                self.dumpTable(user, table)

            else:
                for tm in self.dbm.getTeacherTables():
                    self.dumpTable(tm, table)

#********* This was just an idea, but it may never be used.
#            # Copy comments
#            gui.report(_("Copying comments ..."))
#            table = u"comments"
#            self.makeTable(table)
#            if self.teacher:
#                # Only copy comments pertaining to the owner's reports
#                okIds = self.dbm.listIds(user)
#                for c in self.dbm.listIds(table):
#                    if c in okIds:
#                        for v in self.dbm.read(u"""SELECT value FROM comments
#                                WHERE id = ?""", (c,)):
#                            self.dbs.send(u"""INSERT INTO comments
#                                    VALUES(?, ?)""", (c, v[0]))
#
#            else:
#                self.dumpTable(table)

            if self.teacher:
                # Set creation time
                self.dbs.send(u"""INSERT INTO config
                        VALUES('createtime', ?)""", (self.ctime,))

                # Set db-file 'owner'
                self.dbs.send(u"""UPDATE config SET value = ?
                    WHERE id = 'me'""", (self.teacher,))

            else:
                # Set the last backup time
                self.dbs.send(u"""UPDATE config SET value = ?
                        WHERE id = 'backuptime'""", (self.ctime,))
                self.dbm.send(u"""UPDATE config SET value = ?
                    WHERE id = 'backuptime'""", (self.ctime,))

            self.dbs.close()
            self.dbs = None
            gui.report(_("DONE!"))

        except:
            print_exc()

            message(_("Couldn't create database file."
                    " Removing incomplete file (%1)"), (self.filepath,))
            if self.dbs.isOpen():
                self.dbs.close()
            os.remove(self.filepath)
            self.dbs = None
            self.filepath = None
示例#8
0
def synchronize(dbm, filepath, gui):
    """Synchronize the given file with the given (open) master database.
    """
    # Current master time
    mtime = dbm.getTime()
    # Move the user database file to backup location
    dir = os.path.dirname(filepath)
    bfile = re.sub(".zga$", "_%s.zga" % mtime, filepath)
    if (os.name == 'posix'):
        try:
            if Popen(["lsof", filepath],
                    stdout=PIPE).communicate()[0]:
                warning(_("The database file (%1) is being used"
                        " by another application"), (filepath,))
                return
        except:
            warning(_("You should install 'lsof' so that usage"
                    " of the file can be tested"))
    try:
        os.rename(filepath, bfile)
    except:
        # This trap only works on Windows. Linux will happily
        # allow you to delete a file while another program is
        # working on it! 'lsof filename' (see above) should be
        # a way to avoid that.
        warning(_("Couldn't rename the database file (%1).\n"
                "Is it being used by another application?"),
                (filepath,))
        return

    gui.report(_("Database file renamed to %s") % bfile)

    dbs = DBs(bfile)
    if not dbs.isOpen():
        os.rename(bfile, filepath)
        return

    # Teacher's report table
    teacher = dbs.getConfig(u"me")
    mtb = teacher2user(teacher)
    if mtb not in dbm.getTeacherTables():
        warning(_("%1: Owning teacher (%2) not known to master database"),
                (filepath, teacher))
        return

    gui.report(_("Copying reports from user database to master"))
    # Counter for transferred reports
    rcount = 0
    # Creation time of slave db, i.e. last sync time
    ctime = dbs.getConfig(u"createtime")
    # Get all updated reports
    for id, data in dbs.read(u"SELECT * FROM reports"):
        # Split off the version data
        dver, drep = data.split(u"\n", 1)
        # Get the master version data
        try:
            mver = dbm.readValue(mtb, id).split(u"\n", 1)[0]
        except:
            gui.report(_("Invalid report, not updated : %s") % id)

        if (mver > ctime):
            if confirmationDialog(_("Report update problem"),
                    _("Master version of report has been updated"
                    " since this client was last synchronized.\n"
                    "   Replace that version of '%s'?") % id, False):
                gui.report(_("Revised master version of report '%s'"
                        " will be overwritten") % id)
            else:
                gui.report(_("Revised master version of report '%s'"
                        " not overwritten") % id)
                continue

        elif (dver <= mver):
            # Only do anything if the local version is newer than the
            # the master version
            continue

        if (dver > mtime):
            # The new version has a time stamp later than the
            # current time on the master, adjust it
            if dver.endswith(u"$"):
                dver = mtime + u"$"
            else:
                dver = mtime

        try:
            sqlupd = u"UPDATE %s SET value = ? WHERE id = ?" % mtb
            dbm.send(sqlupd, (dver + u"\n" + drep, id))
            rcount += 1
        except:
            gui.report(_("Couldn't update report '%s'") % id)

    gui.report(_("Transferred %d reports") % rcount)

    # Close the user database
    dbs.close()

    # Remember the latest sync time
    if rcount:
        dbm.send(u"""UPDATE interface SET value = ?
                    WHERE id = 'lastsynctime'""", (mtime,))

    # Recreate the user database
    gui.report(_("Recreating the user database"))
    recreate(dbm, filepath, teacher, gui)