[Slashdotjp-dev 1307] [836] merged from upstream T_2_5_0_231 branch

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2008年 11月 26日 (水) 15:51:21 JST


Revision: 836
          http://svn.sourceforge.jp/view?root=slashdotjp&view=rev&rev=836
Author:   tach
Date:     2008-11-26 15:51:20 +0900 (Wed, 26 Nov 2008)

Log Message:
-----------
merged from upstream T_2_5_0_231 branch

Modified Paths:
--------------
    slashjp/branches/upstream/current/Makefile
    slashjp/branches/upstream/current/Slash/Apache/User/User.pm
    slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/common.js
    slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/tag-ui.css
    slashjp/branches/upstream/current/plugins/Bookmark/bookmark.pl
    slashjp/branches/upstream/current/plugins/Bookmark/mysql_schema.sql
    slashjp/branches/upstream/current/plugins/Console/console.pl
    slashjp/branches/upstream/current/plugins/FireHose/FireHose.pm
    slashjp/branches/upstream/current/plugins/FireHose/firehose.pl
    slashjp/branches/upstream/current/plugins/FireHose/index2.pl
    slashjp/branches/upstream/current/plugins/FireHose/mysql_dump.sql
    slashjp/branches/upstream/current/plugins/FireHose/mysql_schema.sql
    slashjp/branches/upstream/current/plugins/FireHose/templates/dispFireHose;firehose;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/fhadvprefpane;misc;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/firehose_tabs;misc;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseIntro;misc;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseTitle;misc;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/list;firehose;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/paginate;firehose;default
    slashjp/branches/upstream/current/plugins/FireHose/templates/tag_widget;firehose;default
    slashjp/branches/upstream/current/plugins/Journal/Journal.pm
    slashjp/branches/upstream/current/plugins/Journal/journal.pl
    slashjp/branches/upstream/current/plugins/Submit/submit.pl
    slashjp/branches/upstream/current/plugins/Tags/PLUGIN
    slashjp/branches/upstream/current/plugins/Tags/mysql_schema.sql
    slashjp/branches/upstream/current/plugins/Zoo/Zoo.pm
    slashjp/branches/upstream/current/sql/mysql/defaults.sql
    slashjp/branches/upstream/current/sql/mysql/upgrades
    slashjp/branches/upstream/current/tagboxes/FHEditorPop/FHEditorPop.pm
    slashjp/branches/upstream/current/tagboxes/FireHoseScores/FireHoseScores.pm
    slashjp/branches/upstream/current/themes/slashcode/THEME
    slashjp/branches/upstream/current/themes/slashcode/htdocs/slashcode_lite.css
    slashjp/branches/upstream/current/themes/slashcode/htdocs/users.pl
    slashjp/branches/upstream/current/themes/slashcode/htdocs/users2.pl
    slashjp/branches/upstream/current/themes/slashcode/templates/userInfo2;users;default
    slashjp/branches/upstream/current/utils/import_journals_firehose
    slashjp/branches/upstream/current/utils/import_stories_firehose

Added Paths:
-----------
    slashjp/branches/upstream/current/plugins/Tags/archive_globjs_viewed.pl
    slashjp/branches/upstream/current/plugins/Users2/
    slashjp/branches/upstream/current/plugins/Users2/MANIFEST
    slashjp/branches/upstream/current/plugins/Users2/Makefile.PL
    slashjp/branches/upstream/current/plugins/Users2/PLUGIN
    slashjp/branches/upstream/current/plugins/Users2/Users2.pm
    slashjp/branches/upstream/current/themes/slashcode/templates/u2AdminListComments;users;default
    slashjp/branches/upstream/current/themes/slashcode/templates/u2CommentsDatapane;users;default
    slashjp/branches/upstream/current/themes/slashcode/templates/u2ListComments;users;default
    slashjp/branches/upstream/current/themes/slashcode/templates/u2MainView;users;default
    slashjp/branches/upstream/current/themes/slashcode/templates/u2Menu;users;default
    slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBio;users;default
    slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBoxes;users;default


-------------- next part --------------
Modified: slashjp/branches/upstream/current/Makefile
===================================================================
--- slashjp/branches/upstream/current/Makefile	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/Makefile	2008-11-26 06:51:20 UTC (rev 836)
@@ -46,7 +46,7 @@
 THEMEFILES = `find themes -name CVS -prune -o -name .git -prune -o -name [a-zA-z]\*.pl -print`
 PLUGINFILES = `find plugins themes/*/plugins -name CVS -prune -o -name .git -prune -o -name [a-zA-Z]\*.pl -print`
 TAGBOXFILES = `find tagboxes themes/*/tagboxes -name CVS -prune -o -name .git -prune -o -name [a-zA-Z]\*.pl -print`
-PLUGINSTALL = `find . -name CVS -prune -o -name .git -prune -o -type d -print | egrep 'plugins/[a-zA-Z]+$$'`
+PLUGINSTALL = `find . -name CVS -prune -o -name .git -prune -o -type d -print | egrep 'plugins/[a-zA-Z0-9]+$$'`
 TAGINSTALL = `find . -name CVS -prune -o -name .git -prune -o -type d -print | egrep 'tagboxes/[a-zA-Z]+$$'`
 PLUGINDIRS = `find . -name CVS -prune -o -name .git -prune -o -type d -print | egrep 'plugins$$'`
 TAGBOXDIRS = `find . -name CVS -prune -o -name .git -prune -o -type d -print | egrep 'tagboxes$$'`

Modified: slashjp/branches/upstream/current/Slash/Apache/User/User.pm
===================================================================
--- slashjp/branches/upstream/current/Slash/Apache/User/User.pm	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/Slash/Apache/User/User.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -395,7 +395,7 @@
 		$r->err_header_out(Location =>
 			URI->new_abs('/', $constants->{absolutedir})
 		);
-	       return REDIRECT;
+		return REDIRECT;
 	}
 
 	# If the user is connecting over SSL, make sure this is allowed.
@@ -404,7 +404,7 @@
 	# If allow_nonadmin_ssl is 2, then admins and subscribers are allowed in.
 	my $redirect_to_nonssl = 0;
 	if ($is_ssl && !(
-                        # If the user is trying to log in, they are always
+			# If the user is trying to log in, they are always
 			# allowed to make the attempt on the SSL server.
 			# Logging in means the users.pl script and either
 			# an empty op or the 'userlogin' op.
@@ -413,7 +413,7 @@
 			||
 			$uri =~ m{^/(?:users|login)\.pl}
 			) && (!$form->{op} || $form->{op} eq 'userlogin')
-                )
+		)
 	) {
 		my $ans = $constants->{allow_nonadmin_ssl};
 		if ($ans == 1) {
@@ -436,14 +436,14 @@
 			# also subscribers are allowed in.
 			if ($user->{seclev} > 1 || $user->{state}{lostprivs}
 				|| $user->{is_subscriber}) {
-                                # It's an admin or a subscriber, this is fine.
-                        } else {
-                                # Not an admin or subscriber, SSL access forbidden.
-                                $redirect_to_nonssl = 1;
-                        }
+				# It's an admin or a subscriber, this is fine.
+			} else {
+				# Not an admin or subscriber, SSL access forbidden.
+				$redirect_to_nonssl = 1;
+			}
 		}
 	}
-	if ($redirect_to_nonssl) {                             
+	if ($redirect_to_nonssl) {
 		# User is not authorized to connect to the SSL webserver.
 		# Redirect them to the non-SSL URL.
 		my $newloc = $uri;
@@ -590,13 +590,13 @@
 		return OK;
 	}
 
-        if ($uri =~ m[^/help (?: /([^?]*) | /? ) $]x) {
-                $r->args("op=displayhelp");
-                $r->uri('/help.pl');
-                $r->filename($constants->{basedir} . '/help.pl');
-                return OK;
-        }
-       
+	if ($uri =~ m[^/help (?: /([^?]*) | /? ) $]x) {
+		$r->args("op=displayhelp");
+		$r->uri('/help.pl');
+		$r->filename($constants->{basedir} . '/help.pl');
+		return OK;
+	}
+
 	# for self-references (/~/ and /my/)
 	if (($saveuri =~ m[^/(?:%7[eE]|~)] && $uri =~ m[^/~ (?: /(.*) | /? ) $]x)
 		# /my/ or /my can match, but not /mything
@@ -633,17 +633,23 @@
 			} elsif ($logged_in) {
 				$found_the_op = 1;
 				if ($op eq 'journal') {
-					my $args;
-					if ($extra =~ /^\d+$/) {
-						$args = "id=$extra&op=edit";
-					} elsif ($extra eq 'friends') {
-						$args = "op=friendview";
+					if ($constants->{u2}) {
+						$r->args("op=userinfo&dp=journal");
+						$r->uri('/users2.pl');
+						$r->filename($constants->{basedir} . '/users2.pl');
 					} else {
-						$args = "op=list";
+						my $args;
+						if ($extra =~ /^\d+$/) {
+							$args = "id=$extra&op=edit";
+						} elsif ($extra eq 'friends') {
+							$args = "op=friendview";
+						} else {
+							$args = "op=list";
+						}
+						$r->args($args);
+						$r->uri('/journal.pl');
+						$r->filename($constants->{basedir} . '/journal.pl');
 					}
-					$r->args($args);
-					$r->uri('/journal.pl');
-					$r->filename($constants->{basedir} . '/journal.pl');
 
 				} elsif ($op eq 'discussions') {
 					$r->args("op=personal_index");
@@ -657,25 +663,48 @@
 					$r->filename($constants->{basedir} . '/messages.pl');
 
 				} elsif ($op =~ /^(?:friends|fans|freaks|foes|zoo)$/) {
-					my $args = "op=$op";
-					$extra .= '/';
+					if ($constants->{u2}) {
+						$extra .= '/';
 
-					if ($op eq 'friends' && $extra =~ s/^friends\///) {
-						$args =~ s/friends/fof/;
-					} elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
-						$args =~ s/friends/eof/;
-					} elsif ($op eq 'zoo') {
-						$args =~ s/zoo/all/;
+						if ($op eq 'friends' && $extra =~ s/^friends\///) {
+							$op =~ s/friends/fof/;
+						} elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
+							$op =~ s/friends/eof/;
+						} elsif ($op eq 'zoo') {
+							$op =~ s/zoo/all/;
+						}
+
+						my $args = "op=userinfo&dp=$op";
+						$r->args($args);
+						$r->uri('/users2.pl');
+						$r->filename($constants->{basedir} . '/users2.pl');
+					} else {
+						my $args = "op=$op";
+						$extra .= '/';
+
+						if ($op eq 'friends' && $extra =~ s/^friends\///) {
+							$args =~ s/friends/fof/;
+						} elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
+							$args =~ s/friends/eof/;
+						} elsif ($op eq 'zoo') {
+							$args =~ s/zoo/all/;
+						}
+
+						$r->args($args);
+						$r->uri('/zoo.pl');
+						$r->filename($constants->{basedir} . '/zoo.pl');
 					}
 
-					$r->args($args);
-					$r->uri('/zoo.pl');
-					$r->filename($constants->{basedir} . '/zoo.pl');
-
 				} elsif ($op eq 'comments') {
-					$r->args("op=editcomm");
-					$r->uri('/users.pl');
-					$r->filename($constants->{basedir} . '/users.pl');
+					if ($constants->{u2}) {
+						$r->args("op=userinfo&dp=comments");
+						$r->uri('/users2.pl');
+						$r->filename($constants->{basedir} . '/users2.pl');
+					} else {
+						$r->args("op=editcomm");
+						$r->uri('/users.pl');
+						$r->filename($constants->{basedir} . '/users.pl');
+					}
 
 				} elsif ($op eq 'homepage') {
 					$r->args("op=edithome");
@@ -703,28 +732,47 @@
 					$r->filename($constants->{basedir} . '/journal.pl');
 
 				} elsif ($op eq 'tags') {
-					my $args = 'op=showtags';
-					# XXX "!" is a 'reserved' char in URI, escape it here?
-					$args .= "&tagname=$extra" if $extra;
-					$r->args($args);
-					$r->uri('/users.pl');
-					$r->filename($constants->{basedir} . '/users.pl');
+					if ($constants->{u2}) {
+						$r->args("op=userinfo&dp=tags");
+						$r->uri('/users2.pl');
+						$r->filename($constants->{basedir} . '/users2.pl');
+					} else {
+						my $args = 'op=showtags';
+						# XXX "!" is a 'reserved' char in URI, escape it here?
+						$args .= "&tagname=$extra" if $extra;
+						$r->args($args);
+						$r->uri('/users.pl');
+						$r->filename($constants->{basedir} . '/users.pl');
+					}
 
 				} elsif ($op eq 'bookmarks') {
-					$r->args("op=showbookmarks");
-					$r->uri('/users.pl');
-					$r->filename($constants->{basedir} . '/users.pl');
+					if ($constants->{u2}) {
+						$r->args("op=userinfo&dp=bookmarks");
+						$r->uri('/users2.pl');
+						$r->filename($constants->{basedir} . '/users2.pl');
+					} else {
+						$r->args("op=showbookmarks");
+						$r->uri('/users.pl');
+						$r->filename($constants->{basedir} . '/users.pl');
+					}
 
 				} elsif ($op eq 'firehose') {
-					my $filter = fixparam("user:");
-					$r->args("op=userfirehose");
-					$r->uri('users.pl');
-					$r->filename($constants->{basedir} . '/users.pl');
+					if ($constants->{u2}) {
+						my $filter = fixparam("user:");
+						$r->args("op=userinfo&dp=firehose");
+						$r->uri('/users2.pl');
+						$r->filename($constants->{basedir} . '/users2.pl');
+					} else {
+						my $filter = fixparam("user:");
+						$r->args("op=userfirehose");
+						$r->uri('users.pl');
+						$r->filename($constants->{basedir} . '/users.pl');
+					}
 
-                                } elsif ($op eq 'preferences') {
-                                        $r->args("op=displayprefs");
-                                        $r->uri('/preferences.pl');
-                                        $r->filename($constants->{basedir} . '/preferences.pl');
+				} elsif ($op eq 'preferences') {
+					$r->args("op=displayprefs");
+					$r->uri('/preferences.pl');
+					$r->filename($constants->{basedir} . '/preferences.pl');
 
 				} else {
 					$r->args("op=edituser");
@@ -784,31 +832,40 @@
 			$r->filename($constants->{basedir} . '/users.pl');
 
 		} elsif ($op eq 'journal') {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                $r->args("nick=$nick&dp=journal&uid=$uid");
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        my $args = "op=display&nick=$nick&uid=$uid";
-			        $extra .= '/' . $more;
-			        if ($extra) {
-				        if ($extra =~ /^(\d+)\/$/) {
-					        $args .= "&id=$1";
-				        }
-				        if ($extra =~ s/^friends\///) {
-					        $args =~ s/display/friendview/;
-				        }
-				        if ($extra =~ m{^ (rss|atom) / ? $}x) {
-					        $args .= "&logtoken=$logtoken" if $logtoken;
-					        $args .= "&content_type=$1";
-				        }
-			        }
+			$extra .= '/' . $more;
 
-			        $args .= "&$query";
-			        $r->args($args);
-			        $r->uri('/journal.pl');
-			        $r->filename($constants->{basedir} . '/journal.pl');
-                        }
+			if (
+				($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2})
+						&&
+				!($extra =~ m{^ (rss|atom) /?$}x || $extra =~ /^(\d+)\/$/)
+			) {
+				my $args = "nick=$nick&uid=$uid&dp=journal";
+
+				if ($extra =~ s/^friends\///) { # show hose in friend view
+					$args .= 'friends';
+				}
+
+				$r->args($args);
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+
+			} else {
+				my $args = "op=display&nick=$nick&uid=$uid";
+				if ($extra =~ /^(\d+)\/$/) {
+					$args .= "&id=$1";
+				} elsif ($extra =~ s/^friends\///) {
+					$args =~ s/display/friendview/;
+				}
+				if ($extra =~ m{^ (rss|atom) / ? $}x) {
+					$args .= "&logtoken=$logtoken" if $logtoken;
+					$args .= "&content_type=$1";
+				}
+
+				$args .= "&$query";
+				$r->args($args);
+				$r->uri('/journal.pl');
+				$r->filename($constants->{basedir} . '/journal.pl');
+			}
 		} elsif ($op eq 'discussions') {
 			$r->args("op=creator_index&nick=$nick&uid=$uid");
 			$r->uri('/comments.pl');
@@ -820,99 +877,115 @@
 			$r->filename($constants->{basedir} . '/pubkey.pl');
 
 		} elsif ($op eq 'submissions') {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                $r->args("nick=$nick&dp=submissions&uid=$uid");
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        $r->args("nick=$nick&op=usersubmissions&uid=$uid");
-			        $r->uri('/users.pl');
-			        $r->filename($constants->{basedir} . '/users.pl');
-                        }
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				$r->args("nick=$nick&dp=submissions&uid=$uid");
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+			} else {
+				$r->args("nick=$nick&op=usersubmissions&uid=$uid");
+				$r->uri('/users.pl');
+				$r->filename($constants->{basedir} . '/users.pl');
+			}
 		} elsif ($op eq 'comments') {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                $r->args("nick=$nick&dp=comments&uid=$uid");
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        $r->args("nick=$nick&op=usercomments&uid=$uid");
-			        $r->uri('/users.pl');
-			        $r->filename($constants->{basedir} . '/users.pl');
-                        }
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				$r->args("nick=$nick&dp=comments&uid=$uid");
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+			} else {
+				$r->args("nick=$nick&op=usercomments&uid=$uid");
+				$r->uri('/users.pl');
+				$r->filename($constants->{basedir} . '/users.pl');
+			}
 		} elsif ($op =~ /^(?:friends|fans|freaks|foes|zoo)$/) {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                my $args = "nick=$nick&dp=friends&uid=$uid";
-                                $extra .= '/' . $more;
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				my $args = "nick=$nick&uid=$uid&dp=";
+				$extra .= '/' . $more;
 
-                                if ($op eq 'friends' && $extra =~ s/^friends\///) {
-                                        $args =~ s/friends/fof/;
-                                } elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
-                                        $args =~ s/friends/eof/;
-                                } elsif ($op eq 'zoo') {
-                                        $args =~ s/zoo/all/;
-                                }
+				if ($op eq 'friends' && $extra =~ s/^friends\///) {
+					$op =~ s/friends/fof/;
+				} elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
+					$op =~ s/friends/eof/;
+				} elsif ($op eq 'zoo') {
+					$op =~ s/zoo/all/;
+				}
 
-                                if ($extra =~ m{^ (rss|atom) /?$}x) {
-                                        $args .= "&content_type=$1";
-                                }
+				if ($extra =~ m{^ (rss|atom) /?$}x) {
+					my $args = "nick=$nick&uid=$uid&op=$op";
+					$args .= "&content_type=$1";
 
-                                $r->args($args);
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        my $args = "op=$op&nick=$nick&uid=$uid";
-			        $extra .= '/' . $more;
+					$r->args($args);
+					$r->uri('/zoo.pl');
+					$r->filename($constants->{basedir} . '/zoo.pl');
+				} else {
+					$r->args($args . $op);
+					$r->uri('/users2.pl');
+					$r->filename($constants->{basedir} . '/users2.pl');
+				}
+			} else {
+				my $args = "op=$op&nick=$nick&uid=$uid";
+				$extra .= '/' . $more;
 
-			        if ($op eq 'friends' && $extra =~ s/^friends\///) {
-				        $args =~ s/friends/fof/;
-			        } elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
-				        $args =~ s/friends/eof/;
-			        } elsif ($op eq 'zoo') {
-				        $args =~ s/zoo/all/;
-			        }
+				if ($op eq 'friends' && $extra =~ s/^friends\///) {
+					$args =~ s/friends/fof/;
+				} elsif ($op eq 'friends' && $extra =~ s/^foes\///) {
+					$args =~ s/friends/eof/;
+				} elsif ($op eq 'zoo') {
+					$args =~ s/zoo/all/;
+				}
 
-			        if ($extra =~ m{^ (rss|atom) /?$}x) {
-				        $args .= "&content_type=$1";
-			        }
+				if ($extra =~ m{^ (rss|atom) /?$}x) {
+					$args .= "&content_type=$1";
+				}
 
-			        $r->args($args);
-			        $r->uri('/zoo.pl');
-			        $r->filename($constants->{basedir} . '/zoo.pl');
-                        }
+				$r->args($args);
+				$r->uri('/zoo.pl');
+				$r->filename($constants->{basedir} . '/zoo.pl');
+			}
 
 		} elsif ($op eq 'amigos') {
-			$r->args("op=friendview&nick=$nick&uid=$uid");
-			$r->uri('/journal.pl');
-			$r->filename($constants->{basedir} . '/journal.pl');
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				$r->args("nick=$nick&uid=$uid&dp=journalfriends");
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+			} else {
+				$r->args("op=friendview&nick=$nick&uid=$uid");
+				$r->uri('/journal.pl');
+				$r->filename($constants->{basedir} . '/journal.pl');
+			}
 
 		} elsif ($op eq 'tags') {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                my $args = "nick=$nick&dp=tags&uid=$uid";
-                                $args .= "&tagname=$extra" if $extra;
-                                $r->args($args);
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        my $args = "op=showtags&nick=$nick&uid=$uid";
-			        # XXX "!" is a 'reserved' char in URI, escape it here?
-			        $args .= "&tagname=$extra" if $extra;
-			        $r->args($args);
-			        $r->uri('/users.pl');
-			        $r->filename($constants->{basedir} . '/users.pl');
-                        }
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+				my $args;
+				if ($extra) {
+					$args = "op=userinfo&nick=$nick&dp=usertag&uid=$uid";
+					$args .= "&tagname=$extra" if $extra;
+				} else {
+					$args = "op=userinfo&uid=$uid&nick=$nick&dp=tags";		
+				}
+				$r->args($args);
+			} else {
+				my $args = "op=showtags&nick=$nick&uid=$uid";
+				# XXX "!" is a 'reserved' char in URI, escape it here?
+				$args .= "&tagname=$extra" if $extra;
+				$r->args($args);
+				$r->uri('/users.pl');
+				$r->filename($constants->{basedir} . '/users.pl');
+			}
 
 		} elsif ($op eq 'bookmarks') {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                $r->args("nick=$nick&dp=bookmarks&uid=$uid");
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        $r->args("op=showbookmarks&nick=$nick&uid=$uid");
-			        $r->uri('/users.pl');
-			        $r->filename($constants->{basedir} . '/users.pl');
-		        }
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				$r->args("nick=$nick&dp=bookmarks&uid=$uid");
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+			} else {
+				$r->args("op=showbookmarks&nick=$nick&uid=$uid");
+				$r->uri('/users.pl');
+				$r->filename($constants->{basedir} . '/users.pl');
+			}
 		} elsif ($op eq 'firehose') {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
 				my $filter = fixparam("\"user:$nick_orig\"");
 				$r->args("dp=firehose&uid=$uid");
 				$r->uri('/users2.pl');
@@ -923,17 +996,22 @@
 				$r->uri('/users.pl');
 				$r->filename($constants->{basedir} . '/users.pl');
 			}
+		} elsif (($op eq 'admin' && $constants->{u2}) ||
+			 ($op eq 'admin' && $saveuri =~ m[^/(?:%5[eE]|\^)(.+)])) {
+			$r->args("nick=$nick&dp=admin&uid=$uid");
+                        $r->uri('/users2.pl');
+                        $r->filename($constants->{basedir} . '/users2.pl');
 
 		} else {
-                        if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)]) {
-                                $r->args("nick=$nick&uid=$uid");
-                                $r->uri('/users2.pl');
-                                $r->filename($constants->{basedir} . '/users2.pl');
-                        } else {
-			        $r->args("nick=$nick&uid=$uid");
-			        $r->uri('/users.pl');
-			        $r->filename($constants->{basedir} . '/users.pl');
-                        }
+			if ($saveuri =~ m[^/(?:%5[eE]|\^)(.+)] || $constants->{u2}) {
+				$r->args("nick=$nick&uid=$uid");
+				$r->uri('/users2.pl');
+				$r->filename($constants->{basedir} . '/users2.pl');
+			} else {
+				$r->args("nick=$nick&uid=$uid");
+				$r->uri('/users.pl');
+				$r->filename($constants->{basedir} . '/users.pl');
+			}
 		}
 
 		return OK;

Modified: slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/common.js
===================================================================
--- slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/common.js	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/common.js	2008-11-26 06:51:20 UTC (rev 836)
@@ -29,6 +29,10 @@
   firehose_settings.color = '';
   firehose_settings.orderby = '';
   firehose_settings.orderdir = '';
+  firehose_settings.view = '';
+  firehose_settings.tab = '';
+  firehose_settings.fhfilter  = '';
+  firehose_settings.base_filter = '';
 
   firehose_settings.issue = '';
   firehose_settings.is_embedded = 0;
@@ -324,7 +328,7 @@
 	after_article_moved($('#firehose-'+id)[0]);
 }
 
-function firehose_set_options(name, value) {
+function firehose_set_options(name, value, context) {
 	if (firehose_user_class === 0) {
 		return;
 	}
@@ -343,10 +347,11 @@
 	];
 	var params = {};
 	params.setting_name = name;
+	params.context = context;
 	params.op = 'firehose_set_options';
 	params.reskey = reskey_static;
 	var theForm = document.forms.firehoseform;
-	if (name == "firehose_usermode") {
+	if (name == "usermode") {
 		value = value ? 1 : 0;
 		params.setusermode = 1;
 		params[name] = value;
@@ -376,14 +381,30 @@
 		}
 		firehose_settings.page = 0;
 		firehose_settings.more_num = 0;
+		params.filterchanged = 1;
 	}
 
 	if (name == "setfhfilter") {
 		firehose_settings.fhfilter = value;
 		firehose_settings.page = 0;
 		firehose_settings.more_num = 0;
+		params.filterchanged = 1;
 	}
 
+	if (name == "view") {
+		firehose_settings.view = value;	
+		params.viewchanged = 1;
+		firehose_settings.page = 0;
+		firehose_settings.more_num = 0;
+	}
+	
+	if (name == "tab") {
+		firehose_settings.tab = value;	
+		params.tabchanged = 1;
+		firehose_settings.page = 0;
+		firehose_settings.more_num = 0;
+	}
+
 	if (name != "color") {
 	for (i=0; i< pairs.length; i++) {
 		var el = pairs[i];
@@ -400,7 +421,7 @@
 			}
 		}
 	}
-	if (name == "mode" || name == "firehose_usermode" || name == "tab" || name == "mixedmode" || name == "nocolors" || name == "nothumbs") {
+	if (name == "mode" || name == "firehose_usermode" || name == "tab" || name == "mixedmode" || name == "nocolors" || name == "nothumbs" || name == "view") {
 		// blur out then remove items
 		if (name == "mode") {
 			fh_view_mode = value;
@@ -568,6 +589,9 @@
 }
 
 function firehose_click_tag( event ) {
+	// _any_ click can trigger, but click-specific ad will win
+	setTimeout(function(){ inlineAdFirehose(); }, 0);
+
 	var $target = $(event.target), command='', $menu;
 
 	$related_trigger = $target;
@@ -1097,8 +1121,10 @@
 				}
 				if ( firehose_future[firehose_ordered[i]] ) {
 					$('#ttype-'+firehose_ordered[i]).setClass('future');
+					$('#firehose-'+firehose_ordered[i] + "h3").setClass('future');
 				} else {
 					$('#ttype-'+firehose_ordered[i]+'.future').setClass('story');
+					$('#firehose-'+firehose_ordered[i] + "h3.future").setClass('story');
 				}
 			}
 			if ( moved ) after_article_moved();
@@ -1260,10 +1286,10 @@
 	show_modal_box();
 }
 
