User not logged in - login - register
Home Calendar Books School Tool Photo Gallery Message Boards Users Statistics Advertise Site Info
go to bottom | |
 Message Boards » » Behind the scenes of Better Wolf Web Page [1]  
FroshKiller
All American
51911 Posts
user info
edit post

Back in 2009, I started working on a Greasemonkey script for the Wolf Web. A year later, I made a for-real release, worked on it for a few more months, and wound up not spending much time on the Wolf Web.

I've picked the project back up and have basically started a total rewrite. It occurred to me that there were probably people in Tech Talk who might be interested in the process: making decisions about what features to implement and how to implement them, tuning slower functions, etc.

First, let me tell you about my original idea.

The Scaffold
The Wolf Web's HTML has more or less always been a mess from a semantic standpoint. Every single page is a collection of nested tables populated by anonymous elements.

I could see that on any given page, there was a lot of useful information about the content. The problem was that it was difficult to get at any of it. If I was going to add any new features at all, I'd have to tame that jungle.

What I had to do first was set a bunch of IDs and classes on the elements I was interested in using. This would make it much easier to traverse the DOM and get what I wanted. I call this skeleton the scaffold. By adding a little markup to certain pages, I made it much easier to work on new features.

My goal for the scaffold is to make this process fast and invisible to the end user. If a power user decides he wants to add his own feature to the script, he'll be able to use the scaffold. This means I'm going to have to rewrite the script to put all the scaffolding in one module, and I'll probably need to document it on an external site.

jQuery
The very first thing I wrote for the script was an XPath query to see whether the user was logged in and to capture the username. XPath is a goddamn nightmare for Web pages, though.

I decided to use jQuery for DOM traversal and manipulation instead. Greasemonkey allows you to require external resources, so I just plugged that in. I hadn't worked with jQuery much prior to that—I was more of a Prototype guy—but I figured I might as well learn something new while I was learning something else new.

That was a slam dunk. Prototype is nice, but jQuery is much better suited to extending other people's work in my opinion and seems to be more actively supported.

Initial Feature Set
No one cares about the scaffold thing. They only care about what can be done with it.

The most requested feature, like, ever is user blocking. I don't like it, but I decided right away to include it as a powerful example of what was possible. A good example like that was important to me because I wanted to convey that the script itself was a base the end user could build on. That hasn't really happened, but I'll talk about that later.

The rest of the stuff was just good housekeeping: converting IFRAMEs to links, changing YouTube links to embedded videos, adding photo gallery links beneath posters' info, etc. These were just easy things to develop that provided an immediate benefit.

External Services
Greasemonkey scripts can make cross-site requests, which meant I could use jQuery's AJAX functions with external services. Initially, I just had the script hit a PHP script on some Web space of mine to send me an e-mail whenever one user blocked another.

Then, I got the idea to allow users to flag NSFW threads. I created two simple scripts (one to vote, one to check thread statuses) and a simple database back end that the Greasemonkey script could take advantage of.

That's been far and away the most fun and (in my opinion) useful aspect of the script. After I picked it back up, I decided that I would extend this feature even further to implement some community policing and content rating stuff I had proposed as new features for the Wolf Web itself.

The Rewrite
Without getting into fine details in this first post, I'm really overhauling the script. Below are my goals. I'll be documenting my progress in this thread.


  • User preferences - Greasemonkey lets you store some individual settings per userscript, but it doesn't have any sort of front-end method to change settings. I'll create a preferences page that can be called up from the script menu or keyboard shortcut so users can more easily change their options.

  • Voting and karma - I have a database. Might as well use it. I want to keep track of users' opinions of each other.

  • Classifieds - I don't really care for Classifieds as a message board. I'd rather be able to group threads (FS/WTB/etc.) and maybe flag taken items as sold so I don't have to click.

  • Drafts - I had to save the draft for this post in my Drafts folder in Gmail. Wouldn't it be nice if I could just file away drafts when posting a topic or reply and call them up later?

  • Custom highlight styles - I like NSFW threads with a red background, and I like seeing my own threads with a tooltip yellow background. But not everyone shares my preferences. Why not let people define their own colors and words to watch for?



Anyway, I'll be posting about implementing this stuff and soliciting feedback. Once I've got the new scaffolding done, I'll set up a "dev channel" sort of link so anyone who's interested can install what I'm actually working on and see how it's going.

1/25/2012 6:23:41 PM

