New Years Resolutions 2016

It’s that time of year again!

Resolution 1: Post on the blog more regularly. A minimum of once a week.

I know that I say this every time that I come back from a break. It is just a matter of having the self-discipline to find the time to sit down and write something, even it it’s short. It’s not like I have nothing to write – I have a list of topics in the backlog. The problem is that if I miss one week, it becomes a lot easier to miss the next too, so I’m going to practice self-discipline.

Resolution 2: More Apple II Projects

I lost the space I had available to work on stuff as of the summer, so I had to put all of my Apple II gear away. But in about a month, I’m going be getting some office space at home again, so I can set it all up again! I want to continue with the disk imaging, and find some sort of interesting hardware project to do, as well as retrobrite a bunch of stuff. Maybe I can even find something that I can write up for Juiced.GS!

Resolution 3: Work on LuneOS

I did a bit of work with the LuneOS folks last year, but mostly had to leave it alone due to being busy at work. Now that I’m going to have office space at home again, I want to find some time to contribute to the project – maybe get the Photos and Videos app complete and functional.

Resolution 4: FeedSpider rewrite into pure Enyo 2

I know, another FeedSpider rewrite!? The last re-write still relies heavily on prototype.js. With model and collection support, and taking advantage of bindings, I should be able to eliminate that entirely. I’ll be able to complete my goal of releasing FeedSpider for more platforms, especially iOS.

Resolution 5: Grow the business

If I want to be able to fund all of this, I need to keep growing my business, Othello Ventures Ltd. The goal is to take on more development contracts, so that I can bring on more people and turn that into a positive feedback loop. I also have a few other projects in mind that will hopefully help, and I look forward to executing on them. 2015 was a good year for the business. I want 2016 to be a great year!

That all should be enough to keep me busy for an entire year now, shouldn’t it!

FeedSpider Dev Blog: Beware of things that look “easy”

As of Wednesday, I pulled together a fully functioning version of FeedSpider for webOS, which has been submitted to the HP App Catalog and is currently in queue. As of Friday, I built a new version for LuneOS. Getting there was… interesting.

As of my last post, there were 3 (well, really 4) things that needed to be ported over to webOS: OAuth, Sharing, Banner Notifications and Unread (Dashboard) Notifications. Thanks to WebOS Ports’ excellent webos-lib for Enyo 2, much of the access to the system functionality that I needed was made available to me, making the porting job a whole lot easier

OAuth

OAuth wound up being really straightforward. I was able to leverage my previous experience implementing this in Mojo and on Firefox OS to get it working fairly quickly. Thanks to webos-lib’s WebView kind, which implements Enyo 1 WebViews in Enyo 2, I was able to do something very similar to the FirefoxOS iFrame approach.

Of course, there was a webOS twist. As in FeedSpider 1.x, I have the browser redirect to a “local” url (urn:ietf:wg:oauth:2.0:oob) when it gets the authorization code from the service. This causes the Browser to throw an Invalid MIME type error instead of the typical TitleChanged event. I catch the error, and if it the URL contains a code, grab it and go on to get the OAuth token and finish the authentication.

To make this work like it did in the Mojo app, however, I had to make one tweak to the library. On an error, the library returns an object with a message property that is made up of like so: “message: localizedMessage + “: ” + failingURL”. The URL is not sent separately. So, I just added a URL property and returned the failingURL on it’s own, so that I could work with it. That is the beauty of working with open source libraries, you can tweak them to work however you need!

There were two problems that I ran into on this one. First, there is no real way to control the height of the WebView, so I had to hard-code a height into the library. That is something that I may re-visit later if there is good reason to. Secondly, due to a change in webOS 3.0.4, an application can no longer clear it’s own browser cookies. Only the browser application itself can do that. That means that I had to take the same approach as I did on Firefox OS and log the user out of their OAuth Provider’s account in the background after I got the authorization code. A bit of a clunky solution, but otherwise the user would not be able to log in using a different account for any of the OAuth providers.

Sharing

