Saturday Night Experiment

Time: ~7:33pm
Yes, life ain’t the party it used to be. Gone are the late nights of clubbing and replaced are the quiet country nights of sitting at home and… and… well… trying to find anything to do.

Since the wife is in graduate school and spends every free hour studying (read: this means she has little to no “free” hours), I decided, about five minutes ago, that this Saturday night would be different. It is 7:35 PM. (I guess I decided at 7:30PM) She said she would have to study until midnight. I have decided to conduct a little experiement of my own. I have 4.5 hours to design a web application, implement it, and document both the application at the process. What you are reading is the documentation of the process.

I recently took the Ruby on Rails Todo List tutorial. Ruby on Rails is definitely an awesome web application framework (I hate these buzzwords and titles too, but to steal from MTV, I’d call the name “buzz worthy”). Rails will be my tool of choice for my mission. The mission: Write a web application book reader for reading titles from Project Gutenberg.

I’m off to write the specs.
Time: 7:40pm

Time: 7:50 pm
Specs written:

Book Reader specification

OVERVIEW

Installation – not sure, because not sure what ruby on rails is capable of, handle this at another time.

Use –
The main page should give a menu allowing selection of a reading list, current reading, and past reading.
The reading list is a list of books to be read. A browse system for finding books in Gutenberg library should allow books to be added to the reading list.

Books being read and past reading should have multiple bookmarks. There can be 3 types of bookmarks. First is the primary bookmark, this is where teh user left off reading. Second is dogears, this is for points in teh book that are intersting that the user may wish to return to. Third is highlight, these are really just like dog ears, but different types of users may work, think, and feel differently about their books. Highlighs highlight text for easy finding later.

stage 2:
The next set of features probably won’t get implemented immediately, they are teh stage 2 features: Allow preferences for reading books by paragraphs per page (to speed load times), chapter views, and an RSS view. The RSS view oculd be a chapter or number of paragraphs every N days and RSS would be generated for that number of paragraphs or chapters in such increments. Reading the book now becomes as simple as subscribing to the RSS feed.

Stage 2 backend:
Try various gutenberg mirrors in parallel, allow selecting a prefered mirror. Specify a limited local book cache size.

DETAIL

Rails is an MVC, so expanding the above gives natural models for ReadingList, Library, Reading, and Books. Past and Current Reading are really just cases of Reading with a simple boolean switch indicating that the user is done with this Bok.

Properties of Books should come from Gutenberg, so use natural properties for thier publication.

Time to fill up the coffee cup, and check the bread (I’m baking bread while I do this too).

Time: 8:15pm
Coffee cold already. I’ve laid out some tables. I’ll need to parse GUTINDEX.ALL and populate the database with its results. I can do this outside the web application.

I’m getting distracted a bit right now. The first loaf of bread goes into the oven in about 15 minutes. The second loaf about 30 minutes after that. I probably shouldn’t be multi tasking while trying to program. Oh Well, at some point I’m going to clean the tub and take a shower too. I’m aiming for that to be my 10pm 1/2 time break.

The tables are going to look like this: (in psuedo schema)
GUTINDEX:
GUTINDEX_id series/autonum
releasedate,
name varchar(100),
author varchar(100),
SeriesNumber int,
basefilename varchar(30),
booknumber int
GUTINDEXProperties: –e.g. (full)Title, Subtitle, Editor, Language, Illustrator
GUTINDEXProperies_id series/autonum,
GUTINDEX_id int, –fk
Property varchar(20),
Value varchar(100)

# parse GUTINDEX.ALL to populate these tables.
User
User_id seq/auto,
UserName varchar(50),
UserEmail varchar(50),
–whateverelse
BookStatus
BookStatus_id seq/auto,
BookStatus varchar(100), — in ReadingList, CurrentReading, Past Read
User_Books
User_Book_id seq/auto,
User_id int, –pk
PrimaryBookmark int, –an offset?
BookMarkTypes
BookMarkType_id seq/auto,
BookMarkTypeName varchar(100), — in Primary, DogEar, Highlight
BookMarks
BookMark_id seq/auto,
BookMarkType, –pk
BookMark int –an offset?
BookMarkColor

