Moduł Mail::MboxParser

Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowa

Co to jest?

Moduł ten próbuje zapewnić prosty dostęp do standardowych uniksowych skrzynek mailowych. Oferuje jedynie podzbiór metod które mają doprowadzić nas prosto do celu. Bardziej wyrafinowane rzeczy dalej można zrobić wywołując metody z MIME::Tools na odpowiednie zwracane wartości. Nie pozwoli ci on niestety na wysyłanie wiadomości, jedyne jego zastosowanie to odczytywanie wiadomości zawartych w skrzynce.

Mail::MboxParser nie wywodzi się z Mail::Box i nie jest z nim w żaden sposób związany. Zawiera jednak pewnie rozwiązania powstałe dzięki nieocenionym wskazówkom autora Mail::Box, Marka Overmeera.

Poprzez uniksową skrzynke mailową rozmiemy sposób zapisu oraz przetrzymywania maili na sytsemach uniksowych. Uniks używa dwóch skrzynek mailowych do przetrzymywania wiadomości, systemową skrzynke mailową (katalogi mogą różnić się w zależności od systemu np./usr/spool/mail,/var/spool/mail,/var/mail/), skrzynka mailową użytkownika (znajduje się w jego katalogu domowym najczęściej ~/mbox). Maile przychodzą na skrzynkę systemową, zapisywane są natomiast w skrzynce użytkownika po ich przeczytaniu. Pliki przetrzymujące wiadomości zapisywane są w mało czytelnej formie. Dlatego właśnie potrzebujemy specjalnych narzędzi aby je przeczytać.

Metody

new(mailbox, options)
new(scalar-ref, options)
new(array-ref, options)
new(filehandle, options)

Tworzy nowy obiekt MboxParser otwierający określoną skrzynkę mailową, obojętnie z absolutną czy względną ścieżką.

new() może również pobierać referencje do zmiennej zawierającą skrzynkę zarówno jako jeden napis (wskaźnik do skalara) jak i wskaźnik do tablicy, oraz uchwyty do plików z których ma być czytana poczta.

Poniższe opcje mogą okazać sie użyteczne. Wartości w nawiasach poniżej klucza są domyślne.

klucz: | wartość: | opis: ==========|============|=============================== decode | 'NEVER' | nigdy nie odkodowuje przesyła (NEVER) | | zakodowane dane |------------|------------------------------- | 'BODY' | odkoduje treść do formatu | | czytelnego dla człowieka |------------|------------------------------- | 'HEADER' | odkoduje nagłówki jeśli któryś | | jest zakodowany |------------|------------------------------- | 'ALL' | odkodowuje wszystkie dane ==========|============|=============================== uudecode | 1 | włącza rozpakowywanie (0) | | załączników w MIME::Parser |------------|------------------------------- | 0 | zakodowane załączniki są | | traktowane jako tekst treści ==========|============|=============================== newline | 'UNIX' | uniksowe końce linii (AUTO) | | ("\n" vel \012) |------------|------------------------------- | 'WIN' | Win32 końce linii | | ("\n\r" vel \012\015) |------------|------------------------------- | 'AUTO' | spróbuj samowykrywania |------------|------------------------------- | custom | określone przez użytkownika | | ==========|============|=============================== oldparser | 1 | używa starszego (i wolniejszego) (0) | | parsera (gwarantuje stare | | zachowanie) |------------|------------------------------- | 0 | używa Mail::Mbox::MessageParser ==========|============|=============================== parseropts| | zobacz "Wyszczególnione | | opcje parsera" niżej ==========|============|===============================

Opcja newline staje sie przydatna jeśli mamy skrzynkę mailową która nie odwzorowuje wartości ustawień systemowych co do kodowania. Na przykład używasz modułu pod Windowsem ale rozmyślnie masz skrzynkę mailową z nowymi liniami uniksowymi (lub odwrotnie). Jeśli nie ustawisz tej opcji, zakładane jest AUTO, i podstawowe testy są wykonywane na skrzynce. Ta autodetekcja nie jest oczywiście w stanie wykryć przypadku kiedy jako znacznik nowej linii ustawiony jest np. #DELIMITER. Jak na razie potrafi rozróżnic pomiędzy uniksowymi a Win32 nowymi liniami. Jeśli masz szczęście to może działa też na Macintoshach. Jeśli masz bardziej ekstrawaganckie życzenia możesz dać bardziej wymyślne wartości:

my $mb = new Mail::MboxParser ("mbox", newline => '#DELIMITER');

Nie możesz jednak dać w tym miejscu wyrażeń regularnych.