This was actually something that I had partially implemented before getting accepted to the Apps on a Flame program, so it was just a matter of finishing it up. I just had to build a customization dialog using an Enyo list (now that I’ve learned how they work, I love them!), so that the user could choose which services they wanted visible, and implement cross-app launching webos-lib’s enyo.ServiceRequest (which allows me to call into Palm services) – all pretty straightforward.

One of the interesting bits here was getting Instapaper working. Since it uses a direct web service call, rather than just a cross-app launch, I had to work up a dialog to collect its credentials and put in a preferences item to clear the credentials if they were present. However, the way that this is implemented, I should be able to port it over to Firefox OS and other platforms without too much trouble.

I also had to figure out how to handle non-installed apps. The call to open the non-installed application will return a failure message that has a well-defined structure, making it easy to parse out the package ID. With that in hand, I can launch the app catalog. However, since the error message just returns the package ID, I had to build a lookup table for the friendly name, so that I can present it to the user.

Fortunately, launching the app catalog via ServiceRequest is pretty easy. You just have to make a call to open “palm://com.palm.applicationManager” with a target of “http://developer.palm.com/appredirect/?packageid=” + packageID. (ie. com.otheloventures.feedspider2). Also, since Enyo 2 does not offer a yes/no choice dialog, I had to build one, but I think that it turned out pretty nicely.

The problem that I ran into here had to do with the way that things are rendered on screen. When the virtual keyboard comes up for the Instapaper login dialog, the Onyx Toolbar at the bottom of the screen disappears, so I have to call this.resized() on the article panel when the dialog is closed to force the screen to redraw and the toolbar to re-appear.

Banner Notifications

One part of the notification system, the easy part. webos-lib implements an “addBannerMessage” call, which allows you to pop up a banner notification. Adding this was as simple as extending my notification method to support this call.

Unread (Dashboard) Notifications

The other part of the notification system, and something that I expected to be one of the easier parts of the port. This, however, was not the case – I had to do some refactoring.

To trigger the app relaunch, it was just a matter of using ServiceRequest to call the palm://com.palm.power/timeout service and schedule an app relaunch using the palm://com.palm.applicationManager service with the “update” parameter.

In order to support application relaunching and dashboard notifications for unread articles, I needed to change the app to launch headless, using a noWindow: true directive in the appinfo.json file. There is very little documentation on how to handle noWindow and dashboard notifications using Enyo 2. But, fortunately, there was enough material for me to crib something together from the available information. [1] [2] [3]

In order to support this without breaking the other platforms, I wound up splitting my application into two different index pages, one for webOS, and one for everything else, building my own dashboard notification class, and an associated webos-dashboard.html file for it.

When launched on webOS, the application will launch our window manager. Then, based based on whether the app is in update mode or not, it will either try to get an unread count and pop up a dashboard notification, or open the main window by launching a new card with the main index.html page.

 

Fortunately, thanks to the way that Enyo works, it was relatively easy to shim this functionality in with only minor changes to the rest of the application, since the webOS-specific stuff launches the cross-platform stuff. And since it is packaged separately for each platform, I can have different entry points for each platform, maintaining cross-platform compatibility.

Speaking of cross-platform compatibility, if you take a look at the file structure, you will notice that the launching code for each page is split off into it’s own javascript file, rather than just being put in a <script> block in the html file. Even if it is something as simple as:

enyo.ready(function () {
 var launcher = new FeedSpider2.webOSWindowManager();
 launcher.launch();
});

The reason for this is that Firefox OS does not allow inline scripts in it’s html files. Everything has to be in separate .js files. It’s a simple thing to do, but one of those gotchas that you have to watch out for.

LuneOS

LuneOS is not quite webOS. At least not yet. But, as a work in progress, it’s pretty close, and FeedSpider runs on it.