Off to put that into real PostgreSQL DDL.

Time: 8:20pm

Time: 8:25pm
On second thought I should normalize Authors out of GutIndex. Author is now a foreign key to an Authors table. Now if we want to keep details about Authors, that is a little easier. I will not handle the case of books having multiple authors at this time. For now, Authors will be listed in the Authors table again if they published a book with another author. e.g.:
Joe Blow – The Hard Knock Life
Joe Blow and Terry Harry Berry – The Knock ‘Em Hard Guys.

It would be nice to have an N-to-N relationship between books and authors, but for right now, I will only have a N-1 relationship, so Joe Blow and Terry Harry Berry will be an entry in the Authors table separate from Joe Blow. This will make parsing GUTINDEX.ALL easier for now.

Time: 8:29pm

Time: 8:47pm
I’m alsmost done with the DDL. I’m just looking up how to switch users and databases in PostgreSQL. The first loaf of bread went into the oven. I forgot to preheat, that is why it is going in so late. Next loaf goes in at 9pm.

Time: 9:35pm
First loaf is out, and I’m stuck with not being a DBA. I’m dealing with some PostgreSQL permissions because I want to do things right with a DB Owner user for the DB piece. I’m also dealing a bit with case issues in rails. Apparently if you generate a model or controller with uppercase letters, rails changes them to lower case, but separates them with an underscore, so BookStatus became book_status. Whatever OR mapping Rails does then proceeded to look for a table called book_status, but my table is called bookstatus. PostgreSQL table names are not case sensitive, so even though in my pretty looking definition I call it BookStatus, a listing of database objects reveals all lowercase names. Same is true for PostgreSQL users, databases, and probably all objects, so configurating password auth took more time than it should have. I’m not sure why PostgreSQL doesn’t just lower() everything. Ignoring my lines in pg_hba.conf because of upper case characters was a bummer. Not being able to login with an username containing upper case characters was also a bummer. I should mention I’m using PostgreSQL 7.4 because it is what I happen to have on my Ubuntu Breezy (pre-release) system.

Back to hammering out the PostgreSQL permission issues. Seems like I go through this every time.
Time: 9:41pm

Time: 10:10pm
Ugh, I just found Really Getting Started In Rails where it mentions specific rules for naming things. All Primary Key columns in my tables should be named “id”, and foreign key columns should be named tablename_id. That is fine, its just not what I prefer. I’ll go change my column names.

I’m still not quiet sure how to model the concept of Users with ruby. I’m leaning toward having a Users controller which assumes a Default User and using that user until a visitor logs in by accessing a Users/login target. Hopefully I can find a good example.

Time to cut the bread. It smells delicious and Janice (my wife) keeps asking if it is ready.

Time: 10:14pm

Time: 10:50pm
I did some database redesign after reading more rails docs. ClassMethods for Associations is important stuff.

I’m getting tired I can tell I’m not as focused as I would be in the morning. The bread is delicious. It is some of the best bread I’ve made yet. It is about time to cut the second loaf.

With a little more than an hour to go, it doesn’t seem like I’ll be getting very far in my little experiement, but I’ve learned a lot about Rails. That was kind of the point.

Time: 11:12pm
I found Rails Cookbook with exactly the kind of authentication required example for which I am looking. I’ll have to review it to see what kinds of implications it has for my current design.

The second loaf of bread is delicious. I was going for honey wheat, but it didn’t come out that sweet. It is some damn good bread though. I’ve had two pieces of each kind. That is a lot of bread.

Time: 12:00pm

No, I didn’t have a time set, I just found LoginGenerator and figured I could blog on that and call it a night. The time just happened to be midnight when I checked it.

4.5 hours later, I don’t have anything near an application. All I have are a bunch of screwed up Model and Controller files, and a whole lot more Rails knowledge. The Login Generator definitely looks cool. I’ll definitely be trying that out soon.

