Revision [14447]

This is an old revision of BookmarkManager made by BrianKoontz on 2006-06-02 22:37:57.

 

Bookmark Manager

An integrated bookmark manager in the spirit of de.lirio.us.

Try it out! Beta version with latest code here.
 


Design ideas

Progress reports

TODO
Indicates issues that have been addressed

post bookmarklet: javascript:location.href='http://de.lirio.us/rubric/post?uri='+escape(location.href)+'&title='+encodeURIComponent(document.title)+'&when_done=go_back'
post bookmarklet (with popup): javascript:void(open('http://de.lirio.us/rubric/post?uri='+escape(location.href)+'&title='+encodeURIComponent(document.title)+'&when_done=close','Rubric','toolbar=no,width=700,height=325,scrollbars'));


Installation
include_once('Wikka.freetag.class.php');

$freetag_options = array(
'db_user' => 'root',
'db_pass' => ,
'db_host' => 'localhost',
'db_name' => 'freetag',
'PCONNECT' => true,
);
$freetag = new wikka_freetag($freetag_options);

function wikka_id_to_tagger_id ($wikka_id, $obj, $freetag_options) {
if(!isset($wikka_id)) {
return NULL;
}
$wikka_id = mysql_real_escape_string($wikka_id);
$res = $obj->LoadSingle("select tagger_id from ".$freetag_options['db_name'].".freetag_wikka_id_map where wikka_id = '".$wikka_id."';");
$tagger_id = $res['tagger_id'];
if(!$tagger_id) {
$obj->Query("insert ".$freetag_options['db_name'].".freetag_wikka_id_map set "."wikka_id = '".$wikka_id."';");
$res = $obj->LoadSingle("select last_insert_id();");
$tagger_id = $res['last_insert_id()'];
}
return $tagger_id;
}
function output_tag_cloud($freetag,$tag_page_url,$tagger_id=NULL,$header=NULL) {
Output tag cloud
print "<div class='floatr'>";
if($header) {
print $header."<br/>";
}
print $freetag->get_tag_cloud_html(100,10,20,'px','cloud_tag',$tag_page_url,$tagger_id);
print "</div>";
print "<div class=\"clear\"> </div>";
}
function count_objects($wikka_id, $obj, $freetag_options) {
if(isset($wikka_id)) {
$wikka_sql = "AND wikka_id = '".mysql_real_escape_string($wikka_id)."'";
} else {
$wikka_sql = "AND private = 0";
}
$res = $obj->LoadSingle("select COUNT(*) as count from ".$freetag_options['db_name'].".freetag_bookmarks where 1 ".$wikka_sql.";");
$count = $res['count'];
return $count;
}
function count_tagged_objects($wikka_id, $tag, $obj, $freetag_options, $freetag) {
$num_objs = count_objects($wikka_id, $obj, $freetag_options);
$tagger_id = wikka_id_to_tagger_id($wikka_id, $obj, $freetag_options);
$ids = $freetag->get_most_recent_objects($tagger_id, $tag, 0, $num_objs);
return count($ids);
}
$wikka_id = $this->GetUserName();
$tagger_id = wikka_id_to_tagger_id($wikka_id, $this, $freetag_options);
$all_obj_count = count_objects(NULL, $this, $freetag_options);
$your_obj_count = count_objects($wikka_id, $this, $freetag_options);

