Topic: Programma per verificare l'integrità dei documenti PDF WORD ed EXCEL  (Letto 217 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Pasquale

  • python unicellularis
  • *
  • Post: 7
  • Punti reputazione: 0
    • Mostra profilo
Salve a tutti,
ho un server pieno di documenti pdf, word ed excel molto importanti. Ho un secondo hard-disk che in automatica fa la copia di backup settimanale. Il server gira su linux che ha un filesystem abbastanza stabile, ma questo non è stato sufficiente perchè ancora oggi scopre che ci sono alcuni pdf che sono stati corrotti e non si riesce più ad aprirli in nessun modo. Vorrei evitare situazioni spiacevoli come queste creando un programma che verifiche costantemente l'integrità dei files e se danneggiati li ripristini dall'utilma copia di backup utile. Qualche suggerimento?

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 381
  • Punti reputazione: 0
    • Mostra profilo
Re:Programma per verificare l'integrità dei documenti PDF WORD ed EXCEL
« Risposta #1 il: Dicembre 18, 2020, 12:17 »
...ho un server pieno di documenti pdf, word ed excel molto importanti. Ho un secondo hard-disk che in automatica fa la copia di backup settimanale. Il server gira su linux che ha un filesystem abbastanza stabile, ma questo non è stato sufficiente ...
 Qualche suggerimento?

Ciao @Pasquale,

Incuriosito ed anche un po' preoccupato dalla Tua problematica, ho cercato di ragionarci un po' su, anche io uso linux ed ho macchine "vecchie" con notevole quantità di documenti e, pur non avendo incontrato files corrotti, ho pensato che se un file è effettivamente corrotto non si riuscirebbe ad "aprirlo", ho quindi creato un venv ed importato le librerie "PyPDF2" per i pdf, "odfpy" per files libre-office calc e writer (il grosso dei miei documenti), "python-docx" per documenti microsoft word "*.docx" (i file prima della versione 2007 sono problematici, li ho ignorati, se hai necessità guarda qua) e, infine, la libreria "openpyxl" per i file excel "*.xlsx" (stesso discorso che per word) ed ho scritto uno script che Ti propongo di seguito :

import os
import sys

# generatori per estrazioni dei files con estensioni "interessanti"
def get_files(path):
    '''Restituisce i files presenti in una directory.'''
    for f in os.listdir(path):
        f_name = os.path.join(path, f)
        if os.path.exists(f_name) and os.path.isfile(f_name):
            yield f_name

def get_dirs(path):
    '''Restituisce le directory presenti in una directory.'''
    for d in os.listdir(path):
        d_name = os.path.join(path, d)
        if os.path.exists(d_name) and os.path.isdir(d_name):
            yield d_name
   
def recursive_get_files(p_dir):
    '''Restituisce i files presenti in una directory e richiama se
       stessa sulle sub-directory contenute.'''
    yield from get_files(p_dir)
    for sub_dir in get_dirs(p_dir):
        yield from recursive_get_files(sub_dir)

def get_files_for_ext(p_dir):
    '''Esamina i file ricevuti e restituisce solo quelli che possiedono
       una delle volute estensioni.'''
    sel_extension = ['pdf', 'docx', 'docm', 'xlsx', 'odt', 'ods']
    for f in recursive_get_files(p_dir):
        ext = f.split('.')[-1]
        if ext.lower() in sel_extension:
            yield f
'''
Funzioni che verificano la funzionalità dei vari tipi di files utilizzando
librerie specifiche per la loro manipolazione : cercano di aprirli ed in
caso, restituiscono True se riescono, False altrimenti.
Queste funzioni importano localmente le librerie necessarie, per evitare di
doverle installare in caso di tipologie non interessanti, basterà modificare
aeguatamente "sel_extension" in get_files_for_ext()
'''

def open_pdf(filename):
    from PyPDF2 import PdfFileReader  # libreria : PyPDF2
    # qualunque errore da risposta negativa
    doc = None
    try:
        doc = PdfFileReader(filename, 'rb')
    except:
        return False
    finally:
        if doc: doc = None
    return True

