Révision 7707c013
Ajouté par Assos Assos il y a presque 9 ans
drupal7/sites/all/modules/feeds_jsonpath_parser/FeedsJSONPathParser.inc | ||
---|---|---|
1 | 1 |
<?php |
2 |
// $Id: FeedsJSONPathParser.inc,v 1.1.2.4.2.4 2011/02/05 19:28:01 twistor Exp $ |
|
3 | 2 |
|
4 | 3 |
/** |
5 | 4 |
* @file |
6 |
* |
|
7 |
* Provides the Class for Feeds JSONPath Parser. |
|
5 |
* Contains FeedsJSONPathParser. |
|
8 | 6 |
*/ |
9 | 7 |
|
10 | 8 |
/** |
11 |
* Base class for the HTML and XML parsers.
|
|
9 |
* Parses JSON using JSONPath.
|
|
12 | 10 |
*/ |
13 | 11 |
class FeedsJSONPathParser extends FeedsParser { |
14 | 12 |
|
15 | 13 |
/** |
16 |
* Implementation of FeedsParser::parse(). |
|
14 |
* A regular expression that finds four byte UTF-8 chars. |
|
15 |
* |
|
16 |
* @var string |
|
17 |
*/ |
|
18 |
protected static $fourByteRegex = '/(?:\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/s'; |
|
19 |
|
|
20 |
/** |
|
21 |
* The source fields to debug. |
|
22 |
* |
|
23 |
* @var array |
|
24 |
*/ |
|
25 |
protected $debug = array(); |
|
26 |
|
|
27 |
/** |
|
28 |
* Implements FeedsParser::parse(). |
|
17 | 29 |
*/ |
18 | 30 |
public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) { |
19 |
$mappings = $source->importer->processor->config['mappings']; |
|
20 |
$mappings = $this->filterMappings($mappings); |
|
31 |
$mappings = $this->getOwnMappings(); |
|
21 | 32 |
$source_config = $source->getConfigFor($this); |
22 | 33 |
// Allow config inheritance. |
23 | 34 |
if (empty($source_config)) { |
... | ... | |
40 | 51 |
$array = json_decode($raw, TRUE); |
41 | 52 |
} |
42 | 53 |
|
43 |
if (is_array($array)) { |
|
44 |
require_once 'jsonpath-0.8.1.php'; |
|
45 |
|
|
46 |
$all_items = $this->jsonPath($array, $source_config['context']); |
|
47 |
$this->debug($all_items, 'context'); |
|
48 |
unset($array); |
|
49 |
|
|
50 |
foreach ($all_items as $item) { |
|
51 |
$parsed_item = $variables = array(); |
|
52 |
foreach ($source_config['sources'] as $source => $query) { |
|
53 |
$parsed = $this->parseSourceElement($item, $query, $source); |
|
54 |
// Avoid null values. |
|
55 |
if (isset($parsed)) { |
|
56 |
// Variable sunstitution can't handle arrays. |
|
57 |
if (!is_array($parsed)) { |
|
58 |
$variables['{' . $mappings[$source] . '}'] = $parsed; |
|
59 |
} |
|
60 |
else { |
|
61 |
$variables['{' . $mappings[$source] . '}'] = ''; |
|
62 |
} |
|
63 |
$parsed_item[$source] = $parsed; |
|
64 |
} |
|
54 |
if (!is_array($array)) { |
|
55 |
throw new Exception(t('There was an error decoding the JSON document.')); |
|
56 |
} |
|
57 |
require_once feeds_jsonpath_parser_library_path(); |
|
58 |
|
|
59 |
$all_items = $this->jsonPath($array, $source_config['context']); |
|
60 |
unset($array); |
|
61 |
|
|
62 |
// Batch. |
|
63 |
$state = $source->state(FEEDS_PARSE); |
|
64 |
if (!$state->total) { |
|
65 |
$state->total = count($all_items); |
|
66 |
} |
|
67 |
|
|
68 |
$start = (int) $state->pointer; |
|
69 |
$state->pointer = $start + $source->importer->getLimit(); |
|
70 |
$all_items = array_slice($all_items, $start, $source->importer->getLimit()); |
|
71 |
|
|
72 |
// Set progress state. |
|
73 |
$state->progress($state->total, $state->pointer); |
|
74 |
|
|
75 |
// Debug output. |
|
76 |
$this->debug($all_items, 'context'); |
|
77 |
|
|
78 |
foreach ($all_items as $item) { |
|
79 |
// Invoke a hook to check whether the item should be skipped. |
|
80 |
if ($this->invokeHook($item, $source) === TRUE) { |
|
81 |
continue; |
|
82 |
} |
|
83 |
|
|
84 |
$parsed_item = $variables = array(); |
|
85 |
foreach ($source_config['sources'] as $source_key => $query) { |
|
86 |
// Variable substitution. |
|
87 |
$query = strtr($query, $variables); |
|
88 |
$parsed = $this->parseSourceElement($item, $query, $source_key); |
|
89 |
|
|
90 |
$variables['{' . $mappings[$source_key] . '}'] = is_array($parsed) ? reset($parsed) : $parsed; |
|
91 |
|
|
92 |
// Avoid null values. |
|
93 |
if (isset($parsed)) { |
|
94 |
$parsed_item[$source_key] = $parsed; |
|
65 | 95 |
} |
96 |
} |
|
97 |
if (!empty($parsed_item)) { |
|
66 | 98 |
$result->items[] = $parsed_item; |
67 | 99 |
} |
68 | 100 |
} |
69 |
else { |
|
70 |
throw new Exception(t('There was an error decoding the JSON document.')); |
|
71 |
} |
|
72 | 101 |
return $result; |
73 | 102 |
} |
74 | 103 |
|
75 | 104 |
/** |
76 |
* Utilizes the jsonPath function from jsonpath-0.8.1.php |
|
105 |
* Utilizes the jsonPath function from jsonpath-0.8.1.php.
|
|
77 | 106 |
* |
78 | 107 |
* jsonPath returns false if the expression returns zero results and that will |
79 | 108 |
* mess up our for loops, so return an empty array instead. |
80 | 109 |
* |
81 |
* @todo |
|
82 |
* Firgure out error handling. |
|
83 |
* @param $array |
|
84 |
* The input array to parse |
|
85 |
* @$expression |
|
110 |
* @param array $array |
|
111 |
* The input array to parse. |
|
112 |
* @param string $expression |
|
86 | 113 |
* The JSONPath expression. |
114 |
* |
|
87 | 115 |
* @return array |
88 |
* Returns an array that is the output of jsonPath |
|
116 |
* Returns an array that is the output of jsonPath. |
|
117 |
* |
|
118 |
* @todo |
|
119 |
* Firgure out error handling. |
|
89 | 120 |
*/ |
90 |
private function jsonPath($array, $expression) {
|
|
121 |
protected function jsonPath($array, $expression) {
|
|
91 | 122 |
$result = jsonPath($array, $expression); |
92 | 123 |
return ($result === FALSE) ? array() : $result; |
93 | 124 |
} |
... | ... | |
95 | 126 |
/** |
96 | 127 |
* Parses one item from the context array. |
97 | 128 |
* |
98 |
* @param $item |
|
99 |
* A PHP array.
|
|
100 |
* @param $query |
|
129 |
* @param array $item
|
|
130 |
* An array containing one item from the context.
|
|
131 |
* @param string $query
|
|
101 | 132 |
* A JSONPath query. |
133 |
* @param string $source |
|
134 |
* The source element that corresponds to the query. |
|
135 |
* |
|
102 | 136 |
* @return array |
103 | 137 |
* An array containing the results of the query. |
104 | 138 |
*/ |
... | ... | |
108 | 142 |
} |
109 | 143 |
$results = $this->jsonPath($item, $query); |
110 | 144 |
$this->debug($results, $source); |
111 |
unset($item); |
|
112 |
|
|
113 |
/** |
|
114 |
* If there is one result, return it directly. If there are no results, |
|
115 |
* return. Otherwise return the results. |
|
116 |
*/ |
|
117 |
if (count($results) === 1) { |
|
118 |
return $results[0]; |
|
119 |
} |
|
120 |
if (count($results) === 0) { |
|
145 |
|
|
146 |
$count = count($results); |
|
147 |
if ($count === 0) { |
|
121 | 148 |
return; |
122 | 149 |
} |
150 |
|
|
151 |
foreach ($results as $delta => $value) { |
|
152 |
if (is_string($value) && $value !== '') { |
|
153 |
$results[$delta] = !empty($this->config['convert_four_byte']) ? $this->convertFourBytes($value) : $this->stripFourBytes($value); |
|
154 |
} |
|
155 |
} |
|
156 |
|
|
157 |
if ($count === 1) { |
|
158 |
return reset($results); |
|
159 |
} |
|
160 |
|
|
123 | 161 |
return $results; |
124 | 162 |
} |
125 | 163 |
|
... | ... | |
132 | 170 |
if (empty($source_config)) { |
133 | 171 |
$source_config = $this->config; |
134 | 172 |
} |
173 |
|
|
174 |
if (isset($source_config['allow_override']) && |
|
175 |
!$source_config['allow_override'] && |
|
176 |
empty($source_config['config'])) { |
|
177 |
return; |
|
178 |
} |
|
179 |
|
|
135 | 180 |
// Add extensions that might get importerd. |
136 | 181 |
$fetcher = feeds_importer($this->id)->fetcher; |
137 | 182 |
if (isset($fetcher->config['allowed_extensions'])) { |
... | ... | |
145 | 190 |
foreach ($mappings_ as $mapping) { |
146 | 191 |
if (strpos($mapping['source'], 'jsonpath_parser:') === 0) { |
147 | 192 |
$mappings[$mapping['source']] = $mapping['target']; |
148 |
if ($mapping['unique']) {
|
|
193 |
if (!empty($mapping['unique'])) {
|
|
149 | 194 |
$uniques[] = $mapping['target']; |
150 | 195 |
} |
151 | 196 |
} |
... | ... | |
158 | 203 |
'#tree' => TRUE, |
159 | 204 |
); |
160 | 205 |
if (empty($mappings)) { |
161 |
$form['jsonpath']['error_message']['#markup'] = t('FeedsJSONPathParser: No mappings were defined.'); |
|
206 |
// Detect if Feeds menu structure has changed. This will take a while to |
|
207 |
// be released, but since I run dev it needs to work. |
|
208 |
$feeds_menu = feeds_ui_menu(); |
|
209 |
if (isset($feeds_menu['admin/structure/feeds/list'])) { |
|
210 |
$feeds_base = 'admin/structure/feeds/edit/'; |
|
211 |
} |
|
212 |
else { |
|
213 |
$feeds_base = 'admin/structure/feeds/'; |
|
214 |
} |
|
215 |
$form['jsonpath']['error_message']['#markup'] = '<div class="help">' . t('No JSONPath mappings are defined. Define mappings !link.', array('!link' => l(t('here'), $feeds_base . $this->id . '/mapping'))) . '</div><br />'; |
|
162 | 216 |
return $form; |
163 | 217 |
} |
164 | 218 |
$form['jsonpath']['context'] = array( |
... | ... | |
194 | 248 |
'#size' => 80, |
195 | 249 |
); |
196 | 250 |
if (!empty($variables)) { |
197 |
$form['jsonpath']['sources'][$source]['#description'] .= '<br>' . t('The variables '. implode(', ', $variables). ' are availliable for replacement.'); |
|
251 |
$variable_text = format_plural(count($variables), |
|
252 |
t('The variable %v is available for replacement.', array('%v' => implode(', ', $variables))), |
|
253 |
t('The variables %v are available for replacement.', array('%v' => implode(', ', $variables))) |
|
254 |
); |
|
255 |
$form['jsonpath']['sources'][$source]['#description'] .= '<br />' . $variable_text; |
|
198 | 256 |
} |
199 | 257 |
$variables[] = '{' . $target . '}'; |
200 | 258 |
} |
... | ... | |
217 | 275 |
* Override parent::configForm(). |
218 | 276 |
*/ |
219 | 277 |
public function configForm(&$form_state) { |
220 |
$form = $this->sourceForm($this->config); |
|
278 |
$config = $this->getConfig(); |
|
279 |
$config['config'] = TRUE; |
|
280 |
$form = $this->sourceForm($config); |
|
221 | 281 |
$form['jsonpath']['context']['#required'] = FALSE; |
222 | 282 |
$form['jsonpath']['#collapsed'] = FALSE; |
283 |
$form['jsonpath']['allow_override'] = array( |
|
284 |
'#type' => 'checkbox', |
|
285 |
'#title' => t('Allow source configuration override'), |
|
286 |
'#description' => t('This setting allows feed nodes to specify their own JSONPath values for the context and sources.'), |
|
287 |
'#default_value' => $config['allow_override'], |
|
288 |
); |
|
289 |
$form['jsonpath']['convert_four_byte'] = array( |
|
290 |
'#type' => 'checkbox', |
|
291 |
'#title' => t('Convert four byte characters'), |
|
292 |
'#description' => t('Coverts four byte UTF-8 characters to their HTML entity. By default, four byte characters will be stripped.'), |
|
293 |
'#default_value' => !empty($config['convert_four_byte']), |
|
294 |
); |
|
295 |
|
|
223 | 296 |
return $form; |
224 | 297 |
} |
225 | 298 |
|
226 | 299 |
/** |
227 |
* Override parent::getMappingSources(). |
|
228 |
*/ |
|
300 |
* Override parent::getMappingSources().
|
|
301 |
*/
|
|
229 | 302 |
public function getMappingSources() { |
230 | 303 |
$mappings = $this->filterMappings(feeds_importer($this->id)->processor->config['mappings']); |
231 | 304 |
$next = 0; |
232 | 305 |
if (!empty($mappings)) { |
233 |
$last_mapping = end(array_keys($mappings)); |
|
234 |
$next = explode(':', $last_mapping); |
|
235 |
$next = $next[1] + 1; |
|
306 |
$keys = array_keys($mappings); |
|
307 |
|
|
308 |
$nums = array(); |
|
309 |
foreach ($keys as $key) { |
|
310 |
list(, $num) = explode(':', $key); |
|
311 |
$nums[] = $num; |
|
312 |
} |
|
313 |
|
|
314 |
$max = max($nums); |
|
315 |
$next = ++$max; |
|
236 | 316 |
} |
237 | 317 |
return array( |
238 | 318 |
'jsonpath_parser:' . $next => array( |
239 | 319 |
'name' => t('JSONPath Expression'), |
240 |
'description' => t('Allows you to configure n JSONPath expression that will populate this field.'),
|
|
320 |
'description' => t('Allows you to configure a JSONPath expression that will populate this field.'),
|
|
241 | 321 |
), |
242 | 322 |
) + parent::getMappingSources(); |
243 | 323 |
} |
... | ... | |
254 | 334 |
'context' => '', |
255 | 335 |
'sources' => array(), |
256 | 336 |
'debug' => array(), |
337 |
'allow_override' => FALSE, |
|
338 |
'convert_four_byte' => FALSE, |
|
257 | 339 |
); |
258 | 340 |
} |
259 | 341 |
|
... | ... | |
263 | 345 |
* If the values of this source are the same as the base config we set them to |
264 | 346 |
* blank to that the values will be inherited from the importer defaults. |
265 | 347 |
* |
266 |
* @param &$values
|
|
348 |
* @param array $values
|
|
267 | 349 |
* The values from the form to validate, passed by reference. |
268 | 350 |
*/ |
269 | 351 |
public function sourceFormValidate(&$values) { |
352 |
$config = $this->getConfig(); |
|
270 | 353 |
$values = $values['jsonpath']; |
271 |
asort($values); |
|
272 |
asort($this->config); |
|
273 |
if ($values === $this->config) { |
|
354 |
$allow_override = $config['allow_override']; |
|
355 |
unset($config['allow_override']); |
|
356 |
unset($config['convert_four_byte']); |
|
357 |
ksort($values); |
|
358 |
ksort($config); |
|
359 |
if ($values === $config || !$allow_override) { |
|
274 | 360 |
$values = array(); |
275 | 361 |
return; |
276 | 362 |
} |
... | ... | |
284 | 370 |
if (isset($values['jsonpath'])) { |
285 | 371 |
$values = $values['jsonpath']; |
286 | 372 |
} |
287 |
$values['context'] = trim($values['context']); |
|
288 |
foreach ($values['sources'] as &$source) { |
|
289 |
$source = trim($source); |
|
373 |
|
|
374 |
$values['context'] = isset($values['context']) ? trim($values['context']) : ''; |
|
375 |
if (!empty($values['sources'])) { |
|
376 |
foreach ($values['sources'] as &$source) { |
|
377 |
$source = trim($source); |
|
378 |
} |
|
290 | 379 |
} |
291 | 380 |
} |
292 | 381 |
|
382 |
/** |
|
383 |
* Gets the mappings that belong to this parser. |
|
384 |
* |
|
385 |
* @return array |
|
386 |
* An array of mappings keyed source => target. |
|
387 |
*/ |
|
388 |
protected function getOwnMappings() { |
|
389 |
$importer_config = feeds_importer($this->id)->getConfig(); |
|
390 |
return $this->filterMappings($importer_config['processor']['config']['mappings']); |
|
391 |
} |
|
392 |
|
|
293 | 393 |
/** |
294 | 394 |
* Filters mappings, returning the ones that belong to us. |
395 |
* |
|
396 |
* @param array $mappings |
|
397 |
* A mapping array from a processor. |
|
398 |
* |
|
399 |
* @return array |
|
400 |
* An array of mappings keyed source => target. |
|
295 | 401 |
*/ |
296 |
private function filterMappings($mappings) {
|
|
402 |
protected function filterMappings($mappings) {
|
|
297 | 403 |
$our_mappings = array(); |
298 | 404 |
foreach ($mappings as $mapping) { |
299 | 405 |
if (strpos($mapping['source'], 'jsonpath_parser:') === 0) { |
... | ... | |
303 | 409 |
return $our_mappings; |
304 | 410 |
} |
305 | 411 |
|
306 |
private function debug($item, $source) {
|
|
412 |
protected function debug($item, $source) {
|
|
307 | 413 |
if (in_array($source, $this->debug)) { |
308 | 414 |
$o = '<ul>'; |
309 | 415 |
foreach ($item as $i) { |
... | ... | |
313 | 419 |
drupal_set_message($source . ':' . $o); |
314 | 420 |
} |
315 | 421 |
} |
422 |
|
|
423 |
/** |
|
424 |
* Calls our filter hook. |
|
425 |
* |
|
426 |
* @param array &$item |
|
427 |
* The item to alter. |
|
428 |
* @param FeedsSource $source |
|
429 |
* The feed source. |
|
430 |
* @return true|null |
|
431 |
* Returns true if the item should be skipped. |
|
432 |
*/ |
|
433 |
protected function invokeHook(array &$item, FeedsSource $source) { |
|
434 |
foreach (module_implements('feeds_jsonpath_parser_filter') as $module) { |
|
435 |
$function = $module . '_feeds_jsonpath_parser_filter'; |
|
436 |
if ($function($item, $source) === TRUE) { |
|
437 |
return TRUE; |
|
438 |
} |
|
439 |
} |
|
440 |
} |
|
441 |
|
|
442 |
/** |
|
443 |
* Strips four byte characters from a string. |
|
444 |
* |
|
445 |
* @param string $string |
|
446 |
* The input string. |
|
447 |
* |
|
448 |
* @return string |
|
449 |
* The string with four byte characters removed. |
|
450 |
*/ |
|
451 |
public static function stripFourBytes($string) { |
|
452 |
return preg_replace(self::$fourByteRegex, '', $string); |
|
453 |
} |
|
454 |
|
|
455 |
/** |
|
456 |
* Replaces four byte characters with their HTML unicode codepoint. |
|
457 |
* |
|
458 |
* @param string $string |
|
459 |
* The input string. |
|
460 |
* |
|
461 |
* @return string |
|
462 |
* The string with four byte characters converted. |
|
463 |
*/ |
|
464 |
public static function convertFourBytes($string) { |
|
465 |
return preg_replace_callback(self::$fourByteRegex, array('FeedsJSONPathParser', 'doFourByteReplace'), $string); |
|
466 |
} |
|
467 |
|
|
468 |
/** |
|
469 |
* Callback for FeedsJSONPathParser::convertFourBytes(). |
|
470 |
* |
|
471 |
* @param array $matches |
|
472 |
* The regular expression matches. |
|
473 |
* |
|
474 |
* @return string |
|
475 |
* A four byte unicode character converted to its HTML representation. |
|
476 |
*/ |
|
477 |
public static function doFourByteReplace(array $matches) { |
|
478 |
$char = $matches[0]; |
|
479 |
|
|
480 |
// Calculate the codepoint of the character. |
|
481 |
$codepoint = ord($char[0]) - 0xF0 << 18; |
|
482 |
$codepoint += ord($char[1]) - 0x80 << 12; |
|
483 |
$codepoint += ord($char[2]) - 0x80 << 6; |
|
484 |
$codepoint += ord($char[3]) - 0x80; |
|
485 |
|
|
486 |
return '&#' . $codepoint . ';'; |
|
487 |
} |
|
488 |
|
|
316 | 489 |
} |
drupal7/sites/all/modules/feeds_jsonpath_parser/LICENSE.txt | ||
---|---|---|
1 |
GNU GENERAL PUBLIC LICENSE |
|
2 |
|
|
3 |
Version 2, June 1991 |
|
4 |
|
|
5 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, |
|
6 |
Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute |
|
7 |
verbatim copies of this license document, but changing it is not allowed. |
|
8 |
|
|
9 |
Preamble |
|
10 |
|
|
11 |
The licenses for most software are designed to take away your freedom to |
|
12 |
share and change it. By contrast, the GNU General Public License is |
|
13 |
intended to guarantee your freedom to share and change free software--to |
|
14 |
make sure the software is free for all its users. This General Public License |
|
15 |
applies to most of the Free Software Foundation's software and to any other |
|
16 |
program whose authors commit to using it. (Some other Free Software |
|
17 |
Foundation software is covered by the GNU Library General Public License |
|
18 |
instead.) You can apply it to your programs, too. |
|
19 |
|
|
20 |
When we speak of free software, we are referring to freedom, not price. Our |
|
21 |
General Public Licenses are designed to make sure that you have the |
|
22 |
freedom to distribute copies of free software (and charge for this service if |
|
23 |
you wish), that you receive source code or can get it if you want it, that you |
|
24 |
can change the software or use pieces of it in new free programs; and that |
|
25 |
you know you can do these things. |
|
26 |
|
|
27 |
To protect your rights, we need to make restrictions that forbid anyone to |
|
28 |
deny you these rights or to ask you to surrender the rights. These restrictions |
|
29 |
translate to certain responsibilities for you if you distribute copies of the |
|
30 |
software, or if you modify it. |
|
31 |
|
|
32 |
For example, if you distribute copies of such a program, whether gratis or for |
|
33 |
a fee, you must give the recipients all the rights that you have. You must make |
|
34 |
sure that they, too, receive or can get the source code. And you must show |
|
35 |
them these terms so they know their rights. |
|
36 |
|
|
37 |
We protect your rights with two steps: (1) copyright the software, and (2) |
|
38 |
offer you this license which gives you legal permission to copy, distribute |
|
39 |
and/or modify the software. |
|
40 |
|
|
41 |
Also, for each author's protection and ours, we want to make certain that |
|
42 |
everyone understands that there is no warranty for this free software. If the |
|
43 |
software is modified by someone else and passed on, we want its recipients |
|
44 |
to know that what they have is not the original, so that any problems |
|
45 |
introduced by others will not reflect on the original authors' reputations. |
|
46 |
|
|
47 |
Finally, any free program is threatened constantly by software patents. We |
|
48 |
wish to avoid the danger that redistributors of a free program will individually |
|
49 |
obtain patent licenses, in effect making the program proprietary. To prevent |
|
50 |
this, we have made it clear that any patent must be licensed for everyone's |
|
51 |
free use or not licensed at all. |
|
52 |
|
|
53 |
The precise terms and conditions for copying, distribution and modification |
|
54 |
follow. |
|
55 |
|
|
56 |
GNU GENERAL PUBLIC LICENSE |
|
57 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND |
|
58 |
MODIFICATION |
|
59 |
|
|
60 |
0. This License applies to any program or other work which contains a notice |
|
61 |
placed by the copyright holder saying it may be distributed under the terms |
|
62 |
of this General Public License. The "Program", below, refers to any such |
|
63 |
program or work, and a "work based on the Program" means either the |
|
64 |
Program or any derivative work under copyright law: that is to say, a work |
|
65 |
containing the Program or a portion of it, either verbatim or with |
|
66 |
modifications and/or translated into another language. (Hereinafter, translation |
|
67 |
is included without limitation in the term "modification".) Each licensee is |
|
68 |
addressed as "you". |
|
69 |
|
|
70 |
Activities other than copying, distribution and modification are not covered |
|
71 |
by this License; they are outside its scope. The act of running the Program is |
|
72 |
not restricted, and the output from the Program is covered only if its contents |
|
73 |
constitute a work based on the Program (independent of having been made |
|
74 |
by running the Program). Whether that is true depends on what the Program |
|
75 |
does. |
|
76 |
|
|
77 |
1. You may copy and distribute verbatim copies of the Program's source |
|
78 |
code as you receive it, in any medium, provided that you conspicuously and |
|
79 |
appropriately publish on each copy an appropriate copyright notice and |
|
80 |
disclaimer of warranty; keep intact all the notices that refer to this License |
|
81 |
and to the absence of any warranty; and give any other recipients of the |
|
82 |
Program a copy of this License along with the Program. |
|
83 |
|
|
84 |
You may charge a fee for the physical act of transferring a copy, and you |
|
85 |
may at your option offer warranty protection in exchange for a fee. |
|
86 |
|
|
87 |
2. You may modify your copy or copies of the Program or any portion of it, |
|
88 |
thus forming a work based on the Program, and copy and distribute such |
|
89 |
modifications or work under the terms of Section 1 above, provided that you |
|
90 |
also meet all of these conditions: |
|
91 |
|
|
92 |
a) You must cause the modified files to carry prominent notices stating that |
|
93 |
you changed the files and the date of any change. |
|
94 |
|
|
95 |
b) You must cause any work that you distribute or publish, that in whole or in |
|
96 |
part contains or is derived from the Program or any part thereof, to be |
|
97 |
licensed as a whole at no charge to all third parties under the terms of this |
|
98 |
License. |
|
99 |
|
|
100 |
c) If the modified program normally reads commands interactively when run, |
|
101 |
you must cause it, when started running for such interactive use in the most |
|
102 |
ordinary way, to print or display an announcement including an appropriate |
|
103 |
copyright notice and a notice that there is no warranty (or else, saying that |
|
104 |
you provide a warranty) and that users may redistribute the program under |
|
105 |
these conditions, and telling the user how to view a copy of this License. |
|
106 |
(Exception: if the Program itself is interactive but does not normally print such |
|
107 |
an announcement, your work based on the Program is not required to print |
|
108 |
an announcement.) |
|
109 |
|
|
110 |
These requirements apply to the modified work as a whole. If identifiable |
|
111 |
sections of that work are not derived from the Program, and can be |
|
112 |
reasonably considered independent and separate works in themselves, then |
|
113 |
this License, and its terms, do not apply to those sections when you distribute |
|
114 |
them as separate works. But when you distribute the same sections as part |
|
115 |
of a whole which is a work based on the Program, the distribution of the |
|
116 |
whole must be on the terms of this License, whose permissions for other |
|
117 |
licensees extend to the entire whole, and thus to each and every part |
|
118 |
regardless of who wrote it. |
|
119 |
|
|
120 |
Thus, it is not the intent of this section to claim rights or contest your rights to |
|
121 |
work written entirely by you; rather, the intent is to exercise the right to |
|
122 |
control the distribution of derivative or collective works based on the |
|
123 |
Program. |
|
1 |
GNU GENERAL PUBLIC LICENSE |
|
2 |
Version 2, June 1991 |
|
3 |
|
|
4 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc., |
|
5 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
6 |
Everyone is permitted to copy and distribute verbatim copies |
|
7 |
of this license document, but changing it is not allowed. |
|
8 |
|
|
9 |
Preamble |
|
10 |
|
|
11 |
The licenses for most software are designed to take away your |
|
12 |
freedom to share and change it. By contrast, the GNU General Public |
|
13 |
License is intended to guarantee your freedom to share and change free |
|
14 |
software--to make sure the software is free for all its users. This |
|
15 |
General Public License applies to most of the Free Software |
|
16 |
Foundation's software and to any other program whose authors commit to |
|
17 |
using it. (Some other Free Software Foundation software is covered by |
|
18 |
the GNU Lesser General Public License instead.) You can apply it to |
|
19 |
your programs, too. |
|
20 |
|
|
21 |
When we speak of free software, we are referring to freedom, not |
|
22 |
price. Our General Public Licenses are designed to make sure that you |
|
23 |
have the freedom to distribute copies of free software (and charge for |
|
24 |
this service if you wish), that you receive source code or can get it |
|
25 |
if you want it, that you can change the software or use pieces of it |
|
26 |
in new free programs; and that you know you can do these things. |
|
27 |
|
|
28 |
To protect your rights, we need to make restrictions that forbid |
|
29 |
anyone to deny you these rights or to ask you to surrender the rights. |
|
30 |
These restrictions translate to certain responsibilities for you if you |
|
31 |
distribute copies of the software, or if you modify it. |
|
32 |
|
|
33 |
For example, if you distribute copies of such a program, whether |
|
34 |
gratis or for a fee, you must give the recipients all the rights that |
|
35 |
you have. You must make sure that they, too, receive or can get the |
|
36 |
source code. And you must show them these terms so they know their |
|
37 |
rights. |
|
38 |
|
|
39 |
We protect your rights with two steps: (1) copyright the software, and |
|
40 |
(2) offer you this license which gives you legal permission to copy, |
|
41 |
distribute and/or modify the software. |
|
42 |
|
|
43 |
Also, for each author's protection and ours, we want to make certain |
|
44 |
that everyone understands that there is no warranty for this free |
|
45 |
software. If the software is modified by someone else and passed on, we |
|
46 |
want its recipients to know that what they have is not the original, so |
|
47 |
that any problems introduced by others will not reflect on the original |
|
48 |
authors' reputations. |
|
49 |
|
|
50 |
Finally, any free program is threatened constantly by software |
|
51 |
patents. We wish to avoid the danger that redistributors of a free |
|
52 |
program will individually obtain patent licenses, in effect making the |
|
53 |
program proprietary. To prevent this, we have made it clear that any |
|
54 |
patent must be licensed for everyone's free use or not licensed at all. |
|
55 |
|
|
56 |
The precise terms and conditions for copying, distribution and |
|
57 |
modification follow. |
|
58 |
|
|
59 |
GNU GENERAL PUBLIC LICENSE |
|
60 |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
61 |
|
|
62 |
0. This License applies to any program or other work which contains |
|
63 |
a notice placed by the copyright holder saying it may be distributed |
|
64 |
under the terms of this General Public License. The "Program", below, |
|
65 |
refers to any such program or work, and a "work based on the Program" |
|
66 |
means either the Program or any derivative work under copyright law: |
|
67 |
that is to say, a work containing the Program or a portion of it, |
|
68 |
either verbatim or with modifications and/or translated into another |
|
69 |
language. (Hereinafter, translation is included without limitation in |
|
70 |
the term "modification".) Each licensee is addressed as "you". |
|
71 |
|
|
72 |
Activities other than copying, distribution and modification are not |
|
73 |
covered by this License; they are outside its scope. The act of |
|
74 |
running the Program is not restricted, and the output from the Program |
|
75 |
is covered only if its contents constitute a work based on the |
|
76 |
Program (independent of having been made by running the Program). |
|
77 |
Whether that is true depends on what the Program does. |
|
78 |
|
|
79 |
1. You may copy and distribute verbatim copies of the Program's |
|
80 |
source code as you receive it, in any medium, provided that you |
|
81 |
conspicuously and appropriately publish on each copy an appropriate |
|
82 |
copyright notice and disclaimer of warranty; keep intact all the |
|
83 |
notices that refer to this License and to the absence of any warranty; |
|
84 |
and give any other recipients of the Program a copy of this License |
|
85 |
along with the Program. |
|
86 |
|
|
87 |
You may charge a fee for the physical act of transferring a copy, and |
|
88 |
you may at your option offer warranty protection in exchange for a fee. |
|
89 |
|
|
90 |
2. You may modify your copy or copies of the Program or any portion |
|
91 |
of it, thus forming a work based on the Program, and copy and |
|
92 |
distribute such modifications or work under the terms of Section 1 |
|
93 |
above, provided that you also meet all of these conditions: |
|
94 |
|
|
95 |
a) You must cause the modified files to carry prominent notices |
|
96 |
stating that you changed the files and the date of any change. |
|
97 |
|
|
98 |
b) You must cause any work that you distribute or publish, that in |
|
99 |
whole or in part contains or is derived from the Program or any |
|
100 |
part thereof, to be licensed as a whole at no charge to all third |
|
101 |
parties under the terms of this License. |
|
102 |
|
|
103 |
c) If the modified program normally reads commands interactively |
|
104 |
when run, you must cause it, when started running for such |
|
105 |
interactive use in the most ordinary way, to print or display an |
|
106 |
announcement including an appropriate copyright notice and a |
|
107 |
notice that there is no warranty (or else, saying that you provide |
|
108 |
a warranty) and that users may redistribute the program under |
|
109 |
these conditions, and telling the user how to view a copy of this |
|
110 |
License. (Exception: if the Program itself is interactive but |
|
111 |
does not normally print such an announcement, your work based on |
|
112 |
the Program is not required to print an announcement.) |
|
113 |
|
|
114 |
These requirements apply to the modified work as a whole. If |
|
115 |
identifiable sections of that work are not derived from the Program, |
|
116 |
and can be reasonably considered independent and separate works in |
|
117 |
themselves, then this License, and its terms, do not apply to those |
|
118 |
sections when you distribute them as separate works. But when you |
|
119 |
distribute the same sections as part of a whole which is a work based |
|
120 |
on the Program, the distribution of the whole must be on the terms of |
|
121 |
this License, whose permissions for other licensees extend to the |
|
122 |
entire whole, and thus to each and every part regardless of who wrote it. |
|
123 |
|
|
124 |
Thus, it is not the intent of this section to claim rights or contest |
|
125 |
your rights to work written entirely by you; rather, the intent is to |
|
126 |
exercise the right to control the distribution of derivative or |
|
127 |
collective works based on the Program. |
|
124 | 128 |
|
125 | 129 |
In addition, mere aggregation of another work not based on the Program |
126 |
with the Program (or with a work based on the Program) on a volume of a |
|
127 |
storage or distribution medium does not bring the other work under the scope |
|
128 |
of this License. |
|
129 |
|
|
130 |
3. You may copy and distribute the Program (or a work based on it, under |
|
131 |
Section 2) in object code or executable form under the terms of Sections 1 |
|
132 |
and 2 above provided that you also do one of the following: |
|
133 |
|
|
134 |
a) Accompany it with the complete corresponding machine-readable source |
|
135 |
code, which must be distributed under the terms of Sections 1 and 2 above |
|
136 |
on a medium customarily used for software interchange; or, |
|
137 |
|
|
138 |
b) Accompany it with a written offer, valid for at least three years, to give |
|
139 |
any third party, for a charge no more than your cost of physically performing |
|
140 |
source distribution, a complete machine-readable copy of the corresponding |
|
141 |
source code, to be distributed under the terms of Sections 1 and 2 above on |
|
142 |
a medium customarily used for software interchange; or, |
|
143 |
|
|
144 |
c) Accompany it with the information you received as to the offer to distribute |
|
145 |
corresponding source code. (This alternative is allowed only for |
|
146 |
noncommercial distribution and only if you received the program in object |
|
147 |
code or executable form with such an offer, in accord with Subsection b |
|
148 |
above.) |
|
130 |
with the Program (or with a work based on the Program) on a volume of |
|
131 |
a storage or distribution medium does not bring the other work under |
|
132 |
the scope of this License. |
|
133 |
|
|
134 |
3. You may copy and distribute the Program (or a work based on it, |
|
135 |
under Section 2) in object code or executable form under the terms of |
|
136 |
Sections 1 and 2 above provided that you also do one of the following: |
|
137 |
|
|
138 |
a) Accompany it with the complete corresponding machine-readable |
|
139 |
source code, which must be distributed under the terms of Sections |
|
140 |
1 and 2 above on a medium customarily used for software interchange; or, |
|
141 |
|
|
142 |
b) Accompany it with a written offer, valid for at least three |
|
143 |
years, to give any third party, for a charge no more than your |
|
144 |
cost of physically performing source distribution, a complete |
|
145 |
machine-readable copy of the corresponding source code, to be |
|
146 |
distributed under the terms of Sections 1 and 2 above on a medium |
|
147 |
customarily used for software interchange; or, |
|
148 |
|
|
149 |
c) Accompany it with the information you received as to the offer |
|
150 |
to distribute corresponding source code. (This alternative is |
|
151 |
allowed only for noncommercial distribution and only if you |
|
152 |
received the program in object code or executable form with such |
|
153 |
an offer, in accord with Subsection b above.) |
|
149 | 154 |
|
150 | 155 |
The source code for a work means the preferred form of the work for |
151 |
making modifications to it. For an executable work, complete source code |
|
152 |
means all the source code for all modules it contains, plus any associated |
|
153 |
interface definition files, plus the scripts used to control compilation and |
|
154 |
installation of the executable. However, as a special exception, the source |
|
155 |
code distributed need not include anything that is normally distributed (in |
|
156 |
either source or binary form) with the major components (compiler, kernel, |
|
157 |
and so on) of the operating system on which the executable runs, unless that |
|
158 |
component itself accompanies the executable. |
|
159 |
|
|
160 |
If distribution of executable or object code is made by offering access to |
|
161 |
copy from a designated place, then offering equivalent access to copy the |
|
162 |
source code from the same place counts as distribution of the source code, |
|
163 |
even though third parties are not compelled to copy the source along with the |
|
164 |
object code. |
|
165 |
|
|
166 |
4. You may not copy, modify, sublicense, or distribute the Program except as |
|
167 |
expressly provided under this License. Any attempt otherwise to copy, |
|
168 |
modify, sublicense or distribute the Program is void, and will automatically |
|
169 |
terminate your rights under this License. However, parties who have received |
|
170 |
copies, or rights, from you under this License will not have their licenses |
|
171 |
terminated so long as such parties remain in full compliance. |
|
172 |
|
|
173 |
5. You are not required to accept this License, since you have not signed it. |
|
174 |
However, nothing else grants you permission to modify or distribute the |
|
175 |
Program or its derivative works. These actions are prohibited by law if you |
|
176 |
do not accept this License. Therefore, by modifying or distributing the |
|
177 |
Program (or any work based on the Program), you indicate your acceptance |
|
178 |
of this License to do so, and all its terms and conditions for copying, |
|
179 |
distributing or modifying the Program or works based on it. |
|
180 |
|
|
181 |
6. Each time you redistribute the Program (or any work based on the |
|
182 |
Program), the recipient automatically receives a license from the original |
|
183 |
licensor to copy, distribute or modify the Program subject to these terms and |
|
184 |
conditions. You may not impose any further restrictions on the recipients' |
|
185 |
exercise of the rights granted herein. You are not responsible for enforcing |
|
186 |
compliance by third parties to this License. |
|
187 |
|
|
188 |
7. If, as a consequence of a court judgment or allegation of patent |
|
189 |
infringement or for any other reason (not limited to patent issues), conditions |
|
190 |
are imposed on you (whether by court order, agreement or otherwise) that |
|
191 |
contradict the conditions of this License, they do not excuse you from the |
|
192 |
conditions of this License. If you cannot distribute so as to satisfy |
|
193 |
simultaneously your obligations under this License and any other pertinent |
|
194 |
obligations, then as a consequence you may not distribute the Program at all. |
|
195 |
For example, if a patent license would not permit royalty-free redistribution |
|
196 |
of the Program by all those who receive copies directly or indirectly through |
|
197 |
you, then the only way you could satisfy both it and this License would be to |
|
156 |
making modifications to it. For an executable work, complete source |
|
157 |
code means all the source code for all modules it contains, plus any |
|
158 |
associated interface definition files, plus the scripts used to |
|
159 |
control compilation and installation of the executable. However, as a |
|
160 |
special exception, the source code distributed need not include |
|
161 |
anything that is normally distributed (in either source or binary |
|
162 |
form) with the major components (compiler, kernel, and so on) of the |
|
163 |
operating system on which the executable runs, unless that component |
|
164 |
itself accompanies the executable. |
|
165 |
|
|
166 |
If distribution of executable or object code is made by offering |
|
167 |
access to copy from a designated place, then offering equivalent |
|
168 |
access to copy the source code from the same place counts as |
|
169 |
distribution of the source code, even though third parties are not |
|
170 |
compelled to copy the source along with the object code. |
|
171 |
|
|
172 |
4. You may not copy, modify, sublicense, or distribute the Program |
|
173 |
except as expressly provided under this License. Any attempt |
|
174 |
otherwise to copy, modify, sublicense or distribute the Program is |
|
175 |
void, and will automatically terminate your rights under this License. |
|
176 |
However, parties who have received copies, or rights, from you under |
|
177 |
this License will not have their licenses terminated so long as such |
|
178 |
parties remain in full compliance. |
|
179 |
|
|
180 |
5. You are not required to accept this License, since you have not |
|
181 |
signed it. However, nothing else grants you permission to modify or |
|
182 |
distribute the Program or its derivative works. These actions are |
|
183 |
prohibited by law if you do not accept this License. Therefore, by |
|
184 |
modifying or distributing the Program (or any work based on the |
|
185 |
Program), you indicate your acceptance of this License to do so, and |
|
186 |
all its terms and conditions for copying, distributing or modifying |
|
187 |
the Program or works based on it. |
|
188 |
|
|
189 |
6. Each time you redistribute the Program (or any work based on the |
|
190 |
Program), the recipient automatically receives a license from the |
|
191 |
original licensor to copy, distribute or modify the Program subject to |
|
192 |
these terms and conditions. You may not impose any further |
|
193 |
restrictions on the recipients' exercise of the rights granted herein. |
|
194 |
You are not responsible for enforcing compliance by third parties to |
|
195 |
this License. |
|
196 |
|
|
197 |
7. If, as a consequence of a court judgment or allegation of patent |
|
198 |
infringement or for any other reason (not limited to patent issues), |
|
199 |
conditions are imposed on you (whether by court order, agreement or |
|
200 |
otherwise) that contradict the conditions of this License, they do not |
|
201 |
excuse you from the conditions of this License. If you cannot |
|
202 |
distribute so as to satisfy simultaneously your obligations under this |
|
203 |
License and any other pertinent obligations, then as a consequence you |
|
204 |
may not distribute the Program at all. For example, if a patent |
|
205 |
license would not permit royalty-free redistribution of the Program by |
|
206 |
all those who receive copies directly or indirectly through you, then |
|
207 |
the only way you could satisfy both it and this License would be to |
|
198 | 208 |
refrain entirely from distribution of the Program. |
199 | 209 |
|
200 |
If any portion of this section is held invalid or unenforceable under any |
|
201 |
particular circumstance, the balance of the section is intended to apply and |
|
202 |
the section as a whole is intended to apply in other circumstances. |
|
203 |
|
|
204 |
It is not the purpose of this section to induce you to infringe any patents or |
|
205 |
other property right claims or to contest validity of any such claims; this |
|
206 |
section has the sole purpose of protecting the integrity of the free software |
|
207 |
distribution system, which is implemented by public license practices. Many |
|
208 |
people have made generous contributions to the wide range of software |
|
209 |
distributed through that system in reliance on consistent application of that |
|
210 |
system; it is up to the author/donor to decide if he or she is willing to |
|
211 |
distribute software through any other system and a licensee cannot impose |
|
212 |
that choice. |
|
213 |
|
|
214 |
This section is intended to make thoroughly clear what is believed to be a |
|
215 |
consequence of the rest of this License. |
|
216 |
|
|
217 |
8. If the distribution and/or use of the Program is restricted in certain |
|
218 |
countries either by patents or by copyrighted interfaces, the original copyright |
|
219 |
holder who places the Program under this License may add an explicit |
|
220 |
geographical distribution limitation excluding those countries, so that |
|
221 |
distribution is permitted only in or among countries not thus excluded. In such |
|
222 |
case, this License incorporates the limitation as if written in the body of this |
|
223 |
License. |
|
224 |
|
|
225 |
9. The Free Software Foundation may publish revised and/or new versions |
|
226 |
of the General Public License from time to time. Such new versions will be |
|
227 |
similar in spirit to the present version, but may differ in detail to address new |
|
228 |
problems or concerns. |
|
229 |
|
|
230 |
Each version is given a distinguishing version number. If the Program specifies |
|
231 |
a version number of this License which applies to it and "any later version", |
|
232 |
you have the option of following the terms and conditions either of that |
|
233 |
version or of any later version published by the Free Software Foundation. If |
|
234 |
the Program does not specify a version number of this License, you may |
|
235 |
choose any version ever published by the Free Software Foundation. |
|
236 |
|
|
237 |
10. If you wish to incorporate parts of the Program into other free programs |
|
238 |
whose distribution conditions are different, write to the author to ask for |
|
239 |
permission. For software which is copyrighted by the Free Software |
|
240 |
Foundation, write to the Free Software Foundation; we sometimes make |
|
241 |
exceptions for this. Our decision will be guided by the two goals of |
|
242 |
preserving the free status of all derivatives of our free software and of |
|
243 |
promoting the sharing and reuse of software generally. |
|
244 |
|
|
245 |
NO WARRANTY |
|
246 |
|
|
247 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, |
|
248 |
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT |
|
249 |
PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE |
|
250 |
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR |
|
251 |
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT |
|
252 |
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, |
|
253 |
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
254 |
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
255 |
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND |
|
256 |
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
|
257 |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL |
|
258 |
NECESSARY SERVICING, REPAIR OR CORRECTION. |
|
259 |
|
|
260 |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR |
|
261 |
AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR |
|
262 |
ANY OTHER PARTY WHO MAY MODIFY AND/OR |
|
263 |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE |
|
264 |
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, |
|
265 |
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES |
|
266 |
ARISING OUT OF THE USE OR INABILITY TO USE THE |
|
267 |
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA |
|
268 |
OR DATA BEING RENDERED INACCURATE OR LOSSES |
|
269 |
SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE |
|
270 |
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN |
|
271 |
IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF |
|
272 |
THE POSSIBILITY OF SUCH DAMAGES. |
|
273 |
|
|
274 |
END OF TERMS AND CONDITIONS |
|
210 |
If any portion of this section is held invalid or unenforceable under |
|
211 |
any particular circumstance, the balance of the section is intended to |
|
212 |
apply and the section as a whole is intended to apply in other |
|
213 |
circumstances. |
|
214 |
|
|
215 |
It is not the purpose of this section to induce you to infringe any |
|
216 |
patents or other property right claims or to contest validity of any |
|
217 |
such claims; this section has the sole purpose of protecting the |
|
218 |
integrity of the free software distribution system, which is |
|
219 |
implemented by public license practices. Many people have made |
|
220 |
generous contributions to the wide range of software distributed |
|
221 |
through that system in reliance on consistent application of that |
|
222 |
system; it is up to the author/donor to decide if he or she is willing |
|
223 |
to distribute software through any other system and a licensee cannot |
|
224 |
impose that choice. |
|
225 |
|
|
226 |
This section is intended to make thoroughly clear what is believed to |
|
227 |
be a consequence of the rest of this License. |
|
228 |
|
|
229 |
8. If the distribution and/or use of the Program is restricted in |
|
230 |
certain countries either by patents or by copyrighted interfaces, the |
|
231 |
original copyright holder who places the Program under this License |
|
232 |
may add an explicit geographical distribution limitation excluding |
|
233 |
those countries, so that distribution is permitted only in or among |
|
234 |
countries not thus excluded. In such case, this License incorporates |
|
235 |
the limitation as if written in the body of this License. |
|
236 |
|
|
237 |
9. The Free Software Foundation may publish revised and/or new versions |
|
238 |
of the General Public License from time to time. Such new versions will |
|
239 |
be similar in spirit to the present version, but may differ in detail to |
|
240 |
address new problems or concerns. |
|
241 |
|
|
242 |
Each version is given a distinguishing version number. If the Program |
|
243 |
specifies a version number of this License which applies to it and "any |
|
244 |
later version", you have the option of following the terms and conditions |
|
245 |
either of that version or of any later version published by the Free |
|
246 |
Software Foundation. If the Program does not specify a version number of |
|
247 |
this License, you may choose any version ever published by the Free Software |
|
248 |
Foundation. |
|
249 |
|
|
250 |
10. If you wish to incorporate parts of the Program into other free |
|
251 |
programs whose distribution conditions are different, write to the author |
|
252 |
to ask for permission. For software which is copyrighted by the Free |
|
253 |
Software Foundation, write to the Free Software Foundation; we sometimes |
|
254 |
make exceptions for this. Our decision will be guided by the two goals |
|
255 |
of preserving the free status of all derivatives of our free software and |
|
256 |
of promoting the sharing and reuse of software generally. |
|
257 |
|
|
258 |
NO WARRANTY |
|
259 |
|
|
260 |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
|
261 |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
|
262 |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
|
263 |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
|
264 |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
265 |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
|
266 |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
|
267 |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
|
268 |
REPAIR OR CORRECTION. |
|
269 |
|
|
270 |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
|
271 |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
|
272 |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
|
273 |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
|
274 |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
|
275 |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
|
276 |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
|
277 |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
|
278 |
POSSIBILITY OF SUCH DAMAGES. |
|
279 |
|
|
280 |
END OF TERMS AND CONDITIONS |
|
281 |
|
|
282 |
How to Apply These Terms to Your New Programs |
|
283 |
|
|
284 |
If you develop a new program, and you want it to be of the greatest |
|
285 |
possible use to the public, the best way to achieve this is to make it |
|
286 |
free software which everyone can redistribute and change under these terms. |
|
287 |
|
|
288 |
To do so, attach the following notices to the program. It is safest |
|
289 |
to attach them to the start of each source file to most effectively |
|
290 |
convey the exclusion of warranty; and each file should have at least |
|
291 |
the "copyright" line and a pointer to where the full notice is found. |
|
292 |
|
|
293 |
<one line to give the program's name and a brief idea of what it does.> |
|
294 |
Copyright (C) <year> <name of author> |
|
295 |
|
|
296 |
This program is free software; you can redistribute it and/or modify |
|
297 |
it under the terms of the GNU General Public License as published by |
|
298 |
the Free Software Foundation; either version 2 of the License, or |
|
299 |
(at your option) any later version. |
|
300 |
|
|
301 |
This program is distributed in the hope that it will be useful, |
|
302 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
303 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
304 |
GNU General Public License for more details. |
|
305 |
|
|
306 |
You should have received a copy of the GNU General Public License along |
|
307 |
with this program; if not, write to the Free Software Foundation, Inc., |
|
308 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|
309 |
|
|
310 |
Also add information on how to contact you by electronic and paper mail. |
|
311 |
|
|
312 |
If the program is interactive, make it output a short notice like this |
|
313 |
when it starts in an interactive mode: |
|
314 |
|
|
315 |
Gnomovision version 69, Copyright (C) year name of author |
|
316 |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
|
317 |
This is free software, and you are welcome to redistribute it |
|
318 |
under certain conditions; type `show c' for details. |
|
319 |
|
|
320 |
The hypothetical commands `show w' and `show c' should show the appropriate |
|
321 |
parts of the General Public License. Of course, the commands you use may |
|
322 |
be called something other than `show w' and `show c'; they could even be |
|
323 |
mouse-clicks or menu items--whatever suits your program. |
|
324 |
|
|
325 |
You should also get your employer (if you work as a programmer) or your |
|
326 |
school, if any, to sign a "copyright disclaimer" for the program, if |
|
327 |
necessary. Here is a sample; alter the names: |
|
328 |
|
|
329 |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
|
330 |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
|
331 |
|
|
332 |
<signature of Ty Coon>, 1 April 1989 |
|
333 |
Ty Coon, President of Vice |
|
334 |
|
|
335 |
This General Public License does not permit incorporating your program into |
|
336 |
proprietary programs. If your program is a subroutine library, you may |
|
337 |
consider it more useful to permit linking proprietary applications with the |
|
338 |
library. If this is what you want to do, use the GNU Lesser General |
|
339 |
Public License instead of this License. |
drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.api.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
/** |
|
4 |
* @file |
|
5 |
* Documentation of Feeds JSONPath parser hooks. |
|
6 |
*/ |
|
7 |
|
|
8 |
/** |
|
9 |
* Allows filtering or modifying a feed item. |
|
10 |
* |
|
11 |
* @param array &$item |
|
12 |
* The feed item to modify. |
|
13 |
* |
|
14 |
* @return bool |
|
15 |
* Returns true if the item should be skipped. |
|
16 |
*/ |
|
17 |
function hook_feeds_jsonpath_parser_filter(array &$item, FeedsSource $source) { |
|
18 |
// Check for the importer. |
|
19 |
if ($source->id != 'my_importer') { |
|
20 |
return; |
|
21 |
} |
|
22 |
// 1) Alter the items array. |
|
23 |
$item['title'] = 'A hard coded title'; |
|
24 |
|
|
25 |
// 2) Return TRUE which will cause this item to be skipped. |
|
26 |
if ($item['title'] == 'An item I would like to skip.') { |
|
27 |
return TRUE; |
|
28 |
} |
|
29 |
} |
drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.info | ||
---|---|---|
1 |
; $Id: feeds_jsonpath_parser.info,v 1.1.4.2 2011/02/05 18:12:18 twistor Exp $ |
|
2 |
name = Feeds JSONPath Parser |
|
1 |
name = JSONPath Parser |
|
3 | 2 |
description = Parse a JSON document using JSONPath. |
4 | 3 |
files[] = tests/feeds_jsonpath_parser.test |
4 |
files[] = FeedsJSONPathParser.inc |
|
5 | 5 |
package = Feeds |
6 | 6 |
dependencies[] = feeds |
7 | 7 |
core = 7.x |
8 | 8 |
|
9 |
; Information added by drupal.org packaging script on January 1, 1970 - 00:00
|
|
10 |
version = "7.x-1.0-beta2"
|
|
9 |
; Information added by Drupal.org packaging script on 2015-06-25
|
|
10 |
version = "7.x-1.0" |
|
11 | 11 |
core = "7.x" |
12 | 12 |
project = "feeds_jsonpath_parser" |
13 |
datestamp = "1296934371"
|
|
13 |
datestamp = "1435272784"
|
|
14 | 14 |
|
drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.install | ||
---|---|---|
1 | 1 |
<?php |
2 |
// $Id: feeds_jsonpath_parser.install,v 1.1.2.1 2010/09/28 20:18:46 twistor Exp $ |
|
3 | 2 |
|
4 | 3 |
/** |
5 | 4 |
* @file |
... | ... | |
7 | 6 |
*/ |
8 | 7 |
|
9 | 8 |
/** |
10 |
* Implementation of hook_requirements().
|
|
9 |
* Implements hook_requirements().
|
|
11 | 10 |
*/ |
12 | 11 |
function feeds_jsonpath_parser_requirements($phase) { |
13 | 12 |
$requirements = array(); |
14 | 13 |
|
15 |
if ($phase == 'install') { |
|
16 |
$t = get_t(); |
|
17 |
$requirements['feeds_jsonpath_parser']['title'] = $t('Feeds JSONPath Parser'); |
|
18 |
|
|
19 |
if (file_exists(dirname(__FILE__) . '/jsonpath-0.8.1.php')) { |
|
20 |
$requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_OK; |
|
21 |
$requirements['feeds_jsonpath_parser']['value'] = '0.8.1'; |
|
22 |
} |
|
23 |
else { |
|
24 |
$requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_ERROR; |
|
25 |
$requirements['feeds_jsonpath_parser']['value'] = $t('Not found'); |
|
26 |
$requirements['feeds_jsonpath_parser']['description'] = $t('The <a href="@jsonpath">JSONPath</a> plugin is missing. <a href="@download">Download</a> and place in your module directory.', array( |
|
27 |
'@jsonpath' => 'http://goessner.net/articles/JsonPath/', |
|
28 |
'@download' => 'http://jsonpath.googlecode.com/files/jsonpath-0.8.1.php', |
|
29 |
)); |
|
30 |
} |
|
14 |
if ($phase !== 'runtime' && $phase !== 'install') { |
|
15 |
return $requirements; |
|
31 | 16 |
} |
17 |
|
|
18 |
drupal_load('module', 'feeds_jsonpath_parser'); |
|
19 |
|
|
20 |
$t = get_t(); |
|
21 |
$requirements['feeds_jsonpath_parser']['title'] = $t('JSONPath library'); |
|
22 |
$requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_OK; |
|
23 |
$requirements['feeds_jsonpath_parser']['value'] = $t('Installed'); |
|
24 |
|
|
25 |
if (!feeds_jsonpath_parser_library_path()) { |
|
26 |
$requirements['feeds_jsonpath_parser']['severity'] = REQUIREMENT_ERROR; |
|
27 |
$requirements['feeds_jsonpath_parser']['description'] = $t('The <a href="@jsonpath">JSONPath</a> plugin is missing. Download <a href="@download">this file</a> and place in sites/all/libraries/jsonpath.', array( |
|
28 |
'@jsonpath' => 'http://goessner.net/articles/JsonPath/', |
|
29 |
'@download' => 'http://jsonpath.googlecode.com/svn/trunk/src/php/jsonpath.php', |
|
30 |
)); |
|
31 |
$requirements['feeds_jsonpath_parser']['value'] = $t('Not installed'); |
|
32 |
} |
|
33 |
|
|
34 |
if ($phase === 'install') { |
|
35 |
unset($requirements['feeds_jsonpath_parser']['value']); |
|
36 |
} |
|
37 |
|
|
32 | 38 |
return $requirements; |
33 | 39 |
} |
drupal7/sites/all/modules/feeds_jsonpath_parser/feeds_jsonpath_parser.module | ||
---|---|---|
1 | 1 |
<?php |
2 |
// $Id: feeds_jsonpath_parser.module,v 1.1.4.1 2011/02/05 18:12:18 twistor Exp $ |
|
3 | 2 |
|
4 | 3 |
/** |
5 | 4 |
* Implements hook_feeds_plugins(). |
... | ... | |
28 | 27 |
function feeds_jsonpath_parser_enable() { |
29 | 28 |
cache_clear_all('plugins:feeds:plugins', 'cache'); |
30 | 29 |
} |
30 |
|
|
31 |
/** |
|
32 |
* Returns the path of the JSONPath library. |
|
33 |
* |
|
34 |
* @return string|bool |
|
35 |
* The relative path of the JSONPath directory, or false if not found. |
|
36 |
*/ |
|
37 |
function feeds_jsonpath_parser_library_path() { |
|
38 |
$libraries_path = module_exists('libraries') ? libraries_get_path('jsonpath') : FALSE; |
|
39 |
if ($libraries_path && is_dir($libraries_path)) { |
|
40 |
$path = $libraries_path; |
|
41 |
} |
|
42 |
elseif (is_dir(DRUPAL_ROOT . '/sites/all/libraries/jsonpath')) { |
|
43 |
$path = DRUPAL_ROOT . '/sites/all/libraries/jsonpath'; |
|
44 |
} |
|
45 |
// This is defined when simpletest downloads the library for us. |
|
46 |
elseif (variable_get('feeds_jsonpath_library_dir')) { |
|
47 |
$path = variable_get('feeds_jsonpath_library_dir'); |
|
48 |
} |
|
49 |
else { |
|
50 |
$search = glob(dirname(__FILE__) . '/jsonpath*.php'); |
|
51 |
return is_array($search) ? reset($search) : FALSE; |
|
52 |
} |
|
53 |
|
|
54 |
if (!isset($path)) { |
|
55 |
return FALSE; |
|
56 |
} |
|
57 |
|
|
58 |
// Newer forks of JSONPath are all modern and fancy with their autoloaders. |
|
59 |
if (is_file($path . '/vendor/autoload.php')) { |
|
60 |
return $path . '/vendor/autoload.php'; |
|
61 |
} |
|
62 |
// Old school. Look for multiple versions. |
|
63 |
foreach (glob($path . '/jsonpath*.php') as $file) { |
|
64 |
return $file; |
|
65 |
} |
|
66 |
|
|
67 |
return FALSE; |
|
68 |
} |
drupal7/sites/all/modules/feeds_jsonpath_parser/jsonpath-0.8.1.php | ||
---|---|---|
1 |
<?php |
|
2 |
/* JSONPath 0.8.1 - XPath for JSON |
|
3 |
* |
|
4 |
* Copyright (c) 2007 Stefan Goessner (goessner.net) |
|
5 |
* Licensed under the MIT (MIT-LICENSE.txt) licence. |
|
6 |
*/ |
|
7 |
|
|
8 |
// API function |
|
9 |
function jsonPath($obj, $expr, $args=null) { |
|
10 |
$jsonpath = new JsonPath(); |
|
11 |
$jsonpath->resultType = ($args ? $args['resultType'] : "VALUE"); |
|
12 |
$x = $jsonpath->normalize($expr); |
|
13 |
$jsonpath->obj = $obj; |
|
14 |
if ($expr && $obj && ($jsonpath->resultType == "VALUE" || $jsonpath->resultType == "PATH")) { |
|
15 |
$jsonpath->trace(preg_replace("/^\\$;/", "", $x), $obj, "$"); |
|
16 |
if (count($jsonpath->result)) |
|
17 |
return $jsonpath->result; |
|
18 |
else |
|
19 |
return false; |
|
20 |
} |
|
21 |
} |
|
22 |
|
|
23 |
// JsonPath class (internal use only) |
|
24 |
class JsonPath { |
|
25 |
var $obj = null; |
|
26 |
var $resultType = "Value"; |
|
27 |
var $result = array(); |
|
28 |
var $subx = array(); |
|
29 |
|
|
30 |
// normalize path expression |
|
31 |
function normalize($x) { |
|
32 |
$x = preg_replace_callback("/[\['](\??\(.*?\))[\]']/", array(&$this, "_callback_01"), $x); |
|
33 |
$x = preg_replace(array("/'?\.'?|\['?/", "/;;;|;;/", "/;$|'?\]|'$/"), |
|
34 |
array(";", ";..;", ""), |
|
35 |
$x); |
|
36 |
$x = preg_replace_callback("/#([0-9]+)/", array(&$this, "_callback_02"), $x); |
|
37 |
$this->result = array(); // result array was temporarily used as a buffer .. |
|
38 |
return $x; |
|
39 |
} |
|
40 |
function _callback_01($m) { return "[#".(array_push($this->result, $m[1])-1)."]"; } |
|
41 |
function _callback_02($m) { return $this->result[$m[1]]; } |
|
42 |
|
|
43 |
function asPath($path) { |
|
44 |
$x = explode(";", $path); |
|
45 |
$p = "$"; |
|
46 |
for ($i=1,$n=count($x); $i<$n; $i++) |
|
47 |
$p .= preg_match("/^[0-9*]+$/", $x[$i]) ? ("[".$x[$i]."]") : ("['".$x[$i]."']"); |
|
48 |
return $p; |
|
49 |
} |
|
50 |
function store($p, $v) { |
|
51 |
if ($p) array_push($this->result, ($this->resultType == "PATH" ? $this->asPath($p) : $v)); |
|
52 |
return !!$p; |
|
53 |
} |
|
54 |
function trace($expr, $val, $path) { |
|
55 |
if ($expr) { |
|
56 |
$x = explode(";", $expr); |
|
57 |
$loc = array_shift($x); |
|
58 |
$x = implode(";", $x); |
|
59 |
|
|
60 |
if (is_array($val) && array_key_exists($loc, $val)) |
|
61 |
$this->trace($x, $val[$loc], $path.";".$loc); |
|
62 |
else if ($loc == "*") |
|
63 |
$this->walk($loc, $x, $val, $path, array(&$this, "_callback_03")); |
|
64 |
else if ($loc === "..") { |
|
65 |
$this->trace($x, $val, $path); |
|
66 |
$this->walk($loc, $x, $val, $path, array(&$this, "_callback_04")); |
|
67 |
} |
|
68 |
else if (preg_match("/,/", $loc)) // [name1,name2,...] |
|
69 |
for ($s=preg_split("/'?,'?/", $loc),$i=0,$n=count($s); $i<$n; $i++) |
|
70 |
$this->trace($s[$i].";".$x, $val, $path); |
|
71 |
else if (preg_match("/^\(.*?\)$/", $loc)) // [(expr)] |
|
72 |
$this->trace($this->evalx($loc, $val, substr($path,strrpos($path,";")+1)).";".$x, $val, $path); |
|
73 |
else if (preg_match("/^\?\(.*?\)$/", $loc)) // [?(expr)] |
|
74 |
$this->walk($loc, $x, $val, $path, array(&$this, "_callback_05")); |
|
75 |
else if (preg_match("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", $loc)) // [start:end:step] phyton slice syntax |
|
76 |
$this->slice($loc, $x, $val, $path); |
|
77 |
} |
|
78 |
else |
|
79 |
$this->store($path, $val); |
|
80 |
} |
|
81 |
function _callback_03($m,$l,$x,$v,$p) { $this->trace($m.";".$x,$v,$p); } |
|
82 |
function _callback_04($m,$l,$x,$v,$p) { if (is_array($v[$m])) $this->trace("..;".$x,$v[$m],$p.";".$m); } |
|
83 |
function _callback_05($m,$l,$x,$v,$p) { if ($this->evalx(preg_replace("/^\?\((.*?)\)$/","$1",$l),$v[$m])) $this->trace($m.";".$x,$v,$p); } |
|
84 |
|
|
85 |
function walk($loc, $expr, $val, $path, $f) { |
|
86 |
foreach($val as $m => $v) |
|
87 |
call_user_func($f, $m, $loc, $expr, $val, $path); |
|
88 |
} |
|
89 |
function slice($loc, $expr, $v, $path) { |
|
90 |
$s = explode(":", preg_replace("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", "$1:$2:$3", $loc)); |
|
91 |
$len=count($v); |
|
92 |
$start=(int)$s[0]?$s[0]:0; |
|
93 |
$end=(int)$s[1]?$s[1]:$len; |
|
94 |
$step=(int)$s[2]?$s[2]:1; |
|
95 |
$start = ($start < 0) ? max(0,$start+$len) : min($len,$start); |
|
96 |
$end = ($end < 0) ? max(0,$end+$len) : min($len,$end); |
|
97 |
for ($i=$start; $i<$end; $i+=$step) |
|
98 |
$this->trace($i.";".$expr, $v, $path); |
|
99 |
} |
|
100 |
function evalx($x, $v, $vname) { |
|
101 |
$name = ""; |
|
102 |
$expr = preg_replace(array("/\\$/","/@/"), array("\$this->obj","\$v"), $x); |
|
103 |
$res = eval("\$name = $expr;"); |
|
104 |
|
|
105 |
if ($res === FALSE) |
|
106 |
print("(jsonPath) SyntaxError: " . $expr); |
|
107 |
else |
|
108 |
return $name; |
|
109 |
} |
|
110 |
} |
|
111 |
?> |
drupal7/sites/all/modules/feeds_jsonpath_parser/tests/feeds_jsonpath_parser.test | ||
---|---|---|
1 | 1 |
<?php |
2 |
// $Id: feeds_jsonpath_parser.test,v 1.1.2.1 2011/02/05 18:12:18 twistor Exp $ |
|
3 | 2 |
|
4 | 3 |
/** |
5 | 4 |
* @file |
... | ... | |
14 | 13 |
/** |
15 | 14 |
* Describe this test. |
16 | 15 |
*/ |
17 |
public function getInfo() { |
|
16 |
public static function getInfo() {
|
|
18 | 17 |
return array( |
19 | 18 |
'name' => t('JSONPath Parser'), |
20 | 19 |
'description' => t('Regression tests for Feeds JSONPath parser.'), |
21 |
'group' => t('Feeds'), |
|
20 |
'group' => t('Feeds JSONPath Parser'),
|
|
22 | 21 |
); |
23 | 22 |
} |
24 | 23 |
|
... | ... | |
26 | 25 |
* Set up test. |
27 | 26 |
*/ |
28 | 27 |
public function setUp() { |
29 |
parent::setUp(array('feeds', 'feeds_ui', 'ctools', 'job_scheduler', 'feeds_jsonpath_parser')); |
|
28 |
parent::setUp(array('feeds_jsonpath_parser')); |
|
29 |
$this->downloadJsonPath(); |
|
30 |
} |
|
31 |
|
|
32 |
/** |
|
33 |
* Downloads JSONPath. |
|
34 |
*/ |
|
35 |
protected function downloadJsonPath() { |
|
36 |
// We don't use a variable_set() here since we want this to be a unit test. |
|
37 |
if (variable_get('feeds_jsonpath_library_dir')) { |
|
38 |
return; |
|
39 |
} |
|
40 |
$url = 'https://jsonpath.googlecode.com/svn/trunk/src/php/jsonpath.php'; |
|
41 |
$filename = 'jsonpath.php'; |
|
42 |
|
|
43 |
// Avoid downloading the file dozens of times. |
|
44 |
$library_dir = $this->originalFileDirectory . '/simpletest/feeds_jsonpath_parser'; |
|
45 |
$jsonpath_library_dir = DRUPAL_ROOT . '/' . $library_dir . '/jsonpath'; |
|
46 |
|
|
47 |
if (!file_exists(DRUPAL_ROOT . '/' . $library_dir)) { |
|
48 |
drupal_mkdir(DRUPAL_ROOT . '/' . $library_dir); |
|
49 |
} |
|
50 |
|
|
51 |
if (!file_exists($jsonpath_library_dir)) { |
|
52 |
drupal_mkdir($jsonpath_library_dir); |
|
53 |
} |
|
54 |
|
|
55 |
// Local file name. |
|
56 |
$local_file = $jsonpath_library_dir . '/' . $filename; |
|
57 |
|
|
58 |
// Begin single threaded code. |
|
59 |
if (function_exists('sem_get')) { |
|
60 |
$semaphore = sem_get(ftok(__FILE__, 1)); |
|
61 |
sem_acquire($semaphore); |
|
62 |
} |
|
63 |
|
|
64 |
// Download and extact the archive, but only in one thread. |
|
65 |
if (!file_exists($local_file)) { |
|
66 |
$local_file = system_retrieve_file($url, $local_file, FALSE, FILE_EXISTS_REPLACE); |
|
67 |
} |
|
68 |
|
|
69 |
if (function_exists('sem_get')) { |
|
70 |
sem_release($semaphore); |
|
71 |
} |
|
72 |
|
|
73 |
// Verify that the file was successfully downloaded. |
|
74 |
$this->assertTrue(file_exists($local_file), format_string('@file found.', array('@file' => $local_file))); |
|
75 |
|
|
76 |
// Set the library directory. |
|
77 |
variable_set('feeds_jsonpath_library_dir', $jsonpath_library_dir); |
|
30 | 78 |
} |
31 | 79 |
|
32 | 80 |
/** |
... | ... | |
55 | 103 |
'jsonpath[context]' => '$.store.book[*]', |
56 | 104 |
'jsonpath[sources][jsonpath_parser:0]' => 'author', |
57 | 105 |
'jsonpath[sources][jsonpath_parser:1]' => 'price', |
106 |
'jsonpath[allow_override]' => TRUE, |
|
58 | 107 |
); |
59 |
$this->drupalPost('admin/structure/feeds/edit/jsonpath/settings/FeedsJSONPathParser', $edit, 'Save'); |
|
60 |
$this->assertText('Your changes have been saved.'); |
|
61 |
$this->assertRaw('$.store.book[*]'); |
|
62 |
$this->assertRaw('author'); |
|
63 |
$this->assertRaw('price'); |
|
108 |
$edit_url = 'admin/structure/feeds/jsonpath/settings/FeedsJSONPathParser'; |
|
109 |
$node_save_text = 'Basic page Testing JSONPath Parser has been updated.'; |
|
110 |
|
|
111 |
$this->postAndCheck($edit_url, $edit, 'Save', 'Your changes have been saved.'); |
|
64 | 112 |
|
65 | 113 |
// Test import. |
66 |
$path = $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds_jsonpath_parser') .'/tests/feeds_jsonpath_parser/';
|
|
67 |
$nid = $this->createFeedNode('jsonpath', $path . 'test.json', 'Testing JSONPath Parser'); |
|
114 |
$path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds_jsonpath_parser') . '/tests/feeds_jsonpath_parser';
|
|
115 |
$nid = $this->createFeedNode('jsonpath', $path . '/test.json', 'Testing JSONPath Parser');
|
|
68 | 116 |
$this->assertText('Created 4 nodes'); |
69 | 117 |
|
70 | 118 |
// Import again, this verifies url field was mapped correctly. |
71 |
$this->drupalPost('node/'. $nid .'/import', array(), 'Import');
|
|
119 |
$this->drupalPost('node/' . $nid . '/import', array(), 'Import');
|
|
72 | 120 |
$this->assertText('There are no new nodes'); |
73 | 121 |
|
74 | 122 |
// Assert accuracy of aggregated content. I find humor in using our own |
... | ... | |
85 | 133 |
'feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:0]' => 'bar', |
86 | 134 |
'feeds[FeedsJSONPathParser][jsonpath][sources][jsonpath_parser:1]' => 'baz', |
87 | 135 |
); |
88 |
$this->drupalPost('node/'. $nid .'/edit', $edit, 'Save'); |
|
89 |
$this->drupalGet('node/'. $nid .'/edit'); |
|
90 |
// Why not use XPath to test JSONPath? |
|
91 |
$this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-context"][1]/@value', '/foo'); |
|
92 |
$this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser0"][1]/@value', 'bar'); |
|
93 |
$this->assertFieldByXPath('//input[@id="edit-feeds-feedsjsonpathparser-jsonpath-sources-jsonpath-parser1"][1]/@value', 'baz'); |
|
94 |
|
Formats disponibles : Unified diff
Update Feeds JSONPath Parser 7.x-1.0-beta2 -> 7.x-1.0