Fortunately, Enyo does not detect LuneOS as webOS, so it is easy to make a check for “!enyo.platform.webos && window.PalmSystem” and implement LuneOS-specific features that will not affect webOS.Almost everything works the same way that it does in webOS, with a few exceptions:

  1. WebViews are not currently supported, so OAuth doesn’t work. I understand that the plan is to implement a solution using iFrames, similar to to the way that Firefox OS works. So, once that functionality is available, I can implement it for LuneOS. In the meantime, Feedly and AOL Reader support have been disabled.
  2. The dashboard is not implemented in LuneOS yet, so webOS-style banner notifications don’t work. Instead, the application falls back to Firefox OS-style toast notifications.
  3. The apps available for sharing have been tweaked slightly. Significantly, the webOS browser has been replaced with the LuneOS browser. Additionally, if an app is not installed, there is no app catalog, so FeedSpider cannot offer to install it for you.
  4. In addition to no dashboard support, LuneOS does not support the noWindow: true directive, (except for the email application), so at this point, I have disabled the unread count notifications.

As a result of issue #4, I’ve had to separate off the LuneOS build from the webOS build. It removes the noWindow: true directive and uses index.html as an entry point instead of index-webos.html, so you need to make sure to use the LuneOS-specific package, otherwise it will not run at all.

Get it

One last note. I’ve decided to cut official webOS 2.x support from this version of FeedSpider, as WebViews do not currently work on webOS 2.x. Also, scaling is not implemented, so all of the text and UI elements are very small. So, I recommend that people use FeedSpider 1.x for webOS 2.x devices. That being said, if you really want to sideload it, you can do so at your own risk – almost all of the features should work.

Hopefully, FeedSpider is accepted to the App Catalog soon, and I would love if you were to purchase it from there and support a small app developer. But in the mean time, you can always get the webOS, LuneOS and FirefoxOS packages for free from feedspider.net. Or, if you’re feeling brave, you can always build it from source.

What’s next

From here, I plan to start bringing in the localized strings that have been generated by the translation project, and add support for Instapaper to the Firefox OS build. Then to start on the Firefox Desktop and Chrome Desktop versions. As always, features will be added to the webOS, LuneOS and Firefox OS builds as I complete them.

In the near future, I also plan to put this project on the back burner a little, and work with the WebOS Ports team on LuneOS, specifically on Preware – Enyo 2 has become my area of expertise after all. I’m also planing to work with the PivotCE folks on a series of articles about setting up a webOS device in 2014. I’ve got some busy times ahead of me, but it should be fun!

As always, lets close with the screenshots:

FeedSpiderWebOS4

OAuth working on the webOS 3.0.4 emulator

FeedSpiderWebOS6

The sharing dialog in testing. Enyo lists will overflow their containers if they are not given an explicit height.

FeedSpiderWebOS5

Here’s what the sharing dialog is supposed to look like.

FeedSpiderWebOS7

Working dashboard notifications on webOS!

Building FeedSpider from Source

Now that FeedSpider 2.x is open source, I’ve had a couple of questions about how to “build” it from source. Of course, since it’s Javascript, it’s really more of a compress and package process than a build process.

It’s fairly straightforward with just a couple of quirks depending on what platform you’re planning to build for. That being said, this guide assumes that you have at least some experience using the various developer tools. Instructions on how to setup the webOS SDK, Cordova, etc, are outside of the scope of this document.

What you need

  • The FeedSpider source. Get it from GitHub.
  • Apache Cordova. Use the latest version for FirefoxOS, or 2.5.0 for webOS.
  • Node.js. Get it from their website.
  • If packaging for webOS or LuneOS, the webOS SDK. (Note that while the files are still available from HP/Palm, the download page is no longer active).

How to Build

  1. If building for webOS, set up the SDK using the instructions here.
  2. Install Node.js. Instructions here.
  3. Install Cordova. Instructions for FirefoxOS here, webOS here. (Note that when setting up the Cordova app for FirefoxOS, you will call it FeedSpider instead of test-app.)
  4. Unzip the FeedSpider source to a directory of your choice.
  5. Open up a command line and navigate to the FeedSpider source directory.
  6. Run the command “tools\deploy.bat” (Windows) or “tools/deploy.sh” (Mac/Linux) without the quotes to build the package.
  7. After the script run completes, you will be able to find the packaged code in the “deploy” directory under the main directory. Navigate there.
  8. Remove all of the files in the Cordova application directory and copy all of the files in this directory to that directory. (Refer to the Cordova instructions for your platform for which directory the application directory is.)
  9. Copy the appinfo.json (webOS), appinfo-luneos.json (LuneOS) or the manifest.webapp (FirefoxOS) file to the Cordova application directory.
  10. If you copied the appinfo-luneos.json file, rename it to appinfo.json.
  11. Package the application using Cordova (refer to Cordova instructions for your platform) and deploy the package using your preferred method.

