Merge pull request #634 from wallabag/dev

1.6.1
This commit is contained in:
Nicolas Lœuillet 2014-04-11 17:22:04 +02:00
commit 4a74d9857c
16 changed files with 779 additions and 714 deletions

View file

@ -4,7 +4,7 @@ wallabag is a self hostable application allowing you to not miss any content any
More informations on our website: [wallabag.org](http://wallabag.org)
## License
Copyright © 2010-2013 Nicolas Lœuillet <nicolas@loeuillet.org>
Copyright © 2010-2014 Nicolas Lœuillet <nicolas@loeuillet.org>
This work is free. You can redistribute it and/or modify it under the
terms of the Do What The Fuck You Want To Public License, Version 2,
as published by Sam Hocevar. See the COPYING file for more details.

View file

@ -10,177 +10,188 @@
*/
class FeedItem
{
private $elements = array(); //Collection of feed elements
private $version;
private $elements = array(); //Collection of feed elements
private $version;
/**
* Constructor
*
* @param contant (RSS1/RSS2/ATOM) RSS2 is default.
*/
function __construct($version = RSS2)
{
$this->version = $version;
}
/**
* Constructor
*
* @param contant (RSS1/RSS2/ATOM) RSS2 is default.
*/
function __construct($version = RSS2)
{
$this->version = $version;
}
/**
* Set element (overwrites existing elements with $elementName)
*
* @access public
* @param srting The tag name of an element
* @param srting The content of tag
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
* @return void
*/
public function setElement($elementName, $content, $attributes = null)
{
if (isset($this->elements[$elementName])) {
unset($this->elements[$elementName]);
}
$this->addElement($elementName, $content, $attributes);
}
/**
* Set element (overwrites existing elements with $elementName)
*
* @access public
* @param srting The tag name of an element
* @param srting The content of tag
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
* @return void
*/
public function setElement($elementName, $content, $attributes = null)
{
if (isset($this->elements[$elementName])) {
unset($this->elements[$elementName]);
}
$this->addElement($elementName, $content, $attributes);
}
/**
* Add an element to elements array
*
* @access public
* @param srting The tag name of an element
* @param srting The content of tag
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
* @return void
*/
public function addElement($elementName, $content, $attributes = null)
{
$i = 0;
if (isset($this->elements[$elementName])) {
$i = count($this->elements[$elementName]);
} else {
$this->elements[$elementName] = array();
}
$this->elements[$elementName][$i]['name'] = $elementName;
$this->elements[$elementName][$i]['content'] = $content;
$this->elements[$elementName][$i]['attributes'] = $attributes;
}
/**
* Add an element to elements array
*
* @access public
* @param srting The tag name of an element
* @param srting The content of tag
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
* @return void
*/
public function addElement($elementName, $content, $attributes = null)
{
$i = 0;
if (isset($this->elements[$elementName])) {
$i = count($this->elements[$elementName]);
} else {
$this->elements[$elementName] = array();
}
$this->elements[$elementName][$i]['name'] = $elementName;
$this->elements[$elementName][$i]['content'] = $content;
$this->elements[$elementName][$i]['attributes'] = $attributes;
}
/**
* Set multiple feed elements from an array.
* Elements which have attributes cannot be added by this method
*
* @access public
* @param array array of elements in 'tagName' => 'tagContent' format.
* @return void
*/
public function addElementArray($elementArray)
{
if(! is_array($elementArray)) return;
foreach ($elementArray as $elementName => $content)
{
$this->addElement($elementName, $content);
}
}
/**
* Set multiple feed elements from an array.
* Elements which have attributes cannot be added by this method
*
* @access public
* @param array array of elements in 'tagName' => 'tagContent' format.
* @return void
*/
public function addElementArray($elementArray)
{
if(! is_array($elementArray)) return;
foreach ($elementArray as $elementName => $content)
{
$this->addElement($elementName, $content);
}
}
/**
* Return the collection of elements in this feed item
*
* @access public
* @return array
*/
public function getElements()
{
return $this->elements;
}
/**
* Return the collection of elements in this feed item
*
* @access public
* @return array
*/
public function getElements()
{
return $this->elements;
}
// Wrapper functions ------------------------------------------------------
// Wrapper functions ------------------------------------------------------
/**
* Set the 'dscription' element of feed item
*
* @access public
* @param string The content of 'description' element
* @return void
*/
public function setDescription($description)
{
$tag = 'description';
$this->setElement($tag, $description);
}
/**
* Set the 'dscription' element of feed item
*
* @access public
* @param string The content of 'description' element
* @return void
*/
public function setDescription($description)
{
$this->setElement('description', $description);
}
/**
* @desc Set the 'title' element of feed item
* @access public
* @param string The content of 'title' element
* @return void
*/
public function setTitle($title)
{
$this->setElement('title', $title);
}
/**
* @desc Set the 'title' element of feed item
* @access public
* @param string The content of 'title' element
* @return void
*/
public function setTitle($title)
{
$this->setElement('title', $title);
}
/**
* Set the 'date' element of feed item
*
* @access public
* @param string The content of 'date' element
* @return void
*/
public function setDate($date)
{
if(! is_numeric($date))
{
$date = strtotime($date);
}
/**
* Set the 'date' element of feed item
*
* @access public
* @param string The content of 'date' element
* @return void
*/
public function setDate($date)
{
if(! is_numeric($date))
{
$date = strtotime($date);
}
if($this->version == RSS2)
{
$tag = 'pubDate';
$value = date(DATE_RSS, $date);
}
else
{
$tag = 'dc:date';
$value = date("Y-m-d", $date);
}
if($this->version == RSS2)
{
$tag = 'pubDate';
$value = date(DATE_RSS, $date);
}
else
{
$tag = 'dc:date';
$value = date("Y-m-d", $date);
}
$this->setElement($tag, $value);
}
$this->setElement($tag, $value);
}
/**
* Set the 'link' element of feed item
*
* @access public
* @param string The content of 'link' element
* @return void
*/
public function setLink($link)
{
if($this->version == RSS2 || $this->version == RSS1)
{
$this->setElement('link', $link);
$this->setElement('guid', $link);
}
else
{
$this->setElement('link','',array('href'=>$link));
$this->setElement('id', FeedWriter::uuid($link,'urn:uuid:'));
}
/**
* Set the 'link' element of feed item
*
* @access public
* @param string The content of 'link' element
* @return void
*/
public function setLink($link)
{
if($this->version == RSS2 || $this->version == RSS1)
{
$this->setElement('link', $link);
$this->setElement('guid', $link);
}
else
{
$this->setElement('link','',array('href'=>$link));
$this->setElement('id', FeedWriter::uuid($link,'urn:uuid:'));
}
}
}
/**
* Set the 'encloser' element of feed item
* For RSS 2.0 only
*
* @access public
* @param string The url attribute of encloser tag
* @param string The length attribute of encloser tag
* @param string The type attribute of encloser tag
* @return void
*/
public function setEncloser($url, $length, $type)
{
$attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type);
$this->setElement('enclosure','',$attributes);
}
/**
* Set the 'source' element of feed item
*
* @access public
* @param string The content of 'source' element
* @return void
*/
public function setSource($link)
{
$this->setElement('source', $link);
}
/**
* Set the 'encloser' element of feed item
* For RSS 2.0 only
*
* @access public
* @param string The url attribute of encloser tag
* @param string The length attribute of encloser tag
* @param string The type attribute of encloser tag
* @return void
*/
public function setEncloser($url, $length, $type)
{
$attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type);
$this->setElement('enclosure','',$attributes);
}
} // end of class FeedItem
?>

