aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHabeas Codice <habeascodice@federated.social>2015-02-16 15:13:31 -0800
committerHabeas Codice <habeascodice@federated.social>2015-02-16 15:13:31 -0800
commitd9d029470f188796988e002eb90e9dbf96d3dd29 (patch)
treeef922432ae326f358374535bf68492729134e49e
parentca8e22101803454be60af35d2cf71ae80224805a (diff)
parent1d1676094dd82482f113d6de9c2a95407a1a692f (diff)
downloadvolse-hubzilla-d9d029470f188796988e002eb90e9dbf96d3dd29.tar.gz
volse-hubzilla-d9d029470f188796988e002eb90e9dbf96d3dd29.tar.bz2
volse-hubzilla-d9d029470f188796988e002eb90e9dbf96d3dd29.zip
Merge branch 'master' of https://github.com/friendica/red
-rwxr-xr-xboot.php3
-rw-r--r--doc/credits.bb1
-rw-r--r--doc/database.bb37
-rw-r--r--doc/external-resource-links.bb5
-rw-r--r--doc/html/navtreeindex10.js8
-rw-r--r--include/bbcode.php1
-rw-r--r--include/dir_fns.php2
-rw-r--r--include/socgraph.php23
-rw-r--r--include/widgets.php7
-rw-r--r--include/zot.php2
-rw-r--r--library/justifiedGallery/dist/css/justifiedGallery.min.css7
-rw-r--r--library/justifiedGallery/dist/js/jquery.justifiedGallery.min.js7
-rw-r--r--library/justifiedGallery/jquery.justifiedGallery.js (renamed from library/justifiedGallery/dist/js/jquery.justifiedGallery.js)151
-rw-r--r--library/justifiedGallery/justifiedGallery.css (renamed from library/justifiedGallery/dist/css/justifiedGallery.css)17
-rw-r--r--mod/acl.php7
-rwxr-xr-xmod/events.php31
-rw-r--r--mod/home.php14
-rw-r--r--mod/item.php2
-rw-r--r--mod/photos.php8
-rw-r--r--mod/post.php2
-rw-r--r--mod/pubsites.php7
-rw-r--r--mod/rate.php24
-rw-r--r--mod/ratings.php19
-rw-r--r--mod/ratingsearch.php19
-rw-r--r--util/zotsh/README.txt109
-rw-r--r--util/zotsh/easywebdav/LICENSE5
-rw-r--r--util/zotsh/easywebdav/__init__.py5
-rw-r--r--util/zotsh/easywebdav/__init__.pycbin0 -> 455 bytes
-rw-r--r--util/zotsh/easywebdav/__version__.py1
-rw-r--r--util/zotsh/easywebdav/__version__.pycbin0 -> 173 bytes
-rw-r--r--util/zotsh/easywebdav/client.py202
-rw-r--r--util/zotsh/easywebdav/client.pycbin0 -> 8846 bytes
-rwxr-xr-xutil/zotsh/zotsh.py324
-rw-r--r--version.inc2
-rw-r--r--view/js/main.js2
-rw-r--r--view/pdl/mod_ratings.pdl1
-rw-r--r--view/php/theme_init.php4
-rw-r--r--view/theme/redbasic/css/style.css2
-rwxr-xr-xview/tpl/event.tpl1
-rw-r--r--view/tpl/prep.tpl5
-rw-r--r--view/tpl/rating_form.tpl2
41 files changed, 910 insertions, 159 deletions
diff --git a/boot.php b/boot.php
index f632931b6..7e3a2a6d4 100755
--- a/boot.php
+++ b/boot.php
@@ -82,9 +82,8 @@ $DIRECTORY_FALLBACK_SERVERS = array(
'https://zothub.com',
'https://zotid.net',
'https://red.zottel.red',
- 'https://red.pixelbits.de',
+ 'https://redmatrix.info',
'https://my.federated.social',
- 'https://whogotzot.com',
'https://redmatrix.nl'
);
diff --git a/doc/credits.bb b/doc/credits.bb
index d13b99bdd..79055bc29 100644
--- a/doc/credits.bb
+++ b/doc/credits.bb
@@ -50,6 +50,7 @@ Charles
Tony Baldwin
Hauke Zuehl
Keith Fernie
+Anne Walk
toclimb
Daniel Frank
Matthew Exon
diff --git a/doc/database.bb b/doc/database.bb
index 037e9936a..7be6735c9 100644
--- a/doc/database.bb
+++ b/doc/database.bb
@@ -1,36 +1,37 @@
+[h2]Database Tables[/h2]
[table]
[tr][th]Table[/th][th]Description[/th][/tr]
-[tr][td][zrl=[baseurl]/help/db_abook]abook[/zrl][/td][td]contact table[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_abook]abook[/zrl][/td][td]connections of local channels[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_account]account[/zrl][/td][td]service provider account[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_addon]addon[/zrl][/td][td]registered plugins[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_app]app[/zrl][/td][td]peronal app data[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_app]app[/zrl][/td][td]personal app data[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_attach]attach[/zrl][/td][td]file attachments[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_auth_codes]auth_codes[/zrl][/td][td]OAuth usage[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_cache]cache[/zrl][/td][td]OEmbed cache[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_channel]channel[/zrl][/td][td][/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_channel]channel[/zrl][/td][td]local channels[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_chat]chat[/zrl][/td][td]chat room content[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_chatpresence]chatpresence[/zrl][/td][td]channel presence information for chat[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_chatroom]chatroom[/zrl][/td][td] data for the actual chat room[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_chatroom]chatroom[/zrl][/td][td]data for the actual chat room[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_clients]clients[/zrl][/td][td]OAuth usage[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_config]config[/zrl][/td][td]main configuration storage[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_conv]conv[/zrl][/td][td]Diaspora private messages[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_conv]conv[/zrl][/td][td]Diaspora private messages meta conversation structure[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_event]event[/zrl][/td][td]Events[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_fcontact]fcontact[/zrl][/td][td]friend suggestion stuff[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_ffinder]ffinder[/zrl][/td][td]friend suggestion stuff[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_fcontact]fcontact[/zrl][/td][td]friend suggestion stuff (obsolete)[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_ffinder]ffinder[/zrl][/td][td]friend suggestion stuff (obsolete)[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_fserver]fserver[/zrl][/td][td]obsolete[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_fsuggest]fsuggest[/zrl][/td][td]friend suggestion stuff[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_group_member]group_member[/zrl][/td][td]privacy groups[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_groups]groups[/zrl][/td][td]privacy groups[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_fsuggest]fsuggest[/zrl][/td][td]friend suggestion stuff (unused)[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_group_member]group_member[/zrl][/td][td]privacy groups (collections), group info[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_groups]groups[/zrl][/td][td]privacy groups (collections), member info[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_hook]hook[/zrl][/td][td]plugin hook registry[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_hubloc]hubloc[/zrl][/td][td]Red location storage, ties a location to an xchan[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_issue]issue[/zrl][/td][td][/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_item]item[/zrl][/td][td]posts[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_hubloc]hubloc[/zrl][/td][td]Red location storage, ties a hub location to an xchan[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_issue]issue[/zrl][/td][td]future bug/issue database[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_item]item[/zrl][/td][td]all posts and webpages[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_item_id]item_id[/zrl][/td][td]other identifiers on other services for posts[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_likes]likes[/zrl][/td][td]likes of 'things'[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_mail]mail[/zrl][/td][td]private messages[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_manage]manage[/zrl][/td][td]may be unused in Red, table of accounts that can "su" each other[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_menu]menu[/zrl][/td][td]channel menu data[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_menu_item]menu_item[/zrl][/td][td]items uses by channel menus[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_menu]menu[/zrl][/td][td]webpage menu data[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_menu_item]menu_item[/zrl][/td][td]entries for webpage menus[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_notify]notify[/zrl][/td][td]notifications[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_obj]obj[/zrl][/td][td]object data for things (x has y)[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_outq]outq[/zrl][/td][td]Red output queue[/td][/tr]
@@ -49,7 +50,7 @@
[tr][td][zrl=[baseurl]/help/db_site]site[/zrl][/td][td]site table to find directory peers[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_source]source[/zrl][/td][td]channel sources data[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_spam]spam[/zrl][/td][td]unfinished[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_sys_perms]sys_perms[/zrl][/td][td]extensible permissions for the sys channel[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_sys_perms]sys_perms[/zrl][/td][td]extensible permissions for OAuth[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_term]term[/zrl][/td][td]item taxonomy (categories, tags, etc.) table[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_tokens]tokens[/zrl][/td][td]OAuth usage[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_updates]updates[/zrl][/td][td]directory sync updates[/td][/tr]
@@ -58,8 +59,8 @@
[tr][td][zrl=[baseurl]/help/db_xchan]xchan[/zrl][/td][td]list of known channels in the universe[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_xchat]xchat[/zrl][/td][td]bookmarked chat rooms[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_xconfig]xconfig[/zrl][/td][td]as pconfig but for channels with no local account[/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_xign]xign[/zrl][/td][td][/td][/tr]
-[tr][td][zrl=[baseurl]/help/db_xlink]xlink[/zrl][/td][td]"friends of friends" linkages derived from poco[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_xign]xign[/zrl][/td][td]channels ignored by friend suggestions[/td][/tr]
+[tr][td][zrl=[baseurl]/help/db_xlink]xlink[/zrl][/td][td]"friends of friends" linkages derived from poco, also ratings storage[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_xprof]xprof[/zrl][/td][td]if this hub is a directory server, contains basic public profile info of everybody in the network[/td][/tr]
[tr][td][zrl=[baseurl]/help/db_xtag]xtag[/zrl][/td][td]if this hub is a directory server, contains tags or interests of everybody in the network[/td][/tr]
[/table]
diff --git a/doc/external-resource-links.bb b/doc/external-resource-links.bb
index ca1d6f55e..2e6df63aa 100644
--- a/doc/external-resource-links.bb
+++ b/doc/external-resource-links.bb
@@ -8,16 +8,11 @@
[*][url=https://github.com/tonybaldwin/redmatrixthemes/]nubasic[/url]
[b]Third-Party Addons[/b]
-[*][url=http://gitweb.whogotzot.com/red-addons-extra/tree]Additional RedMatrix addons[/url]
[*][url=https://abcentric.net/git/abcjsplugin.git]ABCjs integration - display scores in posts (WIP)[/url]
-[*][url=http://gitweb.whogotzot.com/extra_dir_fns/tree]Extra directory functions[/url]
[b]Related Projects[/b]
[*][url=https://addons.mozilla.org/en-US/firefox/addon/redshare/]Redshare for Firefox[/url]
[*][url=https://github.com/cvogeley/red-for-android]Red for Android[/url]
[*][url=https://github.com/zzottel/feed2red]feed2red.pl (posts Atom/RSS feeds to channel)[/url]
-[*][url=http://gitweb.whogotzot.com/red-stable/tree]Red Stable - up-to-date-but-not-bleeding-edge RedMatrix distribution[/url]
-[b]Utilities[/b]
-[*][url=http://gitweb.whogotzot.com/debian-install-script]Debian Install Script[/url]
#include doc/macros/main_footer.bb;
diff --git a/doc/html/navtreeindex10.js b/doc/html/navtreeindex10.js
new file mode 100644
index 000000000..05c5c8be0
--- /dev/null
+++ b/doc/html/navtreeindex10.js
@@ -0,0 +1,8 @@
+var NAVTREEINDEX10 =
+{
+"zot_8php.html#aeea071f17e306fe3d0c488551906bfab":[6,0,0,84,27],
+"zotfeed_8php.html":[6,0,1,152],
+"zotfeed_8php.html#a24dfc23d366e7f840cf2847d0c1c8eac":[6,0,1,152,0],
+"zping_8php.html":[6,0,1,153],
+"zping_8php.html#a4d3a6b0b8b04ed6469015823e615ee75":[6,0,1,153,0]
+};
diff --git a/include/bbcode.php b/include/bbcode.php
index 8f2b5bd38..749bc2334 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -625,6 +625,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>' ,$Text);
$Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>' ,$Text);
}
+ $Text = str_replace('</tr><br /><tr>',"</tr>\n<tr>",$Text);
$Text = str_replace('[hr]','<hr />', $Text);
// This is actually executed in prepare_body()
diff --git a/include/dir_fns.php b/include/dir_fns.php
index 8c0161ff1..5ed626b8a 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -247,7 +247,7 @@ function sync_directories($dirmode) {
logger('rating updated');
}
else {
- $z = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values( '%s', '%s', %d, '%s', '%s', 1 ) ",
+ $z = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ",
dbesc($rr['channel']),
dbesc($rr['target']),
intval($rr['rating']),
diff --git a/include/socgraph.php b/include/socgraph.php
index 13957e814..59830ef1b 100644
--- a/include/socgraph.php
+++ b/include/socgraph.php
@@ -185,29 +185,6 @@ function poco_load($xchan = '',$url = null) {
$total ++;
-
- $r = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 0 limit 1",
- dbesc($xchan),
- dbesc($hash)
- );
-
- if(! $r) {
- q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', 0 ) ",
- dbesc($xchan),
- dbesc($hash),
- intval($rating),
- dbesc($rating_text),
- dbesc(datetime_convert())
- );
- }
- else {
- q("update xlink set xlink_updated = '%s', xlink_rating = %d, xlink_rating_text = '%s' where xlink_id = %d",
- dbesc(datetime_convert()),
- intval($rating),
- dbesc($rating_text),
- intval($r[0]['xlink_id'])
- );
- }
}
logger("poco_load: loaded $total entries",LOGGER_DEBUG);
diff --git a/include/widgets.php b/include/widgets.php
index d457db07d..fbbc74224 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -962,4 +962,11 @@ function widget_rating($arr) {
return $o;
+}
+
+// used by site ratings pages to provide a return link
+function widget_pubsites() {
+ if(get_app()->poi)
+ return;
+ return '<div class="widget"><ul class="nav nav-pills"><li><a href="pubsites">' . t('Public Hubs') . '</a></li></ul></div>';
} \ No newline at end of file
diff --git a/include/zot.php b/include/zot.php
index cbe0c9303..852376c4b 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -2447,7 +2447,7 @@ function import_site($arr,$pubkey) {
}
$directory_url = htmlspecialchars($arr['directory_url'],ENT_COMPAT,'UTF-8',false);
- $url = htmlspecialchars($arr['url'],ENT_COMPAT,'UTF-8',false);
+ $url = htmlspecialchars(strtolower($arr['url']),ENT_COMPAT,'UTF-8',false);
$sellpage = htmlspecialchars($arr['sellpage'],ENT_COMPAT,'UTF-8',false);
$site_location = htmlspecialchars($arr['location'],ENT_COMPAT,'UTF-8',false);
$site_realm = htmlspecialchars($arr['realm'],ENT_COMPAT,'UTF-8',false);
diff --git a/library/justifiedGallery/dist/css/justifiedGallery.min.css b/library/justifiedGallery/dist/css/justifiedGallery.min.css
deleted file mode 100644
index f59d7c7c1..000000000
--- a/library/justifiedGallery/dist/css/justifiedGallery.min.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Justified Gallery - v3.2.0
- * http://miromannino.com/projects/justified-gallery/
- * Copyright (c) 2014 Miro Mannino
- * Licensed under the MIT license.
- */
-@-webkit-keyframes justified-gallery-show-caption-animation{from{opacity:0}to{opacity:.7}}@-moz-keyframes justified-gallery-show-caption-animation{from{opacity:0}to{opacity:.7}}@-o-keyframes justified-gallery-show-caption-animation{from{opacity:0}to{opacity:.7}}@keyframes justified-gallery-show-caption-animation{from{opacity:0}to{opacity:.7}}@-webkit-keyframes justified-gallery-show-entry-animation{from{opacity:0}to{opacity:1}}@-moz-keyframes justified-gallery-show-entry-animation{from{opacity:0}to{opacity:1}}@-o-keyframes justified-gallery-show-entry-animation{from{opacity:0}to{opacity:1}}@keyframes justified-gallery-show-entry-animation{from{opacity:0}to{opacity:1}}.justified-gallery{width:100%;position:relative;overflow:hidden}.justified-gallery>a,.justified-gallery>div{position:absolute;display:inline-block;overflow:hidden;opacity:0;filter:alpha(opacity=0)}.justified-gallery>a>img,.justified-gallery>div>img{position:absolute;top:50%;left:50%;margin:0;padding:0;border:0}.justified-gallery>a>.caption,.justified-gallery>div>.caption{display:none;position:absolute;bottom:0;padding:5px;background-color:#000;left:0;right:0;margin:0;color:#fff;font-size:12px;font-weight:300;font-family:sans-serif}.justified-gallery>a>.caption.caption-visible,.justified-gallery>div>.caption.caption-visible{display:initial;opacity:.7;filter:"alpha(opacity=70)";-webkit-animation:justified-gallery-show-caption-animation 500ms 0 ease;-moz-animation:justified-gallery-show-caption-animation 500ms 0 ease;-ms-animation:justified-gallery-show-caption-animation 500ms 0 ease}.justified-gallery>.entry-visible{opacity:1;filter:alpha(opacity=100);-webkit-animation:justified-gallery-show-entry-animation 300ms 0 ease;-moz-animation:justified-gallery-show-entry-animation 300ms 0 ease;-ms-animation:justified-gallery-show-entry-animation 300ms 0 ease}.justified-gallery>.spinner{position:absolute;bottom:0;margin-left:-24px;padding:10px 0;left:50%;opacity:initial;filter:initial;overflow:initial}.justified-gallery>.spinner>span{display:inline-block;opacity:0;filter:alpha(opacity=0);width:8px;height:8px;margin:0 4px;background-color:#000;border-top-left-radius:6px;border-top-right-radius:6px;border-bottom-right-radius:6px;border-bottom-left-radius:6px} \ No newline at end of file
diff --git a/library/justifiedGallery/dist/js/jquery.justifiedGallery.min.js b/library/justifiedGallery/dist/js/jquery.justifiedGallery.min.js
deleted file mode 100644
index 2b4584466..000000000
--- a/library/justifiedGallery/dist/js/jquery.justifiedGallery.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Justified Gallery - v3.2.0
- * http://miromannino.com/projects/justified-gallery/
- * Copyright (c) 2014 Miro Mannino
- * Licensed under the MIT license.
- */
-!function(a){a.fn.justifiedGallery=function(b){function c(a,b,c){var d;return d=a>b?a:b,100>=d?c.settings.sizeRangeSuffixes.lt100:240>=d?c.settings.sizeRangeSuffixes.lt240:320>=d?c.settings.sizeRangeSuffixes.lt320:500>=d?c.settings.sizeRangeSuffixes.lt500:640>=d?c.settings.sizeRangeSuffixes.lt640:c.settings.sizeRangeSuffixes.lt1024}function d(b){var c=a(b.currentTarget).find(".caption");b.data.settings.cssAnimation?c.addClass("caption-visible").removeClass("caption-hidden"):c.stop().fadeTo(b.data.settings.captionSettings.animationDuration,b.data.settings.captionSettings.visibleOpacity)}function e(b){var c=a(b.currentTarget).find(".caption");b.data.settings.cssAnimation?c.removeClass("caption-visible").removeClass("caption-hidden"):c.stop().fadeTo(b.data.settings.captionSettings.animationDuration,b.data.settings.captionSettings.nonVisibleOpacity)}function f(b,f,g,h,i,j,k){var l=b.find("img");l.css("width",h),l.css("height",i),l.css("margin-left",-h/2),l.css("margin-top",-i/2),b.width(h),b.height(j),b.css("top",g),b.css("left",f);var m=l.attr("src"),n=m.replace(k.settings.extension,"").replace(k.usedSizeRangeRegExp,"")+c(h,i,k)+m.match(k.settings.extension)[0];l.one("error",function(){l.attr("src",l.data("jg.originalSrc"))});var o=function(){m!==n&&l.attr("src",n)};k.settings.cssAnimation?(b.addClass("entry-visible"),o()):b.stop().fadeTo(k.settings.imagesAnimationDuration,1,o);var p=b.data("jg.captionMouseEvents");if(k.settings.captions===!0){var q=b.find(".caption");if(0===q.length){var r=l.attr("alt");"undefined"==typeof r&&(r=b.attr("title")),"undefined"!=typeof r&&(q=a('<div class="caption">'+r+"</div>"),b.append(q))}0!==q.length&&(k.settings.cssAnimation||q.stop().fadeTo(k.settings.imagesAnimationDuration,k.settings.captionSettings.nonVisibleOpacity),"undefined"==typeof p&&(p={mouseenter:d,mouseleave:e},b.on("mouseenter",void 0,k,p.mouseenter),b.on("mouseleave",void 0,k,p.mouseleave),b.data("jg.captionMouseEvents",p)))}else"undefined"!=typeof p&&(b.off("mouseenter",void 0,k,p.mouseenter),b.off("mouseleave",void 0,k,p.mouseleave),b.removeData("jg.captionMouseEvents"))}function g(a,b){var c,d,e,f,g,h,i=!0,j=0,k=a.galleryWidth-(a.buildingRow.entriesBuff.length-1)*a.settings.margins,l=k/a.buildingRow.aspectRatio,m=a.buildingRow.width/k>a.settings.justifyThreshold;if(b&&"hide"===a.settings.lastRow&&!m){for(c=0;c<a.buildingRow.entriesBuff.length;c++)d=a.buildingRow.entriesBuff[c],a.settings.cssAnimation?d.removeClass("entry-visible"):d.stop().fadeTo(0,0);return-1}for(b&&"nojustify"===a.settings.lastRow&&!m&&(i=!1),c=0;c<a.buildingRow.entriesBuff.length;c++)e=a.buildingRow.entriesBuff[c].find("img"),f=e.data("jg.imgw")/e.data("jg.imgh"),i?(g=l*f,h=l):(g=a.settings.rowHeight*f,h=a.settings.rowHeight),e.data("jg.imgw",Math.ceil(g)),e.data("jg.imgh",Math.ceil(h)),(0===c||j>h)&&(j=h);return a.settings.fixedHeight&&j>a.settings.rowHeight&&(j=a.settings.rowHeight),j}function h(a){a.lastAnalyzedIndex=-1,a.buildingRow.entriesBuff=[],a.buildingRow.aspectRatio=0,a.buildingRow.width=0,a.offY=0,a.firstRowFlushed=!1}function i(a,b){var c,d,e,h=0;if(e=g(a,b),b&&"hide"===a.settings.lastRow&&-1===e)return a.buildingRow.entriesBuff=[],a.buildingRow.aspectRatio=0,void(a.buildingRow.width=0);a.settings.maxRowHeight>0&&a.settings.maxRowHeight<e?e=a.settings.maxRowHeight:0===a.settings.maxRowHeight&&1.5*a.settings.rowHeight<e&&(e=1.5*a.settings.rowHeight);for(var i=0;i<a.buildingRow.entriesBuff.length;i++)c=a.buildingRow.entriesBuff[i],d=c.find("img"),f(c,h,a.offY,d.data("jg.imgw"),d.data("jg.imgh"),e,a),h+=d.data("jg.imgw")+a.settings.margins;a.$gallery.height(a.offY+e+(a.spinner.active?a.spinner.$el.innerHeight():0)),b||(a.offY+=e+a.settings.margins,a.buildingRow.entriesBuff=[],a.buildingRow.aspectRatio=0,a.buildingRow.width=0,a.firstRowFlushed=!0,a.$gallery.trigger("jg.rowflush"))}function j(a){a.checkWidthIntervalId=setInterval(function(){var b=parseInt(a.$gallery.width(),10);a.galleryWidth!==b&&(a.galleryWidth=b,h(a),n(a,!0))},a.settings.refreshTime)}function k(a){clearInterval(a.intervalId),a.intervalId=setInterval(function(){a.phase<a.$points.length?a.$points.eq(a.phase).fadeTo(a.timeslot,1):a.$points.eq(a.phase-a.$points.length).fadeTo(a.timeslot,0),a.phase=(a.phase+1)%(2*a.$points.length)},a.timeslot)}function l(a){clearInterval(a.intervalId),a.intervalId=null}function m(a){a.yield.flushed=0,null!==a.imgAnalyzerTimeout&&clearTimeout(a.imgAnalyzerTimeout)}function n(a,b){m(a),a.imgAnalyzerTimeout=setTimeout(function(){o(a,b)},.001),o(a,b)}function o(b,c){for(var d,e=b.lastAnalyzedIndex+1;e<b.entries.length;e++){var f=a(b.entries[e]),g=f.find("img");if(g.data("jg.loaded")===!0){d=b.firstRowFlushed&&e>=b.entries.length-1;var h=b.galleryWidth-(b.buildingRow.entriesBuff.length-1)*b.settings.margins,j=g.data("jg.imgw")/g.data("jg.imgh");if(h/(b.buildingRow.aspectRatio+j)<b.settings.rowHeight&&(i(b,d),++b.yield.flushed>=b.yield.every))return void n(b,c);b.buildingRow.entriesBuff.push(f),b.buildingRow.aspectRatio+=j,b.buildingRow.width+=j*b.settings.rowHeight,b.lastAnalyzedIndex=e}else if("error"!==g.data("jg.loaded"))return}b.buildingRow.entriesBuff.length>0&&i(b,b.firstRowFlushed),b.spinner.active&&(b.spinner.active=!1,b.$gallery.height(b.$gallery.height()-b.spinner.$el.innerHeight()),b.spinner.$el.detach(),l(b.spinner)),m(b),b.$gallery.trigger(c?"jg.resize":"jg.complete")}function p(a){function b(b){if("string"!=typeof a.settings.sizeRangeSuffixes[b])throw"sizeRangeSuffixes."+b+" must be a string"}function c(a,b){if("string"==typeof a[b]){if(a[b]=parseFloat(a[b],10),isNaN(a[b]))throw"invalid number for "+b}else{if("number"!=typeof a[b])throw b+" must be a number";if(isNaN(a[b]))throw"invalid number for "+b}}if("object"!=typeof a.settings.sizeRangeSuffixes)throw"sizeRangeSuffixes must be defined and must be an object";if(b("lt100"),b("lt240"),b("lt320"),b("lt500"),b("lt640"),b("lt1024"),c(a.settings,"rowHeight"),c(a.settings,"maxRowHeight"),c(a.settings,"margins"),"nojustify"!==a.settings.lastRow&&"justify"!==a.settings.lastRow&&"hide"!==a.settings.lastRow)throw'lastRow must be "nojustify", "justify" or "hide"';if(c(a.settings,"justifyThreshold"),a.settings.justifyThreshold<0||a.settings.justifyThreshold>1)throw"justifyThreshold must be in the interval [0,1]";if("boolean"!=typeof a.settings.cssAnimation)throw"cssAnimation must be a boolean";if(c(a.settings.captionSettings,"animationDuration"),c(a.settings,"imagesAnimationDuration"),c(a.settings.captionSettings,"visibleOpacity"),a.settings.captionSettings.visibleOpacity<0||a.settings.captionSettings.visibleOpacity>1)throw"captionSettings.visibleOpacity must be in the interval [0, 1]";if(c(a.settings.captionSettings,"nonVisibleOpacity"),a.settings.captionSettings.visibleOpacity<0||a.settings.captionSettings.visibleOpacity>1)throw"captionSettings.nonVisibleOpacity must be in the interval [0, 1]";if("boolean"!=typeof a.settings.fixedHeight)throw"fixedHeight must be a boolean";if("boolean"!=typeof a.settings.captions)throw"captions must be a boolean";if(c(a.settings,"refreshTime"),"boolean"!=typeof a.settings.randomize)throw"randomize must be a boolean"}var q={sizeRangeSuffixes:{lt100:"_t",lt240:"_m",lt320:"_n",lt500:"",lt640:"_z",lt1024:"_b"},rowHeight:120,maxRowHeight:0,margins:1,lastRow:"nojustify",justifyThreshold:.75,fixedHeight:!1,captions:!0,cssAnimation:!1,imagesAnimationDuration:300,captionSettings:{animationDuration:500,visibleOpacity:.7,nonVisibleOpacity:0},rel:null,target:null,extension:/\.[^.]+$/,refreshTime:250,randomize:!1};return this.each(function(c,d){var e=a(d);e.addClass("justified-gallery");var f=e.data("jg.context");if("undefined"==typeof f){if("undefined"!=typeof b&&null!==b&&"object"!=typeof b)throw"The argument must be an object";var g=a('<div class="spinner"><span></span><span></span><span></span></div>');f={settings:a.extend({},q,b),imgAnalyzerTimeout:null,entries:null,buildingRow:{entriesBuff:[],width:0,aspectRatio:0},lastAnalyzedIndex:-1,firstRowFlushed:!1,"yield":{every:2,flushed:0},offY:0,spinner:{active:!1,phase:0,timeslot:150,$el:g,$points:g.find("span"),intervalId:null},checkWidthIntervalId:null,galleryWidth:e.width(),$gallery:e},e.data("jg.context",f)}else"norewind"===b||(f.settings=a.extend({},f.settings,b),h(f));if(p(f),f.entries=e.find("> a, > div").toArray(),0!==f.entries.length){f.settings.randomize&&(f.entries.sort(function(){return 2*Math.random()-1}),a.each(f.entries,function(){a(this).appendTo(e)})),f.usedSizeRangeRegExp=new RegExp("("+f.settings.sizeRangeSuffixes.lt100+"|"+f.settings.sizeRangeSuffixes.lt240+"|"+f.settings.sizeRangeSuffixes.lt320+"|"+f.settings.sizeRangeSuffixes.lt500+"|"+f.settings.sizeRangeSuffixes.lt640+"|"+f.settings.sizeRangeSuffixes.lt1024+")$"),f.settings.maxRowHeight>0&&f.settings.maxRowHeight<f.settings.rowHeight&&(f.settings.maxRowHeight=f.settings.rowHeight);var i=!1;a.each(f.entries,function(b,c){var d=a(c),g=d.find("img");if(g.data("jg.loaded")!==!0){g.data("jg.loaded",!1),i=!0,f.spinner.active===!1&&(f.spinner.active=!0,e.append(f.spinner.$el),e.height(f.offY+f.spinner.$el.innerHeight()),k(f.spinner)),null!==f.settings.rel&&d.attr("rel",f.settings.rel),null!==f.settings.target&&d.attr("target",f.settings.target);var h="undefined"!=typeof g.data("safe-src")?g.data("safe-src"):g.attr("src");g.data("jg.originalSrc",h),g.attr("src",h);var j=new Image,l=a(j);l.one("load",function(){g.off("load error"),g.data("jg.imgw",j.width),g.data("jg.imgh",j.height),g.data("jg.loaded",!0),n(f,!1)}),l.one("error",function(){g.off("load error"),g.data("jg.loaded","error"),n(f,!1)}),j.src=h}}),i||n(f,!1),j(f)}})}}(jQuery); \ No newline at end of file
diff --git a/library/justifiedGallery/dist/js/jquery.justifiedGallery.js b/library/justifiedGallery/jquery.justifiedGallery.js
index 7754ae437..21679c96d 100644
--- a/library/justifiedGallery/dist/js/jquery.justifiedGallery.js
+++ b/library/justifiedGallery/jquery.justifiedGallery.js
@@ -1,7 +1,7 @@
-/*
- * Justified Gallery - v3.4.0
- * http://miromannino.com/projects/justified-gallery/
- * Copyright (c) 2014 Miro Mannino
+/*!
+ * Justified Gallery - v3.5.4
+ * http://miromannino.github.io/Justified-Gallery/
+ * Copyright (c) 2015 Miro Mannino
* Licensed under the MIT license.
*/
(function($) {
@@ -16,34 +16,37 @@
// Default options
var defaults = {
sizeRangeSuffixes : {
- 'lt100': '_t',
- 'lt240': '_m',
- 'lt320': '_n',
- 'lt500': '',
- 'lt640': '_z',
- 'lt1024': '_b'
+ 'lt100': '', // e.g. Flickr uses '_t'
+ 'lt240': '', // e.g. Flickr uses '_m'
+ 'lt320': '', // e.g. Flickr uses '_n'
+ 'lt500': '', // e.g. Flickr uses ''
+ 'lt640': '', // e.g. Flickr uses '_z'
+ 'lt1024': '', // e.g. Flickr uses '_b'
},
rowHeight : 120,
- maxRowHeight : 0, //negative value = no limits, 0 = 1.5 * rowHeight
+ maxRowHeight : 0, // negative value = no limits, 0 = 1.5 * rowHeight
margins : 1,
+ border: -1, // negative value = same as margins, 0 = disabled
+
lastRow : 'nojustify', // or can be 'justify' or 'hide'
justifyThreshold: 0.75, /* if row width / available space > 0.75 it will be always justified
- (i.e. lastRow setting is not considered) */
+ (i.e. lastRow setting is not considered) */
fixedHeight : false,
waitThumbnailsLoad : true,
captions : true,
cssAnimation: false,
- imagesAnimationDuration : 500, //ignored with css animations
- captionSettings : { //ignored with css animations
+ imagesAnimationDuration : 500, // ignored with css animations
+ captionSettings : { // ignored with css animations
animationDuration : 500,
visibleOpacity : 0.7,
nonVisibleOpacity : 0.0
},
- rel : null, //rewrite the rel of each analyzed links
- target : null, //rewrite the target of all links
+ rel : null, // rewrite the rel of each analyzed links
+ target : null, // rewrite the target of all links
extension : /\.[^.\\/]+$/,
refreshTime : 100,
- randomize : false
+ randomize : false,
+ ignoreElement: null // a comma seperated list of div element selectors to be ignored e.g.: '.someClass, #someId'
};
function getSuffix(width, height, context) {
@@ -136,12 +139,20 @@
}
}
+ function imgFromEntry($entry) {
+ var $img = $entry.find('> img');
+ if ($img.length === 0) $img = $entry.find('> a > img');
+ return $img;
+ }
+
function displayEntry($entry, x, y, imgWidth, imgHeight, rowHeight, context) {
- var $image = $entry.find('img');
+ var $image = imgFromEntry($entry);
$image.css('width', imgWidth);
$image.css('height', imgHeight);
- $image.css('margin-left', - imgWidth / 2);
- $image.css('margin-top', - imgHeight / 2);
+ //if ($entry.get(0) === $image.parent().get(0)) { // this creates an error in link_around_img test
+ $image.css('margin-left', - imgWidth / 2);
+ $image.css('margin-top', - imgHeight / 2);
+ //}
$entry.width(imgWidth);
$entry.height(rowHeight);
$entry.css('top', y);
@@ -165,9 +176,9 @@
}
if ($image.data('jg.loaded') === 'skipped') {
- $image.one('load', function() {
+ onImageEvent(imageSrc, function() {
showImg($entry, loadNewImage, context);
- $image.data('jg.loaded', 'loaded');
+ $image.data('jg.loaded', true);
});
} else {
showImg($entry, loadNewImage, context);
@@ -216,8 +227,8 @@
var settings = context.settings;
var i, $entry, $image, imgAspectRatio, newImgW, newImgH, justify = true;
var minHeight = 0;
- var availableWidth = context.galleryWidth - (
- (context.buildingRow.entriesBuff.length - 1) * settings.margins);
+ var availableWidth = context.galleryWidth - 2 * context.border - (
+ (context.buildingRow.entriesBuff.length - 1) * settings.margins);
var rowHeight = availableWidth / context.buildingRow.aspectRatio;
var justificable = context.buildingRow.width / availableWidth > settings.justifyThreshold;
@@ -237,11 +248,12 @@
if (isLastRow && !justificable && settings.lastRow === 'nojustify') justify = false;
for (i = 0; i < context.buildingRow.entriesBuff.length; i++) {
- $image = context.buildingRow.entriesBuff[i].find('img');
+ $image = imgFromEntry(context.buildingRow.entriesBuff[i]);
imgAspectRatio = $image.data('jg.imgw') / $image.data('jg.imgh');
if (justify) {
- newImgW = rowHeight * imgAspectRatio;
+ newImgW = (i === context.buildingRow.entriesBuff.length - 1) ? availableWidth
+ : rowHeight * imgAspectRatio;
newImgH = rowHeight;
/* With fixedHeight the newImgH must be greater than rowHeight.
@@ -252,13 +264,15 @@
newImgW = settings.rowHeight * imgAspectRatio;
newImgH = settings.rowHeight;
}*/
+
} else {
newImgW = settings.rowHeight * imgAspectRatio;
newImgH = settings.rowHeight;
}
- $image.data('jg.imgw', Math.ceil(newImgW));
- $image.data('jg.imgh', Math.ceil(newImgH));
+ availableWidth -= Math.round(newImgW);
+ $image.data('jg.jimgw', Math.round(newImgW));
+ $image.data('jg.jimgh', Math.ceil(newImgH));
if (i === 0 || minHeight > newImgH) minHeight = newImgH;
}
@@ -273,12 +287,12 @@
context.buildingRow.entriesBuff = [];
context.buildingRow.aspectRatio = 0;
context.buildingRow.width = 0;
- context.offY = 0;
+ context.offY = context.border;
}
function flushRow(context, isLastRow) {
var settings = context.settings;
- var $entry, $image, minHeight, buildingRowRes, offX = 0;
+ var $entry, $image, minHeight, buildingRowRes, offX = context.border;
//DEBUG// console.log('flush (isLastRow: ' + isLastRow + ')');
@@ -298,14 +312,14 @@
for (var i = 0; i < context.buildingRow.entriesBuff.length; i++) {
$entry = context.buildingRow.entriesBuff[i];
- $image = $entry.find('img');
- displayEntry($entry, offX, context.offY, $image.data('jg.imgw'),
- $image.data('jg.imgh'), minHeight, context);
- offX += $image.data('jg.imgw') + settings.margins;
+ $image = imgFromEntry($entry);
+ displayEntry($entry, offX, context.offY, $image.data('jg.jimgw'),
+ $image.data('jg.jimgh'), minHeight, context);
+ offX += $image.data('jg.jimgw') + settings.margins;
}
//Gallery Height
- context.$gallery.height(context.offY + minHeight +
+ context.$gallery.height(context.offY + minHeight + context.border +
(context.spinner.active ? context.spinner.$el.innerHeight() : 0)
);
@@ -375,7 +389,7 @@
console.log('images status: ');
for (var i = 0; i < context.entries.length; i++) {
var $entry = $(context.entries[i]);
- var $image = $entry.find('img');
+ var $image = imgFromEntry($entry);
console.log(i + ' (alt: ' + $image.attr('alt') + 'loaded: ' + $image.data('jg.loaded') + ')');
}*/
@@ -385,12 +399,12 @@
for (var i = context.lastAnalyzedIndex + 1; i < context.entries.length; i++) {
var $entry = $(context.entries[i]);
- var $image = $entry.find('img');
+ var $image = imgFromEntry($entry);
if ($image.data('jg.loaded') === true || $image.data('jg.loaded') === 'skipped') {
isLastRow = i >= context.entries.length - 1;
- var availableWidth = context.galleryWidth - (
+ var availableWidth = context.galleryWidth - 2 * context.border - (
(context.buildingRow.entriesBuff.length - 1) * settings.margins);
var imgAspectRatio = $image.data('jg.imgw') / $image.data('jg.imgh');
if (availableWidth / (context.buildingRow.aspectRatio + imgAspectRatio) < settings.rowHeight) {
@@ -475,6 +489,7 @@
}
checkOrConvertNumber(settings, 'margins');
+ checkOrConvertNumber(settings, 'border');
if (settings.lastRow !== 'nojustify' &&
settings.lastRow !== 'justify' &&
@@ -516,6 +531,30 @@
}
+ function onImageEvent(imageSrc, onLoad, onError) {
+ if (!onLoad && !onError) {
+ return;
+ }
+ /* Check if the image is loaded or not using another image object.
+ We cannot use the 'complete' image property, because some browsers,
+ with a 404 set complete = true */
+ var memImage = new Image();
+ var $memImage = $(memImage);
+ if (onLoad) {
+ $memImage.one('load', function () {
+ $memImage.off('load error');
+ onLoad(memImage);
+ });
+ }
+ if (onError) {
+ $memImage.one('error', function() {
+ $memImage.off('load error');
+ onError(memImage);
+ });
+ }
+ memImage.src = imageSrc;
+ }
+
return this.each(function (index, gallery) {
var $gallery = $(gallery);
@@ -529,10 +568,15 @@
// Spinner init
var $spinner = $('<div class="spinner"><span></span><span></span><span></span></div>');
+ var extendedSettings = $.extend({}, defaults, arg);
+ var border = extendedSettings.border >= 0 ? extendedSettings.border : extendedSettings.margins;
+
+ var ignoreElement = extendedSettings.ignoreElement;
+
//Context init
context = {
- settings : $.extend({}, defaults, arg),
+ settings : extendedSettings,
imgAnalyzerTimeout : null,
entries : null,
buildingRow : {
@@ -546,7 +590,8 @@
* must be greater than 1, else the analyzeImages will loop */
flushed : 0 //flushed rows without a yield
},
- offY : 0,
+ border : border,
+ offY : border,
spinner : {
active : false,
phase : 0,
@@ -556,7 +601,7 @@
intervalId : null
},
checkWidthIntervalId : null,
- galleryWidth : $gallery.width(),
+ galleryWidth : $gallery.width(),
$gallery : $gallery
};
@@ -571,12 +616,13 @@
// In this case we don't rewind, and analyze all the images
} else {
context.settings = $.extend({}, context.settings, arg);
+ context.border = context.settings.border >= 0 ? context.settings.border : context.settings.margins;
rewind(context);
}
checkSettings(context);
- context.entries = $gallery.find('> a, > div:not(.spinner, #page-end)').toArray();
+ context.entries = $gallery.find('> a, > div:not(.spinner, ' + ignoreElement + ')').toArray();
if (context.entries.length === 0) return;
// Randomize
@@ -588,9 +634,12 @@
}
var imagesToLoad = false;
+ var skippedImages = false;
$.each(context.entries, function (index, entry) {
var $entry = $(entry);
- var $image = $entry.find('img');
+ var $image = imgFromEntry($entry);
+
+ $entry.addClass('jg-entry');
if ($image.data('jg.loaded') !== true && $image.data('jg.loaded') !== 'skipped') {
@@ -612,6 +661,7 @@
$image.data('jg.imgw', width);
$image.data('jg.imgh', height);
$image.data('jg.loaded', 'skipped');
+ skippedImages = true;
startImgAnalyzer(context, false);
return true;
}
@@ -627,32 +677,23 @@
startLoadingSpinnerAnimation(context.spinner);
}
- /* Check if the image is loaded or not using another image object.
- We cannot use the 'complete' image property, because some browsers,
- with a 404 set complete = true */
- var loadImg = new Image();
- var $loadImg = $(loadImg);
- $loadImg.one('load', function imgLoaded () {
+ onImageEvent(imageSrc, function imgLoaded (loadImg) {
//DEBUG// console.log('img load (alt: ' + $image.attr('alt') + ')');
- $image.off('load error');
$image.data('jg.imgw', loadImg.width);
$image.data('jg.imgh', loadImg.height);
$image.data('jg.loaded', true);
startImgAnalyzer(context, false);
- });
- $loadImg.one('error', function imgLoadError () {
+ }, function imgLoadError () {
//DEBUG// console.log('img error (alt: ' + $image.attr('alt') + ')');
- $image.off('load error');
$image.data('jg.loaded', 'error');
startImgAnalyzer(context, false);
});
- loadImg.src = imageSrc;
}
});
- if (!imagesToLoad) startImgAnalyzer(context, false);
+ if (!imagesToLoad && !skippedImages) startImgAnalyzer(context, false);
checkWidth(context);
});
diff --git a/library/justifiedGallery/dist/css/justifiedGallery.css b/library/justifiedGallery/justifiedGallery.css
index 97585f3ed..3a0d55ad5 100644
--- a/library/justifiedGallery/dist/css/justifiedGallery.css
+++ b/library/justifiedGallery/justifiedGallery.css
@@ -1,7 +1,7 @@
/*!
- * Justified Gallery - v3.2.0
- * http://miromannino.com/projects/justified-gallery/
- * Copyright (c) 2014 Miro Mannino
+ * Justified Gallery - v3.5.4
+ * http://miromannino.github.io/Justified-Gallery/
+ * Copyright (c) 2015 Miro Mannino
* Licensed under the MIT license.
*/
@-webkit-keyframes justified-gallery-show-caption-animation {
@@ -83,7 +83,9 @@
/* IE8 or Earlier */
}
.justified-gallery > a > img,
-.justified-gallery > div > img {
+.justified-gallery > div > img,
+.justified-gallery > a > a > img,
+.justified-gallery > div > a > img {
position: absolute;
top: 50%;
left: 50%;
@@ -103,6 +105,7 @@
margin: 0;
color: white;
font-size: 12px;
+ font-weight: 300;
font-family: sans-serif;
}
.justified-gallery > a > .caption.caption-visible,
@@ -119,9 +122,9 @@
opacity: 1.0;
filter: alpha(opacity=100);
/* IE8 or Earlier */
- -webkit-animation: justified-gallery-show-entry-animation 300ms 0 ease;
- -moz-animation: justified-gallery-show-entry-animation 300ms 0 ease;
- -ms-animation: justified-gallery-show-entry-animation 300ms 0 ease;
+ -webkit-animation: justified-gallery-show-entry-animation 500ms 0 ease;
+ -moz-animation: justified-gallery-show-entry-animation 500ms 0 ease;
+ -ms-animation: justified-gallery-show-entry-animation 500ms 0 ease;
}
.justified-gallery > .spinner {
position: absolute;
diff --git a/mod/acl.php b/mod/acl.php
index 6ae803596..e919bb912 100644
--- a/mod/acl.php
+++ b/mod/acl.php
@@ -99,6 +99,7 @@ function acl_init(&$a){
intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED),
intval(XCHAN_FLAGS_DELETED)
);
+
}
else { // Visitors
$r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags
@@ -148,12 +149,14 @@ function acl_init(&$a){
}
}
if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_channel(),'system','taganyone'))) {
- if((! $r) && $type == 'c') {
- $r = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags
+ if((count($r) < 100) && $type == 'c') {
+ $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags
FROM xchan
WHERE not (xchan_flags & %d )>0 $sql_extra2 order by $order_extra2 xchan_name asc" ,
intval(XCHAN_FLAGS_DELETED)
);
+ if($r2)
+ $r = array_merge($r,$r2);
}
}
}
diff --git a/mod/events.php b/mod/events.php
index f209dab1d..010f1f7c4 100755
--- a/mod/events.php
+++ b/mod/events.php
@@ -273,6 +273,10 @@ function events_content(&$a) {
$mode = 'add';
$item_id = intval(argv(2));
}
+ if(argc() > 2 && argv(1) === 'drop') {
+ $mode = 'drop';
+ $event_id = argv(2);
+ }
if(argv(1) === 'new') {
$mode = 'new';
$event_id = '';
@@ -412,6 +416,8 @@ function events_content(&$a) {
$last_date = $d;
// FIXME
$edit = (($rr['item_flags'] & ITEM_WALL) ? array($a->get_baseurl().'/events/event/'.$rr['event_hash'],t('Edit event'),'','') : null);
+ $drop = array($a->get_baseurl().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
+
$title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8'));
if(! $title) {
list($title, $_trash) = explode("<br",bbcode($rr['desc']),2);
@@ -425,6 +431,7 @@ function events_content(&$a) {
'hash' => $rr['event_hash'],
'start'=> $start,
'end' => $end,
+ 'drop' => $drop,
'allDay' => false,
'title' => $title,
@@ -479,6 +486,30 @@ function events_content(&$a) {
}
+ if($mode === 'drop' && $event_id) {
+ $r = q("SELECT * FROM `event` WHERE event_hash = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+ if($r) {
+ $r = q("delete from event where event_hash = '%s' and uid = %d limit 1",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+ if($r) {
+ $r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d",
+ dbesc($event_id),
+ intval(local_channel())
+ );
+ info( t('Event removed') . EOL);
+ }
+ else {
+ notice( t('Failed to remove event' ) . EOL);
+ }
+ goaway(z_root() . '/events');
+ }
+ }
+
if($mode === 'edit' && $event_id) {
$r = q("SELECT * FROM `event` WHERE event_hash = '%s' AND `uid` = %d LIMIT 1",
dbesc($event_id),
diff --git a/mod/home.php b/mod/home.php
index db4ae9c42..6d5c7db25 100644
--- a/mod/home.php
+++ b/mod/home.php
@@ -164,9 +164,16 @@ function home_content(&$a, $update = 0, $load = false) {
}
require_once('include/identity.php');
- $sys = get_sys_channel();
- $uids = " and item.uid = " . intval($sys['channel_id']) . " ";
- $a->data['firehose'] = intval($sys['channel_id']);
+
+ if(get_config('system','site_firehose')) {
+ require_once('include/security.php');
+ $uids = " and item.uid in ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) and item_private = 0 and (item_flags & " . intval(ITEM_WALL) . " ) > 0 ";
+ }
+ else {
+ $sys = get_sys_channel();
+ $uids = " and item.uid = " . intval($sys['channel_id']) . " ";
+ $a->data['firehose'] = intval($sys['channel_id']);
+ }
$page_mode = 'list';
@@ -199,6 +206,7 @@ function home_content(&$a, $update = 0, $load = false) {
intval(ABOOK_FLAG_BLOCKED)
);
+
}
// Then fetch all the children of the parents that are on this page
diff --git a/mod/item.php b/mod/item.php
index eb823b4b0..dbee2df3b 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -644,7 +644,7 @@ function item_post(&$a) {
}
}
- $item_unseen = ((local_channel() != $profile_uid) ? 1 : 0);
+ $item_unseen = 1;
if($post_type === 'wall' || $post_type === 'wall-comment')
$item_flags = $item_flags | ITEM_WALL;
diff --git a/mod/photos.php b/mod/photos.php
index 33854dd76..8ac6ed3d7 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -977,10 +977,10 @@ function photos_content(&$a) {
if($r) {
- foreach($r as $item) {
- like_puller($a,$item,$alike,'like');
- like_puller($a,$item,$dlike,'dislike');
- }
+// foreach($r as $item) {
+// like_puller($a,$item,$alike,'like');
+// like_puller($a,$item,$dlike,'dislike');
+// }
$like_count = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid']] : '');
$like_list = ((x($alike,$link_item['mid'])) ? $alike[$link_item['mid'] . '-l'] : '');
diff --git a/mod/post.php b/mod/post.php
index c90997335..6e35632da 100644
--- a/mod/post.php
+++ b/mod/post.php
@@ -467,7 +467,7 @@ function post_post(&$a) {
* tells us we need to unencapsulate the AES-256-CBC content using the site private key
*/
- if(array_key_exists('iv',$data)) {
+ if($data && array_key_exists('iv',$data)) {
$encrypted_packet = true;
$data = crypto_unencapsulate($data,get_config('system','prvkey'));
logger('mod_zot: decrypt1: ' . $data, LOGGER_DATA);
diff --git a/mod/pubsites.php b/mod/pubsites.php
index c31bbcf97..ff3854492 100644
--- a/mod/pubsites.php
+++ b/mod/pubsites.php
@@ -22,10 +22,13 @@ function pubsites_content(&$a) {
if($ret['success']) {
$j = json_decode($ret['body'],true);
if($j) {
- $o .= '<table border="1"><tr><td>' . t('Site URL') . '</td><td>' . t('Access Type') . '</td><td>' . t('Registration Policy') . '</td><td>' . t('Location') . '</td></tr>';
+ $rate_meta = ((local_channel()) ? '<td>' . t('Rate this hub') . '</td>' : '');
+ $o .= '<table border="1"><tr><td>' . t('Site URL') . '</td><td>' . t('Access Type') . '</td><td>' . t('Registration Policy') . '</td><td>' . t('Location') . '</td><td>' . t('View hub ratings') . '</td>' . $rate_meta . '</tr>';
if($j['sites']) {
foreach($j['sites'] as $jj) {
- $o .= '<tr><td>' . '<a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" >' . $jj['url'] . '</a>' . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><td>' . $jj['location'] . '</td></tr>';
+ $host = strtolower(substr($jj['url'],strpos($jj['url'],'://')+3));
+ $rate_links = ((local_channel()) ? '<td><a href="rate?f=&target=' . $host . '" class="btn-btn-default"><i class="icon-check"></i> ' . t('Rate') . '</a></td>' : '');
+ $o .= '<tr><td>' . '<a href="'. (($jj['sellpage']) ? $jj['sellpage'] : $jj['url'] . '/register' ) . '" >' . $jj['url'] . '</a>' . '</td><td>' . $jj['access'] . '</td><td>' . $jj['register'] . '</td><td>' . $jj['location'] . '</td><td><a href="ratings/' . $host . '" class="btn-btn-default"><i class="icon-eye-open"></i> ' . t('View ratings') . '</a></td>' . $rate_links . '</tr>';
}
}
diff --git a/mod/rate.php b/mod/rate.php
index 694b88ddd..a3a36b4a9 100644
--- a/mod/rate.php
+++ b/mod/rate.php
@@ -21,6 +21,15 @@ function rate_init(&$a) {
if($r) {
$a->poi = $r[0];
}
+ else {
+ $r = q("select * from site where site_url like '%s' ",
+ dbesc('%' . $target)
+ );
+ if($r) {
+ $a->data['site'] = $r[0];
+ $a->data['site']['site_url'] = strtolower($r[0]['site_url']);
+ }
+ }
}
@@ -119,12 +128,15 @@ function rate_content(&$a) {
dbesc($channel['channel_hash']),
dbesc($a->data['target'])
);
- if($r)
+ if($r) {
$a->data['xlink'] = $r[0];
-
- $rating_val = $r[0]['xlink_rating'];
- $rating_text = $r[0]['xlink_rating_text'];
-
+ $rating_val = $r[0]['xlink_rating'];
+ $rating_text = $r[0]['xlink_rating_text'];
+ }
+ else {
+ $rating_val = 0;
+ $rating_text = '';
+ }
// if unset default to enabled
if($poco_rating === false)
@@ -142,6 +154,8 @@ function rate_content(&$a) {
$o = replace_macros(get_markup_template('rating_form.tpl'),array(
'$header' => t('Rating'),
+ '$website' => t('Website:'),
+ '$site' => (($a->data['site']) ? '<a href="' . $a->data['site']['site_url'] . '" >' . $a->data['site']['site_url'] . '</a>' : ''),
'target' => $a->data['target'],
'$tgt_name' => (($a->poi && $a->poi['xchan_name']) ? $a->poi['xchan_name'] : sprintf( t('Remote Channel [%s] (not yet known on this site)'), substr($a->data['target'],0,16))),
'$lbl_rating' => t('Rating (this information is public)'),
diff --git a/mod/ratings.php b/mod/ratings.php
index fe7865778..dc98eb238 100644
--- a/mod/ratings.php
+++ b/mod/ratings.php
@@ -35,7 +35,7 @@ function ratings_init(&$a) {
$results = false;
- $x = z_fetch_url($url . '/ratingsearch/' . $hash);
+ $x = z_fetch_url($url . '/ratingsearch/' . urlencode($hash));
if($x['success'])
@@ -48,8 +48,9 @@ function ratings_init(&$a) {
return;
}
- $a->poi = $results['target'];
-
+ if(array_key_exists('xchan_hash',$results['target']))
+ $a->poi = $results['target'];
+
$friends = array();
$others = array();
@@ -62,9 +63,9 @@ function ratings_init(&$a) {
}
}
- $a->data = array_merge($friends,$others);
+ $a->data = array('target' => $results['target'], 'results' => array_merge($friends,$others));
- if(! $a->data) {
+ if(! $a->data['results']) {
notice( t('No ratings') . EOL);
}
@@ -90,11 +91,17 @@ function ratings_content(&$a) {
if(! $poco_rating)
return;
+ $site_target = ((array_key_exists('target',$a->data) && array_key_exists('site_url',$a->data['target'])) ?
+ '<a href="' . $a->data['target']['site_url'] . '" >' . $a->data['target']['site_url'] . '</a>' : '');
+
+
$o = replace_macros(get_markup_template('prep.tpl'),array(
'$header' => t('Ratings'),
'$rating_lbl' => t('Rating: ' ),
+ '$website' => t('Website: '),
+ '$site' => $site_target,
'$rating_text_lbl' => t('Description: '),
- '$raters' => $a->data
+ '$raters' => $a->data['results']
));
return $o;
diff --git a/mod/ratingsearch.php b/mod/ratingsearch.php
index ec2db570b..9c4f2f827 100644
--- a/mod/ratingsearch.php
+++ b/mod/ratingsearch.php
@@ -33,17 +33,28 @@ function ratingsearch_init(&$a) {
);
if($p)
- $ret['target'] = $p[0];
+ $target = $p[0]['xchan_hash'];
else {
- $ret['message'] = 'channel not found';
- json_return_and_die($ret);
+ $p = q("select * from site where site_url like '%s' ",
+ dbesc('%' . $hash)
+ );
+ if($p) {
+ $target = strtolower($hash);
+ }
+ else {
+ $ret['message'] = 'Rating target not found';
+ json_return_and_die($ret);
+ }
}
+ if($p)
+ $ret['target'] = $p[0];
+
$ret['success'] = true;
$r = q("select * from xlink left join xchan on xlink_xchan = xchan_hash
where xlink_link = '%s' and xlink_rating != 0 and xlink_static = 1 order by xchan_name asc",
- dbesc($p[0]['xchan_hash'])
+ dbesc($target)
);
if($r) {
diff --git a/util/zotsh/README.txt b/util/zotsh/README.txt
new file mode 100644
index 000000000..5d03aec2c
--- /dev/null
+++ b/util/zotsh/README.txt
@@ -0,0 +1,109 @@
+ZotSH - v.0.0.2
+
+Client for browsing RedDAVs.
+
+Install
+-------
+
+ZotSH requires 'requests'(1).
+Please refer to requests docs on how to install it (2)
+
+Extract somewere and launch zotsh.py
+
+
+Description
+-----------
+
+ZotSH is a command line WebDAV client for RedMatrix.
+It knows how to magic-auth to remote hubs using Zot.
+
+ZotSH uses 'easywebdav' library (0) with small modifications
+to 'zotify' it. (See easywebdav/LICENSE)
+
+
+
+Commands
+--------
+
+host <hostname>
+ Authenticate to 'hostname' and switch to it
+
+cd <dirname|..>
+ changhe remote dir
+
+
+ls [path] [-a] [-l] [-d]
+ list remote files in current dir if 'path' not defined
+ -a list all, show hidden dot-files
+ -l list verbose
+ -d list only dirs
+
+exists <path>
+ Check existence of 'path'
+
+mkdir <name>
+ Create directory 'name'
+
+mkdirs <path>
+ Create parent directories to path, if they don't exists
+
+rmdir <name>
+ Delete directory 'name'
+
+delete <path>
+ Delete file 'path'
+
+upload <local_path> [remote_path]
+ Upload local file 'local_paht' to 'remote_paht'
+
+download <remote_path> [local_path]
+ Download remote file 'remote_path' and save it as 'local_path'
+
+cat <remote_paht>
+ Print content of 'remote_path'
+
+pwd
+ Print current path
+
+lcd
+lpwd
+lls
+ Local file management
+
+quit
+help
+
+
+
+Config
+------
+
+Create a .zotshrc file in your home or in same folder with zotsh.py:
+
+
+ [zotsh]
+ host = https://yourhost.com/
+ username = your_username
+ password = your_password
+
+
+Optionally adds
+
+ verify_ssl = false
+
+to skip verification of ssl certs
+
+
+Changelog
+----------
+0.0.2 Fix "CommandNotFound" exception, new 'cat' command
+
+0.0.1 First release
+
+
+Links
+-----
+
+_0 : https://github.com/amnong/easywebdav
+_1 : http://docs.python-requests.org/en/latest/
+_2 : http://docs.python-requests.org/en/latest/user/install/ \ No newline at end of file
diff --git a/util/zotsh/easywebdav/LICENSE b/util/zotsh/easywebdav/LICENSE
new file mode 100644
index 000000000..4f24108f8
--- /dev/null
+++ b/util/zotsh/easywebdav/LICENSE
@@ -0,0 +1,5 @@
+Copyright (c) 2012 year, Amnon Grossman
+
+Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/util/zotsh/easywebdav/__init__.py b/util/zotsh/easywebdav/__init__.py
new file mode 100644
index 000000000..3bc2cad2a
--- /dev/null
+++ b/util/zotsh/easywebdav/__init__.py
@@ -0,0 +1,5 @@
+from .client import *
+
+def connect(*args, **kwargs):
+ """connect(host, port=0, auth=None, username=None, password=None, protocol='http', path="/")"""
+ return Client(*args, **kwargs)
diff --git a/util/zotsh/easywebdav/__init__.pyc b/util/zotsh/easywebdav/__init__.pyc
new file mode 100644
index 000000000..b609b06c1
--- /dev/null
+++ b/util/zotsh/easywebdav/__init__.pyc
Binary files differ
diff --git a/util/zotsh/easywebdav/__version__.py b/util/zotsh/easywebdav/__version__.py
new file mode 100644
index 000000000..d293e3a30
--- /dev/null
+++ b/util/zotsh/easywebdav/__version__.py
@@ -0,0 +1 @@
+__version__ = "1.2.0"
diff --git a/util/zotsh/easywebdav/__version__.pyc b/util/zotsh/easywebdav/__version__.pyc
new file mode 100644
index 000000000..5da5a28ec
--- /dev/null
+++ b/util/zotsh/easywebdav/__version__.pyc
Binary files differ
diff --git a/util/zotsh/easywebdav/client.py b/util/zotsh/easywebdav/client.py
new file mode 100644
index 000000000..da7bf325a
--- /dev/null
+++ b/util/zotsh/easywebdav/client.py
@@ -0,0 +1,202 @@
+import requests
+import platform
+from numbers import Number
+import xml.etree.cElementTree as xml
+from collections import namedtuple
+
+py_majversion, py_minversion, py_revversion = platform.python_version_tuple()
+
+if py_majversion == '2':
+ from httplib import responses as HTTP_CODES
+ from urlparse import urlparse
+else:
+ from http.client import responses as HTTP_CODES
+ from urllib.parse import urlparse
+
+DOWNLOAD_CHUNK_SIZE_BYTES = 1 * 1024 * 1024
+
+class WebdavException(Exception):
+ pass
+
+class ConnectionFailed(WebdavException):
+ pass
+
+
+def codestr(code):
+ return HTTP_CODES.get(code, 'UNKNOWN')
+
+
+File = namedtuple('File', ['name', 'size', 'mtime', 'ctime', 'contenttype'])
+
+
+def prop(elem, name, default=None):
+ child = elem.find('.//{DAV:}' + name)
+ return default if child is None else child.text
+
+
+def elem2file(elem):
+ return File(
+ prop(elem, 'href'),
+ int(prop(elem, 'getcontentlength', 0)),
+ prop(elem, 'getlastmodified', ''),
+ prop(elem, 'creationdate', ''),
+ prop(elem, 'getcontenttype', ''),
+ )
+
+
+class OperationFailed(WebdavException):
+ _OPERATIONS = dict(
+ HEAD = "get header",
+ GET = "download",
+ PUT = "upload",
+ DELETE = "delete",
+ MKCOL = "create directory",
+ PROPFIND = "list directory",
+ )
+
+ def __init__(self, method, path, expected_code, actual_code):
+ self.method = method
+ self.path = path
+ self.expected_code = expected_code
+ self.actual_code = actual_code
+ operation_name = self._OPERATIONS[method]
+ self.reason = 'Failed to {operation_name} "{path}"'.format(**locals())
+ expected_codes = (expected_code,) if isinstance(expected_code, Number) else expected_code
+ expected_codes_str = ", ".join('{0} {1}'.format(code, codestr(code)) for code in expected_codes)
+ actual_code_str = codestr(actual_code)
+ msg = '''\
+{self.reason}.
+ Operation : {method} {path}
+ Expected code : {expected_codes_str}
+ Actual code : {actual_code} {actual_code_str}'''.format(**locals())
+ super(OperationFailed, self).__init__(msg)
+
+class Client(object):
+ def __init__(self, host, port=0, auth=None, username=None, password=None,
+ protocol='http', verify_ssl=True, path=None, cert=None, session=None):
+ if not port:
+ port = 443 if protocol == 'https' else 80
+ self.baseurl = '{0}://{1}:{2}'.format(protocol, host, port)
+ if path:
+ self.baseurl = '{0}/{1}'.format(self.baseurl, path)
+ self.cwd = '/'
+ if session is None:
+ self.session = requests.session()
+ else:
+ self.session = session
+ self.session.verify = verify_ssl
+ self.session.stream = True
+
+ if cert:
+ self.session.cert = cert
+
+ if auth:
+ self.session.auth = auth
+ elif username and password:
+ self.session.auth = (username, password)
+
+ def _send(self, method, path, expected_code, **kwargs):
+ url = self._get_url(path).strip(".")
+ #~ print self.session
+ #~ print self.session.verify
+ #~ print self.session.params
+ #~ print self.session.cookies
+ response = self.session.request(method, url, allow_redirects=False, **kwargs)
+ #~ print response.request.method
+ #~ print response.request.url
+ if isinstance(expected_code, Number) and response.status_code != expected_code \
+ or not isinstance(expected_code, Number) and response.status_code not in expected_code:
+ raise OperationFailed(method, path, expected_code, response.status_code)
+ return response
+
+ def _get_url(self, path):
+ path = str(path).strip()
+ if path.startswith('/'):
+ return self.baseurl + path
+ return "".join((self.baseurl, self.cwd, path))
+
+ def cd(self, path):
+ path = path.strip()
+ if not path:
+ return
+ stripped_path = '/'.join(part for part in path.split('/') if part) + '/'
+
+ if stripped_path == '/':
+ self.cwd = stripped_path
+ elif path.startswith('/'):
+ self.cwd = '/' + stripped_path
+ elif stripped_path == "./":
+ return
+ elif stripped_path == "../":
+ self.cwd ='/'.join( self.cwd.split('/')[:-2] ) + '/'
+ else:
+ self.cwd += stripped_path
+
+ def mkdir(self, path, safe=False):
+ expected_codes = 201 if not safe else (201, 301, 405)
+ self._send('MKCOL', path, expected_codes)
+
+ def mkdirs(self, path):
+ dirs = [d for d in path.split('/') if d]
+ if not dirs:
+ return
+ if path.startswith('/'):
+ dirs[0] = '/' + dirs[0]
+ old_cwd = self.cwd
+ try:
+ for dir in dirs:
+ try:
+ self.mkdir(dir, safe=True)
+ except Exception as e:
+ if e.actual_code == 409:
+ raise
+ finally:
+ self.cd(dir)
+ finally:
+ self.cd(old_cwd)
+
+ def rmdir(self, path, safe=False):
+ path = str(path).rstrip('/') + '/'
+ expected_codes = 204 if not safe else (204, 404)
+ self._send('DELETE', path, expected_codes)
+
+ def delete(self, path):
+ self._send('DELETE', path, 204)
+
+ def upload(self, local_path_or_fileobj, remote_path):
+ if isinstance(local_path_or_fileobj, basestring):
+ with open(local_path_or_fileobj, 'rb') as f:
+ self._upload(f, remote_path)
+ else:
+ self._upload(local_path_or_fileobj, remote_path)
+
+ def _upload(self, fileobj, remote_path):
+ self._send('PUT', remote_path, (200, 201, 204), data=fileobj)
+
+ def download(self, remote_path, local_path_or_fileobj):
+ response = self._send('GET', remote_path, 200, stream=True)
+ if isinstance(local_path_or_fileobj, basestring):
+ with open(local_path_or_fileobj, 'wb') as f:
+ self._download(f, response)
+ else:
+ self._download(local_path_or_fileobj, response)
+
+ def _download(self, fileobj, response):
+ for chunk in response.iter_content(DOWNLOAD_CHUNK_SIZE_BYTES):
+ fileobj.write(chunk)
+
+ def ls(self, remote_path='.'):
+ headers = {'Depth': '1'}
+ response = self._send('PROPFIND', remote_path, (207, 301), headers=headers)
+
+ # Redirect
+ if response.status_code == 301:
+ url = urlparse(response.headers['location'])
+ return self.ls(url.path)
+
+ tree = xml.fromstring(response.content)
+ return [elem2file(elem) for elem in tree.findall('{DAV:}response')]
+
+ def exists(self, remote_path):
+ response = self._send('HEAD', remote_path, (200, 301, 404))
+ return True if response.status_code != 404 else False
diff --git a/util/zotsh/easywebdav/client.pyc b/util/zotsh/easywebdav/client.pyc
new file mode 100644
index 000000000..4c42d2603
--- /dev/null
+++ b/util/zotsh/easywebdav/client.pyc
Binary files differ
diff --git a/util/zotsh/zotsh.py b/util/zotsh/zotsh.py
new file mode 100755
index 000000000..36506b39d
--- /dev/null
+++ b/util/zotsh/zotsh.py
@@ -0,0 +1,324 @@
+#!/usr/bin/env python2
+import sys, os
+import ConfigParser
+import requests
+from requests.auth import HTTPBasicAuth
+import easywebdav
+import easywebdav.__version__ as easywebdavversion
+
+__version__= "0.0.2"
+
+SERVER = None
+USER = None
+PASSWD = None
+VERIFY_SSL=True
+
+#####################################################
+
+class CommandNotFound(Exception):
+ pass
+
+class ZotSH(object):
+ commands = ['cd','ls','exists','mkdir','mkdirs','rmdir','delete','upload','download',
+ 'host', 'pwd','cat',
+ 'lcd','lpwd', 'lls',
+ 'quit', 'help']
+ def __init__(self, host, session=None, davclient=None):
+ self.sessions = {}
+ self.host = host
+ self.session = session
+ self.davclient = davclient
+
+
+ @property
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, host):
+ self._host = host
+ self._hostname = host.replace("https:","").replace("/","")
+
+ @property
+ def hostname(self):
+ return self._hostname
+
+ @hostname.setter
+ def hostname(self, hostname):
+ self._host = "https://%s/" % (hostname)
+ self._hostname = hostname
+
+ @property
+ def session(self):
+ return self._session
+
+ @session.setter
+ def session(self, session):
+ self._session = session
+ self.davclient = easywebdav.connect( self.hostname, protocol='https', session=session, path="cloud", verify_ssl=VERIFY_SSL)
+
+ @property
+ def PS1(self):
+ if self.davclient is None:
+ return "[!]> "
+ return "%s:%s> " % (self.hostname, self.davclient.cwd)
+
+ def get_host_session(self, host=None):
+ #~ if host is None:
+ #~ host = self.host
+ #~ if not host.startswith("https"):
+ #~ host = "https://%s/" % (host)
+ #~ if host in self.sessions:
+ #~ session = self.sessions[host]
+ #~ else:
+ #~ session = requests.Session()
+ #~ self.sessions[host] = session
+ #~ if not host == SERVER
+ #~ session.params.update({'davguest':1})
+ #~ return session
+
+ if self.session is None:
+ session = requests.Session()
+ #session.params.update({'davguest':1})
+ else:
+ session = self.session
+ session.params.update({'davguest': (not host == SERVER) })
+ return session
+
+ def do(self, command, *args):
+ if not command in self.commands:
+ raise CommandNotFound("Unknow command '%s'" % command)
+
+ cmd = getattr(self, "cmd_%s"%command, None)
+ if cmd is None:
+ cmd = getattr(self.davclient, command)
+
+ return cmd(*args)
+
+ def cmd_exists(self, *args):
+ if (len(args)==0):
+ return
+ return self.davclient.exists(args[0])
+
+ def cmd_mkdir(self, *args):
+ if (len(args)==0):
+ return
+ return self.davclient.mkdir(args[0])
+
+ def cmd_mkdirs(self, *args):
+ if (len(args)==0):
+ return
+ return self.davclient.mkdirs(args[0])
+
+ def cmd_rmdir(self, *args):
+ if (len(args)==0):
+ return
+ return self.davclient.rmdir(args[0])
+
+ def cmd_delete(self, *args):
+ if (len(args)==0):
+ return
+ return self.davclient.delete(args[0])
+
+ def cmd_upload(self, *args):
+ if (len(args)==0):
+ return
+ args = list(args)
+ if (len(args)==1):
+ args.append(args[0])
+
+ return self.davclient.upload(args[0], args[1])
+
+ def cmd_download(self, *args):
+ if (len(args)==0):
+ return
+ args = list(args)
+ if (len(args)==1):
+ args.append(args[0])
+
+ return self.davclient.download(args[0], args[1])
+
+ def cmd_host(self, *args):
+ if (len(args)==0):
+ return
+ newhostname = args[0]
+ newhost = "https://%s/" % newhostname
+ if newhostname == "~" or newhost == SERVER:
+ # bach to home server
+ self.host = SERVER
+ self.session = self.get_host_session(SERVER)
+ return
+
+ session_remote = self.get_host_session(newhost)
+ session_home = self.get_host_session(SERVER)
+
+ # call /magic on SERVER
+ r = session_home.get(
+ SERVER + "magic",
+ params={'dest': newhost},
+ allow_redirects=False,
+ verify=VERIFY_SSL )
+
+ if not 'location' in r.headers:
+ raise Exception("Cannot start magic auth to '%s'" % newhostname)
+ auth_url = r.headers['location']
+
+
+ # call auth_url with "test" param
+
+ r = session_remote.get(
+ auth_url,
+ params={'test': 1 },
+ verify=VERIFY_SSL )
+
+ if r.json()['success']:
+ self.hostname = newhostname
+ self.session = session_remote
+ else:
+ raise Exception("Cannot magic auth to '%s'" % newhostname)
+
+
+ def cmd_pwd(self, *args):
+ return "%s%s" % ( self.davclient.baseurl, self.davclient.cwd )
+
+ def cmd_ls(self, *args):
+ extra_args = ["-a", "-l", "-d"]
+
+ show_hidden = "-a" in args
+ show_list = "-l" in args
+ show_only_dir = "-d" in args
+ args = [ a for a in args if not a in extra_args ]
+
+
+ r = self.davclient.ls(*args)
+ l = max([ len(str(f.size)) for f in r ] + [7,])
+
+ def _fmt(type, size, name):
+ if show_list:
+ return "%s %*d %s" % (type, l, f.size , name)
+ else:
+ return name
+
+ if show_hidden :
+ print _fmt('d', 0, "./")
+ if self.davclient.cwd!="/":
+ print _fmt('d', 0, "../")
+
+ for f in r:
+ name = f.name.replace("/cloud"+self.davclient.cwd,"")
+ type = "-"
+ if name.endswith("/"):
+ type = "d"
+ if name!="":
+ if show_hidden or not name.startswith("."):
+ if not show_only_dir or type=="d":
+ print _fmt(type, f.size , name)
+
+ def cmd_lpwd(self, *args):
+ return os.getcwd()
+
+ def cmd_lcd(self, *args):
+ if (len(args)==0):
+ return
+ os.chdir(args[0])
+
+ def cmd_lls(self, *args):
+ for f in os.listdir(os.getcwd()):
+ if os.path.isdir(f):
+ f=f+"/"
+ print f
+
+ def cmd_help(self, *args):
+ print "ZotSH",__version__
+ print
+ print "Commands:"
+ for c in self.commands:
+ print "\t",c
+ print
+ print "easywebdav", easywebdavversion.__version__, "(mod)"
+ print "requests", requests.__version__
+
+ def cmd_cat(self,*args):
+ if (len(args)==0):
+ return
+ rfile = args[0]
+ resp = self.davclient._send('GET', rfile, (200,))
+ print resp.text
+
+def load_conf():
+ global SERVER,USER,PASSWD,VERIFY_SSL
+ homedir = os.getenv("HOME")
+ if homedir is None:
+ homedir = os.path.join(os.getenv("HOMEDRIVE"), os.getenv("HOMEPATH"))
+
+ optsfile = ".zotshrc"
+ if not os.path.isfile(optsfile):
+ optsfile = os.path.join(homedir, ".zotshrc")
+
+ if not os.path.isfile(optsfile):
+ print "Please create a configuration file called '.zotshrc':"
+ print "[zotsh]"
+ print "host = https://yourhost.com/"
+ print "username = your_username"
+ print "password = your_password"
+ sys.exit(-1)
+
+ config = ConfigParser.ConfigParser()
+ config.read(optsfile)
+ SERVER = config.get('zotsh', 'host')
+ USER = config.get('zotsh', 'username')
+ PASSWD = config.get('zotsh', 'password')
+ if config.has_option('zotsh', 'verify_ssl'):
+ VERIFY_SSL = config.getboolean('zotsh', 'verify_ssl')
+
+
+def zotsh():
+
+ zotsh = ZotSH( SERVER)
+
+ session_home = zotsh.get_host_session()
+
+ #~ #login on home server
+ print "loggin in..."
+ r = session_home.get(
+ SERVER + "api/account/verify_credentials",
+ auth=HTTPBasicAuth(USER, PASSWD),
+ verify=VERIFY_SSL )
+
+ print "Hi", r.json()['name']
+
+ zotsh.session = session_home
+
+ # command loop
+ input = raw_input(zotsh.PS1)
+ while (input != "quit"):
+ input = input.strip()
+ if len(input)>0:
+ toks = [ x.strip() for x in input.split(" ") ]
+
+ command = toks[0]
+ args = toks[1:]
+ try:
+ ret = zotsh.do(command, *args)
+ except easywebdav.client.OperationFailed, e:
+ print e
+ except CommandNotFound, e:
+ print e
+ else:
+ if ret is not None:
+ print ret
+
+
+ input = raw_input(zotsh.PS1)
+
+
+
+
+if __name__=="__main__":
+ load_conf()
+ zotsh()
+ sys.exit()
+
+
+
+
diff --git a/version.inc b/version.inc
index 119344005..99ae61ca4 100644
--- a/version.inc
+++ b/version.inc
@@ -1 +1 @@
-2015-02-13.943
+2015-02-16.946
diff --git a/view/js/main.js b/view/js/main.js
index 17ea42db7..7a6798f2f 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -713,6 +713,8 @@ function updateConvItems(mode,data) {
justifiedGalleryActive = true;
$('#photo-album-contents').justifiedGallery({
margins: 3,
+ border: 0,
+ ignoreElement: '#page-end',
sizeRangeSuffixes: {
'lt100': '-2',
'lt240': '-2',
diff --git a/view/pdl/mod_ratings.pdl b/view/pdl/mod_ratings.pdl
index 0b6e32283..df1486c9b 100644
--- a/view/pdl/mod_ratings.pdl
+++ b/view/pdl/mod_ratings.pdl
@@ -1,4 +1,5 @@
[region=aside]
+[widget=pubsites][/widget]
[widget=vcard][/widget]
[widget=rating][/widget]
[widget=suggestions][/widget]
diff --git a/view/php/theme_init.php b/view/php/theme_init.php
index 0009a00e2..b695bd54e 100644
--- a/view/php/theme_init.php
+++ b/view/php/theme_init.php
@@ -9,11 +9,11 @@ head_add_css('library/jRange/jquery.range.css');
head_add_css('view/css/conversation.css');
head_add_css('view/css/widgets.css');
head_add_css('view/css/colorbox.css');
-head_add_css('library/justifiedGallery/dist/css/justifiedGallery.css');
+head_add_css('library/justifiedGallery/justifiedGallery.css');
head_add_css('library/bootstrap-tagsinput/bootstrap-tagsinput.css');
head_add_js('jquery.js');
head_add_js('jquery-migrate-1.1.1.js');
-head_add_js('library/justifiedGallery/dist/js/jquery.justifiedGallery.js');
+head_add_js('library/justifiedGallery/jquery.justifiedGallery.js');
//head_add_js('jquery-compat.js');
head_add_js('spin.js');
diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css
index 6a46d7429..5b24ab731 100644
--- a/view/theme/redbasic/css/style.css
+++ b/view/theme/redbasic/css/style.css
@@ -992,7 +992,7 @@ nav .acpopup {
margin-bottom: 10px;
}
-.edit-event-link, .plink-event-link {
+.edit-event-link, .plink-event-link, .drop-event-link {
float: left;
margin-top: 4px;
margin-right: 4px;
diff --git a/view/tpl/event.tpl b/view/tpl/event.tpl
index f0e00bd2c..5dfc91ebe 100755
--- a/view/tpl/event.tpl
+++ b/view/tpl/event.tpl
@@ -8,6 +8,7 @@
<div class="event-buttons">
{{if $event.item.plink}}<a href="{{$event.plink.0}}" title="{{$event.plink.1}}" class="plink-event-link"><i class="icon-external-link btn btn-default" ></i></a>{{/if}}
{{if $event.edit}}<a href="{{$event.edit.0}}" title="{{$event.edit.1}}" class="edit-event-link"><i class="icon-pencil btn btn-default"></i></a>{{/if}}
+ {{if $event.drop}}<a href="{{$event.drop.0}}" title="{{$event.drop.1}}" class="drop-event-link"><i class="icon-trash btn btn-default"></i></a>{{/if}}
</div>
</div>
<div class="clear"></div>
diff --git a/view/tpl/prep.tpl b/view/tpl/prep.tpl
index 83a86372c..7bef7a417 100644
--- a/view/tpl/prep.tpl
+++ b/view/tpl/prep.tpl
@@ -1,5 +1,10 @@
<h1>{{$header}}</h1>
+{{if $site}}
+<h3>{{$website}} {{$site}}</h3>
+{{/if}}
+
+
{{if $raters}}
{{foreach $raters as $r}}
diff --git a/view/tpl/rating_form.tpl b/view/tpl/rating_form.tpl
index 216bf6ede..95c2eb03f 100644
--- a/view/tpl/rating_form.tpl
+++ b/view/tpl/rating_form.tpl
@@ -1,6 +1,6 @@
<h3>{{$header}}</h3>
-<div class="rating-target-name">{{$tgt_name}}</div>
+<div class="rating-target-name">{{if $site}}{{$website}} {{$site}}{{else}}{{$tgt_name}}{{/if}}</div>
<h3>{{$lbl_rating}}</h3>