Kiedy zarówno wskaźnik do skalara, tablicy jak i \*STDIN dany jest jako pierwszy argument, anonimowy plik tymczasowy jest tworzony do przechowywania danych. Ten proces jest ukryty przed użytkownikiem więc nie ma sie co o niego martwić. Skoro plik tymczasowy zachowuje sie dokładnie tak samo jak skrzynka mailowa nie ma obawy o straty danych, ponieważ wciąż poruszamy sie po danych skrzynki. Żadne dane nie zostaną stracone i wszystko będzie przebiegać gładko.

Wyszczególnione opcje parsera

Kiedy jest dostępny moduł będzie używał Mail::Mbox::MessageParser do parsowania. Aby uzyskać jak największa szybkość możesz zmienić niektóre jego opcje. Prawdopodobnie będziesz musiał to zrobić aby uzyskać cachowanie. Opcje dla parsera są dane poprzez parserops który spodziewa sie referencji do hasza jako wartości. Wartości jakie można podać to:

  • enable_cache
  • Ustawione na prawdę, cachowanie jest używane jedynie jeśli podasz cache_file_name. Nie ma tu wartości domyślnej.

  • cache_file_name
  • Plik używany do cachowania. Ta opcja jest obowiązkowa jeśli enable_cache zostało użyte.

  • enable_grep
  • Kiedy jest ustawione na prawdę (domyślnie), zewnętrzny grep(1) jest użyty aby przyśpieszyć parsowanie. Jeśli twój system nie dostarcza implementacji grep'a, po cichu wraca do parsowania czysto perlowego.

    open(source, options)

    Pobiera dokładnie te same argumenty co new() robi to aby można było zmienić charakterystykę skrzynki mailowej w locie.

    get_messages

    Zwraca tablice zawierającą wszystkie wiadomości ze skrzynki reprezentowane jako obiekty Mail::MboxParser::Mail. Ta metoda jest minimalnie szybsza od iteracji po skrzynce używając next_message ale potrzebuje więcej pamięci. Zużycie pamięci będzie rosło linowo dla każdej nowej wykrytej wiadomości skoro ta metoda tworzy ogromną tablice zawierającą wszystkie wiadomości. Po stworzeniu tej tablicy zostanie ona zwrócona.

    get_message(n)

    Zwraca n-tą wiadomość (pierwsza ma indeks 0) ze skrzynki. Sprawdza $mb->error która zawiera zapis o błędzie jeśli dana wiadomość nie istnieje. W takim przypadku, get_message zwraca undef.

    next_message

    Pozwala iterować po skrzynce jedna wiadomość po drugiej. Wielką przewagą nad get_messages jest bardzo małe zużycie pamięci. Będzie na stałym poziomie w trakcie egzekucji twojego programu. Po drugie od razu zwraca obiekty Mail::MboxParser::Mail ponieważ nie musi przetworzyć wszystkich wiadomości zanim je zwróci.

    set_pos(n)
    rewind
    current_pos

    Te trzy metody radzą sobie z pozycją wewnętrznego uchwytu do pliku skrzynki. Kiedy juz przejdziesz iteracją po całej skrzynce używając next_message MboxParser sięgną końca skrzynki, musimy więc ustawić pozycje aby można było iterować jeszcze raz. Można to zrobić zarówno set_pos albo rewind:

    $mb->rewind; # to samo co $mb->set_pos(0);

    current_pos ujawnia bieżącą pozycje w skrzynce mailowej, może zostać użyta aby później wrócić do tej pozycji jeśli chcemy robić ciekawe rzeczy. Zauważ że current_pos nie zwraca bieżącej linii ale raczej bieżący znak tak samo jak zwracany przez Perlową funkcje tell();

    Należy uważać z tymi metodami używając parsera Mail::Mbox::MessageParser. Ten parser podtrzymuje swój własny stan i nie powinieneś spodziewać się ze będzie on zsynchronizowany z Mail::MboxParser.

    make_index

    Możesz wymusić stworzenie indeksu wiadomości tą metodą. Indeks wiadomości jest mapowaniem pomiędzy numerem indeksu a pozycją bajtu w uchwycie pliku. Za zwyczaj jest to robione automatycznie zaraz po wywołaniu get_message stąd pierwsze wywołanie dla odpowiedniej wiadomości będzie trochę wolniejsze skoro indeks wiadomości musi wcześniej zostać zbudowany. Jest to robione raczej szybko.

    get_pos(n)

    Ta metoda pobiera numer indeksu pewnej wiadomości w skrzynce i zwraca odpowiadającą mu pozycje w uchwycie pliku która reprezentuje ten początek pliku.

    Jest to zazwyczaj używane przez get_message() i nie powinieneś zawracać sobie głowy używaniem jej, za wyjątkiem celów statystycznych.

    nmsgs

    Zwraca ilość wiadomości w skrzynce. Możesz oczywiście również użyć get_messages w kontekście skalarnym, ale wtedy nie utworzymy nowego obiektu. To po prostu zliczy je ponieważ będzie to znacznie szybciej i przy użyciu mniejszej pamięci.

    parser

    Zwraca nagi obiekt Mail::Mbox::MessageParser. Jeśli nie ma takiego obiektu zwraca undef.

    Możesz użyć tej metody do sprawdzenia czy moduł ten używa nowej czy starej wersji parsera. Jeśli parser zwróci wartość fałsz, używa starego pasera.

    Metody wspólne dla wszystkich obiektów

    error

    Wywołaj to metode zaraz po jednej z metod opisanych wyżej możliwa wiadomość o błędzie.

    log

    Pewne wewnętrzne dziwności są tu zapisywane. Znowu tylko ostatnie zdarzenie jest zachowywane.

    Obsługa błędów.

    Mail::MboxParser zapewnia mechanizm abyś mógł zrozumieć dlaczego niektóre metody nie funkcjonują w sposób jaki się tego spodziewasz. To są cztery klasy od niespodziewanych zachowań:

    (1) błędne argumenty

    W tym przypadku wywołujesz metode z argumentami które nie maja sensu, stąd Mail::MboxParser jest zmieszany. Na przykład:

    $mail->store_entity_body; # źle, potrzebuje 2 argumentów $mail->store_entity_body(0); # źle, ciągle potrzebuje jeszcze jednego

    Każdy z powyższych przypadków, da wiadomość o błędzie skrypt zakończy działanie. Wiadomość jednak, powie w której linii twojego skryptu wystąpił błąd.

    (2) poprawne argumenty ale...

    Rozważmy taki kod:

    $mail->store_entity_body(50, \*FH); # może być błędnie

    Oczywiście wywołałeś store_entity_body z odpowiednią liczbą argumentów. To dobrze bo twój skrypt nie zakończy sie tak po prostu. Niestety, twój program nie może wiedzieć wcześniej czy odpowiedni $mail ma 51 jednostkę.

    Co zrobić w takim przypadku?

    Napisać powyższa linie oraz kod sprawdzający zaraz za nią poprzez wywołanie $mail->error:

    $mail->store_entity_body(50, *\FH); if ($mail->error) { print "Oups, something wrong:", $mail->error; }

    W opisach dostępnych metod powyżej, zawsze znajdziesz uwagę kiedy mogłeś użyć $mail->error.

    (3)błędy, których nigdy nie widać

    Niestety istnieją. Kiedy obsługujesz rzeczy z MIME często np. załączniki, Mail::MboxParser wywołuje wiele metod dostarczonych przez pakiet MIME::Tools. Współpracują one doskonale w większości przypadków, ale MIME::Tools może nie wyprodukować nic sensownego jeśli mamy dziwną albo bardzo zagmatwaną skrzynkę.

    Jeśli to sie zdąży możesz znaleźć jakieś informacje na ten temat wywołując $mail->log. Da ci to mniej lub bardziej przefiltrowane wiadomości błędów wyprodukowane przez MIME::Tools.

    (4)apokalipsa

    Jeśli wydaje się że nic nie działa a $mail->error jest pusty. Wtedy w najgorszym przypadku Mail::MboxParser zawiera błąd.

    Nie trzeba chyba mówić ze w takim przypadku należy się skontaktować z autorem.

    Dodatkowe informacje.

    Moj przykładowy progam
    use Mail::MboxParser; my $parseropts = { enable_cache => 1, enable_grep => 1, }; my $mb = Mail::MboxParser->new('/var/mail/paczek', decode => 'ALL', parseropts => $parseropts); print $mb->get_message($mb->nmsgs-1);

    Wynik programu witać tutaj:


    Przydatne linki

    Dokumentacja tego modułu w cpan'ie
    Jeszcze więcej dokumentacji

    Kontakt i informacje o autorze opracowania

    Autor modułu:

    Tassilo von Parseval.

    Autor przekładu: MD

    Numer GG: Słoneczko 2194164

    Uniwersytet Gdański - Instytut Informatyki - Strona domowa - Perl - Wyklady
    [c] Piotr Arłukowicz, materiały z tej strony udostępnione są na licencji GNU.