-function firehose_play() {
+function firehose_play(context) {
 	fh_play = 1;
 	setFirehoseAction();
-	firehose_set_options('pause', '0');
+	firehose_set_options('pause', '0', context);
 	$('#message_area').html('');
 	$('#pauseorplay').html('Updated');
 	$('#play').setClass('hide');
@@ -1274,12 +1300,12 @@
   return fh_play==1;
 }
 
-function firehose_pause() {
+function firehose_pause(context) {
 	fh_play = 0;
 	$('#pause').setClass('hide');
 	$('#play').setClass('show');
 	$('#pauseorplay').html('Paused');
-	firehose_set_options('pause', '1');
+	firehose_set_options('pause', '1', context);
 }
 
 function firehose_add_update_timerid(timerid) {
@@ -1858,9 +1884,12 @@
 	if (!fh_adTimerUrl)
 		return 0;
 
-	if (!$article)
+	if ($article)
+		$article = Slash.Firehose.at_or_below_ad_space($article);
+	else
 		$article = Slash.Firehose.choose_article_for_next_ad();
-	if (!$article)
+
+	if (!$article || !$article.length)
 		return 0;
 
 	var id = $article.article_info__key().key;
@@ -1913,7 +1942,7 @@
 $(function(){
 	$footer = $('#ft');
 	$slashboxes = $('#slashboxes').
-		append('<div id="floating-slashbox-ad" style="display:none; position:absolute; height:'+AD_HEIGHT+'px; width:'+AD_WIDTH+'px;" />');
+		append('<div id="floating-slashbox-ad" />');
 	$ad_position = $slashboxes.find('#floating-slashbox-ad');
 
 	$(window).scroll(fix_ad_position);
@@ -1938,7 +1967,6 @@
 		(
 			(a.has_content == b.has_content) &&
 			(a.is_in_window == b.is_in_window) &&
-			(a.top == b.top) &&
 			(a.pinned == b.pinned)
 		);
 }
@@ -1946,20 +1974,32 @@
 function set_mode( next ){
 	var cur = current_mode;
 
+	// if it's actually a change...
 	if ( ! if_same_mode(cur, next) ) {
-		if ( next.has_content ) {
-			if ( cur.has_content && (next.is_in_window || cur.is_in_window) ) {
-				$ad_position.animate({top: next.top}, 'fast');
+		if ( ! next.has_content ) {
+			$ad_position.hide();
+		} else if ( cur.pinned != next.pinned ) {
+			$ad_position.hide();
+
+			var next_class = next.pinned || '';
+			if ( next.pinned == 'Article' ) {
+				$current_article.
+					prepend($ad_position).
+					css('overflow', 'visible');
+			} else if ( next.pinned == 'Bottom' ) {
+				$slashboxes.after($ad_position);
+				next_class += ' yui_b';
 			} else {
-				$ad_position.hide().css({top: next.top});
-				if ( !cur.has_content ) {
-					$ad_position.fadeIn('fast');
-				} else {
-					$ad_position.show();
-				}
+				$slashboxes.append($ad_position);
 			}
-		} else {
-			$ad_position.hide();
+
+			$ad_position.setClass(next_class);
+
+			if ( !cur.has_content ) {
+				$ad_position.fadeIn('fast');
+			} else {
+				$ad_position.show();
+			}
 		}
 
 		var event_name;
@@ -2028,7 +2068,9 @@
 						top:		ad_top - slashboxes.top
 					};
 
-		if ( ad_top == article.top ) {
+		if ( space_bottom - space_top < AD_HEIGHT ) {
+			next_mode.pinned = 'SqueezedOut';
+		} else if ( ad_top == article.top ) {
 			next_mode.pinned = 'Article';
 		} else if ( ad_top < article.top ) {
 			next_mode.pinned = 'Bottom';
@@ -2103,12 +2145,16 @@
 	}
 }
 
+Slash.Firehose.at_or_below_ad_space = function( $articles ){
+	var min_top = Math.max(window.pageYOffset, $slashboxes.offset().top + $slashboxes.height());
+	return $articles.filter(function(){
+		return $(this).offset().top >= min_top;
+	});
+
+}
+
 Slash.Firehose.choose_article_for_next_ad = function(){
-	var $articles = Slash.Firehose.articles_on_screen();
-	// omit the first article (when we have more than one) if it starts above the screen
-	if ( ($articles.length > 1) && ($articles.offset().top < window.pageYOffset) ) {
-		$articles = $articles.filter(':gt(0)');
-	}
+	var Fh=Slash.Firehose, $articles=Fh.at_or_below_ad_space(Fh.articles_on_screen());
 	return $articles.eq( Math.floor(Math.random()*$articles.length) );
 }
 

Modified: slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/tag-ui.css
===================================================================
--- slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/tag-ui.css	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Ajax/htdocs/images/tag-ui.css	2008-11-26 06:51:20 UTC (rev 836)
@@ -94,8 +94,15 @@
 div.tag-display li.t > .tmenu li.ignore,
 div.tag-display li.t > .tmenu li.descriptive {
 	display: inline-block;
+/*text-decoration:none !important;*/
 }
 
+div.tag-display li.u {
+text-decoration:none !important;
+}
+
+
+
 /* no menus for newly added tags */
 .tag-display li.not-saved .tmenu,
 .tag-display[context=signoff] .tmenu,
@@ -525,3 +532,10 @@
 border-top:1px solid transparnt !important;
 }
 
+
+
+
+/* trying to fix opera */ /*commented out because this breaks ff2*/
+/*
+div.tag-display ul, div.tag-display li {display: inline-block;}
+*/

Modified: slashjp/branches/upstream/current/plugins/Bookmark/bookmark.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/Bookmark/bookmark.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Bookmark/bookmark.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -133,51 +133,6 @@
 		}
 	}
 
-        if (!$user->{is_anon}) {
-                my $events = $slashdb->sqlSelectAllHashref(
-                        'eid', 'eid, date', 'user_events', "uid = " . $user->{uid}  . " and code = 4");
-
-                # Delete the oldest event for this user if they already have 5 events.
-                if ((scalar keys %$events) == 5) {
-                        my $eid = [sort keys %$events]->[0];
-                        $slashdb->sqlDelete('user_events', "uid = " . $user->{uid}  . " and code = 4 and eid = $eid");
-                }
-
-                # Insert event
-                $slashdb->sqlInsert('user_events', {
-                        code  => 4,
-                        uid   => $user->{uid},
-                        event => $bookmark_id,
-                        -date  => 'NOW()',
-                });
-
-                # Create/update event block
-                my $event_blocks = $slashdb->sqlSelectAllHashref(
-                        'uid', 'bid, uid, block', 'user_event_blocks', "uid = " . $user->{uid} . " and code = 4");
-
-                # New block
-                if (!%$event_blocks) {
-                        $slashdb->sqlInsert('user_event_blocks', {
-                                code  => 4,
-                                uid   => $user->{uid},
-                                block => $bookmark_id
-                        });
-                } else {
-                        my @blocks = split(/,/, $event_blocks->{$user->{uid}}->{block});
-
-                        # Remove oldest event from this block
-                        if (scalar @blocks == 5) {
-                                @blocks = @blocks[1 .. 4];
-                        }
-
-                        # Append new event
-                        $blocks[$#blocks + 1] = $bookmark_id;
-                        my $new_blocks = join(",", @blocks);
-
-                        $slashdb->sqlUpdate('user_event_blocks', { block => $new_blocks }, "uid = " . $user->{uid} . " and code = 4");
-                }
-        }
-
 	my $tags = getObject('Slash::Tags');
 
 	$tags->setTagsForGlobj($url_id, "urls", $form->{tags});

Modified: slashjp/branches/upstream/current/plugins/Bookmark/mysql_schema.sql
===================================================================
--- slashjp/branches/upstream/current/plugins/Bookmark/mysql_schema.sql	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Bookmark/mysql_schema.sql	2008-11-26 06:51:20 UTC (rev 836)
@@ -2,7 +2,7 @@
 CREATE TABLE bookmarks (
 	bookmark_id MEDIUMINT UNSIGNED NOT NULL auto_increment,
 	uid MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
-	url_id MEDIUMINT UNSIGNED NOT NULL,
+	url_id INT UNSIGNED NOT NULL,
 	createdtime DATETIME NOT NULL,
 	title VARCHAR(255),
 	srcid_32 BIGINT UNSIGNED NOT NULL DEFAULT 0,

Modified: slashjp/branches/upstream/current/plugins/Console/console.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/Console/console.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Console/console.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -56,7 +56,7 @@
 	if ($constants->{plugin}{FireHose}) {
 		my $firehose = getObject("Slash::FireHose");
 		local $user->{state}{firehose_page} = 'console';
-		$firehosebox = $firehose->listView({ fh_page => 'console.pl'});
+		$firehosebox = $firehose->listView({ fh_page => 'console.pl', view => 'daddypants'});
 	}
 	my $tagnamesbox = '';
 	my $tags = getObject('Slash::Tags');

Modified: slashjp/branches/upstream/current/plugins/FireHose/FireHose.pm
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/FireHose.pm	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/FireHose.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -197,7 +197,7 @@
 		my $publish    = $journal->{promotetype} eq 'publish';
 		my $color_lvl  = $publicize ? 5 : $publish ? 6 : 7; # post == 7
 		my $editor_lvl = $publicize ? 5 : $publish ? 6 : 8; # post == 8
-		my $public     = ($publish || $publicize) ? 'yes' : 'no';
+		my $public     = 'yes';
 		my $popularity = $self->getEntryPopularityForColorLevel($color_lvl);
 		my $editorpop  = $self->getEntryPopularityForColorLevel($editor_lvl);
 
@@ -631,10 +631,18 @@
 	my @where;
 	my $tables = 'firehose';
 	my $filter_globjids;
+	my $tags = getObject('Slash::Tags');
+
+	if ($options->{tagged_as} || $options->{tagged_by_uid}) {
+		$tables .= ', tags';
+		push @where, 'tags.globjid=firehose.globjid';
+	}
+	if ($options->{tagged_as}) {
+		my $tag_id = $tags->getTagnameidFromNameIfExists($options->{tagged_as}) || 0;
+		push @where, "tags.tagnameid = $tag_id";
+	}
 	if ($options->{tagged_by_uid} && (!$doublecheck || $options->{ignore_nix})) {
 		my $tag_by_uid_q = $self->sqlQuote($options->{tagged_by_uid});
-		$tables .= ', tags';
-		push @where, 'tags.globjid=firehose.globjid';
 		push @where, "tags.uid = $tag_by_uid_q";
 
 		if ($options->{ignore_nix}) {
@@ -645,7 +653,6 @@
 		} elsif ($options->{tagged_positive} || $options->{tagged_negative} || $options->{tagged_non_negative}) {
 			my $labels;
 			my $not = '';
-			my $tags = getObject('Slash::Tags');
 
 			if ($options->{tagged_positive}) {
 				$labels = $tags->getPositiveTags;
@@ -820,7 +827,7 @@
 	my $where = (join ' AND ', @where) || '';
 
 	my $other = '';
-	$other = 'GROUP BY firehose.id' if $options->{tagged_by_uid} || $options->{nexus};
+	$other = 'GROUP BY firehose.id' if $options->{tagged_by_uid} || $options->{tagged_as} || $options->{nexus};
 
 	my $count_other = $other;
 	my $offset;
@@ -1251,7 +1258,8 @@
 	my $firehose = getObject("Slash::FireHose");
 	my $opts = $firehose->getAndSetOptions();
 	my $html = {};
-	$html->{fhtablist} = slashDisplay("firehose_tabs", { nodiv => 1, tabs => $opts->{tabs}, options => $opts, section => $form->{section} }, { Return => 1});
+	my $views = $firehose->getUserViews({ tab_display => "yes"});
+	$html->{fhtablist} = slashDisplay("firehose_tabs", { nodiv => 1, tabs => $opts->{tabs}, options => $opts, section => $form->{section}, views => $views }, { Return => 1});
 
 	return Data::JavaScript::Anon->anon_dump({
 		html	=> $html
@@ -1262,17 +1270,20 @@
 sub genSetOptionsReturn {
 	my($slashdb, $constants, $user, $form, $options, $opts) = @_;
 	my $data = {};
-	$data->{html}->{fhtablist} = slashDisplay("firehose_tabs", { nodiv => 1, tabs => $opts->{tabs}, options => $opts, section => $form->{section}  }, { Return => 1});
+	
+	my $firehose = getObject("Slash::FireHose");
+	my $views = $firehose->getUserViews({ tab_display => "yes"});
+	$data->{html}->{fhtablist} = slashDisplay("firehose_tabs", { nodiv => 1, tabs => $opts->{tabs}, options => $opts, section => $form->{section}, views => $views  }, { Return => 1});
 	$data->{html}->{fhoptions} = slashDisplay("firehose_options", { nowrapper => 1, options => $opts }, { Return => 1});
 	$data->{html}->{fhadvprefpane} = slashDisplay("fhadvprefpane", { options => $opts }, { Return => 1});
 
 	$data->{value}->{'firehose-filter'} = $opts->{fhfilter};
-	if ($form->{tab} || $form->{tabtype}) {
+	if ($form->{view} && $form->{viewchanged}) {
 		$data->{eval_last} = "firehose_slider_set_color('$opts->{color}');";
 	}
 
 	my $eval_first = "";
-	for my $o (qw(startdate mode fhfilter orderdir orderby startdate duration color more_num)) {
+	for my $o (qw(startdate mode fhfilter orderdir orderby startdate duration color more_num tab view fhfilter base_filter)) {
 		my $value = $opts->{$o};
 		if ($o eq 'orderby' && $value eq 'editorpop') {
 			$value = 'popularity';
@@ -1356,7 +1367,8 @@
 
 	my $opts = $firehose->getAndSetOptions();
 	my $html = {};
-	$html->{fhtablist} = slashDisplay("firehose_tabs", { nodiv => 1, tabs => $opts->{tabs}, options => $opts, section => $form->{section} }, { Return => 1});
+	my $views = $firehose->getUserViews({ tab_display => "yes"});
+	$html->{fhtablist} = slashDisplay("firehose_tabs", { nodiv => 1, tabs => $opts->{tabs}, options => $opts, section => $form->{section}, views => $views }, { Return => 1});
 	$html->{message_area} = $message;
 	return Data::JavaScript::Anon->anon_dump({
 		html	=> $html
@@ -1700,6 +1712,10 @@
 		$num_with_ipid = $slashdb->countSubmissionsFromIPID($item->{ipid});
 		$accepted_from_ipid = $slashdb->countSubmissionsFromIPID($item->{ipid}, { del => 2});
 	}
+	
+	if ($user->{is_admin}) {
+		$firehose->setFireHoseSession($item->{id});
+	}
 
 	my $the_user = $slashdb->getUser($item->{uid});
 
@@ -1986,60 +2002,360 @@
 	return $similar_stories;
 }
 
+sub getOptionsValidator {
+	my($self) = @_;
+	my $constants = getCurrentStatic();
+	
+	my $colors = $self->getFireHoseColors();
+	my %categories = map { ($_, $_) } (qw(hold quik),
+		(ref $constants->{submit_categories}
+			? map {lc($_)} @{$constants->{submit_categories}}
+			: ()
+		)
+	);
+
+	my $valid = {
+		mode 		=> { full => 1, fulltitle => 1 },
+		type 		=> { feed => 1, bookmark => 1, submission => 1, journal => 1, story => 1, vendor => 1, misc => 1, comment => 1, project => 1 },
+		orderdir 	=> { ASC => 1, DESC => 1},
+		orderby 	=> { createtime => 1, popularity => 1, editorpop => 1, neediness => 1 },
+		pagesizes 	=> { "small" => 1, "large" => 1 },
+		colors		=> $colors,
+		categories 	=> \%categories
+	};
+	return $valid;
+}
+
+sub getGlobalOptionDefaults {
+	my($self) = @_;
+
+	my $defaults = {
+		pause		=> 1,
+		mode 		=> 'full',
+		orderdir	=> 'DESC',
+		orderby		=> 'createtime',
+		mixedmode 	=> 0,
+		color 		=> 'blue',
+		nodates		=> 0,
+		nobylines	=> 0,
+		nothumbs	=> 0,
+		nocolors	=> 0,
+		nocommentcnt	=> 0,
+		noslashboxes 	=> 0,
+		nomarquee	=> 0,
+		mixedmode	=> 0,
+		pagesize	=> "small",
+		usermode	=> 0,
+	};
+
+	return $defaults;	
+}
+
+sub getAndSetGlobalOptions {
+	my($self) = @_;
+	my $form = getCurrentForm();
+	my $user = getCurrentUser();
+	my $options = $self->getGlobalOptionDefaults();
+	my $validator = $self->getOptionsValidator();
+	my $set_options = {};
+
+	if (!$user->{is_anon}) {
+		foreach (keys %$options) {
+			my $set_opt = 0;
+			if (defined $form->{$_} && $form->{setting_name} eq $_ && $form->{context} eq "global") {
+				if (defined $validator->{$_}) {
+					if ($validator->{$_}{$form->{$_}}) {
+						$set_options->{"firehose_$_"} = $form->{$_};
+						$options->{$_} = $set_options->{"firehose_$_"};
+						$set_opt = 1;
+					}
+				} else {
+					$set_opt = 1;
+					$set_options->{"firehose_$_"} = $form->{$_} ? 1 : 0;
+					$options->{$_} = $set_options->{"firehose_$_"};
+				}
+			}
+
+			# if we haven't set the option, pull from saved user options
+			if(!$set_opt) { 
+				$options->{$_} = $user->{"firehose_$_"} if defined $user->{"firehose_$_"};
+			}
+			
+		}
+		if (keys %$set_options > 0) {
+			$self->setUser($user->{uid}, $set_options);
+		}
+	}
+
+	return $options;
+}
+
+sub getUserViews {
+	my($self, $options) = @_;
+	my $user = getCurrentUser();
+
+	my ($where, @where);
+
+	my @uids = (0);
+
+	if($options->{tab_display}) {
+		push @where, "tab_display=" . $self->sqlQuote($options->{tab_display});
+	}
+
+	if (!$user->{is_anon}) {
+		push @uids, $user->{uid};
+		push @where, "uid in (" . (join ',', @uids) . ")";
+	}
+
+	$where = join ' AND ', @where;
+	return $self->sqlSelectAllHashrefArray("*","firehose_view", $where, "ORDER BY uid, id");
+}
+
+sub getUserViewByName {
+	my($self, $name, $options) = @_;
+	my $user = getCurrentUser();
+	my $uid_q = $self->sqlQuote($user->{uid});
+	my $name_q = $self->sqlQuote($name);
+	my $uview = $self->sqlSelectHashref("*", "firehose_view", "uid=$uid_q && viewname = $name_q");
+
+	return $uview if $uview;
+
+	my $sview =  $self->getSystemViewByName($name);
+	
+
+	return $sview;
+}
+
+sub getSystemViewByName {
+	my($self, $name, $options) = @_;
+	my $user = getCurrentUser();
+	my $name_q = $self->sqlQuote($name);
+	return $self->sqlSelectHashref("*", "firehose_view", "uid=0 && viewname = $name_q and seclev <= $user->{seclev}");
+}
+
+sub applyViewOptions {
+	my($self, $view, $options, $second) = @_;
+	my $gSkin = getCurrentSkin();
+
+	$options->{view} = $view->{viewname};
+	$options->{viewref} = $view;
+
+
+	if ($view->{useparentfilter} eq "no") {
+		$options->{fhfilter} = "$view->{filter}";
+		$options->{basefilter} = "";
+		$options->{tab} = "";
+		$options->{tab_ref} = "";
+	} else {
+		# Set skin as base filter
+		$options->{fhfilter} = $gSkin->{name};
+		
+		$options->{base_filter} = $options->{fhfilter};
+		$options->{fhfilter} = "$options->{fhfilter} $view->{filter}";
+	}
+
+	foreach (qw(mode mixedmode pause color duration orderby orderdir)) {
+		$options->{$_} = $view->{$_} if $view->{$_} ne "";
+	}
+
+	return $options;
+}
+
+sub genUntitledTab {
+	my($self, $user_tabs, $options) = @_;
+	my $user = getCurrentUser();
+
+	my $tab_compare = {
+		filter 		=> "fhfilter"
+	};
+
+	my $tab_match = 0;
+	foreach my $tab (@$user_tabs) {
+
+		my $this_tab_compare;
+		%$this_tab_compare = %$tab_compare;
+
+		my $equal = 1;
+
+		foreach (keys %$this_tab_compare) {
+			$options->{$this_tab_compare->{$_}} ||= "";
+			if ($tab->{$_} ne $options->{$this_tab_compare->{$_}}) {
+				$equal = 0;
+			}
+		}
+
+		if ($options->{tab} eq $tab->{tabname}) {
+			$tab->{active} = 1;
+		}
+		
+		if ($equal) {
+			$tab_match = 1;
+		}
+	}
+
+	if (!$tab_match) {
+		my $data = {};
+		foreach (keys %$tab_compare) {
+			$data->{$_} = $options->{$tab_compare->{$_}} || '';
+		}
+		if (!$user->{is_anon}) {
+			$self->createOrReplaceUserTab($user->{uid}, "untitled", $data);
+		}
+		$user_tabs = $self->getUserTabs();
+		foreach (@$user_tabs) {
+			$_->{active} = 1 if $_->{tabname} eq "untitled" 
+		}
+	}
+	return $user_tabs;
+}
+
+
 sub getAndSetOptions {
 	my($self, $opts) = @_;
+
 	my $user 	= getCurrentUser();
 	my $constants 	= getCurrentStatic();
 	my $form 	= getCurrentForm();
 	my $gSkin	= getCurrentSkin();
 
+	my ($f_change, $v_change, $t_change);
+
+	if (!$opts->{initial}) {
+		($f_change, $v_change, $t_change) = ($form->{filterchanged}, $form->{viewchanged}, $form->{tabchanged});
+	}
+	
+	my $validator = $self->getOptionsValidator();
+
 	$opts 	        ||= {};
-	my $options 	= {};
 
-	my $types = { feed => 1, bookmark => 1, submission => 1, journal => 1, story => 1, vendor => 1, misc => 1, comment => 1, project => 1 };
-	my $tabtypes = { tabsection => 1, tabpopular => 1, tabrecent => 1, tabuser => 1, metamod => 1};
+	my $global_opts = $self->getAndSetGlobalOptions();
+	my $user_tabs        = $self->getUserTabs();
+	my %user_tab_names   = map { $_->{tabname} => 1 } @$user_tabs;
+	my %user_tab_by_name   = map { $_->{tabname} => $_ } @$user_tabs;
+	my %user_tab_filters = map { $_->{filter} => $_->{tabname} } @$user_tabs;
+	my $options = {};
 
-	my $tabtype = '';
-	$tabtype = $form->{tabtype} if $form->{tabtype} && $tabtypes->{ $form->{tabtype} };
+	# Beginning of initial pageload handling
+	if ($opts->{initial}) {
+		# Start off with global options if initial load
+		%$options = %$global_opts;
 
-	my $modes = { full => 1, fulltitle => 1 };
-	my $pagesizes = { "small" => 1, "large" => 1 };
+		if (defined $opts->{fhfilter} || defined $form->{fhfilter}) {
+			my $fhfilter = defined $opts->{fhfilter} ? $opts->{fhfilter} : $form->{fhfilter};
 
+			$options->{fhfilter} = $fhfilter;
+			$options->{base_filter} = $fhfilter;
+
+			if (defined $user_tab_filters{$fhfilter}) {
+				$opts->{tab} = $user_tab_filters{$fhfilter};
+			} else {
+				$opts->{tab} = '';
+			} 
+			$form->{tab} = '';
+			$opts->{view} = '';
+			$form->{view} = '';
+			
+		}
+		
+		my $tab = $opts->{tab} || $form->{tab};
+		if ($tab) {
+			my $ret_tab = $user_tab_by_name{$tab}; 
+			$options->{tab} = $tab;
+			$options->{tab_ref} = $ret_tab;
+			$options->{base_filter} = $ret_tab->{filter};
+			$options->{fhfilter} = $ret_tab->{filter}
+		}
+
+		# Jump to default view as necessary
+		if (!$tab && !defined $options->{fhfilter} && !$opts->{view} && !$form->{view}) {
+			$opts->{view} = "stories";
+		}
+
+		my $view;
+		if ($opts->{view} || $form->{view}) {
+			my $viewname = $opts->{view} || $form->{view};
+			$view = $self->getUserViewByName($viewname);
+		}
+
+		if ($view) {
+			$options = $self->applyViewOptions($view, $options);
+		}
+
+	} else {
+		# set only global options
+		$options->{$_} = $global_opts->{$_} foreach qw(nocommentcnt nobylines nodates nothumbs nomarquee nocolors noslashboxes);
+
+		# handle non-initial pageload
+		$options->{fhfilter} = $form->{fhfilter} if defined $form->{fhfilter};
+		
+		if ($f_change && defined $form->{fhfilter}) {
+			my $fhfilter = $form->{fhfilter};
+
+			$options->{fhfilter} = $fhfilter;
+			$options->{base_filter} = $fhfilter;
+
+			if (defined $user_tab_filters{$fhfilter}) {
+				$form->{tab} = $user_tab_filters{$fhfilter};
+			} else {
+				$form->{tab} = '';
+			} 
+			$opts->{tab} = '';
+			$opts->{view} = '';
+			$form->{view} = '';
+		}
+
+		if($t_change && defined $form->{tab}) {
+			my $ret_tab = $user_tab_by_name{$form->{tab}}; 
+			$options->{tab} = $form->{tab};
+			$options->{tab_ref} = $ret_tab;
+			$options->{base_filter} = $ret_tab->{filter};
+			$options->{fhfilter} = $ret_tab->{filter}
+		}
+		
+		if($form->{view}) {
+			my $view = $self->getUserViewByName($form->{view});
+			if($view) {
+				$options->{view} = $form->{view};
+				$options->{viewref} = $view;
+			} 
+		}	
+		$options->{tab} = $form->{tab} if $form->{tab} && !$t_change;
+	}
+
+	$options->{global} = $global_opts;
+
+
+	my $fhfilter = $options->{fhfilter};
+
 	my $no_saved = $form->{no_saved};
 	$opts->{no_set} ||= $no_saved;
 	$opts->{initial} ||= 0;
 
 	if (defined $form->{mixedmode} && $form->{setfield}) {
 		$options->{mixedmode} = $form->{mixedmode} ? 1 : 0;
-	} else {
-		$options->{mixedmode} = $user->{firehose_mixedmode};
 	}
 
 	if (defined $form->{nocommentcnt} && $form->{setfield}) {
 		$options->{nocommentcnt} = $form->{nocommentcnt} ? 1 : 0;
-	} else {
-		$options->{nocommentcnt} = $user->{firehose_nocommentcnt};
-	}
-	my $mode = $form->{mode} || $user->{firehose_mode} || '';
+	} 
+	
+	my $mode = $form->{mode} || $options->{mode} || '';
 	$mode = "fulltitle" if $mode eq "mixed";
 
-	my $pagesize = $form->{pagesize} && $pagesizes->{$form->{pagesize}}
-		? $form->{pagesize} : $user->{firehose_pagesize} || "small";
-	$options->{pagesize} = $pagesize;
+	my $pagesize = $form->{pagesize} && $validator->{pagesize}{$form->{pagesize}};
+	$options->{pageize} = $pagesize || $options->{pagesize}  || "small";
 
-	$mode = $mode && $modes->{$mode} ? $mode : "fulltitle";
 	$options->{mode} = $mode;
-	$options->{pause} = defined $user->{firehose_pause} ? $user->{firehose_pause} : 1;
+
+	$options->{pause} = defined $options->{pause} ? $options->{pause} : 1;
 	$form->{pause} = 1 if $no_saved;
 
 	my $firehose_page = $user->{state}{firehose_page} || '';
 
 	if (defined $form->{pause}) {
-		$options->{pause} = $user->{firehose_paused} = $form->{pause} ? 1 : 0;
-		if ($firehose_page ne 'user') {
-			$self->setUser($user->{uid}, { firehose_paused => $options->{pause} });
-		}
+		$options->{pause} = $form->{pause} ? 1 : 0;
 	}
+
 	if (defined $form->{duration}) {
 		if ($form->{duration} =~ /^-?\d+$/) {
 			$options->{duration} = $form->{duration};
@@ -2070,10 +2386,9 @@
 
 
 	my $colors = $self->getFireHoseColors();
-	if ($form->{color} && $colors->{$form->{color}}) {
+	if ($form->{color} && $validator->{colors}->{$form->{color}}) {
 		$options->{color} = $form->{color};
 	}
-	$options->{color} ||= $user->{firehose_color};
 
 	if ($form->{orderby}) {
 		if ($form->{orderby} eq "popularity") {
@@ -2089,7 +2404,6 @@
 		}
 
 	} else {
-		$options->{orderby} = $user->{firehose_orderby} unless $no_saved;
 		$options->{orderby} ||= 'createtime';
 	}
 
@@ -2101,187 +2415,37 @@
 		}
 
 	} else {
-		$options->{orderdir} = $user->{firehose_orderdir} unless $no_saved;
 		$options->{orderdir} ||= 'DESC';
 	}
 
-	my $fhfilter;
-
 	if ($opts->{initial}) {
 		if (!defined $form->{section}) {
 			$form->{section} = $gSkin->{skid} == $constants->{mainpage_skid} ? 0 : $gSkin->{skid};
 		}
-		if (!$tabtype) {
-			$tabtype = 'tabsection';
-		}
 	}
 
 	my $the_skin = defined $form->{section} ? $self->getSkin($form->{section}) : $gSkin;
 
-	if ($tabtype eq 'tabsection') {
-		$form->{fhfilter} = "story";
-		$options->{orderdir} = "DESC";
-		$options->{orderby} = "createtime";
-		$options->{color} = "black";
-		$form->{color} = "black";
-	} elsif ($tabtype eq 'tabrecent') {
-		$form->{fhfilter} = "-story";
-		$options->{orderby} = "createtime";
-		$options->{orderdir} = "DESC";
-		$options->{color} = "indigo";
-		$form->{color} = "indigo";
-	} elsif ($tabtype eq 'tabpopular') {
-		$form->{fhfilter} = "-story";
-		$options->{orderby} = "popularity";
-		$options->{orderdir} = "DESC";
-		$options->{color} = "black";
-		$form->{color} = "black";
-	} elsif ($tabtype eq 'tabuser') {
-		$form->{fhfilter} = "\"user:$user->{nickname}\"";
-		$options->{color} = "black";
-		$form->{color} = "black";
-		$options->{orderdir} = "DESC";
-		$options->{orderby} = "createtime";
-	} elsif ($tabtype eq 'metamod') {
-		$form->{fhfilter} = "comment";
-		$options->{color} = "black";
-		$form->{color} = "black";
-		$options->{orderdir} = "DESC";
-		$options->{orderby} = "neediness";
-		$options->{mode} = "full";
-		$options->{mixedmode} = 0;
-	}
 
-	if ($tabtype) {
-		$form->{fhfilter} = "$the_skin->{name} $form->{fhfilter}" if $the_skin->{skid} != $constants->{mainpage_skid} || $tabtype eq "tabsection";
-	}
-
-
-	if (defined $form->{fhfilter}) {
-		$fhfilter = $form->{fhfilter};
-		$options->{fhfilter} = $fhfilter;
-	} else {
-		$fhfilter = $user->{firehose_fhfilter} unless $no_saved;
-		$options->{fhfilter} = $fhfilter;
-	}
-
-	my $user_tabs = $self->getUserTabs();
-	my %user_tab_names = map { $_->{tabname} => 1 } @$user_tabs;
-	my @tab_fields = qw(tabname filter mode color orderdir orderby);
-
-	$user_tabs = $self->getUserTabs();
-
-
 	my $skin_prefix="";
 	if ($the_skin && $the_skin->{name} && $the_skin->{skid} != $constants->{mainpage_skid})  {
 		$skin_prefix = "$the_skin->{name} ";
 	}
-	my $system_tabs = [
-		{ tabtype => 'tabsection', color => 'black', filter => $skin_prefix . "story", orderby => 'createtime'},
-		{ tabtype => 'tabpopular', color => 'black', filter => "$skin_prefix\-story", orderby => 'popularity'},
-		{ tabtype => 'tabrecent',  color => 'indigo',  filter => "$skin_prefix\-story", orderby => 'createtime'},
-	];
+	
+	$user_tabs = $self->genUntitledTab($user_tabs, $options);	
 
-	if (!$user->{is_anon}) {
-		push @$system_tabs, { tabtype => 'tabuser', color => 'black', filter => $skin_prefix . "\"user:$user->{nickname}\""};
-	}
 
-	my $sel_tabtype;
-
-	my $tab_compare = {
-		color 		=> "color",
-		filter 		=> "fhfilter"
-	};
-
-	my $tab_match = 0;
-	foreach my $tab (@$user_tabs, @$system_tabs) {
-		my $equal = 1;
-
-		my $this_tab_compare;
-		%$this_tab_compare = %$tab_compare;
-
-		$this_tab_compare->{orderby} = 'orderby' if defined $tab->{tabtype};
-
-		foreach (keys %$this_tab_compare) {
-			$options->{$this_tab_compare->{$_}} ||= "";
-			if ($tab->{$_} ne $options->{$this_tab_compare->{$_}}) {
-				$equal = 0;
-			}
-		}
-		if ($equal) {
-			$tab_match = 1;
-			$tab->{active} = 1;
-			if (defined $tab->{tabtype}) {
-				$sel_tabtype = $tab->{tabtype};
-			}
-
-			# Tab match if new option is being set update tab
-			if ($form->{orderdir} || $form->{orderby} || $form->{mode}) {
-
-				my $data = {};
-				$data->{orderdir} = $options->{orderdir};
-				$data->{orderby}  = $options->{orderby};
-				$data->{mode}  	  = $options->{mode};
-				$data->{filter}	  = $options->{fhfilter};
-				$data->{color}	  = $options->{color};
-				if (!$user->{is_anon} && $tab->{tabname}) {
-					$self->createOrReplaceUserTab($user->{uid}, $tab->{tabname}, $data) ;
-				}
-			}
-		}
-	}
-
-	if (!$tab_match) {
-		my $data = {};
-		foreach (keys %$tab_compare) {
-			$data->{$_} = $options->{$tab_compare->{$_}} || '';
-		}
-		if (!$user->{is_anon}) {
-			$self->createOrReplaceUserTab($user->{uid}, "untitled", $data);
-		}
-		$user_tabs = $self->getUserTabs();
-		foreach (@$user_tabs) {
-			$_->{active} = 1 if $_->{tabname} eq "untitled" 
-		}
-	}
-
-	if (defined $form->{tab}) {
-		my $tabnames_hr = {};
-		foreach (@$user_tabs) {
-			$tabnames_hr->{$_->{tabname}} = $_;
-		}
-		if ($tabnames_hr->{$form->{tab}}) {
-			my $curtab = $tabnames_hr->{$form->{tab}};
-			$options->{color} = $curtab->{color};
-			$fhfilter = $options->{fhfilter} = $curtab->{filter};
-			$options->{mode} = $curtab->{mode};
-			$options->{orderby} = $curtab->{orderby};
-			$options->{orderdir} = $curtab->{orderdir};
-
-			$_->{active} = $_->{tabname} eq $form->{tab} ? 1 : 0  foreach @$user_tabs;
-		}
-	}
-
-	if ($form->{index}) {
-		$mode = "fulltitle";
-		if ($the_skin->{nexus} != $constants->{mainpage_nexus_tid}) {
-			$mode = "full";
-		}
-	}
-
 	if ($user->{is_admin} && $form->{setusermode}) {
-		$self->setUser($user->{uid}, { firehose_usermode => $form->{firehose_usermode} ? 1 : "" });
+		$self->setUser($user->{uid}, { firehose_usermode => $form->{firehose_usermode} ? 1 : "0" });
 	}
 
 	foreach (qw(nodates nobylines nothumbs nocolors noslashboxes nomarquee)) {
 		if ($form->{setfield}) {
 			if (defined $form->{$_}) {
 				$options->{$_} = $form->{$_} ? 1 : 0;
-			} else {
-				$options->{$_} = $user->{"firehose_$_"};
 			}
 		}
-		$options->{$_} = defined $form->{$_} ? $form->{$_} : $user->{"firehose_$_"};
+		$options->{$_} = defined $form->{$_};
 	}
 
 	my $page = $form->{page} || 0;
@@ -2292,27 +2456,36 @@
 
 
 	$fhfilter =~ s/^\s+|\s+$//g;
-	if ($form->{index}) {
-		$fhfilter = "story";
-		my $gSkin = getCurrentSkin();
-		if ($gSkin->{nexus} != $constants->{mainpage_nexus_tid}) {
-			$fhfilter .= " $gSkin->{name}";
+
+	if ($fhfilter =~ /\{nickname\}/) {
+		if (!$opts->{user_view}) {
+			if ($form->{user_view_uid}) {
+					$opts->{user_view} = $self->getUser($form->{user_view_id});
+				if(!$opts->{user_view}) {
+					$opts->{user_view} = $user;
+				}
+			}
 		}
+		my $the_nickname = $opts->{user_view}{nickname};
+		$options->{user_view_uid} = $opts->{user_view}{uid};
+		
+		$fhfilter =~ s/\{nickname\}/$the_nickname/g;
+		$options->{fhfilter} =~ s/\{nickname\}/$the_nickname/g;
+		$options->{base_filter} =~ s/\{nickname\}/$the_nickname/g;
 	}
+
+	if ($fhfilter =~ /\{tag}/) {
+		my $the_tag = $opts->{tag} || $form->{tagname};
+		$fhfilter =~ s/\{tag\}/$the_tag/g;
+		$options->{fhfilter} =~ s/\{tag\}/$the_tag/g;
+		$options->{base_filter} =~ s/\{tag\}/$the_tag/g;
+	}	
+	
 	my $fh_ops = $self->splitOpsFromString($fhfilter);
 
 	my $skins = $self->getSkins();
 	my %skin_nexus = map { $skins->{$_}{name} => $skins->{$_}{nexus} } keys %$skins;
 
-	my %categories = map { ($_, $_) } (qw(hold quik),
-		(ref $constants->{submit_categories}
-			? map {lc($_)} @{$constants->{submit_categories}}
-			: ()
-		)
-	);
-
-	my $authors = $self->getAuthors();
-	my %author_names = map { lc($authors->{$_}{nickname}) => $_ } keys %$authors;
 	my $fh_options = {};
 
 
@@ -2323,9 +2496,9 @@
 			$not = "not_";
 			$_ =~ s/^-//g;
 		}
-		if ($types->{$_} && !defined $fh_options->{type}) {
+		if ($validator->{type}->{$_} && !defined $fh_options->{type}) {
 			push @{$fh_options->{$not."type"}}, $_;
-		} elsif ($user->{is_admin} && $categories{$_} && !defined $fh_options->{category}) {
+		} elsif ($user->{is_admin} && $validator->{categories}{$_} && !defined $fh_options->{category}) {
 			$fh_options->{category} = $_;
 		} elsif ($skin_nexus{$_}) {
 				push @{$fh_options->{$not."nexus"}}, $skin_nexus{$_};
@@ -2345,6 +2518,17 @@
 				$uid ||= $user->{uid};
 			}
 			push @{$fh_options->{$not."uid"}}, $uid;
+		} elsif (/^authorfriend:(.*)$/ && $constants->{plugin}{Zoo}) {
+			my $uid;
+			my $nick = $1;
+			if ($nick) {
+				$uid = $self->getUserUID($nick);
+				$uid ||= $user->{uid};
+			}
+			my $zoo = getObject("Slash::Zoo");
+			my $friends = $zoo->getFriendsUIDs($uid);
+			$friends = [-1], if @$friends < 1;   # No friends, pass a UID that won't match
+			push @{$fh_options->{$not."uid"}}, @$friends;
 		} elsif (/^user:/) {
 			my $nick = $_;
 			$nick =~ s/user://g;
@@ -2356,6 +2540,10 @@
 			$fh_options->{tagged_by_uid} = $uid;
 			$fh_options->{tagged_non_negative} = 1;
 #			$fh_options->{ignore_nix} = 1;
+		} elsif (/^tag:/) {
+			my $tag = $_;
+			$tag =~s/tag://g;
+			$fh_options->{tagged_as} = $tag;
 		} else {
 			if (!defined $fh_options->{filter}) {
 				$fh_options->{filter} = $_;
@@ -2384,48 +2572,18 @@
 		@{$fh_options->{nexus}} = grep { !$not_nexus{$_} } @{$fh_options->{nexus}};
 		delete $fh_options->{nexus} if @{$fh_options->{nexus}} == 0;
 	}
+	
+	my $color = defined $form->{color} && $validator->{colors}->{$form->{color}} ? $form->{color} : "";
+	$color = defined $options->{color} && $validator->{colors}->{$options->{color}} ? $options->{color} : "" if !$color;
 
-	if ($form->{color} && $colors->{$form->{color}}) {
-		$fh_options->{color} = $form->{color};
-	}
+	$fh_options->{color} = $color;
 
-	if ($form->{index}) {
-		$options->{index} = 1;
-		$options->{skipmenu} = 1;
-		if (!$form->{issue} && getCurrentSkin()->{nexus} != $constants->{mainpage_nexus_tid}) {
-			$options->{duration} = -1;
-			$options->{startdate} = '';
-		}
-		$options->{color} = 'black';
-		if ($the_skin->{nexus} == $constants->{mainpage_nexus_tid}) {
-			$options->{mixedmode} = 1;
-			$options->{mode} = 'fulltitle';
-		} else {
-			$options->{mode} = 'full';
-			$options->{mixedmode} = 0;
-		}
-	}
 
 	foreach (keys %$fh_options) {
 		$options->{$_} = $fh_options->{$_};
 	}
 
-	if (!$user->{is_anon} && !$opts->{no_set} && !$form->{index}) {
-		my $data_change = {};
-		my @skip_options_save = qw(uid not_uid type not_type nexus not_nexus primaryskid not_primaryskid smalldevices mainpage);
-		if ($firehose_page eq 'user') {
-			push @skip_options_save, "nothumbs", "nocolors", "pause", "mode", "orderdir", "orderby", "fhfilter", "color";
-		}
-		my %skip_options = map { $_ => 1 } @skip_options_save;
-		foreach (keys %$options) {
-			next if $skip_options{$_};
-			$data_change->{"firehose_$_"} = $options->{$_} if !defined $user->{"firehose_$_"} || $user->{"firehose_$_"} ne $options->{$_};
-		}
-		$self->setUser($user->{uid}, $data_change) if keys %$data_change > 0;
-	}
-
 	$options->{tabs} = $user_tabs;
-	$options->{sel_tabtype} = $sel_tabtype;
 
 	if ($user->{is_admin} && $form->{setusermode}) {
 		$options->{firehose_usermode} = $form->{firehose_usermode} ? 1 : "";
@@ -2466,11 +2624,40 @@
 		$options->{duration} = 1;
 	}
 
+	$options->{not_id} = $opts->{not_id} if $opts->{not_id};
 	if ($form->{not_id} && $form->{not_id} =~ /^\d+$/) {
 		$options->{not_id} = $form->{not_id};
 	}
 
+	
 
+	if ($v_change) {
+		$self->applyViewOptions($options->{viewref}, $options)
+	}
+	
+	if ($form->{index}) {
+		$options->{index} = 1;
+		$options->{pause} = 1;
+		$options->{skipmenu} = 1;
+		if (!$form->{issue} && getCurrentSkin()->{nexus} != $constants->{mainpage_nexus_tid}) {
+			$options->{duration} = -1;
+			$options->{startdate} = '';
+		}
+		if (!$form->{issue} && getCurrentSkin()->{nexus} == $constants->{mainpage_nexus_tid}) {
+			$options->{duration} = 7;
+			$options->{startdate} = '';
+		}
+		
+		$options->{color} = 'black';
+		if ($the_skin->{nexus} == $constants->{mainpage_nexus_tid}) {
+			$options->{mixedmode} = 1;
+			$options->{mode} = 'fulltitle';
+		} else {
+			$options->{mode} = 'full';
+			$options->{mixedmode} = 0;
+		}
+	}
+
 	if ($form->{more_num} && $form->{more_num} =~ /^\d+$/) {
 		$options->{more_num} = $form->{more_num};
 		if (!$user->{is_admin} && (($options->{limit} + $options->{more_num}) > 200)) {
@@ -2480,34 +2667,43 @@
 			$self->setUser($user->{uid}, { firehose_max_more_num => $options->{more_num}});
 		}
 	}
-	if ($user->{state}{firehose_init_list} && $options->{sel_tabtype}) {
-		my $set_opts = $self->getInitTabtypeOptions($options->{sel_tabtype});
-		foreach (keys %$set_opts) {
-			$options->{$_} = $set_opts->{$_};
-		}
-	}
+
 	$options->{smalldevices} = 1 if $self->shouldForceSmall();
-	$options->{limit} = $self->getFireHoseLimitSize($options->{mode}, $pagesize, $options->{smalldevices});
+	$options->{limit} = $self->getFireHoseLimitSize($options->{mode}, $pagesize, $options->{smalldevices}, $options);
+	
 	return $options;
 }
 
 sub getFireHoseLimitSize {
-	my($self, $mode, $pagesize, $forcesmall) = @_;
+	my($self, $mode, $pagesize, $forcesmall, $options) = @_;
 	my $user = getCurrentUser();
 	my $constants = getCurrentStatic();
 	my $form = getCurrentForm();
 
 	my $limit;
 
-	if ($mode eq "full") {
+	if ($options->{view} && $options->{viewref}) {
 		if ($user->{is_admin}) {
-			$limit = $pagesize eq "large" ? 50 : 25;
+			$limit = $options->{viewref}{admin_maxitems};
 		} else {
-			$limit = $pagesize eq "large" ? 20 : 15;
+			$limit = $options->{viewref}{maxitems};
 		}
-	} else {
-		$limit = $user->{is_admin} ? 50 :
+		if ($mode eq "full") {
+			$limit = int($limit / 2);
+		}
+	}
+
+	if (!$limit) {
+		if ($mode eq "full") {
+			if ($user->{is_admin}) {
+				$limit = $pagesize eq "large" ? 50 : 25;
+			} else {
+				$limit = $pagesize eq "large" ? 20 : 15;
+			}
+		} else {
+			$limit = $user->{is_admin} ? 50 :
 			$pagesize eq "large" ? 30 : 20;
+		}
 	}
 
 	$limit = 10 if $forcesmall || $form->{metamod};
@@ -2680,14 +2876,15 @@
 
 sub listView {
 	my($self, $lv_opts) = @_;
+
 	$lv_opts ||= {};
+	$lv_opts->{initial} = 1;
+
 	my $slashdb = getCurrentDB();
 	my $user = getCurrentUser();
 	my $gSkin = getCurrentSkin();
 	my $form = getCurrentForm();
 
-	$user->{state}{firehose_init_list} = 1;
-
 	my $firehose_reader = getObject('Slash::FireHose', {db_type => 'reader'});
 	my $featured;
 
@@ -2705,9 +2902,9 @@
 			$featured = $firehose_reader->getFireHose($res->[0]->{id});
 		}
 	}
-	my $initial = ($form->{tab} || $form->{tabtype} || $form->{fhfilter} || defined $form->{page} || $lv_opts->{fh_page} eq "console.pl" || $form->{ssi} || $form->{taskgen} && defined $form->{fhfilter}) ? 0 : 1;
-	my $options = $lv_opts->{options} || $self->getAndSetOptions({ initial => $initial });
-	my $base_page = $lv_opts->{fh_page} || "firehose.pl";
+	$lv_opts->{fh_page} ||= "firehose.pl";
+	my $base_page = $lv_opts->{fh_page};
+	my $options = $self->getAndSetOptions($lv_opts);
 
 	if ($featured && $featured->{id}) {
 		$options->{not_id} = $featured->{id};
@@ -2807,6 +3004,8 @@
 		day_count => $day_count
 	};
 
+	my $views = $self->getUserViews({ tab_display => "yes"});
+
 	slashDisplay("list", {
 		itemstext		=> $itemstext,
 		itemnum			=> $itemnum,
@@ -2823,7 +3022,8 @@
 		search_results		=> $results,
 		featured		=> $featured,
 		section			=> $section,
-		firehose_more_data 	=> $firehose_more_data
+		firehose_more_data 	=> $firehose_more_data,
+		views			=> $views,
 	}, { Page => "firehose", Return => 1 });
 }
 
@@ -2871,6 +3071,15 @@
 	return $tabs;
 }
 
+sub getUserTabByName {
+	my($self, $name, $options) = @_;
+	$options ||= {};
+	my $user = getCurrentUser();
+	my $uid_q = $self->sqlQuote($user->{uid});
+	my $tabname_q = $self->sqlQuote($name);
+	return $self->sqlSelectHashref("*", "firehose_tab", "uid=$uid_q && tabname=$tabname_q");
+}
+
 sub getSystemDefaultTabs {
 	my($self) = @_;
 	return $self->sqlSelectAllHashrefArray("*", "firehose_tab", "uid='0'")

Modified: slashjp/branches/upstream/current/plugins/FireHose/firehose.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/firehose.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/firehose.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -28,9 +28,9 @@
 	my $anonval = $constants->{firehose_anonval_param} || "";
 
 	my %ops = (
-		list		=> [1,  \&list, 1, $anonval, { index => 1, issue => 1, page => 1, query_apache => -1, virtual_user => -1, startdate => 1, duration => 1, tab => 1, tabtype => 1, change => 1, section => 1  }],
+		list		=> [1,  \&list, 1, $anonval, { index => 1, issue => 1, page => 1, query_apache => -1, virtual_user => -1, startdate => 1, duration => 1, tab => 1, tabtype => 1, change => 1, section => 1 , view => 1 }],
 		view		=> [1, 	\&view, 0,  ""],
-		default		=> [1,	\&list, 1,  $anonval, { index => 1, issue => 1, page => 1, query_apache => -1, virtual_user => -1, startdate => 1, duration => 1, tab => 1, tabtype => 1, change => 1, section => 1 }],
+		default		=> [1,	\&list, 1,  $anonval, { index => 1, issue => 1, page => 1, query_apache => -1, virtual_user => -1, startdate => 1, duration => 1, tab => 1, tabtype => 1, change => 1, section => 1, view => 1 }],
 		edit		=> [1,	\&edit, 100,  ""],
 		metamod		=> [1,  \&metamod, 1, ""],
 		rss		=> [1,  \&rss, 1, ""]
@@ -115,7 +115,7 @@
 	$form->{skipmenu} 	= 1;
 	$form->{pause} 		= 1;
 	$form->{no_saved} 	= 1;
-	print $firehose->listView();
+	print $firehose->listView({ view => 'metamod'});
 }
 
 

Modified: slashjp/branches/upstream/current/plugins/FireHose/index2.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/index2.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/index2.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -78,7 +78,7 @@
 	my($slashdb, $constants, $user, $form, $gSkin) = @_;
 	slashProfInit();
 	my $firehose = getObject("Slash::FireHose");
-	print $firehose->listView();
+	print $firehose->listView({ view => 'stories'});
 	slashProfEnd();
 }
 

Modified: slashjp/branches/upstream/current/plugins/FireHose/mysql_dump.sql
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/mysql_dump.sql	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/mysql_dump.sql	2008-11-26 06:51:20 UTC (rev 836)
@@ -44,3 +44,26 @@
 INSERT INTO firehose_tab VALUES (4,0,'User','"user:{nickname}"','createtime','DESC','black','full');
 
 INSERT INTO vars (name, value, description) VALUES ('metamod_use_firehose', '0', 'Use firehose for metamodding');
+
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "metamod", "no", "comment", "neediness", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 1,"1");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userjournal", "no", '"author:{nickname}" journal', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "usersubmission", "no", '"author:{nickname}" submission', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userbookmark", "no", '"author:{nickname}" bookmark', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userfirehose", "no", '"user:{nickname}"', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "stories", "yes", 'story', "createtime", "DESC", "black", "-1", "full", "1", "yes", "yes", 30, 30, 0,"");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "recent", "yes", '-story', "createtime", "DESC", "blue", "7", "fulltitle", "0", "yes", "yes", 50, 30, 0,"");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "popular", "yes", '-story', "createtime", "DESC", "black", "7", "full", "1", "yes", "yes", 50, 30, 0,"");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "daddypants", "yes", 'unsigned', "createtime", "DESC", "indigo", "-1", "fulltitle", "", "yes", "yes", 50, 30, 100,"");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "usertag", "no", '"user:{nickname}" "tag:{tag}"', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userjournalfriends", "no", '"authorfriend:{nickname}" journal', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");

Modified: slashjp/branches/upstream/current/plugins/FireHose/mysql_schema.sql
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/mysql_schema.sql	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/mysql_schema.sql	2008-11-26 06:51:20 UTC (rev 836)
@@ -87,6 +87,32 @@
 	UNIQUE uid_tabname(uid,tabname)
 ) TYPE=InnoDB;
 
+DROP TABLE IF EXISTS firehose_view;
+CREATE TABLE firehose_view(
+	id mediumint(8) unsigned NOT NULL auto_increment,
+	uid MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
+	viewname VARCHAR(24) NOT NULL DEFAULT 'unnamed',
+	useparentfilter ENUM("no","yes") DEFAULT "yes",
+	tab_display ENUM("no","yes") DEFAULT "no",
+	options_edit ENUM("no","yes") DEFAULT "no",
+	admin_maxitems tinyint NOT NULL DEFAULT -1,
+	maxitems tinyint NOT NULL DEFAULT -1,
+	seclev mediumint UNSIGNED NOT NULL DEFAULT '0',
+
+	filter VARCHAR(255) NOT NULL DEFAULT '',
+	orderby ENUM("popularity","createtime", "editorpop", "activity", "neediness", "") DEFAULT "createtime",
+	orderdir ENUM("ASC", "DESC", "") DEFAULT "DESC",
+	color VARCHAR(16) NOT NULL DEFAULT '',
+	duration ENUM("7","-1","") DEFAULT '',
+	mode ENUM ("full","fulltitle", "") DEFAULT "",
+	mixedmode ENUM("1","0","") DEFAULT "",
+	pause ENUM("1","0","") DEFAULT "";
+
+	PRIMARY KEY (id),
+	UNIQUE id_viewname(id,viewname)
+);
+
+
 DROP TABLE IF EXISTS firehose_update_log;
 CREATE TABLE firehose_update_log(
 	id mediumint(8) unsigned NOT NULL auto_increment,

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/dispFireHose;firehose;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/dispFireHose;firehose;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/dispFireHose;firehose;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -10,46 +10,45 @@
 en_US
 __name__
 dispFireHose
-__seclev__
-10000
 __template__
-[% 
-    firehose = Slash.getObject("Slash::FireHose");
-    pop_val = firehose.getPopLevelForPopularity(item.userpop);
-    nofollow = 1;
-    IF item.type == "story";
-    	nofollow = 0;
-    END;
+[%
+	firehose = Slash.getObject("Slash::FireHose");
+	pop_val = firehose.getPopLevelForPopularity(item.userpop);
 
-    mode = mode || "fulltitle";
-    divwrapper = 1;
-    storylinkwrapper = 1;
-    full = 1;
-    bodywrapper = 1;
-    bodycontent = 1;
-    future = 0;
+	nofollow = 1;
+	IF item.type == "story";
+	   nofollow = 0;
+	END;
+
+	mode = mode || "fulltitle";
+	divwrapper = 1;
+	storylinkwrapper = 1;
+	full = 1;
+	bodywrapper = 1;
+	bodycontent = 1;
+	future = 0;
     IF item.type == "story";
-    	story = Slash.db.getStory(item.srcid);
+	story = Slash.db.getStory(item.srcid);
 	future = story.is_future;
     END;
-    IF mode == "fulltitle";
-    	IF !bodycontent_include;
-	    	bodycontent = 0;
+	IF mode == "fulltitle";
+		IF !bodycontent_include;
+			bodycontent = 0;
+		END;
+	ELSIF mode == "bodycontent";
+		divwrapper = 0;
+		full = 0;
+		bodywrapper = 0;
 	END;
-    ELSIF mode == "bodycontent";
-        divwrapper = 0;
-	full = 0;
-	bodywrapper = 0;
-    END;
-    IF nodivwrapper;
-        divwrapper = 0;
-    END;
-    IF nostorylinkwrapper;
-        storylinkwrapper = 0;
-    END;
+	IF nodivwrapper;
+		divwrapper = 0;
+	END;
+	IF nostorylinkwrapper;
+		storylinkwrapper = 0;
+	END;
     IF user.is_admin;
-    	adminmode = 1;
-        IF options.firehose_usermode.defined;
+	adminmode = 1;
+	IF options.firehose_usermode.defined;
 		IF options.firehose_usermode;
 			adminmode = 0;
 		END;
@@ -57,95 +56,162 @@
 		adminmode = 0;
 	END;
     END;
+
+	IF item.thumb;
+		thumbfile = Slash.db.getStaticFile(item.thumb);
+	END;
+	IF item.type == "story";
+		story = Slash.db.getStory(item.srcid);
+		future = story.is_future;
+	END;
+	IF item.discussion;
+		disc = Slash.db.getDiscussion(item.discussion);
+	END;
+
+
+	the_user = Slash.db.getUser(item.uid);
+	the_skin = Slash.db.getSkin(item.primaryskid);
+
+	fh_page = fh_page || "firehose.pl";
+	IF item.primaryskid && item.primaryskid != gSkin.skid && item.primaryskid != constants.mainpage_skid && item.type == "story";
+		IF user.is_anon;
+			index_add = "";
+			IF form.index;
+				index_add = "index_";
+			END;
+		END;
+	END;
+
+	topic = Slash.db.getTopic(item.tid);
+
+	IF item.url_id;
+		the_url = Slash.db.getUrl(item.url_id);
+	END;
 %]
 [% hasimage = item.tid || (item.thumb && item.type == "story") || (adminmode && item.type == "submission") %]
 [% IF item.url_id;
 	url = Slash.db.getUrl(item.url_id);
 END %]
 [% the_user = Slash.db.getUser(item.uid) %]
-[% IF full %]
+[%
+   link_url = firehose.linkFireHose(item);
+ %]
 [% IF divwrapper %]
-<div id="firehose-[% item.id %]"[% IF item.type %] type="[% item.type %]"[% END %] class="[% IF mode == "full" %]article[% ELSE %]briefarticle[% END %][% IF adminmode == 1 %] adminmode[% ELSE %] usermode[% END %]">
+<div id="firehose-[% item.id %]"[% IF item.type %] type="[% item.type %]"[% END %] class="[% IF mode == "full" %]article[% ELSE %]briefarticle[% END %][% IF adminmode == 1 %] adminmode[% ELSE %] usermode[% END %][% IF !form.skipvote && !options.nothumbs && !skipvote && !featured %] thumbs[% END %]">
 <span class="sd-info-block" style="display: none">
 	<span class="sd-key-firehose-id">[% item.id %]</span>
 	<span class="type">[% item.type %]</span>
 	[% IF user.is_admin %]<span class="stoid">[% item.srcid %]</span>[% END %]
 </span>
 [% END %]
+
+[% IF !form.skipvote && !options.nothumbs && !skipvote && !featured %]
+	<span id="updown-[% item.id %]" class="vote[% IF vote == "down" %]ddown[% ELSIF vote == "up" %]dup[% END %]">
+	  <a href="#" class="up" title="Vote this item up">+</a>
+	  <a href="#" class="down" title="Vote this item down">-</a>
+	</span>
+[% END %]
 	[% PROCESS formatHoseTitle the_user = the_user item = item url = url adminmode=adminmode options = options link_url = link_url %]
-	[% title_type = item.type == "story" ? "story" : "firehose" %]
-	[% PROCESS titlebar h3id="title-" _ item.id id="" future = future title_type = title_type title_type_id = "ttype-" _ item.id options = options %]
-[% END %]
-	[% IF bodywrapper;
-		Slash.getData('byline', { adminmode => adminmode, item => item, the_user => the_user }, 'firehose');
-	%]
-	<div class="[% IF bodycontent && mode == "fulltitle" %]hide[% ELSIF bodycontent %]body[% ELSE %]empty[% END %]" id="fhbody-[% item.id %]"  [% IF !hasimage  %]style="min-height: auto !important; "[% END %]>
-	[% END %]
-		[% IF hasimage %]
-		<div class="topic" id="topic-[% item.id %]">
-			[% IF bodycontent %]
-			[% PROCESS dispTopicFireHose item = item %]
-			[% END %]
-		</div>
-		[% END %]
-		<div id="text-[% item.id %]" class="intro">
-			[% IF bodycontent;
-	   		   introtext = item.introtext;
-			   # set introtext with extra data we want
-			   PROCESS formatHoseIntro; 
-			%]
-			[% introtext %]
-			[% IF view_mode %]
-				[% IF item.bodytext %]
-					[% item.bodytext %]
+						[% title_type = "firehose" %]
+						[% IF item.type == "story";
+							title_type = "story";
+							IF future;
+								title_type = "future";
+							END;
+						   END;
+						%]
+						<h3 class="[% title_type %]">
+							[% IF item.thumb && thumbfile && !featured %]
+								<a href="[% gSkin.rootdir %]/firehose.pl?op=view&amp;id=[% item.id %]"><img src="[% constants.imagedir %][% thumbfile.name %] " height="25" width="30" alt="Screenshot-sm"></a>
+
+							[% END %]
+							[% title %]
+							[% IF adminmode %]
+								<form id="postform-[% item.id %]" method="post" action="[% gSkin.rootdir %]/admin.pl" class="edit">
+									<a href="[% gSkin.rootdir %]/firehose.pl?op=edit&amp;id=[% item.id %]" title="Preview the editable version of this">Edit</a>
+								</form>
+							[% END %]
+				[% IF item.discussion && featured;
+						skin = gSkin;
+						IF item.type == "story"; skin = Slash.db.getSkin(item.primaryskid); END %]
+							<span class="vballoon-marquee rd_5">
+								<span>Comments:</span>
+								<a href="[% skin.rootdir %]/comments.pl?sid=[% item.discussion %]" id="commentcnt-[% item.id %]" title="Comment on this">[% disc.commentcount || 0 %]</a>
+							</span>
 				[% END %]
-				[% IF item.media %]
-				<div class="media">
-					[% item.media %]
-				</div>
+						</h3>
+							[% Slash.getData('byline', { adminmode => adminmode, item => item, the_user => the_user }, 'firehose');	%]
+							<div class="[% IF bodycontent && mode == 'fulltitle' %]hide[% ELSIF bodycontent %]body[% ELSE %]hide[% END %]" id="fhbody-[% item.id %]"[% IF !hasimage %] style="min-height: auto !important;"[% END %]>
+								[% IF item.thumb && ((!featured) || (featured && !item.media)) %]
+								<span class="media">
+									[% PROCESS dispTopicFireHose item = item %]
+								</span>
+								[% ELSIF item.tid && topic.image && !featured %]
+								<span class="media topic">
+									[% PROCESS dispTopicFireHose item = item %]
+								</span>
+								[% END %]
+									[% IF item.type == "journal" %]
+										[% IF (options.view.match('^userjournal') || view_mode) && item.bodytext %]
+											<div class="bodytext">[% item.bodytext %]</div>
+										[% ELSE %]
+											<div id="text-[% item.id %]">
+											[% introtext = item.introtext;
+											    PROCESS formatHoseIntro;
+											   introtext;
+											%]</div>
+										[% END %]
+									[% ELSE # item.type == "journal" %]
+
+										<div id="text-[% item.id %]">
+										[% introtext = item.introtext;
+										    PROCESS formatHoseIntro;
+										    introtext;
+										%]</div>
+										[% IF view_mode && item.bodytext %]
+										<div class="bodytext">[% item.bodytext %]</div>
+										[% END;
+									END # item.type == "journal" %]
+
+									[% IF (view_mode || featured) && item.media %]
+									<p>
+									[% IF item.media %]
+									<div class="media">
+										[% item.media %]
+									</div>
+									[% END %]
+									</p>
+									[% END %]
+
+									[% IF user.is_admin && !user.firehose_usermode %]
+									<div class="tagshide" id="toggletags-body-[% id %]">
+										<div id="admin-extras-[% item.id %]" class="tagadminextra"></div>
+									</div>
+									[% END %]
+
+									[% PROCESS tag_widget id = item.id  top_tags = top_tags system_tags = system_tags vote = vote options = options item = item skipvote = 1; %]
+
+									<span class="reader">
+									<a href="[% link_url %]" class="more">Read More</a>
+									<span class="commentcnt"> <a href="[% skin.rootdir %]/comments.pl?sid=[% item.discussion %]" id="commentcnt-[% item.id %]">[% disc.commentcount || 0 %]</a> comments</span>
+									</span>
+
+							</div>
+				[% IF item.discussion && !featured  && disc.commentcount;
+						skin = gSkin;
+						IF item.type == "story"; skin = Slash.db.getSkin(item.primaryskid); END %]
+							<span class="vballoon-firehoselist rd_5">
+								<span>Comments:</span>
+								<a href="[% skin.rootdir %]/comments.pl?sid=[% item.discussion %]" id="commentcnt-[% item.id %]">[% disc.commentcount || 0 %]</a>
+							</span>
+
 				[% END %]
-			[% END %]
-			[% END %]
-		</div>
-	[% IF bodywrapper %]
-	</div>
-	[% END %]
-			[% IF adminmode && bodycontent %]
-			<form id="postform-[% item.id %]" method="post" action="[% gSkin.rootdir %]/admin.pl" class="edit">
-			<div><a href="[% gSkin.rootdir %]/firehose.pl?op=edit&amp;id=[% item.id %]" title="Preview the editable version of this">Edit Preview</a></div>
-			</form>
-			[% END %]
-[% IF full %]
-		[% IF (future || item.type=="story") %]<div class="whitewash">[% END %]
-		[% PROCESS tag_widget id = item.id  top_tags = top_tags system_tags = system_tags vote = vote options = options item = item %]
-		[% IF (future || item.type=="story") %]</div>[% END %]
-[% IF divwrapper; IF storylinkwrapper %]
-<div class="storylinks">
-	<div>
-		<ul>
-			<li class="more"><b>
-			[% link_url = firehose.linkFireHose(item) %]
-			[% IF item.discussion || item.type == "comment" %]
-				<a href="[% link_url %]">[% IF form.metamod %]Context[% ELSE %]Read More[% END %]</a>
-			[% ELSE %]
-				Nothing More
-			[% END %]
-				</b>
-			</li>
-			[% IF item.discussion;
-			   disc = Slash.db.getDiscussion(item.discussion); %]
-			<li class="comments[% IF !disc.commentcount || options.nocommentcnt %] nocomment[% END %]">
-				[% skin = gSkin %]
-				[% IF item.type == "story"; skin = Slash.db.getSkin(item.primaryskid); END %]
-				<a href="[% skin.rootdir %]/comments.pl?sid=[% item.discussion %]" id="commentcnt-[% item.id %]">[% disc.commentcount %]</a> <span>comment[% IF disc.commentcount != 1 %]s[% END %]</span>
-			</li>
-			[% END %]
-		</ul>
-	</div>
+
+						<hr>
+[% IF divwrapper %]
 </div>
 [% END %]
-</div>
-[% END %]
-[% END %]
+__seclev__
+10000
 __version__
 $Id$

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/fhadvprefpane;misc;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/fhadvprefpane;misc;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/fhadvprefpane;misc;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -29,9 +29,9 @@
         <tr>
                 <td>
                 [% IF paused %]
-                        <span id="advplay" onclick="firehose_play()"><a href="#" style="text-decoration: none; color: black;">Paused</a></span>
+                        <span id="advplay" onclick="firehose_play('global')"><a href="#" style="text-decoration: none; color: black;">Paused</a></span>
                 [% ELSE %]
-                        <span id="advpause" onclick="firehose_pause()"><a href="#" style="text-decoration: none; color: black;">Updating</a></span>
+                        <span id="advpause" onclick="firehose_pause('global')"><a href="#" style="text-decoration: none; color: black;">Updating</a></span>
                 [% END %]
                 </td>
 
@@ -43,9 +43,9 @@
         <tr>
                 <td>
                 [% IF options.mode == "fulltitle" || !options.mode %]
-                        <span id="advabbrev" onclick="firehose_set_options('mode','full')"><a href="#" style="text-decoration: none; color: black;">Headlines</a></span>
+                        <span id="advabbrev" onclick="firehose_set_options('mode','full','global')"><a href="#" style="text-decoration: none; color: black;">Headlines</a></span>
                 [% ELSE %]
-                        <span id="advfull"  onclick="firehose_set_options('mode','fulltitle')"><a href="#" style="text-decoration: none; color: black;">Full Article</a></span>
+                        <span id="advfull"  onclick="firehose_set_options('mode','fulltitle','global')"><a href="#" style="text-decoration: none; color: black;">Full Article</a></span>
                 [% END %]
                 </td>
 
@@ -57,9 +57,9 @@
         <tr>
                 <td>
                 [% IF options.orderdir == "ASC" %]
-                        <span id="advdesc"  onclick="firehose_set_options('orderdir','DESC')"><a href="#" style="text-decoration: none; color: black;">Ascending</a></span>
+                        <span id="advdesc"  onclick="firehose_set_options('orderdir','DESC','global')"><a href="#" style="text-decoration: none; color: black;">Ascending</a></span>
                 [% ELSE %]
-                        <span id="advasc" onclick="firehose_set_options('orderdir','ASC')"><a href="#" style="text-decoration: none; color: black;">Descending</a></span>
+                        <span id="advasc" onclick="firehose_set_options('orderdir','ASC','global')"><a href="#" style="text-decoration: none; color: black;">Descending</a></span>
                 [% END %]
                 </td>
 
@@ -71,9 +71,9 @@
         <tr>
                 <td>
                 [% IF options.orderby == "popularity" || options.orderby == "editorpop" || options.orderby == "popularity2" %]
-                        <span id="advpopularity" onclick="firehose_set_options('orderby','createtime')"><a href="#" style="text-decoration: none; color: black;">Popularity</a></span>
+                        <span id="advpopularity" onclick="firehose_set_options('orderby','createtime','global')"><a href="#" style="text-decoration: none; color: black;">Popularity</a></span>
                 [% ELSE  %]
-                <span id="advtime" onclick="firehose_set_options('orderby','popularity')"><a href="#" style="text-decoration: none; color: black;">Time</a></span>
+                <span id="advtime" onclick="firehose_set_options('orderby','popularity','global')"><a href="#" style="text-decoration: none; color: black;">Time</a></span>
                 [% END %]
                 </td>
 
@@ -85,7 +85,7 @@
 
 <br>
 
-<input type="checkbox" name="nodates" onchange="firehose_set_options('nodates', !this.checked)"[% constants.markup_checked_attribute IF !options.nodates %]> <b>Dates</b> <a href="#" onclick="displayModalPrefHelp('modalprefhelp_nodates'); return false" title="Click To Expand Help" class="help">?</a>
+<input type="checkbox" name="nodates" onchange="firehose_set_options('nodates', !this.checked,'global')"[% constants.markup_checked_attribute IF !options.nodates %]> <b>Dates</b> <a href="#" onclick="displayModalPrefHelp('modalprefhelp_nodates'); return false" title="Click To Expand Help" class="help">?</a>
 <br>
 <div style="padding-left: 10px;">
         <div id="modalprefhelp_nodates" class="modalprefhelp" style="display: none;">
@@ -95,7 +95,7 @@
 
 <br>
 
-<input type="checkbox" name="nobylines" onchange="firehose_set_options('nobylines', !this.checked)"[% constants.markup_checked_attribute IF !options.nobylines %]> <b>Bylines</b> <a href="#" onclick="displayModalPrefHelp('modalprefhelp_nobylines'); return false" title="Click To Expand Help" class="help">?</a>
+<input type="checkbox" name="nobylines" onchange="firehose_set_options('nobylines', !this.checked,'global')"[% constants.markup_checked_attribute IF !options.nobylines %]> <b>Bylines</b> <a href="#" onclick="displayModalPrefHelp('modalprefhelp_nobylines'); return false" title="Click To Expand Help" class="help">?</a>
 <br>
 <div style="padding-left: 10px;">
         <div id="modalprefhelp_nobylines" class="modalprefhelp" style="display: none;">
@@ -105,7 +105,7 @@
 
 <br>
 
-<input type="checkbox" name="nothumbs" onchange="firehose_set_options('nothumbs', !this.checked)"[% constants.markup_checked_attribute IF !options.nothumbs %]> <b>Thumbs</b> <a href="#" onclick="displayModalPrefHelp('modalprefhelp_nothumbs'); return false" title="Click To Expand Help" class="help">?</a>
+<input type="checkbox" name="nothumbs" onchange="firehose_set_options('nothumbs', !this.checked,'global')"[% constants.markup_checked_attribute IF !options.nothumbs %]> <b>Thumbs</b> <a href="#" onclick="displayModalPrefHelp('modalprefhelp_nothumbs'); return false" title="Click To Expand Help" class="help">?</a>
 <br>
 <div style="padding-left: 10px;">
         <div id="modalprefhelp_nothumbs" class="modalprefhelp" style="display: none;">
@@ -115,26 +115,26 @@
 
 <br>
 
-<input type="checkbox" name="nocolors" onchange="firehose_set_options('nocolors', !this.checked)"[% constants.markup_checked_attribute IF !options.nocolors %]> <b>Color Swatches</b>
+<input type="checkbox" name="nocolors" onchange="firehose_set_options('nocolors', !this.checked, 'global')"[% constants.markup_checked_attribute IF !options.nocolors %]> <b>Color Swatches</b>
 
 <br><br>
 
-<input type="checkbox" name="mixedmode" onchange="firehose_set_options('mixedmode', this.checked)"[% constants.markup_checked_attribute IF options.mixedmode %]> <b>Expand Top Rated</b>
+<input type="checkbox" name="mixedmode" onchange="firehose_set_options('mixedmode', this.checked, 'global')"[% constants.markup_checked_attribute IF options.mixedmode %]> <b>Expand Top Rated</b>
 
 <br><br>
 
-<input type="checkbox" name="nocommentcount" onchange="firehose_set_options('nocommentcnt', !this.checked)"[% constants.markup_checked_attribute IF !options.nocommentcnt %]> <b>Show comment count for abbreviated</b>
+<input type="checkbox" name="nocommentcount" onchange="firehose_set_options('nocommentcnt', !this.checked, 'global')"[% constants.markup_checked_attribute IF !options.nocommentcnt %]> <b>Show comment count for abbreviated</b>
 
 <br><br>
 
 [% default = options.pagesize || "small" %]
-<b>Page size</b> [% Slash.createSelect('pagesize', { 'small' => 'Small', 'large' => 'Large'}, { default => default, onchange => "firehose_set_options('pagesize',this.options[this.selectedIndex].value)", return => 1} ) %]
+<b>Page size</b> [% Slash.createSelect('pagesize', { 'small' => 'Small', 'large' => 'Large'}, { default => default, onchange => "firehose_set_options('pagesize',this.options[this.selectedIndex].value, 'global')", return => 1} ) %]
 
 <br><br>
 
 [% IF user.is_admin %]
         <input type="hidden" name="setusermode" value="1">
-        <input type="checkbox" value="1" name="firehose_usermode" onchange="firehose_set_options('firehose_usermode', this.checked)"[% constants.markup_checked_attribute IF options.firehose_usermode %]> <b>User Mode</b>
+        <input type="checkbox" value="1" name="firehose_usermode" onchange="firehose_set_options('firehose_usermode', this.checked, 'global')"[% constants.markup_checked_attribute IF options.firehose_usermode %]> <b>User Mode</b>
 
 <br><br>
 [% END %]

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/firehose_tabs;misc;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/firehose_tabs;misc;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/firehose_tabs;misc;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -15,6 +15,7 @@
 10000
 __template__
 [% fh = Slash.getObject("Slash::FireHose"); %]
+
 [% rss_options = { "fhfilter" => "fhfilter", "orderdir" => "orderdir", "orderby" => "orderby", color => "color", "duration" => "duration" } %]
 [% rss_param_str = "" %]
 [% IF !user.is_anon %]
@@ -40,27 +41,32 @@
 		 END;
 		Slash.createSelect('tab', tabnames, { default => tab_current, return => 1, onchange => "firehose_set_options('tab', this.options[this.selectedIndex].value])"});
 	 ELSE %]
-	 	<li id="fhtab-section" [% IF options.sel_tabtype == "tabsection" && !active_set; active_set = 1; %]class="active"[% END %]>[% UNLESS options.sel_tabtype == "tabsection" %]<a href="/firehose.pl?tabtype=tabsection[% IF form.section %]&amp;section=[% form.section | strip_attribute %][% END %]"
- [% IF !user.is_anon %]onclick="firehose_set_options('tabsection',firehose_settings.section); return false"[% END %]>Stories</a>[% END %]
-<noscript><form action="/firehose.pl" method="post"><input type="hidden" name="tabtype" value="tabsection"></noscript>
-[% fh.createSectionSelect(section) %]
-<noscript><input type="submit" name="change" value="change"></form></noscript>
-		[% IF options.sel_tabtype == "tabsection" %]<a href="[% Slash.root2abs() %]/[% rss_skin_pre %]firehose_stories.rss" title="RSS for Stories"><img src="[% constants.imagedir %]/feed.png" alt="rss"></a>[% END %]
-</li>
-		<li id="fhtab-recent" [% IF options.sel_tabtype == "tabrecent" && !active_set; active_set = 1; %]class="active"[% END %]><a href="/firehose.pl?tabtype=tabrecent[% IF form.section %]&amp;section=[% form.section | strip_attribute %][% END %]" [% IF !user.is_anon %]onclick="firehose_set_options('tabtype','tabrecent'); return false"[% END %]>Recent</a>
-		[% IF options.sel_tabtype == "tabrecent"  %]<a href="[% Slash.root2abs() %]/[% rss_skin_pre %]firehose_recent.rss" "RSS for Recent"><img src="[% constants.imagedir %]/feed.png" alt="rss"></a>[% END %]
-</li>
-		<li id="fhtab-popular" [% IF options.sel_tabtype == "tabpopular" && !active_set; active_set = 1; %]class="active"[% END %]><a href="/firehose.pl?tabtype=tabpopular[% IF form.section %]&amp;section=[% form.section | strip_attribute %][% END %]" [% IF !user.is_anon %]onclick="firehose_set_options('tabtype','tabpopular'); return false"[% END %]>Popular</a>
-		[% IF options.sel_tabtype == "tabpopular" %]<a href="[% Slash.root2abs() %]/[%rss_skin_pre %]firehose_popular.rss" title="RSS for Popular"><img src="[% constants.imagedir %]/feed.png" alt="rss"></a>[% END %]
-		</li>
-		[% IF !user.is_anon %]
-	 	<li id="fhtab-user" [% IF options.sel_tabtype == "tabuser" && !active_set; active_set = 1; %]class="active"[% END %]><a href="/firehose.pl?tabtype=tabuser[% IF form.section %]&amp;section=[% form.section | strip_attribute %][% END %]" onclick="firehose_set_options('tabtype','tabuser'); return false">[% user.nickname | strip_literal %]</a>
-		[% IF options.sel_tabtype == "tabuser" && !user.is_anon && rss_param_str %]<a href="[% Slash.root2abs() %]/firehose.pl?op=rss&amp;content_type=rss[% rss_param_str %]&amp;logtoken=[% Slash.getPublicLogToken() | strip_paramattr %]" title="RSS for [% user.nickname | strip_literal %]"><img src="[% constants.imagedir %]/feed.png" alt="rss"></a>[% END %]
-		</li>
+		[% FOREACH view = views %]
+			[% active_view = 0 %]
+			[% IF options.view == view.viewname;
+				active_view = 1;
+				active_set = 1;
+			 END %]
+			[% IF active_view %]
+				[% rss_link = "";
+				   IF view.viewname == "stories";
+					rss_link = Slash.root2abs() _ "/" _ rss_skin_pre _ "firehose_stories.rss";
+                                   ELSIF view.viewname == "recent";
+					rss_link = Slash.root2abs() _ "/" _ rss_skin_pre _ "firehose_recent.rss";
+				   ELSIF view.viewname == "popular";
+					rss_link = Slash.root2abs() _ "/" _ rss_skin_pre _ "firehose_popular.rss";
+				   ELSIF !user.is_anon;
+					rss_link = Slash.root2abs() _ "/firehose.pl?op=rss&amp;content_type=rss" _ rss_param_str _ "&amp;logtoken=" _ Slash.strip_paramattr(Slash.getPublicLogToken());
+				   END;
+				%]
+			[% END %]
+			<li [% IF active_view %]class="active"[% END %]><a href="[% gSkin.rootdir %]/firehose.pl?view=[% view.viewname %]" onclick="firehose_set_options('view', '[% view.viewname %]');return false;">[% view.viewname %]</a> [% IF active_view && rss_link %]<a href="[% rss_link %]" title="RSS for [% view.viewname %]"><img src="[% constants.imagedir %]/feed.png"></a>[% END %]</li>
 		[% END %]
+
+
 	[% FOREACH tab = tabs %]
 		[% this_tab_active = 0 %]
-		<li id="fhtab-[% tab.tabid %]"[% IF tab.active && !active_set; active_set = 1; this_tab_active = 1; %] class="active"[% END %]>
+		<li id="fhtab-[% tab.tabid %]"[% IF options.tab == tab.tabname && !active_set; active_set = 1; this_tab_active = 1; %] class="active"[% END %]>
 		[% IF this_tab_active %]<span id="tab-form-[% tab.tabid %]" class="hide"><input type="text" id="tab-input-[% tab.tabid %]" size="12" value="[% tab.tabname | strip_literal %]"></span>[% END %]
 		<a href="[% IF this_tab_active %]#[% ELSE %]?tab=[% tab.tabname | strip_attribute %][% END %]" id="tab-text-[% tab.tabid %]" onClick="[% IF this_tab_active %]firehose_open_tab('[% tab.tabid %]');[% ELSE %]firehose_set_options('tab','[% tab.tabname %]');[% END %] return false;" [% IF this_tab_active %]title="Edit this tab"[% END %]>[% tab.tabname | strip_literal %][% IF this_tab_active %]<img src="[% constants.imagedir %]/sic_edit.png" alt="Edit">[% END %]</a>
 		[% IF this_tab_active && rss_param_str %]<a href="[% Slash.root2abs() %]/firehose.pl?op=rss&amp;content_type=rss[% rss_param_str %]&amp;logtoken=[% Slash.getPublicLogToken() | strip_paramattr %]" title="RSS for [% tab.tabname | strip_literal %]"><img src="[% constants.imagedir %]/feed.png" alt="rss"></a>[% END %]

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseIntro;misc;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseIntro;misc;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseIntro;misc;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -32,7 +32,7 @@
 END;
 IF item.url_id && url.url;
 	IF introtext; introtext = introtext _ "<br>"; END;
-	introtext = introtext _ "<a href='" _ url.url _ "'>" _ Slash.strip_literal(url.url) _ "</a>";
+	introtext = introtext _ "<a href='" _ url.url _ "'>Link To Original Source</a>";
 END;
 
 IF (!forform && item.type != "story") || nofollow;

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseTitle;misc;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseTitle;misc;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/formatHoseTitle;misc;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -111,18 +111,25 @@
 		ELSE;
 			editorpop_disp = '(' _ editorpop_disp _ ')';
 		END;
-		pop_str = '<span class="soda pop' _  pop_val _ '" title="Filter Firehose to entries rated ' _ color _ ' or better" onclick="firehose_set_options(\'color\',\'' _ color _ '\')"><span>' _ pop_disp _ editorpop_disp _ '</span></span> ';
+		pop_str = '<span class="soda pop' _  pop_val _ '" title="Filter Firehose to entries rated ' _ color _ ' or better" onclick="firehose_slider_set_color(\'' _ color _ '\')"><span>' _ pop_disp _ editorpop_disp _ '</span></span> ';
 	END;
         IF item.type != "story"; reject_checkbox = PROCESS reject_firehose id = item.id; END;
         title = reject_checkbox _ pop_str _ title;
 ELSE;
 	IF !form.skippop && !options.nocolors;
 		pop_str = '<span class="soda pop' _  pop_val _ '"';
-		pop_str = pop_str _ ' title="Filter Firehose to entries rated ' _ color _ ' or better" onclick="firehose_set_options(\'color\',\'' _ color _ '\')"';
-		pop_str = pop_str _ '><span>&nbsp;</span></span>';
+		pop_str = pop_str _ ' title="Filter Firehose to entries rated ' _ color _ ' or better" onclick="firehose_slider_set_color(\'' _ color _ '\')"';
+		pop_str = pop_str _ '><span>&nbsp;</span></span> ';
 	END;
         title = pop_str _ title;
 END;
+
+IF options.view == "userjournal";
+	IF options.user_view_uid == user.uid;
+		title = title _ ' [ <a href="' _ gSkin.rootdir _ '/journal.pl?op=edit&amp;id=' _ item.srcid _ '">Edit</a> ';
+		title = title _ ' | <a href="' _ gSkin.rootdir _ '/journal.pl?op=removemeta&amp;id=' _ item.srcid _ '">Delete</a> ] ';
+	END;
+END;
 	%]
 [% IF showtitle; title; END; %]
 __seclev__

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/list;firehose;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/list;firehose;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/list;firehose;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -13,6 +13,44 @@
 __seclev__
 10000
 __template__
+[%# this stuff may move later -- pudge %]
+[% IF options.view == "usersubmission";
+	submission_list = Slash.db.getSubmissionsByUID(options.user_view_uid);
+	submission_count = 0;
+	submission_reject = 0;
+	submission_pend = 0;
+	submission_hash = {};
+	FOR submission = submission_list;
+		submission_count = submission_count + 1;
+		IF submission.del == 0;
+			submission_pend = submission_pend + 1;
+		ELSIF submission.del == 1;
+			submission_reject = submission_reject + 1;
+		END;
+		submission_hash.${submission.subid} = submission;
+	END;
+	submission_accept = submission_count - (submission_reject + submission_pend) %]
+<div id="message"><div class="content">Submission Summary:
+[% submission_pend %] pending,
+[% submission_reject %] rejected,
+[% submission_accept %] accepted ([%
+	submission_count;
+	" total, ";
+	USE format;
+	percentage = format('%.2f');
+	percentage((100 * submission_accept) / (submission_accept + submission_reject + submission_pend))
+%]% accepted)</div></div>
+
+
+[% ELSIF options.view == "userjournal" AND (user.uid == options.user_view_uid) %]
+<div id="message"><div class="content">
+	<a href="[% gSkin.rootdir %]/journal.pl?op=list">Manage Journal Entries</a> |
+	<a href="[% gSkin.rootdir %]/journal.pl?op=editprefs">Edit Journal Preferences</a>
+</div></div>
+
+[% END %]
+
+
 [% IF form.metamod %]
 <div id="metamodwrap">
 [% END %]
@@ -146,7 +184,7 @@
 </span>
 [% PROCESS paginate options = options ulid = "fh-paginate" divid = "fh-pag-div" num_items = itemnum fh_page = fh_page last_day = last_day firehose_more_data = firehose_more_data %]
 <script type="text/javascript">
-	[% FOR opt = [ 'startdate', 'mode', 'fhfilter', 'orderdir', 'orderby', 'startdate', 'duration', 'color'] %]
+	[% FOR opt = [ 'startdate', 'mode', 'fhfilter', 'orderdir', 'orderby', 'startdate', 'duration', 'color', 'view', 'tab', 'base_filter'] %]
 		[%- opt_value = options.$opt -%]
 		[% IF opt == 'startdate' %]
 			[% opt_value = opt_value.replace('-',''); %]
@@ -194,7 +232,7 @@
 		firehose_play();
 	[% END %]
 
-[% IF constants.run_ads && !user.state.page_adless && !user.state.page_buying && user.currentSkin != 'admin' && (user.is_admin) # || user.currentPage == 'index2') %]
+[% IF 0 && constants.run_ads && !user.state.page_adless && !user.state.page_buying %]
 	fh_adTimerUrl = '/images/iframe/firehose.html';
 [% END %]
 

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/paginate;firehose;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/paginate;firehose;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/paginate;firehose;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -19,9 +19,13 @@
 [% day_page = fh_page %]
 [% IF fh_page == "users.pl"; day_page = "firehose.pl"; END %]
 [% IF form.index; day_page = "index2.pl"; END %]
-[% idle_submit_plug = "";
-   IF gSkin.name == "idle";
-	idle_submit_plug = '<span style="margin-left: 1em"><a href="' _ gSkin.rootdir _ '/submit.pl?primaryskid=' _ gSkin.skid _ '" class="vbutton bg_666666 rd_5">Submit Idle Story</a></span>';
+[% submit_plug = "";
+   IF options.view.match('^userjournal');
+	submit_plug = '<span style="margin-left: 1em"><a href="' _ gSkin.rootdir _ '/journal.pl?op=edit" class="vbutton bg_666666 rd_5">Write in Journal</a></span>';
+   ELSIF options.view == "usersubmission";
+	submit_plug = '<span style="margin-left: 1em"><a href="' _ gSkin.rootdir _ '/submit.pl?primaryskid=' _ gSkin.skid _ '" class="vbutton bg_666666 rd_5">Submit Story</a></span>';
+   ELSIF gSkin.name == "idle";
+	submit_plug = '<span style="margin-left: 1em"><a href="' _ gSkin.rootdir _ '/submit.pl?primaryskid=' _ gSkin.skid _ '" class="vbutton bg_666666 rd_5">Submit Idle Story</a></span>';
    END;
 
 %]
@@ -58,7 +62,7 @@
 		FOREACH cur_day = days;
 		%]
 		<span class="[% IF (cur_day.0 != last_day || options.orderby != "createtime") || firehose_more_data.future_count <= 0 %]in[% END %]active">
-			<a [% IF !user.is_anon %]onclick="firehose_set_options('issue','[% cur_day.0 %]'); return false;"[% END %] href="[% gSkin.rootdir %]/[% day_page %]?[% f = fh.genFireHoseParams(options, { startdate => cur_day.0, duration => 1}); f; %]">[% cur_day.1 | strip_literal %]</a>
+			<a [% IF !user.is_anon %]onclick="firehose_set_options('issue','[% cur_day.0 %]'); return false;"[% END %] href="[% gSkin.rootdir %]/[% day_page %]?[% f = fh.genFireHoseParams(options, { issue => cur_day.0}); f; %]">[% cur_day.1 | strip_literal %]</a>
 				[% IF firehose_more_data.day_num == cur_day.0 && firehose_more_data.future_count >=0 %]
 					[% Slash.getData('firehose_more_link', firehose_more_data, 'firehose'); %]
 					[% got_more_link = 1; %]
@@ -94,7 +98,7 @@
 			[% IF cur_day.2 %]
 				<a href="[% gSkin.rootdir %]/[% day_page %]">[% cur_day.1 | strip_literal %]</a>
 			[% ELSE %]
-				<a [% IF !user.is_anon %]onclick="firehose_set_options('issue','[% cur_day.0 %]'); return false;"[% END %] href="[% gSkin.rootdir %]/[% day_page %]?[% f = fh.genFireHoseParams(options, { startdate => cur_day.0, duration => 1}); f; %]">[% cur_day.1 | strip_literal %]</a>
+				<a [% IF !user.is_anon %]onclick="firehose_set_options('issue','[% cur_day.0 %]'); return false;"[% END %] href="[% gSkin.rootdir %]/[% day_page %]?[% f = fh.genFireHoseParams(options, { issue => cur_day.0 }); f; %]">[% cur_day.1 | strip_literal %]</a>
 			[% END %]
 			</span>
 		[% END %]
@@ -146,7 +150,7 @@
 
 	[% END %]
 [% END %]
-[% idle_submit_plug %]
+[% submit_plug %]
 [% END %]
 
 [% IF !contentsonly %]

Modified: slashjp/branches/upstream/current/plugins/FireHose/templates/tag_widget;firehose;default
===================================================================
--- slashjp/branches/upstream/current/plugins/FireHose/templates/tag_widget;firehose;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/FireHose/templates/tag_widget;firehose;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -57,7 +57,15 @@
 		[%# the tag 'bars' %]
 		<div class="tag-display-stub" context="user" init="legend:'my&nbsp;tags'"></div>
 		<div class="tag-display-stub" context="top" init="legend:'top&nbsp;tags'">[% tags.top %]</div>
-		<div class="tag-display-stub" context="system" init="legend:'system&nbsp;tags'">[% tags.system %]</div>
+		<div class="tag-display-stub" context="system" init="legend:'system&nbsp;tags'">[% tags.system;
+IF options.view == "usersubmission";
+	this_submission = Slash.db.getSubmission(item.srcid);
+	SWITCH this_submission.del;
+		CASE 0; ' pending';
+		CASE 1; ' rejected';
+		CASE 2; ' accepted';
+	END;
+END %]</div>
 		[%- IF item.type == "story" &&
 			constants.signoff_use &&
 			((user.is_admin && !user.firehose_usermode) || user.acl.signoff_allowed) &&
@@ -80,7 +88,16 @@
 		[%- END %]><span class="button collapse"></span></a>
 		[%# the tag 'bars' %]
 		<div class="tag-display-stub" context="top" init="legend:'top&nbsp;tags'">[% tags.top %]</div>
-		<div class="tag-display-stub" context="system" init="legend:'system&nbsp;tags'">[% tags.system %]</div>
+		<div class="tag-display-stub" context="system" init="legend:'system&nbsp;tags'">[% tags.system;
+IF options.view == "usersubmission";
+	this_submission = Slash.db.getSubmission(item.srcid);
+	SWITCH this_submission.del;
+		CASE 0; ' pending';
+		CASE 1; ' rejected';
+		CASE 2; ' accepted';
+	END;
+END %]</div>
+		<div class="tag-display-stub" context="datatype" init="legend:'type&nbsp;tag'">[% tags.datatype %]</div>
 	</div>
 	[% END %]
 [% END %]

Modified: slashjp/branches/upstream/current/plugins/Journal/Journal.pm
===================================================================
--- slashjp/branches/upstream/current/plugins/Journal/Journal.pm	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Journal/Journal.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -41,15 +41,30 @@
 
 	$self->sqlUpdate('journals', \%j1, "id=$id") if keys %j1;
 	$self->sqlUpdate('journals_text', \%j2, "id=$id") if $j2{article};
-	if ($constants->{plugin}{FireHose}) {
-		# XXX: this will not work with HumanConf!
+
+	$self->insertFireHose($id, $j1{promotetype});
+}
+
+sub insertFireHose {
+	my($self, $id, $promotetype) = @_;
+
+	return unless getCurrentStatic()->{plugin}{FireHose};
+
+	if ($promotetype ne 'post') {
 		my $reskey = getObject('Slash::ResKey');
 		my $rkey = $reskey->key('submit', { nostate => 1 });
-		if ($rkey && $rkey->createuse) {
-			my $firehose = getObject("Slash::FireHose");
-			$firehose->createUpdateItemFromJournal($id);
+		if (!$rkey || !$rkey->createuse) {
+			# user is not able to submit, so we make it
+			# a "non-submitted" FH entry
+			$self->sqlUpdate('journals',
+				{ promotetype => 'post' },
+				"id=" . $self->sqlQuote($id)
+			);
 		}
 	}
+
+	my $firehose = getObject("Slash::FireHose");
+	$firehose->createUpdateItemFromJournal($id);
 }
 
 sub getsByUid {
@@ -196,16 +211,8 @@
 	my($date) = $self->sqlSelect('date', 'journals', "id=$id");
 	my $slashdb = getCurrentDB();
 	$slashdb->setUser($user->{uid}, { journal_last_entry_date => $date });
-	if ($constants->{plugin}{FireHose}) {
-		# XXX: this will not work with HumanConf!
-		my $reskey = getObject('Slash::ResKey');
-		my $rkey = $reskey->key('submit', { nostate => 1 });
-		if ($rkey && $rkey->createuse) {
-			my $firehose = getObject("Slash::FireHose");
-			$firehose->createItemFromJournal($id);
-		}
-	}
 
+	$self->insertFireHose($id, $promotetype);
 
 	return $id;
 }
@@ -226,23 +233,25 @@
 	$self->sqlDelete("journals_text", "id=$id");
 
 	if ($journal->{discussion}) {
-		my $slashdb = getCurrentDB();
+#		my $slashdb = getCurrentDB();
 		# if has been submitted as story or submission, don't
 		# delete the discussion
-		if ($journal->{promotetype} eq 'publicize' || $journal->{promotetype} eq "publish") {
-			my $kind = $self->getDiscussion($journal->{discussion}, 'dkid');
-			my $kinds = $self->getDescriptions('discussion_kinds');
-			# set to disabled only if the journal has not been
-			# converted to a journal-story (it will get re-enabled
-			# later if it is converted to a journal-story)
-			if ($kinds->{$kind} eq 'journal') {
-				$slashdb->setDiscussion($journal->{discussion}, {
-					commentstatus	=> 'disabled',
-				});
-			}
-		} else {
-			$slashdb->deleteDiscussion($journal->{discussion});
-		}
+#		my $kind = $self->getDiscussion($journal->{discussion}, 'dkid');
+#		my $kinds = $self->getDescriptions('discussion_kinds');
+
+		# discussions can be re-used in the hose and stories ...
+		# just leave it alone entirely -- pudge 2008-11-17
+
+		# set to disabled only if the journal has not been
+		# converted to a journal-story (it will get re-enabled
+		# later if it is converted to a journal-story)
+#		if ($kinds->{$kind} eq 'journal') {
+#			$slashdb->setDiscussion($journal->{discussion}, {
+#				commentstatus	=> 'disabled',
+#			});
+#		} else {
+#			$slashdb->deleteDiscussion($journal->{discussion});
+#		}
 	}
 
 	my $date = $self->sqlSelect('MAX(date)', 'journals', "uid=$uid");
@@ -253,6 +262,15 @@
 	}
 	my $slashdb = getCurrentDB();
 	$slashdb->setUser($uid, { -journal_last_entry_date => $date });
+
+	if (getCurrentStatic()->{plugin}{FireHose}) {
+		$slashdb->sqlUpdate('firehose',
+			{ public => 'no' },
+			"type='journal' AND srcid=$id"
+		);
+	}
+
+
 	return $count;
 }
 

Modified: slashjp/branches/upstream/current/plugins/Journal/journal.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/Journal/journal.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Journal/journal.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -571,19 +571,7 @@
 		return($rkey->errstr, $rkey->failure);
 	}
 
-	# don't allow submission if user can't submit stories
-	# note: this may not work properly with SOAP, but submissions
-	# not enabled with SOAP now anyway
-	if ($constants->{journal_create_submission} && $form->{promotetype} eq 'publicize') {
-		my $reskey = getObject('Slash::ResKey');
-		my $submit_rkey = $reskey->key('submit', { nostate => 1 });
-		unless ($submit_rkey->createuse) {
-			return($submit_rkey->errstr, $submit_rkey->failure);
-		}
-	}
-
 	my $slashdb = getCurrentDB();
-        my $event_id;
 	if ($form->{id}) {
 		my %update;
 		my $article = $journal_reader->get($form->{id});
@@ -615,7 +603,6 @@
 				url	=> "$rootdir/~" . fixparam($user->{nickname}) . "/journal/$form->{id}",
 			});
 			$update{discussion}  = $did;
-                        $event_id = $did;
 
 		# update description if changed
 		} elsif (!$form->{comments_on} && $article->{discussion} && $article->{description} ne $description) {
@@ -657,7 +644,6 @@
 				url	=> "$rootdir/~" . fixparam($user->{nickname}) . "/journal/$id",
 			});
 			$journal->set($id, { discussion => $did });
-                        $event_id = $did;
 		}
 
 		slashHook('journal_save_success', { id => $id });
@@ -698,46 +684,6 @@
 		}) if $validator;
 	}
 
-        # Add the User2 event.
-        if ($event_id) {
-        my $events = $slashdb->sqlSelectAllHashref(
-                'eid', 'eid, date', 'user_events', "uid = " . $user->{uid} . " and code = 2");
-
-        if ((scalar keys %$events) == 5) {
-                my $eid = [sort keys %$events]->[0];
-                $slashdb->sqlDelete('user_events', "uid = " . $user->{uid} . " and code = 2 and eid = $eid");
-        }
-
-        $slashdb->sqlInsert('user_events', {
-                code  => 2,
-                uid   => $user->{uid},
-                event => $event_id,
-                -date  => 'NOW()',
-        });
-
-        my $event_blocks = $slashdb->sqlSelectAllHashref(
-                'uid', 'bid, uid, block', 'user_event_blocks', "uid = " . $user->{uid} . " and code = 2");
-
-        if (!%$event_blocks) {
-                $slashdb->sqlInsert('user_event_blocks', {
-                        code  => 2,
-                        uid   => $user->{uid},
-                        block => $event_id,
-                });
-        } else {
-                my @blocks = split(/,/, $event_blocks->{$user->{uid}}->{block});
-
-                if (scalar @blocks == 5) {
-                        @blocks = @blocks[1 .. 4];
-                }
-
-                $blocks[$#blocks + 1] = $event_id;
-                my $new_blocks = join(",", @blocks);
-
-                $slashdb->sqlUpdate('user_event_blocks', { block => $new_blocks }, "uid = " . $user->{uid} . " and code = 2");
-        }
-        } # $event_id
-
 	return 0;
 }
 

Modified: slashjp/branches/upstream/current/plugins/Submit/submit.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/Submit/submit.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Submit/submit.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -18,7 +18,8 @@
 	my $constants = getCurrentStatic();
 	my $user = getCurrentUser();
 	my $form = getCurrentForm();
-
+	
+	slashProfInit();
 	my $submiss_view = $constants->{submiss_view} || $user->{is_admin};
 
 	my %ops = (
@@ -73,9 +74,12 @@
 		}
 	) or return;
 
+	slashProf("submit-op");
 	$ops{$op}[FUNCTION]->($constants, $slashdb, $user, $form);
+	slashProf("","submit-op");
 
 	footer();
+	slashProfEnd();
 }
 
 #################################################################
@@ -129,12 +133,16 @@
 sub blankForm {
 	my($constants, $slashdb, $user, $form) = @_;
 	print getData('submit_body_open');
+	slashProf("pendingsubs");
 	yourPendingSubmissions($constants, $slashdb, $user, $form, { skip_submit_body => 1 });
+	slashProf("","pendingsubs");
 
 	my $reskey = getObject('Slash::ResKey');
 	my $rkey = $reskey->key('submit');
 	if ($rkey->create) {
+		slashProf("displayForm");
 		displayForm($user->{nickname}, $user->{fakeemail}, $form->{skin}, getData('defaulthead'));
+		slashProf("", "displayForm");
 	} else {
 		print $rkey->errstr;
 	}		

Modified: slashjp/branches/upstream/current/plugins/Tags/PLUGIN
===================================================================
--- slashjp/branches/upstream/current/plugins/Tags/PLUGIN	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Tags/PLUGIN	2008-11-26 06:51:20 UTC (rev 836)
@@ -5,6 +5,7 @@
 mysql_dump=mysql_dump.sql
 mysql_schema=mysql_schema.sql
 requiresplugin=Ajax
+task=archive_globjs_viewed.pl
 task=tagbox.pl
 task=tags_tagnamecache.pl
 task=tags_udc.pl

Added: slashjp/branches/upstream/current/plugins/Tags/archive_globjs_viewed.pl
===================================================================
--- slashjp/branches/upstream/current/plugins/Tags/archive_globjs_viewed.pl	                        (rev 0)
+++ slashjp/branches/upstream/current/plugins/Tags/archive_globjs_viewed.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+# This code is a part of Slash, and is released under the GPL.
+# Copyright 1997-2008 by Open Source Technology Group. See README
+# and COPYING for more information, or see http://slashcode.com/.
+
+# Add and delete counts may not precisely match because {uid,globjid}
+# pairs are unique to the separate tables, not across both tables.
+
+use strict;
+
+use Slash::Constants ':slashd';
+
+use vars qw( %task $me );
+
+$task{$me}{timespec} = '0-59/5 * * * *';
+$task{$me}{fork} = SLASHD_NOWAIT;
+$task{$me}{code} = sub {
+	my($virtual_user, $constants, $slashdb, $user) = @_;
+
+	my $min_gvid = $slashdb->sqlSelect('MIN(gvid)', 'globjs_viewed');
+	my $max_gvid = $min_gvid + 50_000;
+	my $where_clause = "gvid < $max_gvid AND viewed_at < DATE_SUB(NOW(), INTERVAL 6 MONTH)";
+
+	my $old_arch_size = $slashdb->sqlSelect('COUNT(*)', 'globjs_viewed_archived');
+	$slashdb->sqlDo("INSERT IGNORE INTO globjs_viewed_archived
+		SELECT * FROM globjs_viewed WHERE $where_clause");
+	my $new_arch_size = $slashdb->sqlSelect('COUNT(*)', 'globjs_viewed_archived');
+	my $added = $new_arch_size - $old_arch_size;
+
+	my $deleted = $slashdb->sqlDelete('globjs_viewed', $where_clause);
+
+	return "$added added, $deleted deleted";
+};
+
+1;
+

Modified: slashjp/branches/upstream/current/plugins/Tags/mysql_schema.sql
===================================================================
--- slashjp/branches/upstream/current/plugins/Tags/mysql_schema.sql	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Tags/mysql_schema.sql	2008-11-26 06:51:20 UTC (rev 836)
@@ -183,4 +183,13 @@
 	UNIQUE globjid_uid (globjid, uid)
 ) TYPE=InnoDB;
 
+CREATE TABLE globjs_viewed_archived (
+	gvid		int UNSIGNED NOT NULL,
+	globjid		int UNSIGNED NOT NULL,
+	uid		mediumint UNSIGNED NOT NULL,
+	viewed_at	datetime NOT NULL,
+	PRIMARY KEY (gvid),
+	UNIQUE globjid_uid (globjid, uid)
+) TYPE=InnoDB;
 
+

Added: slashjp/branches/upstream/current/plugins/Users2/MANIFEST
===================================================================
--- slashjp/branches/upstream/current/plugins/Users2/MANIFEST	                        (rev 0)
+++ slashjp/branches/upstream/current/plugins/Users2/MANIFEST	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,4 @@
+Users2.pm
+Makefile.PL
+MANIFEST
+PLUGIN

Added: slashjp/branches/upstream/current/plugins/Users2/Makefile.PL
===================================================================
--- slashjp/branches/upstream/current/plugins/Users2/Makefile.PL	                        (rev 0)
+++ slashjp/branches/upstream/current/plugins/Users2/Makefile.PL	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,9 @@
+use ExtUtils::MakeMaker;
+use DBIx::Password;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'	=> 'Slash::Users2',
+    'VERSION_FROM' => 'Users2.pm', # finds $VERSION
+    'PM'	=> { 'Users2.pm' => '$(INST_LIBDIR)/Users2.pm' },
+);

Added: slashjp/branches/upstream/current/plugins/Users2/PLUGIN
===================================================================
--- slashjp/branches/upstream/current/plugins/Users2/PLUGIN	                        (rev 0)
+++ slashjp/branches/upstream/current/plugins/Users2/PLUGIN	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,2 @@
+name=Users2
+description="Provides homepages for users"

Added: slashjp/branches/upstream/current/plugins/Users2/Users2.pm
===================================================================
--- slashjp/branches/upstream/current/plugins/Users2/Users2.pm	                        (rev 0)
+++ slashjp/branches/upstream/current/plugins/Users2/Users2.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,362 @@
+package Slash::Users2;
+
+use strict;
+use DBIx::Password;
+use Slash;
+use Slash::Constants qw(:messages);
+use Slash::Display;
+use Slash::Utility;
+
+use vars qw($VERSION);
+use base 'Exporter';
+use base 'Slash::DB::Utility';
+use base 'Slash::DB::MySQL';
+
+($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/;
+
+sub new {
+	my($class, $user) = @_;
+	my $self = {};
+
+	my $plugin = getCurrentStatic('plugin');
+	return unless $plugin->{'Users2'};
+
+	bless($self, $class);
+	$self->{virtual_user} = $user;
+	$self->sqlConnect;
+
+	return $self;
+}
+
+sub getLatestComments {
+        my($self, $uid) = @_;
+
+	my $uid_q = $self->sqlQuote($uid);
+        return $self->sqlSelectAllHashref(
+                'cid',
+                "sid, cid, subject, UNIX_TIMESTAMP(date) as date",
+                'comments',
+                "uid = $uid_q",
+                'order by date desc limit 5');
+}
+
+sub getLatestJournals {
+        my($self, $uid) = @_;
+        
+	my $uid_q = $self->sqlQuote($uid);
+        return $self->sqlSelectAllHashref(
+                'id',
+                'id, description, UNIX_TIMESTAMP(date) as date',
+                'journals',
+                "uid = $uid_q and promotetype = 'publish'",
+                'order by date desc limit 5');
+}
+
+sub getLatestSubmissions {
+        my($self, $uid) = @_;
+
+	my $uid_q = $self->sqlQuote($uid);
+        my $submissions = $self->sqlSelectAllHashref(
+                'id',
+                'id, UNIX_TIMESTAMP(createtime) as date',
+                'firehose',
+                "uid = $uid_q and rejected = 'no' and (type = 'submission' or type = 'feed')",
+                'order by createtime desc limit 5');
+
+        foreach my $subid (keys %$submissions) {
+                ($submissions->{$subid}{'title'}, $submissions->{$subid}{'introtext'}) =
+                        $self->sqlSelect('title, introtext', 'firehose_text', "id = $subid");
+        }
+
+        return $submissions;
+}
+
+sub getLatestFriends {
+        my($self, $uid) = @_;
+
+        my $uid_q = $self->sqlQuote($uid);
+        my $friends = $self->sqlSelectAllHashref(
+                'person',
+                'person',
+                'people',
+                "uid = $uid_q and type = 'friend'",
+                "order by id limit 5"
+        );
+
+        foreach my $id (keys %$friends) {
+                $friends->{$id}->{nickname} = $self->sqlSelect('nickname', 'users', "uid = $id");
+        }
+
+        return $friends;
+}
+
+sub getLatestBookmarks {
+        my($self, $uid, $latest_journals, $latest_submissions) = @_;
+
+        # Get the latest n bookmarks. These could be contained in journals and
+        # submissions, so we want journal size + submissions size + 5.
+        my $num_bookmarks = scalar(keys %$latest_journals) + scalar(keys %$latest_submissions) + 5;
+        my $uid_q = $self->sqlQuote($uid);
+        my $bookmarks_reader = getObject('Slash::Bookmark');
+        my $latest_bookmarks = $bookmarks_reader->getRecentBookmarksByUid($uid_q, $num_bookmarks);
+
+        # Make bookmarks unique against journals
+        my $bookmark_count = 0;
+        foreach my $bookmark (@$latest_bookmarks) {
+                foreach my $journal (keys %$latest_journals) {
+                        if ($bookmark->{initialtitle} eq $latest_journals->{$journal}->{description}) {
+                                delete @$latest_bookmarks[$bookmark_count];
+                                last;
+                        }
+                }
+                ++$bookmark_count;
+        }
+
+        # Make bookmarks unique against submissions
+        $bookmark_count = 0;
+        foreach my $bookmark (@$latest_bookmarks) {
+                foreach my $submission (keys %$latest_submissions) {
+                        if ($bookmark->{initialtitle} eq $latest_submissions->{$submission}->{title}) {
+                                delete @$latest_bookmarks[$bookmark_count];
+                                last;
+                        }
+                }
+                ++$bookmark_count;
+        }
+
+        return $latest_bookmarks;
+}
+
+sub getCommentsDatapane {
+        my($self, $uid, $user, $requested_user) = @_;
+        my $commentstruct = [];
+        my $form = getCurrentForm();
+        my $constants = getCurrentStatic();
+
+        my $min_comment = $form->{min_comment} || 0;
+        $min_comment = 0 unless $user->{seclev} > $constants->{comments_more_seclev}
+                || $constants->{comments_more_seclev} == 2 && $user->{is_subscriber};
+        my $comments_wanted = $user->{show_comments_num} || $constants->{user_comment_display_default};
+        my $commentcount = $self->countCommentsByUID($uid);
+        my $comments = $self->getCommentsByUID($uid, $comments_wanted, $min_comment) if $commentcount;
+
+        if (ref($comments) eq 'ARRAY') {
+                my $kinds = $self->getDescriptions('discussion_kinds');
+                for my $comment (@$comments) {
+                       # This works since $sid is numeric.
+                       $comment->{replies} = $self->countCommentsBySidPid($comment->{sid}, $comment->{cid});
+
+                # This is ok, since with all luck we will not be hitting the DB
+                # ...however, the "sid" parameter here must be the string
+                # based SID from either the "stories" table or from
+                # pollquestions.
+                my $discussion = $self->getDiscussion($comment->{sid});
+
+                        if ($kinds->{ $discussion->{dkid} } =~ /^journal(?:-story)?$/) {
+                                $comment->{type} = 'journal';
+                        } elsif ($kinds->{ $discussion->{dkid} } eq 'poll') {
+                                $comment->{type} = 'poll';
+                        } else {
+                                $comment->{type} = 'story';
+                        }
+                        $comment->{disc_title}  = $discussion->{title};
+                        $comment->{url} = $discussion->{url};
+                }
+        }
+
+        my $mod_reader = getObject("Slash::$constants->{m1_pluginname}", { db_type => 'reader' });
+        my $datapane = slashDisplay('u2CommentsDatapane', {
+                nick           => $requested_user->{nickname},
+                useredit       => $requested_user,
+                nickmatch_flag => ($user->{uid} == $uid ? 1 : 0),
+                commentstruct  => $comments,
+                commentcount   => $commentcount,
+                min_comment    => $min_comment,
+                reasons        => $mod_reader->getReasons(),
+                karma_flag     => 0,
+                admin_flag     => $user->{is_admin},
+        }, { Page => 'users', Return => 1});
+
+        return $datapane;
+}
+
+sub getTagsDatapane {
+        my($self, $uid, $requested_user, $private) = @_;
+
+        my $form = getCurrentForm();
+        my $tags_reader = getObject('Slash::Tags', { db_type => 'reader' });
+
+        my $tagname = $form->{tagname} || '';
+        $tagname = '' if !$tags_reader->tagnameSyntaxOK($tagname);
+        my $tagnameid = $tags_reader->getTagnameidFromNameIfExists($tagname);
+
+        if ($tagnameid) {
+		# Show all user's tags for one particular tagname.
+		my $tags_hr =
+			$tags_reader->getGroupedTagsFromUser($uid, { tagnameid => $tagnameid });
+                my $tags_ar = $tags_hr->{$tagname} || [ ];
+                return slashDisplay('usertagsforname', {
+                        useredit => $requested_user,
+                        tagname  => $tagname,
+                        tags     => $tags_ar,
+                        notitle  => 1,
+                }, { Page => 'users', Return => 1 });
+        } else {
+                my $tags_hr =
+			$tags_reader->getGroupedTagsFromUser($uid, { include_private => $private });
+                my $num_tags = 0;
+                for my $tn (keys %$tags_hr) {
+                        $num_tags += scalar @{ $tags_hr->{$tn} };
+                }
+
+		# Show all user's tagnames, with links to show all
+		# tags for each particular tagname.
+		my $tagname_ar = [ sort keys %$tags_hr ];
+		return slashDisplay('usertagnames', {
+                        useredit => $requested_user,
+                        tagnames => $tagname_ar,
+                        notitle  => 1,
+                }, { Page => 'users', Return => 1 });
+        }
+}
+
+sub getRelations {
+        my($self, $requested_uid, $relation, $nick, $user_uid) = @_;
+
+        my $zoo = getObject('Slash::Zoo', { db_type => 'reader' });
+        my $people = $zoo->getRelationships($requested_uid, $relation);
+        my $datapane;
+
+        if (@$people) {
+                $datapane = slashDisplay('plainlist', {
+                        people   => $people,
+                }, { Page => 'zoo', Return => 1 });
+        } else {
+		# Return a message stating the requested user has no such relationships.
+		# Need better use of Zoo constants here.
+		my %values = (
+                        1 => 'nofriends',
+                        2 => 'nofreaks',
+                        3 => 'nofans',
+                        4 => 'nofoes',
+                        5 => 'nofriendsoffriends',
+                        6 => 'nofriendsenemies',
+                );
+                my $value = $values{$relation} || 'noall';
+                $value = 'your' . $value if ($requested_uid == $user_uid);
+		$datapane = slashDisplay('data', {
+                        uid      => $requested_uid,
+                        nickname => $nick,
+                        value    => $value,
+                }, { Page => 'zoo', Return => 1 });
+        }
+
+        return $datapane;
+}
+
+sub getMarquee {
+        my($self, $latest_comments, $latest_journals, $latest_submissions) = @_;
+
+        my $latest_comment;
+        $latest_comment->{'ts'} = 0;
+        foreach my $latest_id (keys %$latest_comments) {
+                my ($id, $ts) = ($latest_id, $latest_comments->{$latest_id}{'date'});
+                ($latest_comment->{'id'}, $latest_comment->{'ts'})
+                        = ($id, $ts) if ($ts > $latest_comment->{'ts'});
+        }
+
+        my $latest_journal;
+        $latest_journal->{ts} = 0;
+        foreach my $latest_id (keys %$latest_journals) {
+                my ($id, $ts) = ($latest_id, $latest_journals->{$latest_id}{'date'});
+                ($latest_journal->{'id'}, $latest_journal->{'ts'})
+                        = ($id, $ts) if ($ts > $latest_journal->{'ts'});
+        }
+
+        my $latest_submission;
+        $latest_submission->{ts} = 0;
+        foreach my $latest_id (keys %$latest_submissions) {
+                my ($id, $ts) = ($latest_id, $latest_submissions->{$latest_id}{'date'});
+                ($latest_submission->{'id'}, $latest_submission->{'ts'})
+                        = ($id, $ts) if ($ts > $latest_submission->{'ts'});
+        }
+
+        my $latest_thing;
+        if (($latest_comment->{'ts'} > $latest_journal->{'ts'}) &&
+            ($latest_comment->{'ts'} > $latest_submission->{'ts'})) {
+                my $id = $latest_comment->{'id'};
+                $latest_thing->{'type'} = 'comment';
+                $latest_thing->{'id'} = $id;
+                $latest_thing->{'sid'} = $latest_comments->{$id}{'sid'};
+                $latest_thing->{'subject'} = $latest_comments->{$id}{'subject'};
+                $latest_thing->{'body'} = $self->sqlSelect('comment', 'comment_text', "cid = $id");
+
+        } elsif (($latest_journal->{'ts'} > $latest_comment->{'ts'}) &&
+                 ($latest_journal->{'ts'} > $latest_submission->{'ts'})) {
+                my $id = $latest_journal->{'id'};
+                $latest_thing->{'type'} = 'journal';
+                $latest_thing->{'id'} = $id;
+                $latest_thing->{'subject'} = $latest_journals->{$id}{'description'};
+                $latest_thing->{'body'} = $self->sqlSelect('article', 'journals_text', "id = $id");
+
+        } elsif (($latest_submission->{'ts'} > $latest_comment->{'ts'}) &&
+                 ($latest_submission->{'ts'} > $latest_journal->{'ts'})) {
+                my $id = $latest_submission->{'id'};
+                $latest_thing->{'type'} = 'submission';
+                $latest_thing->{'id'} = $id;
+                $latest_thing->{'subject'} = $latest_submissions->{$id}{'title'};
+                $latest_thing->{'body'} = $latest_submissions->{$id}{'introtext'};
+        }
+
+        return $latest_thing;
+}
+
+sub getMarqueeFireHoseId {
+	my($self, $marquee) = @_;
+	my $fhid;
+	if ($marquee && $marquee->{type}) {
+		if ($marquee->{type} eq "submission") {
+			$fhid = $marquee->{id};
+		} elsif ($marquee->{type} eq "journal" || $marquee->{type} eq "comment") {
+			my $fh_reader = getObject("Slash::FireHose", { db_type => "reader" });
+			my $item = $fh_reader->getFireHoseByTypeSrcid($marquee->{type}, $marquee->{id});
+			$fhid = $item->{id} if $item;
+
+		}
+	}
+	return $fhid;
+}
+
+sub DESTROY {
+	my($self) = @_;
+	$self->{_dbh}->disconnect if !$ENV{GATEWAY_INTERFACE} && $self->{_dbh};
+}
+
+
+1;
+
+__END__
+
+# Below is the stub of documentation for your module. You better edit it!
+
+=head1 NAME
+
+Slash::Users2
+
+=head1 SYNOPSIS
+
+	use Slash::Users2;
+
+=head1 DESCRIPTION
+
+Provides homepages for users.
+
+=head1 AUTHOR
+
+Christopher Brown, cbrow****@corp*****
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut

Modified: slashjp/branches/upstream/current/plugins/Zoo/Zoo.pm
===================================================================
--- slashjp/branches/upstream/current/plugins/Zoo/Zoo.pm	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/plugins/Zoo/Zoo.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -51,14 +51,12 @@
 
 	my $slashdb = getCurrentDB();
 	my $user = getCurrentUser();
-	my $people = $slashdb->getUser($uid, 'people');
-	if ($uid == $user->{uid}) {
-		$people = $user->{people};
-	} else {
-		$people = $slashdb->getUser($uid, 'people');
-	}
-	my @people = keys %{$people->{FRIEND()}};
-	return \@people;
+	my $people = $uid == $user->{uid}
+		? $user->{people}
+		: $slashdb->getUser($uid, 'people');
+
+	return [] if !$people || !$people->{FRIEND()};
+	return [ keys %{$people->{FRIEND()}} ];
 }
 
 sub setFriend {

Modified: slashjp/branches/upstream/current/sql/mysql/defaults.sql
===================================================================
--- slashjp/branches/upstream/current/sql/mysql/defaults.sql	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/sql/mysql/defaults.sql	2008-11-26 06:51:20 UTC (rev 836)
@@ -840,7 +840,7 @@
 INSERT INTO vars (name, value, description) VALUES ('cur_performance_stats_lastid', '0', 'accesslogid to start searching at');
 INSERT INTO vars (name, value, description) VALUES ('cur_performance_stats_weeks', '8', 'number of weeks back to compare current stats to');
 INSERT INTO vars (name, value, description) VALUES ('currentqid',1,'The Current Question on the homepage pollbooth');
-INSERT INTO vars (name, value, description) VALUES ('cvs_tag_currentcode','T_2_5_0_227','The current cvs tag that the code was updated to - this does not affect site behavior but may be useful for your records');
+INSERT INTO vars (name, value, description) VALUES ('cvs_tag_currentcode','T_2_5_0_231','The current cvs tag that the code was updated to - this does not affect site behavior but may be useful for your records');
 INSERT INTO vars (name, value, description) VALUES ('datadir','/usr/local/slash/www.example.com','What is the root of the install for Slash');
 INSERT INTO vars (name, value, description) VALUES ('db_auto_increment_increment','1','If your master DB uses auto_increment_increment, i.e. multiple master replication, echo its value into this var');
 INSERT INTO vars (name, value, description) VALUES ('dbsparklines_disp','0','Display dbsparklines in the currentAdminUsers box?');

Modified: slashjp/branches/upstream/current/sql/mysql/upgrades
===================================================================
--- slashjp/branches/upstream/current/sql/mysql/upgrades	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/sql/mysql/upgrades	2008-11-26 06:51:20 UTC (rev 836)
@@ -5602,18 +5602,12 @@
 # 2008-10-23
 UPDATE vars SET value = 'T_2_5_0_226' WHERE name = 'cvs_tag_currentcode';
 
-# SLASHCODE/USEPERL LAST UPDATED HERE
-
-# PUDGE LAST UPDATED HERE
-
 # Fixing incorrectly defined media types in 'css' table
 UPDATE css SET media="screen, projection" WHERE media="screen/projection";
 
 # 2008-10-24
 UPDATE vars SET value = 'T_2_5_0_227' WHERE name = 'cvs_tag_currentcode';
 
-# SLASHDOT LAST UPDATED HERE
-
 # for plugins/Bookmark
 ALTER TABLE bookmark_feeds ADD COLUMN nofilter TINYINT UNSIGNED DEFAULT 0 NOT NULL;
 
@@ -5625,3 +5619,82 @@
 # 2008-10-30
 UPDATE vars SET value = 'T_2_5_0_228' WHERE name = 'cvs_tag_currentcode';
 
+# for plugins/Bookmark
+ALTER TABLE bookmarks CHANGE COLUMN url_id url_id INT UNSIGNED NOT NULL;
+
+# For plugins/FireHose
+CREATE TABLE firehose_view(
+	id mediumint(8) unsigned NOT NULL auto_increment,
+	uid MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
+	viewname VARCHAR(16) NOT NULL DEFAULT 'unnamed',
+	useparentfilter ENUM("no","yes") DEFAULT "yes",
+	tab_display ENUM("no","yes") DEFAULT "no",
+	options_edit ENUM("no","yes") DEFAULT "no",
+	admin_maxitems tinyint NOT NULL DEFAULT -1,
+	maxitems tinyint NOT NULL DEFAULT -1,
+	seclev mediumint UNSIGNED NOT NULL DEFAULT '0',
+	filter VARCHAR(255) NOT NULL DEFAULT '',
+	orderby ENUM("popularity","createtime", "editorpop", "activity", "neediness", "") DEFAULT "createtime",
+	orderdir ENUM("ASC", "DESC", "") DEFAULT "DESC",
+	color VARCHAR(16) NOT NULL DEFAULT '',
+	duration ENUM("7","-1","") DEFAULT '',
+	mode ENUM ("full","fulltitle", "") DEFAULT "",
+	mixedmode ENUM("1","0","") DEFAULT "",
+	pause ENUM("1","0","") DEFAULT "",
+
+	PRIMARY KEY (id),
+	UNIQUE id_viewname(id,viewname)
+);
+
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "metamod", "no", "comment", "neediness", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 1,"1");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userjournal", "no", '"author:{nickname}" journal', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "usersubmission", "no", '"author:{nickname}" submission', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userbookmark", "no", '"author:{nickname}" bookmark', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userfirehose", "no", '"user:{nickname}"', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "stories", "yes", 'story', "createtime", "DESC", "black", "-1", "full", "1", "yes", "yes", 30, 30, 0,"");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "recent", "yes", '-story', "createtime", "DESC", "blue", "7", "fulltitle", "0", "yes", "yes", 50, 30, 0,"");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "popular", "yes", '-story', "createtime", "DESC", "black", "7", "full", "1", "yes", "yes", 50, 30, 0,"");
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "daddypants", "yes", 'unsigned', "createtime", "DESC", "indigo", "-1", "fulltitle", "1", "yes", "yes", 50, 30, 100,"");
+
+UPDATE firehose_view SET filter="-story" WHERE viewname="popular";
+
+# 2008-11-06
+UPDATE vars SET value = 'T_2_5_0_229' WHERE name = 'cvs_tag_currentcode';
+
+# for plugins/Tags
+CREATE TABLE globjs_viewed_archived (
+	gvid            int UNSIGNED NOT NULL,
+	globjid         int UNSIGNED NOT NULL,
+	uid             mediumint UNSIGNED NOT NULL,
+	viewed_at       datetime NOT NULL,
+	PRIMARY KEY (gvid),
+	UNIQUE globjid_uid (globjid, uid)
+) TYPE=InnoDB;
+
+# For plugins/Users2
+INSERT INTO vars (name, value, description) VALUES ('u2','0','Toggle on/off Users2');
+
+# For plugins/FireHose
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "usertag", "no", '"user:{nickname}" "tag:{tag}"', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+UPDATE firehose_view SET mixedmode="" WHERE viewname="daddypants";
+ALTER TABLE firehose_view MODIFY COLUMN viewname VARCHAR(24) DEFAULT 'unnamed';
+INSERT INTO firehose_view (id, uid, viewname, useparentfilter, filter, orderby, orderdir, color, duration, mode, mixedmode, tab_display, options_edit, admin_maxitems, maxitems, seclev, pause) VALUES (NULL, 0, "userjournalfriends", "no", '"authorfriend:{nickname}" journal', "createtime", "DESC", "black", "-1", "full", "0", "no", "no", 20, 20, 0,"1");
+
+# PUDGE LAST UPDATED HERE
+
+# skipping _230 because i goofed
+# 2008-11-20
+UPDATE vars SET value = 'T_2_5_0_231' WHERE name = 'cvs_tag_currentcode';
+
+# SLASHCODE/USEPERL LAST UPDATED HERE
+
+UPDATE firehose SET public="yes" WHERE type="journal";
+
+create temporary table firehose_deletedjournal (id int unsigned not null primary key);
+insert ignore into firehose_deletedjournal select firehose.id from firehose left join journals on (firehose.srcid=journals.id) where firehose.type='journal' and journals.id is null;
+update firehose, firehose_deletedjournal set firehose.public='no' where firehose.id=firehose_deletedjournal.id;
+drop table firehose_deletedjournal;
+
+# SLASHDOT LAST UPDATED HERE
+
+

Modified: slashjp/branches/upstream/current/tagboxes/FHEditorPop/FHEditorPop.pm
===================================================================
--- slashjp/branches/upstream/current/tagboxes/FHEditorPop/FHEditorPop.pm	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/tagboxes/FHEditorPop/FHEditorPop.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -102,9 +102,12 @@
 	} elsif ($type eq "journals") {
 		my $journal = getObject("Slash::Journal");
 		my $j = $journal->get($target_id);
-		$color_level = $j->{promotetype} && $j->{promotetype} eq 'publicize'
-			? 5  # requested to be publicized
-			: 6; # not requested
+		my $publicize = $j->{promotetype} && $j->{promotetype} eq 'publicize';
+		my $publish = $j->{promotetype} && $j->{promotetype} eq 'publish';
+		# Depending on whether the journal author asked for it to be
+		# publicized, published, or merely posted, its starting color
+		# for editors will be blue, indigo, or black.
+		$color_level = $publicize ? 5 : $publish ? 6 : 8;
 	} elsif ($type eq 'urls') {
 		$extra_pop = $self->sqlCount('bookmarks', "url_id=$target_id_q") || 0;
 		$color_level = $self->sqlCount("firehose", "type='feed' AND url_id=$target_id")

Modified: slashjp/branches/upstream/current/tagboxes/FireHoseScores/FireHoseScores.pm
===================================================================
--- slashjp/branches/upstream/current/tagboxes/FireHoseScores/FireHoseScores.pm	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/tagboxes/FireHoseScores/FireHoseScores.pm	2008-11-26 06:51:20 UTC (rev 836)
@@ -220,9 +220,12 @@
 	} elsif ($type eq "journals") {
 		my $journal = getObject("Slash::Journal");
 		my $j = $journal->get($target_id);
-		$color_level = $j->{promotetype} && $j->{promotetype} eq 'publicize'
-			? 5  # requested to be publicized
-			: 6; # not requested
+		my $publicize = $j->{promotetype} && $j->{promotetype} eq 'publicize';
+		my $publish = $j->{promotetype} && $j->{promotetype} eq 'publish';
+		# Depending on whether the journal author asked for it to be
+		# publicized, published, or merely posted, its starting color
+		# for regular users will be blue, indigo, or violet.
+		$color_level = $publicize ? 5 : $publish ? 6 : 7;
 	} elsif ($type eq 'urls') {
 		# XXX should modify next line by users' vote clout
 		$extra_pop = $self->sqlCount('bookmarks', "url_id=$target_id_q") || 0;

Modified: slashjp/branches/upstream/current/themes/slashcode/THEME
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/THEME	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/themes/slashcode/THEME	2008-11-26 06:51:20 UTC (rev 836)
@@ -340,6 +340,13 @@
 template=templates/imageLink;misc;default
 template=templates/help_main;misc;default
 template=templates/help_anon;misc;default
+template=templates/u2MainView;users;default
+template=templates/u2Menu;users;default
+template=templates/u2UserBio;users;default
+template=templates/u2CommentsDatapane;users;default
+template=templates/u2AdminListComments;users;default
+template=templates/u2UserBoxes;users;default
+template=templates/u2ListComments;users;default
 
 misc=misc/spamarmors
 plugin=Admin
@@ -357,3 +364,4 @@
 plugin=Submit
 plugin=Stats
 plugin=Zoo
+plugin=Users2

Modified: slashjp/branches/upstream/current/themes/slashcode/htdocs/slashcode_lite.css
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/htdocs/slashcode_lite.css	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/themes/slashcode/htdocs/slashcode_lite.css	2008-11-26 06:51:20 UTC (rev 836)
@@ -52,7 +52,9 @@
 #message,
 #message .content,
 #message .content p,
-#ostgnavbar
+#ostgnavbar,
+#usermenu ul.menu,
+#usermenu,  #wrapper
 {
 	color: #000 !important; background: transparent !important; border: none; font-family: serif;
 }

Modified: slashjp/branches/upstream/current/themes/slashcode/htdocs/users.pl
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/htdocs/users.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/themes/slashcode/htdocs/users.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -914,7 +914,7 @@
 	$form->{listonly} = 1;
 	$form->{legacy} = 1;
 
-	my $fhbox = $firehose->listView({ fh_page => 'users.pl'});
+	my $fhbox = $firehose->listView({ fh_page => 'users.pl', tab => 'userfirehose', user_view => $user_edit });
 	slashDisplay("userFireHose", { firehosebox => $fhbox, uid => $uid, useredit => $user_edit });
 }
 

Modified: slashjp/branches/upstream/current/themes/slashcode/htdocs/users2.pl
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/htdocs/users2.pl	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/themes/slashcode/htdocs/users2.pl	2008-11-26 06:51:20 UTC (rev 836)
@@ -533,7 +533,7 @@
 		title		=> $title,
 		block 		=> $block,
 		is_editable	=> $is_editable,
-	});
+	}, { Page => 'users' });
 
 	print portalbox($constants->{fancyboxwidth}, $block->{title},
 		$block->{block}, '', $block->{url});
@@ -792,7 +792,7 @@
 		nickmatch_flag		=> ($user->{uid} == $uid ? 1 : 0),
 		stories 		=> $stories,
 		storycount 		=> $storycount,
-	});
+	}, { Page => 'users' });
 }
 
 #################################################################