View file

@ -18,424 +18,423 @@ define('JSONP', 3, true);
*/
class FeedWriter
{
private $self = null; // self URL - http://feed2.w3.org/docs/warning/MissingAtomSelfLink.html
private $hubs = array(); // PubSubHubbub hubs
private $channels = array(); // Collection of channel elements
private $items = array(); // Collection of items as object of FeedItem class.
private $data = array(); // Store some other version wise data
private $CDATAEncoding = array(); // The tag names which have to encoded as CDATA
private $xsl = null; // stylesheet to render RSS (used by Chrome)
private $json = null; // JSON object
private $self = null; // self URL - http://feed2.w3.org/docs/warning/MissingAtomSelfLink.html
private $hubs = array(); // PubSubHubbub hubs
private $channels = array(); // Collection of channel elements
private $items = array(); // Collection of items as object of FeedItem class.
private $data = array(); // Store some other version wise data
private $CDATAEncoding = array(); // The tag names which have to encoded as CDATA
private $xsl = null; // stylesheet to render RSS (used by Chrome)
private $json = null; // JSON object
private $version = null;
private $version = null;
/**
* Constructor
*
* @param constant the version constant (RSS2 or JSON).
*/
function __construct($version = RSS2)
{
$this->version = $version;
/**
* Constructor
*
* @param constant the version constant (RSS2 or JSON).
*/
function __construct($version = RSS2)
{
$this->version = $version;
// Setting default value for assential channel elements
$this->channels['title'] = $version . ' Feed';
$this->channels['link'] = 'http://www.ajaxray.com/blog';
// Setting default value for assential channel elements
$this->channels['title'] = $version . ' Feed';
$this->channels['link'] = 'http://www.ajaxray.com/blog';
//Tag names to encode in CDATA
$this->CDATAEncoding = array('description', 'content:encoded', 'content', 'subtitle', 'summary');
}
//Tag names to encode in CDATA
$this->CDATAEncoding = array('description', 'content:encoded', 'content', 'subtitle', 'summary');
}
public function setFormat($format) {
$this->version = $format;
}
public function setFormat($format) {
$this->version = $format;
}
// Start # public functions ---------------------------------------------
// Start # public functions ---------------------------------------------
/**
* Set a channel element
* @access public
* @param srting name of the channel tag
* @param string content of the channel tag
* @return void
*/
public function setChannelElement($elementName, $content)
{
$this->channels[$elementName] = $content ;
}
/**
* Set a channel element
* @access public
* @param srting name of the channel tag
* @param string content of the channel tag
* @return void
*/
public function setChannelElement($elementName, $content)
{
$this->channels[$elementName] = $content ;
}
/**
* Set multiple channel elements from an array. Array elements
* should be 'channelName' => 'channelContent' format.
*
* @access public
* @param array array of channels
* @return void
*/
public function setChannelElementsFromArray($elementArray)
{
if(! is_array($elementArray)) return;
foreach ($elementArray as $elementName => $content)
{
$this->setChannelElement($elementName, $content);
}
}
/**
* Set multiple channel elements from an array. Array elements
* should be 'channelName' => 'channelContent' format.
*
* @access public
* @param array array of channels
* @return void
*/
public function setChannelElementsFromArray($elementArray)
{
if(! is_array($elementArray)) return;
foreach ($elementArray as $elementName => $content)
{
$this->setChannelElement($elementName, $content);
}
}
/**
* Genarate the actual RSS/JSON file
*
* @access public
* @return void
*/
public function genarateFeed()
{
if ($this->version == RSS2) {
// header('Content-type: text/xml; charset=UTF-8');
// this line prevents Chrome 20 from prompting download
// used by Google: https://news.google.com/news/feeds?ned=us&topic=b&output=rss
// header('X-content-type-options: nosniff');
} elseif ($this->version == JSON) {
// header('Content-type: application/json; charset=UTF-8');
$this->json = new stdClass();
} elseif ($this->version == JSONP) {
// header('Content-type: application/javascript; charset=UTF-8');
$this->json = new stdClass();
}
$this->printHead();
$this->printChannels();
$this->printItems();
$this->printTale();
if ($this->version == JSON || $this->version == JSONP) {
echo json_encode($this->json);
}
}
/**
* Genarate the actual RSS/JSON file
*
* @access public
* @return void
*/
public function genarateFeed()
{
if ($this->version == RSS2) {
// header('Content-type: text/xml; charset=UTF-8');
// this line prevents Chrome 20 from prompting download
// used by Google: https://news.google.com/news/feeds?ned=us&topic=b&output=rss
// header('X-content-type-options: nosniff');
} elseif ($this->version == JSON) {
// header('Content-type: application/json; charset=UTF-8');
$this->json = new stdClass();
} elseif ($this->version == JSONP) {
// header('Content-type: application/javascript; charset=UTF-8');
$this->json = new stdClass();
}
$this->printHead();
$this->printChannels();
$this->printItems();
$this->printTale();
if ($this->version == JSON || $this->version == JSONP) {
echo json_encode($this->json);
}
}
/**
* Create a new FeedItem.
*
* @access public
* @return object instance of FeedItem class
*/
public function createNewItem()
{
$Item = new FeedItem($this->version);
return $Item;
}
/**
* Create a new FeedItem.
*
* @access public
* @return object instance of FeedItem class
*/
public function createNewItem()
{
$Item = new FeedItem($this->version);
return $Item;
}
/**
* Add a FeedItem to the main class
*
* @access public
* @param object instance of FeedItem class
* @return void
*/
public function addItem($feedItem)
{
$this->items[] = $feedItem;
}
/**
* Add a FeedItem to the main class
*
* @access public
* @param object instance of FeedItem class
* @return void
*/
public function addItem($feedItem)
{
$this->items[] = $feedItem;
}
// Wrapper functions -------------------------------------------------------------------
// Wrapper functions -------------------------------------------------------------------
/**
* Set the 'title' channel element
*
* @access public
* @param srting value of 'title' channel tag
* @return void
*/
public function setTitle($title)
{
$this->setChannelElement('title', $title);
}
/**
* Set the 'title' channel element
*
* @access public
* @param srting value of 'title' channel tag
* @return void
*/
public function setTitle($title)
{
$this->setChannelElement('title', $title);
}
/**
* Add a hub to the channel element
*
* @access public
* @param string URL
* @return void
*/
public function addHub($hub)
{
$this->hubs[] = $hub;
}
/**
* Add a hub to the channel element
*
* @access public
* @param string URL
* @return void
*/
public function addHub($hub)
{
$this->hubs[] = $hub;
}
/**
* Set XSL URL
*
* @access public
* @param string URL
* @return void
*/
public function setXsl($xsl)
{
$this->xsl = $xsl;
}
/**
* Set XSL URL
*
* @access public
* @param string URL
* @return void
*/
public function setXsl($xsl)
{
$this->xsl = $xsl;
}
/**
* Set self URL
*
* @access public
* @param string URL
* @return void
*/
public function setSelf($self)
{
$this->self = $self;
}
/**
* Set self URL
*
* @access public
* @param string URL
* @return void
*/
public function setSelf($self)
{
$this->self = $self;
}
/**
* Set the 'description' channel element
*
* @access public
* @param srting value of 'description' channel tag
* @return void
*/
public function setDescription($desciption)
{
$tag = ($this->version == ATOM)? 'subtitle' : 'description';
$this->setChannelElement($tag, $desciption);
}
/**
* Set the 'description' channel element
*
* @access public
* @param srting value of 'description' channel tag
* @return void
*/
public function setDescription($description)
{
$this->setChannelElement('description', $description);
}
/**
* Set the 'link' channel element
*
* @access public
* @param srting value of 'link' channel tag
* @return void
*/
public function setLink($link)
{
$this->setChannelElement('link', $link);
}
/**
* Set the 'link' channel element
*
* @access public
* @param srting value of 'link' channel tag
* @return void
*/
public function setLink($link)
{
$this->setChannelElement('link', $link);
}
/**
* Set the 'image' channel element
*
* @access public
* @param srting title of image
* @param srting link url of the imahe
* @param srting path url of the image
* @return void
*/
public function setImage($title, $link, $url)
{
$this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url));
}
/**
* Set the 'image' channel element
*
* @access public
* @param srting title of image
* @param srting link url of the imahe
* @param srting path url of the image
* @return void
*/
public function setImage($title, $link, $url)
{
$this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url));
}
// End # public functions ----------------------------------------------
// End # public functions ----------------------------------------------
// Start # private functions ----------------------------------------------
// Start # private functions ----------------------------------------------
/**
* Prints the xml and rss namespace
*
* @access private
* @return void
*/
private function printHead()
{
if ($this->version == RSS2)
{
$out = '<?xml version="1.0" encoding="utf-8"?>'."\n";
if ($this->xsl) $out .= '<?xml-stylesheet type="text/xsl" href="'.htmlspecialchars($this->xsl).'"?>' . PHP_EOL;
$out .= '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">' . PHP_EOL;
echo $out;
}
elseif ($this->version == JSON || $this->version == JSONP)
{
$this->json->rss = array('@attributes' => array('version' => '2.0'));
}
}
/**
* Prints the xml and rss namespace
*
* @access private
* @return void
*/
private function printHead()
{
if ($this->version == RSS2)
{
$out = '<?xml version="1.0" encoding="utf-8"?>'."\n";
if ($this->xsl) $out .= '<?xml-stylesheet type="text/xsl" href="'.htmlspecialchars($this->xsl).'"?>' . PHP_EOL;
$out .= '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">' . PHP_EOL;
echo $out;
}
elseif ($this->version == JSON || $this->version == JSONP)
{
$this->json->rss = array('@attributes' => array('version' => '2.0'));
}
}
/**
* Closes the open tags at the end of file
*
* @access private
* @return void
*/
private function printTale()
{
if ($this->version == RSS2)
{
echo '</channel>',PHP_EOL,'</rss>';
}
// do nothing for JSON
}
/**
* Closes the open tags at the end of file
*
* @access private
* @return void
*/
private function printTale()
{
if ($this->version == RSS2)
{
echo '</channel>',PHP_EOL,'</rss>';
}
// do nothing for JSON
}
/**
* Creates a single node as xml format
*
* @access private
* @param string name of the tag
* @param mixed tag value as string or array of nested tags in 'tagName' => 'tagValue' format
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
* @return string formatted xml tag
*/
private function makeNode($tagName, $tagContent, $attributes = null)
{
if ($this->version == RSS2)
{
$nodeText = '';
$attrText = '';
if (is_array($attributes))
{
foreach ($attributes as $key => $value)
{
$attrText .= " $key=\"$value\" ";
}
}
$nodeText .= "<{$tagName}{$attrText}>";
if (is_array($tagContent))
{
foreach ($tagContent as $key => $value)
{
$nodeText .= $this->makeNode($key, $value);
}
}
else
{
//$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent);
$nodeText .= htmlspecialchars($tagContent);
}
//$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>";
$nodeText .= "</$tagName>";
return $nodeText . PHP_EOL;
}
elseif ($this->version == JSON || $this->version == JSONP)
{
$tagName = (string)$tagName;
$tagName = strtr($tagName, ':', '_');
$node = null;
if (!$tagContent && is_array($attributes) && count($attributes))
{
$node = array('@attributes' => $this->json_keys($attributes));
} else {
if (is_array($tagContent)) {
$node = $this->json_keys($tagContent);
} else {
$node = $tagContent;
}
}
return $node;
}
return ''; // should not get here
}
/**
* Creates a single node as xml format
*
* @access private
* @param string name of the tag
* @param mixed tag value as string or array of nested tags in 'tagName' => 'tagValue' format
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
* @return string formatted xml tag
*/
private function makeNode($tagName, $tagContent, $attributes = null)
{
if ($this->version == RSS2)
{
$nodeText = '';
$attrText = '';
if (is_array($attributes))
{
foreach ($attributes as $key => $value)
{
$attrText .= " $key=\"$value\" ";
}
}
$nodeText .= "<{$tagName}{$attrText}>";
if (is_array($tagContent))
{
foreach ($tagContent as $key => $value)
{
$nodeText .= $this->makeNode($key, $value);
}
}
else
{
//$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent);
$nodeText .= htmlspecialchars($tagContent);
}
//$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>";
$nodeText .= "</$tagName>";
return $nodeText . PHP_EOL;
}
elseif ($this->version == JSON || $this->version == JSONP)
{
$tagName = (string)$tagName;
$tagName = strtr($tagName, ':', '_');
$node = null;
if (!$tagContent && is_array($attributes) && count($attributes))
{
$node = array('@attributes' => $this->json_keys($attributes));
} else {
if (is_array($tagContent)) {
$node = $this->json_keys($tagContent);
} else {
$node = $tagContent;
}
}
return $node;
}
return ''; // should not get here
}
private function json_keys(array $array) {
$new = array();
foreach ($array as $key => $val) {
if (is_string($key)) $key = strtr($key, ':', '_');
if (is_array($val)) {
$new[$key] = $this->json_keys($val);
} else {
$new[$key] = $val;
}
}
return $new;
}
private function json_keys(array $array) {
$new = array();
foreach ($array as $key => $val) {
if (is_string($key)) $key = strtr($key, ':', '_');
if (is_array($val)) {
$new[$key] = $this->json_keys($val);
} else {
$new[$key] = $val;
}
}
return $new;
}
/**
* @desc Print channels
* @access private
* @return void
*/
private function printChannels()
{
//Start channel tag
if ($this->version == RSS2) {
echo '<channel>' . PHP_EOL;
// add hubs
foreach ($this->hubs as $hub) {
//echo $this->makeNode('link', '', array('rel'=>'hub', 'href'=>$hub, 'xmlns'=>'http://www.w3.org/2005/Atom'));
echo '<link rel="hub" href="'.htmlspecialchars($hub).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
}
// add self
if (isset($this->self)) {
//echo $this->makeNode('link', '', array('rel'=>'self', 'href'=>$this->self, 'xmlns'=>'http://www.w3.org/2005/Atom'));
echo '<link rel="self" href="'.htmlspecialchars($this->self).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
}
//Print Items of channel
foreach ($this->channels as $key => $value)
{
echo $this->makeNode($key, $value);
}
} elseif ($this->version == JSON || $this->version == JSONP) {
$this->json->rss['channel'] = (object)$this->json_keys($this->channels);
}
}
/**
* @desc Print channels
* @access private
* @return void
*/
private function printChannels()
{
//Start channel tag
if ($this->version == RSS2) {
echo '<channel>' . PHP_EOL;
// add hubs
foreach ($this->hubs as $hub) {
//echo $this->makeNode('link', '', array('rel'=>'hub', 'href'=>$hub, 'xmlns'=>'http://www.w3.org/2005/Atom'));
echo '<link rel="hub" href="'.htmlspecialchars($hub).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
}
// add self
if (isset($this->self)) {
//echo $this->makeNode('link', '', array('rel'=>'self', 'href'=>$this->self, 'xmlns'=>'http://www.w3.org/2005/Atom'));
echo '<link rel="self" href="'.htmlspecialchars($this->self).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
}
//Print Items of channel
foreach ($this->channels as $key => $value)
{
echo $this->makeNode($key, $value);
}
} elseif ($this->version == JSON || $this->version == JSONP) {
$this->json->rss['channel'] = (object)$this->json_keys($this->channels);
}
}
/**
* Prints formatted feed items
*
* @access private
* @return void
*/
private function printItems()
{
foreach ($this->items as $item) {
$itemElements = $item->getElements();
/**
* Prints formatted feed items
*
* @access private
* @return void
*/
private function printItems()
{
foreach ($this->items as $item) {
$itemElements = $item->getElements();
echo $this->startItem();
echo $this->startItem();
if ($this->version == JSON || $this->version == JSONP) {
$json_item = array();
}
if ($this->version == JSON || $this->version == JSONP) {
$json_item = array();
}
foreach ($itemElements as $thisElement) {
foreach ($thisElement as $instance) {
if ($this->version == RSS2) {
echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
} elseif ($this->version == JSON || $this->version == JSONP) {
$_json_node = $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
if (count($thisElement) > 1) {
$json_item[strtr($instance['name'], ':', '_')][] = $_json_node;
} else {
$json_item[strtr($instance['name'], ':', '_')] = $_json_node;
}
}
}
}
echo $this->endItem();
if ($this->version == JSON || $this->version == JSONP) {
if (count($this->items) > 1) {
$this->json->rss['channel']->item[] = $json_item;
} else {
$this->json->rss['channel']->item = $json_item;
}
}
}
}
foreach ($itemElements as $thisElement) {
foreach ($thisElement as $instance) {
if ($this->version == RSS2) {
echo $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
} elseif ($this->version == JSON || $this->version == JSONP) {
$_json_node = $this->makeNode($instance['name'], $instance['content'], $instance['attributes']);
if (count($thisElement) > 1) {
$json_item[strtr($instance['name'], ':', '_')][] = $_json_node;
} else {
$json_item[strtr($instance['name'], ':', '_')] = $_json_node;
}
}
}
}
echo $this->endItem();
if ($this->version == JSON || $this->version == JSONP) {
if (count($this->items) > 1) {
$this->json->rss['channel']->item[] = $json_item;
} else {
$this->json->rss['channel']->item = $json_item;
}
}
}
}
/**
* Make the starting tag of channels
*
* @access private
* @return void
*/
private function startItem()
{
if ($this->version == RSS2)
{
echo '<item>' . PHP_EOL;
}
// nothing for JSON
}
/**
* Make the starting tag of channels
*
* @access private
* @return void
*/
private function startItem()
{
if ($this->version == RSS2)
{
echo '<item>' . PHP_EOL;
}
// nothing for JSON
}
/**
* Closes feed item tag
*
* @access private
* @return void
*/
private function endItem()
{
if ($this->version == RSS2)
{
echo '</item>' . PHP_EOL;
}
// nothing for JSON
}
/**
* Closes feed item tag
*
* @access private
* @return void
*/
private function endItem()
{
if ($this->version == RSS2)
{
echo '</item>' . PHP_EOL;
}
// nothing for JSON
}
// End # private functions ----------------------------------------------
// End # private functions ----------------------------------------------
}