The Authors login example from the Rails cookbook works, but has an annoying bug that if you login incorrectly, it redirects indefinitely. I’m not sure why the authenticate action is being called on redirect_to action=>”index”, but it is. Hopefully this Login Generator will help.

Time: 12:13pm
Major Bummer. It seems Login_Generator is an optional addon to rails to be installed via Gem. Ubuntu doesn’t package gem nor Login_Generator. So my options are to build ruby from source, or figure a way to package it. I’m leaning toward the later for the benefit of all ubuntu folk, but it won’t be tonight.

installing lxr and configuring for gnome lxr using Ubuntu breezy

the lxr package uses glimpse for search. glimpse is not free, so we use the lxr-cvs package. This uses swish-e and a PG/MySql/Oracle/AnythingDBI backend.

install the lxr and the swish-e packages – I’m not sure why the lxr-cvs package is there, or why it exists. Looks like it is moving to a database backend which may be faster?

checkout the source cvs you want to use. I grabbed gnome in an evil way like this

for module in `cvs -z5 co -s | cut -d ' ' -f 1 ` ; do cvs -z5 co $module ; done

configure lxr.conf with proper directories and versions and stuff. The version part is stupid because it assumes you have a dir with subdirs of versions. If you just want to index 1 dir, use its parent as sourceroot and the dirname as version.

  • create postgresql db and user
  • configure the database for password auth
  • initialize the database for use with


createdb lxr ; createuser -A -D -P lxr # then type the password when prompted
echo local lxr all md5 >> /etc/postgresql/7.4/pg_hba.conf
invoke-rc.d postgresql-7.4 restart
psql -U lxr -f /var/lib/lxr-cvs/initdb-postgres lxr

then run lxrgen

cd /var/lib/lxr-cvs ; ./genxref --url=http://localhost/lxr

working around a “secure” build of windows

At work they have these stupid windows images to install from, rather than default installs. One of the side effects is that I cannot drag and drop in Windows Explorer.

Here is my fix and undo of “security” to enable drag and drop in windows.

This is just a copy and paste of information I found in a forum somewhere. It seems the change must be made and you must logoff/logon (or maybe just restart explorer.exe).

Good, then we can try two other remedies. I am assuming by the way that you are not receiving any error messages during your attempts to drag and drop.

1. Check your settings in DCOMCNFG.

This is based on MS KB Q274696: http://support.microsoft.com/default.aspx?scid=kb;en-us…

For XP the modified solution is to open dcomcnfg, go to the properties page for Component Services | Computers | My Computer, go to the Default COM Security page, under “Access Permissions” click “Edit Default” and make sure that the local SYSTEM and INTERACTIVE users have “Access Permission” with the “Allow” checkbox checked.

2. Re-register some DLLs.

Start, Run, and either type CMD and paste the below as a box into the CMD session, or enter each line one-by-one:

regsvr32 urlmon.dll
regsvr32 Shdocvw.dll
regsvr32 Msjava.dll
regsvr32 Actxprxy.dll
regsvr32 Oleaut32.dll
regsvr32 Mshtml.dll
regsvr32 Browseui.dll
regsvr32 Shell32.dll
regsvr32 riched20.dll

TekTippy4U (TechnicalUser)
7 Aug 04 3:46
hi folks;
couple of quick points;
[…as the long tooth becomes a fang ]
I’m not up on current MSOffice DLL versions, and associated apps, nor with all XP DLLs per se — so some DLLs below may be older – feel free to update with the correct file name.
[1] I’m inclined to think it’s related to an unregistered DLL ( improperly registered or overwritten/replaced, and even perhaps an OCX that needs re-registering – thinking an Explorer issue more-so than an IE one).
along these lines – I’d like to add a few to the list (that bcastner already posted);
regsvr32 Comctl32.dll
regsvr32 Shlwapi.dll
regsvr32 User32.dll
regsvr32 User.dll
regsvr32 Olepro32.dll
regsvr32 Ole2.dll
regsvr32 Ole2conv.dll
regsvr32 Ole2disp.dll
regsvr32 Ole2nls.dll
regsvr32 Ole32.dll
regsvr32 Olecli32.dll
regsvr32 Olecnv32.dll
regsvr32 Olesvr.dll
regsvr32 Olesvr32.dll
regsvr32 Olethk32.dll
regsvr32 Oleacc.dll
regsvr32 Setupwbv.dll
regsvr32 Softpub.dll
regsvr32 Wininet.dll
regsvr32 Wintrust.dll
(sorry bout the long list, but might as well try em all – and depending on which version of IE you’re running these files will vary, and you’ll definitely get some errors when trying to register them all).

