[Slim-Checkins] r8758 - in /trunk/server: ./ HTML/EN/ SQL/mysql/
Slim/ Slim/Control/
Slim/Schema/ Slim/Schema/ResultSet/ Slim/Utils/ Slim/Web/Pages/
dsully at svn.slimdevices.com
dsully at svn.slimdevices.com
Tue Aug 1 13:45:58 PDT 2006
Author: dsully
Date: Tue Aug 1 13:45:38 2006
New Revision: 8758
URL: http://svn.slimdevices.com?rev=8758&view=rev
Log:
Bug: 3793
Description: Refactor Web Searching (part 1):
* Add searchRef type so that the same search can be performed again.
Use in place of listRef, so we don't keep a large list of objects in memory.
* Fix All Songs links when searching to search a searchRef or *.namesearch
* Move searchStringSplit() into Slim::Utils::Text
* Move as much common code as possible into Web::Search()
* Turn on comment & lyrics search. These columns need to be TEXT in the DB to
allow for case insensitive searching.
* Further TODO (perhaps post 6.5) - the loop in ::Search and ::BrowseDB are very similar.
Modified:
trunk/server/Changelog6.html
trunk/server/HTML/EN/advanced_search.html
trunk/server/HTML/EN/search.html
trunk/server/SQL/mysql/schema_1_up.sql
trunk/server/Slim/Control/Commands.pm
trunk/server/Slim/Schema.pm
trunk/server/Slim/Schema/ResultSet/Album.pm
trunk/server/Slim/Schema/ResultSet/Base.pm
trunk/server/Slim/Schema/ResultSet/Contributor.pm
trunk/server/Slim/Schema/ResultSet/Genre.pm
trunk/server/Slim/Schema/ResultSet/Track.pm
trunk/server/Slim/Schema/Track.pm
trunk/server/Slim/Utils/Text.pm
trunk/server/Slim/Web/Pages/BrowseDB.pm
trunk/server/Slim/Web/Pages/LiveSearch.pm
trunk/server/Slim/Web/Pages/Search.pm
Modified: trunk/server/Changelog6.html
URL: http://svn.slimdevices.com/trunk/server/Changelog6.html?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Changelog6.html (original)
+++ trunk/server/Changelog6.html Tue Aug 1 13:45:38 2006
@@ -436,6 +436,7 @@
<li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3776">#3776</a> - Dublicate breadcumb links in browse Years</li>
<li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3780">#3780</a> - Artist links lead to all tracks in library</li>
<li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3786">#3786</a> - Browse Genre contains ARRAY(0xnnnnnnn) entries</li>
+ <li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3793">#3793</a> - Can't play "All Songs" from search result page</li>
<li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3800">#3800</a> - Multi-Discs albums will not show correcty in web interface</li>
<li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3801">#3801</a> - Playing a song from a saved playlist will play the whole list</li>
<li><a href="http://bugs.slimdevices.com/show_bug.cgi?id=3803">#3803</a> - changing 'Maintain Client Playlists' setting crashes server</li>
Modified: trunk/server/HTML/EN/advanced_search.html
URL: http://svn.slimdevices.com/trunk/server/HTML/EN/advanced_search.html?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/HTML/EN/advanced_search.html (original)
+++ trunk/server/HTML/EN/advanced_search.html Tue Aug 1 13:45:38 2006
@@ -138,23 +138,20 @@
<input name="search.filesize" value="[% search.filesize.value %]" size="12" maxlength="12" style="text-align: right;" type="text">
[% "BYTES" | string %]
[% END %]
-<!--
- Not yet.
<tr>
<td class="content" align="right" nowrap="nowrap" valign="middle" width="25%">[% "COMMENT" | string %] </td>
<td class="content" align="left" valign="middle" width="75%">
- <input name="search.comments" value="" size="[% size %]" maxlength="1000" type="text">
+ <input name="search.comments.value" value="" size="[% size %]" maxlength="1000" type="text">
</td>
</tr>
<tr>
- <td class="content" align="right" nowrap="nowrap" valign="middle" width="25%">Lyrics</td>
+ <td class="content" align="right" nowrap="nowrap" valign="middle" width="25%">[% "LYRICS" | string %] </td>
<td class="content" align="left" valign="middle" width="75%">
- <input name="search.lyrics" value="" size="[% size %]" maxlength="1000" type="text">
+ <input name="search.lyrics" value="[% search.lyrics.value %]" size="[% size %]" maxlength="1000" type="text">
</td>
</tr>
--->
<tr>
<td> </td>
@@ -178,23 +175,17 @@
</div>
<div id="browsedbList">
- [% IF numresults != '-1' && numresults != '0' %]
- <div class="even">
- <div class="browsedbListItem">
- [% "ALL_SONGS" | string %]
- <div class="browsedbControls">
- [% WRAPPER playlink %]href="[% webroot %][% statusroot %]?player=[% playerURI %]&command=playlist&subcommand=playtracks&listref=searchResults"[% END %]
- [% WRAPPER addlink %]href="[% webroot %][% statusroot %]?player=[% playerURI %]&command=playlist&subcommand=addtracks&listref=searchResults"[% END %]
- </div>
- </div>
- </div>
- [% ELSIF numresults == '0' %]
- [% "EMPTY" | string%]
- [% END %]
- [% IF browse_items %]
+
+ [% IF browse_items.size %]
+
[% FOREACH item = browse_items %]
[% PROCESS browsedbitems_list.html %]
[% END %]
+
+ [% ELSE %]
+
+ [% "NO_SEARCH_RESULTS" | string %]
+
[% END %]
</div>
Modified: trunk/server/HTML/EN/search.html
URL: http://svn.slimdevices.com/trunk/server/HTML/EN/search.html?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/HTML/EN/search.html (original)
+++ trunk/server/HTML/EN/search.html Tue Aug 1 13:45:38 2006
@@ -6,53 +6,44 @@
[% PROCESS pageheader.html %]
<script type="text/javascript" src="/html/prototype.js"></script>
- [% IF liveSearch %]
+[% IF liveSearch %]
<form id="searchForm" name="searchForm" method="GET" action="search.html">
<input type="text" id="query" name="query" size="40" autocomplete="off" />
- [% ELSE %]
+[% ELSE %]
<form id="searchForm" name="searchForm" method="GET" action="search.html">
<input type="text" id="query" name="query" size="40" value="[% query %]"/>
- [% END %]
+[% END %]
<input name="submit" type=submit class="stdclick" value="[% "SEARCH" | string %]"><p>
<input type="hidden" value="1" name="manualSearch">
<input type="hidden" value="[% player %]" name="player">
</form>
- <div id="search-results"></div>
+<div id="search-results"></div>
- <div id="browsedbHeader">
- [% IF searchError %]
- [% searchError %]
+<div id="browsedbHeader">
+ [% IF searchError %]
+ [% searchError %]
+ [% END %]
+ [% IF pageinfo.totalpages && pageinfo.totalpages > 1 %][% PROCESS pagebar %][% END %]
+</div>
+
+<div id="browsedbList">
+
+ [% IF browse_items.size %]
+
+ [% FOREACH item = browse_items %]
+ [% PROCESS browsedbitems_list.html %]
[% END %]
- [% IF pageinfo.totalpages > 1 %][% PROCESS pagebar %][% END %]
- </div>
- <div id="browsedbList">
- [% IF numresults != '-1' && numresults != '0' %]
- <div class="even">
- <div class="browsedbListItem">
- [% "ALL_SONGS" | string %]
- <div class="browsedbControls">
- [% WRAPPER playlink %]href="[% webroot %][% statusroot %]?player=[% playerURI %]&command=playlist&subcommand=playtracks&listref=searchResults"[% END %]
- [% WRAPPER addlink %]href="[% webroot %][% statusroot %]?player=[% playerURI %]&command=playlist&subcommand=addtracks&listref=searchResults"[% END %]
- </div>
- </div>
- </div>
- [% ELSIF numresults == '0' %]
- [% "NO_SEARCH_RESULTS" | string%]
- [% END %]
- [% IF browse_items %]
- [% FOREACH item = browse_items %]
- [% PROCESS browsedbitems_list.html %]
- [% END %]
- [% END %]
- </div>
-[% IF pageinfo.totalpages > 1 %][% PROCESS pagebar %][% END %]
+ [% END %]
+</div>
+
+[% IF pageinfo.totalpages && pageinfo.totalpages > 1 %][% PROCESS pagebar %][% END %]
[% IF liveSearch; INCLUDE "search-observer.html"; END %]
Modified: trunk/server/SQL/mysql/schema_1_up.sql
URL: http://svn.slimdevices.com/trunk/server/SQL/mysql/schema_1_up.sql?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/SQL/mysql/schema_1_up.sql (original)
+++ trunk/server/SQL/mysql/schema_1_up.sql Tue Aug 1 13:45:38 2006
@@ -78,7 +78,7 @@
audio bool,
remote bool,
lossless bool,
- lyrics blob,
+ lyrics text, -- needs to be text so that searches are case insensitive.
moodlogic_id int(10) unsigned,
moodlogic_mixable bool,
musicbrainz_id varchar(40), -- musicbrainz uuid (36 bytes of text)
@@ -250,7 +250,7 @@
CREATE TABLE comments (
id int(10) unsigned NOT NULL auto_increment,
track int(10) unsigned,
- value blob,
+ value text, -- needs to be text so that searches are case insensitive.
PRIMARY KEY (id),
INDEX trackIndex (track),
FOREIGN KEY (`track`) REFERENCES `tracks` (`id`) ON DELETE CASCADE
Modified: trunk/server/Slim/Control/Commands.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Control/Commands.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Control/Commands.pm (original)
+++ trunk/server/Slim/Control/Commands.pm Tue Aug 1 13:45:38 2006
@@ -1002,9 +1002,16 @@
# parse the param
my @tracks = ();
- if ($what =~ /listref/i) {
+ if ($what =~ /listRef/i) {
+
@tracks = _playlistXtracksCommand_parseListRef($client, $what, $listref);
+
+ } elsif ($what =~ /searchRef/i) {
+
+ @tracks = _playlistXtracksCommand_parseSearchRef($client, $what, $listref);
+
} else {
+
@tracks = _playlistXtracksCommand_parseSearchTerms($client, $what);
}
@@ -2109,7 +2116,14 @@
} else {
- $find{$key} = Slim::Utils::Text::ignoreCaseArticles($value);
+ if ($key =~ /\.(?:name|title)search$/) {
+
+ $find{$key} = { 'like' => Slim::Utils::Text::searchStringSplit($value) };
+
+ } else {
+
+ $find{$key} = Slim::Utils::Text::ignoreCaseArticles($value);
+ }
}
}
@@ -2175,6 +2189,28 @@
}
}
+sub _playlistXtracksCommand_parseSearchRef {
+ my $client = shift;
+ my $term = shift;
+ my $searchRef = shift;
+
+ $d_commands && msg("Commands::_playlistXtracksCommand_parseSearchRef()\n");
+
+ if ($term =~ /searchRef=(\w+)&?/i) {
+ $searchRef = $client->param($1);
+ }
+
+ my $cond = $searchRef->{'cond'} || {};
+ my $attr = $searchRef->{'attr'} || {};
+
+ # XXX - For some reason, the join key isn't passed along with the ref.
+ # Perl bug because 'join' is a keyword?
+ if (!$attr->{'join'} && $attr->{'joins'}) {
+ $attr->{'join'} = delete $attr->{'joins'};
+ }
+
+ return Slim::Schema->rs('Track')->search($cond, $attr)->distinct->all;
+}
sub _showCommand_done {
my $args = shift;
Modified: trunk/server/Slim/Schema.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema.pm (original)
+++ trunk/server/Slim/Schema.pm Tue Aug 1 13:45:38 2006
@@ -302,6 +302,13 @@
return $object;
}
+# Return the common searchable types.
+sub searchTypes {
+ my $class = shift;
+
+ return qw(contributor album track);
+}
+
sub lastRescanTime {
my $class = shift;
@@ -1691,9 +1698,6 @@
} else {
- # Check if the album name is one of the "common album names"
- # we've identified in prefs. If so, we require a match on
- # both album name and primary artist name.
if (blessed($contributor)) {
$search->{'contributor'} = $contributor->id;
}
Modified: trunk/server/Slim/Schema/ResultSet/Album.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/ResultSet/Album.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema/ResultSet/Album.pm (original)
+++ trunk/server/Slim/Schema/ResultSet/Album.pm Tue Aug 1 13:45:38 2006
@@ -52,13 +52,21 @@
return 1;
}
+sub searchColumn {
+ my $self = shift;
+
+ return 'titlesearch';
+}
+
sub searchNames {
- my ($self, $terms) = @_;
+ my $self = shift;
+ my $terms = shift;
+ my $attrs = shift || {};
- return $self->search(
- { 'me.titlesearch' => { 'like' => $terms } },
- { 'order_by' => 'me.titlesort, me.disc', 'distinct' => 'me.id' }
- );
+ $attrs->{'order_by'} ||= 'me.titlesort, me.disc';
+ $attrs->{'distinct'} ||= 'me.id';
+
+ return $self->search({ 'me.titlesearch' => { 'like' => $terms } }, $attrs);
}
sub browse {
Modified: trunk/server/Slim/Schema/ResultSet/Base.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/ResultSet/Base.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema/ResultSet/Base.pm (original)
+++ trunk/server/Slim/Schema/ResultSet/Base.pm Tue Aug 1 13:45:38 2006
@@ -15,6 +15,7 @@
sub descendTransform { '' }
sub browseBodyTemplate { '' }
sub orderBy { '' }
+sub searchColumn { 'id' }
sub pageBarResults { 0 }
sub alphaPageBar { 0 }
sub ignoreArticles { 0 }
Modified: trunk/server/Slim/Schema/ResultSet/Contributor.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/ResultSet/Contributor.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema/ResultSet/Contributor.pm (original)
+++ trunk/server/Slim/Schema/ResultSet/Contributor.pm Tue Aug 1 13:45:38 2006
@@ -36,8 +36,16 @@
sub alphaPageBar { 1 }
sub ignoreArticles { 1 }
+sub searchColumn {
+ my $self = shift;
+
+ return 'namesearch';
+}
+
sub searchNames {
- my ($self, $terms) = @_;
+ my $self = shift;
+ my $terms = shift;
+ my $attrs = shift || {};
my @joins = ();
my $cond = {
@@ -51,11 +59,11 @@
push @joins, 'contributorAlbums';
}
- return $self->search($cond, {
- 'order_by' => 'me.namesort',
- 'distinct' => 'me.id',
- 'join' => \@joins,
- });
+ $attrs->{'order_by'} ||= 'me.namesort';
+ $attrs->{'distinct'} ||= 'me.id';
+ $attrs->{'join'} ||= \@joins;
+
+ return $self->search($cond, $attrs);
}
sub browse {
Modified: trunk/server/Slim/Schema/ResultSet/Genre.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/ResultSet/Genre.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema/ResultSet/Genre.pm (original)
+++ trunk/server/Slim/Schema/ResultSet/Genre.pm Tue Aug 1 13:45:38 2006
@@ -35,13 +35,21 @@
sub alphaPageBar { 1 }
+sub searchColumn {
+ my $self = shift;
+
+ return 'namesearch';
+}
+
sub searchNames {
- my ($self, $terms) = @_;
+ my $self = shift;
+ my $terms = shift;
+ my $attrs = shift || {};
- return $self->search(
- { 'me.namesearch' => { 'like' => $terms } },
- { 'order_by' => 'me.namesort', 'distinct' => 'me.id' }
- );
+ $attrs->{'order_by'} ||= 'me.namesort';
+ $attrs->{'distinct'} ||= 'me.id';
+
+ return $self->search({ 'me.namesearch' => { 'like' => $terms } }, $attrs);
}
sub browse {
Modified: trunk/server/Slim/Schema/ResultSet/Track.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/ResultSet/Track.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema/ResultSet/Track.pm (original)
+++ trunk/server/Slim/Schema/ResultSet/Track.pm Tue Aug 1 13:45:38 2006
@@ -35,13 +35,24 @@
sub ignoreArticles { 1 }
+sub searchColumn {
+ my $self = shift;
+
+ return 'titlesearch';
+}
+
sub searchNames {
- my ($self, $terms) = @_;
+ my $self = shift;
+ my $terms = shift;
+ my $attrs = shift || {};
+
+ $attrs->{'order_by'} ||= 'me.disc, me.titlesort';
+ $attrs->{'distinct'} ||= 'me.id';
return $self->search({
'me.titlesearch' => { 'like' => $terms },
'me.audio' => 1,
- }, { 'order_by' => 'me.titlesort', 'distinct' => 'me.id' });
+ }, $attrs);
}
sub orderBy {
Modified: trunk/server/Slim/Schema/Track.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/Track.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Schema/Track.pm (original)
+++ trunk/server/Slim/Schema/Track.pm Tue Aug 1 13:45:38 2006
@@ -13,10 +13,10 @@
use Slim::Utils::Misc;
our @allColumns = (qw(
- id url content_type title titlesort titlesearch album tracknum timestamp
- filesize tag disc thumb remote audio audio_size audio_offset
- year secs cover vbr_scale bitrate samplerate samplesize channels block_alignment
- endian bpm tagversion drm moodlogic_id moodlogic_mixable musicmagic_mixable
+ id url content_type title titlesort titlesearch album tracknum
+ timestamp filesize disc thumb remote audio audio_size audio_offset year secs
+ cover vbr_scale bitrate samplerate samplesize channels block_alignment endian
+ bpm tagversion drm moodlogic_id moodlogic_mixable musicmagic_mixable
musicbrainz_id playcount lastplayed lossless lyrics rating replay_gain replay_peak
));
@@ -33,7 +33,7 @@
$class->belongs_to('album' => 'Slim::Schema::Album');
$class->has_many('genreTracks' => 'Slim::Schema::GenreTrack' => 'track');
- $class->has_many('comment_objects' => 'Slim::Schema::Comment' => 'track');
+ $class->has_many('comments' => 'Slim::Schema::Comment' => 'track');
$class->has_many('contributorTracks' => 'Slim::Schema::ContributorTrack');
@@ -66,12 +66,6 @@
)->search(@_);
}
-sub comments {
- my $self = shift;
-
- return map { $_->value } $self->comment_objects(@_);
-}
-
sub genres {
my $self = shift;
@@ -149,7 +143,7 @@
my $comment;
# extract multiple comments and concatenate them
- for my $c ($self->comments) {
+ for my $c (map { $_->value } $self->comments) {
next unless $c;
@@ -388,7 +382,7 @@
for my $mixer (keys %{$Imports}) {
if (defined $Imports->{$mixer}->{'mixerlink'}) {
- &{$Imports->{$mixer}->{'mixerlink'}}($self,$form,0);
+ &{$Imports->{$mixer}->{'mixerlink'}}($self, $form, 0);
}
}
}
Modified: trunk/server/Slim/Utils/Text.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Utils/Text.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Utils/Text.pm (original)
+++ trunk/server/Slim/Utils/Text.pm Tue Aug 1 13:45:38 2006
@@ -101,11 +101,34 @@
$ignoredArticles = undef;
}
+sub searchStringSplit {
+ my $search = shift;
+ my $searchSubString = shift;
+
+ $searchSubString = defined $searchSubString ? $searchSubString : Slim::Utils::Prefs::get('searchSubString');
+
+ # normalize the string
+ $search = ignoreCaseArticles($search);
+
+ my @strings = ();
+
+ # Don't split - causes an explict AND, which is what we want.. I think.
+ # for my $string (split(/\s+/, $search)) {
+ my $string = $search;
+
+ if ($searchSubString) {
+
+ push @strings, "\%$string\%";
+
+ } else {
+
+ push @strings, [ "$string\%", "\% $string\%" ];
+ }
+ #}
+
+ return \@strings;
+}
+
1;
__END__
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:t
-# End:
Modified: trunk/server/Slim/Web/Pages/BrowseDB.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Web/Pages/BrowseDB.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Web/Pages/BrowseDB.pm (original)
+++ trunk/server/Slim/Web/Pages/BrowseDB.pm Tue Aug 1 13:45:38 2006
@@ -98,7 +98,6 @@
'title' => $title,
'hierarchy' => $hierarchy,
'level' => 0,
- 'attributes' => (scalar(@attrs) ? ('&' . join("&", @attrs)) : ''),
);
push @{$params->{'pwd_list'}}, {
@@ -107,7 +106,6 @@
'hierarchy' => $hierarchy,
'level' => 0,
'orderBy' => $orderBy,
- 'attributes' => (scalar(@attrs) ? ('&' . join("&", @attrs)) : ''),
};
# We want to include Compilations in the pwd, so we need the artist,
Modified: trunk/server/Slim/Web/Pages/LiveSearch.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Web/Pages/LiveSearch.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Web/Pages/LiveSearch.pm (original)
+++ trunk/server/Slim/Web/Pages/LiveSearch.pm Tue Aug 1 13:45:38 2006
@@ -7,7 +7,6 @@
# the results as XMLish data stream, to be dynamically displayed in a <div>
#
# Todo - call filltemplate stuff instead? May be too slow.
-# Use LIMIT - but then we don't get our "total matches" correct.
use strict;
@@ -19,47 +18,10 @@
use constant MAXRESULTS => 10;
-my @allTypes = qw(contributor album track);
-
-sub query {
- my ($class, $query, $types, $limit, $offset) = @_;
-
- my @data = ();
- my $search = Slim::Web::Pages::Search::searchStringSplit($query);
-
- # Default to a valid list of types
- if (!ref($types) || !defined $types->[0]) {
-
- $types = \@allTypes;
- }
-
- for my $type (@$types) {
-
- my $rs = Slim::Schema->rs($type)->searchNames($search);
- my $count = $rs->count;
- my @results = ();
-
- if ($count) {
-
- @results = $rs->slice($offset, $limit);
- }
-
- push @data, [ $type, $count, \@results ];
- }
-
- return \@data;
-}
-
-sub queryWithLimit {
- my ($class, $query, $types, $limit, $offset) = @_;
-
- return $class->query($query, $types, ($limit || MAXRESULTS), ($offset || 0));
-}
-
-sub outputAsXHTML {
+sub outputAsXHTML {
my $class = shift;
my $query = shift;
- my $results = shift;
+ my $rsList = shift;
my $player = shift;
my @xml = (
@@ -67,28 +29,20 @@
'<div id="browsedbList">',
);
- for my $result (@$results) {
+ for my $rs (@$rsList) {
- my $type = $result->[0];
- my $total = $result->[1];
- my $data = $result->[2];
+ my $type = lc($rs->result_source->source_name);
+ my $total = $rs->count;
my $count = 0;
my @output = ();
- next unless ref($data);
-
- for my $item (@{$data}) {
+ while (my $item = $rs->next) {
if ($count <= MAXRESULTS) {
my $rowType = $count % 2 ? 'even' : 'odd';
- push @output, renderItem(
- $rowType,
- $type,
- $item,
- $player
- );
+ push @output, renderItem($rowType, $type, $item, $player);
}
$count++;
@@ -108,9 +62,58 @@
}
push @xml, "</div>\n";
- my $string = join('', @xml);
- return \$string;
+ return \join('', @xml);
+}
+
+sub outputAsXML {
+ my $class = shift;
+ my $query = shift;
+ my $rsList = shift;
+ my $player = shift;
+
+ my @xml = (
+ '<?xml version="1.0" encoding="utf-8" standalone="yes"?>',
+ '<livesearch>',
+ );
+
+ for my $rs (@$rsList) {
+
+ my $type = lc($rs->result_source->source_name);
+ my $total = $rs->count;
+ my $count = 0;
+ my @output = ();
+
+ while (my $item = $rs->next) {
+
+ my $rowType = $count % 2 ? 'even' : 'odd';
+
+ if ($count <= MAXRESULTS) {
+
+ push @output, sprintf('<livesearchitem id="%s">%s</livesearchitem>', $item->id, $item->name);
+ }
+
+ $count++;
+ }
+
+ push @xml, sprintf("<searchresults type=\"%s\" hierarchy=\"%s\" mstring=\"%s "$query": $total\">",
+ $type,
+ $Slim::Web::Pages::hierarchy{$type} || '',
+ Slim::Utils::Strings::string(uc($type . 'SMATCHING'))
+ );
+
+ push @xml, @output if $count;
+
+ if ($total && $total > MAXRESULTS) {
+ push @xml, "<morematches query=\"$query\"/>";
+ }
+
+ push @xml, "</searchresults>";
+ }
+
+ push @xml, "</livesearch>\n";
+
+ return \join('', @xml);
}
sub renderItem {
@@ -180,64 +183,8 @@
<img src=\"html/images/b_add.gif\" width=\"13\" height=\"13\" alt=\"Add to playlist\" title=\"Add to playlist\"/></a> \n
</div>\n</div>\n</div>\n";
- my $string = join('', @xml);
-
- return $string;
+ return join('', @xml);
}
-
-sub outputAsXML {
- my $class = shift;
- my $query = shift;
- my $results = shift;
- my $player = shift;
-
- my @xml = (
- '<?xml version="1.0" encoding="utf-8" standalone="yes"?>',
- '<livesearch>',
- );
-
- for my $result (@$results) {
-
- my $type = $result->[0];
- my $total = $result->[1];
- my $data = $result->[2];
- my $count = 0;
- my @output = ();
-
- for my $item (@{$data}) {
-
- my $rowType = $count % 2 ? 'even' : 'odd';
- if ($count <= MAXRESULTS) {
-
- push @output, sprintf('<livesearchitem id="%s">%s</livesearchitem>',
- $item->id, $item->name,
- );
- }
-
- $count++;
- }
-
- push @xml, sprintf("<searchresults type=\"%s\" hierarchy=\"%s\" mstring=\"%s "$query": $total\">",
- $type,
- $Slim::Web::Pages::hierarchy{$type} || '',
- Slim::Utils::Strings::string(uc($type . 'SMATCHING'))
- );
-
- push @xml, @output if $count;
-
- if ($total && $total > MAXRESULTS) {
- push @xml, "<morematches query=\"$query\"/>";
- }
-
- push @xml, "</searchresults>";
- }
-
- push @xml, "</livesearch>\n";
- my $string = join('', @xml);
-
- return \$string;
-}
-
1;
__END__
Modified: trunk/server/Slim/Web/Pages/Search.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Web/Pages/Search.pm?rev=8758&r1=8757&r2=8758&view=diff
==============================================================================
--- trunk/server/Slim/Web/Pages/Search.pm (original)
+++ trunk/server/Slim/Web/Pages/Search.pm Tue Aug 1 13:45:38 2006
@@ -11,13 +11,13 @@
use Date::Parse qw(str2time);
use File::Spec::Functions qw(:ALL);
-use POSIX ();
use Scalar::Util qw(blessed);
use Slim::Player::TranscodingHelper;
use Slim::Utils::DateTime;
use Slim::Utils::Misc;
use Slim::Utils::Strings qw(string);
+use Slim::Utils::Text;
use Slim::Web::Pages;
use Slim::Web::Pages::LiveSearch;
@@ -37,10 +37,10 @@
my $query = $params->{'query'};
# set some defaults for the template
- $params->{'browse_list'} = " ";
- $params->{'numresults'} = -1;
- $params->{'itemsPerPage'} ||= Slim::Utils::Prefs::get('itemsPerPage');
+ $params->{'browse_list'} = " ";
+ $params->{'numresults'} = -1;
$params->{'browse_items'} = [];
+ $params->{'artwork'} = 0;
# short circuit
if (!defined($query) || ($params->{'manualSearch'} && !$query)) {
@@ -53,50 +53,45 @@
}
# Don't kill the database - use limit & offsets
- my $data = Slim::Web::Pages::LiveSearch->queryWithLimit($query, [ $params->{'type'} ], $params->{'itemsPerPage'}, $params->{'start'});
+ my $types = [ $params->{'type'} ];
+ my $limit = $params->{'itemPerPage'} || 10;
+ my $offset = $params->{'start'} || 0;
+ my $search = Slim::Utils::Text::searchStringSplit($query);
+
+ # Default to a valid list of types
+ if (!ref($types) || !defined $types->[0]) {
+
+ $types = [ Slim::Schema->searchTypes ];
+ }
+
+ my @rsList = ();
+
+ # Create a ResultSet for each of Contributor, Album & Track
+ for my $type (@$types) {
+
+ my $rs = Slim::Schema->rs($type)->searchNames($search);
+ push @rsList, $rs;
+ }
# The user has hit enter, or has a browser that can't handle the javascript.
if ($params->{'manualSearch'}) {
# Tell the template not to do a livesearch request anymore.
$params->{'liveSearch'} = 0;
-
- my @results = ();
- my $descend = 1;
- my @qstring = ('manualSearch=1');
-
- for my $item (@$data) {
-
- $params->{'type'} = $item->[0];
- $params->{'numresults'} = $item->[1];
- $params->{'path'} = 'search.html';
-
- if ($params->{'type'} eq 'track' && $params->{'numresults'}) {
-
- push @results, $item->[2];
-
- $descend = undef;
- }
-
- fillInSearchResults($params, $item->[2], $descend, \@qstring);
- }
-
- if (defined $client && scalar @results && !$params->{'start'}) {
- # stash the full resultset if not paging through the results
- # assumes that when the start parameter is 0 or undefined that
- # the query has just been run
- my $fulldata = Slim::Web::Pages::LiveSearch->query($query, [ 'track' ]);
- $client->param('searchResults', $fulldata->[0][2]);
+ $params->{'path'} = 'search.html';
+
+ for my $rs (@rsList) {
+
+ fillInSearchResults($params, $rs, [ 'manualSearch=1' ]);
}
return Slim::Web::HTTP::filltemplatefile("search.html", $params);
- }
-
- # do it live - and send back the div
- if ($params->{'xmlmode'}) {
- return Slim::Web::Pages::LiveSearch->outputAsXML($query, $data, $player);
+
} else {
- return Slim::Web::Pages::LiveSearch->outputAsXHTML($query, $data, $player);
+
+ # do it live - and send back the div
+ # this should be replaced with a call to filltemplatefile()
+ return Slim::Web::Pages::LiveSearch->outputAsXHTML($query, \@rsList, $player);
}
}
@@ -108,10 +103,9 @@
my @qstring = ();
# template defaults
- $params->{'browse_list'} = " ";
- $params->{'liveSearch'} = 0;
+ $params->{'browse_list'} = " ";
+ $params->{'liveSearch'} = 0;
$params->{'browse_items'} = [];
- $params->{'itemsPerPage'} ||= Slim::Utils::Prefs::get('itemsPerPage');
# Prep the date format
$params->{'dateFormat'} = Slim::Utils::DateTime::shortDateF();
@@ -174,13 +168,13 @@
# We need the _'s in the form, because . means hash key.
if ($newKey =~ s/_(titlesearch|namesearch)$/\.$1/) {
- $params->{$key} = { 'like' => searchStringSplit($params->{$key}) };
- }
-
- # Wildcard comment searches
- if ($newKey =~ /comment/) {
-
- $params->{$key} = "\*$params->{$key}\*";
+ $params->{$key} = { 'like' => Slim::Utils::Text::searchStringSplit($params->{$key}) };
+ }
+
+ # Wildcard searches
+ if ($newKey =~ /comment/ || $newKey =~ /lyrics/) {
+
+ $params->{$key} = { 'like' => Slim::Utils::Text::searchStringSplit($params->{$key}) };
}
$query{$newKey} = $params->{$key};
@@ -203,7 +197,8 @@
# short-circuit the query
if (scalar keys %query == 0) {
- $params->{'numresults'} = -1;
+ $params->{'numresults'} = -1;
+
return Slim::Web::HTTP::filltemplatefile("advanced_search.html", $params);
}
@@ -227,6 +222,7 @@
}
}
+ # Pull in the required joins
if ($query{'genre'}) {
push @joins, 'genreTracks';
@@ -235,6 +231,11 @@
if ($query{'album.titlesearch'}) {
push @joins, 'album';
+ }
+
+ if ($query{'comments.value'}) {
+
+ push @joins, 'comments';
}
# Disambiguate year
@@ -242,181 +243,140 @@
$query{'me.year'} = delete $query{'year'};
}
- # Do the actual search
- my $rs = Slim::Schema->search('Track',
- \%query,
- { 'order_by' => 'titlesort', 'join' => \@joins }
+ # XXXX - for some reason, the 'join' key isn't preserved when passed
+ # along as a ref. Perl bug because 'join' is a keyword? Use 'joins' as well.
+ my %attrs = (
+ 'order_by' => 'me.disc, me.titlesort',
+ 'join' => \@joins,
+ 'joins' => \@joins,
);
- my $count = $rs->count;
-
- my $start = ($params->{'start'} || 0),
- my $end = $params->{'itemsPerPage'} - 1;
+ # Create a resultset - have fillInSearchResults do the actual search.
+ my $rs = Slim::Schema->search('Track', \%query, \%attrs);
if (defined $client && !$params->{'start'}) {
- # stash the full resultset if not paging through the results
- # assumes that when the start parameter is 0 or undefined that
- # the query has just been run
- $client->param('searchResults', [ $rs->all ]);
-
- $rs->reset;
- }
-
- if ($count == $params->{'itemsPerPage'}) {
-
- $params->{'numresults'} = $count;
- }
-
- fillInSearchResults($params, [ $rs->slice($start, $end) ], undef, \@qstring, 1);
+ # stash parameters used to generate this query, so if the user
+ # wants to play All Songs, we can run it again, but without
+ # keeping all the tracks in memory twice.
+ $client->param('searchTrackResults', { 'cond' => \%query, 'attr' => \%attrs });
+ }
+
+ fillInSearchResults($params, $rs, \@qstring, 1);
return Slim::Web::HTTP::filltemplatefile("advanced_search.html", $params);
}
sub fillInSearchResults {
- my ($params, $results, $descend, $qstring, $typeSeparator) = @_;
+ my ($params, $rs, $qstring, $typeSeparator) = @_;
my $player = $params->{'player'};
my $query = $params->{'query'} || '';
- my $type = $params->{'type'} || 'track';
-
- $params->{'type'} = $type;
-
+ my $type = lc($rs->result_source->source_name) || 'track';
+ my $count = $rs->count || return 0;
+
+ # Set some reasonable defaults
+ $params->{'numresults'} = $count;
+ $params->{'itemsPerPage'} ||= Slim::Utils::Prefs::get('itemsPerPage');
+
+ # This is handed to pageInfo to generate the pagebar 1 2 3 >> links.
my $otherParams = 'player=' . Slim::Utils::Misc::escape($player) .
($type ?'&type='. $type : '') .
($query ? '&query=' . Slim::Utils::Misc::escape($query) : '' ) .
'&' .
join('&', @$qstring);
- # Make sure that we have something to show.
- if (!defined $params->{'numresults'} && defined $results && ref($results) eq 'ARRAY') {
-
- $params->{'numresults'} = scalar @$results;
- }
-
- # put in the type separator
- if ($type && !$typeSeparator) {
+ # Put in the type separator
+ if (!$typeSeparator && $count) {
# add reduced item for type headings
push @{$params->{'browse_items'}}, {
- 'numresults' => $params->{'numresults'},
- 'query' => $query,
- 'heading' => $type,
+ 'numresults' => $count,
+ 'query' => $query,
+ 'heading' => $type,
+ 'odd' => 0,
};
}
- my ($start, $end);
-
- if ($params->{'numresults'}) {
-
- $params->{'pageinfo'} = Slim::Web::Pages->pageInfo({
-
- 'itemCount' => $params->{'numresults'},
- 'path' => $params->{'path'},
- 'otherParams' => $otherParams,
- 'start' => $params->{'start'},
- 'perPage' => $params->{'itemsPerPage'},
- });
-
- $start = $params->{'start'} = $params->{'pageinfo'}{'startitem'};
- $end = $params->{'pageinfo'}{'enditem'};
-
- my $itemnumber = 1;
- my $lastAnchor = '';
-
- for my $item (@$results) {
-
- next unless defined $item && ref($item);
-
- # Contributor/Artist uses name, Album & Track uses title.
- my %form = %$params;
-
- $form{'attributes'} = '&' . join('.id=', $type, $item->id);
- $form{'descend'} = $descend;
- $form{'odd'} = ($itemnumber) % 2;
-
- if ($type eq 'track') {
-
- # If we can't get an object for this url, skip it, as the
- # user's database is likely out of date. Bug 863
- my $itemObj = $item;
-
- if (!blessed($itemObj) || !$itemObj->can('id')) {
-
- $itemObj = Slim::Schema->rs('Track')->objectForUrl($item);
- }
-
- if (!blessed($itemObj) || !$itemObj->can('id')) {
-
- next;
- }
-
- $itemObj->displayAsHTML(\%form, 0);
-
- } else {
-
- if ($type eq 'contributor') {
-
- $form{'hierarchy'} = 'contributor,album,track';
- $form{'level'} = 1;
- $form{'hreftype'} = 'browseDb';
-
- } elsif ($type eq 'album') {
-
- $form{'hierarchy'} = 'album,track';
- $form{'level'} = 1;
- $form{'hreftype'} = 'browseDb';
- }
-
- $form{'text'} = $item->name;
- }
-
- $itemnumber++;
-
- my $anchor = substr($item->namesort, 0, 1);
-
- if ($lastAnchor ne $anchor) {
- $form{'anchor'} = $lastAnchor = $anchor;
- }
-
- push @{$params->{'browse_items'}}, \%form;
- }
+ # Add in ALL
+ if ($count > 1) {
+
+ my $attributes = '';
+
+ if ($typeSeparator) {
+ $attributes = sprintf('&searchRef=search%sResults', ucfirst($type));
+ } else {
+ $attributes = sprintf('&%s.%s=%s', $type, $rs->searchColumn, $query);
+ }
+
+ push @{$params->{'browse_items'}}, {
+ 'text' => string('ALL_SONGS'),
+ 'player' => $params->{'player'},
+ 'attributes' => $attributes,
+ 'odd' => 1,
+ };
+ }
+
+ my $offset = ($params->{'start'} || 0),
+ my $limit = ($params->{'itemsPerPage'} || 10) - 1;
+
+ $params->{'pageinfo'} = Slim::Web::Pages->pageInfo({
+
+ 'itemCount' => $params->{'numresults'},
+ 'path' => $params->{'path'},
+ 'otherParams' => $otherParams,
+ 'start' => $params->{'start'},
+ 'perPage' => $params->{'itemsPerPage'},
+ });
+
+ $params->{'start'} = $params->{'pageinfo'}{'startitem'};
+
+ my $itemCount = 1;
+ my $lastAnchor = '';
+ my $descend = $type eq 'track' ? 0 : 1;
+
+ # Get just the items we need for this loop.
+ $rs = $rs->slice($offset, $limit);
+
+ # This is very similar to a loop in Slim::Web::Pages::BrowseDB....
+ while (my $obj = $rs->next) {
+
+ my %form = (
+ 'levelName' => $type,
+ 'hreftype' => 'browseDb',
+ 'descend' => $descend,
+ 'odd' => ($itemCount + 1) % 2,
+ 'skinOverride' => $params->{'skinOverride'},
+ 'player' => $params->{'player'},
+ 'itemobj' => $obj,
+ 'level' => 1,
+ 'artwork' => 0,
+ 'attributes' => sprintf('&%s.id=%d', $type, $obj->id),
+ );
+
+ if ($type eq 'contributor') {
+
+ $form{'hierarchy'} = 'contributor,album,track';
+
+ } elsif ($type eq 'album') {
+
+ $form{'hierarchy'} = 'album,track';
+ }
+
+ $obj->displayAsHTML(\%form, $descend);
+
+ $itemCount++;
+
+ my $anchor = substr($obj->namesort, 0, 1);
+
+ if ($lastAnchor ne $anchor) {
+ $form{'anchor'} = $lastAnchor = $anchor;
+ }
+
+ push @{$params->{'browse_items'}}, \%form;
}
}
-sub searchStringSplit {
- my $search = shift;
- my $searchSubString = shift;
-
- $searchSubString = defined $searchSubString ? $searchSubString : Slim::Utils::Prefs::get('searchSubString');
-
- # normalize the string
- $search = Slim::Utils::Text::ignoreCaseArticles($search);
-
- my @strings = ();
-
- # Don't split - causes an explict AND, which is what we want.. I think.
- # for my $string (split(/\s+/, $search)) {
- my $string = $search;
-
- if ($searchSubString) {
-
- push @strings, "\%$string\%";
-
- } else {
-
- push @strings, [ "$string\%", "\% $string\%" ];
- }
- #}
-
- return \@strings;
-}
-
1;
__END__
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:t
-# End:
More information about the checkins
mailing list