Example #1
0
 def resetfromlog(self):
     """
     drop the db and reinsert (and update) all the entries from log to the empty db
     """
     if not os.path.exists(self.logfile):
         print("The logfile " + self.logfile + " doesn't exist!")
         return
     # backup the old one
     if os.path.exists(self.dbFilePath):
         bak = self.dbFilePath + "~"
         if os.path.exists(bak):
             if input("A backup already exists. Remove it (only Yes is accepted)? ") != "Yes":
                 return
             os.remove(bak)
         os.rename(self.dbFilePath, bak)
     # read new one
     print("This might take a while depending on the log size. Please wait ...")
     self.dbConnection = DBConnection(self.dbFilePath)
     with self.dbConnection.getSessionContext() as session:
         with open(self.logfile, "r") as self.logf:
             for ll in self.logf:
                 if ll.startswith(Register.LOGADD):
                     dbf = self._dbFileFromLog(ll[len(Register.LOGADD):])
                     DBFileRegister.insert(session, dbf, commit=False)
                 elif ll.startswith(Register.LOGUPDATED):
                     dbf = self._dbFileFromLog(ll[len(Register.LOGUPDATED):])
                     session.commit()
                     DBFileRegister.update(session,dbf, setall=True)
                 # TODO display progress (line, items, date)
         session.commit()
     print("Done")
Example #2
0
    def setdata(self):
        """
        Change some details of the entries given by IDs. IDs are required.

        Only filename, comment and group can be changed.
        """
        ff = None
        if (isinstance(self.files, list)):
            if len(self.files) > 1:
                print("Please provide just one name or none at all!")
                return
            elif len(self.files) == 1:
                ff = self.files[0]

        if (self.fileId is None):
            print("Please provide file ID (-i option).")
            return

        self.fileId = int(self.fileId)

        dbf = DBFile(fileId=self.fileId, fileName=ff, group=self.group, comment=self.comment)
        self.log(Register.LOGUPDATE + self._formatDBFileForLog(dbf))
        with self.dbConnection.getSessionContext() as session:
            dbf = DBFileRegister.update(session, dbf)
        if not dbf:
            print("Error updating the entry!")
        else:
            self.log(Register.LOGUPDATED + self._formatDBFileForLog(dbf))
Example #3
0
    def _determineMatchingDBFile(session, fileSize, md1, md5, ed2k):
        # DOC {{{
        """Returns the DBFile() that matches the size, the MD5 sum of the first
        megabyte, the MD5 sum of the entire file and the ED2K sum of the
        specified DBFile() and is already registered in the register.

        Parameters

            session -- an instance of the SQLAlchemy's Session()

            fileSize -- the size of the file to look for in bytes

            md1 -- the MD5 sum of the first megabyte of the file

            md1 -- the MD5 sum of the entire file

            ed2k -- the ED2K sum of the entire file
        """
        # }}}

        # CODE {{{
        dbfs = DBFileRegister.query(
                session     = session,
                fileSize    = fileSize,
                md1         = md1,
                md5         = md5,
                ed2k        = ed2k,
        )

        if ((dbfs is None) or (len(dbfs) == 0)):
            return None
        else:
            return dbfs[0]
Example #4
0
    def query(self):
        """
        Query the register for any entry matching the parameters.

        Only parts of the entry have to match the given parameters (ilike)
        """
        ff = None
        if (isinstance(self.files, list)):
            if len(self.files) > 1:
                print("Please provide just one name or none at all!")
                return
            elif len(self.files) == 1:
                ff = self.files[0]

        # create a new query arguments
        dbFileQueryArguments = DBFileQueryArguments()

        # add a query argument matching the file's ID if it is specified {{{
        if (self.fileId is not None):
            dbFileQueryArguments.fileId = self.fileId
        # }}}

        # add a query argument matching the file's name if it is specified {{{
        if (ff is not None):
            dbFileQueryArguments.fileName = ff
        # }}}

        # add a query argument matching the file's group if it is specified {{{
        if (self.group is not None):
            dbFileQueryArguments.group = self.group
        # }}}

        # add a query argument matching the file's comment if it is specified {{{
        if (self.comment is not None):
            dbFileQueryArguments.comment = self.comment
        # }}}

        with self.dbConnection.getSessionContext() as session:
            ll = DBFileRegister.query(session, dbFileQueryArguments)

        if (ll is None):
            print("No record matches the query!")
        else:
            formatDBFileMethod = self._formatDBFile
            if self.queryasmysum:
                formatDBFileMethod = self._formatDBFileAsMysum
            elif self.queryed2k:
                formatDBFileMethod = self._formatDBFileAsED2K
            elif self.queryverbose:
                formatDBFileMethod = functools.partial(self._formatDBFile, verbose = True)

            for dbf in ll:
                print(formatDBFileMethod(dbf))
