Author Archives: David

About David

A mostly professional code monkey, to contact me translate the following "direct from blog to email" at the website ominian.net. Replace spaces with underscores or dashes, whatever is valid. A script will pick up your email, scrub it against a white list, and if your not a spammer I will get an email.

PyProxy – Aka the development Helper proxy

Coming out of nothing and into supah doopa Alpha is finally a working proof of concept of my python web proxy. I don’t really want to talk about the asinine alternatives I’ve tried until I finally said “fuck it, time to go completely twisted!” Low and behold the actual proxy part is 4 lines of code, which is then expanded to maybe 20-30 to allow for overloading some lower level classes.

Originally a public announcement for this project would have been in August at the earliest, give me time to clean things up and go from proof of concept to working concept but apparently a lot of other people have similar thoughts and I figured it’s better to collaborate then compete.

So some quick notes:
The ultimate goal for PyProxy ( or whatever it ends up being named ) is to sit between a developer and a development server. The first and immediate idea for this was to automagically parse out Python mechanize scripts to replicate the traffic. These mechanize scripts could then be collected into a suite, marking other scripts as requirements ( example login process ). That alone would make it pretty easy to create full system under test unit-tests. The next idea was to add in regex or pattern based hooks that could allow a developer to dial in to a specific domain, or even a specific set of webpages.

After that, the idea was to just continually tack on support plugins and scripts, maybe tell PyProxy the name of the target application’s database, and if it’s MySQL, switch on the general log. This could allow for combining both mechanize scripts AND a SQLObject or SQLAlchemy powered unit-test suite to assert that the correct data was changed.

The final future idea was to make a Firefox/Chrome extension that would allow a developer to control some parts of the proxy from their browser and also see additional information. For Python and PHP web apps, imagine have a finalization plugin that appended a response header listing all File’s used to perform a request…. then imagine having a “click to edit” button that, if the dev. instance is workstation local, would have your favorite IDE open the specified file for editing.

All in all, I think these are really subtle idea’s that if combined together, would cut down some mudane parts of developing a web app.

