phillc http://phillc.com Most recent posts at phillc posterous.com Sat, 31 Mar 2012 13:44:27 -0700 I'm not really a focused writer. http://phillc.com/im-not-really-a-focused-writer http://phillc.com/im-not-really-a-focused-writer

So follow me on twitter or github instead.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Fri, 20 Jan 2012 14:45:00 -0800 Decided to move my blog to posterous. http://phillc.com/decided-to-move-my-blog-to-posterous http://phillc.com/decided-to-move-my-blog-to-posterous

Seems like I have a hard time being motivated enough to write anything down. There is definitely some overhead in writing my own blog, which is why I moved away from my custom Django blog. From there I have tried a bunch of static site generators powered by git/github (like nanoc, jekyll and webgen). I think switching to a tool that I don't have to maintain and has features like mobile compatibility or email posting might tip me over the edge.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Sun, 06 Jun 2010 12:00:00 -0700 v8 scons error http://phillc.com/v8-scons-error http://phillc.com/v8-scons-error

While trying to install Google v8, I had an error:

v8-read-only$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o obj/release/api.o -c -Wall -Werror -W -Wno-unused-parameter -Wnon-virtual-dtor -pedantic -m32 -O3 -fomit-frame-pointer -fdata-sections -ffunction-sections -ansi -fno-rtti -fno-exceptions -fvisibility=hidden -Wall -Werror -W -Wno-unused-parameter -Wnon-virtual-dtor -pedantic -m32 -O3 -fomit-frame-pointer -fdata-sections -ffunction-sections -ansi -DV8_TARGET_ARCH_IA32 -DENABLE_VMSTATE_TRACKING -DENABLE_LOGGING_AND_PROFILING -DENABLE_DEBUGGER_SUPPORT -Isrc src/api.cc
cc1plus: warnings being treated as errors
src/handles-inl.h: In static member function 'static void v8::V8::RemoveMessageListeners(void (*)(v8::Handle, v8::Handle))':
src/handles-inl.h:50: error: dereferencing pointer '' does break strict-aliasing rules
src/handles-inl.h:50: error: dereferencing pointer '' does break strict-aliasing rules
src/utils.h:739: note: initialized from here
cc1plus: error: dereferencing pointer 'dest' does break strict-aliasing rules
cc1plus: error: dereferencing pointer 'dest' does break strict-aliasing rules
cc1plus: error: dereferencing pointer 'dest' does break strict-aliasing rules
cc1plus: error: dereferencing pointer 'dest' does break strict-aliasing rules
src/api.cc:3767: note: initialized from here
scons: *** [obj/release/api.o] Error 1
scons: building terminated because of error

Solved by using export GCC_VERSION=44, before running scons.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Wed, 14 Oct 2009 12:00:00 -0700 Javascript State Machine http://phillc.com/javascript-state-machine http://phillc.com/javascript-state-machine

I wrote a simple Javascript State Machine.

It is intended for keeping track of what the current state is for my heavy AJAX app at work.

I also learned a lot about OO in javascript without using jQuery or the prototype framework, by using prototypes. I wanted to do that so that it would be framework independent.

Below is a simple example of how I use the state machine, and shows a bit of how I connected it with Really Simple History

I have included in this example some comments to show my thinking throughout, and perhaps how to use it.

Site.prototype = new StateMachine();
Site.prototype.states = {
    Begin: {
        enter: function(){
            // do some animation
        },
        exit: function(){
            // hide some stuff
        }
    },
    Page: {
        enter: function(){
            // show some page
        },
        exit: function(){
            // hide it
        },
        change: function(page){
            // example of some event
            this.pages.change_page(page);
            // events can call events
            this.handleEvent('setURL');
        },
        setURL: function(){
            //example of how I integrate with really simple history
            dhtmlHistory.add(['pages'].concat(this.pages.current_page.split('/')).join('.').toLowerCase());
        }
    }
};

// These are some call backs I used for debugging with firebug to ensure
// that events were firing
Site.prototype.beforeEvent = function(name){
    console.log('begin event: ', name);
}
Site.prototype.afterEvent = function(name){
    console.log('end event: ', name);
}
Site.prototype.beforeStateChange = function(to, from){
    console.log('begin state change to: ', to, ' from: ', from);

    // as an example of intercepting, I can stop a state from changing by returning false
    if(to == 'Page' && this.pages.blocker == 'Page'){
        // some logic
        return false;
    }
    return true;
}
Site.prototype.afterStateChange = function(to, from){
    console.log('end state change to: ', to, ' from: ', from);
}