Prospero
All American
11662 Posts
user info
edit post

Whatever happened to Site3 and will this script be enabled for it?

<-no premie

1/25/2012 6:37:41 PM

FroshKiller
All American
51911 Posts
user info
edit post

Good question. I'd asked qntmfred whether I should hold off on working on the script for Site 3. I don't think we're likely to see it soon, so I'm pretending it doesn't exist.

In theory, it'd be relatively easy to convert the script if that layout ever goes live.

1/25/2012 6:41:07 PM

dave421
All American
1391 Posts
user info
edit post

^think he said open beta for site 3 was going to be sometime this month so you should have plenty time to test & get feedback on both before it goes fully live. Thanks for the reminder too. I forgot to install it on this computer.

1/25/2012 11:43:30 PM

Noen
All American
31346 Posts
user info
edit post

The really cool thing about you using jQuery is that it's at least possible to integrate your scripts into core functionality of Tdub over time.

Keep it up man!

1/26/2012 1:25:36 AM

FroshKiller
All American
51911 Posts
user info
edit post

dave421 said:
Quote :
"^think he said open beta for site 3 was going to be sometime this month so you should have plenty time to test & get feedback on both before it goes fully live."


You got a link to where he said that? I've been holding off on any Site 3 stuff since August of 2010.

Noen said:
Quote :
"The really cool thing about you using jQuery is that it's at least possible to integrate your scripts into core functionality of Tdub over time.

Keep it up man!"


Yeah, I noticed T-Dub is using jQuery now. Most of the kind of stuff I'm doing should probably take place server-side. Unfortunately, I don't have that kind of freedom.

Thanks for the encouragement!

Posting a reply reminds me that I wanted to add a quoted reply feature.

1/26/2012 8:25:24 AM

FenderFreek
All American
2805 Posts
user info
edit post

This + original format >>>> Site 3. I've yet to be impressed by anything about it, but this sounds cool as hell.

1/26/2012 8:45:04 AM

BIGcementpon
Status Name
11318 Posts
user info
edit post

^^In PP, 4th post down from the top.
message_topic.aspx?topic=604823&page=6

1/26/2012 10:43:57 AM

catalyst
All American
8704 Posts
user info
edit post

what will be the lower bound on negative karma

i would like to achieve that value

1/26/2012 10:51:07 AM

dakota_man
All American
26584 Posts
user info
edit post

1/26/2012 11:55:43 AM

FroshKiller
All American
51911 Posts
user info
edit post

Good question about karma. I want to get good ideas out of this thread. Here are some ideas I posted back in August of 2010:

Quote :
"Users should be able to vote on posts—not other users, not threads, just posts. The "vote" for a user will be the votes for his posts, after all, and the same applies to threads.

You use the votes to determine karma totals for users, threads, message boards, whatever can "own" a post.

If you want to vote just up or down, the karma rating is just a single number, higher is better. If you want other dimensions for voting (e.g. this isn't just bad, it's [old]), karma gets more complex. But let's run with the simple example.

Current flood control applies to users at an even 0 karma. There are simple tiers you fall into depending on how good or bad your karma is relative to the baseline. I wouldn't have more than two in either direction to keep it simple. So you have the best level, a good level, baseline, a bad level, and a really bad level.

Every time you post, it's an opportunity for the community to influence your karma. When you post a thread, every user's vote should carry a little more weight.

Every vote you make carries weight based on your karma. A bad user's vote doesn't count as much as a good user's vote. Sorry, but that's the way it is.

Karma degrades over time, maybe monthly. You have to contribute if you want to keep a good level. I want this to keep motherfuckers from resting on their laurels. Yeah, you might have been the man in 2004, but you don't post like you ought to, you don't vote like you ought to, nobody votes for your ass, so get to steppin'.

In the simple system, karma is a small, whole number. Level -1, 0, 1, etc. Doesn't go higher than 4 or 5 or something. Votes typically aren't whole numbers themselves. That weight your vote carries based on your karma? We might be talking about 0.01 or something.

Maybe have separate scores in each message board. Just 'cause I'm the shit in Entertainment doesn't mean I get to post a thread every 15 minutes in Tech Talk."

1/26/2012 3:14:24 PM

dakota_man
All American
26584 Posts
user info
edit post

Why don't you just go start /r/thewolfweb and get to work on a red and white stylesheet?

1/26/2012 3:15:47 PM

FroshKiller
All American
51911 Posts
user info
edit post

