Code
Good Things pt 2: YAML
09.02.07 19:36 |
Permalink
I got acquinted with YAML during my short run-in
with Ruby on Rails (more on this
some other day, hopefully). Their official
description is:
Absolutely brilliant stuff. What it gives you, is a simple (no joke!) portable data format that's truly human-readable (indentation, baby!) and can easily be parsed into virtually any programming language's native data structure.
For example, in PHP (via the excellent Spyc library), this is how my webapp's DB settings would look like:
Then you just do
And your whole configuration is accessible in a PHP array:
YAML(tm) (rhymes with "camel") is a straightforward machine parsable data serialization format designed for human readability and interaction with scripting languages such as Perl and Python.
Absolutely brilliant stuff. What it gives you, is a simple (no joke!) portable data format that's truly human-readable (indentation, baby!) and can easily be parsed into virtually any programming language's native data structure.
For example, in PHP (via the excellent Spyc library), this is how my webapp's DB settings would look like:
database:
host: localhost
name: collective_development
username: name
password: passwd
type: mysql
charset: utf-8
Then you just do
include 'lib/spyc.php5';
$c = Spyc::YAMLLoad( 'lib/collective.yml' );
And your whole configuration is accessible in a PHP array:
$link = mysql_connect( $c['database']['host'], $c['database']['username'], $c['database']['password'] );
|
AppleScripting Keynote 3
30.01.07 22:32 |
Permalink
And in particular the add chart command. At first it
seems like a really cool thing - easily create
beautiful charts out of virtually any source. I was
excited to try this with some Webalizer output. Looks
like you have two options - the Automator Action or
Script Editor
The action produces a chart right off the bat, but the input is weird:
What is that? After trying every possible permutation of what I thought an AS 2D array would look like (some of which even compiled!) with different kinds of input sources (AS, text) I finally gave up the Automator Action option.
Using script editor seemed promising at first, but a simple add chart with all the properties produced nothing. Finally managed to find this really nice example, but it only worked with Pages. Digging in the action's bundle revealed that you're supposed to tell the slide to add the chart. OK, time to put this new-found knowledge to work:
The action produces a chart right off the bat, but the input is weird:
Input: (Anything) Two dimensional array of chart labels and data.
What is that? After trying every possible permutation of what I thought an AS 2D array would look like (some of which even compiled!) with different kinds of input sources (AS, text) I finally gave up the Automator Action option.
Using script editor seemed promising at first, but a simple add chart with all the properties produced nothing. Finally managed to find this really nice example, but it only worked with Pages. Digging in the action's bundle revealed that you're supposed to tell the slide to add the chart. OK, time to put this new-found knowledge to work:
tell application "Keynote"
set theData to {{1, 2, 3}, {4, 5, 6}}
set theSlide to (slide 1) of first slideshow
tell theSlide
add chart row names {"Dec", "Jan"} column names {"Machines", "Visits", "Hits"} ¬
data theData type "vertical_bar_3d" group by "column"
end tell
end tell
Tadaa! Sweet. Now all that remains is to add the
webalizer parsing code...
Building universal binaries
24.01.07 15:23 |
Permalink
So far I've had the best success with defining the
following before configure:
Sometimes this lead to:
in which case passing --disable-dependency-tracking to configure seemed to help.
> export LDFLAGS="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386"
> export CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
Sometimes this lead to:
gcc: -E, -S, -save-temps and -M options are not allowed with multiple -arch flags
in which case passing --disable-dependency-tracking to configure seemed to help.
Remembering the QTVR Pan Angle
15.01.07 15:51 |
Permalink
This only works with Safari:
... where getAngle() just uses a cookie:
... which is set with setAngle () like thus:
Finally, the hotspots are wired to go through this function:
QT_WriteOBJECT_XHTML (
'myVRmovie.mov', 800, 600, '',
'controller', 'true',
'id', 'myvrmovie',
'cache', 'true',
'pan', getAngle ());
... where getAngle() just uses a cookie:
function getAngle ()
{
return document.cookie.split ('=')[1];
}
... which is set with setAngle () like thus:
function setAngle ()
{
document.cookie = 'angle=' + Math.floor (document.myvrmovie.GetPanAngle ());
}
Finally, the hotspots are wired to go through this function:
function openPage (url)
{
setAngle ();
window.location (url);
}
Google search to RW (for lazy bums)
30.12.06 11:06 |
Permalink
A really lazy way to add search to
your RW page:
I think you could actually cook up something nice with a Google developer account and XMLHttpRequest...
<div id="gsearch">
<form action="http://www.google.com/search">
<input type="text" name="q"/>
<input type="hidden" name="hl" value="en"/>
<input type="hidden" name="sitesearch" value="http://homepage.mac.com/filipp"/>
<input type="submit" value="Search with Google"/>
</form>
</div>
I think you could actually cook up something nice with a Google developer account and XMLHttpRequest...
Using script.aculo.us with XSLT
28.12.06 20:10 |
Permalink
When using script.aculo.us with XSLT (XML to XHTML),
don't include like this:
This is because scriptaculous.js uses document.write () to include the components and that' apparently verboten when using XSL. The symptoms are weird too:
* Safari will acts as if all was OK, except Ajax.Request won't work
* Firefox/Gecko-based browsers will just hang on loading the document (an invinite "Reading") and you'll notice some class name related errors in the JS log.
In other words, the correct way to include, is by all the files separately and in the right order:
<script src="javascripts/scriptaculous.js" type="text/javascript">
This is because scriptaculous.js uses document.write () to include the components and that' apparently verboten when using XSL. The symptoms are weird too:
* Safari will acts as if all was OK, except Ajax.Request won't work
* Firefox/Gecko-based browsers will just hang on loading the document (an invinite "Reading") and you'll notice some class name related errors in the JS log.
In other words, the correct way to include, is by all the files separately and in the right order:
<script src="javascripts/effects.js" type="text/javascript"></script>
<script src="javascripts/builder.js" type="text/javascript"></script>
<script src="javascripts/dragdrop.js" type="text/javascript"></script>
...
Happy Holidays
23.12.06 00:28 |
Permalink
The past few days have been weird. Got a really great
idea for writing a hwmond replacement called
servermond that would allow you to use at
least some of the functionality of Server Monitor on
any hardware. So far so not good. Getting the SSL
decryption to work to reverse-engineer the Server
Monitor protocol has been unsuccessful due to, quite
frankly, lack of tools. ssldump won't compile
straight, tried the macports version but that won't
run. Finally managed to install ettercap (which seems
like an awesome piece of engineering) but it hasn't
helped me yet... This made me think why there's still
no Mac native front end to any of these powerful free
programs.
Plus, the cigarette addiction's kicking in again. I've been off it for about a year now but the past 5 days I've felt like I quit last weekend or something... Weird.
But to not feel totally unproductive, I've decided to roll out the first public version of Itch - my little Python script for XChat Aqua. Named thus not only because there were a few itches that I wanted to scratch in XChat, but also because it's my first ever Python script (and itchi means "one" in Japanese). Itch features:
There's a few other features that I want to add in there, but the existing ones were "stable" enough to release it into the general public. I consider it my little Christmas present to the Mac IRC population. ;-)
Plus, the cigarette addiction's kicking in again. I've been off it for about a year now but the past 5 days I've felt like I quit last weekend or something... Weird.
But to not feel totally unproductive, I've decided to roll out the first public version of Itch - my little Python script for XChat Aqua. Named thus not only because there were a few itches that I wanted to scratch in XChat, but also because it's my first ever Python script (and itchi means "one" in Japanese). Itch features:
- Simple iTunes and QuickTime Player announcement. /np send nick will try and dcc the current tune to nick.
- /away management (hitting /way toggles you away with a timer) with logging
- Hardware (ioreg) and software (system_profiler) monitoring and specs. Just try /hw and /sp for the possible switches. These are not echoed to the channel.
- iTalk. This was actually pea's brilliant idea. /isay will convert anything you say into "i-talk". iFor iExample iLike iThis.
- Finally, /day will show you what's happened today in history (data from /usr/share/calendar/calendar.*)
There's a few other features that I want to add in there, but the existing ones were "stable" enough to release it into the general public. I consider it my little Christmas present to the Mac IRC population. ;-)
Modulo
19.12.06 11:09 |
Permalink
This one is easy, but so important but used so rarely
that you have time to forget it. How to build a table
programmatically with a certain number of columns,
with only one while - loop:
<table style="border: 1px solid black">
$i = 0;
$col = 4;
$val = 20;
$table = null;
while ($i < $val)
{
$i++;
$table .= '<tr>' + ($i % $col == 0) ? "<td>$i</td></tr>" : "<td>$i</td>";
}
print ($table);
?>
</table>
Variable Scopes
18.12.06 14:44 |
Permalink
value = 0
def setValue():
value = 1
setValue ()
print value
What's that gonna print? That's right - 0. Must use global instead:
value = 0
def setValue():
global value
value = 1
setValue ()
print value
It's actually the exact same with PHP:
$value = 0;
function setValue () { $value = 1; }
setValue ();
print ("value: " . $value);
My brain tells me that if something's been defined previously, then we should be referencing that thing instead. It's not like I'm explicitly using different namespaces in - and outside my function. Like with JavaScript.
Two New Scripts
17.12.06 02:00 |
Permalink
useradd.sh and freplace.sh. The first is a
simple CLI utility for creating users and the
second finds and replaces files.
-a makes new user an administrator.
Replaces target in directory indir with replacement. Has a few extra features as well. Both are still pretty basic, but serve a purpose and I'll probably keep updating them. Handle with care.
> ./useradd.sh
Usage: sudo useradd.sh [-u uid] [-g group] [-a] [-c] [-d home] [-s shell] [-rn realname] name
-a makes new user an administrator.
> ./freplace.sh
Usage: freplace.sh [-sb] [-o owner:group] -d indir target replacement
Replaces target in directory indir with replacement. Has a few extra features as well. Both are still pretty basic, but serve a purpose and I'll probably keep updating them. Handle with care.
Universal Hello World
12.12.06 13:21 |
Permalink
I've been struggling with building universal (fat)
binaries on OS X for quite a while now. Finally
decided to sit down and figure this out. In a
situation with many variables, it's often good to
stop and try to "crystallise" the problem at hand.
What better way to do this than with a Hello World -
if that won't compile and link, then why should
anything else, right?
Then we compile:
So far so good. Now let's see if we can make a fat binary out of this sucker:
Hmm, that wasn't so bad. I guess here is where the "fat" in "fat binary" comes from:
Well, that turned out to be a useless experiment. At least I know that my cross-compiling support works now...
#include <stdio.h>
int main (void)
{
printf ("Hello, world!\n");
return 0;
}
Then we compile:
> gcc hellow.c -o hellow
> ./hellow
Hello, world!
> file hellow
hellow: Mach-O executable ppc
So far so good. Now let's see if we can make a fat binary out of this sucker:
> gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386 -arch ppc64 hellow.c -o hellow-fat
> ./hellow-fat
Hello, world!
> file hellow-fat
hellow-fat: Mach-O fat file with 3 architectures
hellow-fat (for architecture ppc): Mach-O executable ppc
hellow-fat (for architecture i386): Mach-O executable i386
hellow-fat (for architecture ppc64): Mach-O 64-bit executable ppc64
Hmm, that wasn't so bad. I guess here is where the "fat" in "fat binary" comes from:
> ls -lhS hellow*
-rwxr-xr-x 1 filipp filipp 44K Dec 12 13:45 hellow-fat
-rwxr-xr-x 1 filipp filipp 13K Dec 12 13:46 hellow
-rw-r--r-- 1 filipp filipp 80B Dec 12 13:21 hellow.c
Well, that turned out to be a useless experiment. At least I know that my cross-compiling support works now...
BBEdit Session Restore
09.12.06 01:11 |
Permalink
BBEdit's probably my most important tool. Even though
an editor is such a basic thing that it's almost kind
of silly to be attached to one, you just get used to
it over time and it's nice to constantly be finding
new features and ways to use a tool.
I can easily have upwards of 20 documents open simultaneously - sometimes part of the same project, mostly not. This makes you weary of actually closing the app because what if you want to pick up exactly where you left off? Well, luckily, like so many things in life, this problem too can be solved with a little bit of AppleScript:
Just run that after and before every session you want to restore. If you have documents open, it'll save them, if not, open the ones you had open the last time. It's very crude but gets the job done for now. Naturally they don't work with Trasmit links etc because those are just temporarily open.
Properties are wonderful in AS because they are reinitialised only when the script is compiled. That makes them perfect for any kind of "temporary" persistent storage.
I can easily have upwards of 20 documents open simultaneously - sometimes part of the same project, mostly not. This makes you weary of actually closing the app because what if you want to pick up exactly where you left off? Well, luckily, like so many things in life, this problem too can be solved with a little bit of AppleScript:
property theDocuments : {}
tell application "BBEdit"
if (count of document) is greater than 1 then
set theDocuments to file of every document as list
else
open theDocuments
end if
end tell
Just run that after and before every session you want to restore. If you have documents open, it'll save them, if not, open the ones you had open the last time. It's very crude but gets the job done for now. Naturally they don't work with Trasmit links etc because those are just temporarily open.
Properties are wonderful in AS because they are reinitialised only when the script is compiled. That makes them perfect for any kind of "temporary" persistent storage.
PHP's file_get_contents () and cookies
06.12.06 01:16 |
Permalink
Sending cookies - you can do it with
file_get_contents () - just look at the stream
functions' constants (the context parameter). But I
found out it's much easier using the curl plugin
(which isn't always available, btw, but neither is
file_get_contents ()):
It's that simple. An awesome tool for creating all kinds of site parsers.
$c = curl_init ($url);
curl_setopt ($c, CURLOPT_VERBOSE, 1); // For testing
curl_setopt ($c, CURLOPT_COOKIE, "variable=value");
curl_exec ($c);
It's that simple. An awesome tool for creating all kinds of site parsers.
Something New Every Day...
01.12.06 20:32 |
Permalink
JavaScript - Associative Arrays
Considered Harmful
The reason I stumbled across this was that Apple's QuickTime Embedding JS has this problem. The symptoms look crazy - you'll have other JS code inside your embed tag. This happened to me when using Prototype. The fix is easy - just replace "new Array ();" on line 165 with "new Object ();"
The reason I stumbled across this was that Apple's QuickTime Embedding JS has this problem. The symptoms look crazy - you'll have other JS code inside your embed tag. This happened to me when using Prototype. The fix is easy - just replace "new Array ();" on line 165 with "new Object ();"
AppleScript Tidbits
11.11.06 15:23 |
Permalink
AppleScript URL protocol support
Getting the home directory:
Getting and setting the clipboard:
Encoding URLs
Personally, I think you're best off just piping it through PHP:
Bu there's also some info on Apple's website.
How does ScriptEditor know which app is scriptable?
By looking for the NSAppleScriptEnabled key in an application bundle's Info.plist
Getting the home directory:
set theHomeDir to the POSIX path of home
directory of (system info)
Getting and setting the clipboard:
set whatever to the clipboard
set the clipboard to "whatever"
Encoding URLs
Personally, I think you're best off just piping it through PHP:
do shell script "echo myurl | /usr/bin/php -r
\"urlencode(fgets(STDIN));\""
Bu there's also some info on Apple's website.
How does ScriptEditor know which app is scriptable?
By looking for the NSAppleScriptEnabled key in an application bundle's Info.plist
Automate Out-of-Office Reply Toggling
04.11.06 16:43 |
Permalink
This one actually made it to the site:
If there's one thing that computers are better at than humans, it's remembering things. Take for example the typical Out Of Office email reply - you go on vacation and set a rule in Mail.app to automatically respond of your absence to any email with a certain criteria. Then you come back and a day or two later remember to turn the notification back off again.
Well if You use iCal, your Mac most likely already knows when you're leaving and coming back so let's simply tie that information with Mail.app. Here's how:
Open Automator and from the Automator library add a "Run AppleScript" step.
Replace the code with the following, putting in the name of your Out of Office rule:
3) File > Save As Plug-In, give it a name (like "Toggle Out-Of-Office"), Plug-in for: iCal Alarm. Save.
iCal will open with a new event which you can simply delete. Then just create events on the start and end dates of your vacation (if you haven't already) and set our newly created script as the alarm (which you'll find in the alarm "Open file" dropdown menu).
The reply will now activate when yo leave and deactivate when you return. Just make sure your rule is Inactive before you go. :)
If there's one thing that computers are better at than humans, it's remembering things. Take for example the typical Out Of Office email reply - you go on vacation and set a rule in Mail.app to automatically respond of your absence to any email with a certain criteria. Then you come back and a day or two later remember to turn the notification back off again.
Well if You use iCal, your Mac most likely already knows when you're leaving and coming back so let's simply tie that information with Mail.app. Here's how:
Open Automator and from the Automator library add a "Run AppleScript" step.
Replace the code with the following, putting in the name of your Out of Office rule:
set myRule to "Name of my Out of Office rule"
tell application "Mail"
set enabled of rule myRule to not enabled of rule myRule
end tell
3) File > Save As Plug-In, give it a name (like "Toggle Out-Of-Office"), Plug-in for: iCal Alarm. Save.
iCal will open with a new event which you can simply delete. Then just create events on the start and end dates of your vacation (if you haven't already) and set our newly created script as the alarm (which you'll find in the alarm "Open file" dropdown menu).
The reply will now activate when yo leave and deactivate when you return. Just make sure your rule is Inactive before you go. :)
Flannel 1.0
03.11.06 12:02 |
Permalink
This isn't much of a release announcement since it's
not even available for download yet, but Flannel's
demo page is finally up now.
This is all part of a not-so-elaborate scheme to get Flannel out there in the hands of the users. Not knowing the current state of true WYSIWYG publishers out there, I still think it could be very useful for people who just want their stuff online quickly and easily.
There's still alot of work to be done and the version that's running the demo's not the one I had in mind for the 1.0 release, but still...
This is all part of a not-so-elaborate scheme to get Flannel out there in the hands of the users. Not knowing the current state of true WYSIWYG publishers out there, I still think it could be very useful for people who just want their stuff online quickly and easily.
There's still alot of work to be done and the version that's running the demo's not the one I had in mind for the 1.0 release, but still...
Search & Replace with nano!
17.09.06 21:19 |
Permalink
A Random Quote For Site Slogan
09.09.06 12:28 |
Permalink
window.onload = function() {
var quotes = [
"I wanna be a racecar passenger.",
"Alright, you're a cook - can you farm?"];
var i = Math.floor(Math.random()*quotes.length);
document.getElementsByTagName('h2')[0].innerHTML = '"' + quotes[i] + '"';
}
Don't forget to add blank lines before and after the JS!
A Teacher's Pet
08.09.06 11:04 |
Permalink
Punk made it to the Staff Favorites list. It will
also be included on the cover CD of Univers Mac, a French Mac
Magazine! Thanks!
sortUsingSelector
05.09.06 10:09 |
Permalink
After spending 4 days with the problem of sorting an
array of NSDictionaries (!!) using every kind of
method imaginable, I finally found the solution:
You can't use sortUsingSelector because that operates on the object in the array (in this case an NSDictionary). That explains the countless ("[CFDictionary compareScores] selector not recognized etc...") I was getting. Phew
So use sortUsingFunction instead. And as the guys at cocoadev so eloquently showed:
Where "context" is the NSDictionary key you want to sort by.
You can't use sortUsingSelector because that operates on the object in the array (in this case an NSDictionary). That explains the countless ("[CFDictionary compareScores] selector not recognized etc...") I was getting. Phew
So use sortUsingFunction instead. And as the guys at cocoadev so eloquently showed:
int someSort (id obj1, id obj2, void *context)
{
return [[(NSDictionary *)obj1 objectForKey:(NSString *)context] compare:[(NSDictionary *)obj2 objectForKey:(NSString *)context]];
}
Where "context" is the NSDictionary key you want to sort by.
Getting Stuff Into MySQL
14.08.06 19:29 |
Permalink
Forget clumsy scripts to load SQL files into MySQL.
Here's how it worked for me:
check your php.ini "upload_max_filesize"
Strangely, MySQL 4.x doesn't like the "ENCLOSED BY" statement (it works, but will only import the first row)
check your php.ini "upload_max_filesize"
$newFile = move_uploaded file ($FILES['yourfile']['tmp_name'], '/var/tmp/yourfile');
$sql = "LOAD DATA INFILE '$newFile'
INTO TABLE db.table
FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\r'";
Strangely, MySQL 4.x doesn't like the "ENCLOSED BY" statement (it works, but will only import the first row)
PHP weirdness
01.06.06 07:50 |
Permalink
Symbian madness
26.04.06 07:51 |
Permalink
More On Spelling
23.03.06 14:00 |
Permalink
phpBB privmsgs to PunBB
19.02.06 14:01 |
Permalink
DELETE FROM punmessages;
INSERT INTO punmessages (subject,sender_id, sender, owner, posted, message, sender_ip,smileys,showed)
(SELECT privmsgs_subject, privmsgs_from_userid,
(SELECT username FROM phpbb_users WHERE phpbb_users.user_id = privmsgs_from_userid),
privmsgs_to_userid, privmsgs_date, privmsgs_text, INET_NTOA(CONV(privmsgs_ip,16,10)), privmsgs_enable_smilies,
(SELECT user_new_privmsg FROM phpbb_users WHERE phpbb_users.user_id = privmsgs_from_userid)
FROM phpbb_privmsgs, phpbb_privmsgs_text
WHERE privmsgs_id = privmsgs_text_id);