// The actual defenition. Instance vars can be set in it.
function Site(){
    this.pages = new Page();
}

// global scope, so that it can be accessed globally (as it wouldn't normally
// be because the scope that I actually instantiate it inside prorotype's window onload)
var Davis; 


// Once again, just an example of how I integrate it with Really Simple History
function historyChange(newLocation, historyData) {
    var hash = newLocation.split('.');
    var newState = hash.shift().capitalize();
    if(newState == '') newState = 'Begin';
    if(Davis.changeState(newState))
    {
        if(hash.length > 0) Davis.handleEvent('change', hash.join('/'));
    }
}

// This window observe for onload is prototype specific... But you can achieve the same other ways.
Event.observe(window, 'load', function() {
    Davis = new Site(); // my requirements need me to initialize after load

    // Really Simple History stuff
    dhtmlHistory.initialize(historyChange);
    historyChange(dhtmlHistory.currentLocation || '');
});

While implementing this, I also learned a bit about bookmarking and enabling the back button of ajax states. Really Simple History has worked ok for me, but it has some quirks… some of which I haven’t solved yet (especially in IE) and those bugs may be above.

I also got my first dose of unit testing in javascript… and found some really cool library to assist in the development called newjs . However, at the time of this writing, the unit tests are not up to the current code, as a lot has changed… I will deal with that later.

Anyway, while my implementation surely isn’t the best in the world, I hope someone can find use from it.

http://github.com/phillc/Javascript-State-Machine

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Fri, 28 Aug 2009 12:00:00 -0700 Ruby multi-dimensional array helper http://phillc.com/ruby-multi-dimensional-array-helper http://phillc.com/ruby-multi-dimensional-array-helper

I needed something to help me get through a multi-dimensional array. So I extended the Array class.

Grab expects an array of coordinates.

class Array
  def grab(position)
    value = self.fetch(position.first)
    value = value.grab(position[1..-1]) unless position[1..-1].empty?
    value
  rescue NoMethodError
    raise(IndexError, "Multi Dimensional Array not deep enough")
  end
end

Then I can do this:

>> [[1,2,3],"asdf",[[11,22,33],5,6,7]].grab([2,0,0])
=> 11
>> [[1,2,3],"asdf",[[11,22,33],5,6,7]].grab([2,0,2])
=> 33
>> [[1,2,3],"asdf",[[11,22,33],5,6,7]].grab([2,1])
=> 5
>> [[1,2,3],"asdf",[[11,22,33],5,6,7]].grab([1,0])
IndexError: Not an array.
    from /Users/phillip/Desktop/rworkspace/davisbrandcapital/lib/tagging.rb:73:in `grab'
    from (irb):64
>> [[1,2,3],"asdf",[[11,22,33],5,6,7]].grab([1])
=> "asdf"
>>

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Wed, 19 Aug 2009 12:00:00 -0700 Cucumber with Selenium and Authlogic http://phillc.com/cucumber-with-selenium-and-authlogic http://phillc.com/cucumber-with-selenium-and-authlogic

I had some Issues with cucumber/selenium working properly with authlogic. After much searching, I’ve figured out how to get it all to work properly.

I would get an error like:

When I follow "Manage pages"                          # features/step_definitions/webrat_steps.rb:19
  ed out after 5000ms (Selenium::CommandError)
  /opt/local/lib/ruby/1.8/timeout.rb:62:in `timeout'
  /opt/local/lib/ruby/1.8/timeout.rb:93:in `timeout'
  (eval):2:in `/^I follow "([^\"]*)"$/'
  features/plain/admin_page.feature:8:in `When I follow "Manage pages"'

Initially, to setup authlogic to work with regular webrat tests, I had to put the following in my env.rb:

require "authlogic/test_case"

Before do
  activate_authlogic
end

After getting it working with webrat, I decided I wanted to test some of my javascript and AJAX with selenium, so I followed this guide

The database_cleaner gem had to be added because you can’t use

Cucumber::Rails.use_transactional_fixtures

with selenium, so it had to be removed from the env.rb and placed in the plain.rb. As a result, this ended up in my enhanced.rb

require 'database_cleaner'
Before do
  # truncate your tables here, since you can't use transactional fixtures*
  DatabaseCleaner.strategy = :truncation
  DatabaseCleaner.clean
end

and this ended up in my plain.rb

require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean

Originally, I had it just in my enhanced.rb as an After block instead of Before, but after further contemplation, I realized that if something goes terribly wrong with the selenium tests, then the database would have bad data in it… So might as well clean it before hand.

Finally, my problem with authlogic + seleniu, was how I wrote my test. The way it was erroring out made it look like something completely different (the selenium timeout error), but after I watched it a couple times closely, I determined that the test was being sent to the next page before the “button press” was executed.

Here is the beginning of my test that failed:

Scenario: Visit Add Page page
  Given I am logged in
  And I am on "the admin page"
  When I follow "Manage pages"
  And I follow "New Page"

With a little help from a post on stack overflow, I got it to work with the following:

def user
  @user ||= Factory.create(:user)
end

def login
  user
  fill_in "Email", :with => @user.email 
  fill_in "Password", :with => @user.password
  click_button "Login"

  # This is what was added
  if Webrat.configuration.mode == :selenium
    selenium.wait_for_page_to_load
  end
end

Given /^I am logged out$/ do
  @current_user_session.destroy if @current_user_session
end

Given /^I am logged in$/ do
  visit path_to("the login page")
  login
end

When /^I login$/ do
  login
end

Notice I had to add the if selenium line in order to get it to work in webrat.

Something tells me there is a better way to do it… probably overriding the click_button method when selenium is loaded… but I don’t know it well enough quite yet to venture that far, I’ll probably try it soon though.

Edit: oh, its a thing with webrat… but installing the newest version didn’t fix it for me, then I actually read the ticket… I’ll stick with my current solution for now.

Edit2: Actually the issue is in the visit method, if you can believe that. click_button works fine, as it waits for the page to load before clicking, but the visit method is sent so fast, that because of the way my test is set up, we are sent to the next page either before the login button is pressed, or before the request gets a chance to process… I don’t feel like investigating which one it exactly is, because the solution is the same… wait for the next page to load.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Tue, 18 Aug 2009 12:00:00 -0700 e-Text Editor http://phillc.com/e-text-editor http://phillc.com/e-text-editor

Was attempting to compile e-text editor on ubuntu 9.10 (yea yea, I know… my right to complain about broken packages disappears since its alpha) just to try it out, but had a sick number of errors ranging from “Cannot compile wxWidgets” to “Cannot compile WebKit”.

Finally, after trying multiple ways of compiling wxWidgets, I figured out the real error was

"./include/wx/gsocket.h:40: error: using typedef-name ‘GSocket’ after ‘class’"

So I applied a patch I found at http://trac.wxwidgets.org/ticket/10883 to the wxwidgets folder. and it suddenly worked.

edit: I turned out that I also had to update glib. glib version 2.20 did it for me.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Tue, 16 Jun 2009 12:00:00 -0700 xServer xorg.conf for 4850 X2 dual monitor - Ubuntu 9.04 http://phillc.com/xserver-xorgconf-for-4850-x2-dual-monitor-ubu http://phillc.com/xserver-xorgconf-for-4850-x2-dual-monitor-ubu

Thanks to gwydion

I got my xorg.conf to finally work in Ubunutu 9.04 Jaunty. I was having problems where when I boot into ubuntu, I didn’t even get a login screen, it just froze at a black screen after boot up with a few artifacts of color here and there.

Took many, many hours trying to finding this solution. I ended up being able to use the proprietary driver fglrx when all was said and done, instead of having to use vesa.

Here is what I did:

dpkg-reconfigure xserver-xorg
aticonfig --initial -f --adapter=all
aticonfig --cfa --adapater=all
aticonfig --add-pairmode=x+x

Also had to add

Option "EnableRandR12" "false"

to each device section and

EnableRandR12=Sfalse

to the [AMDPCSROOT/SYSTEM/DDX] section of /etc/ati/amdpcsdb (source) in order to disable RandR 1.2

xorg.conf

# xorg.conf (X.Org X Window System server configuration file)
#
# This file was generated by dexconf, the Debian X Configuration tool, using
# values from the debconf database.
#
# Edit this file with caution, and see the xorg.conf manual page.
# (Type "man xorg.conf" at the shell prompt.)
#
# This file is automatically updated on xserver-xorg package upgrades *only*
# if it has not been modified since the last upgrade of the xserver-xorg
# package.
#
# Note that some configuration settings that could be done previously
# in this file, now are automatically configured by the server and settings
# here are ignored.
#
# If you have edited this file but would like it to be automatically updated
# again, run the following command:
#   sudo dpkg-reconfigure -phigh xserver-xorg

Section "ServerLayout"
    Identifier     "aticonfig Layout"
    Screen      0  "aticonfig-Screen[0]-0" 0 0
    Screen         "aticonfig-Screen[1]-0"# RightOf "aticonfig-Screen[0]-0"
EndSection

Section "Files"
EndSection

Section "Module"
EndSection

Section "Monitor"
    Identifier   "aticonfig-Monitor[0]-0"
    Option      "VendorName" "ATI Proprietary Driver"
    Option      "ModelName" "Generic Autodetecting Monitor"
    Option      "DPMS" "true"
    HorizSync   30-82
    VertRefresh  56-76
EndSection

Section "Monitor"
    Identifier   "aticonfig-Monitor[1]-0"
    Option      "VendorName" "ATI Proprietary Driver"
    Option      "ModelName" "Generic Autodetecting Monitor"
    Option      "DPMS" "true"
    HorizSync   30-82
    VertRefresh  50-75
EndSection

Section "Device"
    Identifier  "aticonfig-Device[0]-0"
    Driver      "fglrx"
    Option      "EnableRandR12" "false"
    Option      "PairModes" "1680x1050+1280x1024"
    BusID       "PCI:3:0:0"
    Option          "XAANoOffscreenPixmaps"
EndSection

Section "Device"
    Identifier  "aticonfig-Device[1]-0"
    Driver      "fglrx"
    Option      "EnableRandR12" "false"
    BusID       "PCI:4:0:0"
    Option          "XAANoOffscreenPixmaps"
EndSection

Section "Screen"
    Identifier "aticonfig-Screen[0]-0"
    Device     "aticonfig-Device[0]-0"
    Monitor    "aticonfig-Monitor[0]-0"
    DefaultDepth     24
    SubSection "Display"
        Viewport   0 0
        Depth     24
        Modes      "1680x1050_75.00"
    EndSubSection
EndSection

Section "Screen"
    Identifier "aticonfig-Screen[1]-0"
    Device     "aticonfig-Device[1]-0"
    Monitor    "aticonfig-Monitor[1]-0"
    DefaultDepth     24
    SubSection "Display"
        Viewport   0 0
        Depth     24
        Modes      "1280x1024_75.00"
    EndSubSection
EndSection

This probably is a solution for the 4870 X2, or any other X2 based board.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Fri, 19 Sep 2008 12:00:00 -0700 Automatic static media folder http://phillc.com/automatic-static-media-folder http://phillc.com/automatic-static-media-folder

Added another shortcut… I had a config variable in my settings_local file to specify where the media folder was in order to have django static serve it.

This is much easier.

urls.py:

if DEBUG:
    import os
    media_root = os.path.join(PROJECT_ROOT, 'media')
    urlpatterns += patterns ('',
        (r'^media/(?P.*)$', 'django.views.static.serve', {'document_root': media_root}),
    )

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Tue, 08 Jul 2008 12:00:00 -0700 Structure inside a project http://phillc.com/structure-inside-a-project http://phillc.com/structure-inside-a-project

A common problem I have had is that too much work was required when I needed to deploy my django project, or if i needed to work on the project on another computer. Subversion has been my friend, but part of the problem is the necessary local settings in each of the projects.

In addition to the overall structure between all my projects, I have developed a few tricks to make handling things inside of a project much easier.

Previously, my template folder and my media folder were in different parent directories. This caused me to need to change several variables in the settings.py (or my settings_local.py) of django in each environment that it existed in. However I no longer have to do that.

Inside my settings.py I have this:

import os, sys
PROJECT_ROOT = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'apps'))

The first two lines figure out the directory that the settings.py lives in The third line inserts my apps folder to the python path (this works great with my django directory structure)

Now, the next step for me was to move my template and media directories around. My directory structure for a project is as follows:

-project
—media
—-css
—-js
—-images
—templates
—-application template directory 1
—-application template directory 2
—-base.html
—apps
—-app1
—-app2
—settings.py
—settings_local.py

So as you can see, my templates folder is in the same directory as my settings.py. My media folder is too. In order to avoid making this a variable too:

MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')

TEMPLATE_DIRS = (
     os.path.join(PROJECT_ROOT, 'templates'),
)

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Mon, 07 Jul 2008 12:00:00 -0700 Developed Directory Structure http://phillc.com/developed-directory-structure http://phillc.com/developed-directory-structure

Over the course of my web development life, I have changed my work flow and directory structure many times. Each time gets a little bit better, but I doubt I will ever finish modifying it, as I am always learning new techniques.

I am presently using Django in all of my projects, both at work and as a hobby. Django’s ability to easily reuse applications has mad me change my directory structure several time. Finally, I do believe I have settled.

First thing to know, is that both at work and in my pet projects, I am hosting multiple websites on the same apache instance. This is simply because the load behind the website does not justify buying a new slice (I use slicehost for my hosting needs).

I also make use of several available applications out there, django comment utils, django tagging, and django-registration just to name a few (all/most are findable through django pluggables)

So that being said, I need to have a directory structure capable of handling each one of my projects, all of my own shared applications, and all of the downloaded applications.

Here is what I have come up with.

  • projects/
    — project 1/
    —– apps/
    —— non reusable app 1/
    —— non reusable app 2/
    — project 2/
    — project 3/
    —-apps
    —— non reusable app 3/

  • common/
    — self made reusable app 1/
    — self made reusable app 2/

  • external/
    — grabbed reusable app 1/
    — grabbed reusable app 2/
    — grabbed reusable app 3/

Basically, the idea being that I store my projects in the projects folder, with applications made just for that project in the project’s application folder.

I put applications that I build that will be used by more than one project into the common folder.

Applications that I have grabbed from other people (comment_utils, tagging, etc) into the external folder.

Then for each virtual host, I add to the python path the projects folder, then reference settings by projectname.settings (from observation, django adds the folder where the settings file is to the python path itsself), and the common folder and the external folder. I also add the projects, external, and common folders to the python path inside of conf file.

That works for apache, but then to get manage.py to work (it doesn’t work because none of the python paths are set for it), I edit “/etc/environment” and add the line

PYTHONPATH="/home/username/projects:/home/username/common:/home/username/external"

Bingo, now manage.py works.

Now, any time I want to add a new project, I do not have a ton of hassle trying to get the project’s manage.py to work, and all my virtual hosts in apache have the same structure!

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Sat, 05 Jul 2008 12:00:00 -0700 Making Django Projects Version Control Friendly http://phillc.com/making-django-projects-version-control-friend http://phillc.com/making-django-projects-version-control-friend

Subversion has been my friend ever since I learned about it. However, it took me a while to figure out how to deal with configuration files. For Django, this specifically relates to the settings.py.

Django projects can end up on many different environments. Putting settings.py into source control directly will cause our settings to migrate across all working copies. This is not reasonable, as not every person will have the same environment (not all using mysql, not all using the same directory).

Removing settings.py from version control, and make a separate settings.py.template file that contains just the basic structure is a solution to that. However, it brings another problem: What if you want to change a used application or a middleware? You would then have to make that change on all working copies.

My solution has been to make a settings_local.py.dist

This file has variables in it like media path, database information, and caching options. You can copy these things straight out of the settings.py (and delete them from settings.py)

This file will go under version control.

Now, in your settings.py, add the line

from settings_local import *

(I added the line to the very bottom of my settings.py)

So, now when a working copy of the project is grabbed, the person behind it can copy settings_local.py.dist to settings_local.py. Inside settings_local.py the environment’s details are placed. This file will be ignored from version control.

With this setup, you can add an application or middle ware to settings.py for easy distributing through version control, and it will not affect a workspace’s local variables.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc
Wed, 25 Jun 2008 12:00:00 -0700 Purpose of this website http://phillc.com/purpose-of-this-website http://phillc.com/purpose-of-this-website

Over the course of my programming life, I have written some form of blog in perl, then php, then in a framework of php, then ruby on rails, and now Django.

The real purpose of this site is to get an understanding of every component that goes into a blog. This is without a doubt the best one I’ve ever written, but the same could be said about each of the ones I built before at that time.

This website is built in Django, where I currently build most of my applications now.

In addition to the building of the blog, I decided that it is time for me to write some of my technical thoughts down.

Yes I like to share, discuss, and debate many technological things, however another purpose of this site is to store my docs so that I can grab them anywhere. Not real big things or private things, but things like, a step by step on server setup, so that I can copy paste my long apt-get install command, without trying to remember it from memory.

This serves that purpose well.

This blog is obviously not complete. I will finish it over time, but it does share the same code with another website, so any improvements will reflect on both.

Permalink | Leave a comment  »

]]>
http://posterous.com/images/profile/missing-user-75.png http://posterous.com/users/egPlQiHW2w0CS phillc spyyderz phillc