I don't do the Reddit thing.

1/26/2012 3:33:27 PM

afripino
All American
11425 Posts
user info
edit post

I think the first step should be to purchase tww.com

1/27/2012 3:24:05 AM

FroshKiller
All American
51911 Posts
user info
edit post

I've just copied the script to a different host. Time to really start. What do we got on the spacecraft that's good? Let's start with the Greasemonkey metadata:

// ==UserScript==
// @name Better Wolf Web
// @author Jonathan Hamilton
// @namespace http://jlhamilt.freeshell.org/
// @version 1.0
// @description Extensions for the Wolf Web
// @include http://*thewolfweb.com/*
// @include http://*brentroad.com/*
// @require http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js
// @require http://lolibrary.org/bww/scaffold.js
// @require http://lolibrary.org/bww/gm_jq_xhr.js
// ==/UserScript==


All right, familiar name and namespace. Probably need to update that version number. It runs on thewolfweb.com and brentroad.com, but I think I want to exclude Site 3 for now since the layout will be incompatible with the current scaffolding.

What external resources am I using? An old version of jQuery, my scaffold library, and a library that wraps overrides jQuery's AJAX requests to force them to use Greasemonkey's GM_xmlhttpRequest method.

I'm not a fan of change for the sake of change, so I'm going to stick with that version of jQuery for now unless it turns out there's a bug or vital new feature I need. I will move the external resources on the old host to this other one, though, and update the version number and shit:

// ==UserScript==
// @name Better Wolf Dev
// @author Jonathan Hamilton
// @namespace http://jlhamilt.freeshell.org/
// @version 1.0
// @description Extensions for the Wolf Web
// @include http://*thewolfweb.com/*
// @include http://*brentroad.com/*
// @exclude http://site3.thewolfweb.com/*
// @require http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js
// @require http://jlhamilt.freeshell.org/bwd/scaffold.js
// @require http://jlhamilt.freeshell.org/bwd/gm_jq_xhr.js
// ==/UserScript==


Boom! Welcome to Better Wolf Dev. Feel free to download it if you want to follow along with development, but be advised that it's probably going to be broken 9 times out of 10.

1/27/2012 9:13:01 AM

FroshKiller
All American
51911 Posts
user info
edit post

When I look at this script, I see some things I don't like. I've got some function declarations in here which should probably be hidden away, a bunch of user blocking stuff, and a sorry excuse for control flow when it comes time to decide which functions to run based on which kind of page we're viewing.

I want to change this up. My goal for this part of the script is to have some clean control flow and a separate library for the blocking function.

I figure I'll probably want to put each feature in its own module where possible, so I might as well establish a naming convention. I'll start with bww.blocking.js. I create the new file, move the function declarations for the blocking stuff into it, and add the file as a new external resource in my metadata.

I don't bother to comment or even alphabetize the blocking stuff. This is just a quick and dirty test. Reinstalling and blocking Golovko confirms that we're still in business. Cool.

Already, the main body of the script is much more readable. I'll go ahead and comment the blocking functions now that they're mostly in one place. After I'm done with that, I should consider addressing that control flow.

1/27/2012 9:27:46 AM

qntmfred
retired
40723 Posts
user info
edit post

why not host it on github? that way you'll get version control, issue tracking and even wiki for documentation

1/27/2012 9:56:54 AM

FroshKiller
All American
51911 Posts
user info
edit post

Seems like overkill to me. I didn't think I really needed source control for a tiny project like this.

What say you, Tech Talk? Would you like this bird moved to GitHub?

1/27/2012 10:05:00 AM

gs7
All American
2354 Posts
user info
edit post

Github keeps you from having to worry about host issues ... and it's actually real easy to use.

1/27/2012 10:33:32 AM

Prospero
All American
11662 Posts
user info
edit post

GitHubit

1/27/2012 10:44:18 AM

EuroTitToss
All American
4790 Posts
user info
edit post

SOCIAL CODING, B

1/27/2012 10:58:01 AM

kiljadn
All American
44690 Posts
user info
edit post

github that shit, son

1/27/2012 6:32:38 PM

dakota_man
All American
26584 Posts
user info
edit post

++github

1/27/2012 7:10:45 PM

Noen
All American
31346 Posts
user info
edit post

to me, github is a great place to put it, to me.

or codeplex

1/27/2012 9:52:37 PM

FenderFreek
All American
2805 Posts
user info
edit post

++

1/28/2012 9:36:02 AM

