From 5697f7c92cbc7b2c23d2a8c6ba3d904734dd0739 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Mon, 22 Dec 2014 09:16:08 +0100 Subject: udpate picofeed --- composer.lock | 9 +- vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 10 +- vendor/composer/installed.json | 8 +- vendor/fguillot/picofeed/README.markdown | 1 + .../fguillot/picofeed/docs/feed-parsing.markdown | 1 + vendor/fguillot/picofeed/docs/grabber.markdown | 28 +- .../picofeed/lib/PicoFeed/Client/Client.php | 50 +- .../fguillot/picofeed/lib/PicoFeed/Client/Curl.php | 9 +- .../picofeed/lib/PicoFeed/Client/Grabber.php | 19 +- .../picofeed/lib/PicoFeed/Client/HttpHeaders.php | 43 ++ .../picofeed/lib/PicoFeed/Client/Stream.php | 8 +- .../picofeed/lib/PicoFeed/Config/Config.php | 4 +- .../picofeed/lib/PicoFeed/Encoding/Encoding.php | 20 +- .../picofeed/lib/PicoFeed/Filter/Attribute.php | 24 +- .../picofeed/lib/PicoFeed/Filter/Filter.php | 15 +- .../fguillot/picofeed/lib/PicoFeed/Filter/Html.php | 4 +- .../fguillot/picofeed/lib/PicoFeed/Filter/Tag.php | 2 +- .../fguillot/picofeed/lib/PicoFeed/Parser/Atom.php | 12 +- .../fguillot/picofeed/lib/PicoFeed/Parser/Feed.php | 12 + .../fguillot/picofeed/lib/PicoFeed/Parser/Item.php | 10 +- .../picofeed/lib/PicoFeed/Parser/Parser.php | 41 +- .../picofeed/lib/PicoFeed/Parser/XmlParser.php | 6 +- .../picofeed/lib/PicoFeed/Reader/Favicon.php | 1 - .../picofeed/lib/PicoFeed/Reader/Reader.php | 4 +- .../picofeed/lib/PicoFeed/Rules/01net.com.php | 15 + .../picofeed/lib/PicoFeed/Serialization/Export.php | 2 +- .../picofeed/lib/PicoFeed/Serialization/Import.php | 1 - vendor/fguillot/picofeed/picofeed | 18 + .../fguillot/picofeed/tests/Client/ClientTest.php | 17 + .../picofeed/tests/Client/HttpHeadersTest.php | 19 + .../picofeed/tests/Parser/AtomParserTest.php | 38 +- vendor/fguillot/picofeed/tests/Parser/FeedTest.php | 24 + .../fguillot/picofeed/tests/Parser/ParserTest.php | 8 + .../fguillot/picofeed/tests/Reader/ReaderTest.php | 4 +- .../fguillot/picofeed/tests/fixtures/hamakor.xml | 527 +++++++++++++++++++++ 36 files changed, 902 insertions(+), 114 deletions(-) create mode 100644 vendor/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php create mode 100644 vendor/fguillot/picofeed/lib/PicoFeed/Rules/01net.com.php create mode 100644 vendor/fguillot/picofeed/tests/Client/HttpHeadersTest.php create mode 100644 vendor/fguillot/picofeed/tests/Parser/FeedTest.php create mode 100644 vendor/fguillot/picofeed/tests/fixtures/hamakor.xml diff --git a/composer.lock b/composer.lock index a73fdcce7..8771a76cf 100644 --- a/composer.lock +++ b/composer.lock @@ -57,12 +57,12 @@ "source": { "type": "git", "url": "https://github.com/fguillot/picoFeed.git", - "reference": "6485f32d62698be73c3f0456bb87d960fcae1586" + "reference": "11589851f91cc3f04c84ba873484486d1457e638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/6485f32d62698be73c3f0456bb87d960fcae1586", - "reference": "6485f32d62698be73c3f0456bb87d960fcae1586", + "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/11589851f91cc3f04c84ba873484486d1457e638", + "reference": "11589851f91cc3f04c84ba873484486d1457e638", "shasum": "" }, "require": { @@ -86,7 +86,7 @@ ], "description": "Modern library to write or read feeds (RSS/Atom)", "homepage": "http://fguillot.github.io/picoFeed", - "time": "2014-12-16 23:53:59" + "time": "2014-12-22 03:23:04" }, { "name": "pear/net_url2", @@ -160,6 +160,7 @@ "fguillot/picofeed": 20 }, "prefer-stable": false, + "prefer-lowest": false, "platform": [], "platform-dev": [] } diff --git a/vendor/autoload.php b/vendor/autoload.php index f8495def9..3525cd9c6 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInitb70f37963a41b6db289ef240676024ef::getLoader(); +return ComposerAutoloaderInit473bffa75e8c08e86770574b2fe57877::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 113cd5ee5..b53f76186 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitb70f37963a41b6db289ef240676024ef +class ComposerAutoloaderInit473bffa75e8c08e86770574b2fe57877 { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInitb70f37963a41b6db289ef240676024ef return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitb70f37963a41b6db289ef240676024ef', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit473bffa75e8c08e86770574b2fe57877', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitb70f37963a41b6db289ef240676024ef', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit473bffa75e8c08e86770574b2fe57877', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; array_push($includePaths, get_include_path()); @@ -46,14 +46,14 @@ class ComposerAutoloaderInitb70f37963a41b6db289ef240676024ef $includeFiles = require __DIR__ . '/autoload_files.php'; foreach ($includeFiles as $file) { - composerRequireb70f37963a41b6db289ef240676024ef($file); + composerRequire473bffa75e8c08e86770574b2fe57877($file); } return $loader; } } -function composerRequireb70f37963a41b6db289ef240676024ef($file) +function composerRequire473bffa75e8c08e86770574b2fe57877($file) { require $file; } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 2a5124d70..46ce73f9a 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -119,18 +119,18 @@ "source": { "type": "git", "url": "https://github.com/fguillot/picoFeed.git", - "reference": "6485f32d62698be73c3f0456bb87d960fcae1586" + "reference": "11589851f91cc3f04c84ba873484486d1457e638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/6485f32d62698be73c3f0456bb87d960fcae1586", - "reference": "6485f32d62698be73c3f0456bb87d960fcae1586", + "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/11589851f91cc3f04c84ba873484486d1457e638", + "reference": "11589851f91cc3f04c84ba873484486d1457e638", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2014-12-16 23:53:59", + "time": "2014-12-22 03:23:04", "type": "library", "installation-source": "dist", "autoload": { diff --git a/vendor/fguillot/picofeed/README.markdown b/vendor/fguillot/picofeed/README.markdown index a1e1e39c5..ea18adbb6 100644 --- a/vendor/fguillot/picofeed/README.markdown +++ b/vendor/fguillot/picofeed/README.markdown @@ -41,6 +41,7 @@ Authors - Major Contributors: - [Bernhard Posselt](https://github.com/Raydiation) - [David Pennington](https://github.com/Xeoncross) + - [Mathias Kresin](https://github.com/mkresin) Real world usage ---------------- diff --git a/vendor/fguillot/picofeed/docs/feed-parsing.markdown b/vendor/fguillot/picofeed/docs/feed-parsing.markdown index 82d3703e9..d00e08364 100644 --- a/vendor/fguillot/picofeed/docs/feed-parsing.markdown +++ b/vendor/fguillot/picofeed/docs/feed-parsing.markdown @@ -50,6 +50,7 @@ Feed::language = en-US Feed::description = Feed::logo = Feed::items = 15 items +Feed::isRTL() = false ---- Item::id = 38d8f48284fb03940cbb3aff9101089b81e44efb1281641bdd7c3e7e4bf3b0cd Item::title = openSUSE 13.2 : nouvelle version du caméléon disponible ! diff --git a/vendor/fguillot/picofeed/docs/grabber.markdown b/vendor/fguillot/picofeed/docs/grabber.markdown index 2098b25d0..b99b756ed 100644 --- a/vendor/fguillot/picofeed/docs/grabber.markdown +++ b/vendor/fguillot/picofeed/docs/grabber.markdown @@ -12,12 +12,36 @@ How the content grabber works? **The best results are obtained with XPath rules file.** -How to use the content scraper? -------------------------------- +Standalone usage +---------------- + +```php +download(); +$grabber->parse(); + +// Get raw HTML content +echo $grabber->getRawContent(); + +// Get relevant content +echo $grabber->getContent(); + +// Get filtered relevant content +echo $grabber->getFilteredContent(); +``` + +Fetch full item contents during feed parsing +-------------------------------------------- Before parsing all items, just call the method `$parser->enableContentGrabber()`: ```php +is_modified = false; } else if ($response['status'] == 200) { - - $etag = $this->getHeader($response, 'ETag'); - $last_modified = $this->getHeader($response, 'Last-Modified'); - - if ($this->isPropertyEquals('etag', $etag) || $this->isPropertyEquals('last_modified', $last_modified)) { - $this->is_modified = false; - } - - $this->etag = $etag; - $this->last_modified = $last_modified; + $this->is_modified = $this->hasBeenModified($response, $this->etag, $this->last_modified); + $this->etag = $this->getHeader($response, 'ETag'); + $this->last_modified = $this->getHeader($response, 'Last-Modified'); } if ($this->is_modified === false) { @@ -245,16 +238,39 @@ abstract class Client } /** - * Check if a class property equals to a value + * Check if a request has been modified according to the parameters * * @access public - * @param string $property Class property - * @param string $value Value + * @param array $response + * @param string $etag + * @param string $lastModified * @return boolean */ - private function isPropertyEquals($property, $value) + private function hasBeenModified($response, $etag, $lastModified) { - return $this->$property && $this->$property === $value; + $headers = array( + 'Etag' => $etag, + 'Last-Modified' => $lastModified + ); + + // Compare the values for each header that is present + $presentCacheHeaderCount = 0; + foreach ($headers as $key => $value) { + if (isset($response['headers'][$key])) { + if ($response['headers'][$key] !== $value) { + return true; + } + $presentCacheHeaderCount++; + } + } + + // If at least one header is present and the values match, the response + // was not modified + if ($presentCacheHeaderCount > 0) { + return false; + } + + return true; } /** @@ -324,7 +340,7 @@ abstract class Client Logger::setMessage(get_called_class().' HTTP header: '.$name.' => '.$value); } - return array($status, $headers); + return array($status, new HttpHeaders($headers)); } /** @@ -552,7 +568,7 @@ abstract class Client * * @access public * @param \PicoFeed\Config\Config $config Config instance - * @return \PicoFeed\Config\Config + * @return \PicoFeed\Client\Client */ public function setConfig($config) { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php index 2b0d7e1c0..54b3c6ef9 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php @@ -99,7 +99,7 @@ class Curl extends Client * Prepare HTTP headers * * @access private - * @return array + * @return string[] */ private function prepareHeaders() { @@ -123,7 +123,7 @@ class Curl extends Client * Prepare curl proxy context * * @access private - * @return resource + * @return resource $ch */ private function prepareProxyContext($ch) { @@ -199,6 +199,9 @@ class Curl extends Client $this->handleError($curl_errno); } + // Update the url if there where redirects + $this->url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + curl_close($ch); } @@ -215,7 +218,7 @@ class Curl extends Client list($status, $headers) = $this->parseHeaders(explode("\r\n", $this->headers[$this->headers_counter - 1])); - // When resticted with open_basedir + // When restricted with open_basedir if ($this->needToHandleRedirection($follow_location, $status)) { return $this->handleRedirection($headers['Location']); } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Grabber.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Grabber.php index 57661cb7b..1bca05664 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Grabber.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Grabber.php @@ -3,7 +3,6 @@ namespace PicoFeed\Client; use DOMXPath; - use PicoFeed\Encoding\Encoding; use PicoFeed\Logging\Logger; use PicoFeed\Filter\Filter; @@ -148,7 +147,7 @@ class Grabber * * @access public * @param \PicoFeed\Config\Config $config Config instance - * @return \PicoFeed\Grabber + * @return Grabber */ public function setConfig($config) { @@ -178,6 +177,19 @@ class Grabber return $this->html; } + /** + * Get filtered relevant content + * + * @access public + * @return string + */ + public function getFilteredContent() + { + $filter = Filter::html($this->content, $this->url); + $filter->setConfig($this->config); + return $filter->execute(); + } + /** * Parse the HTML content * @@ -191,8 +203,8 @@ class Grabber Logger::setMessage(get_called_class().' Fix encoding'); Logger::setMessage(get_called_class().': HTTP Encoding "'.$this->encoding.'"'); - $this->html = Filter::stripHeadTags($this->html); $this->html = Encoding::convert($this->html, $this->encoding); + $this->html = Filter::stripHeadTags($this->html); Logger::setMessage(get_called_class().' Content length: '.strlen($this->html).' bytes'); $rules = $this->getRules(); @@ -228,6 +240,7 @@ class Grabber $client->setConfig($this->config); $client->execute($this->url); + $this->url = $client->getUrl(); $this->html = $client->getContent(); $this->encoding = $client->getEncoding(); diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php new file mode 100644 index 000000000..4453a7871 --- /dev/null +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php @@ -0,0 +1,43 @@ + $value) { + $this->headers[strtolower($key)] = $value; + } + } + + public function offsetGet($offset) + { + return $this->headers[strtolower($offset)]; + } + + public function offsetSet($offset, $value) + { + $this->headers[strtolower($offset)] = $value; + } + + public function offsetExists($offset) + { + return isset($this->headers[strtolower($offset)]); + } + + public function offsetUnset($offset) + { + unset($this->headers[strtolower($offset)]); + } +} diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php index a0058f9b0..32d045cb1 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php @@ -16,7 +16,7 @@ class Stream extends Client * Prepare HTTP headers * * @access private - * @return array + * @return string[] */ private function prepareHeaders() { @@ -128,11 +128,11 @@ class Stream extends Client * Decode body response according to the HTTP headers * * @access public - * @param string $body Raw body - * @param array $headers HTTP headers + * @param string $body Raw body + * @param HttpHeaders $headers HTTP headers * @return string */ - public function decodeBody($body, array $headers) + public function decodeBody($body, HttpHeaders $headers) { if (isset($headers['Transfer-Encoding']) && $headers['Transfer-Encoding'] === 'chunked') { $body = $this->decodeChunked($body); diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php b/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php index 9a5381f0f..2ee3718eb 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php @@ -55,8 +55,8 @@ namespace PicoFeed\Config; * @method array getFilterSchemeWhitelist(array $default_value) * @method array getFilterWhitelistedTags(array $default_value) * @method array getFilterBlacklistedTags(array $default_value) - * @method string getFilterImageProxyUrl($default_value) - * @method string getFilterImageProxyCallback($default_value) + * @method string getFilterImageProxyUrl() + * @method \Closure getFilterImageProxyCallback() */ class Config { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Encoding/Encoding.php b/vendor/fguillot/picofeed/lib/PicoFeed/Encoding/Encoding.php index d6296c0b6..7739def5f 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Encoding/Encoding.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Encoding/Encoding.php @@ -152,20 +152,16 @@ class Encoding return $cc1.$cc2; } - public static function convert_CP_1251($input) - { - return iconv('CP1251', 'UTF-8//TRANSLIT', $input); - } - public static function convert($input, $encoding) { - if ($encoding === 'windows-1251') { - return self::convert_CP_1251($input); + switch ($encoding) { + case 'utf-8': + return $input; + case 'windows-1251': + case 'windows-1255': + return iconv($encoding, 'UTF-8//TRANSLIT', $input); + default: + return self::toUTF8($input); } - else if ($encoding === '' || $encoding !== 'utf-8') { - return self::toUTF8($input); - } - - return $input; } } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php index 66b3470f8..5948dec35 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php @@ -460,7 +460,7 @@ class Attribute * Check if an attribute name is an external resource * * @access public - * @param string $data Attribute name + * @param string $attribute Attribute name * @return boolean */ public function isResource($attribute) @@ -491,7 +491,7 @@ class Attribute * Detect if an url is blacklisted * * @access public - * @param string $resouce Attribute value (URL) + * @param string $resource Attribute value (URL) * @return boolean */ public function isBlacklistedMedia($resource) @@ -529,7 +529,7 @@ class Attribute * * @access public * @param array $values List of tags: ['video' => ['src', 'cover'], 'img' => ['src']] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setWhitelistedAttributes(array $values) { @@ -542,7 +542,7 @@ class Attribute * * @access public * @param array $values List of scheme: ['http://', 'ftp://'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setSchemeWhitelist(array $values) { @@ -555,7 +555,7 @@ class Attribute * * @access public * @param array $values List of values: ['src', 'href'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setMediaAttributes(array $values) { @@ -568,7 +568,7 @@ class Attribute * * @access public * @param array $values List of tags: ['http://google.com/', '...'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setMediaBlacklist(array $values) { @@ -581,7 +581,7 @@ class Attribute * * @access public * @param array $values List of tags: ['img' => 'src'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setRequiredAttributes(array $values) { @@ -594,7 +594,7 @@ class Attribute * * @access public * @param array $values List of tags: ['a' => 'target="_blank"'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setAttributeOverrides(array $values) { @@ -607,7 +607,7 @@ class Attribute * * @access public * @param array $values List of tags: ['width', 'height'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setIntegerAttributes(array $values) { @@ -620,7 +620,7 @@ class Attribute * * @access public * @param array $values List of tags: ['http://www.youtube.com'] - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setIframeWhitelist(array $values) { @@ -635,7 +635,7 @@ class Attribute * * @access public * @param string $url Proxy URL - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setImageProxyUrl($url) { @@ -648,7 +648,7 @@ class Attribute * * @access public * @param \Closure $callback - * @return \PicoFeed\Filter\Filter + * @return Attribute */ public function setImageProxyCallback($callback) { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php index 82289444b..0eb3f88ea 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php @@ -2,8 +2,6 @@ namespace PicoFeed\Filter; -use PicoFeed\Parser\XmlParser; - /** * Filter class * @@ -19,7 +17,7 @@ class Filter * @access public * @param string $html HTML content * @param string $website Site URL (used to build absolute URL) - * @return PicoFeed\Filter\Html + * @return Html */ public static function html($html, $website) { @@ -88,16 +86,7 @@ class Filter */ public static function stripHeadTags($data) { - $start = strpos($data, ''); - $end = strpos($data, ''); - - if ($start !== false && $end !== false) { - $before = substr($data, 0, $start); - $after = substr($data, $end + 7); - $data = $before.$after; - } - - return $data; + return preg_replace('@]*?>.*?@siu','', $data ); } /** diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php index f7816f1d2..7abd740b1 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php @@ -150,7 +150,7 @@ class Html * * @access public * @param resource $parser XML parser - * @param string $name Tag name + * @param string $tag Tag name * @param array $attributes Tag attributes */ public function startTag($parser, $tag, array $attributes) @@ -178,7 +178,7 @@ class Html * * @access public * @param resource $parser XML parser - * @param string $name Tag name + * @param string $tag Tag name */ public function endTag($parser, $tag) { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Tag.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Tag.php index dbeffe7a4..40f7c6c98 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Tag.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Tag.php @@ -163,7 +163,7 @@ class Tag * * @access public * @param array $values List of tags: ['video' => ['src', 'cover'], 'img' => ['src']] - * @return \PicoFeed\Filter + * @return Tag */ public function setWhitelistedTags(array $values) { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php index 5bb930b22..154ed3cfb 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php @@ -192,7 +192,7 @@ class Atom extends Parser */ public function findItemUrl(SimpleXMLElement $entry, Item $item) { - $item->url = $this->getUrl($entry, 'alternate'); + $item->url = $this->getUrl($entry, 'alternate', true); } /** @@ -245,7 +245,13 @@ class Atom extends Parser */ public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed) { - $item->language = $feed->language; + $language = (string) $entry->attributes('xml', true)->{'lang'}; + + if ($language === '') { + $language = $feed->language; + } + + $item->language = $language; } /** @@ -283,7 +289,7 @@ class Atom extends Parser private function findLink(SimpleXMLElement $xml, $rel) { foreach ($xml->link as $link) { - if (empty($rel) || $rel === (string) $link['rel']) { + if ($rel === (string) $link['rel']) { return $link; } } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Feed.php b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Feed.php index b8edbd6f8..99fc27e8e 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Feed.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Feed.php @@ -96,6 +96,7 @@ class Feed $output .= 'Feed::'.$property.' = '.$this->$property.PHP_EOL; } + $output .= 'Feed::isRTL() = '.($this->isRTL() ? 'true' : 'false').PHP_EOL; $output .= 'Feed::items = '.count($this->items).' items'.PHP_EOL; foreach ($this->items as $item) { @@ -204,4 +205,15 @@ class Feed { return $this->items; } + + /** + * Return true if the feed is "Right to Left" + * + * @access public + * @return bool + */ + public function isRTL() + { + return Parser::isLanguageRTL($this->language); + } } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Item.php b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Item.php index 6b2864ba7..3642cccea 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Item.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Item.php @@ -226,14 +226,6 @@ class Item */ public function isRTL() { - $language = strtolower($this->language); - - foreach ($this->rtl as $prefix) { - if (strpos($language, $prefix) === 0) { - return true; - } - } - - return false; + return Parser::isLanguageRTL($this->language); } } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Parser.php b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Parser.php index de73504e4..44f0c8e38 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Parser.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Parser.php @@ -5,7 +5,6 @@ namespace PicoFeed\Parser; use SimpleXMLElement; use DateTime; use DateTimeZone; - use PicoFeed\Encoding\Encoding; use PicoFeed\Filter\Filter; use PicoFeed\Logging\Logger; @@ -96,9 +95,9 @@ abstract class Parser * Constructor * * @access public - * @param string $content Feed content - * @param string $http_encoding HTTP encoding (headers) - * @param string $base_url Fallback url when the feed provide relative or broken url + * @param string $content Feed content + * @param string $http_encoding HTTP encoding (headers) + * @param string $fallback_url Fallback url when the feed provide relative or broken url */ public function __construct($content, $http_encoding = '', $fallback_url = '') { @@ -268,7 +267,7 @@ abstract class Parser * * @access public * @param string $args Pieces of data to hash - * @return string Id + * @return string */ public function generateId() { @@ -356,6 +355,38 @@ abstract class Parser return 0; } + /** + * Return true if the given language is "Right to Left" + * + * @static + * @access public + * @param string $language Language: fr-FR, en-US + * @return bool + */ + public static function isLanguageRTL($language) + { + $language = strtolower($language); + + $rtl_languages = array( + 'ar', // Arabic (ar-**) + 'fa', // Farsi (fa-**) + 'ur', // Urdu (ur-**) + 'ps', // Pashtu (ps-**) + 'syr', // Syriac (syr-**) + 'dv', // Divehi (dv-**) + 'he', // Hebrew (he-**) + 'yi', // Yiddish (yi-**) + ); + + foreach ($rtl_languages as $prefix) { + if (strpos($language, $prefix) === 0) { + return true; + } + } + + return false; + } + /** * Set Hash algorithm used for id generation * diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/XmlParser.php b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/XmlParser.php index 2b007e199..0afc89d5d 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/XmlParser.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/XmlParser.php @@ -90,7 +90,7 @@ class XmlParser * @static * @access public * @param string $input XML content - * @return mixed + * @return \DOMNode */ public static function getDomDocument($input) { @@ -114,7 +114,7 @@ class XmlParser * @static * @access public * @param string $input XML content - * @return mixed + * @return \DOMDocument */ public static function getHtmlDocument($input) { @@ -226,7 +226,7 @@ class XmlParser * * @static * @access public - * @param SimpleXMLElement $xml XML element + * @param \SimpleXMLElement $xml XML element * @param array $namespaces XML namespaces * @param string $property XML tag name * @param string $attribute XML attribute name diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Favicon.php b/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Favicon.php index f762c56b2..1d9715143 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Favicon.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Favicon.php @@ -3,7 +3,6 @@ namespace PicoFeed\Reader; use DOMXpath; - use PicoFeed\Client\Client; use PicoFeed\Client\ClientException; use PicoFeed\Client\Url; diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Reader.php b/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Reader.php index 5b807e251..fd629f094 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Reader.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Reader.php @@ -3,12 +3,10 @@ namespace PicoFeed\Reader; use DOMXPath; - use PicoFeed\Config\Config; use PicoFeed\Client\Client; use PicoFeed\Client\Url; use PicoFeed\Logging\Logger; -use PicoFeed\Filter\Filter; use PicoFeed\Parser\XmlParser; /** @@ -45,7 +43,7 @@ class Reader * Constructor * * @access public - * @param \PicoFeed\Config $config Config class instance + * @param \PicoFeed\Config\Config $config Config class instance */ public function __construct(Config $config = null) { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Rules/01net.com.php b/vendor/fguillot/picofeed/lib/PicoFeed/Rules/01net.com.php new file mode 100644 index 000000000..85c0e7eab --- /dev/null +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Rules/01net.com.php @@ -0,0 +1,15 @@ + 'http://www.01net.com/editorial/624550/twitter-rachete-madbits-un-specialiste-francais-de-lanalyse-dimages/', + 'body' => array( + '//div[@class="article_ventre_box"]', + ), + 'strip' => array( + '//script', + '//link', + '//*[contains(@class, "article_navigation")]', + '//h1', + '//*[contains(@class, "article_toolbarMain")]', + '//*[contains(@class, "article_imagehaute_box")]' + ) +); \ No newline at end of file diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Export.php b/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Export.php index 4a3b978fa..61aa2b150 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Export.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Export.php @@ -121,7 +121,7 @@ class Export * @access public * @param SimpleXMLElement $parent Parent Element * @param string $category Category - * @param array $feed Feed properties + * @param array $feeds Feed properties */ public function createCategory(SimpleXMLElement $parent, $category, array $feeds) { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Import.php b/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Import.php index 2f8e4006d..cbc1cfbe2 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Import.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Import.php @@ -4,7 +4,6 @@ namespace PicoFeed\Serialization; use SimpleXmlElement; use StdClass; - use PicoFeed\Logging\Logger; use PicoFeed\Parser\XmlParser; diff --git a/vendor/fguillot/picofeed/picofeed b/vendor/fguillot/picofeed/picofeed index 23f474613..b1fa13336 100755 --- a/vendor/fguillot/picofeed/picofeed +++ b/vendor/fguillot/picofeed/picofeed @@ -3,6 +3,7 @@ require_once 'vendor/autoload.php'; +use PicoFeed\Client\Grabber; use PicoFeed\Reader\Reader; use PicoFeed\Logging\Logger; use PicoFeed\PicoFeedException; @@ -75,6 +76,19 @@ function nofilter_item($url, $item_id) } } +function grabber($url) +{ + $grabber = new Grabber($url); + $grabber->download(); + $grabber->parse(); + + print_r(Logger::getMessages()); + echo "============= CONTENT ================\n"; + echo $grabber->getContent().PHP_EOL; + echo "============= FILTERED ================\n"; + echo $grabber->getFilteredContent().PHP_EOL; +} + // Parse command line arguments if ($argc === 4) { switch ($argv[1]) { @@ -94,6 +108,9 @@ else if ($argc === 3) { case 'debug': debug_feed($argv[2]); die; + case 'grabber': + grabber($argv[2]); + die; } } @@ -102,3 +119,4 @@ printf("%s feed \n", $argv[0]); printf("%s debug \n", $argv[0]); printf("%s item \n", $argv[0]); printf("%s nofilter \n", $argv[0]); +printf("%s grabber \n", $argv[0]); diff --git a/vendor/fguillot/picofeed/tests/Client/ClientTest.php b/vendor/fguillot/picofeed/tests/Client/ClientTest.php index 0a480c5c0..3f094d04c 100644 --- a/vendor/fguillot/picofeed/tests/Client/ClientTest.php +++ b/vendor/fguillot/picofeed/tests/Client/ClientTest.php @@ -18,16 +18,33 @@ class ClientTest extends PHPUnit_Framework_TestCase $this->assertNotEmpty($client->getLastModified()); } + public function testCacheBothHaveToMatch() + { + $client = Client::getInstance(); + $client->setUrl('http://php.net/robots.txt'); + $client->execute(); + $etag = $client->getEtag(); + + $client = Client::getInstance(); + $client->setUrl('http://php.net/robots.txt'); + $client->setEtag($etag); + $client->execute(); + + $this->assertTrue($client->isModified()); + } + public function testCacheEtag() { $client = Client::getInstance(); $client->setUrl('http://php.net/robots.txt'); $client->execute(); $etag = $client->getEtag(); + $lastModified = $client->getLastModified(); $client = Client::getInstance(); $client->setUrl('http://php.net/robots.txt'); $client->setEtag($etag); + $client->setLastModified($lastModified); $client->execute(); $this->assertFalse($client->isModified()); diff --git a/vendor/fguillot/picofeed/tests/Client/HttpHeadersTest.php b/vendor/fguillot/picofeed/tests/Client/HttpHeadersTest.php new file mode 100644 index 000000000..f577d00fa --- /dev/null +++ b/vendor/fguillot/picofeed/tests/Client/HttpHeadersTest.php @@ -0,0 +1,19 @@ + 'test')); + $this->assertEquals('test', $headers['content-typE']); + $this->assertTrue(isset($headers['ConTent-Type'])); + + unset($headers['Content-Type']); + $this->assertFalse(isset($headers['ConTent-Type'])); + } + +} \ No newline at end of file diff --git a/vendor/fguillot/picofeed/tests/Parser/AtomParserTest.php b/vendor/fguillot/picofeed/tests/Parser/AtomParserTest.php index 394734ca1..fc807c688 100644 --- a/vendor/fguillot/picofeed/tests/Parser/AtomParserTest.php +++ b/vendor/fguillot/picofeed/tests/Parser/AtomParserTest.php @@ -3,7 +3,6 @@ namespace PicoFeed\Parser; use PHPUnit_Framework_TestCase; - class AtomParserTest extends PHPUnit_Framework_TestCase { /** @@ -65,6 +64,10 @@ class AtomParserTest extends PHPUnit_Framework_TestCase $parser = new Atom(file_get_contents('tests/fixtures/groovehq.xml'), '', 'http://groovehq.com/'); $feed = $parser->execute(); $this->assertEquals('http://groovehq.com/articles.xml', $feed->getFeedUrl()); + + $parser = new Atom(file_get_contents('tests/fixtures/hamakor.xml'), '', 'http://planet.hamakor.org.il'); + $feed = $parser->execute(); + $this->assertEquals('http://planet.hamakor.org.il/atom.xml', $feed->getFeedUrl()); } public function testSiteUrl() @@ -84,6 +87,10 @@ class AtomParserTest extends PHPUnit_Framework_TestCase $parser = new Atom(file_get_contents('tests/fixtures/groovehq.xml')); $feed = $parser->execute(); $this->assertEquals('', $feed->getSiteUrl()); + + $parser = new Atom(file_get_contents('tests/fixtures/hamakor.xml'), '', 'http://planet.hamakor.org.il'); + $feed = $parser->execute(); + $this->assertEquals('http://planet.hamakor.org.il/', $feed->getSiteUrl()); } public function testFeedId() @@ -126,6 +133,10 @@ class AtomParserTest extends PHPUnit_Framework_TestCase $this->assertNotEmpty($feed->items); $this->assertEquals('fr', $feed->getLanguage()); $this->assertEquals('fr', $feed->items[0]->getLanguage()); + + $parser = new Atom(file_get_contents('tests/fixtures/hamakor.xml'), '', 'http://planet.hamakor.org.il'); + $feed = $parser->execute(); + $this->assertEquals('he', $feed->getLanguage()); } public function testItemId() @@ -138,6 +149,23 @@ class AtomParserTest extends PHPUnit_Framework_TestCase public function testItemUrl() { + $parser = new Atom(file_get_contents('tests/fixtures/hamakor.xml'), '', 'http://planet.hamakor.org.il'); + $feed = $parser->execute(); + $this->assertNotEmpty($feed->items); + $this->assertEquals('http://idkn.wordpress.com/2014/12/20/modular-sinatra/', $feed->items[0]->getUrl()); + $this->assertEquals('http://www.guyrutenberg.com/2014/12/20/kindle-paperwhite-unable-to-open-item/', $feed->items[1]->getUrl()); + + $parser = new Atom(file_get_contents('tests/fixtures/atomsample.xml')); + $feed = $parser->execute(); + $this->assertNotEmpty($feed->items); + $this->assertEquals('http://example.org/2003/12/13/atom03', $feed->items[0]->getUrl()); + + $parser = new Atom(file_get_contents('tests/fixtures/bbc_urdu.xml')); + $feed = $parser->execute(); + $this->assertNotEmpty($feed->items); + $this->assertEquals('http://www.bbc.co.uk/urdu/world/2014/03/140316_missing_malaysia_plane_pilot_mb.shtml', $feed->items[0]->getUrl()); + $this->assertEquals('http://www.bbc.co.uk/urdu/pakistan/2014/03/140316_taliban_talks_pro_ibrahim_zs.shtml', $feed->items[1]->getUrl()); + $parser = new Atom(file_get_contents('tests/fixtures/atom.xml')); $feed = $parser->execute(); $this->assertNotEmpty($feed->items); @@ -176,6 +204,14 @@ class AtomParserTest extends PHPUnit_Framework_TestCase $feed = $parser->execute(); $this->assertNotEmpty($feed->items); $this->assertEquals('', $feed->items[1]->getLanguage()); + + $parser = new Atom(file_get_contents('tests/fixtures/hamakor.xml'), '', 'http://planet.hamakor.org.il'); + $feed = $parser->execute(); + $this->assertNotEmpty($feed->items); + $this->assertEquals('he', $feed->items[0]->getLanguage()); + $this->assertTrue($feed->items[0]->isRTL()); + $this->assertEquals('en-US', $feed->items[1]->getLanguage()); + $this->assertFalse($feed->items[1]->isRTL()); } public function testItemAuthor() diff --git a/vendor/fguillot/picofeed/tests/Parser/FeedTest.php b/vendor/fguillot/picofeed/tests/Parser/FeedTest.php new file mode 100644 index 000000000..afa9dd27d --- /dev/null +++ b/vendor/fguillot/picofeed/tests/Parser/FeedTest.php @@ -0,0 +1,24 @@ +language = 'fr_FR'; + $this->assertFalse($item->isRTL()); + + $item->language = 'ur'; + $this->assertTrue($item->isRTL()); + + $item->language = 'syr-**'; + $this->assertTrue($item->isRTL()); + + $item->language = 'ru'; + $this->assertFalse($item->isRTL()); + } +} \ No newline at end of file diff --git a/vendor/fguillot/picofeed/tests/Parser/ParserTest.php b/vendor/fguillot/picofeed/tests/Parser/ParserTest.php index 449e0c9ce..5d786b8ee 100644 --- a/vendor/fguillot/picofeed/tests/Parser/ParserTest.php +++ b/vendor/fguillot/picofeed/tests/Parser/ParserTest.php @@ -55,6 +55,14 @@ class ParserTest extends PHPUnit_Framework_TestCase $this->assertEquals('da23614e02469a0d7c7bd1bdab5c9c474b1904dc', $parser->generateId('a', 'b')); } + public function testLangRTL() + { + $this->assertFalse(Parser::isLanguageRTL('fr-FR')); + $this->assertTrue(Parser::isLanguageRTL('ur')); + $this->assertTrue(Parser::isLanguageRTL('syr-**')); + $this->assertFalse(Parser::isLanguageRTL('ru')); + } + public function testNamespaceValue() { $xml = XmlParser::getSimpleXml(file_get_contents('tests/fixtures/rue89.xml')); diff --git a/vendor/fguillot/picofeed/tests/Reader/ReaderTest.php b/vendor/fguillot/picofeed/tests/Reader/ReaderTest.php index e9d1bb925..ec2d7d6eb 100644 --- a/vendor/fguillot/picofeed/tests/Reader/ReaderTest.php +++ b/vendor/fguillot/picofeed/tests/Reader/ReaderTest.php @@ -145,10 +145,10 @@ class ReaderTest extends PHPUnit_Framework_TestCase $feed = $parser->execute(); - $this->assertEquals('http://www.groovehq.com/blog/feed', $client->getUrl()); + $this->assertEquals('https://www.groovehq.com/blog/feed', $client->getUrl()); $this->assertEquals('http://www.groovehq.com/blog/feed', $feed->getFeedUrl()); $this->assertNotEquals('http://www.groovehq.com/blog/feed', $feed->items[0]->getUrl()); $this->assertTrue(strpos($feed->items[0]->getUrl(), 'http://') === 0); $this->assertTrue(strpos($feed->items[0]->getUrl(), 'feed') === false); } -} \ No newline at end of file +} diff --git a/vendor/fguillot/picofeed/tests/fixtures/hamakor.xml b/vendor/fguillot/picofeed/tests/fixtures/hamakor.xml new file mode 100644 index 000000000..29d49f58b --- /dev/null +++ b/vendor/fguillot/picofeed/tests/fixtures/hamakor.xml @@ -0,0 +1,527 @@ + + + + פלאנט תוכנה חופשית בישראל (Planet FOSS-IL) + + + http://planet.hamakor.org.il/atom.xml + 2014-12-22T02:31:42+00:00 + Planet/2.0 +http://www.planetplanet.org + + + סינטרה מודולרית + + http://idkn.wordpress.com/?p=7223 + 2014-12-20T20:00:02+00:00 + <p>ב2012 ניסיתי ליצור פוסטים בנושא של <a href="http://idkn.wordpress.com/2012/11/19/advanced-usage-in-sinatra-first-part/">כיצד ניתן להגיע למצב הדומה לrails עם סינטרה</a>.<br /> +בשל חוסר סבלנות וזמן, זנחתי את הפוסט, אבל לא את הרעיון לבצע אותו.<br /> +למעשה זה היה רעיון טוב מאוד לזנוח אותו בזמנו, היות ואז הייתי עושה דברים לא נכון, וכיום יש לי יותר ידע וניסיון בנושא, וגם איך לעבוד נכון יותר, וכן גם גרסת הרובי מאפשרת לנו לעבוד קל יותר.</p> +<p>באותו הזמן של הרצון לחזור ולכתוב על הנושא, מצאתי את עצמי זקוק בדחיפות למערכת שתסייע לי לדבג API שאני יוצר בפרוייקט שמתבצע באמצעות REST, אז החלטתי לצרף שני צרכים עם דבר אחד.</p> +<p>הרעיון שלי הוא למעשה שרת אשר משמש לקוח בדיקות עבור REST, כך שאפשר להתקין אותו על שרת כלשהו בארגון וכולם יכולים להשתמש בו, במקום תוכנה מקומית על המחשב.</p> +<p>הקוד שלי די ממוקד לרובי 2.1 (אני מקווה כי גם מעלה, 2.2 נראה שיתמוך בקוד שלי), ופחות מזה, יצעק לכם על מספר דברים, אשר בקלות ניתן לפתור, אך ראו הוזהרתם.</p> +<p><a href="https://github.com/ik5/ruby_rest_wui">התחלתי ליצור את הפרוייקט</a>, והוא עובד עם סינטרה, ומחזיק נכון לכתיבת הפוסט שלוש מחלקות שונות בשביל ביצוע routing.<br /> +בנוסף, יצרתי לעצמי מבנה ספריות המתאימות למה שאני רוצה לבצע, לפי לוגיקה, כך שהלוגיקה השייכת לממשק, <a href="https://github.com/ik5/ruby_rest_wui/tree/master/logic">נמצאת כאן</a>, בעוד ש<a href="https://github.com/ik5/ruby_rest_wui/tree/master/config">ההגדרות בכלל נמצאות כאן</a>.</p> +<p><a href="http://rack.github.io/">אנחנו משתמשים בRack</a> בעצם, היות וכמעט וכל הframeworks עבור בניית מערכות web ברובי משתמשים בו, אנו זקוקים לקובץ קבוע בשם <a href="https://github.com/ik5/ruby_rest_wui/blob/master/config.ru">config.ru</a>.</p> +<p>הקובץ הזה, בעצם אחראי על התחלת השרת, וטעינה של המערכת שלנו, כאשר הוא תומך בטעינה של יותר ממערכת אחת בו זמנית, כולל שני framework או יותר, אך נכון לגרסה הנוכחית, אני משתמש בו רק עבור Sinatra.</p> +<p>אני משתמש גם ב <a href="http://bundler.io/">Bundler</a> לניהול תלויות, אשר מאפשר לנו גם לדאוג לצעוק על דברים שלא נטענו, ובעיקר עושה לנו סדר של גרסאות של תלויות, ובכך שדברים לא יתנגשו אחד בשני.</p> +<p>לאחר טעינת התלויות, אני טוען קובץ בודד בשם app.rb שהוא בעצם מה שמנהל את האפליקציה שלי. אך במקום להשתמש ב <a href="http://ruby-doc.org/core-2.1.5/Kernel.html#method-i-require">require</a> &quot;רגיל&quot;, אני משתמש בפונקציה בשם <a href="http://ruby-doc.org/core-2.1.5/Kernel.html#method-i-require_relative">require_relative</a>, אשר מאפשרת לטעון דברים מהמיקום הנוכחי של הקובץ המנסה לטעון אותה.</p> +<p>כל הקסם של ניהול מספר מחלקות, נעוץ אצלי ב <a href="https://github.com/ik5/ruby_rest_wui/blob/master/logic/app.rb">app.rb</a>.<br /> +אני יצרתי אותו שיהיה מאוד פשוט &#8211; טען לי את המחלקות האחרון והכנס אותן לסביבת העבודה של רובי, על ידי שימוש ב <a href="https://github.com/sinatra/sinatra/blob/v1.4.5/lib/sinatra/base.rb#L1406">use</a>.</p> +<p>למערכת שיצרתי ישנם שני מצבים &#8211; מערכת לדיבוג REST, ומערכת &quot;בדיקות&quot; אשר עליה אפשר לבדוק שדברים עובדים, והיא בעיקר על תקן &quot;echo&quot; כלשהו.</p> +<p>את המערכת של יצירת המסכים, ושליחת ה REST, יצרתי בקובץ <a href="https://github.com/ik5/ruby_rest_wui/blob/master/logic/rest.rb">rest.rb</a>, והכל מאוגד שם.<br /> +יש שם משהו שהולך לעבור למקום אחר בקרוב, וזה מספר מתודות לסיוע בפעולות.</p> +<p>הקובץ לביצוע הבדיקות, קיבל את השם <a href="https://github.com/ik5/ruby_rest_wui/blob/master/logic/testing.rb">tests.rb</a>, והוא מי שמנהל את כל הניתובים בנושא.<br /> +הגרסה הבאה, הולכת לגרום לו להיות גנרי יותר, מצד אחד, וגמיש יותר מצד שני, ובכך הכוח של סינטרה יכנס ממש לפעולה, עם ניתובים ממש דינאמיים וחכמים.</p> +<p>Sinatra תומך במשהו אשר קיבל את השם <a href="http://www.sinatrarb.com/intro.html#Helpers">Helpers</a>, וזה מתודות אשר מסייעות לנו לבצע דברים, בצורה שלא נהיה צריכים לחזור עליה כל פעם, וזה זמין גם ל view שלנו, ובגרסה הבאה שאשחרר (נכון לכתיבת הפוסט), המידע יעבור לקובץ בשם helpers.rb ואיתו עובדים קצת שונה ברובי.</p> +<p>כל מחלקה של סינטרה, מחזיקה חלק של <a href="http://www.sinatrarb.com/intro.html#Configuration">configure</a> משל עצמה, שזה טוב ורע באותו הזמן. זה טוב, כי זה מספק גמישות, אבל זה רע, כי לפעמים יש לנו קצת חזרה על עצמנו.</p> +<p>במקרה הזה, הגדרתי כי במצב של ‎:development משתמשים ב <a href="http://www.sinatrarb.com/contrib/reloader.html">Sinatra::Reloader</a>, אשר מגיע עם <a href="http://www.sinatrarb.com/contrib/reloader.html">Sinatra-Contrib</a> &#8211; תת פרוייקט המספק הרבה כלי עזר לדברים שונים.<br /> +הסיבה לשימוש ב Reloader הוא לא לאתחל את השרת בכל שינוי שעושים למחלקה של סינטרה, כאשר Reloader מגלה כי התוכן של הקובץ השתנה, הוא גורם ל rack לטעון אותו שוב, וככה אנחנו לא זקוקים לטעינה מחודשת של השרת עצמו.</p> +<p>המערכת שכתבתי, משתמשת ב template בשם <a href="http://haml.info/">haml</a>, למעשה פעם ראשונה אשר אני משתמש בה מרצון. תוכלו למצוא את ה <a href="https://github.com/ik5/ruby_rest_wui/blob/master/views/layout.haml">layout.haml</a> שהוא המסגרת הרגילה וכן כרגע קובץ בשם <a href="https://github.com/ik5/ruby_rest_wui/blob/master/views/index.haml">index.haml</a> תחת ספריית <a href="https://github.com/ik5/ruby_rest_wui/tree/master/views">view</a>.<br /> +ועבור העיצוב, אני משתמש ב <a href="http://foundation.zurb.com/">Foundation 5</a>, אשר אני אוהב אותה יותר מאשר bootstrap.<br /> +עבור Javascript יש גם את jQuery וגם את <a href="http://idkn.wordpress.com/2014/11/04/knockout-js/">knockout.js</a>, כאשר אני נעזר גם ב <a href="https://lodash.com/">lodash.js</a> למספר דברים פשוטים, והיא מספקת בעצם גרסה שעברה אופטימיזציה ל underscore.</p> +<p>את הקבצים של Foundation, וכל ה Javascript ניתן למצוא תחת <a href="https://github.com/ik5/ruby_rest_wui/tree/master/public">public</a>.</p> +<p>דבר אחרון שנשאר לספר עליו הוא שאני משתמש במשהו אשר נקרא <a href="http://puma.io/">puma</a>.<br /> +מה זה ?<br /> +puma הוא משהו שלוקח את rack וגורם לו להיות שרת לכל דבר ועניין, אשר ניתן לבצע עליו חיבור לשרתי HTTP שונים, כדוגמץ apache או nginx.<br /> +החיבור נעשה על ידי הגדרת proxy בשרתים.</p> +<p>ההגדרות של puma, נמצאות תחת config, וכפי שניתן לראות את <a href="https://github.com/ik5/ruby_rest_wui/blob/master/config/puma.rb">הקובץ הראשי והחשוב</a>, הוא גם יודע לבנות לעצמו מבנה ספריות במידה והן לא קיימות, דבר שהוספתי לקוד עצמו. הוא כרגע מכוון למצב של development, ולכן יש לשנות קצת הגדרות בשביל שזה יעבור למצב production.</p> +<p>אתם מוזמנים לבצע fork, לשחק עם הקוד וגם להחזיק לי תיקונים ותוספות.</p><br />תויק תחת:<a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/%d7%a4%d7%99%d7%aa%d7%95%d7%97/ruby/">Ruby</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/ui/">ui</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/operating-systems/unix/">unix</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%a7%d7%a9%d7%95%d7%a8%d7%aa/%d7%90%d7%99%d7%a0%d7%98%d7%a8%d7%a0%d7%98/">אינטרנט</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%99%d7%a4%d7%99%d7%9d-%d7%95%d7%98%d7%a8%d7%99%d7%a7%d7%99%d7%9d/">טיפים וטריקים</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/">טכנולוגיה</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/operating-systems/%d7%9c%d7%99%d7%a0%d7%95%d7%a7%d7%a1/">לינוקס</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/%d7%a4%d7%99%d7%aa%d7%95%d7%97/">פיתוח</a>, <a href="http://idkn.wordpress.com/category/%d7%a7%d7%95%d7%93-%d7%a4%d7%aa%d7%95%d7%97/">קוד פתוח</a>, <a href="http://idkn.wordpress.com/category/%d7%a8%d7%a9%d7%aa%d7%95%d7%aa/">רשתות</a>, <a href="http://idkn.wordpress.com/category/%d7%a9%d7%a8%d7%aa%d7%99%d7%9d/">שרתים</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/">תוכנה</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%95%d7%9b%d7%a0%d7%94/%d7%aa%d7%9b%d7%a0%d7%95%d7%aa/">תכנות</a>, <a href="http://idkn.wordpress.com/category/%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94/%d7%aa%d7%a7%d7%a9%d7%95%d7%a8%d7%aa/">תקשורת</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/idkn.wordpress.com/7223/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/idkn.wordpress.com/7223/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=idkn.wordpress.com&#038;blog=3104636&#038;post=7223&#038;subd=idkn&#038;ref=&#038;feed=1" width="1" height="1" /> + + ik_5 + http://idkn.wordpress.com + + + לראות שונה » קוד פתוח + מבט שונה בעיקר על (פיתוח) תוכנה, עסקים והקוד הפתוח + + http://idkn.wordpress.com/feed/atom/ + 2014-12-22T02:31:34+00:00 + + + + + Kindle Paperwhite &#8220;Unable to Open Item&#8221; + + http://www.guyrutenberg.com/?p=69803 + 2014-12-20T14:40:04+00:00 + <p>Recently, I tried transfering some new ebook to my Kindle Paperwhite (first generation), the books were listed properly. However, when I tried to open them I got<br /> +&#8220;Unable to Open Item&#8221; error, suggesting I re-download the books from Amazon. I tried transferring the files again and again, but it didnt&#8217; help. Some of the books were <code>mobi</code> files while others were &#8220;AZW` (which I got from <a href="http://indiebook.co.il/">אינדיבוק</a>) and all of them opened fine on my computer.</p> +<p>Finally, I followed an advice from a <a href="http://kindledfans.livejournal.com/71655.html?thread=388839#t388839">comment in the KindledFans blog</a>, and converted the files to <code>AZW3</code> (the original comment suggested <code>mobi</code> but <code>AZW3</code> works better with Hebrew). After converting, I moved the files to my Kindle and they opened just fine.</p> + + Guy + http://www.guyrutenberg.com + + + Guy Rutenberg + Keeping track of what I do + + http://www.guyrutenberg.com/feed/atom/ + 2014-12-20T18:48:18+00:00 + + + + + Docker – חלק חמישי + + http://ilsh.info/?p=4571 + 2014-12-19T11:00:31+00:00 + <p><a href="http://ilsh.info/archives/4487">בפרק הקודם</a> הדגמתי הרצת שתי פקודות במיכל (באמצעות הפקודה docker run): האחת איפשרה גישה אינטרקטיבית לעבודה עם המיכל ובשניה הרצנו Daemon שסיפק שירות.</p> +<p>כרגע אתמקד בעבודה עם docker client. עבודה עם docker client מאוד פשוטה (באמצעות דגלים וארגומנטים ניתן לשלוט בהוראות ל- Docker Client):</p> +<div class="codesnip-container"> +<div class="sql codesnip">Usage: &nbsp;<span class="br0">&#91;</span>sudo<span class="br0">&#93;</span> docker <span class="br0">&#91;</span>command<span class="br0">&#93;</span> <span class="br0">&#91;</span>flags<span class="br0">&#93;</span> <span class="br0">&#91;</span>arguments<span class="br0">&#93;</span> <span class="sy0">..</span></div> +</div> +<p><span id="more-4571"></span></p> +<p>הרצת הפקודה docker version תספק לנו אינפורמציה נוספת על גרסת docker בצד השרת ובצד הלקוח (בצד אינפורמציה רבה נוספת).</p> +<div class="codesnip-container"> +<div class="sql codesnip">$ sudo docker version<br /> +<span class="br0">&#91;</span>sudo<span class="br0">&#93;</span> password <span class="kw1">FOR</span> ilan: <br /> +Client version: 1<span class="sy0">.</span>3<span class="sy0">.</span>2<br /> +Client API version: <span class="nu0">1