echo "<h1>BookmarkTest</h1>";
echo "<a href=\.$this->href()."&action=list_all"."\">List all (".$all_obj_count.") | ". ".$this->href()."&action=list_yours"."\">List yours</a> (".$your_obj_count.") | ".
"<a href=\.$this->href()."&action=add"."\">Add
"; if(!isset($_REQUEST['action'])) { // Display all tags at start of session $this->Redirect($this->href()."&action=list_all"); } // Add new entry to DB if(isset($_REQUEST['action']) && ($_REQUEST['action']=="add")) { if(trim($_REQUEST['tags']) != ) {
Private bookmark?
$private = 0;
if(strpos(trim($_REQUEST['tags']), "@private") !
false)
$private = 1;
$this->Query("insert ".$freetag_options['db_name'].".freetag_bookmarks set ".
"title = '".mysql_real_escape_string($_REQUEST['title'])."', ".
"uri = '".mysql_real_escape_string($this->cleanUrl($_REQUEST['uri']))."', ".
"wikka_id = '".mysql_real_escape_string($wikka_id)."', ".
"private = '".$private."', ".
"description = '".mysql_real_escape_string($_REQUEST['desc'])."';");
$freetag->tag_object($tagger_id, $last_id['last_insert_id()'], $_REQUEST['tags']);
$this->Redirect($this->href()."&action=list_yours");
} else {
Display add form
?>
<input type="hidden" name="action" value="add" />
<table>
<tr>
<td align="right">Title:</td>
<td><input name="title" size="40"/></td>
</tr>
<tr>
<td align="right">URI:
<td><input name="uri" size="40"/></td>
</tr>
<tr>
<td align="right">Description:</td>
<td><input name="desc" size="40"/></td>
</tr>
<tr>
<td align="right"></td>
<td><?php echo $this->Format("Use blank space between tags, include \"@private\" for private bookmark"); ?></td>
</tr>
<tr>
<td align="right">Tags:</td>
<td><input name="tags" size="40"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Add" size="40" /></td>
</tr>
</table>
<?php
}
}

