package Bookmarks::C::Main;
use strict;
use base 'Catalyst::Base';
use Bookmarks::Utils;
use File::Slurp;
use List::MoreUtils qw(uniq);
sub auto : Private {
my ( $self, $c ) = @_;
$c->stash->{href}=Bookmarks::C::Main::LinkHelper->new($c);
return 1;
}
sub tags : Global {
my ( $self, $c ) = @_;
$c->stash->{template}='tags';
$c->stash->{tags}=[Bookmarks::M::DB::Tags->get_all_tags_by_name()];
}
sub tag : Regex('^tag/(.*)$') {
my ( $self, $c ) = @_;
my @tagnames=split /\+/,$c->req->snippets->[0];
my ($tagset)=Bookmarks::M::TagSet->retrieve({tags=>[@tagnames]});
if (!defined $tagset) {
$c->stash->{tagnames}=[@tagnames];
$c->stash->{template}='notag';
}
else {
my @links=$tagset->ordered_links();
my @related_tags=$tagset->related_tags();
$c->stash->{tagset}=$tagset;
$c->stash->{links}=[@links];
$c->stash->{related}=[@related_tags];
$c->stash->{template}='links';
}
}
sub icon : Global {
my ( $self, $c ) = @_;
my $link=Bookmarks::M::DB::Links->retrieve($c->req->param('link'));
my $icon=$link->get_icon();
if ($icon) {
$c->res->content_type($link->icon_type());
$c->res->body($icon);
}
else {
$c->res->content_type('image/png');
$c->res->body(scalar read_file($c->config->{root}.'/root.png'));
}
}
sub jump : Global {
my ( $self, $c ) = @_;
my $link=Bookmarks::M::DB::Links->retrieve($c->req->param('link'));
$link->access_count(($link->access_count()||0)+1);
$link->last_access_date(time());
$link->update();
$c->res->status(302);
$c->res->location($link->url());
}
sub add : Global {
my ( $self, $c ) = @_;
my %pre_link=();
for my $field (qw(url title descr)) {
$pre_link{$field}=$c->req->param($field);
}
my @tags=split /[ +]/,($c->req->param('tag')||'');
my ($dblink)=Bookmarks::M::DB::Links->search({url=>$pre_link{url}});
if ($c->req->method eq 'GET') {
$c->stash->{link}=\%pre_link;
$c->stash->{tags}=\@tags;
if (defined $dblink) {
for my $field (qw(url title descr)) {
$c->stash->{link}{$field}||=$dblink->$field();
}
my @dbtags=map { $_->name() } $dblink->tags();
$c->stash->{tags}=[ uniq(@tags,@dbtags) ];
}
$c->stash->{template}='add_form';
$c->stash->{close}=$c->req->param('close');
}
elsif ($c->req->method eq 'POST') {
if (defined $dblink) {
Bookmarks::M::DB::LinksTags->search({
link => $dblink->pk()
})->delete_all();
}
if (defined $dblink and $c->req->param('delete')) {
$dblink->delete();
}
else {
if (!defined $dblink) {
$dblink=Bookmarks::M::DB::Links->create({});
$dblink->add_date(time());
$dblink->access_count(0);
}
$dblink->set(%pre_link);
my ($icon,$type)=Bookmarks::Utils::get_site_icon($pre_link{url});
$dblink->set_icon($icon);
$dblink->icon_type($type);
$dblink->update();
for my $tagname (@tags) {
my $dbtag=Bookmarks::M::DB::Tags->find_or_create({
name => $tagname,
});
Bookmarks::M::DB::LinksTags->find_or_create({
tag => $dbtag->pk(),
link => $dblink->pk(),
});
}
}
Bookmarks::M::DB::Tags->cleanup();
if ($c->req->param('close')) {
$c->stash->{template}='closewin';
}
else {
$c->res->redirect($c->req->base.'tags');
}
}
}
sub edit : Global {
my ( $self, $c ) = @_;
my $link=Bookmarks::M::DB::Links->retrieve($c->req->param('link'));
$c->stash->{link}=$link;
$c->stash->{tags}=[ map {$_->name()} $link->tags() ];
$c->stash->{mode}='edit';
$c->stash->{template}='add_form';
}
sub complete_tag : Global {
my ( $self, $c ) = @_;
my $pretag=$c->req->param('tag');
my @tags=map { $_->name() }
Bookmarks::M::DB::Tags->search_like({name => "${pretag}%"});
$c->res->body($c->prototype->auto_complete_result(\@tags));
}
sub search : Global {
my ( $self, $c ) = @_;
my $query=$c->req->param('q');
my @tags=split /\s+/,$c->req->param('tags');
my @links=Bookmarks::M::DB::Links->search_complex($query,@tags);
$c->stash->{links}=[ @links ];
$c->stash->{template}='results';
}
package Bookmarks::C::Main::LinkHelper;
use YAML;
use URI;
sub new {
my ($class,$c)=@_;
return bless {c=>$c,base=>$c->req->base()},$class;
}
sub stylesheet {
my ($self)=@_;
return URI->new(
$self->{base} . 'style.css'
)->as_string();
}
sub tags {
my ($self)=@_;
return URI->new(
$self->{base} . 'tags'
)->as_string();
}
sub search {
my ($self)=@_;
return URI->new(
$self->{base} . 'search'
)->as_string();
}
sub remove_tag {
my ($self, $tagset, $tag)=@_;
my @tags=grep {$_ ne $tag} $tagset->tags();
return URI->new(
$self->{base} . 'tag/'
. (join '+',map {$_->name()} @tags)
)->as_string();
}
sub add_tag {
my ($self, $tagset, $tag)=@_;
return URI->new(
$self->{base} . 'tag/'
. (join '+',map {$_->name()} ($tagset->tags(),$tag))
)->as_string();
}
sub to_tag {
my ($self, $tag)=@_;
return URI->new(
$self->{base} . 'tag/' . $tag->name()
)->as_string();
}
sub link_icon {
my ($self, $link)=@_;
my $uri=URI->new($self->{base} . 'icon');
$uri->query_form(link=>$link->pk());
return $uri->as_string();
}
sub link {
my ($self, $link)=@_;
my $uri=URI->new($self->{base} . 'jump');
$uri->query_form(link=>$link->pk());
return $uri->as_string();
}
sub edit_link {
my ($self, $link)=@_;
my $uri=URI->new($self->{base} . 'edit');
$uri->query_form(link=>$link->pk());
return $uri->as_string();
}
sub add_action {
my ($self)=@_;
return URI->new(
$self->{base} . 'add'
)->as_string();
}
sub tag_autocomplete {
my ($self)=@_;
return URI->new(
$self->{base} . 'complete_tag'
)->as_string();
}
sub js_library {
my ($self)=@_;
my $ret='';
for my $file (qw(prototype scriptaculous)) {
$ret.=sprintf(q{<script type="text/javascript" src="%s" ></script>},
URI->new(
$self->{base} . "js/$file.js"
)->as_string()
);
}
return $ret;
}
1;