View file

@ -77,7 +77,7 @@ class Database {
}
else {
$sql = '
CREATE TABLE tags (
CREATE TABLE IF NOT EXISTS tags (
id bigserial primary key,
value varchar(255) NOT NULL
);
@ -110,7 +110,7 @@ class Database {
}
else {
$sql = '
CREATE TABLE tags_entries (
CREATE TABLE IF NOT EXISTS tags_entries (
id bigserial primary key,
entry_id integer NOT NULL,
tag_id integer NOT NULL
@ -245,7 +245,7 @@ class Database {
$sql_limit = "LIMIT ".$limit." OFFSET 0";
}
$sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND user_id=? ORDER BY id " . $sql_limit;
$sql = "SELECT * FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=? ORDER BY id " . $sql_limit;
$query = $this->executeQuery($sql, array($user_id));
$entries = $query->fetchAll();
@ -253,7 +253,7 @@ class Database {
}
public function retrieveUnfetchedEntriesCount($user_id) {
$sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND user_id=?";
$sql = "SELECT count(*) FROM entries WHERE (content = '' OR content IS NULL) AND title LIKE 'Untitled - Import%' AND user_id=?";
$query = $this->executeQuery($sql, array($user_id));
list($count) = $query->fetch();
@ -374,7 +374,7 @@ class Database {
$id = null;
}
else {
$id = intval($this->getLastId( (STORAGE == 'postgres') ? 'users_id_seq' : '' ));
$id = intval($this->getLastId( (STORAGE == 'postgres') ? 'entries_id_seq' : '') );
}
return $id;
}

View file

@ -373,9 +373,7 @@ class Poche
$body = $content['rss']['channel']['item']['description'];
// clean content from prevent xss attack
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', CACHE);
$purifier = new HTMLPurifier($config);
$purifier = $this->getPurifier();
$title = $purifier->purify($title);
$body = $purifier->purify($body);
@ -828,10 +826,12 @@ class Poche
define('IMPORT_LIMIT', 5);
}
if (!defined('IMPORT_DELAY')) {
define('IMPORT_DELAY', 5);
define('IMPORT_DELAY', 5);
}
if ( isset($_FILES['file']) ) {
Tools::logm('Import stated: parsing file');
// assume, that file is in json format
$str_data = file_get_contents($_FILES['file']['tmp_name']);
$data = json_decode($str_data, true);
@ -844,18 +844,18 @@ class Poche
$read = 0;
foreach (array('ol','ul') as $list) {
foreach ($html->find($list) as $ul) {
foreach ($ul->find('li') as $li) {
$tmpEntry = array();
$a = $li->find('a');
$tmpEntry['url'] = $a[0]->href;
$tmpEntry['tags'] = $a[0]->tags;
$tmpEntry['is_read'] = $read;
if ($tmpEntry['url']) {
$data[] = $tmpEntry;
}
}
# the second <ol/ul> is for read links
$read = ((sizeof($data) && $read)?0:1);
foreach ($ul->find('li') as $li) {
$tmpEntry = array();
$a = $li->find('a');
$tmpEntry['url'] = $a[0]->href;
$tmpEntry['tags'] = $a[0]->tags;
$tmpEntry['is_read'] = $read;
if ($tmpEntry['url']) {
$data[] = $tmpEntry;
}
}
# the second <ol/ul> is for read links
$read = ((sizeof($data) && $read)?0:1);
}
}
}
@ -866,16 +866,16 @@ class Poche
$data[] = $record;
foreach ($record as $record2) {
if (is_array($record2)) {
$data[] = $record2;
$data[] = $record2;
}
}
}
}
$i = 0; //counter for articles inserted
$urlsInserted = array(); //urls of articles inserted
foreach ($data as $record) {
$url = trim( isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : '') );
if ( $url ) {
if ( $url and !in_array($url, $urlsInserted) ) {
$title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>');
$body = (isset($record['content']) ? $record['content'] : '');
$isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive'])?intval($record['archive']):0));
@ -883,19 +883,21 @@ class Poche
//insert new record
$id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead);
if ( $id ) {
//increment no of records inserted
$i++;
$urlsInserted[] = $url; //add
if ( isset($record['tags']) && trim($record['tags']) ) {
//@TODO: set tags
//@TODO: set tags
}
}
}
}
$i = sizeof($urlsInserted);
if ( $i > 0 ) {
$this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".'));
}
Tools::logm('Import of articles finished: '.$i.' articles added (w/o content if not provided).');
}
//file parsing finished here
@ -906,30 +908,32 @@ class Poche
if ( $recordsDownloadRequired == 0 ) {
//nothing to download
$this->messages->add('s', _('Import finished.'));
Tools::logm('Import finished completely');
Tools::redirect();
}
else {
//if just inserted - don't download anything, download will start in next reload
if ( !isset($_FILES['file']) ) {
//download next batch
Tools::logm('Fetching next batch of articles...');
$items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT);
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', CACHE);
$purifier = new HTMLPurifier($config);
$purifier = $this->getPurifier();
foreach ($items as $item) {
$url = new Url(base64_encode($item['url']));
$content = Tools::getPageContent($url);
$url = new Url(base64_encode($item['url']));
Tools::logm('Fetching article '.$item['id']);
$content = Tools::getPageContent($url);
$title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled'));
$body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined'));
$title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled'));
$body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined'));
//clean content to prevent xss attack
$title = $purifier->purify($title);
$body = $purifier->purify($body);
//clean content to prevent xss attack
$title = $purifier->purify($title);
$body = $purifier->purify($body);
$this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId());
$this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId());
Tools::logm('Article '.$item['id'].' updated.');
}
}
@ -942,16 +946,15 @@ class Poche
* export poche entries in json
* @return json all poche entries
*/
public function export()
{
$filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json";
header('Content-Disposition: attachment; filename='.$filename);
public function export() {
$filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json";
header('Content-Disposition: attachment; filename='.$filename);
$entries = $this->store->retrieveAll($this->user->getId());
echo $this->tpl->render('export.twig', array(
'export' => Tools::renderJson($entries),
));
Tools::logm('export view');
$entries = $this->store->retrieveAll($this->user->getId());
echo $this->tpl->render('export.twig', array(
'export' => Tools::renderJson($entries),
));
Tools::logm('export view');
}
/**
@ -959,43 +962,42 @@ class Poche
* @param string $which 'prod' or 'dev'
* @return string latest $which version
*/
private function getPocheVersion($which = 'prod')
{
$cache_file = CACHE . '/' . $which;
$check_time = time();
private function getPocheVersion($which = 'prod') {
$cache_file = CACHE . '/' . $which;
$check_time = time();
# checks if the cached version file exists
if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) {
$version = file_get_contents($cache_file);
$check_time = filemtime($cache_file);
} else {
$version = file_get_contents('http://static.wallabag.org/versions/' . $which);
file_put_contents($cache_file, $version, LOCK_EX);
}
return array($version, $check_time);
# checks if the cached version file exists
if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) {
$version = file_get_contents($cache_file);
$check_time = filemtime($cache_file);
} else {
$version = file_get_contents('http://static.wallabag.org/versions/' . $which);
file_put_contents($cache_file, $version, LOCK_EX);
}
return array($version, $check_time);
}
public function generateToken()
{
if (ini_get('open_basedir') === '') {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
echo 'This is a server using Windows!';
// alternative to /dev/urandom for Windows
$token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
} else {
$token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
}
}
else {
$token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
if (ini_get('open_basedir') === '') {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
echo 'This is a server using Windows!';
// alternative to /dev/urandom for Windows
$token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
} else {
$token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
}
}
else {
$token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
}
$token = str_replace('+', '', $token);
$this->store->updateUserConfig($this->user->getId(), 'token', $token);
$currentConfig = $_SESSION['poche_user']->config;
$currentConfig['token'] = $token;
$_SESSION['poche_user']->setConfig($currentConfig);
Tools::redirect();
$token = str_replace('+', '', $token);
$this->store->updateUserConfig($this->user->getId(), 'token', $token);
$currentConfig = $_SESSION['poche_user']->config;
$currentConfig['token'] = $token;
$_SESSION['poche_user']->setConfig($currentConfig);
Tools::redirect();
}
public function generateFeeds($token, $user_id, $tag_id, $type = 'home')
@ -1031,6 +1033,7 @@ class Poche
foreach ($entries as $entry) {
$newItem = $feed->createNewItem();
$newItem->setTitle($entry['title']);
$newItem->setSource(Tools::getPocheUrl() . '?view=view&amp;id=' . $entry['id']);
$newItem->setLink($entry['url']);
$newItem->setDate(time());
$newItem->setDescription($entry['content']);
@ -1057,4 +1060,16 @@ class Poche
$this->messages->add('s', _('Cache deleted.'));
Tools::redirect();
}
/**
* return new purifier object with actual config
*/
protected function getPurifier() {
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', CACHE);
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo$purifier = new HTMLPurifier($config);
return new HTMLPurifier($config);
}
}