Edit entry
if(isset($_REQUEST['action']) && ($_REQUEST['action'] "edit") && (isset($_REQUEST['object_id']))) {
$object_id = $_REQUEST['object_id'];
$obj = $this->LoadSingle("select bookmark_id,title,uri,description,wikka_id from ".$freetag_options['db_name'].".freetag_bookmarks where bookmark_id = ".$object_id.";");
Is the logged-in user the owner?
if($wikka_id != $obj['wikka_id']) {
$this->Redirect($this->href()."&action=list_all");
}
if(isset($_REQUEST['modify']) && trim($_REQUEST['tags']) != ) { // Delete all tags, then re-tag $freetag->delete_all_object_tags_for_user($tagger_id,$object_id); // Private bookmark? $private = 0; if(strpos(trim($_REQUEST['tags']), "@private") !== false) $private = 1; $this->Query("update ".$freetag_options['db_name'].".freetag_bookmarks set ". "title = '".mysql_real_escape_string($_REQUEST['title'])."', ". "uri = '".mysql_real_escape_string($this->cleanUrl($_REQUEST['uri']))."', ". "wikka_id = '".mysql_real_escape_string($wikka_id)."', ". "private = '".$private."', ". "description = '".mysql_real_escape_string($_REQUEST['desc'])."' ". "where bookmark_id = ".mysql_real_escape_string($object_id)." ". "limit 1;"); $freetag->tag_object($tagger_id, $obj['bookmark_id'], $_REQUEST['tags']); $this->Redirect($this->href()."&action=list_yours"); } // Display add form print($this->FormOpen()); ?> get_tags_on_object($object_id); $taglist =
Title:
URI:
Description:
Format("Use blank space between tags, include \"@private\" for private bookmark"); ?>
Tags:
;
foreach($tags as $idx=>$res) {
$taglist .= trim($res['raw_tag'])." ";
}
?>
<td><input name="tags" size="40" value="<?php print $taglist?>"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Edit" size="40" /></td>
</tr>
</table>
<?php
print($this->FormClose());
}

Delete entry
if(isset($_REQUEST['action']) && $_REQUEST['action']
"delete") {
$object_id = $_REQUEST['object_id'];
Is the logged-in user the owner?
if($wikka_id != $obj['wikka_id']) {
$this->Redirect($this->href()."&action=list_all");
}
Delete all tags first...
$freetag->delete_all_object_tags_for_user($tagger_id,$object_id);

...then delete object
$this->Query("delete from ".$freetag_options['db_name'].".freetag_bookmarks where bookmark_id = ".mysql_real_escape_string($object_id)." limit 1;");
$this->Redirect($this->href()."&action=list_yours");
}

List all bookmarks (ordered by most recent)
$offset = 0;
if(isset($_REQUEST['offset'])) {
$offset = $_REQUEST['offset'];
}
$limit = 25;
if(isset($_REQUEST['limit'])) {
$limit = $_REQUEST['limit'];
}

Output tag cloud
$url_opts = $this->href()."&action=list_all&tag=";
output_tag_cloud($freetag,$url_opts,NULL,"All tags:");

$ids = ; $tag = ;
if(isset($_REQUEST['tag']) && $_REQUEST['tag'] != ) { $ids = $freetag->get_most_recent_objects(NULL,$_REQUEST['tag'],$offset,$limit); $tag = $_REQUEST['tag']; } else { $ids = $freetag->get_most_recent_objects(NULL,NULL,$offset,$limit); } foreach($ids as $key=>$val) { $tags = $freetag->get_tags_on_object($val['object_id']); $obj = $this->LoadSingle("select title,uri,description,wikka_id from ".$freetag_options['db_name'].".freetag_bookmarks where bookmark_id = ".$val['object_id']." and private = 0;"); if(!isset($obj)) { continue; } print ".$obj['uri']."\">".$obj['title']."</a><br/>";
print "<div class=\"commentsheader\"><b>".$obj['description']."</b>";
print "<br/>";
$taglist = ; foreach($tags as $idx=>$res) { $taglist .= trim($res['tag'])." "; } print $taglist."by ".$obj['wikka_id']." (created: ".$val['tagged_on'].")"; print "
 
"; } // Display pagination links $obj_count = 0; $tag_url = ;
if($tag != ) { $obj_count = count_tagged_objects(NULL, $tag, $this, $freetag_options, $freetag); $tag_url = "&tag=".$tag; } else { $obj_count = count_objects(NULL, $this, $freetag_options); } $prev_offset = $offset - $limit; $prev_url = ;
if($prev_offset < 0) {
$prev_offset = 0;
}
if($offset > 0) {
$prev_url = "<a href=\.$this->href()."&action=list_all&offset=".$prev_offset."&limit=".$limit.$tag_url."\"><<"; } $next_offset = $offset + $limit; $next_url = ;
if($next_offset < $obj_count - 1) {
$next_url = "<a href=\.$this->href()."&action=list_all&offset=".$next_offset."&limit=".$limit.$tag_url."\">>>"; } print "

"; print "

"; print $prev_url." ".$next_url; print "
"; } // List user bookmarks (ordered by most recent) if(isset($_REQUEST['action']) && ($_REQUEST['action']=="list_yours")) { $offset = 0; if(isset($_REQUEST['offset'])) { $offset = $_REQUEST['offset']; } $limit = 25; if(isset($_REQUEST['limit'])) { $limit = $_REQUEST['limit']; } // Output tag cloud $url_opts = $this->href()."&action=list_yours&tag="; output_tag_cloud($freetag,$url_opts,$tagger_id,"Your tags:"); $ids = ;
$tag = ; if(isset($_REQUEST['tag']) && $_REQUEST['tag'] != ) {
$ids = $freetag->get_most_recent_objects($tagger_id, $_REQUEST['tag'], $offset, $limit);
$tag = $_REQUEST['tag'];
} else {
$ids = $freetag->get_most_recent_objects($tagger_id, NULL, $offset, $limit);
}

foreach($ids as $key=>$val) {
$tags = $freetag->get_tags_on_object($val['object_id']);
$obj = $this->LoadSingle("select title,uri,description,wikka_id from ".$freetag_options['db_name'].".freetag_bookmarks where bookmark_id = ".$val['object_id'].";");
print "<a href=\.$obj['uri']."\">".$obj['title']."
"; print "
".$obj['description'].""; print "
.$this->href()."&action=edit&object_id=".$val['object_id']."\">edit</a>";
print "|";
print "<a href=\.$this->href()."&action=delete&object_id=".$val['object_id']."\">delete"; print "
"; $taglist = ;
foreach($tags as $idx=>$res) {
$taglist .= trim($res['raw_tag'])." ";
}
print $taglist."by ".$obj['wikka_id']." (created: ".$val['tagged_on'].")</div>";
print "<div class=\"clear\"> </div>";
}

Display pagination links
$obj_count = 0;
$tag_url = ; if($tag != ) {
$obj_count = count_tagged_objects($wikka_id, $tag, $this, $freetag_options, $freetag);
$tag_url = "&tag=".$tag;
} else {
$obj_count = count_objects($wikka_id, $this, $freetag_options);
}
$prev_offset = $offset - $limit;
$prev_url = ; if($prev_offset < 0) { $prev_offset = 0; } if($offset > 0) { $prev_url = ".$this->href()."&action=list_yours&offset=".$prev_offset."&limit=".$limit.$tag_url."\"><<</a>";
}
$next_offset = $offset + $limit;
$next_url = ; if($next_offset < $obj_count - 1) { $next_url = ".$this->href()."&action=list_yours&offset=".$next_offset."&limit=".$limit.$tag_url."\">>></a>";
}
print "<p><p>";
print "<div class=\"center\">";
print $prev_url." ".$next_url;
print "</div>";
}
?>
	- Save the following file as ##actions/Wikka.freetag.class.php## (needs to be moved to libs/ eventually):

**Wikka.freetag.class.php**
(php)
<?php
Check for freetag library
$freetag_lib = '3rdparty/plugins/freetag/freetag.class.php';
if(!is_file($freetag_lib)) {
print("<br/><br/><div class=\"error\">".$this->Format("Can't find $freetag_lib!")."<br/><br/>\n");
die();
}
include_once($freetag_lib);

class wikka_freetag extends freetag {

function wikka_freetag($freetag_options) {
parent::freetag($freetag_options);
}

function get_most_recent_objects($tagger_id = NULL, $tag = NULL, $offset = 0, $limit = 25) {
$db = $this->db;
if(isset($tagger_id)) {
$tagger_sql = "AND tagger_id = $tagger_id";
} else {
$tagger_sql = ; } $prefix = $this->_table_prefix; $sql = ;
if(!$tag) {
$sql = "SELECT DISTINCT object_id, tagged_on FROM
${prefix}freetagged_objects
WHERE 1
$tagger_sql
ORDER BY tagged_on DESC
LIMIT $offset, $limit ";
} else {
$tag = $db->qstr($tag, get_magic_quotes_gpc());
$sql = "SELECT DISTINCT object_id, tagged_on
FROM ${prefix}freetagged_objects INNER JOIN ${prefix}freetags ON (tag_id = id)
WHERE tag = $tag
$tagger_sql
ORDER BY tagged_on DESC
LIMIT $offset, $limit ";
}

$rs = $db->Execute($sql) or die("Syntax Error: $sql");
$retarr = array();
while(!$rs->EOF) {
$retarr[] = array(
'object_id' => $rs->fields['object_id'],
'tagged_on' => $rs->fields['tagged_on']
);
$rs->MoveNext();
}
return $retarr;
}
}
	- Adjust the DB connection parameters for your own installation

	- (Optional) After line 918 in ##freetag.class.php##, add the following line to prevent @private tags from cluttering up the landscape:
(php)
foreach ($tag_list as $tag => $qty) {
Add the following line:
if(strpos($tag, "private") !
$size = $min_font_size + ($qty - $min_qty) * $step;
	- Add the ""{{bookmarks}}"" handler code to a new page

==Other stuff==

	- The two Perl scripts that follow can be used to import bookmarks from de.lirio.us.  Use your browser to save a page of bookmarks as an HTML file (you might have to save multiple pages; that's OK, the script can handle it). Export the HTML data into text format:

parseDelirious.pl file1.html file2.html file3.html > myLinks.txt
Change the ##$base_url##, ##$wikiname##, and ##$password## global vars in ##importDelirious.pl##, then run against the file created in the previous step:

importDelirious.pl myLinks.txt
##parseDelirious.pl##
(perl)
#! /usr/bin/perl
#
# $Id: parseDelirious.pl,v 1.2 2006/05/30 03:27:21 brian Exp brian $
#
# parseDelirious.pl - Parses a de.lirio.us screen dump (as saved by
# Firefox)
#
#
require HTML::TreeBuilder;

foreach my $filename(@ARGV) {
my $tree = HTML::TreeBuilder->new;
$tree->parse_file($filename);
$tree->elementify();
@nodes = $tree->look_down("class","xfolkentry");
foreach $node(@nodes) {
$_ = $node->look_down("class","uri");
$link = $_->extract_links();
$title = $link->[0]->[1]->as_text();
print "Title: $title\n";
print "URI: $link->[0]->[0]\n";

# Get description, if any
$_=$node->look_down("class","extended");
print "Desc: ";
if($_) {
$desc = $_->as_text();
print "$desc";
}
print "\n";

# A de.lirio.us export quirk prevents some tags from
# displaying; default these to "@private" for later review
@_ = $node->look_down("class","tag");
print "Tags: ";
if($#_ < 0) {
print "\@private";
}
foreach $tagnode(@_) {
$link = $tagnode->extract_links();
$tag = $link->[0]->[1]->as_text();
print "$tag ";
}
print "\n\n\n";
}
$tree = $tree->delete;
}
##importDelirious.pl##
(perl)
#! /usr/bin/perl
#
# $Id: importDelirious.pl,v 1.3 2006/05/31 04:43:19 brian Exp brian $
#
# importDelirious.pl -- Imports file created by parseDelirious.pl
#
# Usage: importDelirious.pl exportFile
#
#

require LWP::UserAgent;
require HTTP::Cookies;

#Global#
$base_url = "
http://some.url.com/wiki/";
$bookmark_page = "Bookmarks";
$wikiname = "
YourName";
$password = "yourpassword";

$ua = LWP::UserAgent->new;
$cookie_jar = HTTP::Cookies->new(file => "lwpcookies.txt",
autosave => 1);
$ua->cookie_jar($cookie_jar);

# Login
$login_url = $base_url."wikka.php?wakka=
UserSettings";
my $req = HTTP::Request->new(POST=>"$login_url");
$req->content_type('application/x-www-form-urlencoded');
$req->content("name=$wikiname&password=$password&action=login&wakka=
UserSettings");
my $res = $ua->request($req);
$cookie_jar->extract_cookies($res);

# Import
open(IN, "<$ARGV[0]")
die "Can't open $ARGV[0] for reading!";
# Set autoflush so progress is displayed
my $oldfh = select(STDOUT); $| = 1; select($oldfh);
print "Importing...";
while(<IN>) {
print ".";
next until /Title: /;
chomp;
$title = (split(": ",$_))[1];
$_ = <IN>;
chomp;
$uri = (split(": ",$_))[1];
$_ = <IN>;
chomp;
$desc = (split(": ",$_))[1];
$_ = <IN>;
chomp;
$tags = (split(": ",$_))[1];
$add_url = $base_url."wikka.php?wakka=".$bookmark_page."&action=add";
$req = HTTP::Request->new(POST=>"$add_url");
$req->content_type('application/x-www-form-urlencoded');
$req->content("title=$title&uri=$uri&desc=$desc&tags=$tags");
$ua->request($req);
}
print "done!\n";
%%



Category
CategoryDevelopmentDiscussion
There are 39 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki