Freelance Camp Santa Cruz 2010

I had a great time at Freelance Camp Santa Cruz this year.
Thanks guys! Looking forward to next year =)

Goodbye, Slicehost.

After 2 years with Slicehost, I’ve finally just finished migrating all my stuff to my own box and deleted my last slice.

Thank you SliceHost for your awesome articles and awesome support. You helped me get off of shared hosting and learn what it takes to manage a real server. I’ve outgrown your services, but I highly recommend you to any developers out their who want to take their game to the next level.

You stay classy, SliceHost.

Sincerely,
- Kevin M. Burns Jr

Your PHP installation appears to be missing the MySQL extension which is required by WordPress.

Wordpress is throwing an error:

Your PHP installation appears to be missing the MySQL extension 
which is required by WordPress.

PHP 5.3.2 is compiled from source on CentOS 5.4 configured ‐‐with-mysql ‐‐with-mysql-pdo…

#> php -i | grep -i 'mysql support'
MySQL Support => enabled

mysqld is running…

#> /etc/init.d/mysqld status
mysqld (pid 21104) is running...

I’ve been googling around for 2 hours now.

What the hell is going on?

UPDATE

Took me 4 hours, but I finally got it working.

The problem is I wasn’t using ‐‐with-aspx2

  1. Deleted all PHP bin, lib, includes, ini, everything
  2. Removed Apache libphp5.so
  3. Compiled PHP 5.3.3 from source
    • ‐‐with-aspx2 (this is required to generate a new .so apache module)
    • ‐‐prefix=/usr/local/php (this installs everything into 1 directory making it easier to uninstall later)
  4. Copied in a fresh php.ini from source to /usr/local/php/lib
  5. Set up symlinks at /usr/sbin/php for php cli
  6. Restarted Apache

BLING BLANG BLAOW

Good Recruiter VS Bad Recruiter

I received 2 inMails from two separate recruiters today, 11 minutes apart.
The first was Excellent. The second was Terrible.
Sentence-by-sentence feedback below.
- — —– — -
- — -

Excellent

From: Katty Douraghy
[1]Subject: open to FT roles in the Bay Area or just contract?

[2]Hi Kevin,
[3]I saw your profile here and wanted to reach out. [4]My name is Katty and my company Artisan is a staffing and recruitment agency in LA & SF.

[5]I am currently working with a client in the Bay Area who is in the mobile/social media space with a focus on music & sports verticals. [6]They are looking for a web apps developer–but the role is fulltime. [7]Are you open to FT too or just contract?

[8]In either case I’d love to speak with you since we do work with clients on both Temp and FT needs–so even if this one isn’t right, I’d like to stay connected for future opportunities too.

[9]Is there a number where I can reach you so I can share more about this role and learn more about you?

Thanks,
Katty
www.artisancreative.com
[10]310-312-2062 x117

- — -

  1. Oh, you have a question about my resume.
  2. Hey, you know my name!
  3. So that’s how you found me.
  4. Ahha, you work for a recruiting agency.
  5. I see that you have a focused talent pool you are targeting.
  6. That sounds like something I might be interested in.
  7. A very specific question. I had better respond.
  8. Sounds like an open door to me.
  9. A specific request for my personal contact information…
  10. And hey look, you even have a phone number…

- — -

Terrible

From: Pemberton Gordon III
[1]Subject: Re: Hiring Tiny Prints -Sunnyvale, CA

[2]Tiny Prints is building a work class technology team. [3]Adnon VP of Engineering was a key contributor in building technology at Yahoo. [4]Is presently at Tiny Prints building a world class technology team with some interesting challenges and opportunities: scalability, mobility, and personalization. [5]Tiny Prints is a online retailer of customized and personalized stationery. [6]Company is well funded and profitable. [7]We have offer base, bonus , and equity. [8]We are looking for people interested in building something great. [9]I would love to tell you our story and give you some compelling reasons of why you should explore opportunities at Tiny Prints.

Hiring:

UI Design
Product Managers
Web Developers ( Front and Back End)

[10]P.O.C. is [11]pemberton.gordon@tinyprints.com http://ww.tinyprints.com