That should get you going! If you run into trouble, drop an email to feedspider@feedspider.net.

FeedSpider Dev Blog: …and We’re Back!

August was a busy month for me, but not so much for FeedSpider. These little side projects have a way of getting put on hold when real life takes over, but now I’m back and I’ve got some exciting development news.

When we last left FeedSpider, version 1.0.1 was in the Firefox Marketplace queue. It fixed a few bugs and notably changed URL handling so that clicked links would open properly in a new browser window instead of the same window. Since then, 1.0.1 was approved, and I’ve been (slowly) working on a few new things.

Firefox 2.x and Prototype.js

One recurring issue that I kept getting reports about was that web service calls would silently fail and the loading spinner would just keep infinitely spinning. This was only happening on FirefoxOS 2.x (I developed on 1.3, and everything worked properly there.) After some investigation (and updating my Flame to 2.2 ’cause the 2.x simulators are very crashy on my dev machine), I discovered that the new version of the Javascript engine used in FirefoxOS 2.x and Prototype.js don’t play nicely for some reason.

The problem lay in the call to initialize Prototype.js’s Ajax.Request object. When creating a new Ajax.Request object, you will pass it the URL that you want to send the request to, and a JavaScript object with the options.

Internally to Prototype.js, Ajax.Request is derived from Ajax.Base. So, when you create a new Ajax.Request object, it passes its Initialize method the $super parameter, which contains a reference to Ajax.Base’s Initialize method, which can then be called to initialize the object.

The problem is that on FirefoxOS 2.x the $super parameter is not passed. The method just receives the two parameters, url and options, instead of the 3 that it is expecting. Since it doesn’t have the correct information, and doesn’t know what else to do, it tries to call the URL parameter as the $super method, blows up and never returns, leaving the UI hanging, waiting for some sort of response.

Since the only other class that extends Ajax.Base is Ajax.PeriodicalUpdater, which I don’t use, and Ajax.Base only defines an initialize method, the simplest solution was to remove the inheritance, incorporate Ajax.Base’s initialize method into Ajax.Request’s, and ship a custom version of the library. It winds up looking like this:

initialize: function(url, options) {
  this.options = {
    method: 'post',
    asynchronous: true,
    contentType: 'application/x-www-form-urlencoded',
    encoding: 'UTF-8',
    parameters: '',
    evalJSON: true,
    evalJS: true
  };
  Object.extend(this.options, options || { });

  this.options.method = this.options.method.toLowerCase();

  if (Object.isHash(this.options.parameters))
    this.options.parameters = this.options.parameters.toObject(); 
  this.transport = Ajax.getTransport();
  this.request(url);
},

Instead of this:

initialize: function($super, url, options) {
  $super(options);
  this.transport = Ajax.getTransport();
  this.request(url);
},

It’s not the cleanest solution, but I am considering moving away from Prototype.js anyways. Enyo kinds can take the place of Prototype.js classes, and I can roll my own Ajax class if I need to.

But, that’s a project for another day. This works for the moment.

Version 2.0.0

With the Prototype.js issue fixed, I was able to build and submit version 2.0.0 to the Firefox Marketplace last Wednesday and see it approved last Friday. It includes the Prototype.js fix, as well as the integration of the Macaw SimpleLang Localization Library, a couple of typo fixes, and a behaviour change that will cause it to fall back to the system JSON parser if there isn’t a better one available. Initially, it supports English, but it’s easy to add new languages as we go.

