source: bookmarks/trunk/bin/bkmk @ 124

Last change on this file since 124 was 124, checked in by peter, 9 years ago

The 'bkmk' script defaults to 'bookmarks.db' for database name.

  • Property svn:executable set to *
File size: 4.2 KB
Line 
1#!/usr/bin/perl -w
2use strict;
3
4use FindBin;
5use lib "$FindBin::RealBin/../lib";
6
7use YAML;
8use Getopt::Long qw{GetOptions GetOptionsFromArray :config pass_through};
9
10use Bookmarks;
11
12GetOptions(
13    'file|f=s' => \my $DBNAME,
14);
15
16my $dbname = $DBNAME || $ENV{BKMK_DBNAME} || 'bookmarks.db';
17die "Usage: $0 --file <dbname> <command>\n" unless $dbname;
18
19my $bookmarks = Bookmarks->new({
20        dbname => $dbname,
21    });
22
23my $command = shift;
24
25my %action_for = (
26    init => sub {
27        my $src_file = shift;
28        $bookmarks->create_tables;
29        load_bookmarks($src_file) if $src_file;
30    },
31
32    get => sub {
33        my $identifier = shift;
34        my $bookmark = find_bookmark($identifier);
35        print $bookmark ? Dump($bookmark->to_hashref) : "Not Found\n";
36    },
37
38    add => sub {
39        GetOptionsFromArray(
40            \@_,
41            'title=s' => \my $TITLE,
42        );
43        my ($uri, @tags) = @_;
44        my $title = defined $TITLE ? $TITLE : fetch_title($uri);
45        my $bookmark = $bookmarks->add({ uri => $uri, title => $title, tags => \@tags });
46        print Dump($bookmark->to_hashref);
47    },
48
49    list => sub {
50        my @tags = @_;
51        my $resources = $bookmarks->search({
52                tags => \@tags
53            });
54        # TODO: list by tags, date, etc.
55        # TODO: coordinate this commandline script with the CGI app
56        print Dump([ map { $_->to_hashref } @{ $resources->results } ]);
57    },
58
59    tag => sub {
60        my ($identifier, @tags) = @_;
61        my $bookmark = find_bookmark($identifier);
62        if ($bookmark) {
63            $bookmark->tags(\@tags);
64            $bookmarks->update($bookmark);
65            print Dump($bookmark->to_hashref);
66        } else {
67            die "Not found\n";
68        }
69    },
70
71    # interactive editing of a bookmark
72    edit => sub {
73        my ($identifier) = @_;
74        my $bookmark = find_bookmark($identifier) or die "Not found\n";
75        my $editor = $ENV{VISUAL} || $ENV{EDITOR} || 'vi';
76       
77        # create a temp file and open it in the user's preferred editor
78        use File::Temp qw{tempfile};
79        my ($fh, $filename) = tempfile(UNLINK => 1);
80        YAML::DumpFile($filename, $bookmark->to_hashref);
81        system($editor, $filename);
82
83        # abort on empty file
84        die "Edit canceled\n" unless -s $filename;
85
86        # update and save the bookmark
87        $bookmark = Bookmark->new(YAML::LoadFile($filename));
88        $bookmarks->update($bookmark);
89        print Dump($bookmark->to_hashref);
90    },
91
92    # bulk loading
93    load => sub {
94        my ($src_file) = @_;
95        load_bookmarks($src_file);
96    },
97
98    # bulk dumping
99    dump => sub {
100        my ($dump_file) = @_;
101        my $dump = [ map { $_->to_hashref } @{ $bookmarks->search->results } ];
102        $dump_file ? YAML::DumpFile($dump_file, $dump) : print Dump($dump);
103    },
104
105    # scanning for current status
106    scan => sub {
107        GetOptionsFromArray(
108            \@_,
109            'csv'       => \my $CSV,
110            'timeout=i' => \my $TIMEOUT,
111        );
112
113        require LWP::UserAgent;
114        require Text::CSV;
115
116        $TIMEOUT ||= 10;
117
118        my $ua = LWP::UserAgent->new;
119        $ua->timeout($TIMEOUT);
120
121        my $csv = Text::CSV->new;
122
123        for my $bookmark (@{ $bookmarks->search->results }) {
124            printf "%3d %s\n", $bookmark->id, $bookmark->uri unless $CSV;
125            my $response = $ua->head($bookmark->uri);
126            printf "   -> %s\n", $response->status_line unless $CSV;
127            $csv->combine(
128                $bookmark->id,
129                $bookmark->uri,
130                $response->code,
131                $response->message,
132            );
133            print $csv->string . "\n" if $CSV;
134        }
135    },
136);
137
138$action_for{$command}->(@ARGV);
139
140sub find_bookmark {
141    my $identifier = shift;
142    my $query = $identifier =~ /^\d+$/ ? { id => $identifier } : { uri => $identifier };
143    return $bookmarks->get_bookmark($query);
144}
145
146sub fetch_title {
147    my $uri = shift;
148    require WWW::Mechanize;
149    my $mech = WWW::Mechanize->new;
150    $mech->get($uri);
151    return $mech->title || $uri;
152}
153
154sub load_bookmarks {
155    my $src_file = shift;
156    my $src_bookmarks = YAML::LoadFile($src_file);
157    for my $bookmark (@{ $src_bookmarks }) {
158        $bookmarks->add($bookmark);
159    }
160}
Note: See TracBrowser for help on using the repository browser.