Commit 12dd1939 authored by Sebastian Reichel's avatar Sebastian Reichel

Imported Upstream version 1.5.6

parent 60207356
*~
*.DS_Store
#*
.idea/*
config.php
icons/*
cache/*/*
......
......@@ -19,10 +19,10 @@ dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
getItemById: function(id) {
return this.store._itemsByIdentity[id];
},
getFeedValue: function(feed, is_cat, key) {
getFeedValue: function(feed, is_cat, key) {
if (!this.store._itemsByIdentity) return undefined;
if (is_cat)
if (is_cat)
treeItem = this.store._itemsByIdentity['CAT:' + feed];
else
treeItem = this.store._itemsByIdentity['FEED:' + feed];
......@@ -30,7 +30,7 @@ dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
if (treeItem)
return this.store.getValue(treeItem, key);
},
getFeedName: function(feed, is_cat) {
getFeedName: function(feed, is_cat) {
return this.getFeedValue(feed, is_cat, 'name');
},
getFeedUnread: function(feed, is_cat) {
......@@ -44,7 +44,7 @@ dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
if (!value) value = '';
if (!this.store._itemsByIdentity) return undefined;
if (is_cat)
if (is_cat)
treeItem = this.store._itemsByIdentity['CAT:' + feed];
else
treeItem = this.store._itemsByIdentity['FEED:' + feed];
......@@ -53,6 +53,9 @@ dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
return this.store.setValue(treeItem, key, value);
},
getNextUnreadFeed: function (feed, is_cat) {
if (!this.store._itemsByIdentity)
return null;
if (is_cat) {
treeItem = this.store._itemsByIdentity['CAT:' + feed];
items = this.store._arrayOfTopLevelItems;
......@@ -79,7 +82,7 @@ dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
}
}
}
return null;
},
hasCats: function() {
......@@ -93,7 +96,7 @@ dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
dojo.declare("fox.FeedTree", dijit.Tree, {
_createTreeNode: function(args) {
var tnode = new dijit._TreeNode(args);
if (args.item.icon)
tnode.iconNode.src = args.item.icon[0];
......@@ -144,7 +147,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
return (item.unread == 0) ? "dijitTreeLabel" : "dijitTreeLabel Unread";
},
getRowClass: function (item, opened) {
return (!item.error || item.error == '') ? "dijitTreeRow" :
return (!item.error || item.error == '') ? "dijitTreeRow" :
"dijitTreeRow Error";
},
getLabel: function(item) {
......@@ -164,7 +167,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
}
},
selectFeed: function(feed, is_cat) {
if (is_cat)
if (is_cat)
treeNode = this._itemNodesMap['CAT:' + feed];
else
treeNode = this._itemNodesMap['FEED:' + feed];
......@@ -176,7 +179,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
}
},
setFeedIcon: function(feed, is_cat, src) {
if (is_cat)
if (is_cat)
treeNode = this._itemNodesMap['CAT:' + feed];
else
treeNode = this._itemNodesMap['FEED:' + feed];
......@@ -189,7 +192,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
return false;
},
setFeedExpandoIcon: function(feed, is_cat, src) {
if (is_cat)
if (is_cat)
treeNode = this._itemNodesMap['CAT:' + feed];
else
treeNode = this._itemNodesMap['FEED:' + feed];
......@@ -210,29 +213,29 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
var tree = this;
var cats = this.model.store._arrayOfTopLevelItems;
cats.each(function(cat) {
var cat_unread = tree.hideReadFeeds(cat.items, hide, show_special);
var id = String(cat.id);
var node = tree._itemNodesMap[id];
var bare_id = parseInt(id.substr(id.indexOf(":")+1));
if (node) {
var check_unread = tree.model.getFeedUnread(bare_id, true);
if (hide && cat_unread == 0 && check_unread == 0) {
Effect.Fade(node[0].rowNode, {duration : 0.3,
Effect.Fade(node[0].rowNode, {duration : 0.3,
queue: { position: 'end', scope: 'FFADE-' + id, limit: 1 }});
} else {
Element.show(node[0].rowNode);
++cat_unread;
}
}
}
});
} else {
this.hideReadFeeds(this.model.store._arrayOfTopLevelItems, hide,
this.hideReadFeeds(this.model.store._arrayOfTopLevelItems, hide,
show_special);
}
},
......@@ -243,13 +246,13 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
items.each(function(feed) {
var id = String(feed.id);
var bare_id = parseInt(feed.bare_id);;
var unread = feed.unread[0];
var node = tree._itemNodesMap[id];
if (node) {
if (hide && unread == 0 && (bare_id > 0 || !show_special)) {
Effect.Fade(node[0].rowNode, {duration : 0.3,
Effect.Fade(node[0].rowNode, {duration : 0.3,
queue: { position: 'end', scope: 'FFADE-' + id, limit: 1 }});
} else {
Element.show(node[0].rowNode);
......@@ -257,7 +260,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
}
}
});
return cat_unread;
},
collapseCat: function(id) {
......@@ -271,7 +274,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
if (node && item) {
var hidden = tree.model.store.getValue(item, 'hidden');
if (hidden)
if (hidden)
tree._expandNode(node);
else
tree._collapseNode(node);
......@@ -290,13 +293,45 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
var id = tree.model.store.getValue(cat, 'id');
var node = tree._itemNodesMap[id][0];
if (hidden)
if (hidden)
tree._collapseNode(node);
else
tree._expandNode(node);
});
},
getVisibleUnreadFeeds: function() {
var items = this.model.store._arrayOfAllItems;
var rv = [];
for (var i = 0; i < items.length; i++) {
var id = String(items[i].id);
var box = this._itemNodesMap[id];
if (box) {
var row = box[0].rowNode;
var cat = false;
try {
cat = box[0].rowNode.parentNode.parentNode;
} catch (e) { }
if (row) {
if (Element.visible(row) && (!cat || Element.visible(cat))) {
var feed_id = String(items[i].bare_id);
var is_cat = !id.match('FEED:');
var unread = this.model.getFeedUnread(feed_id, is_cat);
if (unread > 0)
rv.push([feed_id, is_cat]);
}
}
}
}
return rv;
},
getNextFeed: function (feed, is_cat) {
if (is_cat) {
treeItem = this.model.store._itemsByIdentity['CAT:' + feed];
......@@ -311,7 +346,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
if (items[i] == treeItem) {
for (j = i+1; j < items.length; j++) {
var id = String(items[j].id);
var id = String(items[j].id);
var box = this._itemNodesMap[id];
if (box) {
......@@ -329,7 +364,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
}
if (item) {
return [this.model.store.getValue(item, 'bare_id'),
return [this.model.store.getValue(item, 'bare_id'),
!this.model.store.getValue(item, 'id').match('FEED:')];
} else {
return false;
......@@ -349,7 +384,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
if (items[i] == treeItem) {
for (j = i-1; j > 0; j--) {
var id = String(items[j].id);
var id = String(items[j].id);
var box = this._itemNodesMap[id];
if (box) {
......@@ -368,7 +403,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
}
if (item) {
return [this.model.store.getValue(item, 'bare_id'),
return [this.model.store.getValue(item, 'bare_id'),
!this.model.store.getValue(item, 'id').match('FEED:')];
} else {
return false;
......
......@@ -51,7 +51,7 @@
$op = db_escape_string($_REQUEST["op"]);
$seq = (int) $_REQUEST["seq"];
// header("Content-Type: application/json");
header("Content-Type: text/plain");
function api_wrap_reply($status, $seq, $reply) {
print json_encode(array("seq" => $seq,
......@@ -196,10 +196,11 @@
/* all_articles, unread, adaptive, marked, updated */
$view_mode = db_escape_string($_REQUEST["view_mode"]);
$include_attachments = (bool)db_escape_string($_REQUEST["include_attachments"]);
$since_id = (int)db_escape_string($_REQUEST["since_id"]);
$headlines = api_get_headlines($link, $feed_id, $limit, $offset,
$filter, $is_cat, $show_excerpt, $show_content, $view_mode, false,
$include_attachments);
$include_attachments, $since_id);
print api_wrap_reply(API_STATUS_OK, $seq, $headlines);
......
......@@ -14,8 +14,10 @@
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
$op = $_REQUEST["op"];
require_once "functions.php";
require_once "sessions.php";
if ($op != "share") require_once "sessions.php";
require_once "modules/backend-rpc.php";
require_once "sanity_check.php";
require_once "config.php";
......@@ -40,7 +42,6 @@
init_connection($link);
$op = $_REQUEST["op"];
$subop = $_REQUEST["subop"];
$mode = $_REQUEST["mode"];
......@@ -59,7 +60,7 @@
}
if (!($_SESSION["uid"] && validate_session($link)) && $op != "globalUpdateFeeds" &&
$op != "rss" && $op != "getUnread" && $op != "getProfiles" &&
$op != "rss" && $op != "getUnread" && $op != "getProfiles" && $op != "share" &&
$op != "fbexport" && $op != "logout" && $op != "pubsub") {
if ($op == 'pref-feeds' && $_REQUEST['subop'] == 'add') {
......@@ -205,7 +206,7 @@
case "view":
$id = db_escape_string($_REQUEST["id"]);
$cids = split(",", db_escape_string($_REQUEST["cids"]));
$cids = explode(",", db_escape_string($_REQUEST["cids"]));
$mode = db_escape_string($_REQUEST["mode"]);
$omode = db_escape_string($_REQUEST["omode"]);
......@@ -217,7 +218,7 @@
if ($mode == "") {
array_push($articles, format_article($link, $id, false));
} else if ($mode == "zoom") {
array_push($articles, format_article($link, $id, false, true, true));
array_push($articles, format_article($link, $id, true, true));
} else if ($mode == "raw") {
if ($_REQUEST['html']) {
header("Content-Type: text/html");
......@@ -227,10 +228,10 @@
$article = format_article($link, $id, false);
print $article['content'];
return;
} else {
catchupArticleById($link, $id, 0);
}
catchupArticleById($link, $id, 0);
if (!$_SESSION["bw_limit"]) {
foreach ($cids as $cid) {
if ($cid) {
......@@ -257,12 +258,14 @@
$subop = db_escape_string($_REQUEST["subop"]);
$view_mode = db_escape_string($_REQUEST["view_mode"]);
$limit = (int) get_pref($link, "DEFAULT_ARTICLE_LIMIT");
@$cat_view = db_escape_string($_REQUEST["cat"]);
@$cat_view = db_escape_string($_REQUEST["cat"]) == "true";
@$next_unread_feed = db_escape_string($_REQUEST["nuf"]);
@$offset = db_escape_string($_REQUEST["skip"]);
@$vgroup_last_feed = db_escape_string($_REQUEST["vgrlf"]);
$order_by = db_escape_string($_REQUEST["order_by"]);
if (is_numeric($feed)) $feed = (int) $feed;
/* Feed -5 is a special case: it is used to display auxiliary information
* when there's nothing to load - e.g. no stuff in fresh feed */
......@@ -277,10 +280,10 @@
$label_feed = -11-$feed;
$result = db_query($link, "SELECT id FROM ttrss_labels2 WHERE
id = '$label_feed' AND owner_uid = " . $_SESSION['uid']);
} else if (!$cat_view && $feed > 0) {
} else if (!$cat_view && is_numeric($feed) && $feed > 0) {
$result = db_query($link, "SELECT id FROM ttrss_feeds WHERE
id = '$feed' AND owner_uid = " . $_SESSION['uid']);
} else if ($cat_view && $feed > 0) {
} else if ($cat_view && is_numeric($feed) && $feed > 0) {
$result = db_query($link, "SELECT id FROM ttrss_feed_categories WHERE
id = '$feed' AND owner_uid = " . $_SESSION['uid']);
}
......@@ -361,21 +364,15 @@
$disable_cache = $ret[3];
$vgroup_last_feed = $ret[4];
$reply['headlines']['content'] = $ret[5];
$reply['headlines']['toolbar'] = $ret[6];
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("05", $timing_info);
// if ($_REQUEST["debug"]) print_r($ret);
$headlines_unread = ccache_find($link, $returned_feed, $_SESSION["uid"],
$cat_view, true);
$reply['headlines']['content'] =& $ret[5]['content'];
$reply['headlines']['toolbar'] =& $ret[5]['toolbar'];
if ($headlines_unread == -1) {
$headlines_unread = getFeedUnread($link, $returned_feed, $cat_view);
}
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("05", $timing_info);
$reply['headlines-info'] = array("count" => (int) $headlines_count,
"vgroup_last_feed" => $vgroup_last_feed,
"unread" => (int) $headlines_unread,
"disable_cache" => (bool) $disable_cache);
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("20", $timing_info);
......@@ -384,15 +381,15 @@
$articles = array();
foreach ($topmost_article_ids as $id) {
array_push($articles, format_article($link, $id, $feed, false));
array_push($articles, format_article($link, $id, false));
}
$reply['articles'] = $articles;
}
if ($subop) {
$reply['counters'] = getAllCounters($link, $omode, $feed);
}
// if ($subop) {
// $reply['counters'] = getAllCounters($link, $omode, $feed);
// }
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("30", $timing_info);
......@@ -545,9 +542,15 @@
case "pubsub":
$mode = db_escape_string($_REQUEST['hub_mode']);
$feed_id = db_escape_string($_REQUEST['id']);
$feed_id = (int) db_escape_string($_REQUEST['id']);
$feed_url = db_escape_string($_REQUEST['hub_topic']);
if (!PUBSUBHUBBUB_ENABLED) {
header('HTTP/1.0 404 Not Found');
echo "404 Not found";
return;
}
// TODO: implement hub_verifytoken checking
$result = db_query($link, "SELECT feed_url FROM ttrss_feeds
......@@ -577,8 +580,12 @@
} else if (!$mode) {
// Received update ping, schedule feed update.
//update_rss_feed($link, $feed_id, true, true);
update_rss_feed($link, $feed_id, true, true);
db_query($link, "UPDATE ttrss_feeds SET
last_update_started = '1970-01-01',
last_updated = '1970-01-01' WHERE id = '$feed_id' AND
owner_uid = ".$_SESSION["uid"]);
}
} else {
......@@ -627,6 +634,30 @@
}
break; // fbexport
case "share":
$uuid = db_escape_string($_REQUEST["key"]);
$result = db_query($link, "SELECT ref_id, owner_uid FROM ttrss_user_entries WHERE
uuid = '$uuid'");
if (db_num_rows($result) != 0) {
header("Content-Type: text/html");
$id = db_fetch_result($result, 0, "ref_id");
$owner_uid = db_fetch_result($result, 0, "owner_uid");
$_SESSION["uid"] = $owner_uid;
$article = format_article($link, $id, false, true);
$_SESSION["uid"] = "";
print_r($article['content']);
} else {
print "Article not found.";
}
break;
default:
header("Content-Type: text/plain");
print json_encode(array("error" => array("code" => 7)));
......
......@@ -7,7 +7,7 @@
define('DB_PASS', "XXXXXX");
//define('DB_PORT', '5432'); // when neeeded, PG-only
define('SELF_URL_PATH', 'http://localhost/tt-rss');
define('SELF_URL_PATH', 'http://local.host/tt-rss');
// Full URL of your tt-rss installation. You need to set this option
// correctly for tt-rss to function properly.
......
......@@ -21,6 +21,13 @@
$prefs_cache = false;
}
if ($prefs_cache && !defined('DISABLE_SESSIONS') && !SINGLE_USER_MODE) {
if ($_SESSION["prefs_cache"] && @$_SESSION["prefs_cache"][$pref_name]) {
$tuple = $_SESSION["prefs_cache"][$pref_name];
return convert_pref_type($tuple["value"], $tuple["type"]);
}
}
if ($profile) {
$profile_qpart = "profile = '$profile' AND";
} else {
......@@ -29,20 +36,13 @@
if (get_schema_version($link) < 63) $profile_qpart = "";
if ($prefs_cache && !defined('DISABLE_SESSIONS') && !SINGLE_USER_MODE) {
if ($_SESSION["prefs_cache"] && @$_SESSION["prefs_cache"][$pref_name]) {
$tuple = $_SESSION["prefs_cache"][$pref_name];
return convert_pref_type($tuple["value"], $tuple["type"]);
}
}
$result = db_query($link, "SELECT
value,ttrss_prefs_types.type_name as type_name
FROM
$result = db_query($link, "SELECT
value,ttrss_prefs_types.type_name as type_name
FROM
ttrss_user_prefs,ttrss_prefs,ttrss_prefs_types
WHERE
WHERE
$profile_qpart
ttrss_user_prefs.pref_name = '$pref_name' AND
ttrss_user_prefs.pref_name = '$pref_name' AND
ttrss_prefs_types.id = type_id AND
owner_uid = '$user_id' AND
ttrss_user_prefs.pref_name = ttrss_prefs.pref_name");
......@@ -51,7 +51,7 @@
$value = db_fetch_result($result, 0, "value");
$type_name = db_fetch_result($result, 0, "type_name");
if (!defined('DISABLE_SESSIONS') && !SINGLE_USER_MODE) {
if (!defined('DISABLE_SESSIONS') && !SINGLE_USER_MODE) {
if ($user_id = $_SESSION["uid"]) {
$_SESSION["prefs_cache"][$pref_name]["type"] = $type_name;
$_SESSION["prefs_cache"][$pref_name]["value"] = $value;
......@@ -59,8 +59,8 @@
}
return convert_pref_type($value, $type_name);
} else {
} else {
if ($die_on_error) {
die("Fatal error, unknown preferences key: $pref_name");
} else {
......@@ -70,10 +70,10 @@
}
function convert_pref_type($value, $type_name) {
if ($type_name == "bool") {
return $value == "true";
} else if ($type_name == "integer") {
return sprintf("%d", $value);
if ($type_name == "bool") {
return $value == "true";
} else if ($type_name == "integer") {
return sprintf("%d", $value);
} else {
return $value;
}
......@@ -99,8 +99,8 @@
if (get_schema_version($link) < 63) $profile_qpart = "";
$result = db_query($link, "SELECT type_name
FROM ttrss_prefs,ttrss_prefs_types
$result = db_query($link, "SELECT type_name
FROM ttrss_prefs,ttrss_prefs_types
WHERE pref_name = '$key' AND type_id = ttrss_prefs_types.id");
if (db_num_rows($result) > 0) {
......@@ -125,8 +125,8 @@
$value = 'UTC';
}
db_query($link, "UPDATE ttrss_user_prefs SET
value = '$value' WHERE pref_name = '$key'
db_query($link, "UPDATE ttrss_user_prefs SET
value = '$value' WHERE pref_name = '$key'
$profile_qpart
AND owner_uid = " . $_SESSION["uid"]);
......
......@@ -3,14 +3,14 @@
require_once "config.php";
function db_connect($host, $user, $pass, $db) {
if (DB_TYPE == "pgsql") {
if (DB_TYPE == "pgsql") {
$string = "dbname=$db user=$user";
if ($pass) {
$string .= " password=$pass";
$string .= " password=$pass";
}
if ($host) {
$string .= " host=$host";
}
......@@ -30,10 +30,10 @@ function db_connect($host, $user, $pass, $db) {
} else if (DB_TYPE == "mysql") {
$link = mysql_connect($host, $user, $pass);
if ($link) {
$result = mysql_select_db($db, $link);
$result = mysql_select_db($db, $link);
if (!$result) {
die("Can't select DB: " . mysql_error($link));
}
}
return $link;
} else {
die("Connection failed: " . mysql_error($link));
......@@ -44,7 +44,7 @@ function db_connect($host, $user, $pass, $db) {
function db_escape_string($s, $strip_tags = true) {
if ($strip_tags) $s = strip_tags($s);
if (DB_TYPE == "pgsql") {
if (DB_TYPE == "pgsql") {
return pg_escape_string($s);
} else {
return mysql_real_escape_string($s);
......@@ -57,7 +57,7 @@ function db_query($link, $query, $die_on_error = true) {
if (!$result) {
$query = htmlspecialchars($query); // just in case
if ($die_on_error) {
die("Query <i>$query</i> failed [$result]: " . pg_last_error($link));
die("Query <i>$query</i> failed [$result]: " . pg_last_error($link));
}
}
return $result;
......@@ -131,4 +131,8 @@ function db_last_error($link) {
}
}
function db_quote($str){
return("'$str'");
}
?>
body#ttrssDigest {
background : #f0f0f0;
background : #fafafa;
color : black;
font-family : "Lucida Grande", Arial, sans-serif;
font-family : sans-serif;
font-size : 12px;
margin : 0px;
}
a {
......@@ -23,16 +24,26 @@ a:hover {
}
#header {
font-weight : bold;
font-size : 14px;
font-family : "Lucida Grande", "Segoe UI", Tahoma, Arial, sans-serif;
margin-left : 1em;
margin-right : 1em;
font-size : 13px;
font-family : "Segoe UI", Tahoma, sans-serif;
padding : 5px 5px 5px 1.5em;
color : gray;
position : absolute;
top : 0px;
height : 30px;
left : 0px;
right : 0px;
color : #a0a0a0;
}
#header span.title {
font-weight : bold;
font-style : italic;
}
#header div.links {
float : right;
position : absolute;
right : 1.5em;
}
#search {
......@@ -41,71 +52,112 @@ a:hover {
}
#title {
}
#latest {
padding : 5px;
}
#content {
border : 1px solid #e0e0e0;
background : white;
padding : 0.8em;
margin : 0.5em;
position : absolute;
left : 0px;
top : 30px;
right : 0px;
bottom : 0px;
-webkit-transition: left 0.2s linear, right 0.2s linear;
-moz-transition: left 0.2s linear, right 0.2s linear;
transition: left 0.2s linear, right 0.2s linear;
}
#footer {
font-size : 12px;
text-align : center;
color : gray;
#article {
position : absolute;
overflow : auto;
right : 0px;
width : 60%;
bottom : 0px;
top : 30px;
background : white;
border-width : 0px 0px 0px 2px;
border-color : #e0e0e0;
border-style : solid;
z-index : -1;
opacity : 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
/*#content h1 {
font-weight : bold;
font-size : 25px;
font-family : "Lucida Grande", "Segoe UI", Tahoma, Arial, sans-serif;
letter-spacing : -2;