- — -

  1. The subject says RE:, but this is obviously a forged reply.
  2. You are building a “work class” technology team? Who would want to be a working class technologist?
  3. Is Adnon part of the job title? Or is Adnon a first name? What is his/her last name? Or is that just a typo? Or maybe your VP of Engineering prefers to remain anonymous?
  4. Your third sentence is not a sentence.
  5. Tiny Prints is a online retailer, or an online retailer?
  6. Company is well funded? Who’s company? I assume you just forgot to replace the word “Company” with “TinyPrints” and don’t know anything about their finances.
  7. You have offer base and bonus? I don’t know what that means. I assume it means you offer equity and bonuses.
  8. We are looking for people interested in building something great idiots.
  9. You won’t even bother forming a proper sentence and you want to give me advice?
  10. I’ve never heard the jargon P.O.C. – I assume it stands for Point of Contact.
  11. Do you really work for tinyprints? Cause I get the impression that you are an independent recruiter (which you are).

- — -
- — —– — -

Standard link formats in hypermedia representations

When visiting a website for the first time, a user will expect to see a logo in the top left and primary navigation across the top. In the same way that these User Interface Patterns make websites easier to use, we ought to make our APIs easier to use by relying on existing link conventions to express relationships between resources.

I think it’s awesome that Twilio offers a REST API that makes extensive use of hypermedia.
I noticed an aspect of the Twilio REST API that I feel could be more clear.
URIs seems to be strewn about under all sorts of different tags/keys.
http://www.twilio.com/docs/api/2010-04-01/rest/response#hypermedia

The fact that a tag contains a URI appears to be implicit.
Your application needs to know that TwilioResponse/Call/SubresourceUris/Notifications is a URI
Or that Calls may contain a nextpageuri attribute, which is a URI, and also links to the next page.

A better way to do this would be to standardize on using <link> tags/keys for all URIs and relying on link rels to explicitly define the semantic relationship of the link.

XML – Before

<TwilioResponse> 
    <Calls page="0" numpages="3" pagesize="50" total="147" start="0" end="49"
    uri="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls"
    firstpageuri="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls?Page=0&PageSize=50"
    previouspageuri=""
    nextpageuri="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls?Page=1&PageSize=50"
    lastpageuri="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls?Page=2&PageSize=50">
        <Call> 
            <Sid>CA92d4405c9237c4ea04b56cbda88e128c</Sid> 
            <DateCreated>Fri, 13 Aug 2010 01:16:22 +0000</DateCreated>
            <DateUpdated>Fri, 13 Aug 2010 01:16:22 +0000</DateUpdated> 
            <ParentCallSid/>
            <AccountSid>AC228ba7a5fe4238be081ea6f3c44186f3</AccountSid>
            <To>+15305431221</To> 
            <From>+15104563443</From>
            <PhoneNumberSid>PNe2d8e63b37f46f2adb16f228afdb9058</PhoneNumberSid>
            <Status>queued</Status> 
            <StartTime/> 
            <EndTime/>
            <Duration/>
            <Price/>
            <Flags> 
                <Flag>outbound-api</Flag>
            </Flags>
            <ApiVersion>2010-04-01</ApiVersion> <ForwardedFrom/> <CallerName/>
            <Uri>/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls/CA92d4405c9237c4ea04b56cbda88e128c</Uri>
            <SubresourceUris>
                <Notifications>/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls/CA92d4405c9237c4ea04b56cbda88e128c/Notifications</Notifications>
                <Recordings>/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls/CA92d4405c9237c4ea04b56cbda88e128c/Recordings</Recordings>
            </SubresourceUris>
        </Call>
        ...
    </Calls>
</TwilioResponse>

XML – After

<TwilioResponse> 
    <Calls page="0" numpages="3" pagesize="50" total="147" start="0" end="49">
        <Call> 
            <Sid>CA92d4405c9237c4ea04b56cbda88e128c</Sid> 
            <DateCreated>Fri, 13 Aug 2010 01:16:22 +0000</DateCreated>
            <DateUpdated>Fri, 13 Aug 2010 01:16:22 +0000</DateUpdated> 
            <ParentCallSid/>
            <AccountSid>AC228ba7a5fe4238be081ea6f3c44186f3</AccountSid>
            <To>+15305431221</To> 
            <From>+15104563443</From>
            <PhoneNumberSid>PNe2d8e63b37f46f2adb16f228afdb9058</PhoneNumberSid>
            <Status>queued</Status> 
            <StartTime/> 
            <EndTime/>
            <Duration/>
            <Price/>
            <Flags> 
                <Flag>outbound-api</Flag>
            </Flags>
            <ApiVersion>2010-04-01</ApiVersion> <ForwardedFrom/> <CallerName/>
            <links>
                <link rel="self" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls/CA92d4405c9237c4ea04b56cbda88e128c"/>
                <link rel="http://twilio.com/rel/notifications" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls/CA92d4405c9237c4ea04b56cbda88e128c/Notifications"/>
                <link rel="http://twilio.com/rel/recordings" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls/CA92d4405c9237c4ea04b56cbda88e128c/Recordings"/>
            </links>
        </Call>
        ...
        <links>
            <link rel="self" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls"/>
            <link rel="first" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls?Page=0&PageSize=50"/>
            <link rel="next" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls?Page=1&PageSize=50"/>
            <link rel="prev" href=""/>
            <link rel="last" href="/2010-04-01/Accounts/AC228ba7a5fe4238be081ea6f3c44186f3/Calls?Page=2&PageSize=50"/>
        </links>
    </Calls>
