From b53fb27a607c5cfe8ca16203a99b25633c5c5fb9 Mon Sep 17 00:00:00 2001 From: Emanuele Date: Mon, 11 Nov 2019 22:49:59 +0100 Subject: [PATCH] Porting del codice dal programma originale a libsplit Poco Refactoring, il codice e' pressoche invariato e andra' sistemato in futuro. Predisposizione al multi-threading --- .gitignore | 1 + .settings/.gitignore | 1 + bananaSPLIT/libbabanasplit/libsplit.py | 146 ++++++++++++++++++- bananaSPLIT/libbabanasplit/testSettings.json | 22 ++- 4 files changed, 160 insertions(+), 10 deletions(-) create mode 100644 .settings/.gitignore diff --git a/.gitignore b/.gitignore index 1bf8d3d..4842209 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.DS_Store /.project /.pydevproject +/org.eclipse.core.resources.prefs bananaSPLIT/build \ No newline at end of file diff --git a/.settings/.gitignore b/.settings/.gitignore new file mode 100644 index 0000000..b012ade --- /dev/null +++ b/.settings/.gitignore @@ -0,0 +1 @@ +/org.eclipse.core.resources.prefs diff --git a/bananaSPLIT/libbabanasplit/libsplit.py b/bananaSPLIT/libbabanasplit/libsplit.py index 74c7243..feecc2c 100644 --- a/bananaSPLIT/libbabanasplit/libsplit.py +++ b/bananaSPLIT/libbabanasplit/libsplit.py @@ -4,30 +4,168 @@ Created on 2 nov 2019 @author: Emanuele Trabattoni ''' from libbabanasplit.libfancylogger import fancyLogger -import threading +import threading, time, sys, parse, re, copy +from main import tempContent class bananaSPLITTER(threading.Thread): def __init__(self, fileParams=None, logger=None): self.fileParams = fileParams self.log = logger + self.rawFile = None + self.status = "first" + self.fileList = list() if fileParams is not None: + self.log.info("Sto operando sul file: {}..".format(self.fileParams['name'])) + self.docStruct = self.fileParams['docStruct'] + self.settings = self.fileParams['settings'] + self.fileName = self.fileParams['name'] + self.beginTime = time.time() pass else: self.log.critical("Non e' stato fornito il nome di alcun file da splittare!") pass def run(self): + self.openFile() + pass def openFile(self): + try: + self.info("Carico il contenuto..") + fp = open(self.fileParams['name'], mode='r', encoding=self.settings['encoding']) + self.rawFile = fp.readlines() + fp.close() + except IOError as e: + self.log.critical("Impossibile aprire il file: {}!". + format(self.fileName)) + raise BaseException("OpenFile") pass - def splitFile(self): - pass + def remEmptyLines(self): + self.log.info("Elimino righe vuote e caratteri inutili..") + tempContent = [] + try: + for ll in self.rawFile: + for c in self.settings['delChars']: + ll = ll.replace(c,'') + if ll not in ['\n', '\r']: + tempContent.append(ll) + self.rawFile = copy.deepcopy(tempContent) + return True + except: + self.log.error("Errore inaspettato durante l'eliminazione delle righe vuote!") + raise BaseException("DelLines") + del tempContent - def closeFile(self): + def splitFile(self): #porting del codice dal programma originale + self.log.info("Individuo il contenuto..") + docNumber = 0 + docSkipped = 0 + bodyCounter = 0 + docDate = {} + prevLine = '' + newsPaperName = '' + titleBegin = False + tempBody = list() + docSep=re.compile(self.docStruct['docSep']) + + for l in self.rawFile: #per ogni linea del file + lineWords = l.lstrip().split(' ') #dividi la riga in parole + if self.status == 'first': + #prendo il numero di documento per vedere se ci sono buchi + try: + try: + nn = parse.parse("{current:d} Of {total} Documents",l.strip().capitalize()).named + if nn["current"]-docNumber==1: + pass + else: + if self.settings["showSkipped"]: + self.log.warning("Il conto dei documenti non torna! LexisNexis \ + ne ha saltato qualcuno!\nPrecedente:{0}-Attuale:{1}".format(docNumber,nn["current"])) + docSkipped+=1 + docNumber = nn["current"] + except: + pass #non segnalare eccezione se il parse fallisce + # ricerco la data + if (lineWords[self.settings['monthPosition']]).capitalize() in self.docParams['dateWords']: + try: + docDate=parse.parse(self.docParams['dateFormat'],l).named + docDate['month']=docDate['month'].lstrip().rstrip().capitalize() + docDate['month']=self.docStruct['dateWords'].index(docDate['month'])+1 + title = '' + titleBegin=True + # dopo la data inizia il titolo, ma prima si cerca il nome del giornale + if self.settings['getNewsPaperName']: + try: + if prevLine.split(' ')[0].strip().isalpha(): + newsPaperName = prevLine.strip() + else: + newsPaperName = self.settings['nameNotFoundStr'] + except: + self.log.warning("E' successo qualcosa mentre stavo cercando il nome della pubblicazione,\ + controlla i file di uscita! \n\t[{}]".format(prevLine.strip())) + else: + newsPaperName = self.settings['nameNotFoundStr'] + except: + self.log.warning("Ho trovato una riga ambigua.. potrebbe essere una data ma non so: \n\t[{}]". format(l.strip('\r\n'))) + pass + elif lineWords[0] in self.docStruct['headWords']: + #cambio stato e inizializzo un nuovo documento da riempire + self.status = 'head' + newDoc=dict() + newDoc['title']=title + newDoc['date']=docDate + newDoc['newsPaperName'] = newsPaperName + titleBegin=False + else: + if titleBegin: + title += l.strip().capitalize() + except IndexError: + self.log.error("Errore inaspettato, contatta il tuo sviluppatore di fiducia!") + pass + elif self.status == 'head': + tempContent = list() + if lineWords[0] not in self.docStruct['headWords']: #se la prima parola non e' tra quelle di inizio + tempBody.append(l) # vuol dire che ho trovato l'articolo e aggiungo la prima riga al contenuto del documento + self.status = 'body' + pass + elif self.status == 'body': + if not lineWords[0] in self.docStruct['tailWords']: #se la prima parola non e' tra quelle di fine + if self.settings['delLF']: + tempBody.append(l.strip('\n')) #allora sto leggendo l'articolo + else: + tempBody.append(l) + else: + self.status = 'tail' + anomaly = False + if docSep.match(l) is not None: #controlla se ci sono articoli che non hanno le parole chiave finali + self.log.warning("Ho individuato una separatore valido prima che si chiusesse l'articolo precedente, controlla i tuoi file in uscita!\n\ + L'errore dovrebbe essere intorno all'articolo {} ma non sono sicuro! \n\t\t[{}]".format(docNumber, l.strip())) + self.status = 'tail' + anomaly = True + pass + elif self.status == 'tail': + if docSep.match(l) is not None or anomaly: + self.status = 'first' + anomaly = False + if self.settings['delWordBreak']: + tempContent=[ll.replace('-\n', '') for ll in tempContent] + newDoc['content']=copy.deepcopy(''.join(tempBody)) + self.fileList.append(copy.deepcopy(newDoc)) + tempBody=list() + bodyCounter +=1 + pass + else: + self.log.critical("Stato Interno Sconosciuto") + prevLine=l #salva sempre e comunque il contenuto della linea precedente + pass + #ricerca terminata, espongo i risultati + self.log.info("Nel file ho trovato {0} articoli..".format(bodyCounter)) + if docSkipped > 0: + self.log.warning('Attentione, LexisNexis ne ha saltati {} !!!'.format(docSkipped)) pass def saveSeparate(self): diff --git a/bananaSPLIT/libbabanasplit/testSettings.json b/bananaSPLIT/libbabanasplit/testSettings.json index 8a24f62..c8f9f4e 100644 --- a/bananaSPLIT/libbabanasplit/testSettings.json +++ b/bananaSPLIT/libbabanasplit/testSettings.json @@ -1,13 +1,15 @@ { "version": "v1.1a", + "global": { + "INworkPath": "D:\\Test\\", + "OUTworkPath": "D:\\Test\\Separati\\" + }, "logger": { "logFile": "D:\\Test\\bananaSPLIT.log", "logFormat": "%(asctime)s|%(levelname)-8s| %(message)-50s", "logTimeFormat": "%m-%d %H:%M:%S" }, "splitter": { - "INworkPath": "D:\\Test\\", - "OUTworkPath": "D:\\Test\\Separati\\", "OUTnameFormat": "TEST_{docnum}_{year:04d}{month:02d}{day:02d}_{title}.txt", "docStruct": { "docSep": "\\s*Copyright [(0-9)]+", @@ -35,8 +37,8 @@ "Email:" ], "tailWords": [ - "Newstex ID", - "NOTES", + "Newstex ID:", + "NOTES:", "LANGUAGE:", "GRAPHIC:", "TYPE:", @@ -52,7 +54,7 @@ "encoding": "utf-8", "monthPosition": 0, "getNewsPaperName": true, - "nameNotFoundStr": "--ND--", + "nameNotFoundStr": "ND", "includeTitle": true, "removeDuplicates": true, "showSkipped": false, @@ -66,7 +68,15 @@ "saveBodyNumber": true, "delLF": false, "delWordBreak": true, - "delChars": "'|@|#" + "delChars": [ + "'", + "@", + "#", + "$", + "%", + "^", + "&" + ] } } }