spöokyjon

18617 Posts
user info
edit post

If anybody's looking for a simpler solution to fixing TWW, I just whipped something up myself: BOOM.

1/28/2012 9:56:23 AM

kiljadn
All American
44690 Posts
user info
edit post

hahahaha

1/28/2012 12:44:05 PM

Grandmaster
All American
10829 Posts
user info
edit post

doesn't work with tampermonkey

1/28/2012 6:15:49 PM

spöokyjon

18617 Posts
user info
edit post

That's crazy b/c I did super expansive testing.

1/28/2012 9:10:41 PM

FroshKiller
All American
51911 Posts
user info
edit post

I made a GitHub repository, but I still think it's overkill. Slowed me down like whoa and killed my impulse to update this thread.

https://github.com/FroshKiller/Better-Wolf-Web

I'll stick with it due to popular demand, but I don't understand why anyone would want or need a git repo for, like, four fucking text files.

1/29/2012 6:14:09 PM

lewisje
All American
9196 Posts
user info
edit post

I personally have an SVN repo for a huge number of text files: https://code.google.com/p/jansal/wiki/PassiveSecurity

1/29/2012 7:30:27 PM

FenderFreek
All American
2805 Posts
user info
edit post

^^ It's just to keep it in one place and to be sure that you're always grabbing the latest version. I find it very convenient for hosting any shared code, no matter how small. I would still rely on this thread for discussion, but but using a repo makes viewing and retrieving the source much simpler.

1/30/2012 1:10:44 PM

FroshKiller
All American
51911 Posts
user info
edit post

Yeah, how is that any different than me keeping the latest version in one folder on my host like I was originally doing?

1/30/2012 1:28:36 PM

dakota_man
All American
26584 Posts
user info
edit post

Keeping it in a folder won't earn you scene points in the blogosphere. On rails.

1/30/2012 1:59:42 PM

CaelNCSU
All American
7080 Posts
user info
edit post

^^

You can see the diff across multiple changes (including local), branch it, and approve changes that others make more effectively...

SVN is like going back to vacuum tubes.

^ Rails is so 2008, all the cool kids are using Node



[Edited on January 30, 2012 at 2:06 PM. Reason : a]

[Edited on January 30, 2012 at 2:07 PM. Reason : a]

1/30/2012 2:03:28 PM

FroshKiller
All American
51911 Posts
user info
edit post

But I'm not interested in changes others make. I encourage people to customize their installations, sure, but I ain't trying to incorporate anyone else's work into this. And all that other shit I can do with local source control. I think Dakota's right. :/

1/30/2012 2:25:01 PM

gs7
All American
2354 Posts
user info
edit post

FroshKiller, for your hard work, you get:





[Edited on January 30, 2012 at 3:08 PM. Reason : .]

1/30/2012 3:04:04 PM

FroshKiller
All American
51911 Posts
user info
edit post

Let's talk about how votes work and how I want to make 'em better.

Basically, I have a big stupid table with a record for every thread that someone has reported as NSFW. It's not really that simple, but you get the idea.

In the original script, whenever you visited a page that had a list of threads (e.g. message_section.aspx), the script posted a request to a script on a remote server. This request sent a list of all the thread IDs on the page, and the script returned an array of which threads (if any) had been flagged.

One of my goals for the new version is to support other types of voting. I have a real nice framework for recording arbitrary votes that reflect a thread's content...but how do I determine which type of vote should be reported to the user? Fifty people click [old], twenty click [lol]. Which is it going to be?

Every user gets one vote per post. I already had that control in place. For the time being, I've decided to create a view on the database for the highest vote count for each thread. The script now returns the most popular vote per thread.

2/7/2012 9:50:52 PM

jackleg
All American
170957 Posts
user info
edit post

IS THIS A MELWARE

2/7/2012 9:58:26 PM

FroshKiller
All American
51911 Posts
user info
edit post

I could capture your Wolf Web password! I could also distribute your Wolf Web password to other clients, intercept all login attempts by script users, and sign them in as a different user randomly.

2/7/2012 10:00:47 PM

dakota_man
All American
26584 Posts
user info
edit post

Quote :
"One of my goals for the new version is to support other types of voting."


This sounds like a mistake. Just have an up/down voting system and a tagging system. If you did it arbitrarily enough people could vote on tags that already existed (or adding a duplicate tag uses the voting system to track the prevalence of that tag.)