@@ -867,7 +867,7 @@
 		reasons			=> $mod_reader->getReasons(),
 		karma_flag		=> 0,
 		admin_flag		=> $user->{is_admin},
-	});
+	}, { Page => 'users' });
 }
 
 sub noUser {
@@ -895,16 +895,10 @@
 		tab_selected	=> $user_edit->{uid} == $user->{uid} ? 'me' : 'otheruser',
 	});
 	
-	$form->{mode} = "full";
-	$form->{color} = "black";
-	$form->{orderby} = "createtime";
-	$form->{orderdidr} = "DESC";
 	$form->{skipmenu} = 1;
-	$form->{duration} = -1;
-	$form->{fhfilter} = "\"user:$user_edit->{nickname}\"";
 	$form->{pause} = 1;
 
-	my $fhbox = $firehose->listView({ fh_page => 'users.pl'});
+	my $fhbox = $firehose->listView({ fh_page => 'users.pl', tab => 'userfirehose', user_view => $user_edit });
 	slashDisplay("userFireHose", { firehosebox => $fhbox, uid => $uid, useredit => $user_edit });
 }
 
@@ -916,12 +910,14 @@
 	my $id = $hr->{uid} || 0;
 
 	my $reader = getObject('Slash::DB', { db_type => 'reader' });