View file

@ -59,8 +59,10 @@ class Tools
return $scriptname;
}
$host = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']));
return 'http' . ($https ? 's' : '') . '://'
. $_SERVER["HTTP_HOST"] . $serverport . $scriptname;
. $host . $serverport . $scriptname;
}
public static function redirect($url = '')

View file

@ -8,7 +8,7 @@
* @license http://www.wtfpl.net/ see COPYING file
*/
define ('POCHE', '1.6.0');
define ('POCHE', '1.6.1');
require 'check_setup.php';
require_once 'inc/poche/global.inc.php';

BIN
locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo Normal file → Executable file

Binary file not shown.

116
locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po Normal file → Executable file
View file

@ -1,26 +1,25 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Project-Id-Version: wallabag 1.6.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-02-25 18:33+0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Maryana <mariroz@mr.lviv.ua>\n"
"Last-Translator: Gilles WITTEZAELE <gilles.wittezaele@laposte.net>\n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-SourceCharset: utf-8\n"
"X-Generator: Poedit 1.5.7\n"
"X-Poedit-SearchPath-0: /home/mariroz/_DEV/web/wallabag/wallabag-master-testing\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Generator: Poedit 1.6.4\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"Language: fr_FR\n"
msgid "wallabag, a read it later open source system"
msgstr "wallabag, un système open source de lecture différé"
msgid "login failed: user doesn't exist"
msgstr "identification échouée : l'utilisateur n'existe pas"
msgstr "échec de l'identification : cet utilisateur n'existe pas"
msgid "return home"
msgstr "retour à l'accueil"
@ -32,13 +31,13 @@ msgid "Saving articles"
msgstr "Sauvegarde des articles"
msgid "There are several ways to save an article:"
msgstr "Il y a plusieurs façons de sauver un article :"
msgstr "Il y a plusieurs façons d'enregistrer un article :"
msgid "read the documentation"
msgstr "lisez la documentation"
msgid "download the extension"
msgstr "télécharger l'extension"
msgstr "téléchargez l'extension"
msgid "via F-Droid"
msgstr "via F-Droid"
@ -50,7 +49,7 @@ msgid "via Google Play"
msgstr "via Google PlayStore"
msgid "download the application"
msgstr "télécharger l'application"
msgstr "téléchargez l'application"
msgid "By filling this field"
msgstr "En remplissant ce champ"
@ -85,8 +84,13 @@ msgstr "Une version de développement plus récente est disponible."
msgid "Feeds"
msgstr "Flux"
msgid "Your feed token is currently empty and must first be generated to enable feeds. Click <a href='?feed&amp;action=generate'>here to generate it</a>."
msgstr "Votre jeton de flux est actuellement vide doit d'abord être généré pour activer les flux. Cliquez <a href='?feed&amp;action=generate'>ici</a> pour le générer."
msgid ""
"Your feed token is currently empty and must first be generated to enable "
"feeds. Click <a href='?feed&amp;action=generate'>here to generate it</a>."
msgstr ""
"Votre jeton de flux est actuellement vide et doit d'abord être généré pour "
"activer les flux. Cliquez <a href='?feed&amp;action=generate'>ici</a> pour "
"le générer."
msgid "Unread feed"
msgstr "Flux des non lus"
@ -103,8 +107,12 @@ msgstr "Votre jeton :"
msgid "Your user id:"
msgstr "Votre ID utilisateur :"
msgid "You can regenerate your token: <a href='?feed&amp;action=generate'>generate!</a>."
msgstr "Vous pouvez regénérer votre jeton : <a href='?feed&amp;action=generate'>génération !</a>."
msgid ""
"You can regenerate your token: <a href='?feed&amp;action=generate'>generate!"
"</a>."
msgstr ""
"Vous pouvez regénérer votre jeton : <a href='?feed&amp;"
"action=generate'>génération !</a>."
msgid "Change your theme"
msgstr "Changer votre thème"
@ -136,8 +144,11 @@ msgstr "Répétez votre nouveau mot de passe :"
msgid "Import"
msgstr "Importer"
msgid "Please execute the import script locally as it can take a very long time."
msgstr "Merci d'exécuter l'import en local car cela peut prendre du temps."
msgid ""
"Please execute the import script locally as it can take a very long time."
msgstr ""
"Merci d'exécuter le script d'importation en local car cela peut prendre du "
"temps."
msgid "More info in the official documentation:"
msgstr "Plus d'infos dans la documentation officielle :"
@ -150,13 +161,13 @@ msgid "(you must have a %s file on your server)"
msgstr "(le fichier %s doit être présent sur le serveur)"
msgid "Import from Readability"
msgstr "Import depuis Readability"
msgstr "Importer depuis Readability"
msgid "Import from Instapaper"
msgstr "Import depuis Instapaper"
msgstr "Importer depuis Instapaper"
msgid "Import from wallabag"
msgstr "Import depuis wallabag"
msgstr "Importer depuis wallabag"
msgid "Export your wallabag data"
msgstr "Exporter vos données de wallabag"
@ -185,8 +196,12 @@ msgstr "retourner à l'article"
msgid "plop"
msgstr "plop"
msgid "You can <a href='wallabag_compatibility_test.php'>check your configuration here</a>."
msgstr "Vous pouvez vérifier votre configuration <a href='wallabag_compatibility_test.php'>ici</a>."
msgid ""
"You can <a href='wallabag_compatibility_test.php'>check your configuration "
"here</a>."
msgstr ""
"Vous pouvez vérifier votre configuration <a "
"href='wallabag_compatibility_test.php'>ici</a>."
msgid "favoris"
msgstr "favoris"
@ -248,8 +263,14 @@ msgstr "installation"
msgid "install your wallabag"
msgstr "installez votre wallabag"
msgid "wallabag is still not installed. Please fill the below form to install it. Don't hesitate to <a href='http://doc.wallabag.org/'>read the documentation on wallabag website</a>."
msgstr "wallabag n'est pas encore installé. Merci de remplir le formulaire suivant pour l'installer. N'hésitez pas à <a href='http://doc.wallabag.org'>lire la documentation sur le site de wallabag</a>."
msgid ""
"wallabag is still not installed. Please fill the below form to install it. "
"Don't hesitate to <a href='http://doc.wallabag.org/'>read the documentation "
"on wallabag website</a>."
msgstr ""
"wallabag n'est pas encore installé. Merci de remplir le formulaire suivant "
"pour l'installer. N'hésitez pas à <a href='http://doc.wallabag.org'>lire la "
"documentation sur le site de wallabag</a>."
msgid "Login"
msgstr "Nom d'utilisateur"
@ -267,7 +288,8 @@ msgid "Login to wallabag"
msgstr "Se connecter à wallabag"
msgid "you are in demo mode, some features may be disabled."
msgstr "vous êtes en mode démo, certaines fonctionnalités peuvent être désactivées."
msgstr ""
"vous êtes en mode démo, certaines fonctionnalités peuvent être désactivées."
msgid "Username"
msgstr "Nom d'utilisateur"
@ -318,10 +340,10 @@ msgid "tags:"
msgstr "tags :"
msgid "Edit tags"
msgstr "Editer les tags"
msgstr "Modifier les tags"
msgid "save link!"
msgstr "sauver le lien !"
msgstr "enregistrer le lien !"
msgid "powered by"
msgstr "propulsé par"
@ -360,7 +382,7 @@ msgid "tweet"
msgstr "tweet"
msgid "email"
msgstr "ee-mail"
msgstr "e-mail"
msgid "this article appears wrong?"
msgstr "cet article s'affiche mal ?"
@ -369,7 +391,7 @@ msgid "No link available here!"
msgstr "Aucun lien n'est disponible ici !"
msgid "Poching a link"
msgstr "Sauver un lien"
msgstr "Enregistrer un lien"
msgid "by filling this field"
msgstr "en remplissant ce champ"
@ -396,19 +418,21 @@ msgid "a more recent development version is available."
msgstr "une version de développement plus récente est disponible."
msgid "Please execute the import script locally, it can take a very long time."
msgstr "Merci d'exécuter l'import en local car cela peut prendre du temps."
msgstr ""
"Merci d'exécuter le script d'importation en local car cela peut prendre du "
"temps."
msgid "More infos in the official doc:"
msgstr "Plus d'infos dans la documentation officielle :"
msgid "import from Pocket"
msgstr "import depuis Pocket"
msgstr "importation depuis Pocket"
msgid "import from Readability"
msgstr "import depuis Readability"
msgstr "importation depuis Readability"
msgid "import from Instapaper"
msgstr "import depuis Instapaper"
msgstr "importation depuis Instapaper"
msgid "estimated reading time :"
msgstr "temps de lecture estimé :"
@ -449,8 +473,12 @@ msgstr "en mode démo, vous ne pouvez pas mettre à jour le mot de passe"
msgid "your password has been updated"
msgstr "votre mot de passe a été mis à jour"
msgid "the two fields have to be filled & the password must be the same in the two fields"
msgstr "les deux champs doivent être remplis & le mot de passe doit être le même dans les deux"
msgid ""
"the two fields have to be filled & the password must be the same in the two "
"fields"
msgstr ""
"les deux champs doivent être remplis & le mot de passe doit être le même "
"dans les deux"
msgid "still using the \""
msgstr "utilise encore \""
@ -459,7 +487,7 @@ msgid "that theme does not seem to be installed"
msgstr "ce thème ne semble pas installé"
msgid "you have changed your theme preferences"
msgstr "vous avez changez vos préférences de thème"
msgstr "vous avez changé vos préférences de thème"
msgid "that language does not seem to be installed"
msgstr "cette langue ne semble pas être installée"
@ -468,28 +496,28 @@ msgid "you have changed your language preferences"
msgstr "vous avez changé vos préférences de langue"
msgid "login failed: you have to fill all fields"
msgstr "identification échouée : vous devez remplir tous les champs"
msgstr "échec de l'identification : vous devez remplir tous les champs"
msgid "welcome to your wallabag"
msgstr "bienvenue dans votre wallabag"
msgid "login failed: bad login or password"
msgstr "identification échouée : mauvais identifiant ou mot de passe"
msgstr "échec de l'identification : mauvais identifiant ou mot de passe"
msgid "import from instapaper completed"
msgstr "Import depuis Instapaper complété"
msgstr "Importation depuis Instapaper complété"
msgid "import from pocket completed"
msgstr "Import depuis Pocket complété"
msgstr "Importation depuis Pocket complété"
msgid "import from Readability completed. "
msgstr "Import depuis Readability complété"
msgstr "Importation depuis Readability complété"
msgid "import from Poche completed. "
msgstr "Import depuis Pocket complété"
msgstr "Importation depuis Pocket complété"
msgid "Unknown import provider."
msgstr "Fournisseur d'import inconnu."
msgstr "Format d'importation inconnu."
msgid "Incomplete inc/poche/define.inc.php file, please define \""
msgstr "Fichier inc/poche/define.inc.php incomplet, merci de définir \""
@ -498,7 +526,7 @@ msgid "Could not find required \""
msgstr "Ne peut pas trouver \""
msgid "Uh, there is a problem while generating feeds."
msgstr "Ih, il y a un problème lors de la génération des flux."
msgstr "Hum, il y a un problème lors de la génération des flux."
msgid "Cache deleted."
msgstr "Cache effacé."