</TwilioResponse>

And similarly in JSON :

JSON – Before

{ 
    "page": 0, 
    "num_pages": 3,
    "page_size": 50, 
    "total": 147, 
    "start": 0, 
    "end": 49,
    "uri": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json",
    "first_page_uri": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json?Page=0&PageSize=50",
    "previous_page_uri": null,
    "next_page_uri": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json?Page=1&PageSize=50",
    "last_page_uri": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json?Page=2&PageSize=50",
    "calls": [ 
        { 
            "sid": "CA92d4405c9237c4ea04b56cbda88e128c", 
            "date_created": "Fri, 13 Aug 2010 01:16:22 +0000", 
            "date_updated": "Fri, 13 Aug 2010 01:16:22 +0000", 
            "parent_call_sid": null, 
            "account_sid": "AC228b97a5fe4138be081eaff3c44180f3", 
            "to": "+15305431221", 
            "from": "+15145623443", 
            "phone_number_sid": "PNe2d8e63b37f46f2adb16f228afdb9058", 
            "status": "queued", 
            "start_time": null, 
            "end_time": null, 
            "duration": null, 
            "price": null, 
            "flags":["outbound-api"],
            "api_version": "2010-04-01", 
            "forwarded_from": null, 
            "caller_name": null,
            "uri": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls\/CA92d4405c9237c4ea04b56cbda88e128c.json",
            "subresource_uris": {
                "notifications": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls\/CA92d4405c9237c4ea04b56cbda88e128c\/Notifications.json",
                "recordings": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls\/CA92d4405c9237c4ea04b56cbda88e128c\/Recordings.json"
            }
        }
    ]
}

JSON – After

{ 
    "page": 0, 
    "num_pages": 3,
    "page_size": 50, 
    "total": 147, 
    "start": 0, 
    "end": 49,
    "calls": [ 
        { 
            "sid": "CA92d4405c9237c4ea04b56cbda88e128c", 
            "date_created": "Fri, 13 Aug 2010 01:16:22 +0000", 
            "date_updated": "Fri, 13 Aug 2010 01:16:22 +0000", 
            "parent_call_sid": null, 
            "account_sid": "AC228b97a5fe4138be081eaff3c44180f3", 
            "to": "+15305431221", 
            "from": "+15145623443", 
            "phone_number_sid": "PNe2d8e63b37f46f2adb16f228afdb9058", 
            "status": "queued", 
            "start_time": null, 
            "end_time": null, 
            "duration": null, 
            "price": null, 
            "flags":["outbound-api"],
            "api_version": "2010-04-01", 
            "forwarded_from": null, 
            "caller_name": null,
            "_links": [
                {
                    "rel": "self",
                    "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls\/CA92d4405c9237c4ea04b56cbda88e128c.json"
                },
                {
                    "rel": "http:\/\/twilio.com\/rel\/notifications",
                    "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls\/CA92d4405c9237c4ea04b56cbda88e128c\/Notifications.json"
                },
                {
                    "rel": "http:\/\/twilio.com\/rel\/recordings",
                    "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls\/CA92d4405c9237c4ea04b56cbda88e128c\/Recordings.json"
                }
            ]
        }
    ],
    "_links": [
        {
            "rel": "self",
            "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json"
        },
        {
            "rel": "first",
            "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json?Page=0&PageSize=50"
        },
        {
            "rel": "prev",
            "href": null
        },
        {
            "rel": "next",
            "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json?Page=1&PageSize=50"
        },
        {
            "rel": "last",
            "href": "\/2010-04-01\/Accounts\/AC228b97a5fe4138be081eaff3c44180f3\/Calls.json?Page=2&PageSize=50"
        }
    ]
}

