package Bookmarks::C::Main; use strict; use base 'Catalyst::Base'; use Bookmarks::Utils; use File::Slurp; use List::MoreUtils qw(uniq); =head1 NAME Bookmarks::C::Main - Catalyst component =head1 SYNOPSIS See L =head1 DESCRIPTION Catalyst component. =head1 METHODS =over 4 =item default =cut 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,$type)=$link->get_icon(); if ($icon) { $c->res->content_type($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 ) = @_; unless ($self->_authorized($c)) { $c->res->status(403); $c->res->body('non puoi'); return; } my %pre_link=(); for my $field (qw(pk url title descr)) { $pre_link{$field}=$c->req->param($field); } my @tags=split /[ +]/,($c->req->param('tag')||''); my $dblink; if ($pre_link{pk}) { $dblink=Bookmarks::M::DB::Links->retrieve($pre_link{pk}); } else { ($dblink)=Bookmarks::M::DB::Links->search({url=>$pre_link{url}}); } # GET: prepare the form from the URL params if ($c->req->method eq 'GET') { $c->stash->{link}=\%pre_link; $c->stash->{tags}=\@tags; if (defined $dblink) { for my $field (qw(pk 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'); } # POST: accept data and create link+tags 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) { # devo crearlo $dblink=Bookmarks::M::DB::Links->create({}); $dblink->add_date(time()); $dblink->access_count(0); } for my $field (qw(url title descr)) { $dblink->$field($pre_link{$field}); } 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 ) = @_; unless ($self->_authorized($c)) { $c->res->status(403); $c->res->body('non puoi'); return; } 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'; } sub _authorized { my ($self,$c)=@_; if ($ENV{BOOKMARKS_CAN_EDIT}) { return 1; } return; } =head1 AUTHOR A clever guy =head1 LICENSE This library is free software . You can redistribute it and/or modify it under the same terms as perl itself. =cut 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{}, URI->new( $self->{base} . "js/$file.js" )->as_string() ); } return $ret; } 1;