Example #5
0
    def _determineFileMightBeRegistered(session, fileSize, md1):
        # DOC {{{
        """Returns True if there is a registered file of the size and the MD5
        sum of the first megabyte specified in the provided DBFile(), False
        otherwise.

        Parameters

            session -- an instance of the SQLAlchemy's Session()

            fileSize -- the size of the file to look for in bytes

            md1 -- the MD5 sum of the first megabyte of the file
        """
        # }}}

        # CODE {{{
        dbfs = DBFileRegister.query(
                session     = session,
                fileSize    = fileSize,
                md1         = md1,
        )

        return (dbfs is not None)
Example #6
0
    def batchimport(self):
        """
        store all data stored in the provided files (usually named like sumlog.txt)

        Only [MYSUM...] entries are valid.
        """
        pgr, pcom, pdir = "", "", "" # previous group, comment and directory
        ii = 0 # file no
        jj = 0 # successfully imported entries
        warn = 0 # number of warnings (duplicities)
        failfiles = [] # a list of files that failed to import
        allDBFilesToStore = []

        with self.dbConnection.getSessionContext() as session:
            for ff in self.files:
                ii = ii + 1
                cdir = os.path.dirname(ff) # directory
                if cdir != pdir:
                    print("Directory [{}]".format(cdir))
                    pdir = cdir

                gr, com = self.getgroupcomment(ff, imp=True)
                if gr != pgr or com != pcom:
                    print("Using group:{} comment:{}".format(gr, com))
                    pgr, pcom = gr, com

                self.printstatus(ii, ff, "")

                with open(ff, "r") as fsum:
                    ll = 0
                    fail = False

                    dbFilesToStoreFromImportFile = []
                    for line in fsum:
                        ll = ll + 1
                        self.printstatus(ii, ff, "L" + str(ll))
                        try:
                            ms = MySum.fromString(line)
                        except ValueError:
                            self.printstatus(ii, ff, "not a MYSUM!")
                            print()
                            fail = True
                            break
                        self.printstatus(ii, ff, ms.fileName + " L" + str(ll))

                        dbf = DBFile(
                                fileName    = ms.fileName,
                                group       = gr,
                                comment     = com,
                                fileSize    = ms.fileSize,
                                md1         = ms.md1,
                                md5         = ms.md5,
                                ed2k        = ms.ed2k,
                        )

                        matchingDBFile = self._determineMatchingDBFile(
                                session     = session,
                                fileSize    = dbf.fileSize,
                                md1         = dbf.md1,
                                md5         = dbf.md5,
                                ed2k        = dbf.ed2k,
                        )

                        fullMatch = ((matchingDBFile is not None) and
                                     (dbf.fileName == matchingDBFile.fileName) and
                                     (dbf.group == matchingDBFile.group) and
                                     (dbf.comment == matchingDBFile.comment))

                        if (matchingDBFile):
                            warn = warn + 1

                            if (fullMatch):
                                self.printstatus(ii, ff, "Already registered (full match) as {} L{}".format(matchingDBFile.fileId, ll))
                            else:
                                self.printstatus(ii, ff, "Already registered (data match) as {} L{}".format(matchingDBFile.fileId, ll))
                            print()
                            continue
                        jj = jj + 1
                        dbFilesToStoreFromImportFile.append(dbf)
                    if fail:
                        if ll == 1:
                            self.printstatus(ii, ff, "FAILED")
                            failfiles.append(ff)
                            print()
                        else:
                            sll = "after " + str(ll) + " lines"
                            self.printstatus(ii, ff, "FAILED " + sll)
                            failfiles.append(ff + "       (" + sll + ")")
                            print()
                    else:
                        for dbf in dbFilesToStoreFromImportFile:
                            DBFileRegister.insert(session, dbf, commit=False)
                        allDBFilesToStore.extend(dbFilesToStoreFromImportFile)
                    print()
            print(self.RULER)
            print("About to import {} entries ({} warnings) from {} files out of {}".format(jj, warn, len(self.files) - len(failfiles), len(self.files)))
            if len(failfiles) > 0:
                print("A list of files that failed:")
                for ff in failfiles:
                    print("    " + ff)
            if self.docommit(failfiles):
                session.commit()
                for storedDBFile in allDBFilesToStore:
                    self.log(Register.LOGADD + self._formatDBFileForLog(storedDBFile))
                print("Done.")
            else:
                print("Aborted!")