View file

@ -12,4 +12,5 @@
<script src="{{ poche_url }}themes/{{theme}}/js/jquery.cookie.js"></script>
<script src="{{ poche_url }}themes/{{theme}}/js/init.js"></script>
<script src="{{ poche_url }}themes/default/js/saveLink.js"></script>
<script src="{{ poche_url }}themes/default/js/popupForm.js"></script>
<script src="{{ poche_url }}themes/{{theme}}/js/closeMessage.js"></script>

View file

@ -1,21 +1,7 @@
<div id="search-form" class="messages info">
<form method="get" action="index.php">
<input type="hidden" name="view" value="search"></input>
<input type="hidden" name="view" value="search"></input>
<label><a href="javascript: void(null);" id="search-form-close">X</a>{% trans "Search" %}</label> : <input type="text" name="search" />
<input id="submit-search" type="submit" value="{% trans "Search" %} !"></input>
<input id="submit-search" type="submit" value="{% trans "Search" %} !"></input>
</form>
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#search-form").hide();
$("#search").click(function(){
$("#search-form").toggle();
$("#search").toggleClass("current");
$("#search-arrow").toggleClass("arrow-down");
});
});
</script>

View file

@ -352,10 +352,10 @@ footer a {
letter-spacing:normal;
box-shadow: 0 3px 7px rgba(0,0,0,0.3);
display: inline-block;
width: 32%!important;
width: 32%;
margin-bottom: 1.5em;
vertical-align: top;
margin-left: 1.5%!important;
margin-left: 1.5%;
position: relative;
overflow: hidden;
padding: 1.5em 1.5em 3em 1.5em;
@ -492,7 +492,7 @@ footer a {
}
.entrie:nth-child(3n+1) {
margin-left: 0!important;
margin-left: 0;
}
.results {
@ -540,7 +540,7 @@ footer a {
2.1 = "save a link" popup div related styles
========================================================================== */
#bagit-form {
#bagit-form, #search-form {
background: rgba(0,0,0,0.5);
position: absolute;
top: 0;
@ -555,7 +555,7 @@ footer a {
border-left: 1px #EEE solid;
}
#bagit-form form {
#bagit-form form, #search-form form {
background: #FFF;
position: absolute;
top: 0;
@ -568,7 +568,7 @@ footer a {
padding: 2em;
}
a#bagit-form-close {
a#bagit-form-close, a#search-form-close {
background: #000;
color: #FFF;
padding: 0.2em 0.5em;
@ -577,7 +577,7 @@ a#bagit-form-close {
float: right;
font-size: 0.6em;
}
a#bagit-form-close:hover {
a#bagit-form-close:hover, a#search-form-close:hover {
background: #999;
color: #000;
}
@ -1028,7 +1028,7 @@ blockquote {
display: none;
}
#bagit-form {
#bagit-form, #search-form {
left: 0;
}
}

