Changeset 20 in bookmarks for trunk


Ignore:
Timestamp:
05/21/13 17:55:34 (11 years ago)
Author:
peter
Message:
  • Bookmarks::get_resources() and Bookmarks::get_cotags() both accept arrayrefs as their tag parameters
  • can now use multiple ?tag query parameters in the request and it will search for the intersection of those tags
  • bkmk list takes 0 or more --tag command line options
  • display a checkbox-based form listing the search tags and available cotags at the below the list of bookmarks
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/BookmarkApp.pm

    r19 r20  
    6969    my $format = $q->param('format') || 'html'; 
    7070    my $tag = $q->param('tag'); 
     71    my @tags = $q->param('tag'); 
     72    # special case: handle the empty tag 
     73    if (@tags == 1 && $tags[0] eq '') { 
     74        @tags = (); 
     75    } 
    7176    my $limit = $q->param('limit'); 
    7277    my $offset = $q->param('offset'); 
    7378    my @resources = $bookmarks->get_resources({ 
    74         tag    => $tag, 
     79        tag    => \@tags, 
    7580        limit  => $limit, 
    7681        offset => $offset, 
    7782    }); 
    7883    my @all_tags = $bookmarks->get_tags({ selected => $tag }); 
    79     my @cotags = $bookmarks->get_cotags({ tag => $tag }); 
     84    my @cotags = $bookmarks->get_cotags({ tag => \@tags }); 
    8085 
    8186    if ($format eq 'json') { 
     
    136141                base_url     => $base_url, 
    137142                selected_tag => $tag, 
    138                 tags         => \@all_tags, 
     143                search_tags  => \@tags, 
     144                all_tags     => \@all_tags, 
    139145                cotags       => \@cotags, 
    140146                resources    => \@resources, 
  • trunk/Bookmarks.pm

    r15 r20  
    5353    my $self = shift; 
    5454    my $params = shift; 
    55     my $tag = $params->{tag}; 
     55    my $tags = $params->{tag} || []; 
    5656    my $limit = $params->{limit}; 
    5757    my $offset = $params->{offset}; 
    5858 
    59     my ($sql, @bind) = sql_interp( 
    60         'select * from resources join bookmarks on resources.uri = bookmarks.uri', 
    61         ($tag   ? ('join tags on resources.uri = tags.uri where tags.tag =', \$tag) : ''), 
    62         'order by ctime desc', 
    63         ($limit ? ('limit', \$limit) : ()), 
    64         # an offset is only allowed if we have a limit clause 
    65         ($limit && $offset ? ('offset', \$offset) : ()), 
    66     ); 
     59    # build the query 
     60    my @sql; 
     61 
     62    if (!ref $tags) { 
     63        $tags = [ $tags ]; 
     64    } 
     65    if (@$tags) { 
     66        my $intersect = 0; 
     67        for my $tag (@{ $tags }) { 
     68            push @sql, 'intersect' if $intersect; 
     69            push @sql, 'select resources.*, bookmarks.* from resources join bookmarks on resources.uri = bookmarks.uri'; 
     70            push @sql, 'join tags on resources.uri = tags.uri where tags.tag =', \$tag; 
     71            $intersect++; 
     72        } 
     73    } else { 
     74        push @sql, 'select * from resources join bookmarks on resources.uri = bookmarks.uri'; 
     75    } 
     76    push @sql, 'order by ctime desc'; 
     77    push @sql, ('limit', \$limit) if $limit; 
     78    # an offset is only allowed if we have a limit clause 
     79    push @sql, ('offset', \$offset) if $limit && $offset; 
     80 
     81    my ($sql, @bind) = sql_interp(@sql); 
    6782 
    6883    my $sth_resource = $self->dbh->prepare($sql); 
     
    95110    my $self = shift; 
    96111    my $params = shift; 
    97     my $tag = $params->{tag}; 
    98     my $sth = $self->dbh->prepare('select tag, count(tag) as count from tags where tag != ? and uri in (select uri from tags where tag = ?) group by tag order by tag'); 
    99     $sth->execute($tag, $tag); 
     112    my $tags = $params->{tag} || []; 
     113    if (!ref $tags) { 
     114        $tags = [ $tags ]; 
     115    } 
     116    my @sql; 
     117 
     118    push @sql, 'select tag, count(tag) as count from tags'; 
     119    if (@$tags) { 
     120        push @sql, 'where uri in ('; 
     121        my $intersect = 0; 
     122        for my $tag (@{ $tags }) { 
     123            push @sql, 'intersect' if $intersect; 
     124            push @sql, 'select uri from tags where tag = ', \$tag; 
     125            $intersect++; 
     126        } 
     127        push @sql, ') and tag not in ', $tags, ''; 
     128    } 
     129    push @sql, 'group by tag order by tag'; 
     130 
     131    my ($sql, @bind) = sql_interp(@sql); 
     132    my $sth = $self->dbh->prepare($sql); 
     133    $sth->execute(@bind); 
    100134    return @{ $sth->fetchall_arrayref({}) }; 
    101135} 
  • trunk/bkmk

    r15 r20  
    88GetOptions( 
    99    'file|f=s' => \my $DBNAME, 
     10    'tag=s' => \my @TAGS, 
    1011); 
    1112 
     
    3233    }, 
    3334    list => sub { 
    34         my @resources = $bookmarks->get_resources(); 
     35        my @resources = $bookmarks->get_resources({ 
     36            tag => \@TAGS 
     37        }); 
    3538        # TODO: list by tags, date, etc. 
    3639        # TODO: coordinate this commandline script with the CGI app 
  • trunk/list.tt

    r16 r20  
    2020} 
    2121ul { 
    22     height: 75%; 
    23     overflow-y: scroll; 
    2422    margin: 0; 
    2523    padding: 0; 
     24} 
     25ul.main { 
     26    height: 60%; 
    2627    border-top: 6px solid #eee; 
    2728    border-bottom: 6px solid #eee; 
     29} 
     30.refine { 
     31    height: 15%; 
     32} 
     33.cotags { 
     34    height: 100%; 
     35    border: 1px dotted #999; 
     36} 
     37ul.main, ul.cotags { 
     38    overflow-y: scroll !important; 
    2839} 
    2940li { 
     
    6273      <select name="tag" onchange="document.forms[0].submit()"> 
    6374        <option value="">All bookmarks</option> 
    64         [% FOREACH tag IN tags %] 
     75        [% FOREACH tag IN all_tags %] 
    6576          <option value="[% tag.tag %]" [% IF tag.selected %]selected="selected"[% END %]>[% tag.tag %] ([% tag.count %])</option> 
    6677        [% END %] 
     
    6879      <input type="submit" value="Go"/> 
    6980    </form> 
    70     <!-- 
    71     <select> 
    72     [% FOREACH tag IN cotags %] 
    73       <option>[% tag.tag %] ([% tag.count %])</option> 
    74     [% END %] 
    75     </select> 
    76     --> 
    77     <ul style=""> 
     81    <ul class="main"> 
    7882      [%  FOREACH resource IN resources %] 
    7983        <li> 
     
    9094      [%  END %] 
    9195    </ul> 
    92     [% IF selected_tag %] 
    93       <p> 
    94         <a href="?tag=[% selected_tag %]">[% selected_tag %] links</a> &middot; 
    95         <a href="feed?tag=[% selected_tag %]" type="application/atom+xml">Atom Feed</a> 
    96       </p> 
    97     [% END %] 
    98     <form method="get" action=""> 
    99       [% IF selected_tag %] 
    100         <input type="hidden" name="tag" value="[% selected_tag %]"/> 
    101       [% END %] 
     96    <form method="get" action="" id="reload"> 
    10297      <div> 
    103         <input type="submit" value="Reload"/> 
     98        [% IF selected_tag %] 
     99          <a href="?tag=[% selected_tag %]">[% selected_tag %] links</a> &middot; 
     100          <a href="feed?tag=[% selected_tag %]" type="application/atom+xml">Atom Feed</a> 
     101          <input type="hidden" name="tag" value="[% selected_tag %]"/> 
     102        [% END %] 
     103        <input type="submit" value="Reload"/> 
    104104      </div> 
    105105    </form> 
     106    <div class="refine"> 
     107      <form method="get" action=""> 
     108        <div class="taglists"> 
     109          <ul class="searchtags"> 
     110            [% FOREACH tag IN search_tags %] 
     111              <li> 
     112                <label> 
     113                  <input type="checkbox" name="tag" value="[% tag %]" checked="checked"/> 
     114                  [% tag %] 
     115                </label> 
     116              </li> 
     117            [% END %] 
     118          </ul> 
     119          [% IF cotags.size %] 
     120            <ul class="cotags"> 
     121              [% FOREACH tag IN cotags %] 
     122                <li> 
     123                  <label> 
     124                    <input type="checkbox" name="tag" value="[% tag.tag %]"/> 
     125                    [% tag.tag %] ([% tag.count %]) 
     126                  </label> 
     127                </li> 
     128              [% END %] 
     129            </ul> 
     130          [% END %] 
     131        </div> 
     132        <div> 
     133          <input type="submit" value="Refine"/> 
     134        </div> 
     135      </form> 
     136    </div> 
    106137  </body> 
    107138</html> 
Note: See TracChangeset for help on using the changeset viewer.