Update: I should quote this article from Mike Amundsen.
designing a hypermedia API w/ JSON
It’s probably where I got the idea.

Hackers Are Real

They are out there and they will find your shit if you don’t take security seriously.

kevburnsjr ~: sudo tail /var/log/apache2/error.log -n200
[2010-09-04 04:25:07] [77.48.95.38] File does not exist: /var/www/scripts
[2010-09-04 04:25:07] [77.48.95.38] File does not exist: /var/www/admin
[2010-09-04 04:25:08] [77.48.95.38] File does not exist: /var/www/admin
[2010-09-04 04:25:08] [77.48.95.38] File does not exist: /var/www/admin
[2010-09-04 04:25:08] [77.48.95.38] File does not exist: /var/www/db
[2010-09-04 04:25:09] [77.48.95.38] File does not exist: /var/www/dbadmin
[2010-09-04 04:25:09] [77.48.95.38] File does not exist: /var/www/myadmin
[2010-09-04 04:25:09] [77.48.95.38] File does not exist: /var/www/mysql
[2010-09-04 04:25:09] [77.48.95.38] File does not exist: /var/www/mysqladmin
[2010-09-04 04:25:10] [77.48.95.38] File does not exist: /var/www/typo3
[2010-09-04 04:25:10] [77.48.95.38] File does not exist: /var/www/phpadmin
[2010-09-04 04:25:10] [77.48.95.38] File does not exist: /var/www/phpMyAdmin
[2010-09-04 04:25:11] [77.48.95.38] File does not exist: /var/www/phpmyadmin1
[2010-09-04 04:25:11] [77.48.95.38] File does not exist: /var/www/phpmyadmin2
[2010-09-04 04:25:12] [77.48.95.38] File does not exist: /var/www/pma
[2010-09-04 04:25:12] [77.48.95.38] File does not exist: /var/www/web
[2010-09-04 04:25:12] [77.48.95.38] File does not exist: /var/www/xampp
[2010-09-04 04:25:16] [77.48.95.38] File does not exist: /var/www/php-my-admin
[2010-09-04 04:25:16] [77.48.95.38] File does not exist: /var/www/websql
[2010-09-04 04:25:17] [77.48.95.38] File does not exist: /var/www/phpMyAdmin
[2010-09-04 04:25:17] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2
[2010-09-04 04:25:17] [77.48.95.38] File does not exist: /var/www/php-my-admin
[2010-09-04 04:25:17] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.2.3
[2010-09-04 04:25:18] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.2.6
[2010-09-04 04:25:18] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.1
[2010-09-04 04:25:18] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.4
[2010-09-04 04:25:19] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.5-rc1
[2010-09-04 04:25:19] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.5-rc2
[2010-09-04 04:25:19] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.5
[2010-09-04 04:25:20] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.5-pl1
[2010-09-04 04:25:20] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.6-rc1
[2010-09-04 04:25:20] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.6-rc2
[2010-09-04 04:25:21] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.6
[2010-09-04 04:25:21] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.7
[2010-09-04 04:25:21] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.5.7-pl1
[2010-09-04 04:25:21] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-alpha
[2010-09-04 04:25:22] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-alpha2
[2010-09-04 04:25:22] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-beta1
[2010-09-04 04:25:22] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-beta2
[2010-09-04 04:25:23] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-rc1
[2010-09-04 04:25:23] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-rc2
[2010-09-04 04:25:23] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-rc3
[2010-09-04 04:25:24] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0
[2010-09-04 04:25:24] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-pl1
[2010-09-04 04:25:24] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-pl2
[2010-09-04 04:25:25] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.0-pl3
[2010-09-04 04:25:25] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.1-rc1
[2010-09-04 04:25:26] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.1-rc2
[2010-09-04 04:25:26] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.1
[2010-09-04 04:25:26] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.1-pl1
[2010-09-04 04:25:27] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.1-pl2
[2010-09-04 04:25:27] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.1-pl3
[2010-09-04 04:25:27] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.2-rc1
[2010-09-04 04:25:28] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.2-beta1
[2010-09-04 04:25:28] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.2-rc1
[2010-09-04 04:25:28] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.2
[2010-09-04 04:25:29] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.2-pl1
[2010-09-04 04:25:29] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.3
[2010-09-04 04:25:32] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.3
[2010-09-04 04:25:33] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.3-pl1
[2010-09-04 04:25:33] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.4-rc1
[2010-09-04 04:25:33] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.4-pl1
[2010-09-04 04:25:33] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.4-pl2
[2010-09-04 04:25:34] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.4-pl3
[2010-09-04 04:25:34] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.4-pl4
[2010-09-04 04:25:34] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.6.4
[2010-09-04 04:25:35] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.7.0-beta1
[2010-09-04 04:25:35] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.7.0-rc1
[2010-09-04 04:25:35] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.7.0-pl1
[2010-09-04 04:25:36] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.7.0-pl2
[2010-09-04 04:25:36] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.7.0
[2010-09-04 04:25:36] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0-beta1
[2010-09-04 04:25:37] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0-rc1
[2010-09-04 04:25:37] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0-rc2
[2010-09-04 04:25:37] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0
[2010-09-04 04:25:37] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0.1
[2010-09-04 04:25:38] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0.2
[2010-09-04 04:25:38] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0.3
[2010-09-04 04:25:38] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.0.4
[2010-09-04 04:25:39] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.1-rc1
[2010-09-04 04:25:39] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.1
[2010-09-04 04:25:39] [77.48.95.38] File does not exist: /var/www/phpMyAdmin-2.8.2
[2010-09-04 04:25:40] [77.48.95.38] File does not exist: /var/www/sqlmanager
[2010-09-04 04:25:40] [77.48.95.38] File does not exist: /var/www/mysqlmanager
[2010-09-04 04:25:40] [77.48.95.38] File does not exist: /var/www/p
[2010-09-04 04:25:41] [77.48.95.38] File does not exist: /var/www/PMA2005
[2010-09-04 04:25:41] [77.48.95.38] File does not exist: /var/www/pma2005
[2010-09-04 04:25:44] [77.48.95.38] File does not exist: /var/www/php-myadmin
[2010-09-04 04:25:44] [77.48.95.38] File does not exist: /var/www/phpmy-admin
[2010-09-04 04:25:45] [77.48.95.38] File does not exist: /var/www/webadmin
[2010-09-04 04:25:45] [77.48.95.38] File does not exist: /var/www/sqlweb
[2010-09-04 04:25:45] [77.48.95.38] File does not exist: /var/www/websql
[2010-09-04 04:25:46] [77.48.95.38] File does not exist: /var/www/webdb
[2010-09-04 04:25:46] [77.48.95.38] File does not exist: /var/www/mysqladmin
[2010-09-04 04:25:46] [77.48.95.38] File does not exist: /var/www/mysql-admin