def open_odt_ods(filename):
    from odf.opendocument import load  # libreria: odfpy
    doc = None
    try:
        doc = load(filename)
    except:
        return False
    finally:
        if doc: doc = None
    return True

def open_docx_docm(filename):
    from docx import Document
    doc = None
    try:
        doc = Document(filename)
    except:
        return False
    finally:
        if doc: doc = None
    return True

def open_xlsx(filename):
    import openpyxl
    doc = None
    try:
        doc = openpyxl.load_workbook(filename)
    except:
        return False
    finally:
        if doc: doc = None
    return True
       
       
# Valutatore di integrità; è un generatore
def valutator(p_dir):
    type_operator = {'pdf' : open_pdf,
                     'docx': open_docx_docm,
                     'docm': open_docx_docm,
                     'xlsx': open_xlsx,
                     'odt' : open_odt_ods,
                     'ods' : open_odt_ods
                     }
    # word<2003 : difficile vedi
    # http://blog.digitally-disturbed.co.uk/2012/04/reading-microsoft-word-doc-files-in.html
    for f in get_files_for_ext(p_dir):
        ext = f.split('.')[-1].lower()
        # do per scontatto che ext sia una chiave di type_operator
        if not type_operator[ext](f):
            yield f

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('Utilizzo : python[3] search_type_file.py directory')
        exit()
    p_dir = sys.argv[1]
    if not os.path.exists(p_dir) or not os.path.isdir(p_dir):
        print(p_dir, 'inesistente o non è una directory')
        exit()
    print(p_dir)
    counter = 0
    for f in get_files_for_ext(p_dir):
        counter += 1
    print('Trovati %d files, inizio esame ...' % counter)
    damaged_files = []
    for f in valutator(p_dir):
        damaged_files.append(f)
    if damaged_files:
        print('\nTrovati %d files danneggiati - Elenco :' % len(damaged_files))
        for f in damaged_files:
            print(f)

Cui ho fatto valutare la mia direttrice dei documenti di lavoro, nella quale ho documenti presenti anche da una quindicina di anni ... su 13403 file esaminati ha dato 25 segnalazioni delle quali una parte sono effettivamente files danneggiati, altri avranno, forse dei problemi ma sembrano falsi positivi, in particolare ho notato che la grossa parte delle segnalazioni sono pdf da scansione (quindi con sola immagine) molto probabilmente formattati male, ho ricevuto diversi warning sui pdf

p38b_v) NzP:~$ python search_type_files.py ~/Documenti
/home/nuzzopippo/Documenti
Trovati 13403 files, inizio esame ...
PdfReadWarning: Xref table not zero-indexed. ID numbers for objects will be corrected. [pdf.py:1736]
UserWarning: wmf image format is not supported so the image is being dropped [drawings.py:59]
PdfReadWarning: Xref table not zero-indexed. ID numbers for objects will be corrected. [pdf.py:1736]

Trovati 25 files danneggiati - Elenco :
/home/nuzzopippo/Documenti/Ufficio/Amministrativo/Avvocati/2017/Verbali/finali/in_pdf/verbale_04.pdf
/home/nuzzopippo/Documenti/Ufficio/Amministrativo/Forniture/Senza RUP/Acquisto_autovettura_2010/esempi/2005_01_10.pdf
...


Ho aspettato di provarlo in ufficio, dove avevo materiale più adeguato alla problematica, prima di proporti lo script ... anche se non è certo da utilizzare in modalità "automatica", consuma una notevole quantità di memoria e, comunque, alcune delle segnalazioni sono su files ancora legibili.
Spero possa esserTi utile.

Ciao

Offline Pasquale

  • python unicellularis
  • *
  • Post: 7
  • Punti reputazione: 0
    • Mostra profilo
Re:Programma per verificare l'integrità dei documenti PDF WORD ed EXCEL
« Risposta #2 il: Dicembre 19, 2020, 15:38 »
Ottimo grazie mille era proprio quello che cercavo. me lo studio attentamente per adattarlo alle mie esigenze.

Saluti