#!/usr/local/bin/perl # # Copyright (c) by Kirill Miazine # # This software is distributed under an ISC-style license, please see # for details. # use lib qw( /local/perl /local/perl5/lib/perl5 /local/perl5/lib/perl5/amd64-freebsd ); use Mojolicious::Lite; use IO::Socket::INET; use IO::Socket::SSL; use Mail::IMAPTalk; use Email::MIME; use Date::Parse qw(str2time); use Date::Format qw(time2str); use constant IMAP_HOST => 'localhost:2143'; use constant IMAP_SSL => 0; use constant NOTES_FOLDER => 'Notes'; helper imap_notes => sub { my $self = shift; my $notedata = {}; my @notes; my $imap = $self->stash('_imap'); $imap->examine(NOTES_FOLDER); for my $uid (@{$imap->sort('(date)', 'utf-8', qw(not deleted))}) { my $res = $imap->fetch($uid, '(rfc822)'); my $x = $res->{$uid}; my $msg = Email::MIME->new($x->{'rfc822'}); my $hdr = $msg->header_obj(); my $uuid = $hdr->header('x-universally-unique-identifier'); my $created = str2time($hdr->header('x-mail-created-date')); my $subject = $hdr->header('subject'); my $type = $msg->content_type(); my $body = $msg->body_str(); push @notes, {uid => $uid, uuid => $uuid, subject => $subject, body => $body, type => $type}; } return @notes; }; get '/' => sub { my $self = shift; $self->render('notes'); }; get '/logout' => sub { my $self = shift; $self->session->{'auth_prompt'} = 1; $self->redirect_to('/'); }; get '/:uuid' => sub { my $self = shift; my $uuid = $self->stash('uuid'); my @note = grep { $_->{'uuid'} eq $uuid } $self->imap_notes() or return $self->redirect_to('/'); $self->render('note', note => $note[0]); }; app->plugin('basic_auth'); app->secret('kQyeUANFQRsF9dAXh7Zf3L69UVBqHW'); app->hook(before_dispatch => sub { my $self = shift; my $now = time; return $self->render_text('Please login') if !$self->basic_auth('Notes', sub { my ($u, $p) = @_; delete $self->session->{'auth_prompt'}, return if $self->session->{'auth_prompt'}; if ($u and $p) { my $sock = (IMAP_SSL ? IO::Socket::SSL->new(IMAP_HOST) : IO::Socket::INET->new(IMAP_HOST)) or return; my $imap = Mail::IMAPTalk->new( Socket => $sock, Username => $u, Password => $p, Uid => 1, USeBlocking => 1 ) or return; $imap->set_unicode_folders(1); $imap->select(NOTES_FOLDER) or return; $self->stash(_imap => $imap); } }); }); app->hook(after_dispatch => sub { my $self = shift; my $imap = $self->stash('_imap'); eval { $imap->logout(); }; }); app->start; __DATA__ @@ notes.html.ep % layout 'notes'; @@ note.html.ep % layout 'notes';

<%= $note->{'subject'} %>

<%== $note->{'body'} %>
@@ layouts/notes.html.ep Notes

">Notes (">exit)

<%= content %>