+	my $fh_reader = getObject('Slash::FireHose', { db_type => 'reader' });
 	my $slashdb = getCurrentDB();
 	my $form = getCurrentForm();
 	my $constants = getCurrentStatic();
 	my $user = getCurrentUser();
+	
+	$user->{state}{firehose_page} = "user";
 
-
 	my $admin_flag = ($user->{is_admin}) ? 1 : 0;
 	my($title, $admin_block, $fieldkey) = ('', '', '');
 	my $comments = undef;
@@ -998,12 +994,12 @@
 				$uid = $requested_user->{uid};
 				$nick = $requested_user->{nickname};
 				if ((my $conflict_id = $reader->getUserUID($id)) && $form->{userinfo}) {
-					#slashDisplay('showInfoConflict', {
-						#op		=> 'userinfo',
-						#id		=> $uid,
-						#nick		=> $nick,
-						#conflict_id	=> $conflict_id
-					#});
+					slashDisplay('showInfoConflict', {
+						op		=> 'userinfo',
+						id		=> $uid,
+						nick		=> $nick,
+						conflict_id	=> $conflict_id
+					}, { Page => 'users' });
 					return 1;
 				}
 			}
@@ -1073,7 +1069,7 @@
 	# the target user's info is not available until here.
 	vislenify($requested_user);
         my $msg = getMessage('user_header', { useredit => $requested_user, fieldkey => $fieldkey });