This is a version that I’m happy to call “done” and use as a base for my cross-platform work.

The big version number bump is something that I should have done in the first place to reduce confusion. From here on in, FeedSpider 1.x will refer to the old Mojo-based webOS version, and FeedSpider 2.x will refer to the new Enyo 2-based cross-platform version.

Initial Support for webOS and LuneOS

After getting 2.0.0 to the Marketplace, I started on webOS. Just as a simple test, I set up an appinfo.json, plugged the code into palm-package, and pushed it up to the TouchPad emulator. I’m happy to report that Enyo has performed exactly as advertised. Aside from the things that I knew weren’t going to work because they were programmed specifically for FirefoxOS, everything worked properly, even a few things that I suspected would not.

Just for fun, I also pushed it up to the Pre3 emulator just to see what would happen. The text is a little small, but it works there too, so I might consider a release for webOS 2.x as well.

This means that the webOS port is already 90% to 95% done, and I just have a few OS-specific areas left that I have to port.

As far as LuneOS goes, I still need to update my TouchPad and get the latest build on there, but I’ve sent a couple of packages out into the field for others to try. I’ve had reports that things work really well, including this write-up from PivotCE as part of their article about which webOS apps work on LuneOS:

FeedSpider works amazingly well. I was able to get an early copy and I was impressed. The interface is clean and familiar from his previous work and I could log in and pull down new stories with ease. It’s on the partial list though because the back swipe didn’t take me back and some things just haven’t been coded yet. VERY promising indeed. Perhaps this will find its way into a release of LuneOS in the future. Yup, it’s that good and it’s not even done.

So, it sounds like most of the webOS work will be portable to LuneOS as well. Needless to say, I am very pleased and will certainly use Enyo for cross-platform projects in the future.

Open Source

The final bit of news that I wanted to mention is that FeedSpider 2.x is going open source. I’m releasing the code under an MIT-style license, with the only restrictions being that I reserve the rights to the name and logo. I do plan to keep developing FeedSpider though, and adding more platforms, so don’t worry! This is mostly because I’ve had a few requests to take a look at the code, and I’m hoping that the LuneOS project might be able to make use of it.

If you want to check out the source, its available on GitHub.

What’s Next?

So, what’s next from here? We’re finally moving on to webOS and LuneOS! There are a handful of things from the build last week that had FirefoxOS-specific implementations, so need to be implemented for webOS:

  1. OAuth Authentication (Feedly, AOL Reader). In FirefoxOS, these used iFrames in a way that no other browser seems to support in the same way. So, for webOS, I’m expecting to use WebViews, but we’ll see how that turns out.
  2. Notifications. While the “toast” notifications are functional right now, I should be able to get proper webOS-style notifications working as well. Additionally, for the recurring unread count check, I need to get dashboard notifications working.
  3. Sharing. It just isn’t implemented for webOS yet. But, I know how to do it.

I’ve got most of the code to handle all of this, and the app is already wired for these functionalities, so it shouldn’t be *knock on wood* too difficult to do, just a matter of porting from Mojo to Enyo 2. I’ve even got the handling working for the Back gesture already.

Also, as additional translations come online, thanks to the Mozilla Localization Project, I’ll be able to support additional languages in both webOS and FirefoxOS.

After that, I’ll take a look at porting this as a Firefox Browser app, and as a Google Chrome App, and decide where to go from there. Probably Android or Blackberry. As always, I’ll keep you updated.

In closing, here are the new screenshots:

FeedSpiderWebOS1

Packaged the app, dropped it into the emulator, and things just work!

FeedSpiderWebOS2

We can even get all the way to an article, and stuff like mark read/unread, starred/unstarred, etc work.

FeedSpiderWebOS3

Just for fun, I plugged it into the Pre3 emulator, and things look and work pretty decently there as well.

The Joy of Creation

Nothing is quite as satisfying as finishing a project that you’ve been working on for some time, especially if its been sitting on your desk for a while – important but not urgent. For me, that has been adding Feedly integration to FeedSpider over the last week or so. That is now complete, and I am just waiting for the guys over at Feedly to push my new client id to production so that I can release the app. (As a bonus, I also added support for BazQux Reader. It only took about half an hour thanks to their very Google-like API.)

