[Risolto] filtrare le mail prima di scaricarle
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
[Risolto] filtrare le mail prima di scaricarle
vorrei monitorare regolarmente un mail server e scaricarne solo i messaggi che nel corpo corrispondono a un dato pattern.
Il contenuto dei messaggi scaricati serve a uno script per predisporre dei documenti.
Potrei usare fetchmail (forse insieme a procmail ?), non cancellare dal server i messaggi scaricati, tenere il mio disco pulito mettendo la inbox su /tmp. Però non ho capito se e come è possibile filtrare i messaggi *prima* di averli scaricati localmente.
O forse è possibile scorrere sul server il corpo dei nuovi messaggi con wget / curl o analoghi tool ?
Grazie dell'attenzione.
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
Allora provo un'altra formulazione: posso scaricare automaticamente solo determinate mail sulla base del testo contenuto e ignorare le altre? (e quindi evitare di scaricare i loro allegati)
Sarei molto grato se qualcuno rispondesse anche solo per farmi notare l'illogicità della questione, tenuto conto che sono un incompetente al riguardo
Re: filtrare le mail prima di scaricarle
provo a proporre una possibile soluzione velocemente:
fetchmail in crontab (oppure puo' essere daemon) per avere una copia della corrispondenza in locale sempre aggiornata. L'opzione --keep mantiene le mail sul server. grepmail per le ricerche con regex e mpack per estrarre l'allegato.
Un esempio veloce per gmail da linea di comando (meglio scrivere i parametri in ~/.fetchmailrc).
proto IMAP, server imap.gmail.com, timeout 10s, Secure Sockets Layer, porta 993 di default
Codice: Seleziona tutto
% fetchmail --ssl --keep --timeout 10 -p imap imap.gmail.com -u xxxxxxxxx@gmail.com
grepmail cerca localmente. Il man è ben dettagliato e vi sono anche parecchi esempi. Uno tra questi:
Codice: Seleziona tutto
# cerca tutte le mail, nell'header e nel body, il contenuto "Pilot"
% grepmail -hb "Pilot" saved-mail*
Per l'allegato e' sufficiente fare una pipe dell'output di grepmail su munpack
Codice: Seleziona tutto
# estrai gli allegati dalle mail di ieri
% grepmail -d yesterday /var/mail/$USER | munpack
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
In realtà le mail devo prenderle da un server di PEC, ma se avessi problemi a farlo potrei sempre inoltrarle con un filtro a un indirizzo gmail e mi troverei il lavoro semplificato
Purtroppo dalla tua soluzione mi pare di capire che per greppare un messaggio devo averlo scaricato in locale.
Invece, per il mio script, a me interessano solo alcune delle mail che mi arrivano e non vorrei essere costretto al download di tutte: la posta la leggo su webmail.
Non c'è modo di cercare nel corpo dei messaggi ancora sul server? come ti fa fare gmail, per capirci
-
- Rampante Reduce
- Messaggi: 5460
- Iscrizione: domenica 20 gennaio 2008, 1:13
- Desktop: Kubuntu
- Distribuzione: 20.04 x64
- Contatti:
Re: filtrare le mail prima di scaricarle
E tu scarichi solo il contenuto di UNA cartella, via POP3.
Secondo Principio di Dilbert, di Scott Adams. "Si parte dalla certezza che siamo tutti idioti". Ed alcuni su questo mi ab-battono alla grande.
Come certificato dalla moderazione, incivile e maleducato. You have been warned.
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
non sarà un crivello raffinatissimo ma un inoltro selettivo per forza deve fartelo fare, dopo tutto si paga! Comunque questo lo terrei come piano bSolo se il server PEC ti consente di attivare i filtri.
potresti chiarire per favore?E tu scarichi solo il contenuto di UNA cartella, via POP3.
Re: filtrare le mail prima di scaricarle
PEC (RFC6109)mantiene le specifiche IMAP/POP.rai ha scritto: In realtà le mail devo prenderle da un server di PEC, ma se avessi problemi a farlo potrei sempre inoltrarle con un filtro a un indirizzo gmail e mi troverei il lavoro semplificato
Eventuali dettagli di configurazione vengono forniti dal gestore.
Il motivo e' semplice e dipende dal protocollo utilizzato dal gestore. Se fosse IMAP potresti fare delle query significanti, ma con POP non fai assolutamente niente ! Questo potrebbe essere un buon motivo per greppare localmente.rai ha scritto: Invece, per il mio script, a me interessano solo alcune delle mail che mi arrivano e non vorrei essere costretto al download di tutte: la posta la leggo su webmail.
Certo che si con IMAP, non con POP.rai ha scritto: Non c'è modo di cercare nel corpo dei messaggi ancora sul server? come ti fa fare gmail, per capirci
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
Il mio gestore PEC ofre IMAP solo come servizio aggiuntivo e non lo vorrei pagare:ixamit ha scritto:Certo che si con IMAP, non con POP.
però ho verificato che mi fa selettivamente inoltrare le pec quindi viene buono il piano B se posso contare sul tuo aiuto.
Mi aiuteresti a capire come arrivare ad assegnare ad una variabile della mia shell un stringa presa dal corpo di un messaggio che sta su Gmail?
PS grazie per il link con le specifiche PEC
Re: filtrare le mail prima di scaricarle
Attenzione, io non capisco questa richiesta.... spiega in dettaglio.rai ha scritto: Mi aiuteresti a capire come arrivare ad assegnare ad una variabile della mia shell un stringa presa dal corpo di un messaggio che sta su Gmail?
Se il tuo piano "B" consiste nell'innoltrare da PEC a IMAP(rfc3501) per poter fare delle SEARCH da remoto, si' le puoi fare senza scaricare;
ma se vuoi che ti restituisca parte del HEADER/BODY o altro devi aprire e leggere l'email.
La SEARCH restituisce solo una lista con riferimenti trovati; se vuoi vedere il paragrafo dove e' presente "FOO", devi necessariamente leggere l'email. Similmente a sql, una query non estrae il record. Credo che un esempio sia piu' esplicativo:
Codice: Seleziona tutto
% openssl s_client -crlf -connect imap.gmail.com:993
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
------ [cut here] --------
tag LOGIN USER PASSWORD
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
tag OK xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxx authenticated (Success)
tag SEARCH TEXT "hello"
* SEARCH 26 37 43 48 55 62 63 80 83 88 89 92 93 94 95 97 112 114 134 150 395 445 447 452 540 541 543
tag FETCH 43 (FLAGS BODY[HEADER.FIELDS (To)])
* 43 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (To)] {32}
To: "Max" <xxxxxxxxxxxx@xxxxxxxxxxx>
)
tag OK Success
tag LOGOUT
* BYE LOGOUT Requested
tag OK 73 good day (Success)
read:errno=0
% _
L'esempio di sopra puo' essere semplificato usando apposite librerie con linguaggi di scripting, per esempio python:
Codice: Seleziona tutto
% python
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imaplib
>>> mail = imaplib.IMAP4_SSL('imap.gmail.com')
>>> mail.login('xxxxxxxxxxx@gmail.com', 'password')
('OK', ['xxxxxxxxxxx@gmail.com xxxxxxxx xxxxxxxx authenticated (Success)'])
>>> mail.select()
('OK', ['545'])
>>> mail.search(None, 'TEXT', '"hello"')
('OK', ['26 37 43 48 55 62 63 80 83 88 89 92 93 94 95 97 112 114 134 150 395 445 447 452 540 541 543'])
>>> mail.fetch(43, '(FLAGS BODY) ')
('OK', ['43 (FLAGS (\\Seen) BODY (("TEXT" "PLAIN" ("CHARSET" "ISO-8859-1") NIL NIL "QUOTED-PRINTABLE" 2435 77)("TEXT" "PLAIN" ("NAME" "stereochemistry_aminoacids.txt") NIL NIL "BASE64" 201974 2589) "MIXED"))'])
>>> mail.close()
('OK', ['Returned to authenticated state. (Success)'])
>>> mail.logout()
('BYE', ['LOGOUT Requested'])
>>> quit()
% _
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
sì, ho fatto confusione, volevo dire: come faccio a scaricare in locale solo le mail che corrispondono a un dato pattern ?ixamit ha scritto:Attenzione, io non capisco questa richiesta.... spiega in dettaglio.
sto leggendo la documentazione di openssl e del modulo imaplib ma credo di avere delle lacune di base da colmare. Per questo il tuo aiuto è prezioso
ho provato a loggarmi con openssl ma alla search ottengo
Codice: Seleziona tutto
tag SEARCH TEXT "qualsiasi cosa"
tag BAD SEARCH not allowed now.
Codice: Seleziona tutto
$ python
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imaplib
>>> m = imaplib.IMAP4_SSL('imap.gmail.com')
>>> m.login('xxx@gmail.com', 'password')
('OK', ['xxxxxxxxx@gmail.com xxxxxxxxx xxxxxxxxx authenticated (Success)'])
>>> m.select()
('OK', ['17'])
>>> m.search(None, 'TEXT', '"certificata"')
('OK', ['6 7 8 9 10 12 13 14 16'])
>>> m.fetch(12, '(FLAGS BODY)')
('OK', ['12 (FLAGS (\\Seen) BODY ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 682 13)("APPLICATION" "XML" ("NAME" "daticert.xml") NIL NIL "BASE64" 1018)("MESSAGE" "RFC822" ("NAME" "postacert.eml") NIL NIL "7BIT" 13914 (NIL "Fwd: POSTA CERTIFICATA: COMUNICAZIONE 2261/2014/LAV" ((NIL NIL "xxxxxxxxx" "pec.it")) ((NIL NIL "xxxxxxxxx" "pec.it")) ((NIL NIL "xxxxxxxxx" "pec.it")) ((NIL NIL "xxxxxxxxx" "gmail.com")) NIL NIL "NIL" "<opec275.20140324160757.25897.02.1.30@pec.aruba.it>") (("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 0 0)("MESSAGE" "RFC822" NIL NIL NIL "7BIT" 12965 ("Mon, 24 Mar 2014 16:07:38 +0100" "POSTA CERTIFICATA: COMUNICAZIONE 2261/2014/LAV" (("Per conto di: tribunale.palermo@civile.ptel.giustiziacert.it" NIL "posta-certificata" "hpcertpe.it")) (("Per conto di: tribunale.palermo@civile.ptel.giustiziacert.it" NIL "posta-certificata" "hpcertpe.it")) ((NIL NIL "tribunale.palermo" "civile.ptel.giustiziacert.it")) ((NIL NIL "xxxxxxxxx" "pec.it")) NIL NIL "NIL" "<opec275.20140324160738.01006.06.6.6@hpcertpe.it>") ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 369 9)("APPLICATION" "XML" ("NAME" "daticert.xml") NIL NIL "BASE64" 1204)("MESSAGE" "RFC822" ("NAME" "postacert.eml") NIL NIL "7BIT" 3798 ("Mon, 24 Mar 2014 16:07:37 +0100 (CET)" "COMUNICAZIONE 2261/2014/LAV" ((NIL NIL "tribunale.palermo" "civile.ptel.giustiziacert.it")) ((NIL NIL "tribunale.palermo" "civile.ptel.giustiziacert.it")) ((NIL NIL "tribunale.palermo" "civile.ptel.giustiziacert.it")) ((NIL NIL "xxxxxxxxx" "pec.it")) NIL NIL "NIL" "<opec275.20140324160738.01006.06.6.6@hpcertpe.it>") (("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 702 25)("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 497 18)("TEXT" "XML" ("CHARSET" "us-ascii" "NAME" "IndiceBusta.xml") "IndiceBusta.xml" NIL "7BIT" 190 0)("TEXT" "XML" ("CHARSET" "us-ascii" "NAME" "Comunicazione.xml") "part54668A405A309E8008D5C442270ED6B4" NIL "7BIT" 924 27) "MIXED") 110) "MIXED")("APPLICATION" "X-PKCS7-SIGNATURE" ("NAME" "smime.p7s") NIL NIL "BASE64" 5066) "SIGNED") 278) "MIXED") 305) "MIXED")("APPLICATION" "X-PKCS7-SIGNATURE" ("NAME" "smime.p7s") NIL NIL "BASE64" 3412) "SIGNED"))'])
>>> m.close()
('OK', ['Returned to authenticated state. (Success)'])
>>> m.logout()
('BYE', ['LOGOUT Requested'])
>>> quit()
$
Dato che vorrei raffinare i risultati della search: :·: la ricerca può essere case sensitive ? :·: c'è modo di cercare la stringa esatta invece delle varie parole ? :·: si possono usare regex ?
questa search si esegue su tutte le mail in INBOX, lette o non-lette: :·: c'è modo di restringerla a quelle UNREAD ?
Se no, dopo aver scaricato le mail desiderate lo script dovrebbe 'archiviarle' per non ritrovarsele alla successiva passata
La webGmail mostra anche il testo della PEC originale ma il testo restituito da fetch non comprende il messaggio PEC originale: è incluso in un allegato che si chiama sempre Comunicazione.xml : :·: come ci si arriva?
Re: filtrare le mail prima di scaricarle
Rispondo velocissimamente in quanto ho i minuti contati, stasera se la famiglia mi concede guardo meglio la situazione.rai ha scritto: domande:
Dato che vorrei raffinare i risultati della search: :·: la ricerca può essere case sensitive ? :·: c'è modo di cercare la stringa esatta invece delle varie parole ? :·: si possono usare regex ?
questa search si esegue su tutte le mail in INBOX, lette o non-lette: :·: c'è modo di restringerla a quelle UNREAD ?
Se no, dopo aver scaricato le mail desiderate lo script dovrebbe 'archiviarle' per non ritrovarsele alla successiva passata
La webGmail mostra anche il testo della PEC originale ma il testo restituito da fetch non comprende il messaggio PEC originale: è incluso in un allegato che si chiama sempre Comunicazione.xml : :·: come ci si arriva?
case sesitive, no, mi sembra proprio che sia specificatamente case-insensitive...
ma non scoraggiarti se guardi il mio precedente post trovi un link al rfc... mi sembra a pagina 49 trovi le risposte alle SEARCH (ed anche SEEN/UNSEEN)
Guardo meglio stasera, scusa
Max
Re: filtrare le mail prima di scaricarle
Vedo di buttare giu' uno schizzo (penso 1/2 ora con qualche test). Ho bisogno *comunque* maggiori info da te.ixamit [url=http://forum.ubuntu-it.org/viewtopic.php?p=4560776#p4560776][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Ciao rai,
Rispondo velocissimamente in quanto ho i minuti contati, stasera se la famiglia mi concede guardo meglio la situazione.rai ha scritto: domande:
Dato che vorrei raffinare i risultati della search: :·: la ricerca può essere case sensitive ? :·: c'è modo di cercare la stringa esatta invece delle varie parole ? :·: si possono usare regex ?
questa search si esegue su tutte le mail in INBOX, lette o non-lette: :·: c'è modo di restringerla a quelle UNREAD ?
Se no, dopo aver scaricato le mail desiderate lo script dovrebbe 'archiviarle' per non ritrovarsele alla successiva passata
La webGmail mostra anche il testo della PEC originale ma il testo restituito da fetch non comprende il messaggio PEC originale: è incluso in un allegato che si chiama sempre Comunicazione.xml : :·: come ci si arriva?
case sesitive, no, mi sembra proprio che sia specificatamente case-insensitive...
ma non scoraggiarti se guardi il mio precedente post trovi un link al rfc... mi sembra a pagina 49 trovi le risposte alle SEARCH (ed anche SEEN/UNSEEN)
Guardo meglio stasera, scusa
Max
Come avrai sicuramente visto, nel rfc non hai le regex, quindi dovresti cercare di "raffinare" la ricerca il piu' possibile con quello che offre il protocollo.
Se proprio hai bisogno regex, la si fa *eventualmente* dopo la prima selezione (se proprio e' indispensabile).
A dopo,
Max
Re: filtrare le mail prima di scaricarle
Codice: Seleziona tutto
#! /usr/bin/env python
import sys
import datetime
import socket, imaplib, email
#
# SET ME PLEASE
# vvvvvvvvvvvvvvvvvvvv
HOST = 'imap.gmail.com'
USER = 'user@gmail.com'
PASS = 'password'
# prefered attachement multiparts tuple (FIXME ?? WTF ANALYSIS ??)
PARTS = ('foo','bar')
# ^^^^^^^^^^^^^^^^^^^^
#
# default
MAILBOX = 'INBOX'
SSL = True
VERBOSE = True
#
#
#
# connect host
#
try:
if SSL:
imap = imaplib.IMAP4_SSL(HOST)
else:
imap = imaplib.IMAP4(HOST)
except socket.error, e:
print ("socket.error: %s\n" % e)
sys.exit(1)
#
# login
#
try:
result, data = imap.login(USER, PASS)
except imaplib.IMAP4.error, e:
print ("imaplib.IMAP4.error: %s\n" % e)
sys.exit(1)
if result != "OK":
print ("login fault: %s\n" % result)
sys.exit(1)
if VERBOSE:
print (data)
#
# select mailbox folder
#
result, data = imap.select(MAILBOX, readonly=True)
if result != "OK":
print ("Error select: %s" % data)
result, data = imap.list()
if result == "OK":
print ("Availables mailbox:")
for i in data:
print i
print ("\nPlease, correct MAILBOX. Exit with error")
imap.logout()
sys.exit(1)
# got count of messages (?? WTF ??)
nmail = int(data[0])
if VERBOSE:
print ("You have %d messages in %s\n" % (nmail, MAILBOX))
#
# searching
# argv[n] as criterion string else "ALL"
if len(sys.argv) > 1:
search = " ".join(sys.argv[1:])
else:
search = "ALL"
search = '('+search+')'
if VERBOSE:
print ("imap.uid('search', None, %s)" % search)
try:
result, data = imap.uid('search', None, search)
except imaplib.IMAP4.error, e:
print (search);
print (e)
sys.exit(1)
if result != "OK":
printf ("Search return something wrong. Sorry, exit with error\n")
sys.exit(1)
#
# fetching
#
list_mail=data[0].split()
if VERBOSE:
print ("Your search returned %d messages" % len(list_mail))
for uid in list_mail:
result, data = imap.uid('fetch', uid, '(RFC822)')
if result != "OK":
# FIXME
continue
mail = email.message_from_string(data[0][1])
if VERBOSE:
print ("Date : %s" % mail['Date'])
print ("From : %s" % mail['From'])
print ("To : %s" % mail['To'])
print ("Subject : %s" % mail['Subject'])
# FIXME WHAT FUCKING WRITE HERE! MISSING ANAL...YSIS
if mail.is_multipart():
for part in mail.walk():
type_ext = part.get_content_type()
filename = part.get_filename()
if filename:
if VERBOSE:
print ("%s ==> %s" % (type_ext, filename))
if type_ext in PARTS:
open(filename, 'wb').write(part.get_payload(decode=True))
if VERBOSE:
print
#End For
imap.close()
imap.logout()
sys.exit(0)
Codice: Seleziona tutto
% time ./foo.py seen from "Diana" SINCE 1-Jan-2013 text "jpg"
['xxxxxxxx@gmail.com xxxxxxxxxxxxxxxxxxxxx authenticated (Success)']
You have 543 messages in INBOX
imap.uid('search', None, (seen from Diana SINCE 1-Jan-2010 text jpg))
Your search returned 1 messages
Date : Sun, 10 Feb 2013 15:29:25 +0000 (GMT)
From : Diana xxxxxxxxxx <xxxxxxxxxxxxxxx@xxxxxxxxxxxxxx>
To : Max <xxxxxx@gmail.com>
Subject : =?iso-8859-1?Q?photoshop_o_realt=E0=3F?=
image/jpeg ==> universe.jpg
real 0m4.882s
user 0m0.060s
sys 0m0.012s
%
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
Codice: Seleziona tutto
$ ./foo.py UNSEEN
['xxxxx@gmail.com xxxxx xxxxx authenticated (Success)']
You have 17 messages in INBOX
imap.uid('search', None, (UNSEEN))
Your search returned 1 messages
Date : Tue, 25 Mar 2014 16:45:23 +0100 (CET)
From : xxxxx.xxxxx@pec.it
To : xxxxx@gmail.com
Subject : Fwd: POSTA CERTIFICATA: COMUNICAZIONE 2677/2014/LAV
application/xml ==> daticert.xml
message/rfc822 ==> postacert.eml
text/xml ==> IndiceBusta.xml
text/xml ==> Comunicazione.xml
application/x-pkcs7-signature ==> smime.p7s
fammi sapere cosa altro ti serve sapere per aiutarmi. Da parte mia prometto di studiarmi tutti i moduli che non conosco che useremo (cosa che faccio comunque sempre)
per ogni evenienza posto il file xml da parsare: la parte interessante sta tra i tag <contenuto>
EDIT Sicuramente per miei limiti, non capisco un'altra cosa: quando apri il file in scrittura, dove dovrebbe venire salvato ? anzi, dato che lo apri senza la sintassi with, non dovresti fare il file.close() ?
- Allegati
-
- Comunicazione.xml
- (657 Byte) Scaricato 60 volte
Re: filtrare le mail prima di scaricarle
Quando sei all'oscuro su quello che devi realmente fare predisponi certe vie che possono anche non corrispondere alle reali esigenze.rai ha scritto: ovviamente le mail che cerchiamo sono multipart, ma non ho capito in questo caso la tupla PARTS cosa deve rappresentare: pensavo di doverci mettere il Content-Type dell'allegato che serve (text/xml) ma evidentemente no, dato che qualsiasi cosa ci ho messo non cambia niente... need help
La tupla e' stata concepita come filtro allegati multipart e viene poi gestita in un unico punto sulla write. Ma la write non posso sapere se ti serve.
Per cui la modifica, se ho capito bene, consiste nel definire il ctype multipart TEXT/XML:
Codice: Seleziona tutto
...
PARTS = ('text/xml','bar')
...
Codice: Seleziona tutto
...
part.get_payload(decode=True)
...
E' poi cosa devi parsare, cosa devi ottenere? Se chiedo informazioni devi fare TU l'analisi di quello che vuoi ottenere...
Questo e' quello che lo script fa attualmente:
Codice: Seleziona tutto
% rm Comunicazione.xml
% ./foo.py 'UNSEEN FROM "MAX"'
['xxxxxxxx@gmail.com xxxxxxxxxxxxxxxxx authenticated (Success)']
You have 545 messages in INBOX
imap.uid('search', None, (UNSEEN FROM "MAX"))
Your search returned 1 messages
Date : Fri, 11 Apr 2014 11:28:32 +0200
From :xxxxxxxxxx <xxxxxxxxx@gmail.com>
To :xxxxxxxxxxxx <xxxxxxxxx@gmail.com>
Subject : prova multipart forum programmazione
text/xml ==> Comunicazione.xml
% ll Comunicazione.xml
-rw-r--r-- 1 me me 657 apr 11 12:14 Comunicazione.xml
Codice: Seleziona tutto
% python
Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree as ET
>>> tree = ET.parse('Comunicazione.xml')
>>> root = tree.getroot()
>>> for child in root:
... print child.tag, child.text
...
NumeroRuolo xxxx/2014/LAV
Oggetto FISSAZIONE UDIENZA DI COMPARIZIONE PARTI
Contenuto --
Comunicazione di cancelleria
Sez/Coll.: LA
Tipo procedimento: Diritto del Lavoro
Numero di Ruolo generale: xxxx/2014
Giudice: xxx xxx
Ricorr. principale: xxx xxx
Resist. principale: xxx
Oggetto: FISSAZIONE UDIENZA DI COMPARIZIONE PARTI
Descrizione: FISSATA UDIENZA DI COMPARIZIONE PARTI IL xxx 09:00 NOMINATO CTU xxx xxx
Note:
Notificato alla PEC / in cancelleria il xxx 12:10
Registrato da xxx
--
CodiceUG 0820530098
CodiceFiscaleDestinatario xxxxxxxxx
>>> quit()
% _
Max
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
appena possibile ( stasera? ) cerco di risponderti dopo aver fatto qualche prova
Ciao,
Rai
Re: filtrare le mail prima di scaricarle
stavo rileggendo l'intero 3d e mi era sfuggita questa tua affermazione:
Se cosi' fosse, sarebbe opportuno restringere la ricerca inziale con:rai ha scritto: La webGmail mostra anche il testo della PEC originale ma il testo restituito da fetch non comprende il messaggio PEC originale: è incluso in un allegato che si chiama sempre Comunicazione.xml : :·: come ci si arriva?
Codice: Seleziona tutto
% ./foo.py 'UNSEEN TEXT "comunicazione.xml"'
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
purtroppo arrivano messaggi con 'Comunicazioni.xml' che non contengono i dati che mi servono. Bada bene che se è un casino filtrare ulteriormente le mail, non è un problema fetchare tutte quelle che contengono Comunicazione.xml e poi la greppata la faccio in locale. Il fatto è che ancora non ho capito come dovrebbe arrivare il contenuto di questi allegati nella mia shell mi spiace sono di coccio
scusa, ho una specie di afasia e non riesco a selezionare le info necessarie da quelle superflueixamit ha scritto: Quando sei all'oscuro su quello che devi realmente fare predisponi certe vie che possono anche non corrispondere alle reali esigenze.
quello che devo fare è: appena possibile, dopo l'arrivo della mail, devo predisporre dei documenti odt. Per farlo voglio estrarre determinate substringhe da <contenuto> per metterle nei campi che per ora riempo a manina . . .rai ha scritto:per ogni evenienza posto il file xml da parsare: la parte interessante sta tra i tag <contenuto>
Re: filtrare le mail prima di scaricarle
rai ha scritto: Nope
purtroppo arrivano messaggi con 'Comunicazioni.xml' che non contengono i dati che mi servono. Bada bene che se è un casino filtrare ulteriormente le mail, non è un problema fetchare tutte quelle che contengono Comunicazione.xml e poi la greppata la faccio in locale. Il fatto è che ancora non ho capito come dovrebbe arrivare il contenuto di questi allegati nella mia shell mi spiace sono di coccio
Il primo punto e' la selezione iniziale delle mail da leggere e qui' devi per forza di cose utilizzare la SEARCH del protocollo, magari con piu' chiavi tipo UNSEEN, FROM, SINCE e TEXT. Questo ovviamente per restringere il campo FETCH e ridurre i tempi.
Ora puoi:
1) scaricare/visualizzare localmente *solo* l'allegato ctype == 'TEXT/XML' che contiene il tag <Contenuto>
2) scaricare/visualizzare localmente il testo contenuto all'interno del tag <Contenuto>
3) Applicare una regex sul testo al punto 2
Prova con questa versione leggermente modificata seguendo l'opzione 2:
Codice: Seleziona tutto
#! /usr/bin/env python
import sys
import datetime
import socket, imaplib, email
import xml.etree.ElementTree as ET
#
# SET ME PLEASE
# vvvvvvvvvvvvvvvvvvvv
HOST = 'imap.gmail.com'
USER = 'user@gmail.com'
PASS = 'password'
CONTENT = './Contenuto'
# ^^^^^^^^^^^^^^^^^^^^
#
# default
MAILBOX = 'INBOX'
SSL = True
VERBOSE = False
#
#
#
# connect host
#
try:
if SSL:
imap = imaplib.IMAP4_SSL(HOST)
else:
imap = imaplib.IMAP4(HOST)
except socket.error, e:
print ("socket.error: %s\n" % e)
sys.exit(1)
#
# login
#
try:
result, data = imap.login(USER, PASS)
except imaplib.IMAP4.error, e:
print ("imaplib.IMAP4.error: %s\n" % e)
sys.exit(1)
if result != "OK":
print ("login fault: %s\n" % result)
sys.exit(1)
if VERBOSE:
print (data)
#
# select mailbox folder
#
result, data = imap.select(MAILBOX, readonly=True)
if result != "OK":
print ("Error select: %s" % data)
result, data = imap.list()
if result == "OK":
print ("Availables mailbox:")
for i in data:
print i
print ("\nPlease, correct MAILBOX. Exit with error")
imap.logout()
sys.exit(1)
# got count of messages (?? WTF ??)
nmail = int(data[0])
if VERBOSE:
print ("You have %d messages in %s\n" % (nmail, MAILBOX))
#
# searching
# argv[n] as criterion string else "ALL"
if len(sys.argv) > 1:
search = " ".join(sys.argv[1:])
else:
search = "ALL"
search = '('+search+')'
if VERBOSE:
print ("imap.uid('search', None, %s)" % search)
try:
result, data = imap.uid('search', None, search)
except imaplib.IMAP4.error, e:
print (search);
print (e)
sys.exit(1)
if result != "OK":
printf ("Search return something wrong. Sorry, exit with error\n")
sys.exit(1)
#
# fetching
#
list_mail=data[0].split()
if VERBOSE:
print ("Your search returned %d messages" % len(list_mail))
for uid in list_mail:
result, data = imap.uid('fetch', uid, '(RFC822)')
if result != "OK":
# FIXME
continue
mail = email.message_from_string(data[0][1])
if VERBOSE:
print ("Date : %s" % mail['Date'])
print ("From : %s" % mail['From'])
print ("To : %s" % mail['To'])
print ("Subject : %s" % mail['Subject'])
# FIXME WHAT FUCKING WRITE HERE! MISSING ANAL...YSIS
if mail.is_multipart():
for part in mail.walk():
type_ext = part.get_content_type()
filename = part.get_filename()
if filename:
if VERBOSE:
print ("%s ==> %s" % (type_ext, filename))
if type_ext == 'text/xml':
# open(filename, 'wb').write(part.get_payload(decode=True))
#
root = ET.fromstring(part.get_payload(decode=True))
content = root.findall(CONTENT)
if content:
for elem in content:
print elem.text
if VERBOSE:
print
#End For
imap.close()
imap.logout()
sys.exit(0)
Codice: Seleziona tutto
max@studio:~/foo$ time ./foo.py 'UNSEEN FROM "MAX" SINCE 10-Apr-2014'
--
Comunicazione di cancelleria
Sez/Coll.: LA
Tipo procedimento: Diritto del Lavoro
Numero di Ruolo generale: xxxx/2014
Giudice: xxx xxx
Ricorr. principale: xxx xxx
Resist. principale: xxx
Oggetto: FISSAZIONE UDIENZA DI COMPARIZIONE PARTI
Descrizione: FISSATA UDIENZA DI COMPARIZIONE PARTI IL xxx 09:00 NOMINATO CTU xxx xxx
Note:
Notificato alla PEC / in cancelleria il xxx 12:10
Registrato da xxx
--
real 0m2.692s
user 0m0.052s
sys 0m0.012s
max@studio:~/foo$
-
- Imperturbabile Insigne
- Messaggi: 2842
- Iscrizione: domenica 11 maggio 2008, 18:03
- Desktop: plasma
- Distribuzione: 22.04
- Località: Palermo
Re: filtrare le mail prima di scaricarle
Codice: Seleziona tutto
./foo.py 'unseen TEXT "Comunicazione.xml"' > outfile
solo mi vengono in mente un paio di cose:
:1: la ricerca può restituire diverse mail (anche *tutte utili*) e il loro contenuto finirebbe nello stesso outfile creando qualche confusione in più a awk/grep. Che faresti? printare un separatore di caratteri non equivoci a inizio e fine di ogni mail?
:2: come dicevo prima, serve fare su tutte le mail fetchate qualcosa del tipo
imap.store(mail_num, '+flags.silent', '\\seen')
imap.store(mail_num, '-flags.silent', '\\unseen')
che non saprei come mettere nello script, dato che tu cicli sugli uid e non sui mail_num
:0: se cortesemente ripulisci lo script dallo stuff non utilizzato, oltre ad aiutarmi avrai avuto un ruolo didattico perché mi verrà più facile studiarmi i vari metodi
grazie veramente per la pazienza
Chi c’è in linea
Visualizzano questa sezione: 0 utenti iscritti e 12 ospiti