GitHub repo (https://github.com/devdave/PyProxy) here

Javascript has arrived in force

A quick tally of prospective clients this season is showing that JS is very much in demand in everything from HTML5 mobile support, to Ajaxifying web applications, to more exotic stuff. I’m really glad I invested myself five years ago in developing my grasp of JS, this was one technology choice I appear to have made right.

Doctrine2 building Where like expressions

Use case: You have a search form with multiple search criteria “name”, “id”, “type”, etc.

In your entity’s repository you would have a function like

Note, trying to use Gist for inline code, if it doesn’t work/render then go here https://gist.github.com/1039231

It’s important to note the setParameter call is responsible for wrapping the value in %’s and NOT the where expression itself. At the PDO driver layer, it either ignores or is aware of wrapped % symbology and allows those characters to get past the input scrubbers.

Minus the ->select expression, this could conceivably be portable to any and all Entities by shoving an application level EntityRepostory class between the individual entities and the Doctrine EntityRepository.

Escape from PHP

I am going to be honest with you. I… hate… this place, this zoo, this prison, this reality—whatever you want to call it, I can’t stand it any longer. It’s the smell, if there is such a thing. I feel saturated by it. I can taste your stink, And every time I do, I fear that I’ve somehow been infected by it; it’s repulsive, isn’t it? I must get out of here. I must get free.

— Agent Smith, The Matix

To be quite honest, even though I am a master PHP programmer, I pretty much despise the language and to an extent the culture around PHP.

“Hyuck, why use an open source framework when we can write our own” – 3 different clients last year said that

“We can’t do unit-testing, it will cost too much to implement.” – Pretty much every client, which is my fault because I didn’t properly sell them on TDD or just unit-testing.

Or hell, this isn’t fair to PHP’s culture, but I’ve lost count of how often MySQL is used like a gigantic dump truck. “Normalization? Fuck that, MySQL can handle it… ‘Can’t ya ol’girl?'” At which point the master MySQL server either catches on fire or gridlocks itself into oblivion.

No more luck

A long time ago, in a distant state called Pennsylvania, I went and visited my Brother at his college. Upon my arrival I was invited as a guest to the local charity casino night. Give 10$ and get 1000 casino chips, most of the money went to charity so on purchase you couldn’t trade it back for money… so pretty much a no-stake gambling environment. Great.

At the beginning of the night, I bought my obligatory 1000 chips and started at the Roulette table. My first bet, I put 500 chips on odds and then let it roll. Bam, it lands on odds… so my 500 became 1000 or a total of 1500 chips. When the dealer motioned if I wanted to pull my winnings I shrugged and said “Let it ride” to which the dealer replied back with a shrug. BAM lands on odd again… I’ve now got 3000 chips, 2000 of which are on the table. This time I decided to take action and put all 3000 straight up on lucky 13. When the wheel finished, I walked away from the table laughing, a pillow case of chips over my shoulder.

From that day onward, I know statistically I should never EVER be able to win at any other game of chance. Which makes this whole memory somewhat unfortunate as it leads me think some days what if I had achieved such a statistical impossibility with real money? Of course sometimes it better to not luck out too much.

Komodo IDE auto-generating setters/getters for PHP

I’ve got about thirty auto-generated PHP Doctrine models that are missing their required Java style setters/getters. At class number three of typing in these accessory methods I snapped and said “There has to be a better way” and magically the universe smacked me upside the head and reminded me that I’m using Komodo IDE which just so happens to have a disgustingly powerful Python powered macro system.

Four minutes later, out came the copy & paste hacked together monstrosity below. It’s not perfect but it doesn’t need to be, just has to work well enough to save my sanity and my client’s time.

To use, follow Komodo’s help documentation for creating a new python Macro then copy and paste this code into the macro window OR a slightly easier way, make the macro then click the “edit macro” context menu property to open the macro source file as a new view in Komodo.

The macro uses some very simple rules. It’s only looking for private properties in a format of “^\s*private \$[a-zA-Z0-9_]$”, it collects all of these variable names and then appends them through the setter and getter templates to a string buffer. Finally the buffer is
inserted into the current document at the position of the cursor. The output is coherent but not whitespace friendly which isn’t too big of a deal to re-format. Note, the macro has no concept of PHP syntax, so if there is more then one class in a file, the results will not be desirable.


from xpcom import components
import re

viewSvc = components.classes["@activestate.com/koViewService;1"]\
    .getService(components.interfaces.koIViewService)
view = viewSvc.currentView.queryInterface(components.interfaces.koIScintillaView)

sm = view.scimoz
sm.currentPos   # current position in the editor
sm.text         # editor text
sm.selText      # the selected text
#sm.text = "Hello World!"

output = u"\n"

setterTemplate = """
    function set%s($value){
        $this->%s = $value;
    }
"""

getterTemplate = """
    /**
    *@return string
    */
    function get%s(){
        return $this->%s;
    }
"""

propertyTemplate = """
%s
    
%s
"""

prefixSize = len(u"private $")

def formalName(rawName):
    return u"%s" % "".join([part.title() for part in rawName.split("_")])
        



#todo find a better way to split lines, what if its Mac or Windows format?
for line in sm.text.split("\n"):
    if line.strip().startswith("private $"):
        #trim of the private $ and trailing semi-colon
        realName = line.strip()[prefixSize:-1]        
        output += propertyTemplate % ( setterTemplate %(formalName(realName), realName), getterTemplate % (formalName(realName), realName))        
        
    
    
sm.insertText(sm.currentPos, output)
        

My client’s hate me

I’ve been using mdb-tools, a open source package for extracting Access MDB files, and entering whole new depths of
conceptual joy. Application two and three were written in ASP by a college student, they were stop gap measures meant to live for a year or so… Fast forward 9 years and my client’s hired me to “fix” this problem among others.

In 2004 I replaced a USAF MS Access program used by my squadron with a PHP5 app, now 2011 I feel like I’ve stepped into a time machine and back in the hell that is MS Access and legacy ASP.

   CREATE TABLE CredentialLog
 (
	LogID			Integer, 
	StudentID			Text (100), 
	Cycle			Text (100), 
	AppTo			Text (100), 
	AppFor			Text (100), 
	DayPhone			Text (100), 
	Letter1			Text (100), 
	Letter2			Text (100), 
	Letter3			Text (100), 
	Letter4			Text (100), 
	Letter5			Text (100), 
	Letter6			Text (100), 
	Letter7			Text (100), 
	Letter8			Text (100), 
	Letter9			Text (100), 
	Letter10			Text (100), 
	Letter11			Text (100), 
	Letter12			Text (100), 
	Letter13			Text (100), 
	Letter14			Text (100), 
	Letter15			Text (100), 
	DateRec1			DATETIME, 
	DateRec2			DATETIME, 
	DateRec3			DATETIME, 
	DateRec4			DATETIME, 
	DateRec5			DATETIME, 
	DateRec6			DATETIME, 
	DateRec7			DATETIME, 
	DateRec8			DATETIME, 
	DateRec9			DATETIME, 
	DateRec10			DATETIME, 
	DateRec11			DATETIME, 
	DateRec12			DATETIME, 
	DateRec13			DATETIME, 
	DateRec14			DATETIME, 
	DateRec15			DATETIME, 
	DateSent1			DATETIME, 
	DateSent2			DATETIME, 
	DateSent3			DATETIME, 
	DateSent4			DATETIME, 
	DateSent5			DATETIME, 
	DateSent6			DATETIME, 
	DateSent7			DATETIME, 
	DateSent8			DATETIME, 
	DateSent9			DATETIME, 
	DateSent10			DATETIME, 
	DateSent11			DATETIME, 
	DateSent12			DATETIME, 
	DateSent13			DATETIME, 
	DateSent14			DATETIME, 
	DateSent15			DATETIME, 
	Initial1			Text (8), 
	Initial2			Text (8), 
	Initial3			Text (8), 
	Initial4			Text (8), 
	Initial5			Text (8), 
	Initial6			Text (8), 
	Initial7			Text (8), 
	Initial8			Text (8), 
	Initial9			Text (8), 
	Initial10			Text (8), 
	Initial11			Text (8), 
	Initial12			Text (8), 
	Initial13			Text (8), 
	Initial14			Text (8), 
	Initial15			Text (8)
);