The other quirky thing about this, is that you’d think that an SFC /Scannow would restore the Original DLLs – if some are wrong versions or have been maliciously replaced by malware (as certain usual Windows files can and are – such as rundll32.exe and regedit.exe and notepad.exe to name a few).

[2] Someone will have to follow up on the OCX theory, kinda like the way exoticspice’s faq lists entries to the Interface Key – perhaps it’s a TypeLib prob. I think the OCX files may need the full path listed in the command?

[3] I’ve heard of anomalies with drag-n-drop and cut and paste from having more than 1 Keyboard Language set in the Keyboard Properties > Language tab of Control Panel.

[4] Finally….anyone think this is an Accessibilty Setting option gone awry?

……oh well – a shot in the dark anyway.

TT4U

Notification:
These are just my thoughts….and should be carefully measured against other opinions.
Backup All Important Data/Docs

follow up to gnome-session complaints

http://little.xmtp.net/blog/2005/08/28/stupid-code-aka-gnome-session-phantoms/

I posted some crap about issues I have been having with gnome-session. Well, the stupid error message is still there. The solution to my problem was as easy as using a Mac.

System->Preferences->Sessions. Delete the default session. Logout. Login. A new default session will be created. There will be no stupid long delay.

Sadly I went through the exercise of checking out gnome-session, diving into source, and enabling GSM_VERBOSE_DEBUG=true to read more output in .xsession_errors. One of the errors finally gave me this idea.

Anyway, thinks are better now. I am a happy Ubuntu Gnome user.

RE: Spot the Bug – August 14, 2005

I created this bug a couple of weeks ago for a conference I spoke at to illustrate how so few lines of code could be so buggy. Where’s the bug here?

char dest[50], src[100];
int x, y;

if (x=1)
{
strcpy(dest,src);
dest[50] = ‘\0’;
}

return y;

Solution:
Alright, so I admit it — this chunk of code is a bit nonsensical. But I will say that people do make these mistakes all the time, but probably not all at the same time. 🙂

This code has 4 security defects:
1. The if statement with “=” instead of “==”. Many of you would argue that this is of a quality issue than a security issue, and you’d be right. But security is certainly a subset of quality, and this can cause the code to do things that it shouldn’t do.
2. In strcpy, src is larger than dest, causing a buffer overrun.
3. Arrays start at 0, not 1! Therefore, we are writing past the last allocated spot on the array.
4. The variable y is not initialized.

Now that you’ve heard the bad news about all that’s wrong with this code, it’s time for some good news. I bet you didn’t know that Visual Studio 2005 catches all of these problems! Strcpy is caught by the compiler and noted as a warning. We’ve created safe versions of these libraries in Visual Studio 2005 called Safe CRT libraries. PREfast catches the other 3 bugs — even the “=” error. With these tools and proper education, we hope to get developers all over the world wrting more secure code!

 

[Via Spot the Bug!]

The part that I find exciting is that the compiler catches all of these problems. This is excellent. I’m not sure of that status of GCC in this regard, but given GCC development over the past few years, I’ll bet it is either already there, or coming real soon now.

FileCopyPolicyIsRemote method kinda shows the whole pattern

