source: bookmarks/trunk/bin/bkmk

Last change on this file was 128, checked in by peter, 7 years ago

bkmk list accepts and searches a text query.

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