PHP Static Instantiation – The Underscore Method

Lets make this underscore method a standard for static instantiation.

_() reads as “instance”

class Foo {
 
    public static function _() { return new self(); }
 
    public $n = 100;
 
    function bar() {
        $this->n--;
        return $this;
    }
 
    function __toString() {
        return $this->n." bottles of beer on the wall";
    }
 
}
 
echo Foo::_()->bar()->bar()->bar()->bar()->bar();
 
/* Reads
echo Foo  ^instance bar, bar, bar,  bar,   bar.
 
Output
95 bottles of beer on the wall
 
*/

Facebook Connfuse

I’m finding Facebook Connect to be very difficult to grok.

The documentation is disparate and circular.
The 1 example app I found does not function properly and its source code is not available as best I can tell.
Some tutorials contain links to Facebook SVN repositories that don’t exist anymore.
Every doc is long and obtuse.
Someone should write a good intro and organize their fucking shit.
I guess that someone is me since I’m the one complaining.

Stay tuned.

Zombies and Dubstep

Tripling up

trip-monitors

I have another 22″ Acer and an HDMI slot for it,
but I’m all out of desk space.

Do iframe pages show up in browser history?

The answer is yes and no.

This Google R&D guy gives a good rundown.
http://codinginparadise.org/weblog/2005/08/ajax-tutorial-tale-of-two-iframes-or.html

Long story short… The first IFrame src url will not be included in the browser history for static IFrames. However, all subsequent page urls within the IFrame will.

Unless… You do something tricky like insert the IFrame using JS or manipulate the src attribute in which case the behavior differs by browser and version.

What’s in a name

I’ve been using this as my source of device names for several years.
http://www.playdota.com/items