bool FileCopyPolicyIsRemote( Host h, string filename )
{
string host = h.Name;
/*string[] splits = filename.Split(new char[] {‘/’,’\\’} );// slash or backslash
string basename = splits[splits.Length-1];*/
string basename = Path.GetFileName(filename);
Match m;

if ( FileCopyPolicy==”overwrite” )
return true;
else if ( FileCopyPolicy==”rotate” )
return true;
else if ( FileCopyPolicy==”uselocal” )
return false;
else if ( ( null != (m = Regex.Match(FileCopyPolicy, @”uselocal-(\d+)day” ))) && m.Success )
{
short days = Convert.ToInt16(m.Groups[1].Value);
string returnfile = LocalCacheDirectory + host + Path.DirectorySeparatorChar + basename;
if ( File.Exists(returnfile) &&
( File.GetLastWriteTime(returnfile).AddDays(days) > DateTime.Now ) &&
( new FileInfo(returnfile).Length != 0 )
)
return false;
else
return true;
}
else
return false;//unknown policy

}

Free Opera

Whoo hoo!!!

I’m very happy to lose that 20 pixel ad bar at the top of my Opera browser.

Thanks to Chris Sellers for sending me the link http://my.opera.com/community/party/ so I can get a free registration code in celebration of Opera’s 10 year aniversary.

Opera 8 is really the first release that I’ve used which feels on par with Firefox and IE in terms of web standards and rendering pages. Previously it always seemed to lack just one or two things on my requirement list. Opera 8 is so good and fast that it beast Firefox and IE in speed IMO. It just /feels/ fast.

Thanks Opera people.

Stupid code – aka gnome-session phantoms

This could be some of the worse code I’ve ever seen:

snipit from
the cvs

static char* address = NULL;

if (! address)
{
g_warning ("Host name lookup failure on localhost.");

address = g_new (char, 10);
srand (time (NULL) + (getpid () < <16)); g_snprintf (address, 10, "0%.8x", rand()); };

I discovered it because my gnome login takes about 5 minutes and the message:


(gnome-session:15027): WARNING **: Host name lookup failure on localhost

is the last thing in my .xsession-errors file.

Well, if you know almost any programming language you can read the above C and understand that this error message will always be displayed.

It is not a big deal, now I have to go down another path to solve my problem, but my point is that I shouldn’t have to. It is discouraging. It is what drives people to the “format and reinstall” mentality of Windows users of the past. I moved to Linux because I did not like the “format and reinstall” menatlity. Now, it seems like the tinkerers in Linux land format and reinstall more often than the workers of Windows. Windows 2000 was good, and Windows XP is excellent(except for the horrible fragmentation habits of NTFS). I’m glad that Linux sparked the competition needed to get Windows more stable and usable, but now lets do it again with Linux. Lets clean up these crazy bugs, incorrect and unhelpful log messages, and make Linux just a little better.

I hope the above is not counter productive. I still find the $199 and $299 Full version prices of XP Home and XP Pro completely unacceptable. I will not steal software. Linux is the best alternative. Ubuntu is doing an excellent job. I’m sure much of my problem stems from my installation being a 4.10->5.04->dev branch installation. The reason I run the dev branch is to come across these types of issues and try to help solve the problem. I’m just trying to do my small, tiny, miniscule part.

Things I didn’t know I hate about MS SQL Server 2000

Things I didn’t know I hate about MS SQL Server 2000

No Except operator (aka Oracle Minus). Its called a Relational Database Management System because the databases are supposed to be telational. I suppose I expect too much because I can think in Tuple Relational Calculus and Relational Algebra. Not being able to do simple set arithmetic is quite pathetic. I realize tha SQL Server 2000 is now nearly 6 years old, but please, I’m pretty damn sure PostgreSQL had Except back in 2000. This limitation leaves me feeling like I’m using MySQL.

User defined Functions aren’t allowed to reference or use TEMP tables??? Huh? What kind of restraint is this? In every other RDBMS I’ve used, (very little Oracle and PostgreSQL. MySQL does not count) the difference between Functions and Stored Procedures is almost none. Shouldn’t a Stored Procedure be just like a function which returns no value? Surely I’m missing something on this point. I’m no DBA. Reasons aside, this is a painful restriction.

The combination of the above two restricts me further. I would use the later to work around the former, but alas. I cannot.