View file

@ -9,9 +9,11 @@
<h2>{% trans "Poching a link" %}</h2>
<p>{% trans "There are several ways to save an article:" %} (<a class="special" href="http://doc.wallabag.org" title="{% trans "read the documentation" %}">?</a>)</p>
<ul>
<li>firefox: <a href="https://bitbucket.org/jogaulupeau/poche/downloads/poche.xpi" title="download the firefox extension">{% trans "download the extension" %}</a></li>
<li>chrome: <a href="https://bitbucket.org/jogaulupeau/poche/downloads/poche.crx" title="download the chrome extension">{% trans "download the extension" %}</a></li>
<li>android: <a href="https://bitbucket.org/jogaulupeau/poche/downloads/Poche.apk" title="download the application">{% trans "download the application" %}</a></li>
<li>Firefox: <a href="https://addons.mozilla.org/firefox/addon/wallabag/" title="download the firefox extension">{% trans "download the extension" %}</a></li>
<li>Chrome: <a href="http://doc.wallabag.org/doku.php?id=users:chrome_extension" title="download the chrome extension">{% trans "download the extension" %}</a></li>
<li>Android: <a href="https://f-droid.org/app/fr.gaulupeau.apps.InThePoche" title="download the application">{% trans "via F-Droid" %}</a> {% trans " or " %} <a href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche" title="download the application">{% trans "via Google Play" %}</a></li>
<li>iOS: <a href="https://itunes.apple.com/app/wallabag/id828331015?mt=8" title="download the iOS application">{% trans "download the application" %}</a></li>
<li>Windows Phone: <a href="http://www.windowsphone.com/en-us/store/app/wallabag/ff890514-348c-4d0b-9b43-153fff3f7450" title="download the window phone application">{% trans "download the application" %}</a></li>
<li>
<form method="get" action="index.php">
<label class="addurl" for="plainurl">{% trans "by filling this field" %}:</label>