This way, you could add one of those shitty word clouds to everything!

Maybe I'm just too used to the way reddit works (which I like,) so if I were going to offer a novel suggestion it would be the following: Implement something like a daily allowance of "extra" votes. If, for example, each user gets 2 of these per day then each day they could vote something they really like up by 3, or vote something they really hate down by 3.

2/8/2012 12:04:42 PM

FroshKiller
All American
51911 Posts
user info
edit post

Well, don't say it sounds like a mistake when I haven't even given more detail than just "other types of voting"!

In the original script, you could report a post as NSFW, like I said. The script would highlight NSFW posts in red so you knew which ones to avoid.

I'm talking about letting the script handle other types of content classification like that via voting, not some popularity contest shit. Like I mentioned in my first post, Classifieds is kind of dumb as a message board. I can parse FS/WTB threads into separate sections, but not everyone uses that shorthand. If users (trusted users, maybe) could flag threads in Classifieds as FS or WTB, the script could more reliably group the threads correctly.

2/8/2012 12:31:35 PM

dakota_man
All American
26584 Posts
user info
edit post

You're right. I should have said that based on your description I imagine a cluttered and confusing barrage of different voting icons on everything. I still think a separate tagging system paired with an arbitrary up/down voting system would suffice -- that way you wouldn't have to rely on trust for flagging (tagging) classified threads, you could just assume that the most popular tag on a FS post will be "FS."

2/8/2012 7:26:25 PM

FroshKiller
All American
51911 Posts
user info
edit post

GitHub killed my enthusiasm for rewriting Better Wolf Web, so I said fuck all that bullshit and have started from scratch again. Now, I have new goals.

Minimize Side Effects

Some of my original functions do more than one thing, and it's not clear that they do more than one thing. For example, checkLogin sets a Greasemonkey script value to the currently logged-in username and also returns that username. In the interest of simplifying the script, I'm going to change that. Instead, checkLogin will return the username, and I'll set the script value by calling the function. It's not a big type of change, but it's a disciplined one that will help me keep things straight in the long run.

Add Custom Events

It will be easier for users to customize the script if it fires custom events that users' modifications can respond to. For instance, all scaffolding functions should trigger a "scaffolding finished" sort of trigger. I can bind all additional functionality in Better Wolf Web itself to respond to that as an example of how to extend it.

I may not waste much time on this. It boils down to whether an event fired by one Greasemonkey script can be responded to by another. If that's the case, people could create and publish their own extensions with Better Wolf Web as a dependency.

Undo Premature Optimizations

For some dumb reason, I thought I should filter the users in a thread down to only the unique users. Why? You have any idea how many posts are on a given page of a thread in the worst case? Hint: It's 50. Who the hell cares if you iterate over the same user 50 times?

I also did a lot of post processing (processing of posts) inline during scaffolding. Holy hell, it'd be easier and clearer to select a group of scaffolded elements afterwards and just do the work on them directly. Who cares if it takes another 50 ms?

4/22/2013 10:09:18 PM

FroshKiller
All American
51911 Posts
user info
edit post

Just had a fun hour of troubleshooting.

When I first released BWW, jQuery 1.3.2 was the current stable release, so I implemented it. Since I'm rewriting it now, I figured I should upgrade to something newer, namely 1.9.1.

Lo and behold, my cross-site Ajax requests stopped working, which meant the NSFW warning and flagging features stopped working.

As you might know, using jQuery for Ajax in a Greasemonkey script requires a bridge between the Greasemonkey's XmlHttpRequest handler and jQuery in order to make cross-site requests. I suspected there might be an incompatibility between the bridge and the newer jQuery library, but because of the way Greasemonkey is sandboxed, I wasn't seeing any errors or warnings pop up on my error console.

I finally debugged the son of a bitch and found that jQuery expects the XmlHttpRequest handler to implement a function called getAllResponseHeaders. JavaScript doesn't really have any means of declaring class interfaces, and my bridge didn't implement a function with that name, so I had no idea until I debugged. Once I defined that function, hey presto, the feature started working again.

4/23/2013 11:31:24 AM

 Message Boards » Tech Talk » Behind the scenes of Better Wolf Web Page [1]  
go to top | |
Admin Options : move topic | lock topic

© 2024 by The Wolf Web - All Rights Reserved.
The material located at this site is not endorsed, sponsored or provided by or on behalf of North Carolina State University.
Powered by CrazyWeb v2.39 - our disclaimer.