Wednesday, September 28, 2011

Converting seconds to a time value

Had to solve the convert seconds to a formatted string problem. It's been solved many times  before but I needed a slightly different formatting (as is usually the case for your company's app) so had to roll my own


Posted to a StackOverflow question too. You will see the first 3 lines of the function repeated in many solutions. ;)



seconds2time(0)  ->  "0s" 
seconds2time(59) -> "59s" 
seconds2time(60) -> "1:00" 
seconds2time(1000) -> "16:40" 
seconds2time(4000) -> "1:06:40"
function seconds2time (seconds) {
    var hours   = Math.floor(seconds / 3600);
    var minutes = Math.floor((seconds - (hours * 3600)) / 60);
    var seconds = seconds - (hours * 3600) - (minutes * 60);
    var time = "";

    if (hours != 0) {
      time = hours+":";
    }
    if (minutes != 0 || time !== "") {
      minutes = (minutes < 10 && time !== "") ? "0"+minutes : String(minutes);
      time += minutes+":";
    }
    if (time === "") {
      time = seconds+"s";
    }
    else {
      time += (seconds < 10) ? "0"+seconds : String(seconds);
    }
    return time;
}


Saturday, September 24, 2011

App Store - Error 1004 Please try again later

Really? Please try again later? What utter BS. This error message starting popping up at the beginning of the week and I just didn't have time to figure out what was going on. A quick googling of the error found that I was not alone, not by a long shot and this problem has folks pissed. 


I tried most of the solutions called out for. Sync, transfer purchases, reset all the settings on the iPad, etc... nothing was working. So semi-desperate/inspired, I went into the iTunes settings on my iPad and logged out from my appleID and then logged back in. That did it. There must have been a stale security token hanging about... an hour of my life gone. Well at least spent listening to music :)

Are web sockets ready to deploy?


In short I say the answer is "yes". 


18m ago we needed to add a notification service to our platform. We were adding an Android and Flash clients to the CloudTalk platform and neither platform supported iOS style notifications at the time. We weren't too excited about a long polling solutions since we didn't want to tie up our API request servers with this kind of transaction. We wanted something like websockets, but websockets were not ready at the time; we are early adopters but there was nothing yet to adopt except a commitment to help develop the technology. We settled on building our own "push server" that operated in much the same way as websockets; open a connection to the push server and just hang there waiting for events to stream down. We kept it super simple expecting that at some point we'd upgrade the protocol to websockets when they were more mature. The big lack with our solution was that we couldn't provide notifications in a browser without Flash, but since at the time our web solution was built in flash, this wasn't a problem at the time.


In our system, When an app client registers as being on line it's given an address to connect to for notifications and they wait on the connection for  payloads that are delivered in JSON. The client has a small vocabulary used to validate and check status. We've been really happy with this solution and if we weren't looking for a way to implement notifications on mobile web devices where flash isn't practical (this includes Android too folks) we'd probably let our solution roll on, but we do want to support web apps that don't require flash. So, it was time to look at that "upgrade" to websockets. What I found is that there is fast moving support for websockets in browsers (see Caniuse); but, not all browsers and client libraries support the same handshake protocol levels and there are bugs, so it can be a bit of a task getting a server side set up to handle all the differences. 


There are a few of bright spots here, and ironically for me one of these is a Flash component  web-socket-js (this is a nice bit of code) that you can install in a browser that implements a stable version of the websocket handshake protocol. This takes care of all non-mobile devices, so now it's mobile Safari and mobile Chrome that have to be supported which is still going to be a task as there a lot of phones running old software.