I have or used to have:

  • BUTTERFLY – A brand new (refurbished) Asus UL50Vt Notebook named after Butterfly
  • MJOLLNIR – A new Core i7 desktop named after Thor’s hammer, Mjollnir
  • DEFIANCE – A used 1U dual 3.06Ghz HP Proliant DL360 G3 webserver with 2Gb RAM running Centos 5.5 in a rack at HE in Fremont named after Hood of Defiance
  • MANTLE – A new Ubuntu VMWare guest instance running on Mjollnir with shared folders named after Mantle of Intelligence
  • IRONWOOD – A deceased Ubuntu VirtualBox VM instance named after Ironwood Branch
  • SANGE – A deceased desktop named after Sange (Sange and Yasha)
  • YASHA – A deceased desktop named after Yasha (Sange and Yasha)
  • RADIANCE – A previous company-owned laptop named after Radiance
  • TRAVS – An Asus Eee 1002HA netbook named after Boots of Travel (stolen)

Linus Torvalds thinks you are ugly.

… ugly AND STUPID (unless you use git).

Best way to store an ip in mysql

I used to use varchar(15).

But a little poking around yielded a better solution.

Turns out there’s a standard set of MySQL functions for translating an IP address to and from an integer.

ALTER TABLE `sessions` ADD `client_ip` INT NOT NULL AFTER `created_at`;
 
mysql> SELECT INET_ATON('192.168.10.50') AS ipn;
+------------+
| ipn        |
+------------+
| 3232238130 |
+------------+
 
mysql> SELECT INET_NTOA(3232238130) AS ipa;
+--------------+
| ipa          |
+--------------+
| 192.168.10.50 |
+--------------+

Here’s the algo in case you’re curious:

(192 * 2^24) + (168 * 2^16) + (10 * 2^8) + 50 = 3232238130

UI anti-pattern: Cross Column Alpha Sort

The human eye is trained to follow edges. In the case of a list such as this, the eye’s natural inclination is to move from top to bottom along the column of icons, not left to right across jagged gaps between columns. Splitting the first 4 in the sort across 4 columns is highly illegible.

 

Shame on you, Microsoft. You should know better.

Don’t write apologetic code

If your code needs explaining, you’re doing it wrong. Rewrite it.

/* Bad */
 
$tuucount=0; // total unique users
$tlcount=0;  // total lead count 
$tlrcount=0; // total lead rev
$tarcount = 0; // total aftermarket revenue
$trcount=0; // total toal
/* Better */
 
$total_unique_users = 0;
$total_lead_count = 0; 
$total_lead_revenue = 0; 
$total_aftermarket_revenue = 0;
$total = 0;

Git batch deploy

I should have done this ages ago. 1-click blast is awesome.

deploy.bat
cd c:\web\site\dev
call git push dev master
call git push stage master
call git push appsrv01 master
call git push appsrv02 master
call git push tasksrv01 master
pause

Ocean Beach

Javascript Phone Number Validation Regex

Adheres to the US North American Numbering Plan
http://en.wikipedia.org/wiki/North_American_Numbering_Plan

validate_phone("16505217791x1234") == "(650)521-7791 x1234";
validate_phone("16505217791x")     == "(650)521-7791";
validate_phone("6505217791")       == "(650)521-7791";
validate_phone("1234567890")       == null;
validate_phone("12345678901")      == "(234)567-8901";

PHP

function validate_phone($num) {
    $num = preg_replace("/[^x0-9]/",'',$num);
    $num = preg_replace("/^1/",'',$num);
    $regx = "/^([2-9][0-8][0-9])([2-9][0-9]{2})([0-9]{4})x?([0-9]{1,})?$/";
    $match = preg_match($regx, $num, $m);
    if($match) {
        return "(".$m[1].")".$m[2]."-".$m[3].($m[4]?" x".$m[4]:"");
    }
}

Javascript

function validate_phone(num) {
    num = num.replace(/[^x0-9]/g,'')
    num = num.replace(/^1/,'');
    var regx = /^([2-9][0-8][0-9])([2-9][0-9]{2})([0-9]{4})x?([0-9]{1,})?$/;
    var m = num.match(regx);
    if(m) {
        return "("+m[1]+")"+m[2]+"-"+m[3]+(m[4]!=undefined?' x'+m[4]:'');
    }
}

Lazy Eye Tracking

Anyone who does any sort of design for a living has honed an awareness of the way their attention moves across a medium. The behavior depicted in this commercial is absolutely nonsensical to anyone who does interface design.

People don’t navigate an interface by staring at the tabs and clicking blindly around the screen.

« Previous PageNext Page »