The biggest challenge was implementing OAuth support (detailed in my last post), but between a few false starts with AOL reader, which requires the same technology, and work piling up at my day job, I got it done. The rest of the project was merely tweaking the app to support Feedly’s API, which is Google-like, but just different enough to create it’s own challenges, especially on the platform that I’m working on. And now, that’s finished too.

While I can’t take credit for building the app from the ground up, (Darrin Holst did an excellent job of architecting it), I have done some significant tinkering under the hood, and am very proud of reworking the API and login/credential layers so that the app can properly and easily handle multiple providers with different requirements. This was aptly demonstrated by how easy is was to integrate BazQux Reader. I just had to drop in a new app API, and add the service to the service list. No other changes required.

One of the things that I love about programming is the feeling of having built something, even if it’s just a bunch of bits. It gives you a certain satisfaction and an energy that can’t be duplicated – make you feel like you can take on the world, and makes you feel ready to go energetically into the next project. That’s something that’s feels like its missing nowadays – and why I intend to keep programming and building computers and systems for many years to come.

Programming via clever hack

I picked up an HP Touchpad shortly after the firesale back in 2011, and have been using it as my daily driver ever since – I even picked up a Pre 3 a little later to replace my aging iPhone 4. Suffice it to say, I’m a big fan of the webOS operating system, even though it’s been a while since it was updated.

Of course, with no new hardware on the horizon, and no official updates coming down the pipe for these devices, (although LG is still working hard on developing Open webOS), developers have left for greener pastures, and apps and services have slowly stopped working. One of the main things that I use my devices for is consuming RSS feeds. Until it was shut down, I used Google reader, and one of the best Google Reader apps for webOS: Feeder. After it shut down, we were kind of in a bind, as many Google Reader alternatives sprang up, but no apps supported them, and the developer had left for greener pastures.

So, as a developer, what am I to do but roll my own? Fortunately, Feeder had been open sourced when the developer finished with it, so I forked it and have been working on “FeedSpider” ever since, adding support for The Old Reader and InoReader. But that’s not the clever hack. Both applications cloned the Google Reader API (mostly) and allowed support for simple authentication using ajax calls, so adding support was pretty easy.

Where the clever hack comes in is when dealing with Feedly. Feedly is the largest of the Google Reader successors, and just opened their API up to the public fairly recently. What makes this challenging is that Feedly uses OAuth for authentication, which webOS does not support very well. Fortunately, somebody else already came up with a clever hack for that, which, in short, captures the OAuth authorization code from the browser when it redirects to redirect uri and allows the app to use it. The library mostly works for Feedly, but not quite.

My contribution to the clever hacks list is two-fold. There is a bug in webOS on tablets that causes it not to pop up the keyboard when using a webview inside an app. (Works fine on phones, and I need to use this method to keep support for old devices) that I had to hack around by manually causing the keyboard to pop up then you go to the Twitter, WordPress and Google OAuth providers. I did that by watching for the urlChanged event and acting accordingly.

The more interesting part of the hack was that Feedly forces you to register your redirect URI with them, and will only let you use the one that you registered. Since I’m currently in sandbox mode, they gave me two options, http://localhost, or urn:ietf:wg:oauth:2.0:oob. Localhost won’t work on a webOS device. The browser will just time out. It never actually tries to do the redirect in a way such that I can catch it. The other one will try to do the redirect, but, it generates a “MIME type not supported error.” Here’s the fun bit – this raises a “Mojo.Event.webViewMimeNotSupported” event, which returns the URL that it is trying to redirect to. So, I catch the event, feed it to the filter and get the OAuth code, allowing me to log in, and we’re in business! (Yes this means that I am making good progress on Feedly support and hope to deliver it as a Christmas gift).

This is one of the fun parts for developing for poorly supported operating systems – there’s always a clever hack that will let you do what you want to do, even if the path is a little roundabout at times.