diff options
-rw-r--r-- | index.php | 63 | ||||
-rw-r--r-- | shaarli.css | 9 |
2 files changed, 63 insertions, 9 deletions
@@ -1,5 +1,5 @@ | |||
1 | <?php | 1 | <?php |
2 | // Shaarli 0.0.20 beta - Shaare your links... | 2 | // Shaarli 0.0.21 beta - Shaare your links... |
3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net | 3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net |
4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli | 4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli |
5 | // Licence: http://www.opensource.org/licenses/zlib-license.php | 5 | // Licence: http://www.opensource.org/licenses/zlib-license.php |
@@ -17,6 +17,7 @@ define('BAN_AFTER',4); // Ban IP after this many failures. | |||
17 | define('BAN_DURATION',1800); // Ban duration for IP address after login failures (in seconds) (1800 sec. = 30 minutes) | 17 | define('BAN_DURATION',1800); // Ban duration for IP address after login failures (in seconds) (1800 sec. = 30 minutes) |
18 | define('OPEN_SHAARLI',false); // If true, anyone can add/edit/delete links without having to login | 18 | define('OPEN_SHAARLI',false); // If true, anyone can add/edit/delete links without having to login |
19 | define('HIDE_TIMESTAMPS',false); // If true, the moment when links were saved are not shown to users that are not logged in. | 19 | define('HIDE_TIMESTAMPS',false); // If true, the moment when links were saved are not shown to users that are not logged in. |
20 | define('ENABLE_THUMBNAILS',true); // Enable thumbnails in links. | ||
20 | 21 | ||
21 | // ----------------------------------------------------------------------------------------------- | 22 | // ----------------------------------------------------------------------------------------------- |
22 | // Program config (touch at your own risks !) | 23 | // Program config (touch at your own risks !) |
@@ -47,7 +48,7 @@ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | |||
47 | header("Cache-Control: no-store, no-cache, must-revalidate"); | 48 | header("Cache-Control: no-store, no-cache, must-revalidate"); |
48 | header("Cache-Control: post-check=0, pre-check=0", false); | 49 | header("Cache-Control: post-check=0, pre-check=0", false); |
49 | header("Pragma: no-cache"); | 50 | header("Pragma: no-cache"); |
50 | define('shaarli_version','0.0.20 beta'); | 51 | define('shaarli_version','0.0.21 beta'); |
51 | if (!is_dir(DATADIR)) { mkdir(DATADIR,0705); chmod(DATADIR,0705); } | 52 | if (!is_dir(DATADIR)) { mkdir(DATADIR,0705); chmod(DATADIR,0705); } |
52 | if (!is_file(DATADIR.'/.htaccess')) { file_put_contents(DATADIR.'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. | 53 | if (!is_file(DATADIR.'/.htaccess')) { file_put_contents(DATADIR.'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. |
53 | if (!is_file(CONFIG_FILE)) install(); | 54 | if (!is_file(CONFIG_FILE)) install(); |
@@ -750,8 +751,7 @@ function renderPage() | |||
750 | <form method="GET" name="tagfilter" style="display:inline;padding-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:20%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> | 751 | <form method="GET" name="tagfilter" style="display:inline;padding-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:20%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> |
751 | </div> | 752 | </div> |
752 | HTML; | 753 | HTML; |
753 | $onload = 'onload="document.searchform.searchterm.focus();"'; | 754 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); |
754 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>$onload); | ||
755 | templatePage($data); | 755 | templatePage($data); |
756 | exit; // Never remove this one ! All operations below are reserved for logged in user. | 756 | exit; // Never remove this one ! All operations below are reserved for logged in user. |
757 | } | 757 | } |
@@ -1101,8 +1101,7 @@ HTML; | |||
1101 | <form method="GET" name="tagfilter" style="display:inline;padding-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:20%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> | 1101 | <form method="GET" name="tagfilter" style="display:inline;padding-left:24px;"><input type="text" name="searchtags" id="searchtags" style="width:20%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> |
1102 | </div> | 1102 | </div> |
1103 | HTML; | 1103 | HTML; |
1104 | $onload = 'onload="document.searchform.searchterm.focus();"'; | 1104 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); |
1105 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>$onload); | ||
1106 | templatePage($data); | 1105 | templatePage($data); |
1107 | exit; | 1106 | exit; |
1108 | } | 1107 | } |
@@ -1262,10 +1261,11 @@ function templateLinkList() | |||
1262 | if (isLoggedIn()) $actions=' <form method="GET" class="buttoneditform"><input type="hidden" name="edit_link" value="'.$link['linkdate'].'"><input type="submit" value="Edit" class="smallbutton"></form>'; | 1261 | if (isLoggedIn()) $actions=' <form method="GET" class="buttoneditform"><input type="hidden" name="edit_link" value="'.$link['linkdate'].'"><input type="submit" value="Edit" class="smallbutton"></form>'; |
1263 | $tags=''; | 1262 | $tags=''; |
1264 | if ($link['tags']!='') foreach(explode(' ',$link['tags']) as $tag) { $tags.='<span class="linktag" title="Add tag"><a href="?addtag='.htmlspecialchars($tag).'">'.htmlspecialchars($tag).'</a></span> '; } | 1263 | if ($link['tags']!='') foreach(explode(' ',$link['tags']) as $tag) { $tags.='<span class="linktag" title="Add tag"><a href="?addtag='.htmlspecialchars($tag).'">'.htmlspecialchars($tag).'</a></span> '; } |
1265 | $linklist.='<li '.$classprivate.'><span class="linktitle"><a href="'.htmlspecialchars($link['url']).'">'.htmlspecialchars($title).'</a></span>'.$actions.'<br>'; | 1264 | $linklist.='<li '.$classprivate.'>'.thumbnail($link['url']); |
1265 | $linklist.='<div class="linkcontainer"><span class="linktitle"><a href="'.htmlspecialchars($link['url']).'">'.htmlspecialchars($title).'</a></span>'.$actions.'<br>'; | ||
1266 | if ($description!='') $linklist.='<div class="linkdescription">'.nl2br(htmlspecialchars($description)).'</div><br>'; | 1266 | if ($description!='') $linklist.='<div class="linkdescription">'.nl2br(htmlspecialchars($description)).'</div><br>'; |
1267 | if (!HIDE_TIMESTAMPS || isLoggedIn()) $linklist.='<span class="linkdate">'.htmlspecialchars(linkdate2locale($link['linkdate'])).' - </span>'; | 1267 | if (!HIDE_TIMESTAMPS || isLoggedIn()) $linklist.='<span class="linkdate">'.htmlspecialchars(linkdate2locale($link['linkdate'])).' - </span>'; |
1268 | $linklist.='<span class="linkurl">'.htmlspecialchars($link['url']).'</span><br>'.$tags."</li>\n"; | 1268 | $linklist.='<span class="linkurl">'.htmlspecialchars($link['url']).'</span><br>'.$tags."</div></li>\n"; |
1269 | $i++; | 1269 | $i++; |
1270 | } | 1270 | } |
1271 | 1271 | ||
@@ -1286,6 +1286,53 @@ HTML; | |||
1286 | return $linklist; | 1286 | return $linklist; |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | // Returns the HTML code to display a thumbnail for a link. | ||
1290 | // Understands various services (youtube.com...) | ||
1291 | function thumbnail($url) | ||
1292 | { | ||
1293 | if (!ENABLE_THUMBNAILS) return ''; | ||
1294 | $domain = parse_url($url,PHP_URL_HOST); | ||
1295 | if ($domain=='youtube.com' || $domain=='www.youtube.com') | ||
1296 | { | ||
1297 | parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract video ID and get thumbnail | ||
1298 | if (!empty($params['v'])) return '<div class="thumbnail"><a href="'.htmlspecialchars($url).'"><img src="http://img.youtube.com/vi/'.htmlspecialchars($params['v']).'/2.jpg" width="120" height="90"></a></div>'; | ||
1299 | } | ||
1300 | if ($domain=='imgur.com') | ||
1301 | { | ||
1302 | $path = parse_url($url,PHP_URL_PATH); | ||
1303 | if (substr_count($path,'/')==1) return '<div class="thumbnail"><a href="'.htmlspecialchars($url).'"><img src="http://i.imgur.com/'.htmlspecialchars(substr($path,1)).'s.jpg" width="90" height="90"></a></div>'; | ||
1304 | } | ||
1305 | if ($domain=='i.imgur.com') | ||
1306 | { | ||
1307 | $pi = pathinfo(parse_url($url,PHP_URL_PATH)); | ||
1308 | if (!empty($pi['filename'])) return '<div class="thumbnail"><a href="'.htmlspecialchars($url).'"><img src="http://i.imgur.com/'.htmlspecialchars($pi['filename']).'s.jpg" width="90" height="90"></a></div>'; | ||
1309 | } | ||
1310 | if ($domain=='dailymotion.com' || $domain=='www.dailymotion.com') | ||
1311 | { | ||
1312 | if (strpos($url,'dailymotion.com/video/')) | ||
1313 | { | ||
1314 | $thumburl=str_replace('dailymotion.com/video/','dailymotion.com/thumbnail/video/',$url); | ||
1315 | return '<div class="thumbnail"><a href="'.htmlspecialchars($url).'"><img src="'.htmlspecialchars($thumburl).'" width="120" style="height:auto;"></a></div>'; | ||
1316 | } | ||
1317 | } | ||
1318 | if ($domain=='vimeo.com') | ||
1319 | { | ||
1320 | // This is more complex: we have to perform a HTTP request, then parse the result. | ||
1321 | // This slows down page generation :-( | ||
1322 | // Maybe we should deport this to javascript ? Example: http://stackoverflow.com/questions/1361149/get-img-thumbnails-from-vimeo/4285098#4285098 | ||
1323 | $vid = substr(parse_url($url,PHP_URL_PATH),1); | ||
1324 | // We allow 2 seconds for Vimeo servers to respond. | ||
1325 | list($httpstatus,$headers,$data) = getHTTP('http://vimeo.com/api/v2/video/'.htmlspecialchars($vid).'.php',2); | ||
1326 | if (strpos($httpstatus,'200 OK')) | ||
1327 | { | ||
1328 | $t = unserialize($data); | ||
1329 | if (!empty($t[0]['thumbnail_medium'])) return '<div class="thumbnail"><a href="'.htmlspecialchars($url).'"><img src="'.htmlspecialchars($t[0]['thumbnail_medium']).'" width="120" style="height:auto;"></a></div>'; | ||
1330 | } | ||
1331 | } | ||
1332 | return ''; // No thumbnail. | ||
1333 | |||
1334 | } | ||
1335 | |||
1289 | // ----------------------------------------------------------------------------------------------- | 1336 | // ----------------------------------------------------------------------------------------------- |
1290 | // Template for the whole page. | 1337 | // Template for the whole page. |
1291 | /* Input: $data (associative array). | 1338 | /* Input: $data (associative array). |
diff --git a/shaarli.css b/shaarli.css index 5a977439..3136755b 100644 --- a/shaarli.css +++ b/shaarli.css | |||
@@ -44,7 +44,7 @@ margin: auto; | |||
44 | .paging a:active { color:#fff; } | 44 | .paging a:active { color:#fff; } |
45 | #headerform { padding:5 5 5 5; } | 45 | #headerform { padding:5 5 5 5; } |
46 | #editlinkform { padding:5 5 5 15px; width:80%; } | 46 | #editlinkform { padding:5 5 5 15px; width:80%; } |
47 | #linklist li { padding:4 10 8 20; border-bottom: 1px solid #bbb;} | 47 | #linklist li { padding:4 10 8 20; border-top: 1px solid #bbb; clear:both; } |
48 | #linklist li.private { background-color: #ccc; border-left:8px solid #888; } | 48 | #linklist li.private { background-color: #ccc; border-left:8px solid #888; } |
49 | .linktitle { font-size:14pt; font-weight:bold; } | 49 | .linktitle { font-size:14pt; font-weight:bold; } |
50 | .linktitle a { text-decoration: none; color:#0000EE; } | 50 | .linktitle a { text-decoration: none; color:#0000EE; } |
@@ -63,6 +63,13 @@ border-bottom:1px solid #aaa; border-right:1px solid #aaa; } | |||
63 | #cloudtag a { color:black; text-decoration:none; } | 63 | #cloudtag a { color:black; text-decoration:none; } |
64 | #installform td { font-size: 10pt; padding:10 5 10 5; } | 64 | #installform td { font-size: 10pt; padding:10 5 10 5; } |
65 | #configform td { color:#ccc; font-size: 10pt; padding:10 5 10 5; } | 65 | #configform td { color:#ccc; font-size: 10pt; padding:10 5 10 5; } |
66 | .thumbnail { float:right; margin-left: 10px; } | ||
67 | |||
68 | /* If you want thumbnails on the right: | ||
69 | .thumbnail { float:left; margin-right: 10px; } | ||
70 | .linkcontainer { position: static; margin-left:130px; } | ||
71 | */ | ||
72 | |||
66 | 73 | ||
67 | /* Minimal customisation for jQuery widgets */ | 74 | /* Minimal customisation for jQuery widgets */ |
68 | .ui-autocomplete { background-color:#fff; padding-left:5px;} | 75 | .ui-autocomplete { background-color:#fff; padding-left:5px;} |