Example #7
0
    def registercheck(self, register):
        """
        register (or check) the given files
        """
        pgr, pcom, pdir, psize = "", "", "", 0 # previous group, comment, directory and size
        tstart = time.time()
        ii = 0
        failfiles = []
        dbFilesToStore = []
        with self.dbConnection.getSessionContext() as session:
            for ff in self.files:
                ii = ii + 1
                fileMightBeRegistered = False
                cdir = os.path.dirname(ff) # directory
                sff = os.path.basename(ff) # short filename
                try:
                    if cdir != pdir:
                        print("Directory [{}]".format(cdir))
                        pdir = cdir

                    dbf = DBFile(fileName = sff)

                    if register: # group and comment
                        gr, com = self.getgroupcomment(ff)
                        if gr != pgr or com != pcom:
                            print("Using group:'{}' comment:'{}'".format(gr, com))
                            pgr, pcom = gr, com
                        dbf.group, dbf.comment = gr, com
                    self.printstatus(ii, sff, "Quick")

                    # stage 1 - silent
                    ms = MySum(ff)
                    ms.upgrade(1)
                    dbf.fileSize = ms.fileSize
                    dbf.md1 = ms.md1

                    fileMightBeRegistered = self._determineFileMightBeRegistered(
                            session     = session,
                            fileSize    = dbf.fileSize,
                            md1         = dbf.md1,
                    )

                    if ((not register) and (not fileMightBeRegistered)):
                        self.printstatus(ii, sff, "FAILED")
                        failfiles.append(ff)
                        print()
                        continue

                    tt = threading.Thread(target=ms.upgrade,args=[2])
                    tt.start()
                    while tt.is_alive():
                        try:
                            self.printstatus(ii, sff, self.msgpgs(ms,psize,tstart,fileMightBeRegistered))
                            time.sleep(0.25)
                        except KeyboardInterrupt:
                            ms.requestStop()
                            tt.join()
                            raise

                    tt.join()

                    psize = psize + ms.fileSize

                    dbf.md5     = ms.md5
                    dbf.ed2k    = ms.ed2k

                    matchingDBFile = self._determineMatchingDBFile(
                            session     = session,
                            fileSize    = dbf.fileSize,
                            md1         = dbf.md1,
                            md5         = dbf.md5,
                            ed2k        = dbf.ed2k,
                    )

                    fullMatch = (
                            (matchingDBFile is not None) and
                            (dbf.fileName == matchingDBFile.fileName) and
                            (dbf.group == matchingDBFile.group) and
                            (dbf.comment == matchingDBFile.comment)
                    )

                    if register:
                        if (matchingDBFile is None):
                            DBFileRegister.insert(session, dbf, commit=False)
                            self.printstatus(ii, sff, "New entry " + str(dbf.fileId))
                            dbFilesToStore.append(dbf)
                        else:
                            if (fullMatch):
                                self.printstatus(ii, sff, "Already registered (full match) as " + str(matchingDBFile.fileId))
                            else:
                                self.printstatus(ii, sff, "Already registered (data match) as " + str(matchingDBFile.fileId))
                            failfiles.append(ff)
                    else:
                        if (matchingDBFile is None):
                            self.printstatus(ii, sff, "FAILED")
                            failfiles.append(ff)
                        else:
                            stat = "OK"
                            if (dbf.fileName != matchingDBFile.fileName):
                                stat = "(as " + matchingDBFile.fileName + ") OK"
                            stat = "id:" + str(matchingDBFile.fileId) + " " + stat
                            self.printstatus(ii, sff, stat)
                    print()
                except KeyboardInterrupt:
                    self.printstatus(ii, sff, "Interrupted")
                    failfiles.append(ff + "    (Interrupted)")
                    print()
                    break

            print(self.RULER)
            if register:
                print("About to register {} files out of {}".format(ii-len(failfiles),ii))
            else:
                print("Passed {} files out of {}.{}".format(ii-len(failfiles), ii, "ALL OK" if not len(failfiles) else "" ))
            if len(failfiles) > 0:
                print("A list of files that failed:")
                for ff in failfiles:
                    print("    " + ff)
            if register:
                if len(failfiles) == ii:
                    print("No files were registered!")
                elif self.docommit(failfiles):
                    session.commit()
                    for storedDBFile in dbFilesToStore:
                        self.log(Register.LOGADD + self._formatDBFileForLog(storedDBFile))
                    print("Done.")
                else:
                    print("Aborted!")