diff options
author | dakkar <dakkar@luxion> | 2005-11-09 17:14:54 +0000 |
---|---|---|
committer | dakkar <dakkar@luxion> | 2005-11-09 17:14:54 +0000 |
commit | 27cff350e9e5fb832185bc14dee35b5b8f942a81 (patch) | |
tree | e89f9b5d457b711cce6d908ef0b33792cab20e75 | |
parent | ora il BookmarksManager gestisce per bene i tag multipli, e i template sono f... (diff) | |
download | Bookmarks-27cff350e9e5fb832185bc14dee35b5b8f942a81.tar.gz Bookmarks-27cff350e9e5fb832185bc14dee35b5b8f942a81.tar.bz2 Bookmarks-27cff350e9e5fb832185bc14dee35b5b8f942a81.zip |
* passati i template a HTML4, altrimenti l'autocompletamento non va
* aggiunto autocompletamento per i nomi di tag
* migliorato il caricatore da YAML
* aggiunto un convertitore XBEL -> YAML
* aggiunto campo 'tipo icona'
* aggiunta funzionalità di edit e delete di link
* dopo ogni update di un link, i tag non più riferiti vengono cancellati
* migliorato il recupero favicon, con tipo
-rw-r--r-- | lib/Bookmarks.pm | 1 | ||||
-rw-r--r-- | lib/Bookmarks/C/Main.pm | 92 | ||||
-rw-r--r-- | lib/Bookmarks/M/DB/Tags.pm | 14 | ||||
-rw-r--r-- | lib/Bookmarks/Utils.pm | 16 | ||||
-rw-r--r-- | lib/Bookmarks/V/TT.pm | 12 | ||||
-rw-r--r-- | root/add_form | 13 | ||||
-rw-r--r-- | root/links | 6 | ||||
-rw-r--r-- | root/tags | 3 | ||||
-rwxr-xr-x | script/bookmarks_load.pl | 14 | ||||
-rw-r--r-- | script/bookmarks_makedb.pl | 1 | ||||
-rw-r--r-- | script/check_icons.pl | 39 | ||||
-rw-r--r-- | script/xbel2yaml.pl | 77 |
12 files changed, 234 insertions, 54 deletions
diff --git a/lib/Bookmarks.pm b/lib/Bookmarks.pm index fb88958..810a64f 100644 --- a/lib/Bookmarks.pm +++ b/lib/Bookmarks.pm @@ -2,6 +2,7 @@ package Bookmarks; use strict; use Catalyst qw/-Debug Prototype DefaultEnd/; +use HTML::Element; our $VERSION = '0.01'; diff --git a/lib/Bookmarks/C/Main.pm b/lib/Bookmarks/C/Main.pm index b6170c0..d4c5a66 100644 --- a/lib/Bookmarks/C/Main.pm +++ b/lib/Bookmarks/C/Main.pm @@ -61,7 +61,7 @@ sub icon : Global { my $link=Bookmarks::M::DB::Links->retrieve($c->req->param('link')); my $icon=$link->get_icon(); if ($icon) { - $c->res->content_type('image/x-icon'); + $c->res->content_type($link->icon_type()); $c->res->body($icon); } else { @@ -100,31 +100,41 @@ sub add : Global { # POST: accept data and create link+tags elsif ($c->req->method eq 'POST') { my ($dblink)=Bookmarks::M::DB::Links->search({url=>$pre_link{url}}); - if (!defined $dblink) { # devo crearlo - $dblink=Bookmarks::M::DB::Links->create({}); - $dblink->add_date(time()); - $dblink->access_count(0); + + if (defined $dblink) { + Bookmarks::M::DB::LinksTags->search({ + link => $dblink->pk() + })->delete_all(); + } + + if (defined $dblink and $c->req->param('delete')) { + $dblink->delete(); } - $dblink->set(%pre_link); - $dblink->set_icon(Bookmarks::Utils::get_site_icon($pre_link{url})); - $dblink->update(); - - # tags - Bookmarks::M::DB::LinksTags->search({ - link => $dblink->pk() - })->delete_all(); - - 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(), - }); + else { + if (!defined $dblink) { # devo crearlo + $dblink=Bookmarks::M::DB::Links->create({}); + $dblink->add_date(time()); + $dblink->access_count(0); + } + + $dblink->set(%pre_link); + $dblink->set_icon(Bookmarks::Utils::get_site_icon($pre_link{url})); + $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'; } @@ -134,6 +144,28 @@ sub add : Global { } } +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)); +} + =back @@ -202,6 +234,13 @@ sub link { 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( @@ -209,4 +248,11 @@ sub add_action { )->as_string(); } +sub tag_autocomplete { + my ($self)=@_; + return URI->new( + $self->{base} . 'complete_tag' + )->as_string(); +} + 1; diff --git a/lib/Bookmarks/M/DB/Tags.pm b/lib/Bookmarks/M/DB/Tags.pm index 3686a7d..cc675f7 100644 --- a/lib/Bookmarks/M/DB/Tags.pm +++ b/lib/Bookmarks/M/DB/Tags.pm @@ -22,7 +22,7 @@ GROUP BY links_tags.tag ORDER BY how_many DESC END_SQL -__PACKAGE__->columns(TEMP=> 'how_wany'); +__PACKAGE__->columns(TEMP=> 'how_many'); sub count_links { my ($self)=@_; @@ -52,6 +52,18 @@ sub ordered_links { return sort links_sorter @links; } +sub cleanup { + my ($class)=@_; + + my @tag_list=reverse $class->search_popularity(); + + while ($tag_list[0]->how_many() == 0) { + (shift @tag_list)->delete(); + } + + return; +} + =head1 NAME Bookmarks::M::DB::Tags - CDBI Model Component Table Class diff --git a/lib/Bookmarks/Utils.pm b/lib/Bookmarks/Utils.pm index fd0b68d..a876340 100644 --- a/lib/Bookmarks/Utils.pm +++ b/lib/Bookmarks/Utils.pm @@ -1,15 +1,17 @@ package Bookmarks::Utils; use strict; use warnings; -use LWP::Simple; +use LWP::UserAgent; use URI::URL; +my $ua=LWP::UserAgent->new(); + sub check_link { my ($url)=@_; return 1 if $url!~/^http:/; #my ($type,$length,$update,$expires,$server)=head($url); #return defined $type; - return scalar head($url); + return $ua->head($url)->is_success(); } sub get_site_icon { @@ -38,8 +40,14 @@ sub get_site_icon { print "Trovato: '$favicon'"; $favicon=URI::URL->new($favicon,$url)->abs->canonical->as_string; print ", ovvero '$favicon'\n"; - my $icon=get($favicon); - return $icon; + my $res=$ua->get($favicon); + + if ($res->is_success()) { + return ($res->decoded_content(),$res->header('Content-type')); + } + else { + return; + } } 1; diff --git a/lib/Bookmarks/V/TT.pm b/lib/Bookmarks/V/TT.pm index f2f8e7d..d2063b6 100644 --- a/lib/Bookmarks/V/TT.pm +++ b/lib/Bookmarks/V/TT.pm @@ -3,18 +3,6 @@ package Bookmarks::V::TT; use strict; use base 'Catalyst::View::TT'; -sub process { - my ( $self, $c ) = @_; - my $ret=$self->NEXT::process($c); - if ($ret==1 - and $c->res->content_type =~ m{text/html}) { - my $ct=$c->res->content_type; - $ct=~s{text/html}{application/xhtml+xml}; - $c->res->content_type($ct); - } - return $ret; -} - =head1 NAME Bookmarks::V::TT - TT View Component diff --git a/root/add_form b/root/add_form index 10e83bb..ce0d181 100644 --- a/root/add_form +++ b/root/add_form @@ -1,15 +1,18 @@ -<?xml version="1.0" encoding="utf-8"?> -<html xmlns="http://www.w3.org/1999/xhtml"> +<html> <head> -<title>add</title> +<title>[% IF mode=='edit'; 'Edit link'; ELSE; 'Add link'; END %]</title> +[% c.prototype.auto_complete_stylesheet() %] +[% c.prototype.define_javascript_functions() %] </head> <body> <form action="[% href.add_action() %]" method="post"> <p>Link: <input name="url" type="text" value="[% link.url %]" /></p> <p>Title: <input name="title" type="text" value="[% link.title %]" /></p> <p>Description: <input name="descr" type="text" value="[% link.descr %]" /></p> -<p>Tags: <input name="tag" type="text" value="[% tags.join(' ') %]" /></p> -<input type="submit" /> +<p>Tags: <input autocomplete="off" id="tag_field" name="tag" type="text" value="[% tags.join(' ') %]" /></p> +<div id="tag_field_auto_complete" class="auto_complete"></div> +<script type="text/javascript">new Ajax.Autocompleter('tag_field', 'tag_field_auto_complete', '[% href.tag_autocomplete() %]', { tokens: ' ' })</script> +<input type="submit" name="add" value="Submit" /> [% IF mode=='edit' %]<input type="submit" name="delete" value="Delete" />[% END %] </form> </body> </html>
\ No newline at end of file @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<html xmlns="http://www.w3.org/1999/xhtml"> +<html> <head> <title> Links for @@ -51,6 +50,9 @@ <span class="link title"> <a href="[% href.link(link) %]">»[% link.title %]«</a> </span> + <span class="link edit"> + <a href="[% href.edit_link(link) %]">edit</a> + </span> <ul> [% FOR rtag IN link.tags %] <li> @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<html xmlns="http://www.w3.org/1999/xhtml"> +<html> <head> <title>tags</title> </head> diff --git a/script/bookmarks_load.pl b/script/bookmarks_load.pl index 7b16fa1..6433f24 100755 --- a/script/bookmarks_load.pl +++ b/script/bookmarks_load.pl @@ -30,16 +30,20 @@ for my $link (@$links) { my $dblink=Bookmarks::M::DB::Links->find_or_create({ url => $link->{href}, }); - if (!Bookmarks::Utils::check_link($link->{href})) { - warn "Link $link->{href} non valido, marco come tale\n"; - $link->{description}.=' [INVALID]'; - } + if (!Bookmarks::Utils::check_link($link->{href})) { + warn "Link $link->{href} non valido, marco come tale\n"; + $link->{description}.=' [INVALID]'; + } + else { + my ($icon,$type)=Bookmarks::Utils::get_site_icon($link->{href}); + $dblink->set_icon($icon); + $dblink->icon_type($type); + } $link->{created}||=time(); $link->{modified}||=time(); while (my ($f1,$f2) = each %fields) { $dblink->$f2($link->{$f1}); } - $dblink->set_icon(Bookmarks::Utils::get_site_icon($link->{href})); $dblink->update(); Bookmarks::M::DB::LinksTags->search({link => $dblink->pk()})->delete_all(); diff --git a/script/bookmarks_makedb.pl b/script/bookmarks_makedb.pl index 7b3ee1c..991cdd6 100644 --- a/script/bookmarks_makedb.pl +++ b/script/bookmarks_makedb.pl @@ -28,6 +28,7 @@ create table links ( title text, descr text, icon text, + icon_type text, add_date integer, last_access_date integer, access_count integer diff --git a/script/check_icons.pl b/script/check_icons.pl new file mode 100644 index 0000000..2afdc7d --- /dev/null +++ b/script/check_icons.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl +use strict; +use warnings; +use FindBin; +use DBI; +use MIME::Base64; +use File::MMagic; +use Path::Class; + +my $DBHOME=dir($FindBin::Bin)->parent->file('bookmarks.db'); +my $db=DBI->connect("dbi:SQLite:$DBHOME"); + +my $magic=File::MMagic->new(); + +my $sth=$db->prepare('select pk,icon from links'); +$sth->execute(); +my ($pk,$icon,$type); +my @to_clean=();my %to_update; +while (($pk,$icon)=$sth->fetchrow_array()) { + $icon=decode_base64($icon); + $type=$magic->checktype_contents($icon); + if ($type =~ /^text/) { + push @to_clean,$pk; + } + else { + $to_update{$pk}=$type; + } +} + +$sth=$db->prepare(q{update links set icon='' where pk=?}); +for $pk (@to_clean) { + $sth->execute($pk); +} +$sth=$db->prepare(q{update links set icon_type=? where pk=?}); +while (($pk,$type)=each %to_update) { + $sth->execute($type,$pk); +} + +$db->disconnect; diff --git a/script/xbel2yaml.pl b/script/xbel2yaml.pl new file mode 100644 index 0000000..6cfb186 --- /dev/null +++ b/script/xbel2yaml.pl @@ -0,0 +1,77 @@ +#!/usr/bin/perl +use XML::SAX::ParserFactory; +use YAML; + +my $handler=XBEL::Handler->new(); +my $parser=XML::SAX::ParserFactory->parser(Handler=>$handler); +$parser->parse_uri($ARGV[0]); + +print Dump($handler->bookmarks()); + +package XBEL::Handler; +use base 'XML::SAX::Base'; +use Date::Parse; + +sub new { + my ($class)=@_; + return bless +{ + bookmarks=>[], + status=>'out', + tags=>[], + },$class; +} + +sub start_element { + my ($self,$el)=@_; + + if ($el->{LocalName} eq 'folder') { + $self->{status}='folder'; + push @{$self->{tags}},''; + } + elsif ($el->{LocalName} eq 'bookmark') { + $self->{status}='mark'; + my $mark={}; + $mark->{href}=$el->{Attributes}{'{}href'}{Value}; + $mark->{created}=convert_date($el->{Attributes}{'{}added'}{Value}); + $mark->{modified}=convert_date($el->{Attributes}{'{}modified'}{Value}); + $mark->{tags}=[@{$self->{tags}}]; # force a copy + push @{$self->{bookmarks}},$mark; + } + elsif ($el->{LocalName} eq 'title' and $self->{status} eq 'folder') { + $self->{status}='folder-title'; + } + elsif ($el->{LocalName} eq 'title' and $self->{status} eq 'mark') { + $self->{status}='mark-title'; + } +} + +sub end_element { + my ($self,$el)=@_; + + if ($el->{LocalName} eq 'folder') { + pop @{$self->{tags}}; + } + $self->{status}=''; +} + +sub characters { + my ($self,$data)=@_; + + if ($self->{status} eq 'mark-title') { + $self->{bookmarks}[-1]{description}.=$data->{Data}; + } + elsif ($self->{status} eq 'folder-title') { + $self->{tags}[-1].=$data->{Data}; + } +} + +sub convert_date { + return str2time($_[0]); +} + +sub bookmarks { + my ($self)=@_; + return $self->{bookmarks}; +} + +1; |