Index: trunk/WikiWord/WikiWord/src/main/php/wwclient.php |
— | — | @@ -1,152 +0,0 @@ |
2 | | -<?php |
3 | | -require_once( dirname( __FILE__ ) . "/wwutils.php" ); |
4 | | - |
5 | | -class WWClient { |
6 | | - var $api; |
7 | | - |
8 | | - function __construct( $api ) { |
9 | | - $this->api = $api; |
10 | | - } |
11 | | - |
12 | | - function query( $params ) { |
13 | | - $url = $this->api . '?format=phps'; |
14 | | - |
15 | | - foreach ( $params as $k => $v ) { |
16 | | - if ($v===null) continue; |
17 | | - if ($v===false) $v = ""; |
18 | | - if (is_array($v)) $v = implode("|", $v); |
19 | | - |
20 | | - $url .= '&'; |
21 | | - $url .= urlencode( $k ); |
22 | | - $url .= '='; |
23 | | - $url .= urlencode( $v ); |
24 | | - } |
25 | | - |
26 | | - $data = file_get_contents( $url ); //TODO: CURL |
27 | | - if ( !$data ) throw new Exception("failed to fetch data from $url"); |
28 | | - |
29 | | - $data = unserialize($data); |
30 | | - if ( !$data ) throw new Exception("failed to unserialize data from $url"); |
31 | | - |
32 | | - if ( @$data['error'] ) throw new Exception("API returned error ".$data['error']['code'].": ".$data['error']['message']."; url: $url"); |
33 | | - return $data; |
34 | | - } |
35 | | - |
36 | | - function getPagesForConcept( $id, $lang = null ) { |
37 | | - $p = $this->getConceptInfo( $id, $lang ); |
38 | | - return $p['pages']; |
39 | | - } |
40 | | - |
41 | | - /* |
42 | | - function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat |
43 | | - return getPagesForConcept($id); |
44 | | - } |
45 | | - |
46 | | - function getConcept( $id, $lang = null ) { |
47 | | - $p = $this->getConceptProperties( $id, '', $lang );getConceptInfo |
48 | | - return $p['pages']; |
49 | | - } |
50 | | - |
51 | | - function getRelatedForConcept( $id, $lang = null ) { |
52 | | - $p = $this->getConceptProperties( $id, 'related', $lang ); |
53 | | - return $p['related']; |
54 | | - } |
55 | | - |
56 | | - function getBroaderForConcept( $id, $lang = null ) { |
57 | | - $p = $this->getConceptProperties( $id, 'broader', $lang ); |
58 | | - return $p['broader']; |
59 | | - } |
60 | | - |
61 | | - function getNarrowerForConcept( $id, $lang = null ) { |
62 | | - $p = $this->getConceptProperties( $id, 'narrower', $lang ); |
63 | | - return $p['narrower']; |
64 | | - } |
65 | | - |
66 | | - function getTermsForConcept( $id, $lang = null ) { |
67 | | - $p = $this->getConceptProperties( $id, 'terms', $lang ); |
68 | | - return $p['terms']; |
69 | | - } |
70 | | - |
71 | | - function getDefinitionForConcept( $id, $lang = null ) { |
72 | | - $p = $this->getConceptProperties( $id, 'definition', $lang ); |
73 | | - return $p['definition']; |
74 | | - } |
75 | | - |
76 | | - function getReferencesForConcept( $id, $lang = null ) { |
77 | | - $p = $this->getConceptProperties( $id, 'links', $lang ); |
78 | | - return $p['references']; |
79 | | - } |
80 | | - |
81 | | - function getLinksForConcept( $id, $lang = null ) { |
82 | | - $p = $this->getConceptProperties( $id, 'links', $lang ); |
83 | | - return $p['links']; |
84 | | - } |
85 | | - |
86 | | - function getScoresForConcept( $id, $lang = null ) { |
87 | | - $p = $this->getConceptProperties( $id, 'scores', $lang ); |
88 | | - return $p['scores']; |
89 | | - }*/ |
90 | | - |
91 | | - function getConceptInfo( $id, $lang = null ) { |
92 | | - $param = array( |
93 | | - 'query' => 'info', |
94 | | - 'gcid' => $id, |
95 | | - 'lang' => $lang |
96 | | - ); |
97 | | - |
98 | | - $rs = $this->query( $param ); |
99 | | - |
100 | | - if (!isset($rs['id'])) $rs['id'] = $id; |
101 | | - if (!isset($rs['lang'])) $rs['lang'] = $lang; |
102 | | - |
103 | | - return $rs; |
104 | | - } |
105 | | - |
106 | | - /* |
107 | | - function getConceptProperties( $id, $props, $lang =$props null ) { |
108 | | - $param = array( |
109 | | - 'query' => 'properties', |
110 | | - 'props' => ( is_array($props) ? join('|', $props) : $props ), |
111 | | - 'gcid' => $id, |
112 | | - ); |
113 | | - |
114 | | - if ( $lang ) $param['lang'] = $lang; |
115 | | - |
116 | | - $rs = $this->query( $param ); |
117 | | - |
118 | | - if (!isset($rs['id'])) $rs['id'] = $id; |
119 | | - if (!isset($rs['lang'])) $rs['lang'] = $lang; |
120 | | - |
121 | | - return $rs; |
122 | | - }*/ |
123 | | - |
124 | | - function getConceptsForTerm( $qlang, $term, $languages, $norm = 1, $limit = 100 ) { |
125 | | - if ( is_array( $languages ) ) $languages = implode('|', $languages); |
126 | | - |
127 | | - $param = array( |
128 | | - 'query' => 'concepts', |
129 | | - 'qlang' => $qlang, |
130 | | - 'lang' => $languages, |
131 | | - 'norm' => $norm, |
132 | | - 'term' => $term, |
133 | | - ); |
134 | | - |
135 | | - $rs = $this->query( $param ); |
136 | | - |
137 | | - return $rs['concepts']; |
138 | | - } |
139 | | - |
140 | | - /* |
141 | | - function getConceptsForPage( $lang, $page ) { |
142 | | - $param = array( |
143 | | - 'query' => 'concepts', |
144 | | - 'lang' => $lang, |
145 | | - 'page' => $page, |
146 | | - ); |
147 | | - |
148 | | - $rs = $this->query( $param ); |
149 | | - |
150 | | - return $rs['concepts']; |
151 | | - } |
152 | | - */ |
153 | | -} |
Index: trunk/WikiWord/WikiWord/src/main/php/wwtest.php |
— | — | @@ -1,20 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -$IP = dirname(__FILE__); |
5 | | - |
6 | | -require_once("$IP/config.php"); |
7 | | -require_once("$IP/wwutils.php"); |
8 | | - |
9 | | -$utils = new WWUtils(); |
10 | | -$utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
11 | | - |
12 | | -$utils->debug = true; |
13 | | - |
14 | | -if (!isset($argv[1])) die("usage: wwtest <id>\n"); |
15 | | - |
16 | | -$id = $argv[1]; |
17 | | -$max = @$argv[2]; |
18 | | - |
19 | | -$images = $utils->getImagesAbout($id, $max); |
20 | | - |
21 | | -print_r($images); |
\ No newline at end of file |
Index: trunk/WikiWord/WikiWord/src/main/php/wikiword.php |
— | — | @@ -1,481 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -$IP = dirname(__FILE__); |
5 | | - |
6 | | -require_once("$IP/config.php"); |
7 | | -require_once("$IP/wwimages.php"); |
8 | | - |
9 | | -if ($wwAPI) require_once("$IP/wwclient.php"); |
10 | | -else require_once("$IP/wwthesaurus.php"); |
11 | | - |
12 | | -function printLocalConceptList($lang, $concepts) { |
13 | | - global $utils; |
14 | | - if (is_string($concepts)) $concepts = $utils->unpickle($concepts, $lang, true, false, true); |
15 | | - |
16 | | - ?> |
17 | | - <ul class="terselist"> |
18 | | - <?php |
19 | | - foreach ($concepts as $c) { |
20 | | - ?><li><?php |
21 | | - printLocalConceptLink($lang, $c); |
22 | | - ?></li><?php |
23 | | - } |
24 | | - ?> |
25 | | - </ul> |
26 | | - <?php |
27 | | -} |
28 | | - |
29 | | -function printConceptImageList($concept, $class = "terselist") { |
30 | | - global $utils, $wwThumbSize, $wwMaxPreviewImages; |
31 | | - |
32 | | - if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK |
33 | | - else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages); |
34 | | - |
35 | | - ?> |
36 | | - <ul class="<?php print $class; ?>"> |
37 | | - <?php |
38 | | - foreach ($images as $img) { |
39 | | - ?><li><?php |
40 | | - print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize); |
41 | | - ?></li><?php |
42 | | - } |
43 | | - ?> |
44 | | - </ul> |
45 | | - <?php |
46 | | -} |
47 | | - |
48 | | -function printLocalConceptLink($lang, $row) { |
49 | | - global $wwSelf, $images; |
50 | | - |
51 | | - $row = normalizeConceptRow($lang, $row); |
52 | | - |
53 | | - extract($row); |
54 | | - |
55 | | - if (!isset($weight) && isset($freq)) $weight = $freq; |
56 | | - if (!isset($weight) && isset($conf)) $weight = $conf; |
57 | | - if (!isset($concept_name) && isset($name)) $concept_name = $name; |
58 | | - if (!isset($concept_name)) $concept_name = NULL; |
59 | | - if (!isset($concept) && isset($id)) $concept = $id; |
60 | | - if (!isset($concept)) $concept = NULL; |
61 | | - |
62 | | - if ($lang == 'commons') $domain = 'commons.wikimedia.org'; |
63 | | - else $domain = "$lang.wikipedia.org"; |
64 | | - |
65 | | - $wu = $concept_name ? "http://$domain/wiki/" . urlencode($concept_name) : NULL; |
66 | | - $cu = "$wwSelf?id=" . urlencode($concept) . "&lang=" . urlencode($lang); |
67 | | - |
68 | | - if ($images) $cu .= "&images=1"; |
69 | | - |
70 | | - ?> |
71 | | - <li> |
72 | | - <?php if ($concept_name) { ?> |
73 | | - <a href="<?php print htmlspecialchars($cu); ?>"><?php print htmlspecialchars($concept_name); ?></a> |
74 | | - <?php } ?> |
75 | | - <?php if ($concept) { ?> |
76 | | - (<a href="<?php print htmlspecialchars($wu); ?>" title="<?php print htmlspecialchars($concept_name); ?>">wiki page</a>) |
77 | | - <?php } ?> |
78 | | - </li> |
79 | | - <?php |
80 | | -} |
81 | | - |
82 | | -function printTermList($lang, $terms) { |
83 | | - global $utils; |
84 | | - if (is_string($terms)) $terms = $utils->unpickle($terms, $lang); |
85 | | - |
86 | | - ?> |
87 | | - <ul class="terselist"> |
88 | | - <?php |
89 | | - foreach ($terms as $t) { |
90 | | - printTermLink($lang, $terms); |
91 | | - } |
92 | | - ?> |
93 | | - </ul> |
94 | | - <?php |
95 | | -} |
96 | | - |
97 | | -function printTermLink($lang, $row) { |
98 | | - global $wwSelf; |
99 | | - |
100 | | - extract($row); |
101 | | - |
102 | | - if (!isset($weight) && isset($freq)) $weight = $freq; |
103 | | - if (!isset($weight) && isset($conf)) $weight = $conf; |
104 | | - if (!isset($term_text) && isset($term)) $term_text = $term; |
105 | | - if (!isset($term_text) && isset($text)) $term_text = $text; |
106 | | - if (!isset($term_text) && isset($name)) $term_text = $name; |
107 | | - if (!isset($term_text) && isset($value)) $term_text = $value; |
108 | | - |
109 | | - $tu = "$wwSelf?term=" . urlencode($term_text) . "&lang=" . urlencode($lang); |
110 | | - |
111 | | - ?> |
112 | | - <li> |
113 | | - <a href="<?php print htmlspecialchars($tu); ?>"><?php print htmlspecialchars($term_text); ?></a> |
114 | | - </li> |
115 | | - <?php |
116 | | -} |
117 | | - |
118 | | -function normalizeConceptRow($lang, $row) { |
119 | | - global $wwSelf; |
120 | | - |
121 | | - #FIXME: handle complex concept records! |
122 | | - |
123 | | - if (!$row) return $row; |
124 | | - |
125 | | - if (!isset($row['lang'])) $row['lang'] = $lang; |
126 | | - if (!isset($row['weight']) && isset($row['freq'])) $row['weight'] = $row['freq']; |
127 | | - if (!isset($row['weight']) && isset($row['conf'])) $row['weight'] = $row['conf']; |
128 | | - if (!empty($row['local_concept_name'])) $row['concept_name'] = $row['local_concept_name']; |
129 | | - if (!isset($row['concept_name']) && isset($row['name'])) $row['concept_name'] = $row['name']; |
130 | | - if (!isset($row['concept_name']) && isset($row['global_concept_name'])) $row['concept_name'] = $row['global_concept_name']; |
131 | | - if (!isset($row['reference_id']) && isset($row['global_id'])) $row['reference_id'] = $row['global_id']; |
132 | | - if (!isset($row['reference_id']) && isset($row['global_concept'])) $row['reference_id'] = $row['global_concept']; |
133 | | - if (!isset($row['reference_id']) && isset($row['concept'])) $row['reference_id'] = $row['concept']; |
134 | | - if (!isset($row['reference_id']) && isset($row['id'])) $row['reference_id'] = $row['id']; |
135 | | - if (!empty($row['definition']) && is_array($row['definition'])) $row['definition'] = $row['definition'][$lang]; |
136 | | - |
137 | | - #print "<pre>"; |
138 | | - #print_r($row); |
139 | | - #print "</pre>"; |
140 | | - |
141 | | - $row['wu'] = "http://$lang.wikipedia.org/wiki/" . urlencode($row['concept_name']); |
142 | | - #$row['cu'] = "$wwSelf?id=" . urlencode($row['concept']) . "&lang=" . urlencode($lang); |
143 | | - $row['cu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&lang=" . urlencode($lang); |
144 | | - $row['gu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&images=g"; |
145 | | - |
146 | | - if (!isset($row['weight']) || !$row['weight']) { |
147 | | - $row['wclass'] = "unknown"; |
148 | | - $row['weight'] = NULL; |
149 | | - } |
150 | | - else if ($row['weight']>1000) $row['wclass'] = "huge"; |
151 | | - else if ($row['weight']>100) $row['wclass'] = "big"; |
152 | | - else if ($row['weight']>10) $row['wclass'] = "normal"; |
153 | | - else if ($row['weight']>2) $row['wclass'] = "some"; |
154 | | - else $row['wclass'] = "little"; |
155 | | - |
156 | | - return $row; |
157 | | -} |
158 | | - |
159 | | -function printLocalConcept($a_lang, $a_row, $b_lang, $b_row, $pos = 0, $terse = true) { |
160 | | - global $wwSelf, $images, $utils; |
161 | | - global $wwMaxPreviewImages, $wwMaxGalleryImages; |
162 | | - |
163 | | - $a_row = normalizeConceptRow($a_lang, $a_row); |
164 | | - $b_row = normalizeConceptRow($b_lang, $b_row); |
165 | | - |
166 | | - if ($a_lang && $a_row) extract($a_row, EXTR_PREFIX_ALL, "a"); |
167 | | - if ($b_lang && $b_row) extract($b_row, EXTR_PREFIX_ALL, "b"); |
168 | | - |
169 | | - ?> |
170 | | - <tr class="row_item"> |
171 | | - <td class="cell_weight <?php print "weight_$a_wclass"; ?>"><?php print htmlspecialchars($a_weight); ?></td> |
172 | | - <td colspan="3" class="cell_name <?php print "weight_$a_wclass"; ?>"> |
173 | | - <h3> |
174 | | - <a href="<?php print htmlspecialchars($a_cu); ?>"><?php print htmlspecialchars($a_concept_name); ?></a> |
175 | | - <span class="conceptref">(<a href="<?php print htmlspecialchars($a_wu); ?>" title="<?php print htmlspecialchars($a_concept_name); ?>">wiki page</a>)</span> |
176 | | - </h3> |
177 | | - </td> |
178 | | - <?php if ($b_row) { ?> |
179 | | - <td colspan="3" class="cell_name <?php print "weight_$b_wclass"; ?>"> |
180 | | - <h3> |
181 | | - <a href="<?php print htmlspecialchars($b_cu); ?>"><?php print htmlspecialchars($b_concept_name); ?></a> |
182 | | - <span class="conceptref">(<a href="<?php print htmlspecialchars($b_wu); ?>" title="<?php print htmlspecialchars($b_concept_name); ?>">wiki page</a>)</span> |
183 | | - </h3> |
184 | | - </td> |
185 | | - <?php } ?> |
186 | | - </tr> |
187 | | - |
188 | | - <?php if (isset($a_definition) && !empty($a_definition)) { ?> |
189 | | - <tr class="row_def"> |
190 | | - <td></td> |
191 | | - <td class="cell_label">Definition:</td> |
192 | | - <td colspan="2"><?php print htmlspecialchars($a_definition); ?></td> |
193 | | - <?php if ($b_row) { ?> |
194 | | - <td class="cell_label">Definition:</td> |
195 | | - <td colspan="2"><?php print htmlspecialchars($b_definition); ?></td> |
196 | | - <?php } ?> |
197 | | - </tr> |
198 | | - <?php } ?> |
199 | | - |
200 | | - <?php if (isset($a_terms) && !empty($a_terms)) { ?> |
201 | | - <tr class="row_details row_terms"> |
202 | | - <td></td> |
203 | | - <td class="cell_label">Terms:</td> |
204 | | - <td class="cell_terms" colspan="2"><?php printTermList($a_lang, $a_terms); ?></td> |
205 | | - <?php if ($b_row) { ?> |
206 | | - <td class="cell_label">Terms:</td> |
207 | | - <td class="cell_terms" colspan="2"><?php printTermList($b_lang, $b_terms); ?></td> |
208 | | - <?php } ?> |
209 | | - </tr> |
210 | | - <?php } ?> |
211 | | - |
212 | | - <?php if ($images) { ?> |
213 | | - <tr class="row_details row_images"> |
214 | | - <td></td> |
215 | | - <td class="cell_label">Images:</td> |
216 | | - <td class="cell_broader" colspan="<?php $b_row ? 5 : 2 ?>"> |
217 | | - <?php |
218 | | - $gallery = $utils->getImagesAbout($a_reference_id, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages ); |
219 | | - $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" ); |
220 | | - ?> |
221 | | - </td> |
222 | | - </tr> |
223 | | - <?php } ?> |
224 | | - |
225 | | - <?php if (isset($a_similar) && !empty($a_similar)) { ?> |
226 | | - <tr class="row_details row_similar"> |
227 | | - <td></td> |
228 | | - <td class="cell_label">Similar:</td> |
229 | | - <td class="cell_similar" colspan="2"><?php printLocalConceptList($a_lang, $a_similar); ?></td> |
230 | | - <?php if ($b_row) { ?> |
231 | | - <td class="cell_label">Similar:</td> |
232 | | - <td class="cell_similar" colspan="2"><?php printLocalConceptList($b_lang, $b_similar); ?></td> |
233 | | - <?php } ?> |
234 | | - </tr> |
235 | | - <?php } ?> |
236 | | - |
237 | | - <?php if (isset($a_related) && !empty($a_related)) { ?> |
238 | | - <tr class="row_details row_related"> |
239 | | - <td></td> |
240 | | - <td class="cell_label">Related:</td> |
241 | | - <td class="cell_related" colspan="2"><?php printLocalConceptList($a_lang, $a_related); ?></td> |
242 | | - <?php if ($b_row) { ?> |
243 | | - <td class="cell_label">Related:</td> |
244 | | - <td class="cell_related" colspan="2"><?php printLocalConceptList($b_lang, $b_related); ?></td> |
245 | | - <?php } ?> |
246 | | - </tr> |
247 | | - <?php } ?> |
248 | | - |
249 | | - <?php if (isset($a_narrower) && !empty($a_narrower)) { ?> |
250 | | - <tr class="row_details row_narrower"> |
251 | | - <td></td> |
252 | | - <td class="cell_label">Narrower:</td> |
253 | | - <td class="cell_narrower" colspan="2"><?php printLocalConceptList($a_lang, $a_narrower); ?></td> |
254 | | - <?php if ($b_row) { ?> |
255 | | - <td class="cell_label">Narrower:</td> |
256 | | - <td class="cell_narrower" colspan="2"><?php printLocalConceptList($b_lang, $b_narrower); ?></td> |
257 | | - <?php } ?> |
258 | | - </tr> |
259 | | - <?php } ?> |
260 | | - |
261 | | - <?php if (isset($a_broader) && !empty($a_broader)) { ?> |
262 | | - <tr class="row_details row_broader"> |
263 | | - <td></td> |
264 | | - <td class="cell_label">Broader:</td> |
265 | | - <td class="cell_broader" colspan="2"><?php printLocalConceptList($a_lang, $a_broader); ?></td> |
266 | | - <?php if ($b_row) { ?> |
267 | | - <td class="cell_label">Broader:</td> |
268 | | - <td class="cell_broader" colspan="2"><?php printLocalConceptList($b_lang, $b_broader); ?></td> |
269 | | - <?php } ?> |
270 | | - </tr> |
271 | | - <?php } ?> |
272 | | - |
273 | | - <?php |
274 | | - if (isset($a_weight) && $a_weight && $a_weight<2 && $pos>=3) return false; |
275 | | - else return true; |
276 | | -} |
277 | | - |
278 | | -$concept = @$_REQUEST['id']; |
279 | | -$term = @$_REQUEST['term']; |
280 | | -$lang = @$_REQUEST['lang']; |
281 | | -$tolang = @$_REQUEST['tolang']; |
282 | | -$images = (@$_REQUEST['images'] || $wwImageSearch === true ) && !($wwImageSearch === false); |
283 | | - |
284 | | -if (!isset($_REQUEST['translate'])) $tolang = NULL; |
285 | | -if ($lang == $tolang) $tolang = NULL; |
286 | | - |
287 | | -if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"]; |
288 | | - |
289 | | -$error = NULL; |
290 | | - |
291 | | -if ($lang && !isset($wwLanguages[$lang])) { |
292 | | - $lang = NULL; |
293 | | - $error = "bad language code: $lang"; |
294 | | -} |
295 | | - |
296 | | -if ($wwAPI) $thesaurus = new WWClient($wwAPI); |
297 | | -else { |
298 | | - $thesaurus = new WWThesaurus(); |
299 | | - $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
300 | | -} |
301 | | - |
302 | | -$utils = new WWImages( $thesaurus ); |
303 | | -if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
304 | | - |
305 | | -if (@$_REQUEST['debug']) $utils->debug = true; |
306 | | - |
307 | | -$limit = 20; |
308 | | - |
309 | | -$result = NULL; |
310 | | - |
311 | | -if (!$error) { |
312 | | - try { |
313 | | - if ($lang && $concept) { |
314 | | - $result = $thesaurus->getConceptInfo($concept, $lang); |
315 | | - if ( $result ) $result = array( $result ); //hack |
316 | | - } else if ($lang && $term) { |
317 | | - $result = $thesaurus->getConceptsForTerm($lang, $term, $limit); |
318 | | - } |
319 | | - } catch (Exception $e) { |
320 | | - $error = $e->getMessage(); |
321 | | - } |
322 | | -} |
323 | | - |
324 | | - |
325 | | -?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
326 | | -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
327 | | -<head> |
328 | | - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
329 | | - <title>WikiWord Navigator</title> |
330 | | - |
331 | | - <style type="text/css"> |
332 | | - body { font-family: verdana, helvetica, arial, sans-serif; } |
333 | | - td { text-align: left; vertical-align: top; } |
334 | | - th { text-align: left; vertical-align: top; font-weight:bold; } |
335 | | - .error { color: red; font-weight: bold; } |
336 | | - .weight_huge { font-size: 140%; font-weight:bold; } |
337 | | - .weight_big { font-size: 120%; font-weight:bold; } |
338 | | - .weight_normal { font-size: 110%; font-weight:bold; } |
339 | | - .weight_some { font-size: 100%; font-weight:bold; } |
340 | | - .weight_little { font-size: 90%; font-weight:bold; } |
341 | | - .weight_unknown { font-size: 100%; font-weight:bold; } |
342 | | - .row_def td { font-size: 80%; font-style:italic; } |
343 | | - .row_details td { font-size: 80%; } |
344 | | - .cell_weight { text-align: right; } |
345 | | - .cell_label { text-align: right; } |
346 | | - .header { text-align: left; } |
347 | | - .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; } |
348 | | - .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; } |
349 | | - .note { font-size:80%; } |
350 | | - .terselist, .terselist li { display: inline; margin:0; padding:0; } |
351 | | - .terselist li { display: inline; } |
352 | | - .terselist li:before { content:" - " } |
353 | | - .terselist li:first-child:before { content:"" } |
354 | | - |
355 | | - .gallery li { display: inline; padding:0.5ex; margin:0.5ex; } |
356 | | - </style> |
357 | | -</head> |
358 | | -<body> |
359 | | - <div class="header"> |
360 | | - <h1>WikiWord Navigator</h1> |
361 | | - <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p> |
362 | | - <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>. |
363 | | - It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p> |
364 | | - </div> |
365 | | - |
366 | | - <div class="inputform" > |
367 | | - <form name="search" action="<?php print $wwSelf; ?>"> |
368 | | - <table border="0" class="inputgrid"> |
369 | | - <tr> |
370 | | - <td> |
371 | | - <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/> |
372 | | - </td> |
373 | | - <td> |
374 | | - <label for="term" style="display:none">Language: </label> |
375 | | - <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?> |
376 | | - </td> |
377 | | - <td> |
378 | | - <input type="submit" name="go" value="go"/> |
379 | | - </td> |
380 | | - <?php if ($wwImageSearch === null) { ?> |
381 | | - <td> |
382 | | - <label for="images">Images: </label> |
383 | | - <input type="checkbox" name="images" value="Images" <?php print $images ? " checked=\"checked\"" : ""?>/> |
384 | | - </td> |
385 | | - <?php } ?> |
386 | | - </tr> |
387 | | - <?php if ($wwAllowTranslate) { ?> |
388 | | - <tr> |
389 | | - <td> |
390 | | - |
391 | | - </td> |
392 | | - <td> |
393 | | - <label for="term" style="display:none">Translate: </label> |
394 | | - <?php WWUtils::printSelector("tolang", $wwLanguages, @$_REQUEST['tolang']) ?> |
395 | | - </td> |
396 | | - <td> |
397 | | - <input type="submit" name="translate" value="translate"/> |
398 | | - </td> |
399 | | - </tr> |
400 | | - <?php } ?> |
401 | | - </table> |
402 | | - <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered, matching is case-sensitive.</p> |
403 | | - </form> |
404 | | - </div> |
405 | | -<?php |
406 | | -if ($error) { |
407 | | - print "<p class=\"error\">".htmlspecialchars($error)."</p>"; |
408 | | -} |
409 | | -?> |
410 | | - |
411 | | -<?php |
412 | | -if ($result && $concept) { |
413 | | - foreach ( $result as $row ) { |
414 | | - if (@$row['id']) $id = $row['id']; |
415 | | - else if (@$row['concept']) $id = $row['concept']; |
416 | | - else $id = "concept"; |
417 | | - |
418 | | -?> |
419 | | - <div id="<?php print htmlspecialchars("concept-$id")?>"> |
420 | | - |
421 | | - <table border="0" class="results"> |
422 | | - <?php |
423 | | - if ($lang) { |
424 | | - $continue= printLocalConcept($lang, $row, NULL, NULL, 0, false); |
425 | | - } |
426 | | - //else $continue= printGlobalConcept($lang, $row, $count); |
427 | | - |
428 | | - if (!$continue) break; |
429 | | - ?> |
430 | | - </table> |
431 | | - </div> |
432 | | - |
433 | | -<?php |
434 | | - } #concept loop |
435 | | -} else if ($result && $term) { |
436 | | - if ($tolang) $title = "$lang: $term -> $tolang"; |
437 | | - else if ($term) $title = "$lang: $term"; |
438 | | -?> |
439 | | - <h2><?php print htmlspecialchars($title); ?></h2> |
440 | | - <table border="0" class="results"> |
441 | | - <?php |
442 | | - $count = 0; |
443 | | - foreach ( $result as $row ) { |
444 | | - $count += 1; |
445 | | - |
446 | | - if ($lang) { |
447 | | - $show_single = true; |
448 | | - |
449 | | - if ($tolang && isset($row['global_concept'])) { |
450 | | - $toresult = $utils->queryConceptInfo($row['global_concept'], $tolang); |
451 | | - while ($torow = mysql_fetch_assoc($toresult)) { |
452 | | - $continue= printLocalConcept($lang, $row, $tolang, $torow, $count, true); |
453 | | - $show_single = false; |
454 | | - } |
455 | | - mysql_free_result($toresult); |
456 | | - } |
457 | | - |
458 | | - if ($show_single) { |
459 | | - $continue= printLocalConcept($lang, $row, NULL, NULL, $count, true); |
460 | | - } |
461 | | - } |
462 | | - //else $continue= printGlobalConcept($lang, $row, $count); |
463 | | - |
464 | | - if (!$continue) break; |
465 | | - } |
466 | | - ?> |
467 | | - </table> |
468 | | - |
469 | | - <p>Found <?php print $count; ?> items.</p> |
470 | | - |
471 | | -<?php |
472 | | -} |
473 | | -?> |
474 | | - |
475 | | -<p class="footer"> |
476 | | -The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a> |
477 | | -<p> |
478 | | -</body> |
479 | | -</html> |
480 | | -<?php |
481 | | -$utils->close(); |
482 | | -?> |
\ No newline at end of file |
Index: trunk/WikiWord/WikiWord/src/main/php/wwthesaurus.php |
— | — | @@ -1,498 +0,0 @@ |
2 | | -<?php |
3 | | -require_once(dirname(__FILE__)."/wwutils.php"); |
4 | | - |
5 | | - /** Unknown type, SHOULD not occurr in final data. MAY be used for |
6 | | - * resources that are referenced but where not available for analysis, |
7 | | - * or have not yet been analyzed. |
8 | | - **/ |
9 | | - define('WW_RC_TYPE_UNKNOWN', 0); |
10 | | - |
11 | | - /** |
12 | | - * A "real" page, describing a concept. |
13 | | - */ |
14 | | - define('WW_RC_TYPE_ARTICLE', 10); |
15 | | - |
16 | | - /** |
17 | | - * This page is a supplemental part of an article, typically a transcluded |
18 | | - * subpage or simmilar. |
19 | | - */ |
20 | | - define('WW_RC_TYPE_SUPPLEMENT', 15); |
21 | | - |
22 | | - |
23 | | - /** |
24 | | - * A page solely defining a redirect/alias for another page |
25 | | - */ |
26 | | - define('WW_RC_TYPE_REDIRECT', 20); |
27 | | - |
28 | | - /** |
29 | | - * A disambuguation page, listing different meanings for the page title, |
30 | | - * each linking to a article page. |
31 | | - */ |
32 | | - define('WW_RC_TYPE_DISAMBIG', 30); |
33 | | - |
34 | | - /** |
35 | | - * A page that contains a list of concepts that share some common property or quality, |
36 | | - * usually each linking to a page describing that concept. |
37 | | - */ |
38 | | - define('WW_RC_TYPE_LIST', 40); |
39 | | - |
40 | | - /** |
41 | | - * A category page. |
42 | | - */ |
43 | | - define('WW_RC_TYPE_CATEGORY', 50); |
44 | | - |
45 | | - /** |
46 | | - * This page does not contain relevant information for WikiWord |
47 | | - */ |
48 | | - define('WW_RC_TYPE_OTHER', 99); |
49 | | - |
50 | | - /** |
51 | | - * A page that is broken in some way, or was marked as bad or disputed. Such pages |
52 | | - * SHOULD generally be treated as if theys didn't exist. |
53 | | - */ |
54 | | - define('WW_RC_TYPE_BAD', 100); |
55 | | - |
56 | | - /** |
57 | | - * A resource that is not a page by itself, but merely a section of a page. Sections |
58 | | - * SHOULD always be part of a page of type ARTICLE, and are expected to descibe |
59 | | - * a narrower concept than the "parent" page. |
60 | | - */ |
61 | | - define('WW_RC_TYPE_SECTION', 200); |
62 | | - |
63 | | - |
64 | | -class WWThesaurus extends WWUTils { |
65 | | - |
66 | | - function normalizeSearchString( $s, $norm = 1 ) { |
67 | | - if ( $norm >= 1 ) $s = mb_strtolower($s, "utf-8"); |
68 | | - if ( $norm >= 1 ) $s = str_replace("-", "", $s); |
69 | | - |
70 | | - #TODO: 2: whitespace and punctuation |
71 | | - #TODO: 3: translit |
72 | | - |
73 | | - return $s; |
74 | | - } |
75 | | - |
76 | | - function queryConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) { |
77 | | - global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages; |
78 | | - |
79 | | - if ( !$languages ) $languages = array_keys( $wwLanguages ); |
80 | | - |
81 | | - $term = $this->normalizeSearchString($term, $norm); |
82 | | - |
83 | | - $sql = "SELECT I.*, S.score FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as I" |
84 | | - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_search_index as S ON I.concept = S.concept " |
85 | | - . " WHERE term = " . $this->quote($term) |
86 | | - . " AND I.lang IN " . $this->quoteSet($languages) |
87 | | - . " AND S.lang = " . $this->quote($qlang) |
88 | | - . " AND S.norm <= " . (int)$norm |
89 | | - . " ORDER BY S.score DESC, S.concept " |
90 | | - . " LIMIT " . (int)$limit; |
91 | | - |
92 | | - #FIXME: query-lang vs. output-languages! |
93 | | - |
94 | | - return $this->query($sql); |
95 | | - } |
96 | | - |
97 | | - function getConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) { |
98 | | - $rs = $this->queryConceptsForTerm($qlang, $term, $languages); |
99 | | - $list = WWUtils::slurpRows($rs); |
100 | | - mysql_free_result($rs); |
101 | | - return $this->buildConcepts($list); |
102 | | - } |
103 | | - |
104 | | - function getPagesForConcept( $id, $lang = null ) { |
105 | | - $p = $this->getConceptInfo( $id, $lang ); |
106 | | - return $p['pages']; |
107 | | - } |
108 | | - |
109 | | - /* |
110 | | - function queryConceptsForPage($lang, $page, $limit = 100) { |
111 | | - global $wwTablePrefix, $wwThesaurusDataset; |
112 | | - |
113 | | - $page = trim($page); |
114 | | - |
115 | | - $sql = "SELECT O.global_concept as id, O.* FROM {$wwTablePrefix}_{$lang}_resource as R " |
116 | | - . " JOIN {$wwTablePrefix}_{$lang}_about as A ON A.resource = R.id " |
117 | | - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND A.concept = O.local_concept " |
118 | | - . " WHERE R.name = \"" . mysql_real_escape_string($page) . "\"" |
119 | | - . " LIMIT " . (int)$limit; |
120 | | - |
121 | | - return $this->query($sql); |
122 | | - } |
123 | | - |
124 | | - function getConceptsForPage($lang, $page, $limit = 100) { |
125 | | - $rs = $this->queryConceptsForPage($lang, $page); |
126 | | - $list = WWUtils::slurpRows($rs); |
127 | | - mysql_free_result($rs); |
128 | | - return $list; |
129 | | - } |
130 | | - |
131 | | - function queryLocalConcepts($id) { |
132 | | - global $wwTablePrefix, $wwThesaurusDataset; |
133 | | - $sql = "SELECT O.lang, O.local_concept_name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O "; |
134 | | - $sql .= " WHERE O.global_concept = " . (int)$id; |
135 | | - |
136 | | - return $this->query($sql); |
137 | | - } |
138 | | - |
139 | | - function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat |
140 | | - return getPagesForConcept($id); |
141 | | - } */ |
142 | | - |
143 | | - /* |
144 | | - function queryLocalConceptInfo($lang, $id) { |
145 | | - global $wwTablePrefix, $wwThesaurusDataset; |
146 | | - |
147 | | - $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$lang}_concept_info as F " |
148 | | - . " JOIN {$wwTablePrefix}_{$lang}_concept as C ON F.concept = C.id " |
149 | | - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND F.concept = O.local_concept " |
150 | | - . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON F.concept = D.concept " |
151 | | - . " WHERE O.local_concept = $id "; |
152 | | - |
153 | | - return $this->query($sql); |
154 | | - } |
155 | | - |
156 | | - function queryConceptInfo($id, $lang) { |
157 | | - global $wwTablePrefix, $wwThesaurusDataset; |
158 | | - |
159 | | - $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O " |
160 | | - . " LEFT JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as F ON O.global_concept = F.concept " |
161 | | - . " LEFT JOIN {$wwTablePrefix}_{$lang}_concept as C ON O.local_concept = C.id " |
162 | | - . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON O.local_concept = D.concept " |
163 | | - . " WHERE O.global_concept = $id AND O.lang = \"" . mysql_real_escape_string($lang) . "\" "; |
164 | | - |
165 | | - return $this->query($sql); |
166 | | - }*/ |
167 | | - |
168 | | - /*function getConceptInfo( $id, $lang = null ) { |
169 | | - $result = $this->getConcept($id, $lang); |
170 | | - |
171 | | - $result['broader'] = $this->getBroaderForConcept($id); |
172 | | - $result['narrower'] = $this->getNarrowerForConcept($id); |
173 | | - $result['related'] = $this->getRelatedForConcept($id); |
174 | | - |
175 | | - if ( $lang ) { |
176 | | - $d = $this->getDefinitionForConcept($id); |
177 | | - $result['related'] = $d[$lang]; |
178 | | - } |
179 | | - |
180 | | - return $result; |
181 | | - }*/ |
182 | | - |
183 | | - /* |
184 | | - function unpickle($s, $lang, $hasId=true, $hasName=true, $hasConf=true) { |
185 | | - $ss = explode("\x1E", $s); |
186 | | - $items = array(); |
187 | | - |
188 | | - $fetchNames = false; |
189 | | - |
190 | | - foreach ($ss as $i) { |
191 | | - $r = explode("\x1F", $i); |
192 | | - $offs = -1; |
193 | | - |
194 | | - if ($hasId) $r['id'] = @$r[$offs += 1]; |
195 | | - if ($hasName) $r['name'] = @$r[$offs += 1]; |
196 | | - if ($hasConf) $r['conf'] = @$r[$offs += 1]; |
197 | | - |
198 | | - if ($hasId && !isset($r['name'])) |
199 | | - $fetchNames = true; |
200 | | - |
201 | | - if ($hasId) $items[ $r['id'] ] = $r; |
202 | | - else $items[] = $r; |
203 | | - } |
204 | | - |
205 | | - if ($fetchNames) { |
206 | | - $names = $this->fetchNames(array_keys($items), $lang); |
207 | | - |
208 | | - $keys = array_keys($items); |
209 | | - foreach ($keys as $k) { |
210 | | - $id = $items[$k]['id']; |
211 | | - $items[$k]['name'] = $names[$id]; |
212 | | - } |
213 | | - } |
214 | | - |
215 | | - return $items; |
216 | | - } |
217 | | - |
218 | | - function fetchNames($ids, $lang) { |
219 | | - global $wwTablePrefix, $wwThesaurusDataset; |
220 | | - |
221 | | - $names = array(); |
222 | | - if (!$ids) return $names; |
223 | | - |
224 | | - $set = NULL; |
225 | | - foreach ($ids as $id) { |
226 | | - if ($set===NULL) $set = ""; |
227 | | - else $set .= ", "; |
228 | | - $set .= $id; |
229 | | - } |
230 | | - |
231 | | - $sql = "select global_concept as id, local_concept_name as name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin "; |
232 | | - $sql .= "where global_concept in ($set) and lang = \"" . mysql_real_escape_string($lang) . "\" "; |
233 | | - |
234 | | - $res = $this->query($sql); |
235 | | - |
236 | | - while ($row = mysql_fetch_assoc($res)) { |
237 | | - $id = $row['id']; |
238 | | - $names[$id] = $row['name']; |
239 | | - } |
240 | | - |
241 | | - mysql_free_result($res); |
242 | | - |
243 | | - return $names; |
244 | | - } |
245 | | - */ |
246 | | - |
247 | | - function splitPages( $s ) { |
248 | | - $pp = explode("|", $s); |
249 | | - |
250 | | - $pages = array(); |
251 | | - foreach ($pp as $p) { |
252 | | - list($t, $n) = explode(":", $p, 2); |
253 | | - $pages[$n] = (int)$t; |
254 | | - } |
255 | | - |
256 | | - return $pages; |
257 | | - } |
258 | | - |
259 | | - function splitConcepts( $s ) { |
260 | | - $ss = explode("|", $s); |
261 | | - |
262 | | - $concepts = array(); |
263 | | - foreach ($ss as $p) { |
264 | | - list($id, $n) = explode(":", $p, 2); |
265 | | - $id = (int)$id; |
266 | | - $concepts[$id] = $n; |
267 | | - } |
268 | | - |
269 | | - return $concepts; |
270 | | - } |
271 | | - |
272 | | - ///////////////////////////////////////////////////////// |
273 | | - function getConceptInfo( $id, $lang = null, $fields = null ) { |
274 | | - global $wwTablePrefix, $wwThesaurusDataset; |
275 | | - |
276 | | - #TODO: concept cache! |
277 | | - |
278 | | - if ( $fields && is_array($fields)) $fields = implode(", ", $fields); |
279 | | - if ( !$fields ) $fields = "*"; |
280 | | - |
281 | | - #TODO: scores, concept-type, ... |
282 | | - |
283 | | - $sql = "SELECT $fields FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info " |
284 | | - . " WHERE concept = ".(int)$id; |
285 | | - |
286 | | - if ($lang) { |
287 | | - if ( is_array($lang) ) $sql .= " AND lang IN " . $this->quoteSet($lang); |
288 | | - else $sql .= " AND lang = " . $this->quote($lang); |
289 | | - } |
290 | | - |
291 | | - $r = $this->getRows($sql); |
292 | | - if (!$r) return false; |
293 | | - |
294 | | - return $this->buildConcept($r); |
295 | | - } |
296 | | - |
297 | | - function buildConcepts($rows) { |
298 | | - $concepts = array(); |
299 | | - $buff = array(); |
300 | | - $id = null; |
301 | | - foreach($rows as $row) { |
302 | | - if ( $id !== null && $id != $row['concept'] ) { |
303 | | - if ($buff) { |
304 | | - $concepts[$id] = $this->buildConcept($buff); |
305 | | - $buff = array(); |
306 | | - } |
307 | | - |
308 | | - $id = null; |
309 | | - $score = null; |
310 | | - } |
311 | | - |
312 | | - if ($id === null) { |
313 | | - $id = (int)$row['concept']; |
314 | | - } |
315 | | - |
316 | | - $buff[] = $row; |
317 | | - } |
318 | | - |
319 | | - usort($concepts, array('WWThesaurus', 'byScore')); |
320 | | - return $concepts; |
321 | | - } |
322 | | - |
323 | | - function byScore( $a, $b ) { |
324 | | - if ( isset($a['score']) && isset($b['score']) ) return $b['score'] - $a['score']; |
325 | | - if ( isset($a['conf']) && isset($b['conf']) ) return $b['conf'] - $a['conf']; |
326 | | - if ( isset($a['freq']) && isset($b['freq']) ) return $b['freq'] - $a['freq']; |
327 | | - if ( isset($a['id']) && isset($b['id']) ) return $a['id'] - $b['id']; |
328 | | - return 0; |
329 | | - } |
330 | | - |
331 | | - function buildConcept($rows) { |
332 | | - $concept = array(); |
333 | | - $concept["languages"] = array(); |
334 | | - |
335 | | - $broader = array(); |
336 | | - $narrower = array(); |
337 | | - $similar = array(); |
338 | | - $related = array(); |
339 | | - |
340 | | - foreach ($rows as $row) { |
341 | | - if (!isset($concept["id"]) && isset($row["concept"])) $concept["id"] = (int)$row["concept"]; |
342 | | - if (!isset($concept["score"]) && isset($row["score"])) $concept["score"] = (int)$row["score"]; |
343 | | - |
344 | | - $lang = $row["lang"]; |
345 | | - $concept["languages"][] = $lang; |
346 | | - |
347 | | - #TODO: scores, concept-type, ... |
348 | | - |
349 | | - if (@$row["name"] !== null) $concept["name"][$lang] = $row["name"]; |
350 | | - if (@$row["definition"] !== null) $concept["definition"][$lang] = $row["definition"]; |
351 | | - if (@$row["pages"] !== null) $concept["pages"][$lang] = $this->splitPages($row["pages"]); |
352 | | - |
353 | | - if (@$row["broader"] !== null) $broader[$lang] = $this->splitConcepts($row["broader"]); |
354 | | - if (@$row["narrower"] !== null) $narrower[$lang] = $this->splitConcepts($row["narrower"]); |
355 | | - if (@$row["similar"] !== null) $similar[$lang] = $this->splitConcepts($row["similar"]); |
356 | | - if (@$row["related"] !== null) $related[$lang] = $this->splitConcepts($row["related"]); |
357 | | - } |
358 | | - |
359 | | - $concept["broader"] = $this->mogrifyLocalInfo($broader); |
360 | | - $concept["narrower"] = $this->mogrifyLocalInfo($narrower); |
361 | | - $concept["similar"] = $this->mogrifyLocalInfo($similar); |
362 | | - $concept["related"] = $this->mogrifyLocalInfo($related); |
363 | | - |
364 | | - return $concept; |
365 | | - } |
366 | | - |
367 | | - function mogrifyLocalInfo( $byLanguage ) { |
368 | | - $byId = array(); |
369 | | - |
370 | | - foreach ( $byLanguage as $lang => $items ) { |
371 | | - foreach ( $items as $id => $name ) { |
372 | | - $byId[$id][$lang] = $name; |
373 | | - } |
374 | | - } |
375 | | - |
376 | | - return $byId; |
377 | | - } |
378 | | - |
379 | | - /* |
380 | | - function getConcept( $id, $lang = null, $limit = 100 ) { |
381 | | - return $this->getConceptInfo($id, $lang); |
382 | | - } |
383 | | - |
384 | | - function getRelatedForConcept( $id, $lang = null, $limit = 100 ) { |
385 | | - $concept = $this->getConceptInfo($id, $lang, "lang, related"); |
386 | | - if (!$concept) return false; |
387 | | - else if ($lang) return $concept["related"][$lang]; |
388 | | - else return $concept["related"]; |
389 | | - } |
390 | | - |
391 | | - function getBroaderForConcept( $id, $lang = null, $limit = 100 ) { |
392 | | - $concept = $this->getConceptInfo($id, $lang, "lang, broader"); |
393 | | - if (!$concept) return false; |
394 | | - else if ($lang) return $concept["broader"][$lang]; |
395 | | - else return $concept["broader"]; |
396 | | - } |
397 | | - |
398 | | - function getNarrowerForConcept( $id, $lang = null, $limit = 100 ) { |
399 | | - $concept = $this->getConceptInfo($id, $lang, "lang, narrower"); |
400 | | - if (!$concept) return false; |
401 | | - else if ($lang) return $concept["narrower"][$lang]; |
402 | | - else return $concept["narrower"]; |
403 | | - } |
404 | | - |
405 | | - function getPagesForConcept( $id, $lang = null, $limit = 100 ) { |
406 | | - if (!$lang) return false; |
407 | | - |
408 | | - $concept = $this->getConceptInfo($id, $lang, "lang, pages"); |
409 | | - if (!$concept) return false; |
410 | | - else if ($lang) return array_keys( $concept["pages"][$lang] ); |
411 | | - } |
412 | | - |
413 | | - function getNamesForConcept( $id, $lang = null ) { |
414 | | - $concept = $this->getConceptInfo($id, $lang, "lang, name"); |
415 | | - if (!$concept) return false; |
416 | | - |
417 | | - $result = array(); |
418 | | - foreach ($concept["languages"] as $ll) { |
419 | | - if (@$concept["name@$ll"]) |
420 | | - $result[$ll] = $concept["name@$ll"]; |
421 | | - } |
422 | | - |
423 | | - return $result; |
424 | | - } |
425 | | - |
426 | | - function getDefinitionForConcept( $id, $lang = null, $limit = 100 ) { |
427 | | - $concept = $this->getConceptInfo($id, $lang, "lang, definition"); |
428 | | - if (!$concept) return false; |
429 | | - |
430 | | - $result = array(); |
431 | | - foreach ($concept["languages"] as $ll) { |
432 | | - if (@$concept["definition@$ll"]) |
433 | | - $result[$ll] = $concept["definition@$ll"]; |
434 | | - } |
435 | | - |
436 | | - return $result; |
437 | | - }*/ |
438 | | - |
439 | | - function getTermsForConcept( $id, $lang = null, $limit = 100 ) { |
440 | | - global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages; |
441 | | - |
442 | | - if ( !$lang ) $lang = array_keys( $wwLanguages ); |
443 | | - if ( !is_array($lang) ) $lang = preg_split('![\\s,;|/:]\\s*!', $lang); |
444 | | - $result = array(); |
445 | | - |
446 | | - foreach ($lang as $ll) { |
447 | | - $sql = "SELECT M.term_text FROM {$wwTablePrefix}_{$ll}_meaning as M" |
448 | | - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($ll) . "\" AND M.concept = O.local_concept " |
449 | | - . " WHERE O.global_concept = " . (int)$id |
450 | | - . " ORDER BY freq DESC " |
451 | | - . " LIMIT " . (int)$limit; |
452 | | - |
453 | | - $terms = $this->getList($sql, "term_text"); |
454 | | - if ( $terms === false || $terms === null ) return false; |
455 | | - if ( !$terms ) continue; |
456 | | - |
457 | | - $result[$ll] = $terms; |
458 | | - } |
459 | | - |
460 | | - return $result; |
461 | | - } |
462 | | - |
463 | | - /* |
464 | | - function getLinksForConcept( $id, $lang = null, $limit = 100 ) { |
465 | | - global $wwTablePrefix, $wwThesaurusDataset; |
466 | | - |
467 | | - $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C " |
468 | | - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.target = C.id " |
469 | | - . " WHERE L.anchor = ".(int)$id |
470 | | - . " LIMIT " . (int)$limit; |
471 | | - |
472 | | - return $this->getRows($sql); |
473 | | - } |
474 | | - |
475 | | - function getReferencesForConcept( $id, $lang = null, $limit = 100 ) { |
476 | | - global $wwTablePrefix, $wwThesaurusDataset; |
477 | | - |
478 | | - $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C " |
479 | | - . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.anchor = C.id " |
480 | | - . " WHERE L.target = ".(int)$id |
481 | | - . " LIMIT " . (int)$limit; |
482 | | - |
483 | | - return $this->getRows($sql); |
484 | | - } |
485 | | - |
486 | | - function getScoresForConcept( $id, $lang = null ) { |
487 | | - global $wwTablePrefix, $wwThesaurusDataset; |
488 | | - |
489 | | - $sql = "SELECT S.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_stats as S " |
490 | | - . " WHERE S.concept = ".(int)$id |
491 | | - ; |
492 | | - |
493 | | - $r = $this->getRows($sql); |
494 | | - if ( !$r ) return false; |
495 | | - |
496 | | - return $r; |
497 | | - }*/ |
498 | | - |
499 | | -} |
Index: trunk/WikiWord/WikiWord/src/main/php/wwwikis.php |
— | — | @@ -1,72 +0,0 @@ |
2 | | -<?php |
3 | | -require_once(dirname(__FILE__)."/wwutils.php"); |
4 | | - |
5 | | -if (!defined('NS_IMAGE')) |
6 | | - define('NS_IMAGE', 6); |
7 | | - |
8 | | -if (!defined('NS_TEMPLATE')) |
9 | | - define('NS_TEMPLATE', 10); |
10 | | - |
11 | | - |
12 | | -class WWWikis extends WWUtils { |
13 | | - var $wikidbs = array(); |
14 | | - |
15 | | - function getWikiTableName($lang, $table) { |
16 | | - global $wwWikitableNamePattern, $wwCommonsTablePrefix; |
17 | | - |
18 | | - if ( $lang == "commons" && $wwCommonsTablePrefix ) return "$wwCommonsTablePrefix$table"; |
19 | | - |
20 | | - if ($wwWikitableNamePattern) { |
21 | | - return str_replace(array('{lang}', '{name}'), array($lang, $table), $wwWikitableNamePattern); |
22 | | - } |
23 | | - |
24 | | - return $table; |
25 | | - } |
26 | | - |
27 | | - function getWikiInfo($lang) { |
28 | | - global $wwWikiInfoTable, $wwWikiDbName, $wwWikiServerName, $wwCommonsServerName; |
29 | | - |
30 | | - $db = str_replace('{lang}', $lang, $wwWikiDbName); |
31 | | - |
32 | | - $dbname = "{$lang}wiki_p"; |
33 | | - $sql = "select * from $wwWikiInfoTable "; |
34 | | - $sql .= " where dbname = " . $this->quote("$db"); |
35 | | - |
36 | | - $rs = $this->query($sql); |
37 | | - $info = mysql_fetch_assoc($rs); |
38 | | - mysql_free_result($rs); |
39 | | - |
40 | | - if (!$info) $info = false; |
41 | | - else $info['server'] = str_replace('{num}', $info['server'], $wwWikiServerName); |
42 | | - |
43 | | - if ($lang == "commons" && $wwCommonsServerName) $info['server'] = $wwCommonsServerName; |
44 | | - |
45 | | - return $info; |
46 | | - } |
47 | | - |
48 | | - function getWikiConnection($lang) { |
49 | | - if (isset($this->wikidbs[$lang])) return $this->wikidbs[$lang]; |
50 | | - |
51 | | - $info = $this->getWikiInfo($lang); |
52 | | - |
53 | | - if (!$info) { |
54 | | - $db = false; |
55 | | - } else { |
56 | | - $db = mysql_connect($info['server'], $this->dbuser, $this->dbpassword); |
57 | | - if (!$db) throw new Exception("Connection Failure to Database: " . mysql_error()); |
58 | | - if (!mysql_select_db($info['dbname'], $db)) throw new Exception ("Database not found: " . mysql_error()); |
59 | | - if (!mysql_query("SET NAMES Latin1;", $db)) throw new Exception ("Database not found: " . mysql_error()); |
60 | | - } |
61 | | - |
62 | | - $this->wikidbs[$lang] = $db; |
63 | | - return $db; |
64 | | - } |
65 | | - |
66 | | - function queryWiki($lang, $sql) { |
67 | | - $db = $this->getWikiConnection($lang); |
68 | | - if (!$db) throw new Exception ("Wiki not found: $lang"); |
69 | | - |
70 | | - return $this->query($sql, $db); |
71 | | - } |
72 | | - |
73 | | -} |
Index: trunk/WikiWord/WikiWord/src/main/php/api.php |
— | — | @@ -1,140 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -$IP = dirname(__FILE__); |
5 | | - |
6 | | -require_once("$IP/config.php"); |
7 | | -require_once("$IP/wwthesaurus.php"); |
8 | | - |
9 | | -$query = @$_REQUEST['query']; |
10 | | - |
11 | | -if ( $query ) { |
12 | | - $lang = @$_REQUEST['lang']; |
13 | | - $qlang = @$_REQUEST['qlang']; |
14 | | - $format = @$_REQUEST['format']; |
15 | | - if ( !$format ) $format = 'phps'; |
16 | | - |
17 | | - if ($lang) $lang = preg_replace('[^\\w\\d_]', '', $lang); |
18 | | - if ($qlang) $qlang = preg_replace('[^\\w\\d_]', '', $qlang); |
19 | | - |
20 | | - if ($lang) { |
21 | | - $lang = preg_split('![\\s,;|/:]\\s*!', $lang); |
22 | | - if ( !$qlang ) $qlang = $lang[0]; |
23 | | - if (count($lang) == 1) $lang = $lang[0]; |
24 | | - } |
25 | | - |
26 | | - $result = array( 'query' => $query ); |
27 | | - $start = microtime(true); |
28 | | - |
29 | | - try { |
30 | | - $thesaurus = new WWThesaurus(); |
31 | | - $db = $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
32 | | - |
33 | | - if ( !$db ) { |
34 | | - $result['error'] = array('code' => 1010, 'message' => "failed to connect to thesaurus database"); |
35 | | - } else if ($query == 'concepts') { |
36 | | - $term = @$_REQUEST['term']; |
37 | | - $norm = @$_REQUEST['norm']; |
38 | | - |
39 | | - if ( $norm === null ) $norm = 1; |
40 | | - #$page = @$_REQUEST['page']; |
41 | | - |
42 | | - if ( $qlang === null ) $result['error'] = array('code' => 150, 'message' => "missing parameter qlang"); |
43 | | - else if ( $term !== null ) { |
44 | | - $result['concepts'] = $thesaurus->getConceptsForTerm($qlang, $term, $lang, $norm); #TODO: limit! |
45 | | - if ( $result['concepts'] === false || $result['concepts'] === null ) { |
46 | | - $result['error'] = array('code' => 210, 'message' => "failed to retrieve concepts for term $langt:$term"); |
47 | | - } |
48 | | - } /*else if ( $page !== null ) { |
49 | | - $result['concepts'] = $thesaurus->getConceptsForPage($lang, $page); |
50 | | - if ( $result['concepts'] === false || $result['concepts'] === null ) { |
51 | | - $result['error'] = array('code' => 250, 'message' => "failed to retrieve concepts for page $langt:$page"); |
52 | | - } |
53 | | - } */else { |
54 | | - $result['error'] = array('code' => 110, 'message' => "missing parameter term"); |
55 | | - } |
56 | | - } else if ($query == 'concept' || $query == 'info') { |
57 | | - $gcid = @$_REQUEST['gcid']; |
58 | | - if (!$gcid) $gcid = @$_REQUEST['id']; |
59 | | - |
60 | | - if ( $gcid === null ) { |
61 | | - $result['error'] = array('code' => 120, 'message' => "missing parameter gcid"); |
62 | | - } else { |
63 | | - $result['concept'] = $thesaurus->getConceptInfo($gcid, $lang); #TODO: limit! |
64 | | - if ( $result['concept'] === false || $result['concept'] === null ) { |
65 | | - $result['error'] = array('code' => 210, 'message' => "concept not found: $gcid"); |
66 | | - } |
67 | | - } |
68 | | - } else if ($query == 'properties') { |
69 | | - $gcid = @$_REQUEST['gcid']; |
70 | | - if (!$gcid) $gcid = @$_REQUEST['id']; |
71 | | - |
72 | | - $props = @$_REQUEST['props']; |
73 | | - |
74 | | - if ( $gcid === null ) $result['error'] = array('code' => 120, 'message' => "missing parameter gcid"); |
75 | | - else if ( $props === null ) $result['error'] = array('code' => 130, 'message' => "missing parameter props"); |
76 | | - else { |
77 | | - $props = preg_split('![\\s,;|/:]\\s*!', $props); |
78 | | - |
79 | | - $info = $thesaurus->getConcept($gcid, $lang); |
80 | | - |
81 | | - if ( !$info ) $result['error'] = array('code' => 100, 'message' => "concept not found: $gcid"); |
82 | | - else { |
83 | | - $result = array_merge($result, $info); |
84 | | - |
85 | | - foreach ( $props as $p ) { |
86 | | - $m = "get" . ucfirst($p) . "ForConcept"; |
87 | | - if ( !method_exists($thesaurus, $m) ) { |
88 | | - $result['error'] = array('code' => 190, 'message' => "unknown property: $p"); |
89 | | - break; |
90 | | - } |
91 | | - |
92 | | - $result[$p] = $thesaurus->$m($gcid, $lang); |
93 | | - |
94 | | - if ( $result[$p] === false || $result[$p] === null ) { |
95 | | - $result['error'] = array('code' => 220, 'message' => "failed to retrieve property $p for concept $gcid"); |
96 | | - break; |
97 | | - } |
98 | | - } |
99 | | - |
100 | | - if (!isset($result['id'])) $result['id'] = $gcid; |
101 | | - if (!isset($result['lang'])) $result['lang'] = $lang; |
102 | | - } |
103 | | - } |
104 | | - } else { |
105 | | - $result['error'] = array('code' => 10, 'message' => "bad query: $query"); |
106 | | - } |
107 | | - } catch (Exception $e) { |
108 | | - $result['error'] = array('code' => 1000, 'message' => "unexpected exception: " . $e->getMessage()); |
109 | | - } |
110 | | - |
111 | | - $result['time'] = (microtime(true) - $start) . " sec"; |
112 | | - |
113 | | - if ( isset($result['error']) ) { |
114 | | - #TODO: HTTP error codce would be nice, but causes file_get_contents to swallow the data. |
115 | | - # need to use CURL in client! |
116 | | - #header("Status: 400 Bad Request", true, 400); |
117 | | - } |
118 | | - |
119 | | - #TODO: JSON (+YAML?), WDDX |
120 | | - if ($format == 'phps') { |
121 | | - header("Content-Type: application/vnd.php.serialized"); #as proposed by http://www.alvestrand.no/pipermail/ietf-types/2004-August/001259.html |
122 | | - $data = serialize($result); |
123 | | - echo $data; |
124 | | - } else if ($format == 'php') { |
125 | | - header("Content-Type: text/php; charset=UTF-8"); |
126 | | - var_export($result); |
127 | | - } else if ($format == 'text') { |
128 | | - header("Content-Type: text/plain; charset=UTF-8"); |
129 | | - print_r($result); |
130 | | - } else { |
131 | | - header("Content-Type: text/plain; charset=UTF-8"); |
132 | | - header("Status: 400 Bad Request", true, 400); |
133 | | - echo "Bad format: $format"; |
134 | | - } |
135 | | - |
136 | | - exit(); |
137 | | -} |
138 | | - |
139 | | -header("Content-Type: text/plain; charset=UTF-8"); |
140 | | -?> |
141 | | -WikiWord REST API |
\ No newline at end of file |
Index: trunk/WikiWord/WikiWord/src/main/php/wwutils.php |
— | — | @@ -1,200 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -class WWUtils { |
5 | | - var $debug = false; |
6 | | - var $db = NULL; |
7 | | - |
8 | | - var $dbuser; |
9 | | - var $dbpassword; |
10 | | - |
11 | | - function connect($server, $user, $password, $database) { |
12 | | - $db = mysql_connect($server, $user, $password) or die("Connection Failure to Database: " . htmlspecialchars(mysql_error())."\n"); |
13 | | - mysql_select_db($database, $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n"); |
14 | | - mysql_query("SET NAMES UTF8;", $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n"); |
15 | | - |
16 | | - $this->dbuser = $user; |
17 | | - $this->dbpassword = $password; |
18 | | - $this->db = $db; |
19 | | - |
20 | | - return $db; |
21 | | - } |
22 | | - |
23 | | - function query($sql, $db = NULL) { |
24 | | - if ($db == NULL && isset($this)) $db = $this->db; |
25 | | - |
26 | | - if ($this->debug) { |
27 | | - print "\n<br/>" . htmlspecialchars($sql) . "<br/>\n"; |
28 | | - } |
29 | | - |
30 | | - if (!$db) { |
31 | | - throw new Exception("not connected!"); |
32 | | - } |
33 | | - |
34 | | - $result = mysql_query($sql, $db); |
35 | | - |
36 | | - if(!$result) { |
37 | | - $error = mysql_error($db); |
38 | | - $errno = mysql_errno($db); |
39 | | - throw new Exception("$error (#$errno);\nlast query: $sql"); |
40 | | - } |
41 | | - |
42 | | - return $result; |
43 | | - } |
44 | | - |
45 | | - function quote($s) { |
46 | | - if (is_array($s)) throw new Exception("can't quote arrays, use quoteSet() instead."); |
47 | | - if (is_null($s)) return "NULL"; |
48 | | - |
49 | | - return '"' . mysql_real_escape_string($s) . '"'; |
50 | | - } |
51 | | - |
52 | | - function quoteSet($a) { |
53 | | - if (!$a) throw new Exception("empty set literal not supported by mysql"); |
54 | | - |
55 | | - if ( !is_array($a) ) $a = array( $a ); |
56 | | - |
57 | | - $s = ""; |
58 | | - |
59 | | - foreach ($a as $x) { |
60 | | - if ($s) $s.= ", "; |
61 | | - |
62 | | - if (is_string($x)) $s .= $this->quote($x); |
63 | | - else $s .= $x; |
64 | | - } |
65 | | - |
66 | | - return '(' . $s . ')'; |
67 | | - } |
68 | | - |
69 | | - function close() { |
70 | | - if ($this->db) mysql_close($this->db); |
71 | | - $this->db = NULL; |
72 | | - |
73 | | - foreach ($this->wikidbs as $name => $db) { |
74 | | - if ($db) mysql_close($db); |
75 | | - } |
76 | | - |
77 | | - $this->wikidbs = array(); |
78 | | - } |
79 | | - |
80 | | - function getRows($sql, $key = NULL) { |
81 | | - $rs = $this->query($sql); |
82 | | - $list = WWUtils::slurpRows($rs, $key); |
83 | | - mysql_free_result($rs); |
84 | | - return $list; |
85 | | - } |
86 | | - |
87 | | - function getList($sql, $valueField, $key = NULL) { |
88 | | - $rs = $this->query($sql); |
89 | | - $list = WWUtils::slurpList($rs, $valueField, $key); |
90 | | - mysql_free_result($rs); |
91 | | - return $list; |
92 | | - } |
93 | | - |
94 | | - static function slurpList($rs, $field, $key = null) { |
95 | | - if (is_string($rs)) $rs = $this->query($rs); |
96 | | - |
97 | | - $list = array(); |
98 | | - while ($row = mysql_fetch_assoc($rs)) { |
99 | | - if (is_array($field)) { |
100 | | - $value = array(); |
101 | | - foreach ($field as $f) { |
102 | | - $value[$f] = $row[$f]; |
103 | | - } |
104 | | - } else { |
105 | | - $value = $row[$field]; |
106 | | - } |
107 | | - |
108 | | - if ($key) { |
109 | | - $k = $row[$key]; |
110 | | - $list[$k] = $value; |
111 | | - } else { |
112 | | - $list[] = $value; |
113 | | - } |
114 | | - } |
115 | | - |
116 | | - return $list; |
117 | | - } |
118 | | - |
119 | | - static function slurpRows($rs, $key = null) { |
120 | | - if (is_string($rs)) $rs = $this->query($rs); |
121 | | - |
122 | | - $list = array(); |
123 | | - while ($row = mysql_fetch_assoc($rs)) { |
124 | | - if ($key) { |
125 | | - $k = $row[$key]; |
126 | | - $list[$k] = $row; |
127 | | - } else { |
128 | | - $list[] = $row; |
129 | | - } |
130 | | - } |
131 | | - |
132 | | - return $list; |
133 | | - } |
134 | | - |
135 | | - static function slurpAssoc($rs, $keyField, $valueField) { |
136 | | - if (is_string($rs)) $rs = $this->query($rs); |
137 | | - |
138 | | - $list = array(); |
139 | | - while ($row = mysql_fetch_assoc($rs)) { |
140 | | - $key = $row[$keyField]; |
141 | | - |
142 | | - if (is_array($valueField)) { |
143 | | - $value = array(); |
144 | | - foreach ($valueField as $f) { |
145 | | - $value[$f] = $row[$f]; |
146 | | - } |
147 | | - } else { |
148 | | - $value = $row[$valueField]; |
149 | | - } |
150 | | - |
151 | | - $list[$key] = $value; |
152 | | - } |
153 | | - |
154 | | - return $list; |
155 | | - } |
156 | | - |
157 | | - function pickLocal($items, $languages) { |
158 | | - if ( is_string($languages) ) $languages = array( $languages, "en", "commons" ); |
159 | | - |
160 | | - foreach ($languages as $lang) { |
161 | | - if (isset($items[$lang])) return $items[$lang]; |
162 | | - } |
163 | | - |
164 | | - return false; |
165 | | - } |
166 | | - |
167 | | - static function authFailed($realm) { |
168 | | - header("Status: 401 Unauthorized", true, 401); |
169 | | - header('WWW-Authenticate: Basic realm="'.$realm.'"'); |
170 | | - die(); |
171 | | - } |
172 | | - |
173 | | - static function doBasicHttpAuth($passwords, $realm) { |
174 | | - if (!isset($_SERVER['PHP_AUTH_USER'])) { |
175 | | - authFailed(); |
176 | | - } |
177 | | - |
178 | | - $usr = $_SERVER['PHP_AUTH_USER']; |
179 | | - if (!isset($passwords[$usr])) { |
180 | | - authFailed(); |
181 | | - } |
182 | | - |
183 | | - $pw = $_SERVER['PHP_AUTH_PW']; |
184 | | - if ($pw != $passwords[$usr]) { |
185 | | - authFailed(); |
186 | | - } |
187 | | - |
188 | | - return $usr; |
189 | | - } |
190 | | - |
191 | | - static function printSelector($name, $choices, $current = NULL) { |
192 | | - print "\n\t\t<select name=\"".htmlspecialchars($name)."\" id=\"".htmlspecialchars($name)."\">\n"; |
193 | | - |
194 | | - foreach ($choices as $choice => $name) { |
195 | | - $sel = $choice == $current ? " selected=\"selected\"" : ""; |
196 | | - print "\t\t\t<option value=\"".htmlspecialchars($choice)."\"$sel>".htmlspecialchars($name)."</option>\n"; |
197 | | - } |
198 | | - |
199 | | - print "</select>"; |
200 | | - } |
201 | | -} |
Index: trunk/WikiWord/WikiWord/src/main/php/wikipics.php |
— | — | @@ -1,340 +0,0 @@ |
2 | | -<?php |
3 | | - |
4 | | -$IP = dirname(__FILE__); |
5 | | - |
6 | | -require_once("$IP/config.php"); |
7 | | -require_once("$IP/wwimages.php"); |
8 | | - |
9 | | -if ($wwAPI) require_once("$IP/wwclient.php"); |
10 | | -else require_once("$IP/wwthesaurus.php"); |
11 | | - |
12 | | -function printConceptList($concepts, $lang) { |
13 | | - ?> |
14 | | - <ul class="terselist"> |
15 | | - <?php |
16 | | - foreach ($concepts as $c) { |
17 | | - ?><li><?php |
18 | | - print getConceptDetailsLink($lang, $c); |
19 | | - ?></li><?php |
20 | | - } |
21 | | - ?> |
22 | | - </ul> |
23 | | - <?php |
24 | | -} |
25 | | - |
26 | | -function printConceptImageList($concept, $class = "terselist") { |
27 | | - global $utils, $wwThumbSize, $wwMaxPreviewImages; |
28 | | - |
29 | | - if (!$concept) return false; |
30 | | - |
31 | | - if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK |
32 | | - else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages); |
33 | | - |
34 | | - ?> |
35 | | - <ul class="<?php print $class; ?>"> |
36 | | - <?php |
37 | | - foreach ($images as $img) { |
38 | | - ?><li><?php |
39 | | - print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize); |
40 | | - ?></li><?php |
41 | | - } |
42 | | - ?> |
43 | | - </ul> |
44 | | - <?php |
45 | | -} |
46 | | - |
47 | | -function getConceptDetailsURL($langs, $concept) { |
48 | | - global $wwSelf; |
49 | | - |
50 | | - if ( is_array($langs) ) $langs = implode('|', $langs); |
51 | | - |
52 | | - return "$wwSelf?id=" . urlencode($concept['id']) . "&lang=" . urlencode($langs); |
53 | | -} |
54 | | - |
55 | | -function getConceptDetailsLink($langs, $concept) { |
56 | | - global $utils; |
57 | | - $name = $utils->pickLocal($concept['name'], $langs); |
58 | | - |
59 | | - $u = getConceptDetailsURL($langs, $concept); |
60 | | - return '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars($name) . '</a>'; |
61 | | -} |
62 | | - |
63 | | -function pickPage( $pages ) { |
64 | | - if (!$pages) return false; |
65 | | - |
66 | | - foreach ( $pages as $page => $type ) { |
67 | | - if ($type == 10) return $page; |
68 | | - } |
69 | | - |
70 | | - return $pages[0]; |
71 | | -} |
72 | | - |
73 | | -function getConceptPageURLs($lang, $concept) { |
74 | | - if (!isset($concept['pages'][$lang]) || !$concept['pages'][$lang]) return false; |
75 | | - |
76 | | - if ($lang == 'commons') $domain = 'commons.wikimedia.org'; |
77 | | - else $domain = "$lang.wikipedia.org"; |
78 | | - |
79 | | - $urls = array(); |
80 | | - foreach ($concept['pages'][$lang] as $page => $type) { |
81 | | - $u = "http://$domain/wiki/" . urlencode($page); |
82 | | - $links[$page] = $u; |
83 | | - } |
84 | | - |
85 | | - return $urls; |
86 | | -} |
87 | | - |
88 | | -function getConceptPageLinks($lang, $concept) { |
89 | | - $urls = getConceptPageURLs($lang, $concept); |
90 | | - if (!$urls) return false; |
91 | | - |
92 | | - foreach ($urls as $page => $u) { |
93 | | - $u = "http://$domain/wiki/" . urlencode($page); |
94 | | - $links[] = '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars( str_replace("_", " ", $page) ) . '</a>'; |
95 | | - } |
96 | | - |
97 | | - return $links; |
98 | | -} |
99 | | - |
100 | | -function getAllConceptPageLinks($concept) { |
101 | | - $links = array(); |
102 | | - |
103 | | - foreach ( $concept['languages'] as $lang ) { |
104 | | - $ll = getConceptPageLinks($lang, $concept); |
105 | | - if ($ll) $links[$lang] = $ll; |
106 | | - } |
107 | | - |
108 | | - return $links; |
109 | | -} |
110 | | - |
111 | | -function printList($items, $escape = true, $class = "list") { |
112 | | - ?> |
113 | | - <ul class="<?php print htmlspecialchars($class); ?>"> |
114 | | - <?php |
115 | | - foreach ($items as $item) { |
116 | | - if ( $escape ) $item = htmlspecialchars($item); |
117 | | - print "\t\t<li>" . $item . "</li>\n"; |
118 | | - } |
119 | | - ?> |
120 | | - </ul> |
121 | | - <?php |
122 | | -} |
123 | | - |
124 | | -function printDefList($items, $scapeKeys = true, $escapeValues = true, $class = "list") { |
125 | | - ?> |
126 | | - <dl class="<?php print htmlspecialchars($class); ?>"> |
127 | | - <?php |
128 | | - foreach ($items as $key => $item) { |
129 | | - if ( $escapeKeys ) $key = htmlspecialchars($key); |
130 | | - print "\t\t<dt>" . $key . "</dt>\n"; |
131 | | - |
132 | | - if ( $escapeValues ) $item = htmlspecialchars($item); |
133 | | - print "\t\t\t<dd>" . $item . "</dd>\n"; |
134 | | - } |
135 | | - ?> |
136 | | - </sl> |
137 | | - <?php |
138 | | -} |
139 | | - |
140 | | -function getWeightClass($weight) { |
141 | | - if (!isset($weight) || !$weight) { |
142 | | - return "unknown"; |
143 | | - $weight = NULL; |
144 | | - } |
145 | | - else if ($weight>1000) return "huge"; |
146 | | - else if ($weight>100) return "big"; |
147 | | - else if ($weight>10) return "normal"; |
148 | | - else if ($weight>2) return "some"; |
149 | | - else return "little"; |
150 | | -} |
151 | | - |
152 | | -function printConcept($concept, $langs, $terse = true) { |
153 | | - global $utils, $wwMaxPreviewImages, $wwMaxGalleryImages; |
154 | | - |
155 | | - extract( $concept ); |
156 | | - $wclass = getWeightClass($score); |
157 | | - |
158 | | - ?> |
159 | | - <tr class="row_item"> |
160 | | - <td class="cell_weight <?php print "weight_$wclass"; ?>"><?php print htmlspecialchars($score); ?></td> |
161 | | - <td colspan="3" class="cell_name <?php print "weight_$wclass"; ?>"> |
162 | | - <h3> |
163 | | - <?php print getConceptDetailsLink($langs, $concept); ?> |
164 | | - <?php /* TODO: wiki links */ ?> |
165 | | - </h3> |
166 | | - </td> |
167 | | - </tr> |
168 | | - |
169 | | - <?php if (isset($definition) && !empty($definition)) { |
170 | | - $definition = $utils->pickLocal($definition, $langs); |
171 | | - ?> |
172 | | - |
173 | | - <tr class="row_def"> |
174 | | - <td></td> |
175 | | - <td colspan="3"><?php print htmlspecialchars($definition); ?></td> |
176 | | - </tr> |
177 | | - <?php } ?> |
178 | | - |
179 | | - <tr class="row_details row_images"> |
180 | | - <td></td> |
181 | | - <td class="cell_images" colspan="3"> |
182 | | - <?php |
183 | | - $gallery = $utils->getImagesAbout($concept, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages ); |
184 | | - $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" ); |
185 | | - ?> |
186 | | - </td> |
187 | | - </tr> |
188 | | - |
189 | | - |
190 | | - <?php |
191 | | - if (isset($score) && $score && $score<2 && $pos>=3) return false; |
192 | | - else return true; |
193 | | -} |
194 | | - |
195 | | -$conceptId = @$_REQUEST['id']; |
196 | | -$term = @$_REQUEST['term']; |
197 | | -$lang = @$_REQUEST['lang']; |
198 | | - |
199 | | -if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"]; |
200 | | - |
201 | | -$error = NULL; |
202 | | - |
203 | | -if ($lang && !isset($wwLanguages[$lang])) { |
204 | | - $lang = NULL; |
205 | | - $error = "bad language code: $lang"; |
206 | | -} |
207 | | - |
208 | | -if ($wwAPI) $thesaurus = new WWClient($wwAPI); |
209 | | -else { |
210 | | - $thesaurus = new WWThesaurus(); |
211 | | - $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
212 | | -} |
213 | | - |
214 | | -$utils = new WWImages( $thesaurus ); |
215 | | -if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
216 | | - |
217 | | -if (@$_REQUEST['debug']) $utils->debug = true; |
218 | | - |
219 | | -$limit = 20; |
220 | | -$norm = 1; |
221 | | - |
222 | | -$result = NULL; |
223 | | - |
224 | | -$languages = array( $lang, "en", "commons" ); #TODO: make the user define this list |
225 | | - |
226 | | -if (!$error) { |
227 | | - try { |
228 | | - if ($lang && $conceptId) { |
229 | | - $result = $thesaurus->getConceptInfo($conceptId, $lang); |
230 | | - if ( $result ) $result = array( $result ); //hack |
231 | | - } else if ($lang && $term) { |
232 | | - $result = $thesaurus->getConceptsForTerm($lang, $term, $languages, $norm, $limit); |
233 | | - } |
234 | | - } catch (Exception $e) { |
235 | | - $error = $e->getMessage(); |
236 | | - } |
237 | | -} |
238 | | - |
239 | | - |
240 | | -?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
241 | | -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
242 | | -<head> |
243 | | - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
244 | | - <title>WikiWord Navigator</title> |
245 | | - |
246 | | - <style type="text/css"> |
247 | | - body { font-family: verdana, helvetica, arial, sans-serif; } |
248 | | - td { text-align: left; vertical-align: top; } |
249 | | - th { text-align: left; vertical-align: top; font-weight:bold; } |
250 | | - .error { color: red; font-weight: bold; } |
251 | | - .weight_huge { font-size: 140%; font-weight:bold; } |
252 | | - .weight_big { font-size: 120%; font-weight:bold; } |
253 | | - .weight_normal { font-size: 110%; font-weight:bold; } |
254 | | - .weight_some { font-size: 100%; font-weight:bold; } |
255 | | - .weight_little { font-size: 90%; font-weight:bold; } |
256 | | - .weight_unknown { font-size: 100%; font-weight:bold; } |
257 | | - .row_def td { font-size: 80%; font-style:italic; } |
258 | | - .row_details td { font-size: 80%; } |
259 | | - .cell_weight { text-align: right; } |
260 | | - .cell_label { text-align: right; } |
261 | | - .header { text-align: left; } |
262 | | - .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; } |
263 | | - .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; } |
264 | | - .note { font-size:80%; } |
265 | | - .terselist, .terselist li { display: inline; margin:0; padding:0; } |
266 | | - .terselist li { display: inline; } |
267 | | - .terselist li:before { content:" - " } |
268 | | - .terselist li:first-child:before { content:"" } |
269 | | - |
270 | | - .gallery li { display: inline; padding:0.5ex; margin:0.5ex; } |
271 | | - </style> |
272 | | -</head> |
273 | | -<body> |
274 | | - <div class="header"> |
275 | | - <h1>WikiWord Navigator</h1> |
276 | | - <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p> |
277 | | - <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>. |
278 | | - It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p> |
279 | | - </div> |
280 | | - |
281 | | - <div class="inputform" > |
282 | | - <form name="search" action="<?php print $wwSelf; ?>"> |
283 | | - <table border="0" class="inputgrid"> |
284 | | - <tr> |
285 | | - <td> |
286 | | - <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/> |
287 | | - </td> |
288 | | - <td> |
289 | | - <label for="term" style="display:none">Language: </label> |
290 | | - <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?> |
291 | | - </td> |
292 | | - <td> |
293 | | - <input type="submit" name="go" value="go"/> |
294 | | - </td> |
295 | | - </tr> |
296 | | - </table> |
297 | | - <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered.</p> |
298 | | - </form> |
299 | | - </div> |
300 | | -<?php |
301 | | -if ($error) { |
302 | | - print "<p class=\"error\">".htmlspecialchars($error)."</p>"; |
303 | | -} |
304 | | -?> |
305 | | - |
306 | | -<?php |
307 | | -if ($result) { |
308 | | - if ( $conceptId ) $terse = false; |
309 | | - else $terse = true; |
310 | | - |
311 | | - $count = 0; |
312 | | - foreach ( $result as $row ) { |
313 | | - $count = $count + 1; |
314 | | - $row['pos'] = $count; |
315 | | - |
316 | | -?> |
317 | | - <table border="0" class="results"> |
318 | | - <?php |
319 | | - $continue= printConcept($row, $languages, $terse); |
320 | | - |
321 | | - if (!$continue) break; |
322 | | - ?> |
323 | | - </table> |
324 | | - </div> |
325 | | - |
326 | | -<?php |
327 | | - } #concept loop |
328 | | - |
329 | | - if ($term) { ?> |
330 | | - <p>Found <?php print $count; ?> items.</p> |
331 | | - <?php } |
332 | | -} ?> |
333 | | - |
334 | | -<p class="footer"> |
335 | | -The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a> |
336 | | -<p> |
337 | | -</body> |
338 | | -</html> |
339 | | -<?php |
340 | | -$utils->close(); |
341 | | -?> |
\ No newline at end of file |
Index: trunk/WikiWord/WikiWord/src/main/php/wwimages.php |
— | — | @@ -1,496 +0,0 @@ |
2 | | -<?php |
3 | | -require_once(dirname(__FILE__)."/wwwikis.php"); |
4 | | - |
5 | | -class ImageCollection { |
6 | | - |
7 | | - function __construct() { |
8 | | - $this->images = array(); |
9 | | - } |
10 | | - |
11 | | - static function compareRecords($a, $b) { |
12 | | - $d = (float)$b['score'] - (float)$a['score']; //NOTE: descending |
13 | | - |
14 | | - if ( $d > 0 ) return 1; |
15 | | - else if ( $d < 0 ) return -1; |
16 | | - else return 0; |
17 | | - } |
18 | | - |
19 | | - function size() { |
20 | | - return count($this->images); |
21 | | - } |
22 | | - |
23 | | - function listImages($max) { |
24 | | - uasort($this->images, "Imagecollection::compareRecords"); |
25 | | - |
26 | | - if ($max) return array_slice($this->images, 0, $max); |
27 | | - else return $this->images; |
28 | | - } |
29 | | - |
30 | | - function addImage($image, $key, $usage = "page", $weight = 1) { |
31 | | - if (!isset($this->images[$image])) { |
32 | | - $rec = array( |
33 | | - "name" => $image, |
34 | | - "score" => 0, |
35 | | - ); |
36 | | - } else { |
37 | | - $rec = $this->images[$image]; |
38 | | - } |
39 | | - |
40 | | - if (!isset($rec[$usage])) $rec[$usage] = array(); |
41 | | - $rec[$usage][] = $key; |
42 | | - $rec["score"] += $weight; |
43 | | - |
44 | | - $this->images[$image] = $rec; |
45 | | - return $rec['score']; |
46 | | - } |
47 | | - |
48 | | - function addImages($images, $key, $usage = "page", $weight = 1) { |
49 | | - foreach ($images as $image) { |
50 | | - $this->addImage($image, $key, $usage, $weight); |
51 | | - } |
52 | | - } |
53 | | - |
54 | | - function addImageUsage($image, $wiki, $usage = "page", $weight = 1) { |
55 | | - $this->addImage($image, $key, $usage, $weight); |
56 | | - } |
57 | | - |
58 | | - function addTags($image, $tags, $prefix = "") { |
59 | | - global $wwTagScores; |
60 | | - |
61 | | - if (isset($this->images[$image])) { |
62 | | - foreach ($tags as $tag => $weight) { |
63 | | - if (is_int($tag)) { |
64 | | - $tag = $prefix.$weight; |
65 | | - |
66 | | - if (isset($wwTagScores[$tag])) $weight = $wwTagScores[$tag]; |
67 | | - else $weight = 0; |
68 | | - } else { |
69 | | - $tag = $prefix.$tag; |
70 | | - } |
71 | | - |
72 | | - $this->images[$image]['score'] += $weight; |
73 | | - $this->images[$image]['tags'][] = $tag; |
74 | | - } |
75 | | - } |
76 | | - } |
77 | | - |
78 | | -} |
79 | | - |
80 | | -class WWImages extends WWWikis { |
81 | | - var $thesaurus; |
82 | | - |
83 | | - function __construct($thesaurus) { |
84 | | - $this->thesaurus = $thesaurus; |
85 | | - if ( !empty( $this->thesaurus->db ) ) $this->db = $thesaurus->db; |
86 | | - } |
87 | | - |
88 | | - function queryImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
89 | | - if ($lang == "commons") $commonsOnly = false; |
90 | | - |
91 | | - $imagelinks_table = $this->getWikiTableName($lang, "imagelinks"); |
92 | | - $page_table = $this->getWikiTableName($lang, "page"); |
93 | | - $image_table = $this->getWikiTableName($lang, "image"); |
94 | | - $commons_image_table = $this->getWikiTableName("commons", "image"); |
95 | | - |
96 | | - $sql = "/* queryImagesOnPage(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ "; |
97 | | - |
98 | | - $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I "; |
99 | | - $sql .= " JOIN $page_table as P on P.page_id = I.il_from "; |
100 | | - if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to "; |
101 | | - if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to "; |
102 | | - |
103 | | - $sql .= " WHERE P.page_namespace = " . (int)$ns; |
104 | | - $sql .= " AND P.page_title = " . $this->quote($title); |
105 | | - if ($commonsOnly) $sql .= " AND R.img_name IS NULL"; |
106 | | - |
107 | | - return $this->queryWiki($lang, $sql); |
108 | | - } |
109 | | - |
110 | | - function getImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
111 | | - $rs = $this->queryImagesOnPage($lang, $ns, $title, $commonsOnly); |
112 | | - |
113 | | - $list = WWUtils::slurpList($rs, "name"); |
114 | | - mysql_free_result($rs); |
115 | | - |
116 | | - return $list; |
117 | | - } |
118 | | - |
119 | | - function queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) { |
120 | | - if ($lang == "commons") $commonsOnly = false; |
121 | | - |
122 | | - $imagelinks_table = $this->getWikiTableName($lang, "imagelinks"); |
123 | | - $page_table = $this->getWikiTableName($lang, "page"); |
124 | | - $image_table = $this->getWikiTableName($lang, "image"); |
125 | | - $commons_image_table = $this->getWikiTableName("commons", "image"); |
126 | | - $templatelinks_table = $this->getWikiTableName($lang, "templatelinks"); |
127 | | - |
128 | | - $sql = "/* queryImagesOnPageTemplates(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ "; |
129 | | - |
130 | | - $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I "; |
131 | | - $sql .= " JOIN $page_table as TP on TP.page_id = I.il_from "; |
132 | | - $sql .= " JOIN $templatelinks_table as T on T.tl_namespace = TP.page_namespace AND T.tl_title = TP.page_title "; |
133 | | - $sql .= " JOIN $page_table as P on P.page_id = T.tl_from "; |
134 | | - if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to "; |
135 | | - if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to "; |
136 | | - |
137 | | - $sql .= " WHERE P.page_namespace = " . (int)$ns; |
138 | | - $sql .= " AND P.page_title = " . $this->quote($title); |
139 | | - if ($commonsOnly) $sql .= " AND R.img_name IS NULL"; |
140 | | - |
141 | | - return $this->queryWiki($lang, $sql); |
142 | | - } |
143 | | - |
144 | | - function getImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) { |
145 | | - $rs = $this->queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly); |
146 | | - $list = WWUtils::slurpList($rs, "name"); |
147 | | - mysql_free_result($rs); |
148 | | - return $list; |
149 | | - } |
150 | | - |
151 | | - function queryImagesInCategory($lang, $title) { |
152 | | - $categorylinks_table = $this->getWikiTableName($lang, "categorylinks"); |
153 | | - $page_table = $this->getWikiTableName($lang, "page"); |
154 | | - |
155 | | - $sql = "/* queryImagesInCategory(" . $this->quote($lang) . ", " . $this->quote($title) . ") */ "; |
156 | | - |
157 | | - $sql .= " SELECT P.page_title as name FROM $page_table as P "; |
158 | | - $sql .= " JOIN $categorylinks_table as C on C.cl_from = P.page_id "; |
159 | | - |
160 | | - $sql .= " WHERE C.cl_to = " . $this->quote($title); |
161 | | - $sql .= " AND P.page_namespace = " . NS_IMAGE; |
162 | | - |
163 | | - return $this->queryWiki($lang, $sql); |
164 | | - } |
165 | | - |
166 | | - function getImagesInCategory($lang, $title) { |
167 | | - $rs = $this->queryImagesInCategory($lang, $title); |
168 | | - $list = WWUtils::slurpList($rs, "name"); |
169 | | - mysql_free_result($rs); |
170 | | - return $list; |
171 | | - } |
172 | | - |
173 | | - function queryTagsForImages($lang, $images, $tagTable) { |
174 | | - if (!$images) return false; |
175 | | - |
176 | | - $sql = "/* queryTagsForImages(" . $this->quote($lang) . ", " . $this->quoteSet($images) . ") */ "; |
177 | | - |
178 | | - $sql .= " SELECT image, group_concat( concat(type, ':', tag) separator '|') as tags "; |
179 | | - $sql .= " FROM $tagTable as T "; |
180 | | - $sql .= " WHERE T.image IN " . $this->quoteSet($images); |
181 | | - $sql .= " GROUP BY image "; |
182 | | - |
183 | | - return $this->queryWiki($lang, $sql); |
184 | | - } |
185 | | - |
186 | | - function getTagsForImages($lang, $images, $tagTable) { |
187 | | - if (!$images) return array(); |
188 | | - |
189 | | - $rs = $this->queryTagsForImages($lang, $images, $tagTable); |
190 | | - $list = WWUtils::slurpAssoc($rs, "image", "tags"); |
191 | | - mysql_free_result($rs); |
192 | | - return $list; |
193 | | - } |
194 | | - |
195 | | - function queryTemplatesOnImagePage($lang, $image) { |
196 | | - $page_table = $this->getWikiTableName($lang, "page"); |
197 | | - $templatelinks_table = $this->getWikiTableName($lang, "templatelinks"); |
198 | | - |
199 | | - $sql = "/* queryTemplatesOnImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ "; |
200 | | - |
201 | | - $sql .= " SELECT tl_title as template FROM $templatelinks_table as T "; |
202 | | - $sql .= " JOIN $page_table as P on P.page_id = T.tl_from AND T.tl_namespace = " . NS_TEMPLATE . " "; |
203 | | - |
204 | | - $sql .= " WHERE P.page_title = " . $this->quote($image); |
205 | | - $sql .= " AND P.page_namespace = " . NS_IMAGE; |
206 | | - |
207 | | - return $this->queryWiki($lang, $sql); |
208 | | - } |
209 | | - |
210 | | - function getTemplatesOnImagePage($lang, $image) { |
211 | | - $rs = $this->queryTemplatesOnImagePage($lang, $image); |
212 | | - $list = WWUtils::slurpList($rs, "template"); |
213 | | - mysql_free_result($rs); |
214 | | - return $list; |
215 | | - } |
216 | | - |
217 | | - function queryCategoriesOfImagePage($lang, $image) { |
218 | | - $page_table = $this->getWikiTableName($lang, "page"); |
219 | | - $categorylinks_table = $this->getWikiTableName($lang, "categorylinks"); |
220 | | - |
221 | | - $sql = "/* queryCategoriesOfImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ "; |
222 | | - |
223 | | - $sql .= " SELECT cl_to as category FROM $categorylinks_table as C "; |
224 | | - $sql .= " JOIN $page_table as P on P.page_id = C.cl_from "; |
225 | | - |
226 | | - $sql .= " WHERE P.page_title = " . $this->quote($image); |
227 | | - $sql .= " AND P.page_namespace = " . NS_IMAGE; |
228 | | - |
229 | | - return $this->queryWiki($lang, $sql); |
230 | | - } |
231 | | - |
232 | | - function getCategoriesOfImagePage($lang, $image) { |
233 | | - $rs = $this->queryCategoriesOfImagePage($lang, $image); |
234 | | - $list = WWUtils::slurpList($rs, "category"); |
235 | | - mysql_free_result($rs); |
236 | | - return $list; |
237 | | - } |
238 | | - |
239 | | - function getTemplateScores($templates, $values = NULL) { |
240 | | - global $wwTemplateScores; |
241 | | - if ($values === NULL) $values = $wwTemplateScores; |
242 | | - |
243 | | - if (!$values) return 0; |
244 | | - |
245 | | - $score = 0; |
246 | | - foreach ($templates as $t) { |
247 | | - $v = @$values[$t]; |
248 | | - if ($v) $score += $v; |
249 | | - } |
250 | | - |
251 | | - return $score; |
252 | | - } |
253 | | - |
254 | | - function getRelevantImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
255 | | - $img = $this->getImagesOnPage($lang, 0, $title, true); |
256 | | - $timg = $this->getImagesOnPageTemplates($lang, 0, $title, true); |
257 | | - $img = array_diff($img, $timg); |
258 | | - return $img; |
259 | | - } |
260 | | - |
261 | | - function queryImagesOnPagesGlobally( $concepts ) { |
262 | | - global $wwLanguages; |
263 | | - |
264 | | - if (!$concepts) return false; |
265 | | - |
266 | | - $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks"); |
267 | | - |
268 | | - $wikis = array(); |
269 | | - $pages = array(); |
270 | | - |
271 | | - foreach ($concepts as $lang => $rc) { |
272 | | - if (!isset($wwLanguages[$lang])) continue; |
273 | | - |
274 | | - $wiki = $lang . "wiki"; |
275 | | - if (!in_array($wiki, $wikis)) $wikis[] = $wiki; |
276 | | - |
277 | | - foreach ($rc as $r => $t) { |
278 | | - if ( $t != 10) continue; //use only articles |
279 | | - $p = "gil_wiki = " . $this->quote($wiki) . " AND gil_page_namespace_id = 0 AND gil_page_title = " . $this->quote($r); |
280 | | - $pages[] = $p; |
281 | | - } |
282 | | - } |
283 | | - |
284 | | - if (!$pages || !$wikis) return false; |
285 | | - |
286 | | - $sql = " /* queryImagesOnPagesGlobally() */ "; |
287 | | - $sql .= " SELECT distinct gil_to as image FROM $globalimagelinks_table "; |
288 | | - $sql .= " WHERE gil_wiki in " . $this->quoteSet( $wikis ); |
289 | | - $sql .= " AND gil_page_namespace_id = 0 "; |
290 | | - $sql .= " AND ( ( " . implode(" ) OR ( ", $pages) . " ) ) "; |
291 | | - |
292 | | - print "(** $sql **)"; |
293 | | - |
294 | | - return $this->queryWiki("commons", $sql); |
295 | | - } |
296 | | - |
297 | | - function getImagesOnPagesGlobally( $concepts ) { |
298 | | - if (!$concepts) return array(); |
299 | | - |
300 | | - $rs = $this->queryImagesOnPagesGlobally($concepts); |
301 | | - if (!$rs) return false; |
302 | | - |
303 | | - $list = WWUtils::slurpList($rs, "image"); |
304 | | - mysql_free_result($rs); |
305 | | - return $list; |
306 | | - } |
307 | | - |
308 | | - function queryGlobalUsageCounts( $images, $wikis = ".*wiki" ) { |
309 | | - if (!$images) return false; |
310 | | - |
311 | | - $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks"); |
312 | | - |
313 | | - $sql = " /* queryGlobalUsageCounts() */ "; |
314 | | - $sql .= " SELECT gil_to as image, gil_wiki as wiki, count(*) as linkcount FROM $globalimagelinks_table "; |
315 | | - $sql .= " WHERE gil_page_namespace_id = 0 "; |
316 | | - $sql .= " AND gil_to IN " . $this->quoteSet( $images ); |
317 | | - |
318 | | - if ( $wikis ) { |
319 | | - if ( is_array( $wikis ) ) $sql .= " AND gil_wiki IN " . $this->quoteSet( $wikis ); |
320 | | - else if ( is_array( $wikis ) ) $sql .= " AND gil_wiki REGEX " . $this->quote( '^' . $wikis . '$' ); |
321 | | - |
322 | | - #TODO: could also limit to to x or min size n using toolserver.wiki ! |
323 | | - } |
324 | | - |
325 | | - $sql .= " GROUP BY gil_to, gil_wiki "; |
326 | | - $sql .= " ORDER BY gil_to, gil_wiki "; |
327 | | - |
328 | | - return $this->queryWiki("commons", $sql); |
329 | | - } |
330 | | - |
331 | | - function getGlobalUsageCounts( $images, $wikis = ".*wiki" ) { |
332 | | - if (!$images) return array(); |
333 | | - |
334 | | - $rs = $this->queryGlobalUsageCounts($images, $wikis); |
335 | | - if (!$rs) return false; |
336 | | - |
337 | | - if (is_string($rs)) $rs = $this->query($rs); |
338 | | - |
339 | | - $imageUsage = array(); |
340 | | - $current = NULL; |
341 | | - $stats = array(); |
342 | | - while ($row = mysql_fetch_assoc($rs)) { |
343 | | - $image = $row["image"]; |
344 | | - $wiki = $row["wiki"]; |
345 | | - $linkcount = $row["linkcount"]; |
346 | | - |
347 | | - if ( is_null($current) ) $current = $image; |
348 | | - else if ($current != $image) { |
349 | | - $imageUsage[$current] = $stats; |
350 | | - $stats = array(); |
351 | | - $current = $image; |
352 | | - } |
353 | | - |
354 | | - $stats[$wiki] = $linkcount; |
355 | | - } |
356 | | - |
357 | | - if ($current) $imageUsage[$current] = $stats; |
358 | | - |
359 | | - return $imageUsage; |
360 | | - } |
361 | | - |
362 | | - function getImagesAbout($concept, $max = 0) { |
363 | | - global $wwLanguages, $wwFrequentImageThreshold; //FIXME: put config into member vars! |
364 | | - |
365 | | - $pages = null; |
366 | | - if ( is_array($concept) ) { |
367 | | - if (isset($concept['pages']) && $concept['pages']!==null) $pages = $concept['pages']; |
368 | | - else if (isset($concept['id']) && $concept['id']!==null) $concept = $concept['id']; |
369 | | - else if (isset($concept['concept'])) $concept = $concept['concept']; |
370 | | - } |
371 | | - |
372 | | - if ($pages === null) { |
373 | | - $pages = $this->thesaurus->getPagesForConcept($concept); |
374 | | - if (!$pages) return false; |
375 | | - } |
376 | | - |
377 | | - $images = new ImageCollection(); |
378 | | - |
379 | | - $globalImageList = $this->getImagesOnPagesGlobally($pages); //use wikis for $wwLanguages only |
380 | | - //TODO: sanity limit on number of images. $max * 5 ? |
381 | | - $globalImageUsage = $this->getGlobalUsageCounts($globalImageList, ".*wiki"); //use all wikipedias |
382 | | - |
383 | | - foreach ($globalImageUsage as $image => $usage) { |
384 | | - foreach ($usage as $wiki => $c) { |
385 | | - if ( $c >= $wwFrequentImageThreshold ) continue; |
386 | | - $images->addImageUsage($image, $wiki.":*", "article", 1); |
387 | | - } |
388 | | - } |
389 | | - |
390 | | - if ($max && $images->size()>$max) { //short-cirquit, if we already reached the max |
391 | | - $this->addImageTags($images); |
392 | | - return $images->listImages($max); |
393 | | - } |
394 | | - |
395 | | - if (isset($pages['commons'])) { |
396 | | - $cpages = $pages['commons']; |
397 | | - |
398 | | - foreach ($cpages as $cpage => $t) { |
399 | | - if ( $t == 50 && preg_match('/^Category:(.*)$/', $cpage, $m) ) { |
400 | | - if ( @$m[1] ) $cpage = $m[1]; //hack |
401 | | - $img = $this->getImagesInCategory("commons", $cpage); |
402 | | - |
403 | | - if ($img) $images->addImages($img, "commons:category:" . $cpage, "category", 0.5); |
404 | | - } |
405 | | - } |
406 | | - } |
407 | | - |
408 | | - $this->addImageTags($images); |
409 | | - return $images->listImages($max); |
410 | | - } |
411 | | - |
412 | | - function addImageTags($images) { |
413 | | - global $wwTagsTable; |
414 | | - |
415 | | - |
416 | | - if ( $wwTagsTable ) { |
417 | | - $img = array(); |
418 | | - foreach ($images->images as $image) { |
419 | | - $img[] = $image['name']; |
420 | | - } |
421 | | - |
422 | | - $tagMap = $this->getTagsForImages('commons', $img, $wwTagsTable); |
423 | | - foreach ($tagMap as $image => $tags) { |
424 | | - if ($tags) { |
425 | | - if (is_string($tags)) $tags = preg_split('/\s*[|;]\s*/', $tags); |
426 | | - $images->addTags($image, $tags, ""); |
427 | | - } |
428 | | - } |
429 | | - } else { |
430 | | - foreach ($images->images as $image) { |
431 | | - $image = $image['name']; |
432 | | - |
433 | | - $tmps = $this->getTemplatesOnImagePage('commons', $image); |
434 | | - if ($tmps) $images->addTags($image, $tmps, "Template:"); |
435 | | - |
436 | | - $cats = $this->getCategoriesOfImagePage('commons', $image); |
437 | | - if ($cats) $images->addTags($image, $cats, "Category:"); |
438 | | - } |
439 | | - } |
440 | | - } |
441 | | - |
442 | | - function getThumbnailURL($image, $width = 120, $height = NULL) { |
443 | | - global $wwThumbnailURL; |
444 | | - |
445 | | - if (is_array($image)) $image = $image['name']; |
446 | | - |
447 | | - if (!$height) $height = $width; |
448 | | - |
449 | | - $u = $wwThumbnailURL; |
450 | | - $u = str_replace("{name}", urlencode($image), $u); |
451 | | - $u = str_replace("{width}", !$width ? "" : urlencode($width), $u); |
452 | | - $u = str_replace("{height}", !$height ? "" : urlencode($height), $u); |
453 | | - |
454 | | - return $u; |
455 | | - } |
456 | | - |
457 | | - function getImagePageURL($image) { |
458 | | - global $wwImagePageURL; |
459 | | - |
460 | | - if (is_array($image)) $image = $image['name']; |
461 | | - |
462 | | - $u = $wwImagePageURL; |
463 | | - $u = str_replace("{name}", urlencode($image), $u); |
464 | | - |
465 | | - return $u; |
466 | | - } |
467 | | - |
468 | | - function getThumbnailHTML($image, $w = 120, $h = NULL) { |
469 | | - $thumb = $this->getThumbnailURL($image, $w, $h); |
470 | | - $page = $this->getImagePageURL($image); |
471 | | - |
472 | | - if (is_array($image)) { |
473 | | - $title = @$image['title']; |
474 | | - $name = @$image['name']; |
475 | | - } else { |
476 | | - $name = $image; |
477 | | - } |
478 | | - |
479 | | - if (!@$title) $title = $name; |
480 | | - |
481 | | - $tags = ""; |
482 | | - if (isset($image['tags'])) { |
483 | | - foreach ($image['tags'] as $tag) { |
484 | | - $tags .= "tag-" . str_replace(":", "-", $tag) . " "; |
485 | | - } |
486 | | - } |
487 | | - |
488 | | - $html= "<img src=\"" . htmlspecialchars($thumb) . "\" alt=\"" . htmlspecialchars($title) . "\" border=\"0\"/>"; |
489 | | - $html= "<a href=\"" . htmlspecialchars($page) . "\" title=\"" . htmlspecialchars($title) . " (score " . htmlspecialchars($image['score']) . ")\" class=\"thumb-link $tags\">$html</a>"; |
490 | | - |
491 | | - if (is_array($image)) { |
492 | | - $html .= "<!-- " . str_replace("--", "~~", var_export( $image, true ) ) . " -->"; |
493 | | - } |
494 | | - |
495 | | - return $html; |
496 | | - } |
497 | | -} |
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/build-search-index.sh |
— | — | @@ -0,0 +1,15 @@ |
| 2 | +#!/bin/bash |
| 3 | +set -e |
| 4 | + |
| 5 | +db="$1" |
| 6 | +collection="$2" |
| 7 | +thesaurus="$3" |
| 8 | +languages="en de fr nl it es pt pl" |
| 9 | + |
| 10 | +echo "preparing search index" |
| 11 | +replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" < search-index.sql | mysql "$db" |
| 12 | + |
| 13 | +for n in $languages; do |
| 14 | + echo "collection search index: $n" |
| 15 | + replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" '{lang}' "$n" < search-index-local.sql | mysql "$db" |
| 16 | +done |
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/search-index-local.sql |
— | — | @@ -0,0 +1,16 @@ |
| 2 | +-- collect definitions |
| 3 | +insert into {collection}_{thesaurus}_search_index ( |
| 4 | + concept, concept_name, `type`, |
| 5 | + `lang`, `term`, `score`, `norm` ) |
| 6 | +select O.global_concept, M.concept_name, C.type, "{lang}", |
| 7 | + REPLACE( LCASE( CAST(M.term_text as CHAR CHARACTER SET utf8) COLLATE utf8_general_ci ), "-", "" ), |
| 8 | + M.rule * M.freq, 1 |
| 9 | +from {collection}_{lang}_meaning as M |
| 10 | +join {collection}_{thesaurus}_origin as O on O.lang = "{lang}" and O.local_concept = M.concept |
| 11 | +join {collection}_{thesaurus}_concept as C on C.id = O.global_concept |
| 12 | +where (M.rule not in (10, 30) OR M.freq > 1) and C.type > 0 |
| 13 | +on duplicate key update |
| 14 | + score = if (score > values(score), score, values(score)), |
| 15 | + norm = if (norm < values(norm), score, values(norm)); |
| 16 | + |
| 17 | +-- FIXME: normalization levels! 0=none, 1=case-and-dash (+translit?), 2=whitespace-and-punctuation, 4=soundex |
\ No newline at end of file |
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/concept-info.sql |
— | — | @@ -0,0 +1,20 @@ |
| 2 | +SET SESSION group_concat_max_len = 262144; -- 1024*256 |
| 3 | + |
| 4 | +create table if not exists {collection}_{thesaurus}_concept_info ( |
| 5 | + concept int(11) NOT NULL, |
| 6 | + `lang` varbinary(10) NOT NULL, |
| 7 | + `name` varbinary(255) NOT NULL, |
| 8 | + `pages` MEDIUMBLOB DEFAULT NULL, |
| 9 | + `definition` MEDIUMBLOB DEFAULT NULL, |
| 10 | + `broader` MEDIUMBLOB DEFAULT NULL, |
| 11 | + `narrower` MEDIUMBLOB DEFAULT NULL, |
| 12 | + `similar` MEDIUMBLOB DEFAULT NULL, |
| 13 | + `related` MEDIUMBLOB DEFAULT NULL, |
| 14 | + PRIMARY KEY ( concept, lang ) |
| 15 | + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; |
| 16 | + |
| 17 | +truncate {collection}_{thesaurus}_concept_info; |
| 18 | + |
| 19 | +insert into {collection}_{thesaurus}_concept_info ( concept, lang, name ) |
| 20 | +select global_concept, lang, local_concept_name |
| 21 | +from {collection}_{thesaurus}_origin; |
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/search-index.sql |
— | — | @@ -0,0 +1,13 @@ |
| 2 | +create table if not exists {collection}_{thesaurus}_search_index ( |
| 3 | + concept int(11) NOT NULL, |
| 4 | + concept_name varbinary(255) NOT NULL, |
| 5 | + type int(11) NOT NULL, |
| 6 | + `lang` varbinary(10) NOT NULL, |
| 7 | + `term` varchar(255) character set utf8 collate utf8_general_ci NOT NULL, |
| 8 | + `score` int NOT NULL, |
| 9 | + `norm` int NOT NULL, |
| 10 | + PRIMARY KEY ( lang, term, concept ), |
| 11 | + KEY ( concept, lang ) |
| 12 | + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; |
| 13 | + |
| 14 | +truncate {collection}_{thesaurus}_search_index; |
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/build-concept-info.sh |
— | — | @@ -0,0 +1,15 @@ |
| 2 | +#!/bin/bash |
| 3 | +set -e |
| 4 | + |
| 5 | +db="$1" |
| 6 | +collection="$2" |
| 7 | +thesaurus="$3" |
| 8 | +languages="commons en de fr nl it es pt pl" |
| 9 | + |
| 10 | +echo "preparing concept info" |
| 11 | +replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" < concept-info.sql | mysql "$db" |
| 12 | + |
| 13 | +for n in $languages; do |
| 14 | + echo "collection concept info: $n" |
| 15 | + replace '{collection}' "$collection" '{thesaurus}' "$thesaurus" '{lang}' "$n" < concept-info-local.sql | mysql "$db" |
| 16 | +done |
Index: trunk/WikiWord/WikiWord/src/main/php/maintenance/concept-info-local.sql |
— | — | @@ -0,0 +1,61 @@ |
| 2 | +SET SESSION group_concat_max_len = 262144; -- 1024*256 |
| 3 | + |
| 4 | +-- collect definitions |
| 5 | +update {collection}_{thesaurus}_concept_info as I |
| 6 | +join {collection}_{thesaurus}_origin as O on I.lang = O.lang and I.concept = O.global_concept |
| 7 | +join {collection}_{lang}_definition as D on O.local_concept = D.concept and O.lang = "{lang}" |
| 8 | +set I.definition = D.definition |
| 9 | +where I.lang = "{lang}"; |
| 10 | + |
| 11 | +-- collect wiki pages |
| 12 | +update {collection}_{thesaurus}_concept_info as I |
| 13 | +join ( select O.global_concept as concept, O.lang as lang, |
| 14 | + group_concat(distinct concat(R.type, ":", R.name) separator "|" ) as pages |
| 15 | + from {collection}_{thesaurus}_origin as O |
| 16 | + join {collection}_{lang}_about as A on A.concept = O.local_concept and O.lang = "{lang}" |
| 17 | + join {collection}_{lang}_resource as R on R.id = A.resource |
| 18 | + where O.lang = "{lang}" and R.type IN (10, 50) |
| 19 | + group by O.global_concept, O.lang |
| 20 | + ) as X |
| 21 | +on I.concept = X.concept and I.lang = X.lang |
| 22 | +set I.pages = X.pages |
| 23 | +where I.lang = "{lang}"; |
| 24 | + |
| 25 | +-- collect broader concepts |
| 26 | +update {collection}_{thesaurus}_concept_info as I |
| 27 | +join ( select narrow as concept, group_concat(distinct concat(broad, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as broader |
| 28 | +from {collection}_{thesaurus}_broader |
| 29 | + left join {collection}_{thesaurus}_origin as O on O.global_concept = broad and O.lang = "{lang}" |
| 30 | + group by narrow ) as X |
| 31 | +on X.concept = I.concept and I.lang = "{lang}" |
| 32 | +set I.broader = X.broader; |
| 33 | + |
| 34 | +-- collect narrower concepts |
| 35 | +update {collection}_{thesaurus}_concept_info as I |
| 36 | +join ( select broad as concept, group_concat(distinct concat(narrow, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as narrower |
| 37 | +from {collection}_{thesaurus}_broader |
| 38 | + left join {collection}_{thesaurus}_origin as O on O.global_concept = narrow and O.lang = "{lang}" |
| 39 | + group by broad ) as X |
| 40 | +on X.concept = I.concept and I.lang = "{lang}" |
| 41 | +set I.narrower = X.narrower; |
| 42 | + |
| 43 | +-- collect similar concepts |
| 44 | +update {collection}_{thesaurus}_concept_info as I |
| 45 | +join ( select concept1 as concept, group_concat(distinct concat(concept2, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as similar |
| 46 | +from {collection}_{thesaurus}_relation |
| 47 | + left join {collection}_{thesaurus}_origin as O on O.global_concept = concept2 and O.lang = "{lang}" |
| 48 | + where langmatch >= 1 or langref >= 1 |
| 49 | + group by concept1 ) as X |
| 50 | +on X.concept = I.concept and I.lang = "{lang}" |
| 51 | +set I.similar = X.similar; |
| 52 | + |
| 53 | +-- collect related concepts |
| 54 | +update {collection}_{thesaurus}_concept_info as I |
| 55 | +join ( select concept1 as concept, group_concat(distinct concat(concept2, ":", if (local_concept_name is null, "", local_concept_name)) separator "|") as related |
| 56 | +from {collection}_{thesaurus}_relation |
| 57 | + left join {collection}_{thesaurus}_origin as O on O.global_concept = concept2 and O.lang = "{lang}" |
| 58 | + where bilink >= 1 |
| 59 | + group by concept1 ) as X |
| 60 | +on X.concept = I.concept and I.lang = "{lang}" |
| 61 | +set I.related = X.related; |
| 62 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/search/wikiword.php |
— | — | @@ -0,0 +1,481 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +$IP = dirname(__FILE__); |
| 5 | + |
| 6 | +require_once("$IP/config.php"); |
| 7 | +require_once("$IP/wwimages.php"); |
| 8 | + |
| 9 | +if ($wwAPI) require_once("$IP/wwclient.php"); |
| 10 | +else require_once("$IP/wwthesaurus.php"); |
| 11 | + |
| 12 | +function printLocalConceptList($lang, $concepts) { |
| 13 | + global $utils; |
| 14 | + if (is_string($concepts)) $concepts = $utils->unpickle($concepts, $lang, true, false, true); |
| 15 | + |
| 16 | + ?> |
| 17 | + <ul class="terselist"> |
| 18 | + <?php |
| 19 | + foreach ($concepts as $c) { |
| 20 | + ?><li><?php |
| 21 | + printLocalConceptLink($lang, $c); |
| 22 | + ?></li><?php |
| 23 | + } |
| 24 | + ?> |
| 25 | + </ul> |
| 26 | + <?php |
| 27 | +} |
| 28 | + |
| 29 | +function printConceptImageList($concept, $class = "terselist") { |
| 30 | + global $utils, $wwThumbSize, $wwMaxPreviewImages; |
| 31 | + |
| 32 | + if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK |
| 33 | + else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages); |
| 34 | + |
| 35 | + ?> |
| 36 | + <ul class="<?php print $class; ?>"> |
| 37 | + <?php |
| 38 | + foreach ($images as $img) { |
| 39 | + ?><li><?php |
| 40 | + print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize); |
| 41 | + ?></li><?php |
| 42 | + } |
| 43 | + ?> |
| 44 | + </ul> |
| 45 | + <?php |
| 46 | +} |
| 47 | + |
| 48 | +function printLocalConceptLink($lang, $row) { |
| 49 | + global $wwSelf, $images; |
| 50 | + |
| 51 | + $row = normalizeConceptRow($lang, $row); |
| 52 | + |
| 53 | + extract($row); |
| 54 | + |
| 55 | + if (!isset($weight) && isset($freq)) $weight = $freq; |
| 56 | + if (!isset($weight) && isset($conf)) $weight = $conf; |
| 57 | + if (!isset($concept_name) && isset($name)) $concept_name = $name; |
| 58 | + if (!isset($concept_name)) $concept_name = NULL; |
| 59 | + if (!isset($concept) && isset($id)) $concept = $id; |
| 60 | + if (!isset($concept)) $concept = NULL; |
| 61 | + |
| 62 | + if ($lang == 'commons') $domain = 'commons.wikimedia.org'; |
| 63 | + else $domain = "$lang.wikipedia.org"; |
| 64 | + |
| 65 | + $wu = $concept_name ? "http://$domain/wiki/" . urlencode($concept_name) : NULL; |
| 66 | + $cu = "$wwSelf?id=" . urlencode($concept) . "&lang=" . urlencode($lang); |
| 67 | + |
| 68 | + if ($images) $cu .= "&images=1"; |
| 69 | + |
| 70 | + ?> |
| 71 | + <li> |
| 72 | + <?php if ($concept_name) { ?> |
| 73 | + <a href="<?php print htmlspecialchars($cu); ?>"><?php print htmlspecialchars($concept_name); ?></a> |
| 74 | + <?php } ?> |
| 75 | + <?php if ($concept) { ?> |
| 76 | + (<a href="<?php print htmlspecialchars($wu); ?>" title="<?php print htmlspecialchars($concept_name); ?>">wiki page</a>) |
| 77 | + <?php } ?> |
| 78 | + </li> |
| 79 | + <?php |
| 80 | +} |
| 81 | + |
| 82 | +function printTermList($lang, $terms) { |
| 83 | + global $utils; |
| 84 | + if (is_string($terms)) $terms = $utils->unpickle($terms, $lang); |
| 85 | + |
| 86 | + ?> |
| 87 | + <ul class="terselist"> |
| 88 | + <?php |
| 89 | + foreach ($terms as $t) { |
| 90 | + printTermLink($lang, $terms); |
| 91 | + } |
| 92 | + ?> |
| 93 | + </ul> |
| 94 | + <?php |
| 95 | +} |
| 96 | + |
| 97 | +function printTermLink($lang, $row) { |
| 98 | + global $wwSelf; |
| 99 | + |
| 100 | + extract($row); |
| 101 | + |
| 102 | + if (!isset($weight) && isset($freq)) $weight = $freq; |
| 103 | + if (!isset($weight) && isset($conf)) $weight = $conf; |
| 104 | + if (!isset($term_text) && isset($term)) $term_text = $term; |
| 105 | + if (!isset($term_text) && isset($text)) $term_text = $text; |
| 106 | + if (!isset($term_text) && isset($name)) $term_text = $name; |
| 107 | + if (!isset($term_text) && isset($value)) $term_text = $value; |
| 108 | + |
| 109 | + $tu = "$wwSelf?term=" . urlencode($term_text) . "&lang=" . urlencode($lang); |
| 110 | + |
| 111 | + ?> |
| 112 | + <li> |
| 113 | + <a href="<?php print htmlspecialchars($tu); ?>"><?php print htmlspecialchars($term_text); ?></a> |
| 114 | + </li> |
| 115 | + <?php |
| 116 | +} |
| 117 | + |
| 118 | +function normalizeConceptRow($lang, $row) { |
| 119 | + global $wwSelf; |
| 120 | + |
| 121 | + #FIXME: handle complex concept records! |
| 122 | + |
| 123 | + if (!$row) return $row; |
| 124 | + |
| 125 | + if (!isset($row['lang'])) $row['lang'] = $lang; |
| 126 | + if (!isset($row['weight']) && isset($row['freq'])) $row['weight'] = $row['freq']; |
| 127 | + if (!isset($row['weight']) && isset($row['conf'])) $row['weight'] = $row['conf']; |
| 128 | + if (!empty($row['local_concept_name'])) $row['concept_name'] = $row['local_concept_name']; |
| 129 | + if (!isset($row['concept_name']) && isset($row['name'])) $row['concept_name'] = $row['name']; |
| 130 | + if (!isset($row['concept_name']) && isset($row['global_concept_name'])) $row['concept_name'] = $row['global_concept_name']; |
| 131 | + if (!isset($row['reference_id']) && isset($row['global_id'])) $row['reference_id'] = $row['global_id']; |
| 132 | + if (!isset($row['reference_id']) && isset($row['global_concept'])) $row['reference_id'] = $row['global_concept']; |
| 133 | + if (!isset($row['reference_id']) && isset($row['concept'])) $row['reference_id'] = $row['concept']; |
| 134 | + if (!isset($row['reference_id']) && isset($row['id'])) $row['reference_id'] = $row['id']; |
| 135 | + if (!empty($row['definition']) && is_array($row['definition'])) $row['definition'] = $row['definition'][$lang]; |
| 136 | + |
| 137 | + #print "<pre>"; |
| 138 | + #print_r($row); |
| 139 | + #print "</pre>"; |
| 140 | + |
| 141 | + $row['wu'] = "http://$lang.wikipedia.org/wiki/" . urlencode($row['concept_name']); |
| 142 | + #$row['cu'] = "$wwSelf?id=" . urlencode($row['concept']) . "&lang=" . urlencode($lang); |
| 143 | + $row['cu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&lang=" . urlencode($lang); |
| 144 | + $row['gu'] = "$wwSelf?id=" . urlencode($row['reference_id']) . "&images=g"; |
| 145 | + |
| 146 | + if (!isset($row['weight']) || !$row['weight']) { |
| 147 | + $row['wclass'] = "unknown"; |
| 148 | + $row['weight'] = NULL; |
| 149 | + } |
| 150 | + else if ($row['weight']>1000) $row['wclass'] = "huge"; |
| 151 | + else if ($row['weight']>100) $row['wclass'] = "big"; |
| 152 | + else if ($row['weight']>10) $row['wclass'] = "normal"; |
| 153 | + else if ($row['weight']>2) $row['wclass'] = "some"; |
| 154 | + else $row['wclass'] = "little"; |
| 155 | + |
| 156 | + return $row; |
| 157 | +} |
| 158 | + |
| 159 | +function printLocalConcept($a_lang, $a_row, $b_lang, $b_row, $pos = 0, $terse = true) { |
| 160 | + global $wwSelf, $images, $utils; |
| 161 | + global $wwMaxPreviewImages, $wwMaxGalleryImages; |
| 162 | + |
| 163 | + $a_row = normalizeConceptRow($a_lang, $a_row); |
| 164 | + $b_row = normalizeConceptRow($b_lang, $b_row); |
| 165 | + |
| 166 | + if ($a_lang && $a_row) extract($a_row, EXTR_PREFIX_ALL, "a"); |
| 167 | + if ($b_lang && $b_row) extract($b_row, EXTR_PREFIX_ALL, "b"); |
| 168 | + |
| 169 | + ?> |
| 170 | + <tr class="row_item"> |
| 171 | + <td class="cell_weight <?php print "weight_$a_wclass"; ?>"><?php print htmlspecialchars($a_weight); ?></td> |
| 172 | + <td colspan="3" class="cell_name <?php print "weight_$a_wclass"; ?>"> |
| 173 | + <h3> |
| 174 | + <a href="<?php print htmlspecialchars($a_cu); ?>"><?php print htmlspecialchars($a_concept_name); ?></a> |
| 175 | + <span class="conceptref">(<a href="<?php print htmlspecialchars($a_wu); ?>" title="<?php print htmlspecialchars($a_concept_name); ?>">wiki page</a>)</span> |
| 176 | + </h3> |
| 177 | + </td> |
| 178 | + <?php if ($b_row) { ?> |
| 179 | + <td colspan="3" class="cell_name <?php print "weight_$b_wclass"; ?>"> |
| 180 | + <h3> |
| 181 | + <a href="<?php print htmlspecialchars($b_cu); ?>"><?php print htmlspecialchars($b_concept_name); ?></a> |
| 182 | + <span class="conceptref">(<a href="<?php print htmlspecialchars($b_wu); ?>" title="<?php print htmlspecialchars($b_concept_name); ?>">wiki page</a>)</span> |
| 183 | + </h3> |
| 184 | + </td> |
| 185 | + <?php } ?> |
| 186 | + </tr> |
| 187 | + |
| 188 | + <?php if (isset($a_definition) && !empty($a_definition)) { ?> |
| 189 | + <tr class="row_def"> |
| 190 | + <td></td> |
| 191 | + <td class="cell_label">Definition:</td> |
| 192 | + <td colspan="2"><?php print htmlspecialchars($a_definition); ?></td> |
| 193 | + <?php if ($b_row) { ?> |
| 194 | + <td class="cell_label">Definition:</td> |
| 195 | + <td colspan="2"><?php print htmlspecialchars($b_definition); ?></td> |
| 196 | + <?php } ?> |
| 197 | + </tr> |
| 198 | + <?php } ?> |
| 199 | + |
| 200 | + <?php if (isset($a_terms) && !empty($a_terms)) { ?> |
| 201 | + <tr class="row_details row_terms"> |
| 202 | + <td></td> |
| 203 | + <td class="cell_label">Terms:</td> |
| 204 | + <td class="cell_terms" colspan="2"><?php printTermList($a_lang, $a_terms); ?></td> |
| 205 | + <?php if ($b_row) { ?> |
| 206 | + <td class="cell_label">Terms:</td> |
| 207 | + <td class="cell_terms" colspan="2"><?php printTermList($b_lang, $b_terms); ?></td> |
| 208 | + <?php } ?> |
| 209 | + </tr> |
| 210 | + <?php } ?> |
| 211 | + |
| 212 | + <?php if ($images) { ?> |
| 213 | + <tr class="row_details row_images"> |
| 214 | + <td></td> |
| 215 | + <td class="cell_label">Images:</td> |
| 216 | + <td class="cell_broader" colspan="<?php $b_row ? 5 : 2 ?>"> |
| 217 | + <?php |
| 218 | + $gallery = $utils->getImagesAbout($a_reference_id, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages ); |
| 219 | + $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" ); |
| 220 | + ?> |
| 221 | + </td> |
| 222 | + </tr> |
| 223 | + <?php } ?> |
| 224 | + |
| 225 | + <?php if (isset($a_similar) && !empty($a_similar)) { ?> |
| 226 | + <tr class="row_details row_similar"> |
| 227 | + <td></td> |
| 228 | + <td class="cell_label">Similar:</td> |
| 229 | + <td class="cell_similar" colspan="2"><?php printLocalConceptList($a_lang, $a_similar); ?></td> |
| 230 | + <?php if ($b_row) { ?> |
| 231 | + <td class="cell_label">Similar:</td> |
| 232 | + <td class="cell_similar" colspan="2"><?php printLocalConceptList($b_lang, $b_similar); ?></td> |
| 233 | + <?php } ?> |
| 234 | + </tr> |
| 235 | + <?php } ?> |
| 236 | + |
| 237 | + <?php if (isset($a_related) && !empty($a_related)) { ?> |
| 238 | + <tr class="row_details row_related"> |
| 239 | + <td></td> |
| 240 | + <td class="cell_label">Related:</td> |
| 241 | + <td class="cell_related" colspan="2"><?php printLocalConceptList($a_lang, $a_related); ?></td> |
| 242 | + <?php if ($b_row) { ?> |
| 243 | + <td class="cell_label">Related:</td> |
| 244 | + <td class="cell_related" colspan="2"><?php printLocalConceptList($b_lang, $b_related); ?></td> |
| 245 | + <?php } ?> |
| 246 | + </tr> |
| 247 | + <?php } ?> |
| 248 | + |
| 249 | + <?php if (isset($a_narrower) && !empty($a_narrower)) { ?> |
| 250 | + <tr class="row_details row_narrower"> |
| 251 | + <td></td> |
| 252 | + <td class="cell_label">Narrower:</td> |
| 253 | + <td class="cell_narrower" colspan="2"><?php printLocalConceptList($a_lang, $a_narrower); ?></td> |
| 254 | + <?php if ($b_row) { ?> |
| 255 | + <td class="cell_label">Narrower:</td> |
| 256 | + <td class="cell_narrower" colspan="2"><?php printLocalConceptList($b_lang, $b_narrower); ?></td> |
| 257 | + <?php } ?> |
| 258 | + </tr> |
| 259 | + <?php } ?> |
| 260 | + |
| 261 | + <?php if (isset($a_broader) && !empty($a_broader)) { ?> |
| 262 | + <tr class="row_details row_broader"> |
| 263 | + <td></td> |
| 264 | + <td class="cell_label">Broader:</td> |
| 265 | + <td class="cell_broader" colspan="2"><?php printLocalConceptList($a_lang, $a_broader); ?></td> |
| 266 | + <?php if ($b_row) { ?> |
| 267 | + <td class="cell_label">Broader:</td> |
| 268 | + <td class="cell_broader" colspan="2"><?php printLocalConceptList($b_lang, $b_broader); ?></td> |
| 269 | + <?php } ?> |
| 270 | + </tr> |
| 271 | + <?php } ?> |
| 272 | + |
| 273 | + <?php |
| 274 | + if (isset($a_weight) && $a_weight && $a_weight<2 && $pos>=3) return false; |
| 275 | + else return true; |
| 276 | +} |
| 277 | + |
| 278 | +$concept = @$_REQUEST['id']; |
| 279 | +$term = @$_REQUEST['term']; |
| 280 | +$lang = @$_REQUEST['lang']; |
| 281 | +$tolang = @$_REQUEST['tolang']; |
| 282 | +$images = (@$_REQUEST['images'] || $wwImageSearch === true ) && !($wwImageSearch === false); |
| 283 | + |
| 284 | +if (!isset($_REQUEST['translate'])) $tolang = NULL; |
| 285 | +if ($lang == $tolang) $tolang = NULL; |
| 286 | + |
| 287 | +if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"]; |
| 288 | + |
| 289 | +$error = NULL; |
| 290 | + |
| 291 | +if ($lang && !isset($wwLanguages[$lang])) { |
| 292 | + $lang = NULL; |
| 293 | + $error = "bad language code: $lang"; |
| 294 | +} |
| 295 | + |
| 296 | +if ($wwAPI) $thesaurus = new WWClient($wwAPI); |
| 297 | +else { |
| 298 | + $thesaurus = new WWThesaurus(); |
| 299 | + $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
| 300 | +} |
| 301 | + |
| 302 | +$utils = new WWImages( $thesaurus ); |
| 303 | +if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
| 304 | + |
| 305 | +if (@$_REQUEST['debug']) $utils->debug = true; |
| 306 | + |
| 307 | +$limit = 20; |
| 308 | + |
| 309 | +$result = NULL; |
| 310 | + |
| 311 | +if (!$error) { |
| 312 | + try { |
| 313 | + if ($lang && $concept) { |
| 314 | + $result = $thesaurus->getConceptInfo($concept, $lang); |
| 315 | + if ( $result ) $result = array( $result ); //hack |
| 316 | + } else if ($lang && $term) { |
| 317 | + $result = $thesaurus->getConceptsForTerm($lang, $term, $limit); |
| 318 | + } |
| 319 | + } catch (Exception $e) { |
| 320 | + $error = $e->getMessage(); |
| 321 | + } |
| 322 | +} |
| 323 | + |
| 324 | + |
| 325 | +?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| 326 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
| 327 | +<head> |
| 328 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| 329 | + <title>WikiWord Navigator</title> |
| 330 | + |
| 331 | + <style type="text/css"> |
| 332 | + body { font-family: verdana, helvetica, arial, sans-serif; } |
| 333 | + td { text-align: left; vertical-align: top; } |
| 334 | + th { text-align: left; vertical-align: top; font-weight:bold; } |
| 335 | + .error { color: red; font-weight: bold; } |
| 336 | + .weight_huge { font-size: 140%; font-weight:bold; } |
| 337 | + .weight_big { font-size: 120%; font-weight:bold; } |
| 338 | + .weight_normal { font-size: 110%; font-weight:bold; } |
| 339 | + .weight_some { font-size: 100%; font-weight:bold; } |
| 340 | + .weight_little { font-size: 90%; font-weight:bold; } |
| 341 | + .weight_unknown { font-size: 100%; font-weight:bold; } |
| 342 | + .row_def td { font-size: 80%; font-style:italic; } |
| 343 | + .row_details td { font-size: 80%; } |
| 344 | + .cell_weight { text-align: right; } |
| 345 | + .cell_label { text-align: right; } |
| 346 | + .header { text-align: left; } |
| 347 | + .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; } |
| 348 | + .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; } |
| 349 | + .note { font-size:80%; } |
| 350 | + .terselist, .terselist li { display: inline; margin:0; padding:0; } |
| 351 | + .terselist li { display: inline; } |
| 352 | + .terselist li:before { content:" - " } |
| 353 | + .terselist li:first-child:before { content:"" } |
| 354 | + |
| 355 | + .gallery li { display: inline; padding:0.5ex; margin:0.5ex; } |
| 356 | + </style> |
| 357 | +</head> |
| 358 | +<body> |
| 359 | + <div class="header"> |
| 360 | + <h1>WikiWord Navigator</h1> |
| 361 | + <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p> |
| 362 | + <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>. |
| 363 | + It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p> |
| 364 | + </div> |
| 365 | + |
| 366 | + <div class="inputform" > |
| 367 | + <form name="search" action="<?php print $wwSelf; ?>"> |
| 368 | + <table border="0" class="inputgrid"> |
| 369 | + <tr> |
| 370 | + <td> |
| 371 | + <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/> |
| 372 | + </td> |
| 373 | + <td> |
| 374 | + <label for="term" style="display:none">Language: </label> |
| 375 | + <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?> |
| 376 | + </td> |
| 377 | + <td> |
| 378 | + <input type="submit" name="go" value="go"/> |
| 379 | + </td> |
| 380 | + <?php if ($wwImageSearch === null) { ?> |
| 381 | + <td> |
| 382 | + <label for="images">Images: </label> |
| 383 | + <input type="checkbox" name="images" value="Images" <?php print $images ? " checked=\"checked\"" : ""?>/> |
| 384 | + </td> |
| 385 | + <?php } ?> |
| 386 | + </tr> |
| 387 | + <?php if ($wwAllowTranslate) { ?> |
| 388 | + <tr> |
| 389 | + <td> |
| 390 | + |
| 391 | + </td> |
| 392 | + <td> |
| 393 | + <label for="term" style="display:none">Translate: </label> |
| 394 | + <?php WWUtils::printSelector("tolang", $wwLanguages, @$_REQUEST['tolang']) ?> |
| 395 | + </td> |
| 396 | + <td> |
| 397 | + <input type="submit" name="translate" value="translate"/> |
| 398 | + </td> |
| 399 | + </tr> |
| 400 | + <?php } ?> |
| 401 | + </table> |
| 402 | + <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered, matching is case-sensitive.</p> |
| 403 | + </form> |
| 404 | + </div> |
| 405 | +<?php |
| 406 | +if ($error) { |
| 407 | + print "<p class=\"error\">".htmlspecialchars($error)."</p>"; |
| 408 | +} |
| 409 | +?> |
| 410 | + |
| 411 | +<?php |
| 412 | +if ($result && $concept) { |
| 413 | + foreach ( $result as $row ) { |
| 414 | + if (@$row['id']) $id = $row['id']; |
| 415 | + else if (@$row['concept']) $id = $row['concept']; |
| 416 | + else $id = "concept"; |
| 417 | + |
| 418 | +?> |
| 419 | + <div id="<?php print htmlspecialchars("concept-$id")?>"> |
| 420 | + |
| 421 | + <table border="0" class="results"> |
| 422 | + <?php |
| 423 | + if ($lang) { |
| 424 | + $continue= printLocalConcept($lang, $row, NULL, NULL, 0, false); |
| 425 | + } |
| 426 | + //else $continue= printGlobalConcept($lang, $row, $count); |
| 427 | + |
| 428 | + if (!$continue) break; |
| 429 | + ?> |
| 430 | + </table> |
| 431 | + </div> |
| 432 | + |
| 433 | +<?php |
| 434 | + } #concept loop |
| 435 | +} else if ($result && $term) { |
| 436 | + if ($tolang) $title = "$lang: $term -> $tolang"; |
| 437 | + else if ($term) $title = "$lang: $term"; |
| 438 | +?> |
| 439 | + <h2><?php print htmlspecialchars($title); ?></h2> |
| 440 | + <table border="0" class="results"> |
| 441 | + <?php |
| 442 | + $count = 0; |
| 443 | + foreach ( $result as $row ) { |
| 444 | + $count += 1; |
| 445 | + |
| 446 | + if ($lang) { |
| 447 | + $show_single = true; |
| 448 | + |
| 449 | + if ($tolang && isset($row['global_concept'])) { |
| 450 | + $toresult = $utils->queryConceptInfo($row['global_concept'], $tolang); |
| 451 | + while ($torow = mysql_fetch_assoc($toresult)) { |
| 452 | + $continue= printLocalConcept($lang, $row, $tolang, $torow, $count, true); |
| 453 | + $show_single = false; |
| 454 | + } |
| 455 | + mysql_free_result($toresult); |
| 456 | + } |
| 457 | + |
| 458 | + if ($show_single) { |
| 459 | + $continue= printLocalConcept($lang, $row, NULL, NULL, $count, true); |
| 460 | + } |
| 461 | + } |
| 462 | + //else $continue= printGlobalConcept($lang, $row, $count); |
| 463 | + |
| 464 | + if (!$continue) break; |
| 465 | + } |
| 466 | + ?> |
| 467 | + </table> |
| 468 | + |
| 469 | + <p>Found <?php print $count; ?> items.</p> |
| 470 | + |
| 471 | +<?php |
| 472 | +} |
| 473 | +?> |
| 474 | + |
| 475 | +<p class="footer"> |
| 476 | +The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a> |
| 477 | +<p> |
| 478 | +</body> |
| 479 | +</html> |
| 480 | +<?php |
| 481 | +$utils->close(); |
| 482 | +?> |
\ No newline at end of file |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/search/wikiword.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 483 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/search/wikipics.php |
— | — | @@ -0,0 +1,340 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +$IP = dirname(__FILE__); |
| 5 | + |
| 6 | +require_once("$IP/config.php"); |
| 7 | +require_once("$IP/wwimages.php"); |
| 8 | + |
| 9 | +if ($wwAPI) require_once("$IP/wwclient.php"); |
| 10 | +else require_once("$IP/wwthesaurus.php"); |
| 11 | + |
| 12 | +function printConceptList($concepts, $lang) { |
| 13 | + ?> |
| 14 | + <ul class="terselist"> |
| 15 | + <?php |
| 16 | + foreach ($concepts as $c) { |
| 17 | + ?><li><?php |
| 18 | + print getConceptDetailsLink($lang, $c); |
| 19 | + ?></li><?php |
| 20 | + } |
| 21 | + ?> |
| 22 | + </ul> |
| 23 | + <?php |
| 24 | +} |
| 25 | + |
| 26 | +function printConceptImageList($concept, $class = "terselist") { |
| 27 | + global $utils, $wwThumbSize, $wwMaxPreviewImages; |
| 28 | + |
| 29 | + if (!$concept) return false; |
| 30 | + |
| 31 | + if (is_array($concept) && !isset($concept['id']) && isset($concept[0])) $images = $concept; #XXX: HACK |
| 32 | + else $images = $utils->getImagesAbout($concept, $wwMaxPreviewImages); |
| 33 | + |
| 34 | + ?> |
| 35 | + <ul class="<?php print $class; ?>"> |
| 36 | + <?php |
| 37 | + foreach ($images as $img) { |
| 38 | + ?><li><?php |
| 39 | + print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize); |
| 40 | + ?></li><?php |
| 41 | + } |
| 42 | + ?> |
| 43 | + </ul> |
| 44 | + <?php |
| 45 | +} |
| 46 | + |
| 47 | +function getConceptDetailsURL($langs, $concept) { |
| 48 | + global $wwSelf; |
| 49 | + |
| 50 | + if ( is_array($langs) ) $langs = implode('|', $langs); |
| 51 | + |
| 52 | + return "$wwSelf?id=" . urlencode($concept['id']) . "&lang=" . urlencode($langs); |
| 53 | +} |
| 54 | + |
| 55 | +function getConceptDetailsLink($langs, $concept) { |
| 56 | + global $utils; |
| 57 | + $name = $utils->pickLocal($concept['name'], $langs); |
| 58 | + |
| 59 | + $u = getConceptDetailsURL($langs, $concept); |
| 60 | + return '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars($name) . '</a>'; |
| 61 | +} |
| 62 | + |
| 63 | +function pickPage( $pages ) { |
| 64 | + if (!$pages) return false; |
| 65 | + |
| 66 | + foreach ( $pages as $page => $type ) { |
| 67 | + if ($type == 10) return $page; |
| 68 | + } |
| 69 | + |
| 70 | + return $pages[0]; |
| 71 | +} |
| 72 | + |
| 73 | +function getConceptPageURLs($lang, $concept) { |
| 74 | + if (!isset($concept['pages'][$lang]) || !$concept['pages'][$lang]) return false; |
| 75 | + |
| 76 | + if ($lang == 'commons') $domain = 'commons.wikimedia.org'; |
| 77 | + else $domain = "$lang.wikipedia.org"; |
| 78 | + |
| 79 | + $urls = array(); |
| 80 | + foreach ($concept['pages'][$lang] as $page => $type) { |
| 81 | + $u = "http://$domain/wiki/" . urlencode($page); |
| 82 | + $links[$page] = $u; |
| 83 | + } |
| 84 | + |
| 85 | + return $urls; |
| 86 | +} |
| 87 | + |
| 88 | +function getConceptPageLinks($lang, $concept) { |
| 89 | + $urls = getConceptPageURLs($lang, $concept); |
| 90 | + if (!$urls) return false; |
| 91 | + |
| 92 | + foreach ($urls as $page => $u) { |
| 93 | + $u = "http://$domain/wiki/" . urlencode($page); |
| 94 | + $links[] = '<a href="' . htmlspecialchars($u) . '">' . htmlspecialchars( str_replace("_", " ", $page) ) . '</a>'; |
| 95 | + } |
| 96 | + |
| 97 | + return $links; |
| 98 | +} |
| 99 | + |
| 100 | +function getAllConceptPageLinks($concept) { |
| 101 | + $links = array(); |
| 102 | + |
| 103 | + foreach ( $concept['languages'] as $lang ) { |
| 104 | + $ll = getConceptPageLinks($lang, $concept); |
| 105 | + if ($ll) $links[$lang] = $ll; |
| 106 | + } |
| 107 | + |
| 108 | + return $links; |
| 109 | +} |
| 110 | + |
| 111 | +function printList($items, $escape = true, $class = "list") { |
| 112 | + ?> |
| 113 | + <ul class="<?php print htmlspecialchars($class); ?>"> |
| 114 | + <?php |
| 115 | + foreach ($items as $item) { |
| 116 | + if ( $escape ) $item = htmlspecialchars($item); |
| 117 | + print "\t\t<li>" . $item . "</li>\n"; |
| 118 | + } |
| 119 | + ?> |
| 120 | + </ul> |
| 121 | + <?php |
| 122 | +} |
| 123 | + |
| 124 | +function printDefList($items, $scapeKeys = true, $escapeValues = true, $class = "list") { |
| 125 | + ?> |
| 126 | + <dl class="<?php print htmlspecialchars($class); ?>"> |
| 127 | + <?php |
| 128 | + foreach ($items as $key => $item) { |
| 129 | + if ( $escapeKeys ) $key = htmlspecialchars($key); |
| 130 | + print "\t\t<dt>" . $key . "</dt>\n"; |
| 131 | + |
| 132 | + if ( $escapeValues ) $item = htmlspecialchars($item); |
| 133 | + print "\t\t\t<dd>" . $item . "</dd>\n"; |
| 134 | + } |
| 135 | + ?> |
| 136 | + </sl> |
| 137 | + <?php |
| 138 | +} |
| 139 | + |
| 140 | +function getWeightClass($weight) { |
| 141 | + if (!isset($weight) || !$weight) { |
| 142 | + return "unknown"; |
| 143 | + $weight = NULL; |
| 144 | + } |
| 145 | + else if ($weight>1000) return "huge"; |
| 146 | + else if ($weight>100) return "big"; |
| 147 | + else if ($weight>10) return "normal"; |
| 148 | + else if ($weight>2) return "some"; |
| 149 | + else return "little"; |
| 150 | +} |
| 151 | + |
| 152 | +function printConcept($concept, $langs, $terse = true) { |
| 153 | + global $utils, $wwMaxPreviewImages, $wwMaxGalleryImages; |
| 154 | + |
| 155 | + extract( $concept ); |
| 156 | + $wclass = getWeightClass($score); |
| 157 | + |
| 158 | + ?> |
| 159 | + <tr class="row_item"> |
| 160 | + <td class="cell_weight <?php print "weight_$wclass"; ?>"><?php print htmlspecialchars($score); ?></td> |
| 161 | + <td colspan="3" class="cell_name <?php print "weight_$wclass"; ?>"> |
| 162 | + <h3> |
| 163 | + <?php print getConceptDetailsLink($langs, $concept); ?> |
| 164 | + <?php /* TODO: wiki links */ ?> |
| 165 | + </h3> |
| 166 | + </td> |
| 167 | + </tr> |
| 168 | + |
| 169 | + <?php if (isset($definition) && !empty($definition)) { |
| 170 | + $definition = $utils->pickLocal($definition, $langs); |
| 171 | + ?> |
| 172 | + |
| 173 | + <tr class="row_def"> |
| 174 | + <td></td> |
| 175 | + <td colspan="3"><?php print htmlspecialchars($definition); ?></td> |
| 176 | + </tr> |
| 177 | + <?php } ?> |
| 178 | + |
| 179 | + <tr class="row_details row_images"> |
| 180 | + <td></td> |
| 181 | + <td class="cell_images" colspan="3"> |
| 182 | + <?php |
| 183 | + $gallery = $utils->getImagesAbout($concept, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages ); |
| 184 | + $c = printConceptImageList( $gallery, $terse ? "terselist" : "gallery" ); |
| 185 | + ?> |
| 186 | + </td> |
| 187 | + </tr> |
| 188 | + |
| 189 | + |
| 190 | + <?php |
| 191 | + if (isset($score) && $score && $score<2 && $pos>=3) return false; |
| 192 | + else return true; |
| 193 | +} |
| 194 | + |
| 195 | +$conceptId = @$_REQUEST['id']; |
| 196 | +$term = @$_REQUEST['term']; |
| 197 | +$lang = @$_REQUEST['lang']; |
| 198 | + |
| 199 | +if (!isset($wwSelf)) $wwSelf = @$_SERVER["PHP_SELF"]; |
| 200 | + |
| 201 | +$error = NULL; |
| 202 | + |
| 203 | +if ($lang && !isset($wwLanguages[$lang])) { |
| 204 | + $lang = NULL; |
| 205 | + $error = "bad language code: $lang"; |
| 206 | +} |
| 207 | + |
| 208 | +if ($wwAPI) $thesaurus = new WWClient($wwAPI); |
| 209 | +else { |
| 210 | + $thesaurus = new WWThesaurus(); |
| 211 | + $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
| 212 | +} |
| 213 | + |
| 214 | +$utils = new WWImages( $thesaurus ); |
| 215 | +if ( !$utils->db ) $utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
| 216 | + |
| 217 | +if (@$_REQUEST['debug']) $utils->debug = true; |
| 218 | + |
| 219 | +$limit = 20; |
| 220 | +$norm = 1; |
| 221 | + |
| 222 | +$result = NULL; |
| 223 | + |
| 224 | +$languages = array( $lang, "en", "commons" ); #TODO: make the user define this list |
| 225 | + |
| 226 | +if (!$error) { |
| 227 | + try { |
| 228 | + if ($lang && $conceptId) { |
| 229 | + $result = $thesaurus->getConceptInfo($conceptId, $lang); |
| 230 | + if ( $result ) $result = array( $result ); //hack |
| 231 | + } else if ($lang && $term) { |
| 232 | + $result = $thesaurus->getConceptsForTerm($lang, $term, $languages, $norm, $limit); |
| 233 | + } |
| 234 | + } catch (Exception $e) { |
| 235 | + $error = $e->getMessage(); |
| 236 | + } |
| 237 | +} |
| 238 | + |
| 239 | + |
| 240 | +?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| 241 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> |
| 242 | +<head> |
| 243 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| 244 | + <title>WikiWord Navigator</title> |
| 245 | + |
| 246 | + <style type="text/css"> |
| 247 | + body { font-family: verdana, helvetica, arial, sans-serif; } |
| 248 | + td { text-align: left; vertical-align: top; } |
| 249 | + th { text-align: left; vertical-align: top; font-weight:bold; } |
| 250 | + .error { color: red; font-weight: bold; } |
| 251 | + .weight_huge { font-size: 140%; font-weight:bold; } |
| 252 | + .weight_big { font-size: 120%; font-weight:bold; } |
| 253 | + .weight_normal { font-size: 110%; font-weight:bold; } |
| 254 | + .weight_some { font-size: 100%; font-weight:bold; } |
| 255 | + .weight_little { font-size: 90%; font-weight:bold; } |
| 256 | + .weight_unknown { font-size: 100%; font-weight:bold; } |
| 257 | + .row_def td { font-size: 80%; font-style:italic; } |
| 258 | + .row_details td { font-size: 80%; } |
| 259 | + .cell_weight { text-align: right; } |
| 260 | + .cell_label { text-align: right; } |
| 261 | + .header { text-align: left; } |
| 262 | + .inputform { text-align: center; margin:1ex auto; padding:1ex; width:80%; border:1px solid #666666; background-color:#DDDDDD; } |
| 263 | + .footer { font-size:80%; text-align: center; border-top: 1px solid #666666; } |
| 264 | + .note { font-size:80%; } |
| 265 | + .terselist, .terselist li { display: inline; margin:0; padding:0; } |
| 266 | + .terselist li { display: inline; } |
| 267 | + .terselist li:before { content:" - " } |
| 268 | + .terselist li:first-child:before { content:"" } |
| 269 | + |
| 270 | + .gallery li { display: inline; padding:0.5ex; margin:0.5ex; } |
| 271 | + </style> |
| 272 | +</head> |
| 273 | +<body> |
| 274 | + <div class="header"> |
| 275 | + <h1>WikiWord Navigator</h1> |
| 276 | + <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p> |
| 277 | + <p>The WikiWord Navigator was created as part of the WikiWord project run by <a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a>. |
| 278 | + It is based on a <a href="http://brightbyte.de/page/WikiWord">diploma thesis</a> by Daniel Kinzler, and runs on the <a href="http://toolserver.org/">Wikimedia Toolserver</a>. WikiWord is an ongoing research project. Please contact <a href="http://brightbyte.de/page/Special:Contact">Daniel Kinzler</a> for more information.</p> |
| 279 | + </div> |
| 280 | + |
| 281 | + <div class="inputform" > |
| 282 | + <form name="search" action="<?php print $wwSelf; ?>"> |
| 283 | + <table border="0" class="inputgrid"> |
| 284 | + <tr> |
| 285 | + <td> |
| 286 | + <label for="term">Term: </label><input type="text" name="term" id="term" size="24" value="<?php print htmlspecialchars($term); ?>"/> |
| 287 | + </td> |
| 288 | + <td> |
| 289 | + <label for="term" style="display:none">Language: </label> |
| 290 | + <?php WWUtils::printSelector("lang", $wwLanguages, $lang) ?> |
| 291 | + </td> |
| 292 | + <td> |
| 293 | + <input type="submit" name="go" value="go"/> |
| 294 | + </td> |
| 295 | + </tr> |
| 296 | + </table> |
| 297 | + <p class="note">Note: this is a thesaurus lookup, not a full text search. Only exact matches are considered.</p> |
| 298 | + </form> |
| 299 | + </div> |
| 300 | +<?php |
| 301 | +if ($error) { |
| 302 | + print "<p class=\"error\">".htmlspecialchars($error)."</p>"; |
| 303 | +} |
| 304 | +?> |
| 305 | + |
| 306 | +<?php |
| 307 | +if ($result) { |
| 308 | + if ( $conceptId ) $terse = false; |
| 309 | + else $terse = true; |
| 310 | + |
| 311 | + $count = 0; |
| 312 | + foreach ( $result as $row ) { |
| 313 | + $count = $count + 1; |
| 314 | + $row['pos'] = $count; |
| 315 | + |
| 316 | +?> |
| 317 | + <table border="0" class="results"> |
| 318 | + <?php |
| 319 | + $continue= printConcept($row, $languages, $terse); |
| 320 | + |
| 321 | + if (!$continue) break; |
| 322 | + ?> |
| 323 | + </table> |
| 324 | + </div> |
| 325 | + |
| 326 | +<?php |
| 327 | + } #concept loop |
| 328 | + |
| 329 | + if ($term) { ?> |
| 330 | + <p>Found <?php print $count; ?> items.</p> |
| 331 | + <?php } |
| 332 | +} ?> |
| 333 | + |
| 334 | +<p class="footer"> |
| 335 | +The WikiWord Navigator is part of the <a href="http://wikimedia.de">Wikimedia</a> project <a href="http://brightbyte.de/page/WikiWord">WikiWord</a> |
| 336 | +<p> |
| 337 | +</body> |
| 338 | +</html> |
| 339 | +<?php |
| 340 | +$utils->close(); |
| 341 | +?> |
\ No newline at end of file |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/search/wikipics.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 342 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwclient.php |
— | — | @@ -0,0 +1,152 @@ |
| 2 | +<?php |
| 3 | +require_once( dirname( __FILE__ ) . "/wwutils.php" ); |
| 4 | + |
| 5 | +class WWClient { |
| 6 | + var $api; |
| 7 | + |
| 8 | + function __construct( $api ) { |
| 9 | + $this->api = $api; |
| 10 | + } |
| 11 | + |
| 12 | + function query( $params ) { |
| 13 | + $url = $this->api . '?format=phps'; |
| 14 | + |
| 15 | + foreach ( $params as $k => $v ) { |
| 16 | + if ($v===null) continue; |
| 17 | + if ($v===false) $v = ""; |
| 18 | + if (is_array($v)) $v = implode("|", $v); |
| 19 | + |
| 20 | + $url .= '&'; |
| 21 | + $url .= urlencode( $k ); |
| 22 | + $url .= '='; |
| 23 | + $url .= urlencode( $v ); |
| 24 | + } |
| 25 | + |
| 26 | + $data = file_get_contents( $url ); //TODO: CURL |
| 27 | + if ( !$data ) throw new Exception("failed to fetch data from $url"); |
| 28 | + |
| 29 | + $data = unserialize($data); |
| 30 | + if ( !$data ) throw new Exception("failed to unserialize data from $url"); |
| 31 | + |
| 32 | + if ( @$data['error'] ) throw new Exception("API returned error ".$data['error']['code'].": ".$data['error']['message']."; url: $url"); |
| 33 | + return $data; |
| 34 | + } |
| 35 | + |
| 36 | + function getPagesForConcept( $id, $lang = null ) { |
| 37 | + $p = $this->getConceptInfo( $id, $lang ); |
| 38 | + return $p['pages']; |
| 39 | + } |
| 40 | + |
| 41 | + /* |
| 42 | + function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat |
| 43 | + return getPagesForConcept($id); |
| 44 | + } |
| 45 | + |
| 46 | + function getConcept( $id, $lang = null ) { |
| 47 | + $p = $this->getConceptProperties( $id, '', $lang );getConceptInfo |
| 48 | + return $p['pages']; |
| 49 | + } |
| 50 | + |
| 51 | + function getRelatedForConcept( $id, $lang = null ) { |
| 52 | + $p = $this->getConceptProperties( $id, 'related', $lang ); |
| 53 | + return $p['related']; |
| 54 | + } |
| 55 | + |
| 56 | + function getBroaderForConcept( $id, $lang = null ) { |
| 57 | + $p = $this->getConceptProperties( $id, 'broader', $lang ); |
| 58 | + return $p['broader']; |
| 59 | + } |
| 60 | + |
| 61 | + function getNarrowerForConcept( $id, $lang = null ) { |
| 62 | + $p = $this->getConceptProperties( $id, 'narrower', $lang ); |
| 63 | + return $p['narrower']; |
| 64 | + } |
| 65 | + |
| 66 | + function getTermsForConcept( $id, $lang = null ) { |
| 67 | + $p = $this->getConceptProperties( $id, 'terms', $lang ); |
| 68 | + return $p['terms']; |
| 69 | + } |
| 70 | + |
| 71 | + function getDefinitionForConcept( $id, $lang = null ) { |
| 72 | + $p = $this->getConceptProperties( $id, 'definition', $lang ); |
| 73 | + return $p['definition']; |
| 74 | + } |
| 75 | + |
| 76 | + function getReferencesForConcept( $id, $lang = null ) { |
| 77 | + $p = $this->getConceptProperties( $id, 'links', $lang ); |
| 78 | + return $p['references']; |
| 79 | + } |
| 80 | + |
| 81 | + function getLinksForConcept( $id, $lang = null ) { |
| 82 | + $p = $this->getConceptProperties( $id, 'links', $lang ); |
| 83 | + return $p['links']; |
| 84 | + } |
| 85 | + |
| 86 | + function getScoresForConcept( $id, $lang = null ) { |
| 87 | + $p = $this->getConceptProperties( $id, 'scores', $lang ); |
| 88 | + return $p['scores']; |
| 89 | + }*/ |
| 90 | + |
| 91 | + function getConceptInfo( $id, $lang = null ) { |
| 92 | + $param = array( |
| 93 | + 'query' => 'info', |
| 94 | + 'gcid' => $id, |
| 95 | + 'lang' => $lang |
| 96 | + ); |
| 97 | + |
| 98 | + $rs = $this->query( $param ); |
| 99 | + |
| 100 | + if (!isset($rs['id'])) $rs['id'] = $id; |
| 101 | + if (!isset($rs['lang'])) $rs['lang'] = $lang; |
| 102 | + |
| 103 | + return $rs; |
| 104 | + } |
| 105 | + |
| 106 | + /* |
| 107 | + function getConceptProperties( $id, $props, $lang =$props null ) { |
| 108 | + $param = array( |
| 109 | + 'query' => 'properties', |
| 110 | + 'props' => ( is_array($props) ? join('|', $props) : $props ), |
| 111 | + 'gcid' => $id, |
| 112 | + ); |
| 113 | + |
| 114 | + if ( $lang ) $param['lang'] = $lang; |
| 115 | + |
| 116 | + $rs = $this->query( $param ); |
| 117 | + |
| 118 | + if (!isset($rs['id'])) $rs['id'] = $id; |
| 119 | + if (!isset($rs['lang'])) $rs['lang'] = $lang; |
| 120 | + |
| 121 | + return $rs; |
| 122 | + }*/ |
| 123 | + |
| 124 | + function getConceptsForTerm( $qlang, $term, $languages, $norm = 1, $limit = 100 ) { |
| 125 | + if ( is_array( $languages ) ) $languages = implode('|', $languages); |
| 126 | + |
| 127 | + $param = array( |
| 128 | + 'query' => 'concepts', |
| 129 | + 'qlang' => $qlang, |
| 130 | + 'lang' => $languages, |
| 131 | + 'norm' => $norm, |
| 132 | + 'term' => $term, |
| 133 | + ); |
| 134 | + |
| 135 | + $rs = $this->query( $param ); |
| 136 | + |
| 137 | + return $rs['concepts']; |
| 138 | + } |
| 139 | + |
| 140 | + /* |
| 141 | + function getConceptsForPage( $lang, $page ) { |
| 142 | + $param = array( |
| 143 | + 'query' => 'concepts', |
| 144 | + 'lang' => $lang, |
| 145 | + 'page' => $page, |
| 146 | + ); |
| 147 | + |
| 148 | + $rs = $this->query( $param ); |
| 149 | + |
| 150 | + return $rs['concepts']; |
| 151 | + } |
| 152 | + */ |
| 153 | +} |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwclient.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 154 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwtest.php |
— | — | @@ -0,0 +1,20 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +$IP = dirname(__FILE__); |
| 5 | + |
| 6 | +require_once("$IP/config.php"); |
| 7 | +require_once("$IP/wwutils.php"); |
| 8 | + |
| 9 | +$utils = new WWUtils(); |
| 10 | +$utils->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
| 11 | + |
| 12 | +$utils->debug = true; |
| 13 | + |
| 14 | +if (!isset($argv[1])) die("usage: wwtest <id>\n"); |
| 15 | + |
| 16 | +$id = $argv[1]; |
| 17 | +$max = @$argv[2]; |
| 18 | + |
| 19 | +$images = $utils->getImagesAbout($id, $max); |
| 20 | + |
| 21 | +print_r($images); |
\ No newline at end of file |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwtest.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 22 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwutils.php |
— | — | @@ -0,0 +1,200 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class WWUtils { |
| 5 | + var $debug = false; |
| 6 | + var $db = NULL; |
| 7 | + |
| 8 | + var $dbuser; |
| 9 | + var $dbpassword; |
| 10 | + |
| 11 | + function connect($server, $user, $password, $database) { |
| 12 | + $db = mysql_connect($server, $user, $password) or die("Connection Failure to Database: " . htmlspecialchars(mysql_error())."\n"); |
| 13 | + mysql_select_db($database, $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n"); |
| 14 | + mysql_query("SET NAMES UTF8;", $db) or die ("Database not found: " . htmlspecialchars(mysql_error())."\n"); |
| 15 | + |
| 16 | + $this->dbuser = $user; |
| 17 | + $this->dbpassword = $password; |
| 18 | + $this->db = $db; |
| 19 | + |
| 20 | + return $db; |
| 21 | + } |
| 22 | + |
| 23 | + function query($sql, $db = NULL) { |
| 24 | + if ($db == NULL && isset($this)) $db = $this->db; |
| 25 | + |
| 26 | + if ($this->debug) { |
| 27 | + print "\n<br/>" . htmlspecialchars($sql) . "<br/>\n"; |
| 28 | + } |
| 29 | + |
| 30 | + if (!$db) { |
| 31 | + throw new Exception("not connected!"); |
| 32 | + } |
| 33 | + |
| 34 | + $result = mysql_query($sql, $db); |
| 35 | + |
| 36 | + if(!$result) { |
| 37 | + $error = mysql_error($db); |
| 38 | + $errno = mysql_errno($db); |
| 39 | + throw new Exception("$error (#$errno);\nlast query: $sql"); |
| 40 | + } |
| 41 | + |
| 42 | + return $result; |
| 43 | + } |
| 44 | + |
| 45 | + function quote($s) { |
| 46 | + if (is_array($s)) throw new Exception("can't quote arrays, use quoteSet() instead."); |
| 47 | + if (is_null($s)) return "NULL"; |
| 48 | + |
| 49 | + return '"' . mysql_real_escape_string($s) . '"'; |
| 50 | + } |
| 51 | + |
| 52 | + function quoteSet($a) { |
| 53 | + if (!$a) throw new Exception("empty set literal not supported by mysql"); |
| 54 | + |
| 55 | + if ( !is_array($a) ) $a = array( $a ); |
| 56 | + |
| 57 | + $s = ""; |
| 58 | + |
| 59 | + foreach ($a as $x) { |
| 60 | + if ($s) $s.= ", "; |
| 61 | + |
| 62 | + if (is_string($x)) $s .= $this->quote($x); |
| 63 | + else $s .= $x; |
| 64 | + } |
| 65 | + |
| 66 | + return '(' . $s . ')'; |
| 67 | + } |
| 68 | + |
| 69 | + function close() { |
| 70 | + if ($this->db) mysql_close($this->db); |
| 71 | + $this->db = NULL; |
| 72 | + |
| 73 | + foreach ($this->wikidbs as $name => $db) { |
| 74 | + if ($db) mysql_close($db); |
| 75 | + } |
| 76 | + |
| 77 | + $this->wikidbs = array(); |
| 78 | + } |
| 79 | + |
| 80 | + function getRows($sql, $key = NULL) { |
| 81 | + $rs = $this->query($sql); |
| 82 | + $list = WWUtils::slurpRows($rs, $key); |
| 83 | + mysql_free_result($rs); |
| 84 | + return $list; |
| 85 | + } |
| 86 | + |
| 87 | + function getList($sql, $valueField, $key = NULL) { |
| 88 | + $rs = $this->query($sql); |
| 89 | + $list = WWUtils::slurpList($rs, $valueField, $key); |
| 90 | + mysql_free_result($rs); |
| 91 | + return $list; |
| 92 | + } |
| 93 | + |
| 94 | + static function slurpList($rs, $field, $key = null) { |
| 95 | + if (is_string($rs)) $rs = $this->query($rs); |
| 96 | + |
| 97 | + $list = array(); |
| 98 | + while ($row = mysql_fetch_assoc($rs)) { |
| 99 | + if (is_array($field)) { |
| 100 | + $value = array(); |
| 101 | + foreach ($field as $f) { |
| 102 | + $value[$f] = $row[$f]; |
| 103 | + } |
| 104 | + } else { |
| 105 | + $value = $row[$field]; |
| 106 | + } |
| 107 | + |
| 108 | + if ($key) { |
| 109 | + $k = $row[$key]; |
| 110 | + $list[$k] = $value; |
| 111 | + } else { |
| 112 | + $list[] = $value; |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + return $list; |
| 117 | + } |
| 118 | + |
| 119 | + static function slurpRows($rs, $key = null) { |
| 120 | + if (is_string($rs)) $rs = $this->query($rs); |
| 121 | + |
| 122 | + $list = array(); |
| 123 | + while ($row = mysql_fetch_assoc($rs)) { |
| 124 | + if ($key) { |
| 125 | + $k = $row[$key]; |
| 126 | + $list[$k] = $row; |
| 127 | + } else { |
| 128 | + $list[] = $row; |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + return $list; |
| 133 | + } |
| 134 | + |
| 135 | + static function slurpAssoc($rs, $keyField, $valueField) { |
| 136 | + if (is_string($rs)) $rs = $this->query($rs); |
| 137 | + |
| 138 | + $list = array(); |
| 139 | + while ($row = mysql_fetch_assoc($rs)) { |
| 140 | + $key = $row[$keyField]; |
| 141 | + |
| 142 | + if (is_array($valueField)) { |
| 143 | + $value = array(); |
| 144 | + foreach ($valueField as $f) { |
| 145 | + $value[$f] = $row[$f]; |
| 146 | + } |
| 147 | + } else { |
| 148 | + $value = $row[$valueField]; |
| 149 | + } |
| 150 | + |
| 151 | + $list[$key] = $value; |
| 152 | + } |
| 153 | + |
| 154 | + return $list; |
| 155 | + } |
| 156 | + |
| 157 | + function pickLocal($items, $languages) { |
| 158 | + if ( is_string($languages) ) $languages = array( $languages, "en", "commons" ); |
| 159 | + |
| 160 | + foreach ($languages as $lang) { |
| 161 | + if (isset($items[$lang])) return $items[$lang]; |
| 162 | + } |
| 163 | + |
| 164 | + return false; |
| 165 | + } |
| 166 | + |
| 167 | + static function authFailed($realm) { |
| 168 | + header("Status: 401 Unauthorized", true, 401); |
| 169 | + header('WWW-Authenticate: Basic realm="'.$realm.'"'); |
| 170 | + die(); |
| 171 | + } |
| 172 | + |
| 173 | + static function doBasicHttpAuth($passwords, $realm) { |
| 174 | + if (!isset($_SERVER['PHP_AUTH_USER'])) { |
| 175 | + authFailed(); |
| 176 | + } |
| 177 | + |
| 178 | + $usr = $_SERVER['PHP_AUTH_USER']; |
| 179 | + if (!isset($passwords[$usr])) { |
| 180 | + authFailed(); |
| 181 | + } |
| 182 | + |
| 183 | + $pw = $_SERVER['PHP_AUTH_PW']; |
| 184 | + if ($pw != $passwords[$usr]) { |
| 185 | + authFailed(); |
| 186 | + } |
| 187 | + |
| 188 | + return $usr; |
| 189 | + } |
| 190 | + |
| 191 | + static function printSelector($name, $choices, $current = NULL) { |
| 192 | + print "\n\t\t<select name=\"".htmlspecialchars($name)."\" id=\"".htmlspecialchars($name)."\">\n"; |
| 193 | + |
| 194 | + foreach ($choices as $choice => $name) { |
| 195 | + $sel = $choice == $current ? " selected=\"selected\"" : ""; |
| 196 | + print "\t\t\t<option value=\"".htmlspecialchars($choice)."\"$sel>".htmlspecialchars($name)."</option>\n"; |
| 197 | + } |
| 198 | + |
| 199 | + print "</select>"; |
| 200 | + } |
| 201 | +} |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwutils.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 202 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwthesaurus.php |
— | — | @@ -0,0 +1,498 @@ |
| 2 | +<?php |
| 3 | +require_once(dirname(__FILE__)."/wwutils.php"); |
| 4 | + |
| 5 | + /** Unknown type, SHOULD not occurr in final data. MAY be used for |
| 6 | + * resources that are referenced but where not available for analysis, |
| 7 | + * or have not yet been analyzed. |
| 8 | + **/ |
| 9 | + define('WW_RC_TYPE_UNKNOWN', 0); |
| 10 | + |
| 11 | + /** |
| 12 | + * A "real" page, describing a concept. |
| 13 | + */ |
| 14 | + define('WW_RC_TYPE_ARTICLE', 10); |
| 15 | + |
| 16 | + /** |
| 17 | + * This page is a supplemental part of an article, typically a transcluded |
| 18 | + * subpage or simmilar. |
| 19 | + */ |
| 20 | + define('WW_RC_TYPE_SUPPLEMENT', 15); |
| 21 | + |
| 22 | + |
| 23 | + /** |
| 24 | + * A page solely defining a redirect/alias for another page |
| 25 | + */ |
| 26 | + define('WW_RC_TYPE_REDIRECT', 20); |
| 27 | + |
| 28 | + /** |
| 29 | + * A disambuguation page, listing different meanings for the page title, |
| 30 | + * each linking to a article page. |
| 31 | + */ |
| 32 | + define('WW_RC_TYPE_DISAMBIG', 30); |
| 33 | + |
| 34 | + /** |
| 35 | + * A page that contains a list of concepts that share some common property or quality, |
| 36 | + * usually each linking to a page describing that concept. |
| 37 | + */ |
| 38 | + define('WW_RC_TYPE_LIST', 40); |
| 39 | + |
| 40 | + /** |
| 41 | + * A category page. |
| 42 | + */ |
| 43 | + define('WW_RC_TYPE_CATEGORY', 50); |
| 44 | + |
| 45 | + /** |
| 46 | + * This page does not contain relevant information for WikiWord |
| 47 | + */ |
| 48 | + define('WW_RC_TYPE_OTHER', 99); |
| 49 | + |
| 50 | + /** |
| 51 | + * A page that is broken in some way, or was marked as bad or disputed. Such pages |
| 52 | + * SHOULD generally be treated as if theys didn't exist. |
| 53 | + */ |
| 54 | + define('WW_RC_TYPE_BAD', 100); |
| 55 | + |
| 56 | + /** |
| 57 | + * A resource that is not a page by itself, but merely a section of a page. Sections |
| 58 | + * SHOULD always be part of a page of type ARTICLE, and are expected to descibe |
| 59 | + * a narrower concept than the "parent" page. |
| 60 | + */ |
| 61 | + define('WW_RC_TYPE_SECTION', 200); |
| 62 | + |
| 63 | + |
| 64 | +class WWThesaurus extends WWUTils { |
| 65 | + |
| 66 | + function normalizeSearchString( $s, $norm = 1 ) { |
| 67 | + if ( $norm >= 1 ) $s = mb_strtolower($s, "utf-8"); |
| 68 | + if ( $norm >= 1 ) $s = str_replace("-", "", $s); |
| 69 | + |
| 70 | + #TODO: 2: whitespace and punctuation |
| 71 | + #TODO: 3: translit |
| 72 | + |
| 73 | + return $s; |
| 74 | + } |
| 75 | + |
| 76 | + function queryConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) { |
| 77 | + global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages; |
| 78 | + |
| 79 | + if ( !$languages ) $languages = array_keys( $wwLanguages ); |
| 80 | + |
| 81 | + $term = $this->normalizeSearchString($term, $norm); |
| 82 | + |
| 83 | + $sql = "SELECT I.*, S.score FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as I" |
| 84 | + . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_search_index as S ON I.concept = S.concept " |
| 85 | + . " WHERE term = " . $this->quote($term) |
| 86 | + . " AND I.lang IN " . $this->quoteSet($languages) |
| 87 | + . " AND S.lang = " . $this->quote($qlang) |
| 88 | + . " AND S.norm <= " . (int)$norm |
| 89 | + . " ORDER BY S.score DESC, S.concept " |
| 90 | + . " LIMIT " . (int)$limit; |
| 91 | + |
| 92 | + #FIXME: query-lang vs. output-languages! |
| 93 | + |
| 94 | + return $this->query($sql); |
| 95 | + } |
| 96 | + |
| 97 | + function getConceptsForTerm($qlang, $term, $languages, $norm = 1, $limit = 100) { |
| 98 | + $rs = $this->queryConceptsForTerm($qlang, $term, $languages); |
| 99 | + $list = WWUtils::slurpRows($rs); |
| 100 | + mysql_free_result($rs); |
| 101 | + return $this->buildConcepts($list); |
| 102 | + } |
| 103 | + |
| 104 | + function getPagesForConcept( $id, $lang = null ) { |
| 105 | + $p = $this->getConceptInfo( $id, $lang ); |
| 106 | + return $p['pages']; |
| 107 | + } |
| 108 | + |
| 109 | + /* |
| 110 | + function queryConceptsForPage($lang, $page, $limit = 100) { |
| 111 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 112 | + |
| 113 | + $page = trim($page); |
| 114 | + |
| 115 | + $sql = "SELECT O.global_concept as id, O.* FROM {$wwTablePrefix}_{$lang}_resource as R " |
| 116 | + . " JOIN {$wwTablePrefix}_{$lang}_about as A ON A.resource = R.id " |
| 117 | + . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND A.concept = O.local_concept " |
| 118 | + . " WHERE R.name = \"" . mysql_real_escape_string($page) . "\"" |
| 119 | + . " LIMIT " . (int)$limit; |
| 120 | + |
| 121 | + return $this->query($sql); |
| 122 | + } |
| 123 | + |
| 124 | + function getConceptsForPage($lang, $page, $limit = 100) { |
| 125 | + $rs = $this->queryConceptsForPage($lang, $page); |
| 126 | + $list = WWUtils::slurpRows($rs); |
| 127 | + mysql_free_result($rs); |
| 128 | + return $list; |
| 129 | + } |
| 130 | + |
| 131 | + function queryLocalConcepts($id) { |
| 132 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 133 | + $sql = "SELECT O.lang, O.local_concept_name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O "; |
| 134 | + $sql .= " WHERE O.global_concept = " . (int)$id; |
| 135 | + |
| 136 | + return $this->query($sql); |
| 137 | + } |
| 138 | + |
| 139 | + function getLocalConcepts($id) { //NOTE: deprecated alias for backward compat |
| 140 | + return getPagesForConcept($id); |
| 141 | + } */ |
| 142 | + |
| 143 | + /* |
| 144 | + function queryLocalConceptInfo($lang, $id) { |
| 145 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 146 | + |
| 147 | + $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$lang}_concept_info as F " |
| 148 | + . " JOIN {$wwTablePrefix}_{$lang}_concept as C ON F.concept = C.id " |
| 149 | + . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($lang) . "\" AND F.concept = O.local_concept " |
| 150 | + . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON F.concept = D.concept " |
| 151 | + . " WHERE O.local_concept = $id "; |
| 152 | + |
| 153 | + return $this->query($sql); |
| 154 | + } |
| 155 | + |
| 156 | + function queryConceptInfo($id, $lang) { |
| 157 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 158 | + |
| 159 | + $sql = "SELECT O.*, C.*, F.*, definition FROM {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O " |
| 160 | + . " LEFT JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info as F ON O.global_concept = F.concept " |
| 161 | + . " LEFT JOIN {$wwTablePrefix}_{$lang}_concept as C ON O.local_concept = C.id " |
| 162 | + . " LEFT JOIN {$wwTablePrefix}_{$lang}_definition as D ON O.local_concept = D.concept " |
| 163 | + . " WHERE O.global_concept = $id AND O.lang = \"" . mysql_real_escape_string($lang) . "\" "; |
| 164 | + |
| 165 | + return $this->query($sql); |
| 166 | + }*/ |
| 167 | + |
| 168 | + /*function getConceptInfo( $id, $lang = null ) { |
| 169 | + $result = $this->getConcept($id, $lang); |
| 170 | + |
| 171 | + $result['broader'] = $this->getBroaderForConcept($id); |
| 172 | + $result['narrower'] = $this->getNarrowerForConcept($id); |
| 173 | + $result['related'] = $this->getRelatedForConcept($id); |
| 174 | + |
| 175 | + if ( $lang ) { |
| 176 | + $d = $this->getDefinitionForConcept($id); |
| 177 | + $result['related'] = $d[$lang]; |
| 178 | + } |
| 179 | + |
| 180 | + return $result; |
| 181 | + }*/ |
| 182 | + |
| 183 | + /* |
| 184 | + function unpickle($s, $lang, $hasId=true, $hasName=true, $hasConf=true) { |
| 185 | + $ss = explode("\x1E", $s); |
| 186 | + $items = array(); |
| 187 | + |
| 188 | + $fetchNames = false; |
| 189 | + |
| 190 | + foreach ($ss as $i) { |
| 191 | + $r = explode("\x1F", $i); |
| 192 | + $offs = -1; |
| 193 | + |
| 194 | + if ($hasId) $r['id'] = @$r[$offs += 1]; |
| 195 | + if ($hasName) $r['name'] = @$r[$offs += 1]; |
| 196 | + if ($hasConf) $r['conf'] = @$r[$offs += 1]; |
| 197 | + |
| 198 | + if ($hasId && !isset($r['name'])) |
| 199 | + $fetchNames = true; |
| 200 | + |
| 201 | + if ($hasId) $items[ $r['id'] ] = $r; |
| 202 | + else $items[] = $r; |
| 203 | + } |
| 204 | + |
| 205 | + if ($fetchNames) { |
| 206 | + $names = $this->fetchNames(array_keys($items), $lang); |
| 207 | + |
| 208 | + $keys = array_keys($items); |
| 209 | + foreach ($keys as $k) { |
| 210 | + $id = $items[$k]['id']; |
| 211 | + $items[$k]['name'] = $names[$id]; |
| 212 | + } |
| 213 | + } |
| 214 | + |
| 215 | + return $items; |
| 216 | + } |
| 217 | + |
| 218 | + function fetchNames($ids, $lang) { |
| 219 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 220 | + |
| 221 | + $names = array(); |
| 222 | + if (!$ids) return $names; |
| 223 | + |
| 224 | + $set = NULL; |
| 225 | + foreach ($ids as $id) { |
| 226 | + if ($set===NULL) $set = ""; |
| 227 | + else $set .= ", "; |
| 228 | + $set .= $id; |
| 229 | + } |
| 230 | + |
| 231 | + $sql = "select global_concept as id, local_concept_name as name from {$wwTablePrefix}_{$wwThesaurusDataset}_origin "; |
| 232 | + $sql .= "where global_concept in ($set) and lang = \"" . mysql_real_escape_string($lang) . "\" "; |
| 233 | + |
| 234 | + $res = $this->query($sql); |
| 235 | + |
| 236 | + while ($row = mysql_fetch_assoc($res)) { |
| 237 | + $id = $row['id']; |
| 238 | + $names[$id] = $row['name']; |
| 239 | + } |
| 240 | + |
| 241 | + mysql_free_result($res); |
| 242 | + |
| 243 | + return $names; |
| 244 | + } |
| 245 | + */ |
| 246 | + |
| 247 | + function splitPages( $s ) { |
| 248 | + $pp = explode("|", $s); |
| 249 | + |
| 250 | + $pages = array(); |
| 251 | + foreach ($pp as $p) { |
| 252 | + list($t, $n) = explode(":", $p, 2); |
| 253 | + $pages[$n] = (int)$t; |
| 254 | + } |
| 255 | + |
| 256 | + return $pages; |
| 257 | + } |
| 258 | + |
| 259 | + function splitConcepts( $s ) { |
| 260 | + $ss = explode("|", $s); |
| 261 | + |
| 262 | + $concepts = array(); |
| 263 | + foreach ($ss as $p) { |
| 264 | + list($id, $n) = explode(":", $p, 2); |
| 265 | + $id = (int)$id; |
| 266 | + $concepts[$id] = $n; |
| 267 | + } |
| 268 | + |
| 269 | + return $concepts; |
| 270 | + } |
| 271 | + |
| 272 | + ///////////////////////////////////////////////////////// |
| 273 | + function getConceptInfo( $id, $lang = null, $fields = null ) { |
| 274 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 275 | + |
| 276 | + #TODO: concept cache! |
| 277 | + |
| 278 | + if ( $fields && is_array($fields)) $fields = implode(", ", $fields); |
| 279 | + if ( !$fields ) $fields = "*"; |
| 280 | + |
| 281 | + #TODO: scores, concept-type, ... |
| 282 | + |
| 283 | + $sql = "SELECT $fields FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_info " |
| 284 | + . " WHERE concept = ".(int)$id; |
| 285 | + |
| 286 | + if ($lang) { |
| 287 | + if ( is_array($lang) ) $sql .= " AND lang IN " . $this->quoteSet($lang); |
| 288 | + else $sql .= " AND lang = " . $this->quote($lang); |
| 289 | + } |
| 290 | + |
| 291 | + $r = $this->getRows($sql); |
| 292 | + if (!$r) return false; |
| 293 | + |
| 294 | + return $this->buildConcept($r); |
| 295 | + } |
| 296 | + |
| 297 | + function buildConcepts($rows) { |
| 298 | + $concepts = array(); |
| 299 | + $buff = array(); |
| 300 | + $id = null; |
| 301 | + foreach($rows as $row) { |
| 302 | + if ( $id !== null && $id != $row['concept'] ) { |
| 303 | + if ($buff) { |
| 304 | + $concepts[$id] = $this->buildConcept($buff); |
| 305 | + $buff = array(); |
| 306 | + } |
| 307 | + |
| 308 | + $id = null; |
| 309 | + $score = null; |
| 310 | + } |
| 311 | + |
| 312 | + if ($id === null) { |
| 313 | + $id = (int)$row['concept']; |
| 314 | + } |
| 315 | + |
| 316 | + $buff[] = $row; |
| 317 | + } |
| 318 | + |
| 319 | + usort($concepts, array('WWThesaurus', 'byScore')); |
| 320 | + return $concepts; |
| 321 | + } |
| 322 | + |
| 323 | + function byScore( $a, $b ) { |
| 324 | + if ( isset($a['score']) && isset($b['score']) ) return $b['score'] - $a['score']; |
| 325 | + if ( isset($a['conf']) && isset($b['conf']) ) return $b['conf'] - $a['conf']; |
| 326 | + if ( isset($a['freq']) && isset($b['freq']) ) return $b['freq'] - $a['freq']; |
| 327 | + if ( isset($a['id']) && isset($b['id']) ) return $a['id'] - $b['id']; |
| 328 | + return 0; |
| 329 | + } |
| 330 | + |
| 331 | + function buildConcept($rows) { |
| 332 | + $concept = array(); |
| 333 | + $concept["languages"] = array(); |
| 334 | + |
| 335 | + $broader = array(); |
| 336 | + $narrower = array(); |
| 337 | + $similar = array(); |
| 338 | + $related = array(); |
| 339 | + |
| 340 | + foreach ($rows as $row) { |
| 341 | + if (!isset($concept["id"]) && isset($row["concept"])) $concept["id"] = (int)$row["concept"]; |
| 342 | + if (!isset($concept["score"]) && isset($row["score"])) $concept["score"] = (int)$row["score"]; |
| 343 | + |
| 344 | + $lang = $row["lang"]; |
| 345 | + $concept["languages"][] = $lang; |
| 346 | + |
| 347 | + #TODO: scores, concept-type, ... |
| 348 | + |
| 349 | + if (@$row["name"] !== null) $concept["name"][$lang] = $row["name"]; |
| 350 | + if (@$row["definition"] !== null) $concept["definition"][$lang] = $row["definition"]; |
| 351 | + if (@$row["pages"] !== null) $concept["pages"][$lang] = $this->splitPages($row["pages"]); |
| 352 | + |
| 353 | + if (@$row["broader"] !== null) $broader[$lang] = $this->splitConcepts($row["broader"]); |
| 354 | + if (@$row["narrower"] !== null) $narrower[$lang] = $this->splitConcepts($row["narrower"]); |
| 355 | + if (@$row["similar"] !== null) $similar[$lang] = $this->splitConcepts($row["similar"]); |
| 356 | + if (@$row["related"] !== null) $related[$lang] = $this->splitConcepts($row["related"]); |
| 357 | + } |
| 358 | + |
| 359 | + $concept["broader"] = $this->mogrifyLocalInfo($broader); |
| 360 | + $concept["narrower"] = $this->mogrifyLocalInfo($narrower); |
| 361 | + $concept["similar"] = $this->mogrifyLocalInfo($similar); |
| 362 | + $concept["related"] = $this->mogrifyLocalInfo($related); |
| 363 | + |
| 364 | + return $concept; |
| 365 | + } |
| 366 | + |
| 367 | + function mogrifyLocalInfo( $byLanguage ) { |
| 368 | + $byId = array(); |
| 369 | + |
| 370 | + foreach ( $byLanguage as $lang => $items ) { |
| 371 | + foreach ( $items as $id => $name ) { |
| 372 | + $byId[$id][$lang] = $name; |
| 373 | + } |
| 374 | + } |
| 375 | + |
| 376 | + return $byId; |
| 377 | + } |
| 378 | + |
| 379 | + /* |
| 380 | + function getConcept( $id, $lang = null, $limit = 100 ) { |
| 381 | + return $this->getConceptInfo($id, $lang); |
| 382 | + } |
| 383 | + |
| 384 | + function getRelatedForConcept( $id, $lang = null, $limit = 100 ) { |
| 385 | + $concept = $this->getConceptInfo($id, $lang, "lang, related"); |
| 386 | + if (!$concept) return false; |
| 387 | + else if ($lang) return $concept["related"][$lang]; |
| 388 | + else return $concept["related"]; |
| 389 | + } |
| 390 | + |
| 391 | + function getBroaderForConcept( $id, $lang = null, $limit = 100 ) { |
| 392 | + $concept = $this->getConceptInfo($id, $lang, "lang, broader"); |
| 393 | + if (!$concept) return false; |
| 394 | + else if ($lang) return $concept["broader"][$lang]; |
| 395 | + else return $concept["broader"]; |
| 396 | + } |
| 397 | + |
| 398 | + function getNarrowerForConcept( $id, $lang = null, $limit = 100 ) { |
| 399 | + $concept = $this->getConceptInfo($id, $lang, "lang, narrower"); |
| 400 | + if (!$concept) return false; |
| 401 | + else if ($lang) return $concept["narrower"][$lang]; |
| 402 | + else return $concept["narrower"]; |
| 403 | + } |
| 404 | + |
| 405 | + function getPagesForConcept( $id, $lang = null, $limit = 100 ) { |
| 406 | + if (!$lang) return false; |
| 407 | + |
| 408 | + $concept = $this->getConceptInfo($id, $lang, "lang, pages"); |
| 409 | + if (!$concept) return false; |
| 410 | + else if ($lang) return array_keys( $concept["pages"][$lang] ); |
| 411 | + } |
| 412 | + |
| 413 | + function getNamesForConcept( $id, $lang = null ) { |
| 414 | + $concept = $this->getConceptInfo($id, $lang, "lang, name"); |
| 415 | + if (!$concept) return false; |
| 416 | + |
| 417 | + $result = array(); |
| 418 | + foreach ($concept["languages"] as $ll) { |
| 419 | + if (@$concept["name@$ll"]) |
| 420 | + $result[$ll] = $concept["name@$ll"]; |
| 421 | + } |
| 422 | + |
| 423 | + return $result; |
| 424 | + } |
| 425 | + |
| 426 | + function getDefinitionForConcept( $id, $lang = null, $limit = 100 ) { |
| 427 | + $concept = $this->getConceptInfo($id, $lang, "lang, definition"); |
| 428 | + if (!$concept) return false; |
| 429 | + |
| 430 | + $result = array(); |
| 431 | + foreach ($concept["languages"] as $ll) { |
| 432 | + if (@$concept["definition@$ll"]) |
| 433 | + $result[$ll] = $concept["definition@$ll"]; |
| 434 | + } |
| 435 | + |
| 436 | + return $result; |
| 437 | + }*/ |
| 438 | + |
| 439 | + function getTermsForConcept( $id, $lang = null, $limit = 100 ) { |
| 440 | + global $wwTablePrefix, $wwThesaurusDataset, $wwLanguages; |
| 441 | + |
| 442 | + if ( !$lang ) $lang = array_keys( $wwLanguages ); |
| 443 | + if ( !is_array($lang) ) $lang = preg_split('![\\s,;|/:]\\s*!', $lang); |
| 444 | + $result = array(); |
| 445 | + |
| 446 | + foreach ($lang as $ll) { |
| 447 | + $sql = "SELECT M.term_text FROM {$wwTablePrefix}_{$ll}_meaning as M" |
| 448 | + . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_origin as O ON O.lang = \"" . mysql_real_escape_string($ll) . "\" AND M.concept = O.local_concept " |
| 449 | + . " WHERE O.global_concept = " . (int)$id |
| 450 | + . " ORDER BY freq DESC " |
| 451 | + . " LIMIT " . (int)$limit; |
| 452 | + |
| 453 | + $terms = $this->getList($sql, "term_text"); |
| 454 | + if ( $terms === false || $terms === null ) return false; |
| 455 | + if ( !$terms ) continue; |
| 456 | + |
| 457 | + $result[$ll] = $terms; |
| 458 | + } |
| 459 | + |
| 460 | + return $result; |
| 461 | + } |
| 462 | + |
| 463 | + /* |
| 464 | + function getLinksForConcept( $id, $lang = null, $limit = 100 ) { |
| 465 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 466 | + |
| 467 | + $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C " |
| 468 | + . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.target = C.id " |
| 469 | + . " WHERE L.anchor = ".(int)$id |
| 470 | + . " LIMIT " . (int)$limit; |
| 471 | + |
| 472 | + return $this->getRows($sql); |
| 473 | + } |
| 474 | + |
| 475 | + function getReferencesForConcept( $id, $lang = null, $limit = 100 ) { |
| 476 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 477 | + |
| 478 | + $sql = "SELECT C.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept as C " |
| 479 | + . " JOIN {$wwTablePrefix}_{$wwThesaurusDataset}_link as L ON L.anchor = C.id " |
| 480 | + . " WHERE L.target = ".(int)$id |
| 481 | + . " LIMIT " . (int)$limit; |
| 482 | + |
| 483 | + return $this->getRows($sql); |
| 484 | + } |
| 485 | + |
| 486 | + function getScoresForConcept( $id, $lang = null ) { |
| 487 | + global $wwTablePrefix, $wwThesaurusDataset; |
| 488 | + |
| 489 | + $sql = "SELECT S.* FROM {$wwTablePrefix}_{$wwThesaurusDataset}_concept_stats as S " |
| 490 | + . " WHERE S.concept = ".(int)$id |
| 491 | + ; |
| 492 | + |
| 493 | + $r = $this->getRows($sql); |
| 494 | + if ( !$r ) return false; |
| 495 | + |
| 496 | + return $r; |
| 497 | + }*/ |
| 498 | + |
| 499 | +} |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwthesaurus.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 500 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwimages.php |
— | — | @@ -0,0 +1,496 @@ |
| 2 | +<?php |
| 3 | +require_once(dirname(__FILE__)."/wwwikis.php"); |
| 4 | + |
| 5 | +class ImageCollection { |
| 6 | + |
| 7 | + function __construct() { |
| 8 | + $this->images = array(); |
| 9 | + } |
| 10 | + |
| 11 | + static function compareRecords($a, $b) { |
| 12 | + $d = (float)$b['score'] - (float)$a['score']; //NOTE: descending |
| 13 | + |
| 14 | + if ( $d > 0 ) return 1; |
| 15 | + else if ( $d < 0 ) return -1; |
| 16 | + else return 0; |
| 17 | + } |
| 18 | + |
| 19 | + function size() { |
| 20 | + return count($this->images); |
| 21 | + } |
| 22 | + |
| 23 | + function listImages($max) { |
| 24 | + uasort($this->images, "Imagecollection::compareRecords"); |
| 25 | + |
| 26 | + if ($max) return array_slice($this->images, 0, $max); |
| 27 | + else return $this->images; |
| 28 | + } |
| 29 | + |
| 30 | + function addImage($image, $key, $usage = "page", $weight = 1) { |
| 31 | + if (!isset($this->images[$image])) { |
| 32 | + $rec = array( |
| 33 | + "name" => $image, |
| 34 | + "score" => 0, |
| 35 | + ); |
| 36 | + } else { |
| 37 | + $rec = $this->images[$image]; |
| 38 | + } |
| 39 | + |
| 40 | + if (!isset($rec[$usage])) $rec[$usage] = array(); |
| 41 | + $rec[$usage][] = $key; |
| 42 | + $rec["score"] += $weight; |
| 43 | + |
| 44 | + $this->images[$image] = $rec; |
| 45 | + return $rec['score']; |
| 46 | + } |
| 47 | + |
| 48 | + function addImages($images, $key, $usage = "page", $weight = 1) { |
| 49 | + foreach ($images as $image) { |
| 50 | + $this->addImage($image, $key, $usage, $weight); |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + function addImageUsage($image, $wiki, $usage = "page", $weight = 1) { |
| 55 | + $this->addImage($image, $key, $usage, $weight); |
| 56 | + } |
| 57 | + |
| 58 | + function addTags($image, $tags, $prefix = "") { |
| 59 | + global $wwTagScores; |
| 60 | + |
| 61 | + if (isset($this->images[$image])) { |
| 62 | + foreach ($tags as $tag => $weight) { |
| 63 | + if (is_int($tag)) { |
| 64 | + $tag = $prefix.$weight; |
| 65 | + |
| 66 | + if (isset($wwTagScores[$tag])) $weight = $wwTagScores[$tag]; |
| 67 | + else $weight = 0; |
| 68 | + } else { |
| 69 | + $tag = $prefix.$tag; |
| 70 | + } |
| 71 | + |
| 72 | + $this->images[$image]['score'] += $weight; |
| 73 | + $this->images[$image]['tags'][] = $tag; |
| 74 | + } |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | +} |
| 79 | + |
| 80 | +class WWImages extends WWWikis { |
| 81 | + var $thesaurus; |
| 82 | + |
| 83 | + function __construct($thesaurus) { |
| 84 | + $this->thesaurus = $thesaurus; |
| 85 | + if ( !empty( $this->thesaurus->db ) ) $this->db = $thesaurus->db; |
| 86 | + } |
| 87 | + |
| 88 | + function queryImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
| 89 | + if ($lang == "commons") $commonsOnly = false; |
| 90 | + |
| 91 | + $imagelinks_table = $this->getWikiTableName($lang, "imagelinks"); |
| 92 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 93 | + $image_table = $this->getWikiTableName($lang, "image"); |
| 94 | + $commons_image_table = $this->getWikiTableName("commons", "image"); |
| 95 | + |
| 96 | + $sql = "/* queryImagesOnPage(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ "; |
| 97 | + |
| 98 | + $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I "; |
| 99 | + $sql .= " JOIN $page_table as P on P.page_id = I.il_from "; |
| 100 | + if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to "; |
| 101 | + if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to "; |
| 102 | + |
| 103 | + $sql .= " WHERE P.page_namespace = " . (int)$ns; |
| 104 | + $sql .= " AND P.page_title = " . $this->quote($title); |
| 105 | + if ($commonsOnly) $sql .= " AND R.img_name IS NULL"; |
| 106 | + |
| 107 | + return $this->queryWiki($lang, $sql); |
| 108 | + } |
| 109 | + |
| 110 | + function getImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
| 111 | + $rs = $this->queryImagesOnPage($lang, $ns, $title, $commonsOnly); |
| 112 | + |
| 113 | + $list = WWUtils::slurpList($rs, "name"); |
| 114 | + mysql_free_result($rs); |
| 115 | + |
| 116 | + return $list; |
| 117 | + } |
| 118 | + |
| 119 | + function queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) { |
| 120 | + if ($lang == "commons") $commonsOnly = false; |
| 121 | + |
| 122 | + $imagelinks_table = $this->getWikiTableName($lang, "imagelinks"); |
| 123 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 124 | + $image_table = $this->getWikiTableName($lang, "image"); |
| 125 | + $commons_image_table = $this->getWikiTableName("commons", "image"); |
| 126 | + $templatelinks_table = $this->getWikiTableName($lang, "templatelinks"); |
| 127 | + |
| 128 | + $sql = "/* queryImagesOnPageTemplates(" . $this->quote($lang) . ", " . (int)$ns . ", " . $this->quote($title) . ", " . (int)$commonsOnly . ") */ "; |
| 129 | + |
| 130 | + $sql .= " SELECT I.il_to as name FROM $imagelinks_table as I "; |
| 131 | + $sql .= " JOIN $page_table as TP on TP.page_id = I.il_from "; |
| 132 | + $sql .= " JOIN $templatelinks_table as T on T.tl_namespace = TP.page_namespace AND T.tl_title = TP.page_title "; |
| 133 | + $sql .= " JOIN $page_table as P on P.page_id = T.tl_from "; |
| 134 | + if ($commonsOnly) $sql .= " LEFT JOIN $image_table as R on R.img_name = I.il_to "; |
| 135 | + if ($commonsOnly) $sql .= " JOIN $commons_image_table as C on C.img_name = I.il_to "; |
| 136 | + |
| 137 | + $sql .= " WHERE P.page_namespace = " . (int)$ns; |
| 138 | + $sql .= " AND P.page_title = " . $this->quote($title); |
| 139 | + if ($commonsOnly) $sql .= " AND R.img_name IS NULL"; |
| 140 | + |
| 141 | + return $this->queryWiki($lang, $sql); |
| 142 | + } |
| 143 | + |
| 144 | + function getImagesOnPageTemplates($lang, $ns, $title, $commonsOnly = false) { |
| 145 | + $rs = $this->queryImagesOnPageTemplates($lang, $ns, $title, $commonsOnly); |
| 146 | + $list = WWUtils::slurpList($rs, "name"); |
| 147 | + mysql_free_result($rs); |
| 148 | + return $list; |
| 149 | + } |
| 150 | + |
| 151 | + function queryImagesInCategory($lang, $title) { |
| 152 | + $categorylinks_table = $this->getWikiTableName($lang, "categorylinks"); |
| 153 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 154 | + |
| 155 | + $sql = "/* queryImagesInCategory(" . $this->quote($lang) . ", " . $this->quote($title) . ") */ "; |
| 156 | + |
| 157 | + $sql .= " SELECT P.page_title as name FROM $page_table as P "; |
| 158 | + $sql .= " JOIN $categorylinks_table as C on C.cl_from = P.page_id "; |
| 159 | + |
| 160 | + $sql .= " WHERE C.cl_to = " . $this->quote($title); |
| 161 | + $sql .= " AND P.page_namespace = " . NS_IMAGE; |
| 162 | + |
| 163 | + return $this->queryWiki($lang, $sql); |
| 164 | + } |
| 165 | + |
| 166 | + function getImagesInCategory($lang, $title) { |
| 167 | + $rs = $this->queryImagesInCategory($lang, $title); |
| 168 | + $list = WWUtils::slurpList($rs, "name"); |
| 169 | + mysql_free_result($rs); |
| 170 | + return $list; |
| 171 | + } |
| 172 | + |
| 173 | + function queryTagsForImages($lang, $images, $tagTable) { |
| 174 | + if (!$images) return false; |
| 175 | + |
| 176 | + $sql = "/* queryTagsForImages(" . $this->quote($lang) . ", " . $this->quoteSet($images) . ") */ "; |
| 177 | + |
| 178 | + $sql .= " SELECT image, group_concat( concat(type, ':', tag) separator '|') as tags "; |
| 179 | + $sql .= " FROM $tagTable as T "; |
| 180 | + $sql .= " WHERE T.image IN " . $this->quoteSet($images); |
| 181 | + $sql .= " GROUP BY image "; |
| 182 | + |
| 183 | + return $this->queryWiki($lang, $sql); |
| 184 | + } |
| 185 | + |
| 186 | + function getTagsForImages($lang, $images, $tagTable) { |
| 187 | + if (!$images) return array(); |
| 188 | + |
| 189 | + $rs = $this->queryTagsForImages($lang, $images, $tagTable); |
| 190 | + $list = WWUtils::slurpAssoc($rs, "image", "tags"); |
| 191 | + mysql_free_result($rs); |
| 192 | + return $list; |
| 193 | + } |
| 194 | + |
| 195 | + function queryTemplatesOnImagePage($lang, $image) { |
| 196 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 197 | + $templatelinks_table = $this->getWikiTableName($lang, "templatelinks"); |
| 198 | + |
| 199 | + $sql = "/* queryTemplatesOnImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ "; |
| 200 | + |
| 201 | + $sql .= " SELECT tl_title as template FROM $templatelinks_table as T "; |
| 202 | + $sql .= " JOIN $page_table as P on P.page_id = T.tl_from AND T.tl_namespace = " . NS_TEMPLATE . " "; |
| 203 | + |
| 204 | + $sql .= " WHERE P.page_title = " . $this->quote($image); |
| 205 | + $sql .= " AND P.page_namespace = " . NS_IMAGE; |
| 206 | + |
| 207 | + return $this->queryWiki($lang, $sql); |
| 208 | + } |
| 209 | + |
| 210 | + function getTemplatesOnImagePage($lang, $image) { |
| 211 | + $rs = $this->queryTemplatesOnImagePage($lang, $image); |
| 212 | + $list = WWUtils::slurpList($rs, "template"); |
| 213 | + mysql_free_result($rs); |
| 214 | + return $list; |
| 215 | + } |
| 216 | + |
| 217 | + function queryCategoriesOfImagePage($lang, $image) { |
| 218 | + $page_table = $this->getWikiTableName($lang, "page"); |
| 219 | + $categorylinks_table = $this->getWikiTableName($lang, "categorylinks"); |
| 220 | + |
| 221 | + $sql = "/* queryCategoriesOfImagePage(" . $this->quote($lang) . ", " . $this->quote($image) . ") */ "; |
| 222 | + |
| 223 | + $sql .= " SELECT cl_to as category FROM $categorylinks_table as C "; |
| 224 | + $sql .= " JOIN $page_table as P on P.page_id = C.cl_from "; |
| 225 | + |
| 226 | + $sql .= " WHERE P.page_title = " . $this->quote($image); |
| 227 | + $sql .= " AND P.page_namespace = " . NS_IMAGE; |
| 228 | + |
| 229 | + return $this->queryWiki($lang, $sql); |
| 230 | + } |
| 231 | + |
| 232 | + function getCategoriesOfImagePage($lang, $image) { |
| 233 | + $rs = $this->queryCategoriesOfImagePage($lang, $image); |
| 234 | + $list = WWUtils::slurpList($rs, "category"); |
| 235 | + mysql_free_result($rs); |
| 236 | + return $list; |
| 237 | + } |
| 238 | + |
| 239 | + function getTemplateScores($templates, $values = NULL) { |
| 240 | + global $wwTemplateScores; |
| 241 | + if ($values === NULL) $values = $wwTemplateScores; |
| 242 | + |
| 243 | + if (!$values) return 0; |
| 244 | + |
| 245 | + $score = 0; |
| 246 | + foreach ($templates as $t) { |
| 247 | + $v = @$values[$t]; |
| 248 | + if ($v) $score += $v; |
| 249 | + } |
| 250 | + |
| 251 | + return $score; |
| 252 | + } |
| 253 | + |
| 254 | + function getRelevantImagesOnPage($lang, $ns, $title, $commonsOnly = false) { |
| 255 | + $img = $this->getImagesOnPage($lang, 0, $title, true); |
| 256 | + $timg = $this->getImagesOnPageTemplates($lang, 0, $title, true); |
| 257 | + $img = array_diff($img, $timg); |
| 258 | + return $img; |
| 259 | + } |
| 260 | + |
| 261 | + function queryImagesOnPagesGlobally( $concepts ) { |
| 262 | + global $wwLanguages; |
| 263 | + |
| 264 | + if (!$concepts) return false; |
| 265 | + |
| 266 | + $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks"); |
| 267 | + |
| 268 | + $wikis = array(); |
| 269 | + $pages = array(); |
| 270 | + |
| 271 | + foreach ($concepts as $lang => $rc) { |
| 272 | + if (!isset($wwLanguages[$lang])) continue; |
| 273 | + |
| 274 | + $wiki = $lang . "wiki"; |
| 275 | + if (!in_array($wiki, $wikis)) $wikis[] = $wiki; |
| 276 | + |
| 277 | + foreach ($rc as $r => $t) { |
| 278 | + if ( $t != 10) continue; //use only articles |
| 279 | + $p = "gil_wiki = " . $this->quote($wiki) . " AND gil_page_namespace_id = 0 AND gil_page_title = " . $this->quote($r); |
| 280 | + $pages[] = $p; |
| 281 | + } |
| 282 | + } |
| 283 | + |
| 284 | + if (!$pages || !$wikis) return false; |
| 285 | + |
| 286 | + $sql = " /* queryImagesOnPagesGlobally() */ "; |
| 287 | + $sql .= " SELECT distinct gil_to as image FROM $globalimagelinks_table "; |
| 288 | + $sql .= " WHERE gil_wiki in " . $this->quoteSet( $wikis ); |
| 289 | + $sql .= " AND gil_page_namespace_id = 0 "; |
| 290 | + $sql .= " AND ( ( " . implode(" ) OR ( ", $pages) . " ) ) "; |
| 291 | + |
| 292 | + print "(** $sql **)"; |
| 293 | + |
| 294 | + return $this->queryWiki("commons", $sql); |
| 295 | + } |
| 296 | + |
| 297 | + function getImagesOnPagesGlobally( $concepts ) { |
| 298 | + if (!$concepts) return array(); |
| 299 | + |
| 300 | + $rs = $this->queryImagesOnPagesGlobally($concepts); |
| 301 | + if (!$rs) return false; |
| 302 | + |
| 303 | + $list = WWUtils::slurpList($rs, "image"); |
| 304 | + mysql_free_result($rs); |
| 305 | + return $list; |
| 306 | + } |
| 307 | + |
| 308 | + function queryGlobalUsageCounts( $images, $wikis = ".*wiki" ) { |
| 309 | + if (!$images) return false; |
| 310 | + |
| 311 | + $globalimagelinks_table = $this->getWikiTableName("commons", "globalimagelinks"); |
| 312 | + |
| 313 | + $sql = " /* queryGlobalUsageCounts() */ "; |
| 314 | + $sql .= " SELECT gil_to as image, gil_wiki as wiki, count(*) as linkcount FROM $globalimagelinks_table "; |
| 315 | + $sql .= " WHERE gil_page_namespace_id = 0 "; |
| 316 | + $sql .= " AND gil_to IN " . $this->quoteSet( $images ); |
| 317 | + |
| 318 | + if ( $wikis ) { |
| 319 | + if ( is_array( $wikis ) ) $sql .= " AND gil_wiki IN " . $this->quoteSet( $wikis ); |
| 320 | + else if ( is_array( $wikis ) ) $sql .= " AND gil_wiki REGEX " . $this->quote( '^' . $wikis . '$' ); |
| 321 | + |
| 322 | + #TODO: could also limit to to x or min size n using toolserver.wiki ! |
| 323 | + } |
| 324 | + |
| 325 | + $sql .= " GROUP BY gil_to, gil_wiki "; |
| 326 | + $sql .= " ORDER BY gil_to, gil_wiki "; |
| 327 | + |
| 328 | + return $this->queryWiki("commons", $sql); |
| 329 | + } |
| 330 | + |
| 331 | + function getGlobalUsageCounts( $images, $wikis = ".*wiki" ) { |
| 332 | + if (!$images) return array(); |
| 333 | + |
| 334 | + $rs = $this->queryGlobalUsageCounts($images, $wikis); |
| 335 | + if (!$rs) return false; |
| 336 | + |
| 337 | + if (is_string($rs)) $rs = $this->query($rs); |
| 338 | + |
| 339 | + $imageUsage = array(); |
| 340 | + $current = NULL; |
| 341 | + $stats = array(); |
| 342 | + while ($row = mysql_fetch_assoc($rs)) { |
| 343 | + $image = $row["image"]; |
| 344 | + $wiki = $row["wiki"]; |
| 345 | + $linkcount = $row["linkcount"]; |
| 346 | + |
| 347 | + if ( is_null($current) ) $current = $image; |
| 348 | + else if ($current != $image) { |
| 349 | + $imageUsage[$current] = $stats; |
| 350 | + $stats = array(); |
| 351 | + $current = $image; |
| 352 | + } |
| 353 | + |
| 354 | + $stats[$wiki] = $linkcount; |
| 355 | + } |
| 356 | + |
| 357 | + if ($current) $imageUsage[$current] = $stats; |
| 358 | + |
| 359 | + return $imageUsage; |
| 360 | + } |
| 361 | + |
| 362 | + function getImagesAbout($concept, $max = 0) { |
| 363 | + global $wwLanguages, $wwFrequentImageThreshold; //FIXME: put config into member vars! |
| 364 | + |
| 365 | + $pages = null; |
| 366 | + if ( is_array($concept) ) { |
| 367 | + if (isset($concept['pages']) && $concept['pages']!==null) $pages = $concept['pages']; |
| 368 | + else if (isset($concept['id']) && $concept['id']!==null) $concept = $concept['id']; |
| 369 | + else if (isset($concept['concept'])) $concept = $concept['concept']; |
| 370 | + } |
| 371 | + |
| 372 | + if ($pages === null) { |
| 373 | + $pages = $this->thesaurus->getPagesForConcept($concept); |
| 374 | + if (!$pages) return false; |
| 375 | + } |
| 376 | + |
| 377 | + $images = new ImageCollection(); |
| 378 | + |
| 379 | + $globalImageList = $this->getImagesOnPagesGlobally($pages); //use wikis for $wwLanguages only |
| 380 | + //TODO: sanity limit on number of images. $max * 5 ? |
| 381 | + $globalImageUsage = $this->getGlobalUsageCounts($globalImageList, ".*wiki"); //use all wikipedias |
| 382 | + |
| 383 | + foreach ($globalImageUsage as $image => $usage) { |
| 384 | + foreach ($usage as $wiki => $c) { |
| 385 | + if ( $c >= $wwFrequentImageThreshold ) continue; |
| 386 | + $images->addImageUsage($image, $wiki.":*", "article", 1); |
| 387 | + } |
| 388 | + } |
| 389 | + |
| 390 | + if ($max && $images->size()>$max) { //short-cirquit, if we already reached the max |
| 391 | + $this->addImageTags($images); |
| 392 | + return $images->listImages($max); |
| 393 | + } |
| 394 | + |
| 395 | + if (isset($pages['commons'])) { |
| 396 | + $cpages = $pages['commons']; |
| 397 | + |
| 398 | + foreach ($cpages as $cpage => $t) { |
| 399 | + if ( $t == 50 && preg_match('/^Category:(.*)$/', $cpage, $m) ) { |
| 400 | + if ( @$m[1] ) $cpage = $m[1]; //hack |
| 401 | + $img = $this->getImagesInCategory("commons", $cpage); |
| 402 | + |
| 403 | + if ($img) $images->addImages($img, "commons:category:" . $cpage, "category", 0.5); |
| 404 | + } |
| 405 | + } |
| 406 | + } |
| 407 | + |
| 408 | + $this->addImageTags($images); |
| 409 | + return $images->listImages($max); |
| 410 | + } |
| 411 | + |
| 412 | + function addImageTags($images) { |
| 413 | + global $wwTagsTable; |
| 414 | + |
| 415 | + |
| 416 | + if ( $wwTagsTable ) { |
| 417 | + $img = array(); |
| 418 | + foreach ($images->images as $image) { |
| 419 | + $img[] = $image['name']; |
| 420 | + } |
| 421 | + |
| 422 | + $tagMap = $this->getTagsForImages('commons', $img, $wwTagsTable); |
| 423 | + foreach ($tagMap as $image => $tags) { |
| 424 | + if ($tags) { |
| 425 | + if (is_string($tags)) $tags = preg_split('/\s*[|;]\s*/', $tags); |
| 426 | + $images->addTags($image, $tags, ""); |
| 427 | + } |
| 428 | + } |
| 429 | + } else { |
| 430 | + foreach ($images->images as $image) { |
| 431 | + $image = $image['name']; |
| 432 | + |
| 433 | + $tmps = $this->getTemplatesOnImagePage('commons', $image); |
| 434 | + if ($tmps) $images->addTags($image, $tmps, "Template:"); |
| 435 | + |
| 436 | + $cats = $this->getCategoriesOfImagePage('commons', $image); |
| 437 | + if ($cats) $images->addTags($image, $cats, "Category:"); |
| 438 | + } |
| 439 | + } |
| 440 | + } |
| 441 | + |
| 442 | + function getThumbnailURL($image, $width = 120, $height = NULL) { |
| 443 | + global $wwThumbnailURL; |
| 444 | + |
| 445 | + if (is_array($image)) $image = $image['name']; |
| 446 | + |
| 447 | + if (!$height) $height = $width; |
| 448 | + |
| 449 | + $u = $wwThumbnailURL; |
| 450 | + $u = str_replace("{name}", urlencode($image), $u); |
| 451 | + $u = str_replace("{width}", !$width ? "" : urlencode($width), $u); |
| 452 | + $u = str_replace("{height}", !$height ? "" : urlencode($height), $u); |
| 453 | + |
| 454 | + return $u; |
| 455 | + } |
| 456 | + |
| 457 | + function getImagePageURL($image) { |
| 458 | + global $wwImagePageURL; |
| 459 | + |
| 460 | + if (is_array($image)) $image = $image['name']; |
| 461 | + |
| 462 | + $u = $wwImagePageURL; |
| 463 | + $u = str_replace("{name}", urlencode($image), $u); |
| 464 | + |
| 465 | + return $u; |
| 466 | + } |
| 467 | + |
| 468 | + function getThumbnailHTML($image, $w = 120, $h = NULL) { |
| 469 | + $thumb = $this->getThumbnailURL($image, $w, $h); |
| 470 | + $page = $this->getImagePageURL($image); |
| 471 | + |
| 472 | + if (is_array($image)) { |
| 473 | + $title = @$image['title']; |
| 474 | + $name = @$image['name']; |
| 475 | + } else { |
| 476 | + $name = $image; |
| 477 | + } |
| 478 | + |
| 479 | + if (!@$title) $title = $name; |
| 480 | + |
| 481 | + $tags = ""; |
| 482 | + if (isset($image['tags'])) { |
| 483 | + foreach ($image['tags'] as $tag) { |
| 484 | + $tags .= "tag-" . str_replace(":", "-", $tag) . " "; |
| 485 | + } |
| 486 | + } |
| 487 | + |
| 488 | + $html= "<img src=\"" . htmlspecialchars($thumb) . "\" alt=\"" . htmlspecialchars($title) . "\" border=\"0\"/>"; |
| 489 | + $html= "<a href=\"" . htmlspecialchars($page) . "\" title=\"" . htmlspecialchars($title) . " (score " . htmlspecialchars($image['score']) . ")\" class=\"thumb-link $tags\">$html</a>"; |
| 490 | + |
| 491 | + if (is_array($image)) { |
| 492 | + $html .= "<!-- " . str_replace("--", "~~", var_export( $image, true ) ) . " -->"; |
| 493 | + } |
| 494 | + |
| 495 | + return $html; |
| 496 | + } |
| 497 | +} |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwimages.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 498 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/common/wwwikis.php |
— | — | @@ -0,0 +1,72 @@ |
| 2 | +<?php |
| 3 | +require_once(dirname(__FILE__)."/wwutils.php"); |
| 4 | + |
| 5 | +if (!defined('NS_IMAGE')) |
| 6 | + define('NS_IMAGE', 6); |
| 7 | + |
| 8 | +if (!defined('NS_TEMPLATE')) |
| 9 | + define('NS_TEMPLATE', 10); |
| 10 | + |
| 11 | + |
| 12 | +class WWWikis extends WWUtils { |
| 13 | + var $wikidbs = array(); |
| 14 | + |
| 15 | + function getWikiTableName($lang, $table) { |
| 16 | + global $wwWikitableNamePattern, $wwCommonsTablePrefix; |
| 17 | + |
| 18 | + if ( $lang == "commons" && $wwCommonsTablePrefix ) return "$wwCommonsTablePrefix$table"; |
| 19 | + |
| 20 | + if ($wwWikitableNamePattern) { |
| 21 | + return str_replace(array('{lang}', '{name}'), array($lang, $table), $wwWikitableNamePattern); |
| 22 | + } |
| 23 | + |
| 24 | + return $table; |
| 25 | + } |
| 26 | + |
| 27 | + function getWikiInfo($lang) { |
| 28 | + global $wwWikiInfoTable, $wwWikiDbName, $wwWikiServerName, $wwCommonsServerName; |
| 29 | + |
| 30 | + $db = str_replace('{lang}', $lang, $wwWikiDbName); |
| 31 | + |
| 32 | + $dbname = "{$lang}wiki_p"; |
| 33 | + $sql = "select * from $wwWikiInfoTable "; |
| 34 | + $sql .= " where dbname = " . $this->quote("$db"); |
| 35 | + |
| 36 | + $rs = $this->query($sql); |
| 37 | + $info = mysql_fetch_assoc($rs); |
| 38 | + mysql_free_result($rs); |
| 39 | + |
| 40 | + if (!$info) $info = false; |
| 41 | + else $info['server'] = str_replace('{num}', $info['server'], $wwWikiServerName); |
| 42 | + |
| 43 | + if ($lang == "commons" && $wwCommonsServerName) $info['server'] = $wwCommonsServerName; |
| 44 | + |
| 45 | + return $info; |
| 46 | + } |
| 47 | + |
| 48 | + function getWikiConnection($lang) { |
| 49 | + if (isset($this->wikidbs[$lang])) return $this->wikidbs[$lang]; |
| 50 | + |
| 51 | + $info = $this->getWikiInfo($lang); |
| 52 | + |
| 53 | + if (!$info) { |
| 54 | + $db = false; |
| 55 | + } else { |
| 56 | + $db = mysql_connect($info['server'], $this->dbuser, $this->dbpassword); |
| 57 | + if (!$db) throw new Exception("Connection Failure to Database: " . mysql_error()); |
| 58 | + if (!mysql_select_db($info['dbname'], $db)) throw new Exception ("Database not found: " . mysql_error()); |
| 59 | + if (!mysql_query("SET NAMES Latin1;", $db)) throw new Exception ("Database not found: " . mysql_error()); |
| 60 | + } |
| 61 | + |
| 62 | + $this->wikidbs[$lang] = $db; |
| 63 | + return $db; |
| 64 | + } |
| 65 | + |
| 66 | + function queryWiki($lang, $sql) { |
| 67 | + $db = $this->getWikiConnection($lang); |
| 68 | + if (!$db) throw new Exception ("Wiki not found: $lang"); |
| 69 | + |
| 70 | + return $this->query($sql, $db); |
| 71 | + } |
| 72 | + |
| 73 | +} |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/common/wwwikis.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 74 | + |
Index: trunk/WikiWord/WikiWord/src/main/php/web/api.php |
— | — | @@ -0,0 +1,140 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +$IP = dirname(__FILE__); |
| 5 | + |
| 6 | +require_once("$IP/config.php"); |
| 7 | +require_once("$IP/wwthesaurus.php"); |
| 8 | + |
| 9 | +$query = @$_REQUEST['query']; |
| 10 | + |
| 11 | +if ( $query ) { |
| 12 | + $lang = @$_REQUEST['lang']; |
| 13 | + $qlang = @$_REQUEST['qlang']; |
| 14 | + $format = @$_REQUEST['format']; |
| 15 | + if ( !$format ) $format = 'phps'; |
| 16 | + |
| 17 | + if ($lang) $lang = preg_replace('[^\\w\\d_]', '', $lang); |
| 18 | + if ($qlang) $qlang = preg_replace('[^\\w\\d_]', '', $qlang); |
| 19 | + |
| 20 | + if ($lang) { |
| 21 | + $lang = preg_split('![\\s,;|/:]\\s*!', $lang); |
| 22 | + if ( !$qlang ) $qlang = $lang[0]; |
| 23 | + if (count($lang) == 1) $lang = $lang[0]; |
| 24 | + } |
| 25 | + |
| 26 | + $result = array( 'query' => $query ); |
| 27 | + $start = microtime(true); |
| 28 | + |
| 29 | + try { |
| 30 | + $thesaurus = new WWThesaurus(); |
| 31 | + $db = $thesaurus->connect($wwDBServer, $wwDBUser, $wwDBPassword, $wwDBDatabase); |
| 32 | + |
| 33 | + if ( !$db ) { |
| 34 | + $result['error'] = array('code' => 1010, 'message' => "failed to connect to thesaurus database"); |
| 35 | + } else if ($query == 'concepts') { |
| 36 | + $term = @$_REQUEST['term']; |
| 37 | + $norm = @$_REQUEST['norm']; |
| 38 | + |
| 39 | + if ( $norm === null ) $norm = 1; |
| 40 | + #$page = @$_REQUEST['page']; |
| 41 | + |
| 42 | + if ( $qlang === null ) $result['error'] = array('code' => 150, 'message' => "missing parameter qlang"); |
| 43 | + else if ( $term !== null ) { |
| 44 | + $result['concepts'] = $thesaurus->getConceptsForTerm($qlang, $term, $lang, $norm); #TODO: limit! |
| 45 | + if ( $result['concepts'] === false || $result['concepts'] === null ) { |
| 46 | + $result['error'] = array('code' => 210, 'message' => "failed to retrieve concepts for term $langt:$term"); |
| 47 | + } |
| 48 | + } /*else if ( $page !== null ) { |
| 49 | + $result['concepts'] = $thesaurus->getConceptsForPage($lang, $page); |
| 50 | + if ( $result['concepts'] === false || $result['concepts'] === null ) { |
| 51 | + $result['error'] = array('code' => 250, 'message' => "failed to retrieve concepts for page $langt:$page"); |
| 52 | + } |
| 53 | + } */else { |
| 54 | + $result['error'] = array('code' => 110, 'message' => "missing parameter term"); |
| 55 | + } |
| 56 | + } else if ($query == 'concept' || $query == 'info') { |
| 57 | + $gcid = @$_REQUEST['gcid']; |
| 58 | + if (!$gcid) $gcid = @$_REQUEST['id']; |
| 59 | + |
| 60 | + if ( $gcid === null ) { |
| 61 | + $result['error'] = array('code' => 120, 'message' => "missing parameter gcid"); |
| 62 | + } else { |
| 63 | + $result['concept'] = $thesaurus->getConceptInfo($gcid, $lang); #TODO: limit! |
| 64 | + if ( $result['concept'] === false || $result['concept'] === null ) { |
| 65 | + $result['error'] = array('code' => 210, 'message' => "concept not found: $gcid"); |
| 66 | + } |
| 67 | + } |
| 68 | + } else if ($query == 'properties') { |
| 69 | + $gcid = @$_REQUEST['gcid']; |
| 70 | + if (!$gcid) $gcid = @$_REQUEST['id']; |
| 71 | + |
| 72 | + $props = @$_REQUEST['props']; |
| 73 | + |
| 74 | + if ( $gcid === null ) $result['error'] = array('code' => 120, 'message' => "missing parameter gcid"); |
| 75 | + else if ( $props === null ) $result['error'] = array('code' => 130, 'message' => "missing parameter props"); |
| 76 | + else { |
| 77 | + $props = preg_split('![\\s,;|/:]\\s*!', $props); |
| 78 | + |
| 79 | + $info = $thesaurus->getConcept($gcid, $lang); |
| 80 | + |
| 81 | + if ( !$info ) $result['error'] = array('code' => 100, 'message' => "concept not found: $gcid"); |
| 82 | + else { |
| 83 | + $result = array_merge($result, $info); |
| 84 | + |
| 85 | + foreach ( $props as $p ) { |
| 86 | + $m = "get" . ucfirst($p) . "ForConcept"; |
| 87 | + if ( !method_exists($thesaurus, $m) ) { |
| 88 | + $result['error'] = array('code' => 190, 'message' => "unknown property: $p"); |
| 89 | + break; |
| 90 | + } |
| 91 | + |
| 92 | + $result[$p] = $thesaurus->$m($gcid, $lang); |
| 93 | + |
| 94 | + if ( $result[$p] === false || $result[$p] === null ) { |
| 95 | + $result['error'] = array('code' => 220, 'message' => "failed to retrieve property $p for concept $gcid"); |
| 96 | + break; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + if (!isset($result['id'])) $result['id'] = $gcid; |
| 101 | + if (!isset($result['lang'])) $result['lang'] = $lang; |
| 102 | + } |
| 103 | + } |
| 104 | + } else { |
| 105 | + $result['error'] = array('code' => 10, 'message' => "bad query: $query"); |
| 106 | + } |
| 107 | + } catch (Exception $e) { |
| 108 | + $result['error'] = array('code' => 1000, 'message' => "unexpected exception: " . $e->getMessage()); |
| 109 | + } |
| 110 | + |
| 111 | + $result['time'] = (microtime(true) - $start) . " sec"; |
| 112 | + |
| 113 | + if ( isset($result['error']) ) { |
| 114 | + #TODO: HTTP error codce would be nice, but causes file_get_contents to swallow the data. |
| 115 | + # need to use CURL in client! |
| 116 | + #header("Status: 400 Bad Request", true, 400); |
| 117 | + } |
| 118 | + |
| 119 | + #TODO: JSON (+YAML?), WDDX |
| 120 | + if ($format == 'phps') { |
| 121 | + header("Content-Type: application/vnd.php.serialized"); #as proposed by http://www.alvestrand.no/pipermail/ietf-types/2004-August/001259.html |
| 122 | + $data = serialize($result); |
| 123 | + echo $data; |
| 124 | + } else if ($format == 'php') { |
| 125 | + header("Content-Type: text/php; charset=UTF-8"); |
| 126 | + var_export($result); |
| 127 | + } else if ($format == 'text') { |
| 128 | + header("Content-Type: text/plain; charset=UTF-8"); |
| 129 | + print_r($result); |
| 130 | + } else { |
| 131 | + header("Content-Type: text/plain; charset=UTF-8"); |
| 132 | + header("Status: 400 Bad Request", true, 400); |
| 133 | + echo "Bad format: $format"; |
| 134 | + } |
| 135 | + |
| 136 | + exit(); |
| 137 | +} |
| 138 | + |
| 139 | +header("Content-Type: text/plain; charset=UTF-8"); |
| 140 | +?> |
| 141 | +WikiWord REST API |
\ No newline at end of file |
Property changes on: trunk/WikiWord/WikiWord/src/main/php/web/api.php |
___________________________________________________________________ |
Name: svn:mergeinfo |
1 | 142 | + |