-        header($msg, '', { shill_id => $requested_user->{shill_id} }) or return;
+        header($msg, '', { shill_id => $requested_user->{shill_id}, U2 => 1 }) or return;
 	# This is a hardcoded position, bad idea and should be fixed -Brian
 	# Yeah, we should pull this into a template somewhere...
 	print getMessage('note', { note => $hr->{note} }) if defined $hr->{note};
@@ -1121,7 +1117,7 @@
 
 		$title = getTitle('user_netID_user_title', $data);
 
-		$admin_block = getUserAdmin($netid, $fieldkey, 0) if $admin_flag;
+		$admin_block = getUserAdmin($netid, $fieldkey, 0) if ($form->{dp} && $form->{dp} eq 'admin' && $admin_flag);
 
 		if ($form->{fieldname}) {
 			if ($form->{fieldname} eq 'ipid') {
@@ -1161,7 +1157,7 @@
 			}
 		}	
 	} else {
-		$admin_block = getUserAdmin($id, $fieldkey, 1) if $admin_flag;
+		$admin_block = getUserAdmin($id, $fieldkey, 1) if ($form->{dp} && $form->{dp} eq 'admin' && $admin_flag);
 
 		$commentcount      = $reader->countCommentsByUID($requested_user->{uid});
 		$commentcount_time = $reader->countCommentsByUID($requested_user->{uid}, { cid_at_or_after => $cid_for_time_period });
@@ -1303,24 +1299,24 @@
 	my $uid_hoursback = $constants->{istroll_uid_hours} || 72;
 
 	if ($requested_user->{nonuid}) {
-		#slashDisplay('netIDInfo', {
-			#title			=> $title,
-			#id			=> $id,
-			#useredit		=> $requested_user,
-			#commentstruct		=> $commentstruct || [],
-			#commentcount		=> $commentcount,
-			#min_comment		=> $min_comment,
-			#admin_flag		=> $admin_flag,
-			#admin_block		=> $admin_block,
-			#netid			=> $netid,
-			#netid_vis		=> $netid_vis,
-			#reasons			=> $mod_reader->getReasons(),
-			#subcount		=> $subcount,
-			#submissions		=> $submissions,
-			#hr_hours_back		=> $ipid_hoursback,
-			#cids_to_mods		=> $cids_to_mods,
-			#comment_time		=> $comment_time
-		#});
+		slashDisplay('netIDInfo', {
+			title			=> $title,
+			id			=> $id,
+			useredit		=> $requested_user,
+			commentstruct		=> $commentstruct || [],
+			commentcount		=> $commentcount,
+			min_comment		=> $min_comment,
+			admin_flag		=> $admin_flag,
+			admin_block		=> $admin_block,
+			netid			=> $netid,
+			netid_vis		=> $netid_vis,
+			reasons			=> $mod_reader->getReasons(),
+			subcount		=> $subcount,
+			submissions		=> $submissions,
+			hr_hours_back		=> $ipid_hoursback,
+			cids_to_mods		=> $cids_to_mods,
+			comment_time		=> $comment_time
+		}, { Page => 'users' });
 
 	} else {
 		if (! $requested_user->{uid}) {
@@ -1356,134 +1352,79 @@
 			$metamods = $metamod_reader->getMetamodlogForUser($uid, 30);
 		}
 
+		my $users2 = getObject('Slash::Users2', { db_type => 'reader' });
+
+		# Tags slashbox
 		my $tags_reader = getObject('Slash::Tags', { db_type => 'reader' });
 		my $tagshist;
 		if ($tags_reader) {
-			$tagshist = $tags_reader->getGroupedTagsFromUser($requested_user->{uid}, { orderby => 'created_at', orderdir => 'DESC', limit => 5, include_private => 1 });
+			$tagshist = $tags_reader->getGroupedTagsFromUser($requested_user->{uid}, { orderby => 'created_at', orderdir => 'DESC', include_private => 1, limit => 100 });
 		}
 
-                my $latest_comments = 
-                        $reader->sqlSelectAllHashref('cid',
-                                                     "sid, cid, subject, UNIX_TIMESTAMP(date) as date",
-                                                     'comments',
-                                                     "uid = $uid",
-                                                     'order by date desc limit 5');
-        
-                my $latest_comment;
-                $latest_comment->{'ts'} = 0;
-                foreach my $latest_id (keys %$latest_comments) {
-                        my ($id, $ts) = ($latest_id, $latest_comments->{$latest_id}{'date'});
-                        ($latest_comment->{'id'}, $latest_comment->{'ts'}) = ($id, $ts) if $ts > $latest_comment->{'ts'};
-                }
+		# Comments slashbox
+		my $latest_comments = $users2->getLatestComments($uid);
 
-                my $latest_journals =
-                        $reader->sqlSelectAllHashref('id',
-                                                     'id, description, UNIX_TIMESTAMP(date) as date',
-                                                     'journals',
-                                                     "uid = $uid and promotetype = 'publish'",
-                                                     'order by date desc limit 5');
+		# Journals slashbox
+		my $latest_journals = $users2->getLatestJournals($uid);
 
-                my $latest_journal;
-                $latest_journal->{ts} = 0;
-                foreach my $latest_id (keys %$latest_journals) {
-                        my ($id, $ts) = ($latest_id, $latest_journals->{$latest_id}{'date'});
-                        ($latest_journal->{'id'}, $latest_journal->{'ts'}) = ($id, $ts) if $ts > $latest_journal->{'ts'};
-                }
+		# Submissions slashbox
+		my $latest_submissions = $users2->getLatestSubmissions($uid);
 
-                my $latest_submissions =
-                        $reader->sqlSelectAllHashref('id',
-                                                     'id, UNIX_TIMESTAMP(createtime) as date',
-                                                     'firehose',
-                                                     "uid = $uid and rejected = 'no' and (type = 'submission' or type = 'feed')",
-                                                     'order by createtime desc limit 5');
+		# Bookmarks slashbox
+		my $latest_bookmarks =
+                        $users2->getLatestBookmarks($uid, $latest_journals, $latest_submissions);
 
-                foreach my $latest_subid (keys %$latest_submissions) {
-                        ($latest_submissions->{$latest_subid}{'title'}, $latest_submissions->{$latest_subid}{'introtext'}) =
-                                $reader->sqlSelect('title, introtext',
-                                                   'firehose_text',
-                                                   "id = $latest_subid");
-                }
+		# Friends slashbox
+		my $latest_friends = $users2->getLatestFriends($uid);
 
-                my $latest_submission;
-                $latest_submission->{ts} = 0;
-                foreach my $latest_id (keys %$latest_submissions) {
-                        my ($id, $ts) = ($latest_id, $latest_submissions->{$latest_id}{'date'});
-                        ($latest_submission->{'id'}, $latest_submission->{'ts'}) = ($id, $ts) if $ts > $latest_submission->{'ts'};
-                }
+		# Relationship pane
+		my $relations_datapane;
+                if ($form->{dp} && $form->{dp} =~ /^(?:friends|fans|freaks|foes|fof|eof|all)$/) {
+			# Need better use of Zoo constants here.
+			my %relations = (
+                                friends => 1,
+                                freaks  => 2,
+                                fans    => 3,
+                                foes    => 4,
+                                fof     => 5,
+                                eof     => 6,
+                                all     => undef,
+                        );
 
-                # Latest bookmarks
-                my $bookmarks_reader = getObject('Slash::Bookmark');
-                my $latest_bookmarks;
-                if ($bookmarks_reader) {
-                        $latest_bookmarks = $bookmarks_reader->getRecentBookmarksByUid($uid, 5);
-                }
+			$relations_datapane =
+				$users2->getRelations($uid, $relations{$form->{dp}}, $nick, $user->{uid});
+		}
 
-                my $latest_thing;
-                if (($latest_comment->{'ts'} > $latest_journal->{'ts'}) &&
-                    ($latest_comment->{'ts'} > $latest_submission->{'ts'})) {
-                        my $id = $latest_comment->{'id'};
-                        $latest_thing->{'type'} = 'comment';
-                        $latest_thing->{'id'} = $id;
-                        $latest_thing->{'sid'} = $latest_comments->{$id}{'sid'};
-                        $latest_thing->{'subject'} = $latest_comments->{$id}{'subject'};
-                        $latest_thing->{'body'} = $reader->sqlSelect('comment', 'comment_text', "cid = $id");
-
-                } elsif (($latest_journal->{'ts'} > $latest_comment->{'ts'}) &&
-                         ($latest_journal->{'ts'} > $latest_submission->{'ts'})) {
-                        my $id = $latest_journal->{'id'};
-                        $latest_thing->{'type'} = 'journal';
-                        $latest_thing->{'id'} = $id;
-                        $latest_thing->{'subject'} = $latest_journals->{$id}{'description'};
-                        $latest_thing->{'body'} = $reader->sqlSelect('article', 'journals_text', "id = $id");
-
-                } elsif (($latest_submission->{'ts'} > $latest_comment->{'ts'}) &&
-                         ($latest_submission->{'ts'} > $latest_journal->{'ts'})) {
-                        my $id = $latest_submission->{'id'};
-                        $latest_thing->{'type'} = 'submission';
-                        $latest_thing->{'id'} = $id;
-                        $latest_thing->{'subject'} = $latest_submissions->{$id}{'title'};
-                        $latest_thing->{'body'} = $latest_submissions->{$id}{'introtext'};
+		# Tags pane
+		my $tags_datapane;
+                if ($form->{dp} && $form->{dp} eq 'tags') {
+                        $tags_datapane =
+				$users2->getTagsDatapane($uid, $requested_user, $user->{is_admin});
                 }
 
-                my $latest_friends = $reader->sqlSelectAllHashref('person', 'person', 'people', "uid = $uid", "order by id limit 5");
-                foreach my $friend_id (keys %$latest_friends) {
-                        $latest_friends->{$friend_id}->{nickname} =
-                                $reader->sqlSelect("nickname", "users", "uid = $friend_id");
-                }
+		# Set up default view (remove marquee for subsections)
+		my $main_view = 0;
+                my $marquee;
+		my $not_fhid;
+                if ((!$form->{dp}) || ($form->{dp} eq 'admin' && !$user->{is_admin})) {
+                        $main_view = 1;
+                        $form->{dp} = 'firehose';
+			# Marquee is the "latest thing"
+			$marquee = $users2->getMarquee($latest_comments, $latest_journals, $latest_submissions);
+			$not_fhid = $users2->getMarqueeFireHoseId($marquee);
+		}
 
-                # Datapanes should be caluclated elsewhere. This is a temp kludge.
-                my $friends_datapane;
-                if ($form->{dp} eq 'friends') {
-                        my $zoo = getObject('Slash::Zoo');
-                        my $people = $zoo->getRelationships($uid, 1);
+		if ($form->{dp} eq 'firehose' || $form->{dp} =~ /^journal/ || $form->{dp} eq 'submissions' || $form->{dp} eq 'bookmarks' || $form->{dp} eq 'usertag') {
 
-                        if (@$people) {     
-                                $friends_datapane = slashDisplay('plainlist', {
-                                        people          => $people,
-                                        nickname        => $nick
-                                        }, { Page => 'zoo', Return => 1 }
-                                );
-                        }
-                }
-
-                my $tags_datapane;
-                $tags_datapane = showTags() if ($form->{dp} eq 'tags');
-
-		if ($form->{dp} && $form->{dp} == "firehose") {
 			$form->{listonly} = 1;
 			$form->{mode} = "full";
 			$form->{color} = "black";
 			$form->{orderby} = "createtime";
 			$form->{orderdir} = "DESC";
 			$form->{skipmenu} = 1;
-			$form->{duration} = -1;
-			$form->{fhfilter} = "\"user:$requested_user->{nickname}\"";
-			$form->{pause} = 1;
 		}
 
-                my $data_pane = $form->{dp};
-
-		slashDisplay('userInfo2', {
+		slashDisplay('u2MainView', {
 			title			=> $title,
 			uid			=> $uid,
 			useredit		=> $requested_user,
@@ -1510,10 +1451,12 @@
                         latest_submissions      => $latest_submissions,
                         latest_bookmarks        => $latest_bookmarks,
                         latest_friends          => $latest_friends,
-                        latest_thing            => $latest_thing,
-                        friends_datapane        => $friends_datapane,
-                        tags_datapane           => $tags_datapane,
-                        data_pane               => $data_pane,
+			marquee                 => $marquee,
+			relations_datapane      => $relations_datapane,
+			tags_datapane           => $tags_datapane,
+			data_pane               => $form->{dp},
+			main_view               => $main_view,
+			not_fhid		=> $not_fhid,
 		}, { Page => 'users', Skin => 'default'});
 	}
 

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2AdminListComments;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2AdminListComments;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2AdminListComments;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,312 @@
+__section__
+default
+__description__
+Template handles listing of comments for both IPIDs and UIDS
+Also can interleave moderations performed against the
+comments if they're provided and the user is an admin
+
+__title__
+u2AdminListComments;users;default
+__page__
+users
+__lang__
+en_US
+__name__
+u2AdminListComments
+__template__
+[% 
+total_cols = 7;
+a_count=0; a_down=0; 
+unanimous=0; unresolved=0;
+a_m2_down=0; a_m2_up=0; a_m2_count=0; a_m2_unfair_votes=0;
+moddable_items=0;
+prev_com = {};
+thread_toggle = 0;
+row_class_1 = "data_hl1";
+row_class_2 = "data_hl2";
+row_class_3 = "data_hl3";
+%]
+[% total_mods_shown=0; %]
+[% IF commentcount > 0 %]
+	[% commenttitle = ((min_comment == 0) ? "" : "$commentstruct.size of ");
+		IF type=="user";
+			thisnick = useredit.nickname | strip_literal;
+			commenttitle = comment_title _ thisnick _ "'s ";
+		ELSIF type=="netid";
+			 commenttitle = comment_title _ "$netid" _ "'s ";
+		END;
+		IF comment_time;
+		ELSE;
+		 commenttitle = commenttitle _ ((commentstruct.size == commentcount || min_comment > 0)
+			? ""
+			: "Latest $commentstruct.size of $commentcount ")
+		_ "Comment"
+		_ (commentcount == 1 ? "" : "s");
+		END;
+		IF comment_time;
+			commenttitle = commenttitle _ " comments for last $comment_time days ";
+		END %]
+	[% IF commentstruct.size > 0 and admin_flag %]
+		<form method="post" action="[% gSkin.rootdir %]/admin.pl">
+		<div>
+		<input type="hidden" name="op" value="moderate_recent">
+		[%	
+			returnto_base = PROCESS base_url;
+			returnto_tail = PROCESS state_url;
+			returnto = returnto_base _ returnto_url;
+		%]
+		<input type="hidden" name="returnto" value="[% returnto | strip_attribute %]">
+	[% END %]
+	[% IF title %]
+		[% show_m1s = form.show_m1s.defined ? form.show_m1s : user.mod_with_comm %]
+		[% show_m1s_op = show_m1s ? 0 : 1;
+		   IF admin_flag;
+		   	self_url = PROCESS base_url;
+		   	url_tail = PROCESS state_url override = { show_m1s => show_m1s_op};
+		   	self_url = self_url  _ url_tail;
+		   	extra = "<a href='" _ self_url _ "'><img src=\"" _  constants.imagedir _ (show_m1s ? "/contract.gif" : "/expand.gif") _ "\"  alt=\"\" width=\"14\" height=\"14\"></a>";
+		   END;
+		%]
+		[% PROCESS titlebar width="100%" title = commenttitle max_min_button = extra -%]
+		[% max_min_button = "" %]
+	[% END %]
+	<table width="100%" border="0" cellpadding="3" cellspacing="0" class="data">
+	<tr class="data_head">
+		[% IF type=="netid"; total_cols = total_cols + 1; %]<th>User</th>[% END %]
+		<th>Subject[% IF admin_flag %]<span class="admin_data_label"> / Moderator</span>[% END %]</th>
+		<th>Datestamp</th>
+		<th>[% IF admin_flag and constants.m1_admin_show_mods_with_comments %]<span class="admin_data_label">M2</span>[% END %]</th>
+		<th>Replies</th>
+		<th>[% IF admin_flag %]<span class="admin_data_label">CK</span>[% END %]</th>
+		<th>[% IF admin_flag %]<span class="admin_data_label">IPID</span>[% END %]</th>
+		<th>Score</th>
+	</tr>
+	[% n = min_comment %]
+	[% prev_comm_sid = 0; total_replies=0; total_karma=0; total_score=0; shown_comments=0 %]
+	[% FOREACH comment = commentstruct;  
+		n = n + 1;
+		shown_comments = shown_comments + 1; total_replies = comment.replies + total_replies;
+		replies = comment.replies ? comment.replies : '';
+		score = comment.pts + comment.tweak;
+		score = Slash.constrain_score(score)
+		total_score = comment.pts + total_score;
+		total_karma = comment.karma + total_karma;
+		reasonnum = comment.reason;
+		reasonname = reasons.$reasonnum.name;
+		IF reasonnum;	
+			IF !seen_reasons.$reasonname;  seen_reasons.$reasonname=0; END;
+			seen_reasons.$reasonname = seen_reasons.$reasonname + 1;
+		END;
+		reasontext = reasonnum ? ', ' _ reasons.$reasonnum.name : '';
+		%]
+		[% IF prev_comm_sid && prev_comm_sid != comment.sid; %][% PROCESS attached_to_row the_comment = prev_com colspan=total_cols %] [% thread_toggle=!thread_toggle; END %]
+		[%-
+		'<tr class="'; thread_toggle ? row_class_1 : row_class_2; '">';
+		IF type == "netid";
+		'<td valign="top"><nobr>';
+		%]
+		[%- PROCESS nick_and_uid nickname=comment.nickname uid=comment.uid -%]
+		[%-	
+		'</nobr></td>';
+		END;
+		IF admin_flag and comment.type!="archived";
+			moddable_items=moddable_items+1;
+		END;
+		'<td valign="top">';
+			IF min_comment > 0; '<b>'; n; '</b> '; END;
+			'<a href="';
+				gSkin.rootdir;
+				'/comments.pl?sid='; comment.sid;
+				'&amp;cid='; comment.cid;
+			'">';
+			comment.subj;
+			'</a>&nbsp;';
+		'</td>';
+		'<td valign="top"><nobr>&nbsp;'; IF comment.type == "archived"; "*"; END; Slash.timeCalc(comment.cdate); '</nobr></td>';
+		'<td></td>';
+		'<td valign="top" align="right"><nobr>&nbsp;'; replies; '</nobr></td>';
+		'<td align="right">'; IF admin_flag; comment.karma; END; '</td>';
+		'<td>'; 
+			IF admin_flag; -%]
+			 	[%- PROCESS link_ipid ipid=comment.ipid ipid_vis=comment.ipid_vis -%]
+			[% END; 
+		'</td>';
+		'<td valign="top"><nobr>&nbsp;'; %][% PROCESS make_reason_mod_select text = score _ reasontext reasons = reasons comment=comment admin_flag=admin_flag %][% '</nobr></td>';
+		"</tr>\n";
+		%]
+		[% IF admin_flag and constants.m1_admin_show_mods_with_comments %]
+			[%- FOREACH m = cids_to_mods.${comment.cid}; total_mods_shown = total_mods_shown+1; %]
+				[%- IF m.active;
+					a_count=a_count+1;
+					IF m.val< 1;
+						a_down=a_down+1;
+					END;
+					a_m2_count = a_m2_count + m.m2fair + m.m2unfair;
+					a_m2_unfair_votes = a_m2_unfair_votes + m.m2unfair;
+					IF m.m2status>0;
+						IF m.m2fair > m.m2unfair;  a_m2_up = a_m2_up + 1; END;
+						IF m.m2unfair > m.m2fair;  a_m2_down = a_m2_down + 1; END;
+						IF (m.m2unfair == 0) and (m.m2fair>0 ); unanimous=unanimous + 1; END;
+					ELSE;
+						IF reasons.${m.reason}.m2able;
+							unresolved=unresolved + 1;
+						END;
+					END;
+				 END -%]
+				[% IF form.show_m1s.defined ? form.show_m1s : user.mod_with_comm %]
+				<tr class="[% row_class_3 %]">
+				[% IF type=="netid" %]<td></td>[% END %]
+				<td align=right>[% PROCESS nick_and_uid nickname=m.nickname uid=m.uid %]</td>
+				<td>[% Slash.timeCalc(m.ts) %][% IF !m.active %]*[% END %]</td>
+				<td>[% PROCESS make_m2_string moderation=m reasons=reasons%]</td>
+				<td> </td>
+				<td> </td>
+				<td>[% PROCESS link_ipid ipid=m.ipid ipid_vis=Slash.vislenify(m.ipid) %]</td>
+				<td>[% IF m.val > 0; "+"; END; m.val %], [% reasons.${m.reason}.name %] </td>
+				
+ </tr>
+				[% END %]
+			[%- END -%]
+		[%- END -%]
+		[%- prev_com = comment -%]
+		[%-  prev_comm_sid = comment.sid; -%]
+		[%- END -%]
+		[% IF shown_comments > 0 %]
+				[%- PROCESS attached_to_row the_comment = commentstruct.last colspan=total_cols -%]
+				[%-
+					avg_score = total_score / shown_comments FILTER format('%2.1f');
+					reason_most = ""; reason_most_hits = -1;
+					FOREACH rs = seen_reasons;
+						IF rs.value > reason_most_hits;
+							reason_most = rs.key;
+							reason_most_hits = rs.value;
+						END;
+					END; %]
+					[%
+
+					IF admin_flag and constants.m1_admin_show_mods_with_comments and total_mods_shown>0; %]
+						<tr class="[% row_class_1 %]><td colspan="[% total_cols %]">[% PROCESS horiz_rule %]</td></tr>
+						[%
+						'<tr class="' _ row_class_3 _ '">';
+						IF type=="netid"; 
+							"<td></td>"; 
+						END; 
+						'<td align="right"> Total Moderations: ' _ a_count _ '</td>';
+				 	  	'<td align="left">'; IF constants.m2 %][% unanimous %] Unanimous [% a_m2_up %] Fair [% a_m2_down %] Unfair [% unresolved %] Unresolved[% ELSE; '&nbsp;'; END %]</td>
+						[%-
+						'<td align="left" colspan="3">'; IF constants.m2 %][% a_m2_unfair_votes %] Unfair ([% Slash.getData('percentage', { sum=> a_m2_unfair_votes, count => a_m2_count}, "misc") %])[% ELSE; '&nbsp;'; END %]</td> [%
+						'<td></td>';
+				      		'<td align="left">';%] [% Slash.getData('percentage',{ sum=>a_down, count => a_count},"misc") %] Downmods</a> </td>[%
+						'</tr>';
+					END;
+
+					"<tr class=\"" _ row_class_2 _ "\"><td "; IF type=="netid"; 'colspan="2"'; END; ">";
+					IF commentcount > n && (user.seclev > constants.comments_more_seclev
+						|| (constants.comments_more_seclev == 2 && user.is_subscriber)); %]
+                                                        <a href="/users2.pl?op=userinfo&uid=[% useredit.uid %]&min_comment=[% n %]">[% commentcount - n %] More Comment[% IF (commentcount-n)>1 %]s[% END %]...</a>
+					[% END %]
+					</td>
+<td></td><td></td>
+					<td align="right">[% IF admin_flag %]<b>[% total_replies %]</b>[% END %]</td>
+					<td align="right">[% IF admin_flag %]<b>[% total_karma %]</b>[% END %]</td>
+					<td></td>
+					<td>[% IF admin_flag %]<b>[% avg_score %][% IF reason_most_hits>0 %], [% reason_most %][% END %]</b>
+						[% IF moddable_items %]<br><input type="submit" value="Moderate">[% END %]
+					[% END %]</td>
+					</tr>
+		[% END %]				
+		</table>
+		[%- IF commentstruct.size > 0 and admin_flag -%]
+			</div></form>
+		[%- END -%]
+ [% END %]
+
+
+[% BLOCK attached_to_row;
+	IF the_comment.disc_type == 'poll';
+		the_label = 'Poll: ';
+	ELSIF the_comment.disc_type == 'journal';
+		the_label = 'Journal Discussion: ';
+	ELSE;
+		the_label = '';
+	END;
+	the_label = the_label _ the_comment.disc_title; %]
+	<tr class="[% thread_toggle ? row_class_1 : row_class_2; %]"><td valign="top" colspan="[% colspan %]" align="right">&nbsp;&nbsp;&nbsp;attached to <a href="[% the_comment.url | strip_urlattr %]">[% the_label %]</a></td></tr>
+[% END %]
+
+[% BLOCK nick_and_uid;
+	nickname | strip_literal;
+	IF uid != constants.anonymous_coward_uid;
+		' (<a href="';
+		gSkin.rootdir;
+		'/users.pl?op=userinfo&amp;fieldname=uid&amp;userfield=';
+		uid;
+		'">';
+		uid;
+		'</a>)';
+	END;
+END %]
+
+[% BLOCK link_ipid %]
+<a href="[% gSkin.rootdir %]/users.pl?op=userinfo&amp;userfield=[% ipid | strip_attribute %]&amp;fieldname=ipid">[% ipid_vis %]</a>
+[% END %]
+
+[% BLOCK make_m2_string; 
+	IF !constants.m2 || !reasons.${moderation.reason}.m2able || !moderation.active;
+		m2fair_str = "-";
+		m2unfair_str = "-";
+	ELSE;
+		IF moderation.m2status > 0; 
+			m2fair_str = "<b><i>" _ moderation.m2fair _ "</i></b>"; m2unfair_str = "<b><i>" _ moderation.m2unfair _ "</i></b>";
+	        ELSE;
+			m2fair_str = moderation.m2fair; m2unfair_str =  moderation.m2unfair;
+        	END;
+	END;
+	m2fair_str _ " " _ m2unfair_str;
+ END %]
+
+[% BLOCK make_reason_mod_select %]
+	[% IF admin_flag and comment.type != "archived";
+	h = { "" => text };
+	FOREACH r = reasons;
+		h.${r.key} = reasons.${r.key}.name;
+	END;
+	Slash.createSelect("reason_${comment.sid}_${comment.cid}", h, '', 1, 1);
+	ELSE;
+		text;
+	END %]
+[% END %]
+
+[% BLOCK base_url %]
+	[% base_url = gSkin.rootdir _ "/users.pl?op=userinfo&amp;fieldname=";
+	IF type == "user";
+		base_url = "/users.pl?op=userinfo&amp;uid=" _ useredit.uid;
+	ELSE; 
+		fp_fieldname = BLOCK; form.fieldname | fixparam; END;
+		fp_netid = BLOCK; netid | fixparam; END;
+		base_url = base_url _ fp_fieldname _ "&amp;userfield=" _ fp_netid;
+	END;
+	base_url;
+	%]
+[% END %]
+[% BLOCK state_url;
+	state_url="";
+	state_params = ["show_m2s","show_m1s","min_comment","m2_listing"];
+	FOREACH param = state_params;
+		state_param = "st_" _ param;
+		IF form.${param}.defined || override.${param}.defined;
+			state_url = state_url _ "&amp;" _ param _ "=";
+			IF override.${param}.defined;
+				fp_val = BLOCK; override.${param} | fixparam; END;
+			ELSE;
+				fp_val = BLOCK; form.${param} | fixparam; END;
+			END;
+			state_url = state_url _ fp_val;
+		END;
+	END;
+	state_url;
+END %]
+
+__seclev__
+10000
+__version__

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2CommentsDatapane;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2CommentsDatapane;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2CommentsDatapane;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,40 @@
+__section__
+default
+__description__
+Display user's info
+
+__title__
+
+__page__
+users
+__lang__
+en_US
+__name__
+u2CommentsDatapane
+__template__
+[% IF commentstruct.size %]
+	[% n = min_comment %]
+	[% FOREACH comment = commentstruct %]
+		[% n = n + 1 %]
+		[% IF comment.type == 'poll';
+			label   = "Poll: $comment.disc_title ";
+			ELSIF comment.type == 'journal';
+			label   = "Journal Discussion: $comment.disc_title";
+			ELSE;
+			label    = comment.disc_title;
+		END %]
+		<br><b>[% n %]</b> <a href="[% gSkin.rootdir %]/comments.pl?sid=[% comment.sid %]&amp;cid=[% comment.cid %]">
+		[% comment.subject %]</a> posted on [% Slash.timeCalc(comment.date) %]
+	(Score:[% comment.points %][% IF comment.replies %] Replies: [% comment.replies %][% END %])
+		<br>attached to <a href="[% comment.url %]">[% label %]</a>
+	[% END %]
+	[% IF (user.seclev > constants.comments_more_seclev || (comments_more_seclev == 2 && user.is_subscriber)) && commentcount > n %]
+		<p><a href="[% gSkin.rootdir %]/users2.pl?dp=comments&amp;min_comment=[% n %]"     >More Comments...</a>
+	[% END %]
+[% ELSE %]
+	<b>[% useredit.nickname | strip_literal %] has yet to post any comments.</b>
+[% END %]
+
+__seclev__
+500
+__version__

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2ListComments;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2ListComments;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2ListComments;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,311 @@
+__section__
+default
+__description__
+Template handles listing of comments for both IPIDs and UIDS
+Also can interleave moderations performed against the
+comments if they're provided and the user is an admin
+
+__title__
+u2ListComments;users;default
+__page__
+users
+__lang__
+en_US
+__name__
+u2ListComments
+__template__
+[% 
+total_cols = 7;
+a_count=0; a_down=0; 
+unanimous=0; unresolved=0;
+a_m2_down=0; a_m2_up=0; a_m2_count=0; a_m2_unfair_votes=0;
+moddable_items=0;
+prev_com = {};
+thread_toggle = 0;
+row_class_1 = "data_hl1";
+row_class_2 = "data_hl2";
+row_class_3 = "data_hl3";
+%]
+[% total_mods_shown=0; %]
+[% IF commentcount > 0 %]
+	[% commenttitle = ((min_comment == 0) ? "" : "$commentstruct.size of ");
+		IF type=="user";
+			thisnick = useredit.nickname | strip_literal;
+			commenttitle = comment_title _ thisnick _ "'s ";
+		ELSIF type=="netid";
+			 commenttitle = comment_title _ "$netid" _ "'s ";
+		END;
+		IF comment_time;
+		ELSE;
+		 commenttitle = commenttitle _ ((commentstruct.size == commentcount || min_comment > 0)
+			? ""
+			: "Latest $commentstruct.size of $commentcount ")
+		_ "Comment"
+		_ (commentcount == 1 ? "" : "s");
+		END;
+		IF comment_time;
+			commenttitle = commenttitle _ " comments for last $comment_time days ";
+		END %]
+	[% IF commentstruct.size > 0 and admin_flag %]
+		<form method="post" action="[% gSkin.rootdir %]/admin.pl">
+		<div>
+		<input type="hidden" name="op" value="moderate_recent">
+		[%	
+			returnto_base = PROCESS base_url;
+			returnto_tail = PROCESS state_url;
+			returnto = returnto_base _ returnto_url;
+		%]
+		<input type="hidden" name="returnto" value="[% returnto | strip_attribute %]">
+	[% END %]
+	[% IF title %]
+		[% show_m1s = form.show_m1s.defined ? form.show_m1s : user.mod_with_comm %]
+		[% show_m1s_op = show_m1s ? 0 : 1;
+		   IF admin_flag;
+		   	self_url = PROCESS base_url;
+		   	url_tail = PROCESS state_url override = { show_m1s => show_m1s_op};
+		   	self_url = self_url  _ url_tail;
+		   	extra = "<a href='" _ self_url _ "'><img src=\"" _  constants.imagedir _ (show_m1s ? "/contract.gif" : "/expand.gif") _ "\"  alt=\"\" width=\"14\" height=\"14\"></a>";
+		   END;
+		%]
+		[% max_min_button = "" %]
+	[% END %]
+	<table width="100%" border="0" cellpadding="3" cellspacing="0" class="data">
+	<tr>
+		[% IF type=="netid"; total_cols = total_cols + 1; %]<th>User</th>[% END %]
+		<th>Subject[% IF admin_flag %]<span class="admin_data_label"> / Moderator</span>[% END %]</th>
+		<th>Datestamp</th>
+		<th>[% IF admin_flag and constants.m1_admin_show_mods_with_comments %]<span class="admin_data_label">M2</span>[% END %]</th>
+		<th>Replies</th>
+		<th>[% IF admin_flag %]<span class="admin_data_label">CK</span>[% END %]</th>
+		<th>[% IF admin_flag %]<span class="admin_data_label">IPID</span>[% END %]</th>
+		<th>Score</th>
+	</tr>
+	[% n = min_comment %]
+	[% prev_comm_sid = 0; total_replies=0; total_karma=0; total_score=0; shown_comments=0 %]
+	[% FOREACH comment = commentstruct;  
+		n = n + 1;
+		shown_comments = shown_comments + 1; total_replies = comment.replies + total_replies;
+		replies = comment.replies ? comment.replies : '';
+		score = comment.pts + comment.tweak;
+		score = Slash.constrain_score(score)
+		total_score = comment.pts + total_score;
+		total_karma = comment.karma + total_karma;
+		reasonnum = comment.reason;
+		reasonname = reasons.$reasonnum.name;
+		IF reasonnum;	
+			IF !seen_reasons.$reasonname;  seen_reasons.$reasonname=0; END;
+			seen_reasons.$reasonname = seen_reasons.$reasonname + 1;
+		END;
+		reasontext = reasonnum ? ', ' _ reasons.$reasonnum.name : '';
+		%]
+		[% IF prev_comm_sid && prev_comm_sid != comment.sid; %][% PROCESS attached_to_row the_comment = prev_com colspan=total_cols %] [% thread_toggle=!thread_toggle; END %]
+		[%-
+		'<tr class="'; thread_toggle ? row_class_1 : row_class_2; '">';
+		IF type == "netid";
+		'<td valign="top"><nobr>';
+		%]
+		[%- PROCESS nick_and_uid nickname=comment.nickname uid=comment.uid -%]
+		[%-	
+		'</nobr></td>';
+		END;
+		IF admin_flag and comment.type!="archived";
+			moddable_items=moddable_items+1;
+		END;
+		'<td valign="top">';
+			IF min_comment > 0; '<b>'; n; '</b> '; END;
+			'<a href="';
+				gSkin.rootdir;
+				'/comments.pl?sid='; comment.sid;
+				'&amp;cid='; comment.cid;
+			'">';
+			comment.subj;
+			'</a>&nbsp;';
+		'</td>';
+		'<td valign="top"><nobr>&nbsp;'; IF comment.type == "archived"; "*"; END; Slash.timeCalc(comment.cdate); '</nobr></td>';
+		'<td></td>';
+		'<td valign="top" align="right"><nobr>&nbsp;'; replies; '</nobr></td>';
+		'<td align="right">'; IF admin_flag; comment.karma; END; '</td>';
+		'<td>'; 
+			IF admin_flag; -%]
+			 	[%- PROCESS link_ipid ipid=comment.ipid ipid_vis=comment.ipid_vis -%]
+			[% END; 
+		'</td>';
+		'<td valign="top"><nobr>&nbsp;'; %][% PROCESS make_reason_mod_select text = score _ reasontext reasons = reasons comment=comment admin_flag=admin_flag %][% '</nobr></td>';
+		"</tr>\n";
+		%]
+		[% IF admin_flag and constants.m1_admin_show_mods_with_comments %]
+			[%- FOREACH m = cids_to_mods.${comment.cid}; total_mods_shown = total_mods_shown+1; %]
+				[%- IF m.active;
+					a_count=a_count+1;
+					IF m.val< 1;
+						a_down=a_down+1;
+					END;
+					a_m2_count = a_m2_count + m.m2fair + m.m2unfair;
+					a_m2_unfair_votes = a_m2_unfair_votes + m.m2unfair;
+					IF m.m2status>0;
+						IF m.m2fair > m.m2unfair;  a_m2_up = a_m2_up + 1; END;
+						IF m.m2unfair > m.m2fair;  a_m2_down = a_m2_down + 1; END;
+						IF (m.m2unfair == 0) and (m.m2fair>0 ); unanimous=unanimous + 1; END;
+					ELSE;
+						IF reasons.${m.reason}.m2able;
+							unresolved=unresolved + 1;
+						END;
+					END;
+				 END -%]
+				[% IF form.show_m1s.defined ? form.show_m1s : user.mod_with_comm %]
+				<tr class="[% row_class_3 %]">
+				[% IF type=="netid" %]<td></td>[% END %]
+				<td align=right>[% PROCESS nick_and_uid nickname=m.nickname uid=m.uid %]</td>
+				<td>[% Slash.timeCalc(m.ts) %][% IF !m.active %]*[% END %]</td>
+				<td>[% PROCESS make_m2_string moderation=m reasons=reasons%]</td>
+				<td> </td>
+				<td> </td>
+				<td>[% PROCESS link_ipid ipid=m.ipid ipid_vis=Slash.vislenify(m.ipid) %]</td>
+				<td>[% IF m.val > 0; "+"; END; m.val %], [% reasons.${m.reason}.name %] </td>
+				
+ </tr>
+				[% END %]
+			[%- END -%]
+		[%- END -%]
+		[%- prev_com = comment -%]
+		[%-  prev_comm_sid = comment.sid; -%]
+		[%- END -%]
+		[% IF shown_comments > 0 %]
+				[%- PROCESS attached_to_row the_comment = commentstruct.last colspan=total_cols -%]
+				[%-
+					avg_score = total_score / shown_comments FILTER format('%2.1f');
+					reason_most = ""; reason_most_hits = -1;
+					FOREACH rs = seen_reasons;
+						IF rs.value > reason_most_hits;
+							reason_most = rs.key;
+							reason_most_hits = rs.value;
+						END;
+					END; %]
+					[%
+
+					IF admin_flag and constants.m1_admin_show_mods_with_comments and total_mods_shown>0; %]
+						<tr class="[% row_class_1 %]><td colspan="[% total_cols %]">[% PROCESS horiz_rule %]</td></tr>
+						[%
+						'<tr class="' _ row_class_3 _ '">';
+						IF type=="netid"; 
+							"<td></td>"; 
+						END; 
+						'<td align="right"> Total Moderations: ' _ a_count _ '</td>';
+				 	  	'<td align="left">'; IF constants.m2 %][% unanimous %] Unanimous [% a_m2_up %] Fair [% a_m2_down %] Unfair [% unresolved %] Unresolved[% ELSE; '&nbsp;'; END %]</td>
+						[%-
+						'<td align="left" colspan="3">'; IF constants.m2 %][% a_m2_unfair_votes %] Unfair ([% Slash.getData('percentage', { sum=> a_m2_unfair_votes, count => a_m2_count}, "misc") %])[% ELSE; '&nbsp;'; END %]</td> [%
+						'<td></td>';
+				      		'<td align="left">';%] [% Slash.getData('percentage',{ sum=>a_down, count => a_count},"misc") %] Downmods</a> </td>[%
+						'</tr>';
+					END;
+
+					"<tr class=\"" _ row_class_2 _ "\"><td "; IF type=="netid"; 'colspan="2"'; END; ">";
+					IF commentcount > n && (user.seclev > constants.comments_more_seclev
+						|| (constants.comments_more_seclev == 2 && user.is_subscriber)); %]
+                                                        <a href="/users2.pl?dp=comments&uid=[% useredit.uid %]&min_comment=[% n %]">[% commentcount - n %] More Comment[% IF (commentcount-n)>1 %]s[% END %]...</a>
+					[% END %]
+					</td>
+<td></td><td></td>
+					<td align="right">[% IF admin_flag %]<b>[% total_replies %]</b>[% END %]</td>
+					<td align="right">[% IF admin_flag %]<b>[% total_karma %]</b>[% END %]</td>
+					<td></td>
+					<td>[% IF admin_flag %]<b>[% avg_score %][% IF reason_most_hits>0 %], [% reason_most %][% END %]</b>
+						[% IF moddable_items %]<br><input type="submit" value="Moderate">[% END %]
+					[% END %]</td>
+					</tr>
+		[% END %]				
+		</table>
+		[%- IF commentstruct.size > 0 and admin_flag -%]
+			</div></form>
+		[%- END -%]
+ [% END %]
+
+
+[% BLOCK attached_to_row;
+	IF the_comment.disc_type == 'poll';
+		the_label = 'Poll: ';
+	ELSIF the_comment.disc_type == 'journal';
+		the_label = 'Journal Discussion: ';
+	ELSE;
+		the_label = '';
+	END;
+	the_label = the_label _ the_comment.disc_title; %]
+	<tr class="[% thread_toggle ? row_class_1 : row_class_2; %]"><td valign="top" colspan="[% colspan %]" align="right">&nbsp;&nbsp;&nbsp;attached to <a href="[% the_comment.url | strip_urlattr %]">[% the_label %]</a></td></tr>
+[% END %]
+
+[% BLOCK nick_and_uid;
+	nickname | strip_literal;
+	IF uid != constants.anonymous_coward_uid;
+		' (<a href="';
+		gSkin.rootdir;
+		'/users.pl?op=userinfo&amp;fieldname=uid&amp;userfield=';
+		uid;
+		'">';
+		uid;
+		'</a>)';
+	END;
+END %]
+
+[% BLOCK link_ipid %]
+<a href="[% gSkin.rootdir %]/users.pl?op=userinfo&amp;userfield=[% ipid | strip_attribute %]&amp;fieldname=ipid">[% ipid_vis %]</a>
+[% END %]
+
+[% BLOCK make_m2_string; 
+	IF !constants.m2 || !reasons.${moderation.reason}.m2able || !moderation.active;
+		m2fair_str = "-";
+		m2unfair_str = "-";
+	ELSE;
+		IF moderation.m2status > 0; 
+			m2fair_str = "<b><i>" _ moderation.m2fair _ "</i></b>"; m2unfair_str = "<b><i>" _ moderation.m2unfair _ "</i></b>";
+	        ELSE;
+			m2fair_str = moderation.m2fair; m2unfair_str =  moderation.m2unfair;
+        	END;
+	END;
+	m2fair_str _ " " _ m2unfair_str;
+ END %]
+
+[% BLOCK make_reason_mod_select %]
+	[% IF admin_flag and comment.type != "archived";
+	h = { "" => text };
+	FOREACH r = reasons;
+		h.${r.key} = reasons.${r.key}.name;
+	END;
+	Slash.createSelect("reason_${comment.sid}_${comment.cid}", h, '', 1, 1);
+	ELSE;
+		text;
+	END %]
+[% END %]
+
+[% BLOCK base_url %]
+	[% base_url = gSkin.rootdir _ "/users.pl?op=userinfo&amp;fieldname=";
+	IF type == "user";
+		base_url = "/users.pl?op=userinfo&amp;uid=" _ useredit.uid;
+	ELSE; 
+		fp_fieldname = BLOCK; form.fieldname | fixparam; END;
+		fp_netid = BLOCK; netid | fixparam; END;
+		base_url = base_url _ fp_fieldname _ "&amp;userfield=" _ fp_netid;
+	END;
+	base_url;
+	%]
+[% END %]
+[% BLOCK state_url;
+	state_url="";
+	state_params = ["show_m2s","show_m1s","min_comment","m2_listing"];
+	FOREACH param = state_params;
+		state_param = "st_" _ param;
+		IF form.${param}.defined || override.${param}.defined;
+			state_url = state_url _ "&amp;" _ param _ "=";
+			IF override.${param}.defined;
+				fp_val = BLOCK; override.${param} | fixparam; END;
+			ELSE;
+				fp_val = BLOCK; form.${param} | fixparam; END;
+			END;
+			state_url = state_url _ fp_val;
+		END;
+	END;
+	state_url;
+END %]
+
+__seclev__
+10000
+__version__

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2MainView;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2MainView;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2MainView;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,211 @@
+__section__
+default
+__description__
+Display user's info
+
+__title__
+
+__page__
+users
+__lang__
+en_US
+__name__
+u2MainView
+__template__
+[% orig_title = title %]
+
+[% IF main_view %]
+<div class="head">
+        <div class="yui-b">
+                [% PROCESS u2UserBio useredit=useredit %]
+        </div>
+
+        <div class="article" id="marquee_content">
+                <h3>[% marquee.subject %]</h3>
+                <div class="body">
+                        [% marquee.body %]
+                </div>
+        </div>
+</div>
+[% END %]
+
+[% PROCESS u2Menu 
+        data_pane=data_pane
+        comments_size=latest_comments.size
+        journals_size=latest_journals.size
+        submissions_size=latest_submissions.size
+        bookmarks_size=latest_bookmarks.size
+        tagshist_size=tagshist.size
+        is_admin=user.is_admin
+        nickname=useredit.nickname
+%]
+
+<div class="yui-b" id="userboxes">
+        [% IF !main_view; PROCESS u2UserBio useredit=useredit; END; %]
+
+        [% PROCESS u2UserBoxes
+                latest_comments=latest_comments
+                latest_journals=latest_journals
+                latest_submissions=latest_submissions
+                latest_bookmarks=latest_bookmarks
+                latest_friends=latest_friends
+                tagshist=tagshist
+                is_admin=user.is_admin
+        %]
+
+</div>
+
+
+<div id="yui-main">
+        <div class="yui-b">
+
+        [% IF data_pane == 'admin' && admin_flag %]
+                [% admin_block %]
+
+                <p>
+
+                [%
+                IF constants.m2;
+                        mod_options.show_m2s = form.show_m2s.defined ? form.show_m2s : user.m2_with_mod;
+                        mod_options.need_m2_form = 1;
+                        mod_options.need_m2_button = 1;
+                        mod_options.meta_mod_only = 1;
+                END;
+
+                m1_classname = "Slash::" _ constants.m1_pluginname;
+                moddb = Slash.getObject(m1_classname);
+                IF moddb; moddb.dispModCommentLog('uid', useredit.uid, mod_options); END;
+
+                IF !constants.m1_admin_show_mods_with_comments;
+                        mod_options.title = "Moderations performed on";
+                        mod_options.title = mod_options.title _ nickname | strip_literal;
+                        mod_options.title = mod_options.title _ "'s comments";
+                        mod_options.hr_hours_back = hr_hours_back;
+
+                        IF moddb; moddb.dispModCommentLog('cuid', useredit.uid, mod_options); END;
+                END;
+
+                IF constants.m2;
+                        m2_listing = form.m2_listing.defined ? form.m2_listing : user.show_m2_listing;
+                        IF m2_listing;
+                                "<h3>Recent M2s</h3>";
+                                PROCESS listMetamods
+                                        m2_listing = m2_listing
+                                        metamods = metamods
+                                        the_user = useredit;
+                        END;
+                END;
+
+                '<p>';
+
+                IF tagshist && tagshist.size > 0;
+                        "<h3>Recent Tags</h3>";
+                        '<table class="data" width="100%">';
+                        '<tr class="data_head"><th>Tag</th><th>Object</th><th>Time</th></tr>';
+                        toggle = 0;
+                        FOREACH tag = tagshist.keys.sort;
+                                '<tr class="data_hl'; toggle ? "2" : "1"; '">';
+                                '<td>'; tagshist.$tag.0.tagname; '</td>';
+                                '<td>';
+                                IF tagshist.$tag.0.globj_type == "stories";
+                                        PROCESS linkStory dynamic=1 sid=tagshist.$tag.0.story.sid text=tagshist.$tag.0.story.title title=tagshist.$tag.0.story.title;
+                                ELSIF tagshist.$tag.0.globj_type == "urls";
+                                        '<a href="';
+                                        tagshist.$tag.0.url.url;
+                                        '">'; tagshist.$tag.0.url.bookmark.title || tagshist.$tag.0.url.validtitle || tagshist.$tag.0.url.initialtitle | strip_literal;
+                                        '</a>';
+                                ELSIF tagshist.$tag.0.globj_type == "journals";
+                                        nick = Slash.db.getUser(tagshist.$tag.0.journal.uid, 'nickname');
+                                        '<a href="';
+                                        gSkin.rootdir;
+                                        '/~';
+                                        nick | fixparam;
+                                        '/journal/';
+                                        tagshist.$tag.0.journal.id;
+                                        '/">';
+                                        tagshist.$tag.0.journal.description | strip_literal;
+                                        '</a>';
+                                ELSIF tagshist.$tag.0.globj_type == "submissions";
+                                        '<a href="';
+                                        gSkin.rootdir;
+                                        '/submit.pl?op=viewsub&amp;subid=';
+                                        tagshist.$tag.0.submission.subid;
+                                        '">';
+                                        tagshist.$tag.0.submission.subj | strip_literal;
+                                        '</a>';
+                                END;
+                                '&nbsp;('; tagshist.$tag.0.globj_type; ')';
+                                '</td>';
+                                '<td>'; Slash.timeCalc(tagshist.$tag.0.created_at); '</td>';
+                                '</tr>';
+                                toggle = !toggle;
+                        END;
+                        '</table>';
+                END;
+                %]
+
+        [% ELSIF data_pane == 'journal';
+                fh = Slash.getObject("Slash::FireHose");
+		fhbox = fh.listView({ fh_page => 'users.pl', view => 'userjournal', user_view => useredit, not_id => not_fhid });
+                fhbox;
+
+           ELSIF data_pane == 'journalfriends';
+                fh = Slash.getObject("Slash::FireHose");
+                fhbox = fh.listView({ fh_page => 'users.pl', view => 'userjournalfriends', user_view => useredit, not_id => not_fhid });
+                fhbox;
+
+           ELSIF data_pane == 'submissions';
+                fh = Slash.getObject("Slash::FireHose");
+                fhbox = fh.listView({ fh_page => 'users.pl', view => 'usersubmission', user_view => useredit, not_id => not_fhid });
+                fhbox;
+
+           ELSIF data_pane == 'bookmarks';
+                fh = Slash.getObject("Slash::FireHose");
+                fhbox = fh.listView({ fh_page => 'users.pl', view => 'userbookmark', user_view => useredit, not_id => not_fhid });
+                fhbox;
+        %]
+        [% ELSIF (data_pane == 'friends') ||
+                 (data_pane == 'fans')    ||
+                 (data_pane == 'freaks')  ||
+                 (data_pane == 'foes')    ||
+                 (data_pane == 'fof')     ||
+                 (data_pane == 'eof')     ||
+                 (data_pane == 'all') %]
+                <p>
+                <div id="friendsmenu">
+                        <ul>
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/friends">Friends</a></li>
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/fans">Fans</a></li>
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/foes">Foes</a></li>
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/freaks">Freaks</a></li>
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/friends/friends">Friends of Friends</a></li>
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/friends/foes">Foes of Friends</a></li>
+                        </ul>
+                </div>
+                [% relations_datapane %]
+
+        [% ELSIF data_pane == 'tags' %]
+                [% tags_datapane %]
+
+        [% ELSIF data_pane == 'comments' %]
+                [% PROCESS u2ListComments admin_flag=admin_flag commentstruct=commentstruct commentcount=commentcount min_comment=min_comment reasons=reasons cids_to_mods=cids_to_mods type="user" useredit=useredit comment_time=comment_time %]
+
+        [% ELSIF data_pane == 'firehose' || data_pane == '';
+                fh = Slash.getObject("Slash::FireHose");
+		fhbox = fh.listView({ fh_page => 'users.pl', view => 'userfirehose', user_view => useredit, not_id => not_fhid });
+                fhbox;
+	%]
+        [% ELSIF data_pane == 'usertag';
+                fh = Slash.getObject("Slash::FireHose");
+		fhbox = fh.listView({ fh_page => 'users.pl', view => 'usertag', user_view => useredit, not_id => not_fhid, tag => form.tagname });
+                fhbox;
+        END %]
+        </div>
+</div>
+
+
+[% title = orig_title %]
+
+__seclev__
+500
+__version__

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2Menu;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2Menu;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2Menu;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,31 @@
+__section__
+default
+__description__
+Display user's info
+
+__title__
+
+__page__
+users
+__lang__
+en_US
+__name__
+u2Menu
+__template__
+[% tilde = '^'; IF constants.u2; tilde = '~'; END; %]
+<div class="nav">
+<ul class="menu" id="tablist">
+<li[% IF data_pane == 'firehose' || data_pane == '' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/firehose">Firehose</a></li>
+[% IF comments_size != 0 %]<li[% IF data_pane == 'comments' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/comments">Comments</a></li>[% END %]
+[% IF journals_size != 0 %]<li[% IF data_pane == 'journal' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/journal">Journals</a></li>[% END %]
+[% IF submissions_size != 0 %]<li[% IF data_pane == 'submissions' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/submissions">Submissions</a></li>[% END %]
+[% IF bookmarks_size != 0 %]<li[% IF data_pane == 'bookmarks' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/bookmarks">Bookmarks</a></li>[% END %]
+<li[% IF data_pane == 'friends' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/friends">Friends</a></li>
+[% IF tagshist_size > 2 || data_pane == "usertag" %]<li[% IF data_pane == 'tags' || data_pane == 'usertag' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]/tags">Tags</a></li>[% END %]
+[% IF is_admin %]<li[% IF data_pane == 'admin' %] class="active"[% END %]><a href="[% gSkin.rootdir %]/[% tilde; nickname | strip_paramattr %]">Admin</a></li>[% END %]
+</ul>
+</div>
+
+__seclev__
+500
+__version__

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBio;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBio;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBio;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,128 @@
+__section__
+default
+__description__
+Display user's bio
+
+__title__
+
+__page__
+users
+__lang__
+en_US
+__name__
+u2UserBio
+__template__
+[% tilde = '^'; IF constants.u2; tilde = '~'; END; %]
+<div class="block" id="user_bio">
+        <div class="title" id="user_bio_title">
+        	<h4><a href="[% gSkin.rootdir %]/[% tilde; useredit.nickname | strip_paramattr %]" style="text-decoration:none;">[% useredit.nickname | strip_literal %] ([% useredit.uid %])</a> [% PROCESS zoo_icons person=useredit.uid implied="" %]</h4>
+	</div>
+
+        <div class="content" id="user_bio_content">
+        [%
+                IF user.uid == useredit.uid OR user.is_admin;
+                        IF useredit.realname; useredit.realname | strip_literal; ELSE; '(no real name given)<br>'; END;
+                        '<a href="mailto:';
+                        useredit.realemail | strip_paramattr; '">';
+                        Slash.ellipsify(Slash.strip_literal(useredit.realemail)); '</a>';
+                        '<br>';
+
+                        IF useredit.fakeemail;
+                                IF useredit.fakeemail == useredit.realemail;
+                                        '(shown without obfuscation)';
+                                ELSE;
+                                        'shown as <a href="mailto:';
+                                        useredit.fakeemail | strip_paramattr; '">';
+                                        Slash.ellipsify(Slash.strip_literal(useredit.fakeemail)); '</a>';
+                                END;
+                        ELSE;
+                                '(email not shown publicly)';
+                        END;
+                ELSE;
+                        '<br>&nbsp;&nbsp;';
+                        IF useredit.fakeemail;
+                                '<a href="mailto:';
+                                useredit.fakeemail | strip_paramattr; '">';
+                                Slash.ellipsify(Slash.strip_literal(useredit.fakeemail)); '</a>';
+                        ELSE;
+                               '(email not shown publicly)';
+                        END;
+                END;
+
+                IF useredit.homepage;
+                        '<br><a href="';
+                        useredit.homepage | strip_attribute;
+                        '"';
+                        IF useredit.karma <= constants.goodkarma;
+                                ' rel="nofollow"';
+                        END;
+                        '>';
+                        Slash.ellipsify(Slash.strip_literal(useredit.homepage)); '</a>';
+                END;
+
+                IF user.uid == useredit.uid OR user.is_admin;
+                        '<br>Karma: ';
+                        PROCESS karma karma=useredit.karma admin_flag=user.is_admin;
+                END;
+
+                IF useredit.aim && !useredit.aimdisplay;
+                        '<br><b>AOL IM:</b> ';
+                        useredit.aim | strip_literal;
+                        ' (<b><a href="aim:addbuddy?screenname=';
+                        useredit.aim | strip_attribute;
+                        '">Add Buddy</a>, ';
+                        '<a href="aim:goim?screenname=';
+                        useredit.aim | strip_attribute;
+                        '&amp;message=Greetings!">Send Message</a></b>)';
+                END;
+
+                IF useredit.yahoo;
+                        '<br><b>Yahoo! ID:</b> ';
+                        '<a href="http://profiles.yahoo.com/';
+                        useredit.yahoo | strip_attribute;
+                        '">';
+                        useredit.yahoo | strip_literal;
+                        '</a> (<b><a href="http://edit.yahoo.com/config/set_buddygrp?';
+                        '.src=&amp;.cmd=a&amp;.bg=Friends&amp;.bdl=';
+                        useredit.yahoo | strip_attribute;
+                        '">Add User</a>, ';
+                        '<a href="http://edit.yahoo.com/config/send_webmesg?.target=';
+                        useredit.yahoo | strip_attribute;
+                        '">Send Message</a></b>)';
+                END;
+
+                IF useredit.jabber;
+                        '<br><b>Jabber:</b> ';
+                        useredit.jabber | strip_literal;
+                END;
+
+                IF useredit.calendar_url;
+                        '<br><b>Public Calendar:</b> ';
+                        '<a href="webcal://';
+                        useredit.calendar_url | strip_attribute;
+                        '">Subscribe</a>, <a href="http://';
+                        useredit.calendar_url | strip_attribute;
+                        '">Download</a>';
+                END;
+
+                IF useredit.bio;
+                        '<br><hr>';
+                        Slash.parseDomainTags(useredit.bio);
+                END;
+
+                IF user.uid != useredit.uid;
+                        '<br><b><a href="';
+                        gSkin.rootdir;
+                        '/zoo.pl?op=check&uid=';
+                        useredit.uid;
+                        '">Change your relationship with ';
+                        useredit.nickname | strip_literal;
+                        '</a></b>';
+                END;
+        %]        
+        </div>
+</div>
+
+__seclev__
+500
+__version__

Added: slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBoxes;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBoxes;users;default	                        (rev 0)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/u2UserBoxes;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -0,0 +1,121 @@
+__section__
+default
+__description__
+Display user's info
+
+__title__
+
+__page__
+users
+__lang__
+en_US
+__name__
+u2UserBoxes
+__template__
+[% IF latest_comments.size != 0 %]
+<div class="block" id="latest_comments">
+        <div class="title" id="latest_comments_title">
+                <h4>Comments</h4>
+        </div>
+
+        <div class="content" id="latest_comments_content">
+                <ul>
+                [% FOREACH cid = latest_comments.keys.sort %]
+                        <li><a href="[% gSkin.rootdir %]/comments.pl?sid=[% latest_comments.$cid.sid %]&cid=[% cid %]">[% latest_comments.$cid.subject %]</a></li>
+                [% END %]
+                </ul>
+        </div>
+</div>
+[% END %]
+
+[% IF latest_journals.size != 0 %]
+<div class="block" id="latest_journals">
+        <div class="title" id="latest_journals_title">
+                <h4>Journal Entries</h4>
+        </div>
+        <div class="content" id="latest_journals_content">
+                <ul>
+                [% FOREACH jid = latest_journals.keys.sort %]
+                        <li><a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/journal/[% latest_journals.$jid.id %]">[% latest_journals.$jid.description %]</a><br></li>
+                [% END %]
+                </ul>
+        </div>
+</div>
+[% END %]
+
+[% IF latest_submissions.size != 0 %]
+<div class="block" id="latest_submissions">
+        <div class="title" id="latest_submissions_title">
+                <h4>Submissions</h4>
+        </div>
+
+        <div class="content" id="latest_submissions_content">
+                <ul>
+                [% FOREACH sid = latest_submissions.keys.sort %]
+                        <li><a href="[% gSkin.rootdir %]/firehose.pl?op=view&id=[% latest_submissions.$sid.id %]">[% latest_submissions.$sid.title %]</a></li>
+                [% END %]
+                </ul>
+        </div>
+</div>
+[% END %]
+
+[% IF latest_bookmarks.size != 0 %]
+<div class="block" id="latest_bookmarks">
+        <div class="title" id="latest_bookmarks_title">
+                <h4>Bookmarks </h4>
+        </div>
+
+        <div class="content" id="latest_bookmarks_content">
+                <ul>
+                [% bookmarks_counter = 0 %]
+                [% FOREACH bid = latest_bookmarks %]
+                        [% NEXT IF bid.initialtitle == '' %]
+                        [% LAST IF bookmarks_counter == 5 %]
+                        <li><a href="[% bid.url %]">[% bid.initialtitle %]</a></li>
+                        [% bookmarks_counter = bookmarks_counter + 1 %]
+                [% END %]
+                </ul>
+        </div>
+</div>
+[% END %]
+
+[% IF latest_friends.size != 0 %]
+<div class="block" id="latest_friends">
+        <div class="title" id="latest_friends_title">
+                <h4>Friends</h4>
+        </div>
+
+        <div class="content" id="latest_friends_content">
+                <ul>
+                [% FOREACH fid = latest_friends.keys.sort %]
+                        <li><a href="[% gSkin.rootdir %]/~[% latest_friends.$fid.nickname %]">[% latest_friends.$fid.nickname %]</a></li>
+                [% END %]
+                </ul>
+        </div>
+</div>
+[% END %]
+
+[% IF tagshist.size > 2 %]
+<div class="block" id="latest_tags">
+        <div class="title" id="latest_tags_title">
+                <h4>Tags</h4>
+        </div>
+
+        <div class="content" id="latest_tags_content">
+                <ul>
+                [% tags_counter = 0 %]
+                [% FOREACH tag = tagshist.keys %]
+                        [% LAST IF tags_counter == 5 %]
+                        [% NEXT IF !is_admin && tagshist.$tag.0.private == 1 %] 
+                        <li>
+                        <a href="[% gSkin.rootdir %]/~[% useredit.nickname | strip_paramattr %]/tags/[% tagshist.$tag.0.tagname %]">[% tagshist.$tag.0.tagname %]</a>&nbsp;([% tagshist.$tag.0.globj_type %])
+                        </li>
+                        [% tags_counter = tags_counter + 1 %]
+                [% END %]
+                </ul>
+        </div>
+</div>
+[% END %]
+__seclev__
+500
+__version__

Modified: slashjp/branches/upstream/current/themes/slashcode/templates/userInfo2;users;default
===================================================================
--- slashjp/branches/upstream/current/themes/slashcode/templates/userInfo2;users;default	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/themes/slashcode/templates/userInfo2;users;default	2008-11-26 06:51:20 UTC (rev 836)
@@ -23,7 +23,7 @@
 
                                 <div class="content" id="user_bio_content">
                                         [%
-                                '<a href="'; gSkin.rootdir; '/~';
+                                '<a href="'; gSkin.rootdir; '/^';
                                 useredit.nickname | strip_paramattr; '/">';
                                 useredit.nickname | strip_literal; '</a> ';
                                 PROCESS zoo_icons person=useredit.uid implied="";
@@ -251,13 +251,38 @@
 			<div class="yui-u maincol">
                 		[% IF data_pane == '' && user.is_admin %]
 		                        [% admin_block %]
+                                        <p>
+                                        [%
+                                        IF constants.m2;
+                                                m2_listing = form.m2_listing.defined ? form.m2_listing : user.show_m2_listing;
+                                                "<h3>Recent M2s</h3>";
+                                                PROCESS listMetamods
+                                                        m2_listing = m2_listing
+                                                        metamods = metamods
+                                                        the_user = useredit;
+                                        END;
+                                        %]
 
-		                [% ELSIF data_pane == 'journal' %]
+		                [% ELSIF data_pane == 'journal';
+					fh = Slash.getObject("Slash::FireHose");
+					fhbox = fh.listView({ fh_page => 'users.pl', view => 'userjournal', user_view => useredit });
+					fhbox;
 
-		                [% ELSIF data_pane == 'submissions' %]
+		                   ELSIF data_pane == 'journalfriends';
+					fh = Slash.getObject("Slash::FireHose");
+					fhbox = fh.listView({ fh_page => 'users.pl', view => 'userjournalfriends', user_view => useredit });
+					fhbox;
 
-		                [% ELSIF data_pane == 'bookmarks' %]
-	
+		                   ELSIF data_pane == 'submissions';
+					fh = Slash.getObject("Slash::FireHose");
+					fhbox = fh.listView({ fh_page => 'users.pl', view => 'usersubmission', user_view => useredit });
+					fhbox;
+
+		                   ELSIF data_pane == 'bookmarks';
+					fh = Slash.getObject("Slash::FireHose");
+					fhbox = fh.listView({ fh_page => 'users.pl', view => 'userbookmark', user_view => useredit });
+					fhbox;
+				%]	
 		                [% ELSIF data_pane == 'friends' %]
        	                                [% friends_datapane %]
 
@@ -266,7 +291,7 @@
 
 				[% ELSIF data_pane == 'firehose' || (data_pane == '' && !user.is_admin);
 					fh = Slash.getObject("Slash::FireHose");
-					fhbox = fh.listView({ fh_page => 'users.pl'});
+					fhbox = fh.listView({ fh_page => 'users.pl', view => 'userfirehose', user_view => useredit });
 					fhbox;
 		
 		                 ELSE %]

Modified: slashjp/branches/upstream/current/utils/import_journals_firehose
===================================================================
--- slashjp/branches/upstream/current/utils/import_journals_firehose	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/utils/import_journals_firehose	2008-11-26 06:51:20 UTC (rev 836)
@@ -4,6 +4,7 @@
 
 use Slash::Test shift || 'slash';
 my $limit = shift;
+my $offset = shift;
 local $| = 1;
 
 my $firehose = getObject("Slash::FireHose");
@@ -11,7 +12,14 @@
 printf STDERR "Fetching IDs ...\n";
 
 my $slashdb = getCurrentDB();
-my $ids = $slashdb->sqlSelectColArrayref('id', 'journals', '', ($limit ? "LIMIT $limit" : ()));
+my $limitstr;
+if ($limit && $offset) {
+	$limitstr = "LIMIT $offset,$limit";
+} elsif ($limit) {
+	$limitstr = "LIMIT $limit";
+}
+
+my $ids = $slashdb->sqlSelectColArrayref('id', 'journals', '', ($limitstr || ()));
 my $i = 0;
 my %ids;
 
@@ -27,5 +35,5 @@
 }
 printf STDERR "\nImported %d journals\n", scalar(keys %ids);
 
-my $string = join '; ', map { "$_:$ids{$_}" } @$ids;
+my $string = join '; ', map { "$_:$ids{$_}" } sort { $a <=> $b } keys %ids;
 print "\n$string\nDone\n";

Modified: slashjp/branches/upstream/current/utils/import_stories_firehose
===================================================================
--- slashjp/branches/upstream/current/utils/import_stories_firehose	2008-11-21 09:07:54 UTC (rev 835)
+++ slashjp/branches/upstream/current/utils/import_stories_firehose	2008-11-26 06:51:20 UTC (rev 836)
@@ -4,13 +4,21 @@
 
 use Slash::Test shift || 'slash';
 my $limit = shift;
+my $offset = shift;
 local $| = 1;
 
 my $firehose = getObject("Slash::FireHose");
 printf STDERR "Fetching IDs ...\n";
 
 my $slashdb = getCurrentDB();
-my $ids = $slashdb->sqlSelectColArrayref('stoid', 'stories', '', ($limit ? "LIMIT $limit" : ()));
+my $limitstr;
+if ($limit && $offset) {
+	$limitstr = "LIMIT $offset,$limit";
+} elsif ($limit) {
+	$limitstr = "LIMIT $limit";
+}
+
+my $ids = $slashdb->sqlSelectColArrayref('stoid', 'stories', '', ($limitstr || ()));
 my $i = 0;
 my %ids;
 
@@ -20,6 +28,7 @@
 	my $globjid = $slashdb->getGlobjidCreate("stories", $id);
 	my $fhid;
 	$fhid = $firehose->getFireHoseIdFromGlobjid($globjid) if $globjid;
+#	$ids{$id} = $fhid;
 
 	$ids{$id} = $firehose->createItemFromStory($id) unless $fhid;
 }


Slashdotjp-dev メーリングリストの案内
Back to archive index