diff --git a/II/Config.pm b/II/Config.pm new file mode 100644 index 0000000..6d734af --- /dev/null +++ b/II/Config.pm @@ -0,0 +1,36 @@ +package II::Config; + +use Config::Tiny; + +sub new { + my $class = shift; + + my $c = Config::Tiny->new(); + $c = Config::Tiny->read('config.ini'); + + my $self = { _config => $c, }; + + bless $self, $class; + return $self; +} + +sub load { + my ($self) = @_; + my $config = $self->{_config}; + + my $key = $config->{auth}->{key}; + my $nick = $config->{auth}->{nick}; + my $host = $config->{node}->{host}; + my @echoareas = split /,/, $config->{node}->{echoareas}; + + $c = { + nick => $nick, + key => $key, + host => $host, + echoareas => [@echoareas], + }; + + return $c; +} + +1; diff --git a/II/DB.pm b/II/DB.pm new file mode 100644 index 0000000..e44d628 --- /dev/null +++ b/II/DB.pm @@ -0,0 +1,258 @@ +package II::DB; + +use SQL::Abstract; +use DBI; + +use Data::Dumper; + +sub new { + my $class = shift; + + my $dbh = DBI->connect( "dbi:SQLite:dbname=ii.sql", "", "" ); + my $sql = SQL::Abstract->new(); + + my $self = { + _dbh => $dbh, + _sql => $sql, + }; + + bless $self, $class; + return $self; +} + +sub write_out { + my ( $self, %data ) = @_; + my $dbh = $self->{_dbh}; + my $sql = $self->{_sql}; + + my ( $stmt, @bind ) = $sql->insert( 'output', \%data ); + + my $sth = $dbh->prepare($stmt); + $sth->execute(@bind); + + print "Message writed to DB!\n"; +} + +sub update_out { + my ($self, $hash) = @_; + my $dbh = $self->{_dbh}; + + my $q = "update output set send=1 where hash='$hash'"; + my $sth = $dbh->prepare($q); + $sth->execute(); +} + +sub write { + my ( $self, %data ) = @_; + my $dbh = $self->{_dbh}; + my $sql = $self->{_sql}; + + my ( $stmt, @bind ) = $sql->insert( 'messages', \%data ); + + my $sth = $dbh->prepare($stmt); + $sth->execute(@bind); + + print "Message writed to DB!\n"; +} + +sub select_out { + my ($self) = @_; + my $dbh = $self->{_dbh}; + + my $q + = "select from_user, to_user, subg, time, echo, post, hash, base64 from output where send=0"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + + my @posts; + while ( my @hash = $sth->fetchrow_array() ) { + my ( $from, $to, $subg, $time, $echo, $post, $h, $base64 ) = @hash; + my $data = { + from => "$from", + to => "$to", + subg => "$subg", + time => $time, + echo => "$echo", + post => "$post", + hash => $h, + base64 => $base64, + }; + push( @posts, $data ); + } + + return @posts; +} + +sub select_index { + my ( $self, $limit ) = @_; + my $dbh = $self->{_dbh}; + + my $q = "select hash from messages order by time desc limit $limit"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + + my @hashes; + while ( my @hash = $sth->fetchrow_array() ) { + my ($h) = @hash; + push( @hashes, $h ); + } + + return @hashes; +} + +sub select_subg { + my ( $self, $echo ) = @_; + +} + +sub from_me { + my ( $self, $config ) = @_; + my $dbh = $self->{_dbh}; + my $nick = $config->{nick}; + + # print Dumper($config); + # print "NICK: $nick\n"; + + my $q + = "select from_user, to_user, subg, time, echo, post, hash from messages where from_user='$nick'"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + + my @posts; + while ( my @hash = $sth->fetchrow_array() ) { + my ( $from, $to, $subg, $time, $echo, $post, $h ) = @hash; + my $data = { + from => "$from", + to => "$to", + subg => "$subg", + time => $time, + echo => "$echo", + post => "$post", + hash => $h, + }; + push( @posts, $data ); + } + + return @posts; +} + +sub thread { + my ( $self, $subg, $echo ) = @_; + my $dbh = $self->{_dbh}; + + my $q + = "select from_user, to_user, subg, time, echo, post, hash from messages where echo='$echo' and subg like '%$subg%' order by time"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + + my @posts; + while ( my @hash = $sth->fetchrow_array() ) { + my ( $from, $to, $subg, $time, $echo, $post, $h ) = @hash; + my $data = { + from => "$from", + to => "$to", + subg => "$subg", + time => $time, + echo => "$echo", + post => "$post", + hash => $h, + }; + push( @posts, $data ); + } + + return @posts; +} + +sub echoes { + my ( $self, $echo ) = @_; + my $dbh = $self->{_dbh}; + + my $q + = "select from_user, to_user, subg, time, echo, post, hash from messages where echo='$echo' order by time desc"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + + my @posts; + while ( my @hash = $sth->fetchrow_array() ) { + my ( $from, $to, $subg, $time, $echo, $post, $h ) = @hash; + my $data = { + from => "$from", + to => "$to", + subg => "$subg", + time => $time, + echo => "$echo", + post => "$post", + h => $h, + }; + push( @posts, $data ); + } + + return @posts; +} + +sub to_me { + my ( $self, $config ) = @_; + my $dbh = $self->{_dbh}; + my $nick = $config->{nick}; + + # print Dumper($config); + # print "NICK: $nick\n"; + + my $q + = "select from_user, to_user, subg, time, echo, post, hash from messages where to_user='$nick'"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + + my @posts; + while ( my @hash = $sth->fetchrow_array() ) { + my ( $from, $to, $subg, $time, $echo, $post, $h ) = @hash; + my $data = { + from => "$from", + to => "$to", + subg => "$subg", + time => $time, + echo => "$echo", + post => "$post", + hash => "$h", + }; + push( @posts, $data ); + } + + return @posts; +} + +sub select_new { + my ( $self, $msg ) = @_; + my $dbh = $self->{_dbh}; + + my $q + = "select from_user, to_user, subg, time, echo, post, hash from messages where hash='$msg'"; + + my $sth = $dbh->prepare($q); + $sth->execute(); + my ( $from, $to, $subg, $time, $echo, $post ); + + while ( my @hash = $sth->fetchrow_array() ) { + ( $from, $to, $subg, $time, $echo, $post, $h ) = @hash; + } + + my $data = { + from => "$from", + to => "$to", + subg => "$subg", + time => $time, + echo => "$echo", + post => "$post", + hash => "$h", + }; + + return $data; +} + +1; diff --git a/II/Enc.pm b/II/Enc.pm new file mode 100644 index 0000000..a6484f9 --- /dev/null +++ b/II/Enc.pm @@ -0,0 +1,65 @@ +package II::Enc; + +use II::DB; +use MIME::Base64; + +sub new { + my $class = shift; + + my $db = II::DB->new(); + + my $self = { + _config => shift, + _data => shift, + _db => $db, + }; + + bless $self, $class; + return $self; +} + +sub encode { + my ($self) = @_; + my $config = $self->{_config}; + my $data = $self->{_data}; + my $db = $self->{_db}; + my $hash = II::Enc->new_hash(); + + # Make base64 message + my $message = $data->{echo}."\n"; + $message .= $data->{to}."\n"; + $message .= $data->{subg}."\n\n"; + $message .= '@repto:'.$data->{hash}."\n" if defined($data->{hash}); + $message .= $data->{post}; + + my $encoded = `echo "$message" | base64`; + $encoded =~ s/\//_/g; + $encoded =~ s/\+/-/g; + + # Make data + my %out = ( + hash => $hash, + time => $data->{time}, + echo => $data->{echo}, + from_user => $data->{from}, + to_user => $data->{to}, + subg => $data->{subg}, + post => $data->{post}, + base64 => $encoded, + send => 0, + ); + + $db->write_out(%out); + + return 0; +} + +sub new_hash { + my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9 ); + my $string; + $string .= $chars[ rand @chars ] for 1 .. 21; + + return $string; +} + +1; diff --git a/II/Get.pm b/II/Get.pm new file mode 100644 index 0000000..c619b45 --- /dev/null +++ b/II/Get.pm @@ -0,0 +1,108 @@ +package II::Get; +use LWP::Simple; + +use II::DB; + +use Data::Dumper; + +sub new { + my $class = shift; + + my $self = { _config => shift, }; + + bless $self, $class; + return $self; +} + +sub get_echo { + my ($self) = @_; + my $config = $self->{_config}; + my $echoareas = $config->{echoareas}; + my $host = $config->{host}; + + my $db = II::DB->new(); + + my $echo_url = 'e/'; + my $msg_url = 'm/'; + + my $msgs; + foreach my $echo (@$echoareas) { + # my @content = get( "$host" . "$echo_url" . "$echo" ); + my @content = `curl $host$echo_url$echo`; + + # if ( is_success( getprint( "$host" . "$echo_url" . "$echo" ) ) ) { + + # Write echoes file + open my $echo_fh, ">", "./echo/$echo" + or die "Cannot open file: $!\n"; + print $echo_fh @content; + close $echo_fh; + + # Get messages + open my $echo_fh, "<", "./echo/$echo" + or die "Cannot open file: $!\n"; + while (<$echo_fh>) { + chomp($_); + if ( !( -e "./msg/$_" ) ) { + $msgs .= $_ . "\n"; + # @w_cmd = ( 'wget', '-O', + # "./msg/$_", "$host" . "$msg_url" . "$_" ); + `curl $host$msg_url$_ > ./msg/$_`; + # system(@w_cmd) == 0 or die "Cannot download file: $!\n"; + } + } + close $echo_fh; + + # } + } + + my $new_messages + = "
Новых сообщений нет
"; + # } + $render .= $t->foot(); + + return $render; +} + +1; diff --git a/II/Send.pm b/II/Send.pm new file mode 100644 index 0000000..4e4319c --- /dev/null +++ b/II/Send.pm @@ -0,0 +1,41 @@ +package II::Send; + +use HTTP::Request::Common qw(POST); +use LWP::UserAgent; +use II::DB; +use Data::Dumper; + +sub new { + my $class = shift; + + my $self = { + _config => shift, + _echo => shift, + _base64 => shift, + }; + + bless $self, $class; + return $self; +} + +sub send { + my ($self, $hash) = @_; + my $config = $self->{_config}; + my $echo = $self->{_echo}; + my $base64 = $self->{_base64}; + + # Push message to server + my $host = $config->{host}; + my $auth = $config->{key}; + $host .= "u/point"; + my $ua = LWP::UserAgent->new(); + my $response = $ua->post( $host, { 'pauth' => $auth, 'tmsg' => $base64 } ); + print Dumper($response); + + my $db = II::DB->new(); + if ($response->{_rc} == 200) { + $db->update_out($hash); + } +} + +1; diff --git a/II/T.pm b/II/T.pm new file mode 100644 index 0000000..5fb2100 --- /dev/null +++ b/II/T.pm @@ -0,0 +1,169 @@ +package II::T; + +use HTML::Template; +use Data::Dumper; + +sub new { + my $class = shift; + my $self = {}; + bless $self, $class; + return $self; +} + +sub head { + my ( $self, $title ) = @_; + my $t = HTML::Template->new( filename => 't/head.html' ); + + $t->param( TITLE => $title ); + + return $t->output; +} + +sub index { + my ( $self, $echoareas ) = @_; + my $i = HTML::Template->new( filename => 't/index.html' ); + + my $index = '/g; + $pre = 1; + } + elsif ( ( $line =~ /^====/ ) and ( $pre == 1 ) ) { + $line =~ s/====/<\/pre>\n====/g; + $pre = 0; + } + $txt .= $line; + } + close $fh; + return $txt; +} + +sub foot { + my ($self) = @_; + + my $f = HTML::Template->new( filename => 't/foot.html' ); + + return $f->output(); +} + +1; diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..34a050c --- /dev/null +++ b/config.ini @@ -0,0 +1,7 @@ +[auth] +key = you_auth_key +nick = you_nick + +[node] +host = http://your_ii_node.ii +echoareas = im.100 diff --git a/ii.sql b/ii.sql new file mode 100644 index 0000000..2453b76 Binary files /dev/null and b/ii.sql differ diff --git a/iiplc.app b/iiplc.app new file mode 100644 index 0000000..b440aab --- /dev/null +++ b/iiplc.app @@ -0,0 +1,157 @@ +use strict; +use warnings; + +use Plack::Builder; +use Plack::Request; +use Plack::Response; + +use II::Config; +use II::Get; +use II::Send; +use II::Render; +use II::DB; +use II::Enc; + +# Debug +use Data::Dumper; + +my $c = II::Config->new(); +my $config = $c->load(); + +my $GET = II::Get->new($config); +my $render = II::Render->new(); + +my $echo = sub { + my $env = shift; + + my $req = Plack::Request->new($env); + + my $query = $req->param('echo'); + + my $echo_messages = $render->echo_mes($query); + + return [ 200, [ 'Content-type' => 'text/html' ], ["$echo_messages"], ]; +}; + +my $thread = sub { + my $env = shift; + + my $req = Plack::Request->new($env); + + my $subg = $req->param('subg'); + my $echo = $req->param('echo'); + + my $thread = $render->thread( $subg, $echo ); + + return [ 200, [ 'Content-type' => 'text/html' ], ["$thread"], ]; +}; + +my $get = sub { + my $msgs = $GET->get_echo(); + my $new_mes = $render->new_mes($msgs); + return [ 200, [ 'Content-type' => 'text/html' ], ["$new_mes"], ]; +}; + +my $root = sub { + my $index = $render->index($config); + return [ 200, [ 'Content-type' => 'text/html' ], [$index], ]; +}; + +my $me = sub { + my $messages = $render->to_me($config); + return [ 200, [ 'Content-type' => 'text/html' ], [$messages], ]; +}; + +my $tree = sub { + my $subges = $render->tree($config); + return [ 200, [ 'Content-type' => 'text/html' ], ['Дерево'], ]; +}; + +my $new = sub { + my $env = shift; + + my $req = Plack::Request->new($env); + my $echo = $req->param('echo'); + + my $send = $render->send_new($echo); + return [ 200, [ 'Content-type' => 'text/html' ], [$send], ]; +}; + +my $send = sub { + my $env = shift; + + my $req = Plack::Request->new($env); + my $hash = $req->param('hash'); + my $send = $render->send($hash); + + return [ 200, [ 'Content-type' => 'text/html' ], [$send], ]; +}; + +my $enc = sub { + my $env = shift; + + my $req = Plack::Request->new($env); + + # Get parameters + my $echo = $req->param('echo'); + my $to = $req->param('to'); + my $post = $req->param('post'); + my $subg = $req->param('subg'); + my $hash = $req->param('hash'); + my $time = time(); + + print Dumper($config); + my $data = { + echo => $echo, + to => $to, + from => $config->{nick}, + subg => $subg, + post => $post, + time => $time, + hash => $hash, + }; + + my $enc = II::Enc->new( $config, $data ); + $enc->encode() == 0 or die "$!\n"; + + return [ 302, [ 'Location' => '/out' ], [], ]; +}; + +my $out = sub { + my $out = $render->out(); + + return [ 200, [ 'Content-type' => 'text/html' ], [$out], ]; +}; + +# Push message to server +my $push = sub { + my $env = shift; + + my $req = Plack::Request->new($env); + + my $echo = $req->param('echo'); + my $base64 = $req->param('base64'); + my $hash = $req->param('hash'); + + my $s = II::Send->new( $config, $echo, $base64 ); + $s->send($hash); + + my $db = II::DB->new(); + $db->update_out($hash); + + return [ 302, [ 'Location' => "/e?echo=$echo" ], [], ]; +}; + +builder { + mount '/' => $root; + mount '/e' => $echo; + mount '/s' => $thread; + mount '/me' => $me; + mount '/tree' => $tree; + mount '/get/' => $get; + mount '/send' => $send; + mount '/enc' => $enc; + mount '/out' => $out; + mount '/push' => $push; + mount '/new' => $new; +}; diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..0a3677c --- /dev/null +++ b/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Debug server +plackup iiplc.app + +# Production +# starman -l 127.0.0.1:5000 run.pl whatever diff --git a/t/foot.html b/t/foot.html new file mode 100644 index 0000000..691287b --- /dev/null +++ b/t/foot.html @@ -0,0 +1,2 @@ + +