The second bright spot is the server side. There is a lot going on here too. We were happy to see that Jetty7 has native support, but pretty much every platform you might use has got at least a library that works stackoverflow - websocket-for-html5, though if you choose a solution without source code you're gonna hurt when one of those jenky clients hooks up and you cannot fix the problem. There is one way forward on the server side that I think everyone should be looking at and that's jumping on Node.js. This Node package  node-websocket-server rocks. You can be up and running in minutes and putting together websocket serverside code just a few minutes later. Node has really changed my point of view about creating a system of cooperating services and the support ecosystem is exploding  (I'll write more about that in another post) 


Lastly, the native support on the client side is starting to gel. iOS has support already and there are libraries that will enable Android native apps as well (no concrete info on whether native support in the Android SDK yet). This is good. We've never been particularly happy with the timeliness of iOS notifications and it would be good if we can get all of our native apps all tied into the same system. 


At this point it looks to me like it is possible to provide decent support using websockets, you will be challenged by some clients but it's doable and taking into account how easy you can setup a websocket service with platforms like Node it's definitely a "go for it" decision.

Sunday, November 8, 2009

Windows 7 update not all smelling of roses

My mission was to upgrade 2 Vista Machines to Win7. I'd been a beta tester, had the RC running on an old hunk of hardware which was running reasonably reliably so I was confident that this would be a one weekend chore. I'd read all of Thurrott's missives on upgrading and regardless of the desirability of a clean install I was willing to try a couple of upgrades in place of the following:

64bit vista home premium on a desktop -> 64 bit Win7 home premium
32bit vista ultimate on laptop -> 64bit home premium

I decided to get the family 3 pack of upgrades for 150$ which is a good deal, even if I only ever do 2 upgrades. I have another Vista box which is currently running linux, so you never know.

I had both machines checkpointed by Norton Ghost 12 (more on Ghost later, if you don't use this software you should be) and was ready to roll. First up the laptop.

Ok - I whip out the 64bit disk and run setup and it tells me that I'm not allowed to update a 32bit OS w/ a 64bit OS. After a moments thought, this seemed like a reasonable constraint, I am a little bummed out because I believe that the 64bit OS provides better performance; but I swap in the 32 bit disk and try again. I get past the 32 bit boundary and wouldn't you know it, you cannot down grade from Ultimate to Premium in place - sorry, did I understand that? I cannot down grade to Premium. What's that some kind of penalty for not wanting to spend an extra $100+ to upgrade to Ultimate for features I will never use? Now this is starting to feel like a regular Microsoft deal...

So back to the 64 bit disk and a clean install keeping my old files (this is a nice option, puts all the old stuff in a directory called Windows.old, so you can move it all back into the new Windows and User directories. But, I'm still pissed as now I need to get the 20 or so install packages needed to get this machine up and going again. 2 hours later, I've installed Emacs (always first install for me) and I've got 19 to go. Painful yes, but no real issues installing. I had to find a few drivers - most notably the Video and sound drivers on line but otherwise the laptop works great and it is much faster user experience wise.

Feeling a bit chuff from my first upgrade I turn to the desktop, this was to be an even easier upgrade as I was going 64bit Vista Premium to 64bit Win7 Premium, what could go wrong?
There was a slight wrinkle - I was going to clone the current 500Gb disk to a 1.5Tb disk first and this turned out to be a nightmare. First attempt at cloning with the Seagate Software took 3 days, at that point I should have boxed the drive, assuming many bad sectors and gone back to Fry's, but I didn't. I set it to be the boot drive and booted it up (this actually required that I get a repair disk off the internet and fix the MBR first, but this was to be expected, the Seagate program had failed in so many ways so far, I could not expect it to boot) So, it boots, and I try to log in and... nothing cannot get any keyboards to work.

Ok, now what? I figure, the Seagate program did a shit job and I whip out Norton and clone the disk with that. I get it to boot but again, no keyboard. Hmmm.... being a clever guy, I go back to the original disk and set my password to empty and repeat the entire process, now I don't have to log in, just click my picture. I clone the disk and get the log in screen, click my pic and it starts to log in - yes!, but actually NO. The screen says "Preparing your Desktop" forever. WTF? 30m of searching later, I find a most excellent post (Norton communities - good stuff) that says try Norton checkpoint restore. Ok, what do I have to lose? The instructions are good, create a partition on new disk for the checkpoint, leave the first part of the disk empty (partition only) and while I'm trying to create the partition for the checkpoint, Norton Ghost tells me there are numerous unwritable sectors around the boot record. Some things just make you go "hmmmm...". Why is this just now showing up. So drive out of PC, back in box, me in car to Fry's return drive ask for another and... drum roll... all the boxes are open returns, and these duchebags put the damn things back on the shelf. The drives are obviously bad. So I settle for a 1Tb drive (poor baby) which has no returns on the shelf and head home, after a detour past the new Canon cameras (I left a little drool on the 5d and 7d)

So, new partition at the end of the drive, checkpoint the old drive, put in Norton Ghost 12, boot from it and - FMe - its a windows boot and it blue screens :-) now I'm really feeling the love. I jump into setup inspired and turn off the PATA disks (just a damn lucky guess) and try again. It restores and boots in about 1hr and everything just works!!! Ghost is god! You must buy this, it's the only way to update your hard drive.

64bit Disk in the machine, hit Setup on the Win7 disk and start the process and - wait for it - "We recommend you remove the following software which will cause problems..." Recommend my ass, Setup terminates and you have to remove about 10 pieces of software including ironically Northon Ghost 14. So I'm so invested, I'd run around the yard naked if asked and maybe if not.
I remove a lot of software and next time it starts the upgrade, 2hrs later I'm running Windows 7 and all is good, though it did take about a bottle of gin to keep me sane through the whole process.

PS. all the forums say you can reinstall Ghost 12 and it should work (not there yet). Also you need to get a new antivirus as you had to remove norton AV to upgrade. This is no loss, that program sucks. MS is supposed to be releasing an AV soon, or you can pick up AVG or Avast

Sunday, July 19, 2009

Wrapper for Android Log class

While debugging an Android application, I realized that the ability to access log entries with 'logcat' beyond some OS defined cutoff was not possible, there were no options to write your log entries the SD card, so I put together a quick wrapper class that is already useful in its first incarnation here.

To use this class, drop it into your android package and comment out the import statements in your classes where you want the log entries to be written to a file. Java will pick up this copy of the Log class which in turn just forwards the entry to the Android logger. Next set the log file directory to point to the dir on the sdcard for your application then add the correct package name and you''re ready to go.

Note that the Log.e method includes a variant that takes a throwable. This method will write a stack trace to the log file for you.

Much more can be added here. What would you like to add?

/**
* Android Log class wrapper that writes all of your log entries
* to a log file on the sdcard
*/

//package com.MyApp

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;

/**
* @author jos
*
*/
public class Log {
static File logFile = new File("/sdcard/myApp/" + Long.toString((new Date()).getTime()) + ".log");
static OutputStreamWriter osw = null;

static {
try {
FileOutputStream fis = new FileOutputStream(logFile);
osw = new OutputStreamWriter(fis);
} catch (Exception e){
android.util.Log.e("Logwrapper", "failed to open log file!");
}
}
static public int d(String t, String m) {
writeLog("D", t, m);
return android.util.Log.d(t, m);
}

static public int e(String t, String m, Throwable tr) {
writeLog("E", t, m);
writeLog(android.util.Log.getStackTraceString(tr));
return android.util.Log.e(t, m, tr);
}

static public int e(String t, String m) {
writeLog("E", t, m);
return android.util.Log.e(t, m);
}
static public int i(String t, String m) {
writeLog("i", t, m);
return android.util.Log.i(t, m);
}
static public int w(String t, String m) {
writeLog("w", t, m);
return android.util.Log.w(t, m);
}
static public int v(String t, String m) {
writeLog("V", t, m);
return android.util.Log.v(t, m);
}

private static void writeLog(String type, String tag, String m) {
writeLog(type + "/" + tag + "\t" + m + "\n");
}

private static void writeLog(String s) {
try {
osw.write(s);
osw.flush();
} catch (Exception e) {}
}
}

Thursday, August 28, 2008

Developer outreach matters

I was at an alumni (Columbia U.) sposored event at the Google campus speaking with the local alumni club president who works for Yahoo. At some point in the discussion I mentioned to him that Google has done a spectacular job of reaching out to developers in both the traditional sense - tools and support - and in the marketing sense. What I meant was that Google makes is sexy and cool to be developing on the Google platform.

Where as connecting up with many other platforms is just work, somehow Google makes you feel like you are part of the in crowd. And this matters. Yahoo for example has some some technically excellent components and APIs for application developers to use, but developers in the many tens of thousands are being wooed to the camp every day.

So what is Google is doing? Here's a few things I've noticed:
1. they will sponsor anything that looks like it's interesting to developers
2. seminars and learning opportunities on their campus and sponsored conferences
3. unbelievably good support in their user forums for developer API's
4. really good APIs that are relevant and constantly improving

It's not that the others don't do these things, they just don't do them as well.
And based on converstaions I've had with a couple of Google's competitors, they know this.