Posted: Feb 28, 2009 by Billy GrayTagged palm, webos
I have admittedly ragged on Palm a bit of late, but I just watched their webcast on Developing Application for webOS, and I had but one thought:
“Ssssssssssssnap!”
Seriously, though. If you’re doing iPhone development, sure you get the Cocoa framework and access to OpenGL and all that, but you don’t get such open access to the system and other applications (with Sync!) like you will with webOS. At least, that’s my hunch, I guess time will tell. But just the basic layout of the high-level architecture warms my heart.
You know what else is awesome? The API has “stages” and “scenes”! That rocks.
Jury is still out as to whether you can run processor intensive games in this platform, but honestly we’re not game programmers, and this does seem to uniquely enable easy development.
On a total tangent, I went to the Jelly NYC event at my workspace today and mentioned that next week we’ll be starting the beta for Strip on the iPhone (sign up for the mailing list over here, or just e-mail us). Of the 15 or so people there, one of them was a hard core, long-time user of Strip, and is still toting his Palm around waiting for a way to migrate to his iPhone. Can’t wait. Stay tuned!
How many of you characters have read Smashing the Stack for Fun and Profit by Aleph1? Just curious. Also, if you did, did you make it all the way to the end?
Posted: Feb 20, 2009 by Billy GrayTagged strip, git, pr0n
We just merged our development branch for Strip into the master branch. Now, granted some of this is XIB files, icon images, and included openssl headers. Nonetheless:
We’re going to push out a couple of changes to the Tempo API tonight at 10pm EST. Last night we found a small bug that prompted us to address a pair of issues, and update our documentation:
A type attribute will be required for multi-value params in context search:
The /entries/search end-point allows you to post an XML document that we call a context. It’s a lot like the Tempo reporting interface, it allows you to specify a set of parameters and it will return the corresponding entries if the request is well-formed.
Certain parameters that you can send up in a context document are multi-valued and must be presented within a type=“array” set. These are tags, project-ids, user-ids, and exclude-tags. Here’s an example:
This has actually always been the case, but our documentation did not reflect this.
The interval parameter will be supported in context search:
As shown the example above, you can use an interval shortcut string to avoid having to specify start-date and end-date. The list of currently available intervals is:
today
yesterday
thisweek
lastweek
last7days
thismonth
lastmonth
thisquarter
lastquarter
thisyear
lastyear
alltime
XML output includes type attribute hints:
For all non-string data in output from our XMLAPI, a type attribute has been re-introduced. This shouldn’t break anybody’s compatibility with the API, as we haven’t had any attributes present in the past for you to look up, but please get in touch if you think this will be a problem for you. This is an example of what that looks like:
As I wrote last week, I’m really interested in any piece of reading where artists discuss methods of process, or simply getting around to doing their work. Most of the challenge is actually sitting down and setting about doing what you intend without knowing how it’s going to turn out necessarily, and being okay with that.
That’s not quite how it works in programming, but sometimes it is! Sometimes here at Zetetic we set out to find a way to do something without knowing what we’ll find. In fact, new challenges and new ideas always push you in this direction, so it happens pretty often, and like sitting down to create something in the context of art (wherein you see yourself, maybe, as an “artist” or a “poet”), you have to be okay with not knowing exactly how it’s going to turn out, and trusting yourself to make decisions as you create.
There’s an article on the 37Signals blog today, titled, “The moment of truth is a real audience,” and here you find where the lines of art and entertainment cross-over in ways that are challenging to deal with for the artist, but it’s very straight forward for someone who sees himself as an entertainer, a producer, or a manufacturer of software. The article quotes playwright Matt Hart:
[Fellow playwright George S.] Kaufman did not hold with the theory or the practice of having run-throughs for his friends or friends of the cast, or even for people whose judgment he respected and trusted. He held firmly to the idea that no one person or collection of persons, no matter how wise in the ways of the theatre, could ever be as sound in their reactions as a regulation audience that had planked down their money at the box-office window, and in the main I think he was correct.
For the artist, acceptance and understanding of his work is not always in the bag, and the understandable fear of a lack of understanding or acceptance can be debilitating (whether the artist has ever gone out on that limb or not!) For the programmer, I think things are a lot simpler: you made something that does what you intended it to do, or you didn’t. It’s useful to people, or it’s not. But it’s still pretty disappointing when your software fails to gain wide appeal, when it doesn’t quite make the cut of your intended audience.
So, I think the trial by fire of a paying audience is a good thing. Even if you don’t get the acceptance and the understanding you hoped for. Maybe people aren’t ready for your cool idea, or maybe you need to build on your means of expression. YET, I think it’s crucial here to understand that with art, you can perfect your means and reach all your goals and never get critical acceptance, and you can’t expect to. I wonder if you can’t expect to with software either?
Speaking of trial-by-fire, great progress continues with Strip for the iPhone and we should be ready to beta the application very soon. Have you signed up for the beta mailing list? Scroll to the bottom of this page if you haven’t, and sign up! We’ll announce details on beta participation there within the next couple of weeks.
Palm appears to be making a real effort to re-establish the developer base for their platform. While I’m a skeptic, webOS is a pretty cool idea for an application development platform. Remains to be seen how well it works, and if the trade-off for ease of development is the capability of applications. I’d bet good money that it will be a lot easier to develop applications for webOS than it is for iPhone OS, but I’d also bet that you won’t be able to pull off some of the low-level graphics processing that enables cool games and animations.
The first chapter of an O’Reilly book on developing for the OS is up on the developer site, and it’s being written by the lead architect. Wouldn’t it be great if the API and documentation were up? I’m guessing that means it’s still under heavy revision.
I needed a bit of SQL to gin up a series of sequential dates in Oracle that I could use in generating data for flash charts in APEX. It’s important to have a solid series of dates that you can LEFT OUTER JOIN against so that NULL values correspond to one of your series points, keeping all the data properly aligned.
In looking around for some good examples I found some way more complex date series tricks
, but didn’t see any article on the simple basics of doing a series of dates between a start and end date. Here’s what I found along the way:
-- notes for generating date sequences in oracle
--
-- gleaned from a pretty interesting article by Indrajit Agasti on generating
-- various series of working (non-weekend) days:
-- http://www.dba-oracle.com/t_test_data_date_generation_sql.htm
--
-- i'm sure this old hat for many oracle devs but i didn't see it out there
-- anywhere so i figured a quick ref of notes i took in the process might
-- be useful to somebody else
-- to knock a string into a date object:
SELECT TO_DATE('01-JUN-2008') FROM DUAL;
-- getting an integer difference between two dates:
SELECT TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008') FROM DUAL;
-- generating a sequential series using dim (this is odd, admittedly)
-- 0, 1, 2 ... 9 (n - 1)
SELECT dim FROM DUAL
MODEL
DIMENSION BY (0 dim) MEASURES (0 rnum)
RULES ITERATE (10) (
rnum [ITERATION_NUMBER] = ITERATION_NUMBER
);
-- easier, returns 1,1,1... (10 rows), so use rownum to get increasing integers
SELECT ROWNUM FROM (
SELECT 1 FROM DUAL
CONNECT BY LEVEL <= 10
);
-- drop in our dates
-- returns 1, 2, 3 ... 31
SELECT ROWNUM FROM (
SELECT 1 FROM DUAL
CONNECT BY LEVEL <= (TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008'))
);
-- full date set then: (may 1st, to may 31st)
SELECT TO_DATE('01-MAY-2008') + ROWNUM - 1
FROM (
SELECT ROWNUM FROM (
SELECT 1 FROM DUAL
CONNECT BY LEVEL <= (TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008'))
)
);
-- being inclusive of the end-date (june 1st)
SELECT ROWNUM FROM (
SELECT 1 FROM DUAL
CONNECT BY LEVEL <= (TO_DATE('01-JUN-2008') - TO_DATE('01-MAY-2008') + 1)
)
I’ve been a big fan of jQuery for some time now, and one of my favorite plug-ins is Ryan Cramer’s asmSelect, which is a really cool alternative implementation of a multiple select control. There’s no swing tables, there’s no explaining to users how they need to hold down control (or command for mac users) while they click their desired options. There’s just a nice manageable list, to which you add selections using a drop down. There’s a nice example here, if you’re unfamiliar with this interface.
In any event, some of our clients were not really digging the Shuttle control available in Oracle’s Application Express. “Shuttle” is really just a pair of swing tables. So I figured, “why not set those back to normal select[multiple] elements and run the asmSelect plugin?” However, it wasn’t that easy, so I’ve written up how to get it going. I’m working in APEX 3.1.2, if you decide to follow along.
First you need to make sure you’ve got the select element set to multiple in the interface:
Next, add the needed jQuery libs to your application. There are a number of ways to do this, but since I’m not going for anything fancy, I went with the latest version of jQuery (1.3), the latest version of the asmSelect plugin, the included CSS, and avoiding any jQuery UI animation options:
jquery-1.3.1.min.js
jquery.asmselect.js
jquery.asmselect.css
jquery.noconflict.js
That last one is actually a quick little file I threw together to allow for jquery to be compatible with apex’s built-in use of prototype:
/* jquery no-conflict script, sets $() function to $j() */
var $j = jQuery.noConflict();
Not much to it, pretty standard.
I attached them to the application itself (Shared Components → Static Files → Create, then select your app for the association). Once they are uploaded, you need to link them in from your page template. Head over to Shared Components → Templates and select your default page template for editing. You can jam this into the head section of the document template:
These statements will include the javascript and css files we uploaded into our app as static files. Below these, in the header template (or in the html header area of a specific page), we can add a script block and some code to activate the asmSelect plugin on every select[multiple] on our page:
<script type="text/javascript">
$j(document).ready(function() {
// wire up the select multiples to be asmSelects
$j("select[multiple]").asmSelect({ });
});
</script>
At this point, if you reload your application page, having saved your changes and such and there are no errors in the setup, you’ll see:
the original select show up and quickly disappear (asmSelect hides it)
the new asmSelect element
However, if you attempt to submit your form, it will explode on you. You’ll get a pretty heinous 404 error message saying that the page couldn’t be found. What’s happening here?
Not Found
The requested URL /pls/apex/wwv_flow.accept was not found on this server.
Oracle-Application-Server-10g/10.1.3.4.0 Oracle-HTTP-Server Server at apex.example.com Port 80
APEX is at heart a set of complex stored procedures made accessible over the web via mod_plsql running in Apache. If you’ve ever written a stored procedure for mod_plsql (htp.prn and all that), you’ve probably run into this problem before: if you send any params that the procedure doesn’t expect, mod_plsql will bomb out with a 404 error.
What’s happening to us here is that by using asmSelect we’ve added a parameter that’s not being expected by APEX. Every form element on the apex page matches an ITEM that you created on the page (like P1_PRODUCT_TYPE above). In this case, asmSelect hides the element represented by P1_PRODUCT_TYPE and drops select#asmSelect0 right next to it in the DOM.
So what do we do?
What can be added to the DOM can be taken away!
I tried faking out APEX by creating a corresponding page-level item with the same name and that didn’t work, so I just moved on to the next obvious thing: remove the asmSelect element when the form’s submit element fires. Here’s how I first tried it:
<script type="text/javascript">
$j(document).ready(function() {
// wire up the select multiples to be asmSelects
$j("select[multiple]").asmSelect({ });
$j("#wwvFormFlow").submit(function() {
$j(".asmSelect").remove();
});
});
</script>
That didn’t quite work out, because APEX already has its own ideas about the form’s submit event. And honestly, I don’t really want to mess with APEX, I just want to work around it. So I decided on another trick we worked out some time ago, intercepting the submit event and then letting APEX do its thing afterward:
<script type="text/javascript">
$j(document).ready(function() {
// wire up the select multiples to be asmSelects
$j("select[multiple]").asmSelect({ });
// subordinate the submit function in apex so we can supplant it
function submitOverride(event) {
// remove the asmSelects from the DOM so they don't mess up submitted params
$j(".asmSelect").remove();
// execute the original submit
this._submit();
}
document.wwv_flow._submit = document.wwv_flow.submit;
document.wwv_flow.submit = submitOverride;
});
</script>
This really did the trick, removing the asmSelect right after submit fires, sending up the correct form elements. And since asmSelect manages the original selection list as your are making changes, the selected items are preserved.
For one last bit of finesse, hide the original select element (in our case the item P1_PRODUCT_TYPE) on page load by setting style="display:none;" on the element, which makes your page load a bit smoother:
Lately my subway-reading materials seem to broadly spin around what it means to be an artist, and processes, and what’s involved in actually setting about the doing of your work, the making of your art. I crunched through Haruki Murakami’s memoir What I Talk About When I Talk About Running so quickly that I think I need to read it again (I’m looking forward to it, and I rarely re-read books), and I’ve since moved on to Art & Fear by David Bayles and Ted Orland. This is a particularly interesting subject for me as a song-writer and a programmer, although for really different (and probably obvious) reasons that I’m not going to go into right now, save to pull some choice quotes that I’ve found to be really profound.
This one is from Art & Fear:
Vision & Execution
More often, though, fears rise in those entirely appropriate (and frequently recurring) moments when vision races ahead of execution. Consider the story of the young student – well, David Bayles, to be exact – who began piano studies with a Master. After a few months’ practice, David lamented to his teacher, “But I can hear the music so much better in my head than I can get out of my fingers.”
To which the Master replied, “What makes you think that ever changes?”
That’s why they’re called Masters. When he raised David’s discovery from an expression of self-doubt to a simple observation of reality, uncertainty became an asset. Lessn for the day: vision is always ahead of execution — and it should be. Vision, Uncertainty, and Knowledge of Materials are inevitabilities that all artists must acknowledge and learn from: vision is always ahead of execution, knowledge of materials is your contact with reality, and uncertainty is a virtue.
We’ve mentioned in the past that we’re no longer supporting or developing Strip on the PalmOS platform. Even so, people still ask about looking at the code and making updates. Strip for Palm OS is free and open-source software, so we’ve pushed the code up to Github to facilitate any further development others may wish to do. It’s the beauty of open source – feel free to fork it, hack it, send pull requests, or release your own version. Fair warning – the code was written a long time ago on an ancient (in relative terms) platform so it might leave something to desired if you’re used to more modern toolkits!
It’s a been a little while since I’ve given any kind of update on our progress with STRIP for the iPhone platform. We’ve been hammering away at our data model and at this point I think we’ve arrived at a fairly stable first implementation and work-flow for the app. After changing it what seems a billion times, I think we’ve got it. For now.
There are still some tweaks we need to make before we start the beta of the initial version. Also of note: wireless backup and sync won’t be available in the initial version. It will be done, oh yes, and it will be done well, but not in time for the first release. We want to at least get this out there for Strip fans to test it out and make sure we’re going in the right direction here. This feature is really important to us, as it’s one of the features that really made the previous versions of Strip stand out, and we’re committed to its implementation.
We’ve put together a mailing list just for Strip (low volume, announcement only) for those of you who want to be alerted directly when we’re ready to do the beta. Sign up for it over on the Strip page.
We still need to put together an export tool for old Palm OS Strip users who want to migrate to various systems, and a means to import that export into the iPhone version. We intend to have that piece in place by the end of the beta, before we go live, but I can’t commit to a time-frame just yet.
Thanks again for your patience as we work hard to get this right.
It’s been in the news for a few days: two of the MySQL execs, Martin Mickos and Monty Widenus, are leaving Sun Microsystems, Sun having bought and absorbed MySQL AB.
I’ve always been a Sun fan (Solaris FTW), but it’s a well-known joke that being bought-out by Sun is the kiss of death. So what happens to MySQL now, and what happens in the open-source database space? Drizzle, an open-source and derivative project led by Brian Aker, doesn’t seem to have clearly defined its space (“the cloud?”), with people wondering if it’s really just a SQLite competitor (alternative might be a better turn of phrase because it’s got a long way to go before it could “compete” with SQLite). Speculation aside, what is known is that it drops many of the features that make MySQL a full-featured relational database.
Ladies and gentlemen, I think that we have a winner, the elephant in the room: PostgreSQL. Somebody’s gotta say it. Sorry to gloat. PostgreSQL is and has been “the most advanced open-source database,” long before these MySQL upstarts came along.
In the end, MySQL was never a completely open project. MySQL AB offered a GPL version but only included code that they owned the copyright to. Contributing developers wouldn’t see changes included in the core unless they were rewritten by MySQL AB or donated (read sign over their IP) to the company. It’s pretty heinous to tout such a model as an open-source success story, and it looks like the opposite is now true: MySQL is clearly floundering.
On the 37Signals blog today there was some talk about Axl Rose and Frank Sinatra, two musicians I love to gab about:
Sinatra’s one take style produced classics. Axl’s dithering produced a pile of mush. We can all learn something from that. It’s easy to fall into a trap of nitpicking over things that don’t really matter. Instead, focus on the essence of what you’re doing. Press record, get it done, and get it out there.
Lately I’ve taken our first takes on demos for the new band, or just scrapping them and coming back to it when the time is right. Sometimes that means a different approach, sometimes a better room sound. I almost always go for a first take on a guitar solo, if I don’t double it with another one for maximum shred \m/.
With that in mind, an update on our progress with Strip should be forthcoming.
When we set out to build Tempo time tracking, we knew it would be important get out of the user’s way when they need to entering time. The way we saw it, there were three problems:
Staying productive while busy is challenging – we often change tasks (and therefore the client we are billing changes).
It can be difficult to accurately remember how much time we spend on individually tasks.
It can be a real work-flow interruption to load up a website and type information into a form.
That’s why we created Tempo’s command line text interface. For instance, I can simply type in what I am working on next, and Tempo will time me. When I need to change tasks I just type in what I’m working on next and the last timer stops:
doing a screenshare demo #bigcorp @support
Similarly I can log time via this command line, not just start timers:
But if you don’t already have Tempo loaded in a browser then starting things up to enter your time can be an interruption in the flow, a disturbance in the force. Thankfully, text entry can come from anywhere! So we created various alternate ways to quickly enter time with minimal impact:
Bookmarklet brings up a small window in your browser
This text syntax has been a big win for us and our customers. While we’ve seen a few services out there implementing similar features, we’re pretty much the only game in town that takes it this far.
We’ve found that when people first try Tempo, the convenience of the command line and all these points of entry go unseen for a little while. We have a core group of customers that love these features, but many folks who might use them don’t know they are there until we show them and explain how it works. Then a light bulb goes off and we’ve won some new fans.
Obviously, that means we’ve got some work to do on the UI. The good news is that the awesome team at nGen Works is working with us to help us improve the ease of use and aesthetics of the application.
Meanwhile we want to expand what Tempo’s command line is capable of, and we could use your input here. Many of our customers have been asking for new features and we’d like to add in some of our own. But to do this we need to make some changes.
First the initial commands themselves (log time and start a timer) don’t actually have a command! This isn’t such a problem when the command itself is easy to distinguish — the widget, the bookmarklet, the website itself all send in a specific piece of text to parse. Things get much trickier with e-mail, where the commands also have to work, and where we have to scan the message for the command.
E-mail comes with a lot of junk in it, especially e-mail from web-based services, or e-mails quoting other e-mails. There are lots of tricks to parsing out what you don’t want, but finding a start command like this is like trying to find a needle in a haystack:
I am doing stuff
Yup, that would be a valid start-timer command. Now, if you check our text-entry cheat sheet, you’ll see that I’m fudging things a little bit here. We do require a keyword for timers sent in by email – start. We are thinking about standardizing the use of keyword prefixes across text entry methods. For instance, this is our proposed syntax for timers:
start writing about the CLI #tempo @blogging
stop
And this is our proposed syntax for logging time directly:
log 1h did some stuff #tempo @development
log 1:30 …
Requiring a keyword at the beginning of every command would allow us to expand the syntax and add new features in the future like these:
stop 2h [ stop timer and add two hours ]
stop -30m [ stop timer and take off 30 minutes ]
start 1h … [ indicates I started an hour ago ]
log start 3pm stop 4pm [ record 1 hour between 3 and 4 pm ]
We’re fairly sure this is where we want to take it, but we’d love to get some feedback. Let us know what you think.
Products highlight
Tempo
Simple Time Tracking, Mobile Access, Powerful Reporting