source: branches/New_Config_Format-branch/gsdl/perllib/classify/DateList.pm@ 1279

Last change on this file since 1279 was 677, checked in by sjboddie, 25 years ago

changes for new browsing support

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1###########################################################################
2#
3# DateList.pm --
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26# classifier plugin for sorting by date
27
28# no options - always sorts by 'Date' metadata
29
30# date is assumed to be in the form yyyymmdd
31
32# at present dates are split by year - this should change
33
34package DateList;
35
36use sorttools;
37
38sub new {
39 my ($class, @options) = @_;
40
41 return bless {
42 'list'=>{},
43 }, $class;
44}
45
46sub init {
47 my $self = shift (@_);
48
49 $self->{'list'} = {};
50}
51
52sub classify {
53 my $self = shift (@_);
54 my ($doc_obj) = @_;
55
56 my $doc_OID = $doc_obj->get_OID();
57 my $date = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), 'Date');
58
59 # if this document doesn't contain Date element we won't
60 # include it in this classification
61 if (defined $date && $date =~ /\d/) {
62 if (defined $self->{'list'}->{$doc_OID}) {
63 print STDERR "WARNING: DateList::classify called multiple times for $doc_OID\n";
64 }
65 $self->{'list'}->{$doc_OID} = $date;
66 }
67}
68
69
70sub get_classify_info {
71 my $self = shift (@_);
72
73 my @classlist = sort {$self->{'list'}->{$a} cmp $self->{'list'}->{$b};} keys %{$self->{'list'}};
74
75 return $self->splitlist (\@classlist);
76}
77
78
79sub get_entry {
80 my $self = shift (@_);
81 my ($title, $childtype, $thistype) = @_;
82
83 # organise into classification structure
84 my %classifyinfo = ('childtype'=>$childtype,
85 'Title'=>$title,
86 'contains'=>[]);
87 $classifyinfo{'thistype'} = $thistype
88 if defined $thistype && $thistype =~ /\w/;
89
90 return \%classifyinfo;
91}
92
93# splitlist takes an ordered list of classifications (@$classlistref) and splits it
94# up into sub-sections by date
95sub splitlist {
96 my $self = shift (@_);
97 my ($classlistref) = @_;
98 my $classhash = {};
99
100 # top level
101 my $childtype = "HList";
102 if (scalar (@$classlistref) <= 20) {$childtype = "DateList";}
103 my $classifyinfo = $self->get_entry ("Date", $childtype, "Invisible");
104
105 # don't need to do any splitting if there are less than 20 classifications
106 if ((scalar @$classlistref) <= 20) {
107 foreach $subOID (@$classlistref) {
108 push (@{$classifyinfo->{'contains'}}, {'OID'=>$subOID});
109 }
110 return $classifyinfo;
111 }
112
113 # first split up the list into separate year classifications
114 foreach $classification (@$classlistref) {
115 my $date = $self->{'list'}->{$classification};
116 $date =~ s/^(\d\d\d\d).*$/$1/;
117 $classhash->{$date} = [] unless defined $classhash->{$date};
118 push (@{$classhash->{$date}}, $classification);
119 }
120
121 $classhash = $self->compactlist ($classhash);
122
123 foreach $subclass (sort keys %$classhash) {
124 my $tempclassify = $self->get_entry($subclass, "DateList");
125 foreach $subsubOID (@{$classhash->{$subclass}}) {
126 push (@{$tempclassify->{'contains'}}, {'OID'=>$subsubOID});
127 }
128 push (@{$classifyinfo->{'contains'}}, $tempclassify);
129 }
130
131 return $classifyinfo;
132}
133
134sub compactlist {
135 my $self = shift (@_);
136 my ($classhashref) = @_;
137 my $compactedhash = {};
138 my @currentOIDs = ();
139 my $currentfirstletter = "";
140 my $currentlastletter = "";
141 my $lastkey = "";
142
143 # minimum and maximum documents to be displayed per page.
144 # the actual maximum will be max + (min-1).
145 # the smallest sub-section is a single letter at present
146 # so in this case there may be many times max documents
147 # displayed on a page.
148 my $min = 10;
149 my $max = 30;
150
151 foreach $subsection (sort keys %$classhashref) {
152 $currentfirstletter = $subsection if $currentfirstletter eq "";
153 if ((scalar (@currentOIDs) < $min) ||
154 ((scalar (@currentOIDs) + scalar (@{$classhashref->{$subsection}})) <= $max)) {
155 push (@currentOIDs, @{$classhashref->{$subsection}});
156 $currentlastletter = $subsection;
157 } else {
158
159 if ($currentfirstletter eq $currentlastletter) {
160 @{$compactedhash->{$currentfirstletter}} = @currentOIDs;
161 $lastkey = $currentfirstletter;
162 } else {
163 @{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
164 $lastkey = "$currentfirstletter-$currentlastletter";
165 }
166 if (scalar (@{$classhashref->{$subsection}}) >= $max) {
167 $compactedhash->{$subsection} = $classhashref->{$subsection};
168 @currentOIDs = ();
169 $currentfirstletter = "";
170 $lastkey = $subsection;
171 } else {
172 @currentOIDs = @{$classhashref->{$subsection}};
173 $currentfirstletter = $subsection;
174 $currentlastletter = $subsection;
175 }
176 }
177 }
178
179 # add final OIDs to last sub-classification if there aren't many otherwise
180 # add final sub-classification
181 if (scalar (@currentOIDs) < $min) {
182 my ($newkey) = $lastkey =~ /^(\d\d\d\d)/;
183 @currentOIDs = (@{$compactedhash->{$lastkey}}, @currentOIDs);
184 delete $compactedhash->{$lastkey};
185 @{$compactedhash->{"$newkey-$currentlastletter"}} = @currentOIDs;
186 } else {
187 if ($currentfirstletter eq $currentlastletter) {
188 @{$compactedhash->{$currentfirstletter}} = @currentOIDs;
189 } else {
190 @{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
191 }
192 }
193
194 return $compactedhash;
195}
196
1971;
Note: See TracBrowser for help on using the repository browser.