View file

@ -11,3 +11,4 @@
<script src="{{ poche_url }}themes/default/js/autoClose.js"></script>
<script src="{{ poche_url }}themes/default/js/closeMessage.js"></script>
<script src="{{ poche_url }}themes/default/js/saveLink.js"></script>
<script src="{{ poche_url }}themes/default/js/popupForm.js"></script>

View file

@ -0,0 +1,20 @@
$(document).ready(function() {
$("#search-form").hide();
function closeSearch() {
$("#search-form").toggle();
$("#search").toggleClass("current");
$("#search-arrow").toggleClass("arrow-down");
}
$("#search").click(function(){
closeSearch();
});
$("#search-form-close").click(function(){
closeSearch();
});
});

View file

@ -75,7 +75,7 @@ $.fn.ready(function() {
========================================================================== */
$(window).keydown(function(e){
if ( ( e.target.tagName.toLowerCase() !== 'input' && e.keyCode == 83 ) || e.keyCode == 27 ) {
if ( ( e.target.tagName.toLowerCase() !== 'input' && e.keyCode == 83 ) || (e.keyCode == 27 && $bagitForm.is(':visible') ) ) {
$bagit.removeClass("current");
$("#bagit-arrow").removeClass("arrow-down");
toggleSaveLinkForm();