Commit 4d605c9d authored by Erase's avatar Erase

Mise à jour RSS Fusion + gestion affinée des filtres par flux

parent a1f287bb
......@@ -18,33 +18,66 @@
$oConf = json_decode(file_get_contents($conf));
if($oConf && gettype($oConf) == 'object'){
$_links = $oConf->flux;
//~ Set config
\Config::set('where', $oConf->where);
\Config::set('_starWords', $oConf->_starWords);
\Config::set('_badWords', $oConf->_badWords);
$_links = array();
$_items = array();
$_c = array();
//~ Load feeds
$oFeeds = new FeedReader($_links);
foreach($oConf->flux as $link){
//array_push($_links, $link['flux']);
if(!is_null($oFeeds->objParseFeed)){
$_items = array();
$_c = array();
$oFeeds = new FeedReader(array($link->flux));
if(!is_null($oFeeds->objParseFeed)){
foreach($oFeeds->objParseFeed->items as $item){
if(!empty($item['link']) && !in_array($item['link'], $_c)){
//~ Prevent duplicate item by link
array_push($_c, $item['link']);
//~ Where
$_cible = explode('|', $link->where);
foreach($oFeeds->objParseFeed->items as $item){
if(!empty($item['link']) && !in_array($item['link'], $_c)){
//~ Delete duplicate item by link
array_push($_c, $item['link']);
if(count($_cible) > 1){
$merge_str = "";
foreach ($_cible as $cible) {
$merge_str .= " ".strtolower($item[$cible]);
}
}else{
if($_cible[0] && $_cible[0] != 'all'){
$merge_str = strtolower($item[$_cible[0]]);
}else{
$merge_str = strtolower($item['title']." ".$item['description']." ".$item['link']);
}
}
//~ Keywords filter
if((count(Config::get('_starWords')) && $item['show'] == 'star')
OR (!count(Config::get('_starWords')) && $item['show'] == 'show')){
array_push($_items, $item);
}
}
}
$_words = explode(',', $link->words);
if(count($_words) && $link->words != ""){
$oIsIn = $oFeeds->isInStr($merge_str, $_words);
if($link->filter == 'show' && $oIsIn){
//~ add
array_push($_items, $item);
}elseif($link->filter == 'hide' && !$oIsIn){
//~ add
array_push($_items, $item);
}
}else{
//~ No "keywords", show all
array_push($_items, $item);
}
}
}
}
}
//~ Sort by pubdate
$pub = array();
foreach ($_items as $key => $row)
{
$pub[$key] = $row['pubdate'];
}
array_multisort($pub, SORT_DESC, $_items);
//~ Generate RSS
$rssfeed = '<?xml version="1.0" encoding="UTF-8"?>';
......@@ -65,8 +98,6 @@
$rssfeed .= '<enclosure url="'.$item['enclosure'].'" />';
$rssfeed .= '<permalink>'.$item['permalink'].'</permalink>';
$rssfeed .= '<show>'.$item['show'].'</show>';
$rssfeed .= '<base>'.$item['base'].'</base>';
$rssfeed .= '</item>';
}
}
......
......@@ -38,105 +38,96 @@
'data' => array()
);
//var_dump($_POST);
//~ Check data
if(array_key_exists('flux', $_POST) && !empty($_POST['flux'])){
$_links = array_unique(
array_map('trim',
preg_split( '/\r\n|\r|\n/', $_POST['flux'])
)
);
//~ Where to look
if(array_key_exists('where', $_POST) && !empty($_POST['where'])){
\Config::set('where', $_POST['where']);
}
//~ Check if feeds are valid
$oFeeds = new FeedReader($_POST['flux']);
if(!is_null($oFeeds->objParseFeed)){
//~ Valid !
//~ Show or hide keywords
if(array_key_exists('filter', $_POST) && !empty($_POST['filter'])){
$mode = "_starWords";
if($_POST['filter'] === 'hide'){
$mode = "_badWords";
//~ Set <link> RSS
$rss_link = ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1)) || $_SERVER['SSL'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);
if(array_key_exists('link', $_POST) && !empty($_POST['link'])){
$rss_link = htmlspecialchars($_POST['link'], ENT_QUOTES, Config::get('characterSet'));
}
if(!empty($_POST['words'])){
Config::set($mode, array_unique(
array_map('trim',
explode(',', $_POST['words'])
)
));
//~ Set <title> RSS
$rss_title = "";
if(array_key_exists('titre', $_POST) && !empty($_POST['titre'])){
$rss_title = htmlspecialchars($_POST['titre'], ENT_QUOTES, Config::get('characterSet'));
}
}
$oFeeds = new FeedReader($_links);
//~ Set <description> RSS
$rss_description = "";
if(array_key_exists('desc', $_POST) && !empty($_POST['desc'])){
$rss_description = htmlspecialchars($_POST['desc'], ENT_QUOTES, Config::get('characterSet'));
}
if(!is_null($oFeeds->objParseFeed)){
//~ Set <link> RSS
$rss_link = ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1)) || $_SERVER['SSL'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);
if(array_key_exists('link', $_POST) && !empty($_POST['link'])){
$rss_link = htmlspecialchars($_POST['link'], ENT_QUOTES, Config::get('characterSet'));
}
//~ Set <title> RSS
$rss_title = "";
if(array_key_exists('titre', $_POST) && !empty($_POST['titre'])){
$rss_title = htmlspecialchars($_POST['titre'], ENT_QUOTES, Config::get('characterSet'));
}
//~ Set <description> RSS
$rss_description = "";
if(array_key_exists('desc', $_POST) && !empty($_POST['desc'])){
$rss_description = htmlspecialchars($_POST['desc'], ENT_QUOTES, Config::get('characterSet'));
}
//~ Config is ok ! Storage
$conf_storage = json_encode(array(
//~ Get param for all feeds
$_links = array();
foreach($_POST['flux'] as $index => $link){
if(!empty($link)){
array_push(
$_links,
array(
'flux' => $link,
'filter' => $_POST['filter'][$index],
'where' => $_POST['where'][$index],
'words' => $_POST['words'][$index]
)
);
}
}
//~ Config is ok ! Storage
$conf_storage = json_encode(array(
'flux' => $_links,
'link' => $rss_link,
'title' => $rss_title,
'description' => $rss_description,
'where' => \Config::get('where'),
'_starWords' => \Config::get('_starWords'),
'_badWords' => \Config::get('_badWords')
'description' => $rss_description
));
$conf_name = str_replace('.', '', uniqid(mt_rand(), true));
$path = TL_ROOT . '/../../c/';
if(file_put_contents($path.$conf_name, $conf_storage)){
//~ Generate link to return
$_d['sucess'] = true;
$_d['message'] = "Voici le lien RSS relatif à votre configuration";
$_d['data'] = array(
'file' => './flux.php?c='.$conf_name,
'_' => $_POST
);
//~ Delete old file conf
if ($handle = opendir($path)){
//~ Loop through the directory
while (false !== ($file = readdir($handle))){
//~ Check the file we're doing is actually a file
if (is_file($path.$file) && $file !== 'index.php' && $file !== '.gitignore'){
//~ Check if the file is older than 30 days old
if (filemtime($path.$file) < (time() - (30 * 24 * 60 * 60))){ //~ 3 days
//~ Do the deletion
unlink($path.$file);
}
}
}
}
}else{
//~ Error
$_d['sucess'] = false;
$_d['message'] = "Une erreur est survenue lors de l'enregistrement de votre configuration";
}
}else{
$_d['sucess'] = false;
$_d['message'] = "Une erreur est survenue lors du chargement de flux RSS";
}
$conf_name = str_replace('.', '', uniqid(mt_rand(), true));
$path = TL_ROOT . '/../../c/';
if(file_put_contents($path.$conf_name, $conf_storage)){
//~ Generate link to return
$_d['sucess'] = true;
$_d['message'] = "Voici le lien RSS relatif à votre configuration";
$_d['data'] = array(
'file' => './flux.php?c='.$conf_name,
'_' => $_POST
);
//~ Delete old file conf
if ($handle = opendir($path)){
//~ Loop through the directory
while (false !== ($file = readdir($handle))){
//~ Check the file we're doing is actually a file
if (is_file($path.$file) && $file !== 'index.php' && $file !== '.gitignore'){
//~ Check if the file is older than 30 days old
if (filemtime($path.$file) < (time() - (30 * 24 * 60 * 60))){ //~ 3 days
//~ Do the deletion
unlink($path.$file);
}
}
}
}
}else{
//~ Error
$_d['sucess'] = false;
$_d['message'] = "Une erreur est survenue lors de l'enregistrement de votre configuration";
}
}else{
$_d['sucess'] = false;
$_d['message'] = "Une erreur est survenue lors du chargement de flux RSS";
}
}else{
//~ No data
$_d['sucess'] = false;
......
......@@ -63,36 +63,56 @@
<div class="clear"></div>
<div class="xml-form shadow" id="form">
<form id="xml_form" method="POST" action="" accept-charset="UTF-8">
<fieldset class="full-form">
<label for="flux" data-lng>URL des flux RSS à fusionner (un lien par ligne)</label>
<textarea id="flux" name="flux"></textarea>
</fieldset>
<div class="clear"></div>
<div class="bottom-shadow"></div>
<div class="no-shadow hidden"></div>
<div class="clear"></div>
<div style="background-color:#ddd;">
<fieldset class="full-form">
<div class="container-feeds">
<div class="bloc mcw-bloc">
<span data-lng>Pour le flux :</span>
<input class="mcw mcw-text" type="text" name="flux[]" placeholder="URL">
<br><br>
<span data-lng class="small">je désire :</span>
<select class="mcw mcw-select" name="filter[]">
<option value="show" data-lng>afficher</option>
<option value="hide" data-lng>masquer</option>
</select>
<span data-lng class="small">en effectuant ma recherche sur</span>
<select class="mcw mcw-select" name="where[]">
<option value="title" data-lng>le titre</option>
<option value="description" data-lng>la description</option>
<option value="link" data-lng>le lien</option>
<option value="title|description" data-lng>le titre et la description</option>
<option value="title|link" data-lng>le titre et le lien</option>
<option value="link|description" data-lng>le lien et la description</option>
<option value="all" data-lng>tous les éléments</option>
</select>
<br><br>
<span data-lng>les items contenant le(s) mot(s) clés (séparer chaque mot clé par une virgule) :</span>
<br><input class="mcw mcw-text" type="text" name="words[]" value="">
<fieldset id="question" class="full-form">
<h3 data-lng>Options des items</h3>
<span data-lng>Je désire</span>
<select name="filter" id="filter">
<option value="show" data-lng>afficher</option>
<option value="hide" data-lng>masquer</option>
</select>
<span data-lng>en effectuant ma recherche sur</span>
<select name="where" id="where">
<option value="title" data-lng>le titre</option>
<option value="description" data-lng>la description</option>
<option value="all" data-lng>le titre et la description</option>
</select>
<span data-lng>les items contenant le(s) mot(s) clés (séparer chaque mot clé par une virgule) :</span>
<input type="text" name="words" value="" id="words">
</fieldset>
<div class="clear"></div>
<div class="bottom-shadow"></div>
<div class="no-shadow hidden"></div>
<div class="clear"></div>
<span class="mcw mcw-buttons buttons">
<a class="mcw mcw-a add_field" href="#">Add</a>
</span>
<div class="clear"></div>
<div class="bottom-shadow"></div>
<div class="no-shadow hidden"></div>
<div class="clear"></div>
</div>
</div>
</fieldset>
</div>
<h3 data-lng>Options du flux généré</h3>
<fieldset>
<label for="titre" data-lng>Titre du flux général</label>
......@@ -127,7 +147,7 @@
&nbsp; &nbsp;| &nbsp; &nbsp; 
<span data-lng>Sources disponibles sur</span> <a href="https://framagit.org/Erase/RSS-Fusion-Demo" target="_blank" title="RSS-Fusion-Démo sur Framagit">Framagit</a>
&nbsp; &nbsp;| &nbsp; &nbsp; 
<span class="small">version 0.6.4</span>
<span class="small">version 0.7.0b</span>
</div>
</footer>
</div>
......@@ -140,5 +160,6 @@
</script>
<?php endif;?>
<script src="js/custom.js" type="text/javascript"></script>
<script src="js/multicolumns.js" type="text/javascript"></script>
</body>
</html>
\ No newline at end of file
$(document).ready(function() {
var max_fields = 20; //maximum input boxes allowed
var wrapper = $(".container-feeds");
var add_button = $(".add_field");
var x = 1;
$(wrapper).on("click",".remove_field", function(e){
e.preventDefault();
$(this).parents('div.bloc').remove(); x--;
})
$(wrapper).on("click",".add_field", function(e){
e.preventDefault();
e.preventDefault();
if(x < max_fields){
x++;
$n = $('.bloc').first().html();
$(wrapper).append('<div class="bloc mcw-bloc">'+$n+'</div>').find('.bloc').last().find('.buttons').append('<a href="#" class="remove_field">Remove</a>');
}
})
});
\ No newline at end of file
......@@ -4,13 +4,18 @@
"Créer un flux personnalisé" : "Create your personal feed",
"URL des flux RSS à fusionner (un lien par ligne)" : "URLs of the existing source feeds, one per line",
"Options des items" : "Items options",
"Je désire" : "I want to",
"Pour le flux :" : "For this feed:",
"je désire :" : "I want to:",
"afficher" : "include",
"masquer" : "exclude",
"en effectuant ma recherche sur" : "items where the",
"le titre" : "title",
"la description" : "description",
"le lien" : "link",
"le titre et la description" : "title and description",
"le titre et le lien" : "title and link",
"le lien et la description" : "link and description",
"tous les éléments" : "all",
"les items contenant le(s) mot(s) clés (séparer chaque mot clé par une virgule) :" : "contain the word(s) (comma ',' separated words) :",
"Options du flux généré" : "Generated feed options",
"Titre du flux général" : "Generated feed title",
......
......@@ -4,13 +4,18 @@
"Créer un flux personnalisé" : "Créer un flux personnalisé",
"URL des flux RSS à fusionner (un lien par ligne)" : "URL des flux RSS à fusionner (un lien par ligne)",
"Options des items" : "Options des items",
"Je désire" : "Je désire",
"Pour le flux :" : "Pour le flux :",
"je désire :" : "je désire :",
"afficher" : "afficher",
"masquer" : "masquer",
"en effectuant ma recherche sur" : "en effectuant ma recherche sur",
"le titre" : "le titre",
"la description" : "la description",
"le lien" : "le lien",
"le titre et la description" : "le titre et la description",
"le titre et le lien" : "le titre et le lien",
"le lien et la description" : "le lien et la description",
"tous les éléments" : "tous les éléments",
"les items contenant le(s) mot(s) clés (séparer chaque mot clé par une virgule) :" : "les items contenant le(s) mot(s) clés (séparer chaque mot clé par une virgule) :",
"Options du flux généré" : "Options du flux généré",
"Titre du flux général" : "Titre du flux général",
......
......@@ -670,6 +670,62 @@ section article a {
padding:20px 0;
}
.xml-form .mcw{
}
.xml-form .mcw-bloc{
width:auto;
text-align: left;
background:#efefef;
padding:20px;
}
.xml-form .mcw-text{
}
.xml-form .mcw-select{
width:auto;
padding-right: 20px;
}
.xml-form .mcw-a{
}
.xml-form .mcw-buttons{
text-align:right;
}
.xml-form .mcw-buttons a{
display: inline-block;
background:#E84F40;
width:50px;
color:#323232;
text-align: center;
padding:10px 15px;
text-decoration: none;
opacity: 0.7;
border-radius: 10px;
}
.xml-form .mcw-buttons a:hover{
opacity: 1;
}
.xml-form .mcw-buttons a:first-child{
background:#58D68D;
}
.xml-form span.small{
display: inline-block;
width: auto;
padding: 0 10px 0 5px;
}
@media screen and (max-width: 1280px) {
header{
-moz-background-size: cover; /* Gecko 1.9.2 (Firefox 3.6) */
......
......@@ -8,9 +8,13 @@ RSS-Fusion
* Surcharge de personnalisation
Démo et exemple d'utilisation
----------
Un **[exemple d'utilisation en ligne]** est parfois disponible, selon la sucharge du serveur en mousse qui l'héberge. Les sources de cet exemple sont disponibles **[par ici].**
Par défaut
----------
* Système de mise en cache des flux (durée par défaut = 1h)
* Système de mise en cache des flux (durée = 1h)
* Données triées par date/heure décroissante
* Possibilité de spécifier des mots clés ("star and bad words")
......@@ -29,8 +33,8 @@ $ git clone https://git.framasoft.org/Erase/RSS-Fusion.git
```
ou en [téléchargeant l'archive zip]
Vérifier/assigner les droits en écriture au sein du répertoire :
* `/data`
~~Vérifier/assigner les droits en écriture au sein du répertoire :~~
* ~~`/data`~~
......@@ -83,4 +87,6 @@ Auteur
[téléchargeant l'archive zip]: <https://framagit.org/Erase/RSS-Fusion/repository/archive.zip>
[SimplePie]: <http://simplepie.org/>
[Creative Commons BY-NC-SA 4.0]: <http://creativecommons.org/licenses/by-nc-sa/4.0/>
[Un simple développeur paysagiste]: <http://www.green-effect.fr>
\ No newline at end of file
[Un simple développeur paysagiste]: <http://www.green-effect.fr>
[exemple d'utilisation en ligne]: <http://rss-fusion.green-effect.fr/>
[par ici]: <https://framagit.org/Erase/RSS-Fusion-Demo>
\ No newline at end of file
......@@ -14,8 +14,12 @@
ini_set('display_errors', (Config::get('displayErrors') ? 1 : 0));
error_reporting((Config::get('displayErrors') || Config::get('logErrors')) ? 1 : 0);
/*
$_links = array(
/*
** For example
*/
/* $_links = array(
"http://www.lemonde.fr/rss/une.xml",
"https://rss.framasoft.org/"
);
......@@ -24,7 +28,7 @@
echo "<pre>";
var_dump($feeds->objParseFeed->items)
*/
var_dump($feeds->objParseFeed->items)*/
?>
File mode changed from 100755 to 100644
......@@ -105,12 +105,19 @@ class FeedReader
// Where
$where = \Config::get('where');
if(!is_null($where) && $where == 'title'){
$merge_str = strtolower($items[$i]['title']);
}elseif(!is_null($where) && $where == 'description'){
$merge_str = strtolower($items[$i]['description']);
$_cible = explode('|', \Config::get('where'));
if(count($_cible) > 1){
$merge_str = "";
foreach ($_cible as $cible) {
$merge_str .= " ".strtolower($items[$i][$cible]);
}
}else{
$merge_str = strtolower($items[$i]['title']." ".$items[$i]['description']);
if($_cible[0] && $_cible[0] != 'all'){
$merge_str = strtolower($items[$i][$_cible[0]]);
}else{
$merge_str = strtolower($items[$i]['title']." ".$items[$i]['description']." ".$items[$i]['link']);
}
}
// Bad and star words
......
......@@ -17,8 +17,7 @@
$GLOBALS['TL_CONFIG']['characterSet'] = 'utf-8';
$GLOBALS['TL_CONFIG']['displayErrors'] = false;
$GLOBALS['TL_CONFIG']['logErrors'] = false;
$GLOBALS['TL_CONFIG']['language'] = 'fr'; //~ (fr || en)
$GLOBALS['TL_CONFIG']['logErrors'] = true;
......@@ -62,4 +61,29 @@ $GLOBALS['TL_CONFIG']['RssReaderReferer'] = "RSS-Fusion with SimplePie";
*/
$GLOBALS['TL_CONFIG']['_starWords'] = array();
$GLOBALS['TL_CONFIG']['_badWords'] = array();
$GLOBALS['TL_CONFIG']['where'] = 'all'; //~ (title | description | all)
\ No newline at end of file
$GLOBALS['TL_CONFIG']['where'] = 'all'; //~ (title, description, link, all)
//*
// Search in title only
// $GLOBALS['TL_CONFIG']['where'] = 'title';
//*
//*
// Search in description only
// $GLOBALS['TL_CONFIG']['where'] = ' description';
//*
//*
// Search in url only
// $GLOBALS['TL_CONFIG']['where'] = 'link';
//*
//*
// Search in multiple content, separate with "|"
// $GLOBALS['TL_CONFIG']['where'] = 'title|description';
//*
//*
// Search in all content
// $GLOBALS['TL_CONFIG']['where'] = 'all';
//*
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment