Orchard Media Library and Dropbox

The new Media Library module in Orchard 1.7 has many interesting new features, and I was particularly excited by the ability to import images from Bing via the Web Search feature which was presented at Orchard Harvest this year.

Being a regular Dropbox user, the idea of being able to import media straight from the cloud seemed very useful, so I got to work on a Dropbox media import feature which you can now find over on the Orchard Gallery.

Installation & Getting Started

After installing the module on your Orchard site you will need to create an API Key over on your Dropbox Developer Console. There are a few questions that you have to answer to create the right kind of key, so ensure you create a Dropbox API app, with access to files and datastores, that can access all file types already present on Dropbox. See the screenshot below if you aren’t sure.

Once you receive the App Key and App Secret, head over to your Orchard site and go to Dashboard » Settings » Media to save them.

When you are ready to start importing media, you’ll see Dropbox appear on the media import screen. The first time you do this, you’ll need to link your Orchard user with a Dropbox account. This uses OAuth, so you’ll be briefly redirected to the Dropbox site to confirm that you wish to proceed.

After authenticating with Dropbox, you are ready to start importing media! You can browse all your Dropbox folders, and can preview images Ctrl-clicking will allow multiple selection.

Technical stuff

The source is available over on GitHub. Please direct your pull requests there.

The module uses Dropnet to talk to Dropbox, making use of the Core API features. (Dropnet is itself based on RestSharp, a fantastic library).

The UI was implemented using knockout.js. This was my first foray into client side MVVM, and a very pleasant experience. Needless to say I will be client side MVVM’ing all the things in the future.

The thumbnail images are cached in the browser, although ideally they would be downloaded directly from Dropbox without generating another request to Orchard (see below). If you notice thumbnails not updating, try clearing your browser cache.

To do

There are still one or two things left to do with this module but haven’t got round to just yet, namely:

  • Ability to delete Dropbox credentials from a user in case they want to switch accounts
  • Offer the option to use public links to files, hosting the files on Dropbox instead of importing them into the media library.
  • Download thumbnail images directly rather than through Orchard site

That’s all! I hope you find this module useful, I’ve had a lot of fun writing it.

Questions, comments, suggestions? I sporadically tweet.

Cyanogenmod 10.1, storage space running out

Hooray, first post of 2013! So what if it’s May…

Living life on the bleeding edge isn’t always fun. My Galaxy S2 has been more or less crippled for the couple of weeks after upgrading to a CM10.1 nightly and getting that horrible “Storage space is low” message a couple of days later. I tried a number of things to free up space on the phone’s internal SD card, but every time I moved something off or deleted an app, the space would be filled again within hours. Upgrading to newer nightlies didn’t seem to fix it, and more and more space was getting eaten up.

After some poking around I found about 1.8GB of log files in /data/log. Proving that I should have just given up and Googled it a lot sooner, searching for the same problem led me to a thread describing the very same problem. Deleting the log files doesn’t seem to have any adverse effects, and of course frees up all that space.

Apparently the problem is caused by the phone losing a data connection, and dumping ~1.5MB of logging information every second until it comes back. Can’t find any information about whether it’s been fixed in the latest nightlies, but rm /data/log/*.log running every couple of hours under Tasker should do the trick :)

Content & Display type alternates for content parts in Orchard

The Shape Tracing feature for Orchard makes it a snap to find and override shapes all over your sites, and I use it regularly to create alternates. A common use case is to find and override a part’s shape based on it’s content type – really useful if you want to alter how a part looks if it is on a page, product, contact, etc. I found myself in a scenario today where I wanted to override a shape based on both the content type or the display type, and both at the same time.

The documentation on Alternates lists only 2 alternates for parts, [ShapeType]__[ContentType], and [ShapeType]__[Id], but thanks to Orchard’s near-infinite level of flexibility, we can quite easily add as many alternates as we want.

A quick read through WidgetAlternatesFactory and UrlAlternatesFactory should be more than enough to get you started, but the key is to latch on to when a shape is displayed, and inject some alternate shape names.

I ended up with the following implementation:

public class PartContentTypeAlternateFactory : ShapeDisplayEvents {
    public override void Displaying(ShapeDisplayingContext context) {
        context.ShapeMetadata.OnDisplaying(displayedContext => {
            var shapeType = displayedContext.ShapeMetadata.Type;
            var contentItem = displayedContext.Shape.ContentItem;
            var displayType = displayedContext.ShapeMetadata.DisplayType;
            var contentType = contentItem.ContentType;
            displayedContext.ShapeMetadata.Alternates.Add(
                String.Format("{0}__{1}", shapeType, displayType));
            displayedContext.ShapeMetadata.Alternates.Add(
                String.Format("{0}__{1}__{2}", shapeType, (string)contentType, displayType));
            });
    }
}

And you end up with some alternates like this:

Surprisingly, I couldn’t find any information about people hitting this problem before (maybe I’m just doing it wrong?), but if this helps let me know in the comments!

Alternates are very powerful, for example you can customise the shape of the first item on your blog, override shapes based on the current URL, and much more.

Happy Orcharding!

Pushover notifications for Orchard CMS

I’m a big fan of Pushover – a push notification service – having used it for a few months for notifications from some home automation tasks. It’s free after purchasing the inexpensive app (for under 5k messages/month), easy to use, and useful for those small but important messages that might normally get swallowed into the great void some of us call ‘Email’.

This fits in quite nicely with Orchard‘s rather useful Rules module, as integration with Pushover would allow us to receive notifications to our mobile devices when events happen on an Orchard site, such as content being created, comments submitted by readers, or events fired from other modules.

So to glue this all together I’ve written a new module for Orchard called Kobowi.Pushover (source), making use of the rules and tokens modules for completely customisable messages triggered from almost any event!

To get started, you’ll need a Pushover account and an API key, and of course either the iOS or Android app installed on your device. Once you have entered the API key under your site settings, you can then start creating rules which use “Send a Pushover message” as an action.

The module uses a very simple wrapper around Pushover’s RESTful API called pushover-dotnet, which you can use to easily add Pushover notifications to your own projects.

I hope that you find this useful, and as always I’m eagerly awaiting any feedback :)

CWM Recovery/Cyanogenmod 9 on A1CS Fusion5

After getting the stock ROM back on again (and removing all the crap I’d installed), the next step was to install a CWM recovery, then use this to install Cyanogenmod 9.

This thread over on xda-developers was incredibly useful, unfortunately the recovery and ROM originally posted have since been removed. There are a few guides that give you a recovery image as a cpio archive, except that didn’t work on this device as firstly the recovery partition doesn’t appear to be mountable, and secondly there is no cpio executable installed! A lot of other A10 based tablets appear to have their recovery partition on /dev/block/nandf. Not this one, it’s on nandg.

Eventually I was able to track down a recovery image from Spanish forum HTCMania – here is what you need to do:

  1. Make sure USB debugging is enabled on the device.
  2. Download RecoveryIcs.tar and extract somewhere.
  3. Using either the included adb.exe or the one from the Android SDK, push the recovery image to the device.

    adb push recovery.img /data/recovery.img

  4. Copy the contents of recovery.img over the top of /dev/block/nandg.

    adb shell dd if=/data/recovery.img of=/dev/block/nandg

  5. Depending on your ROM you can either reboot into recovery using “adb reboot recovery”, or power off the device and press and hold MENU/VOL+ and POWER, release POWER after 3 seconds, then release MENU/VOL+ after 3 seconds.

Once you’ve booted into the the recovery, you can navigate using the power button to select and by mashing the HOME/VOL- button to scroll, and the power button to select.

The last part is the easiest. Christian Troy has been working hard on a CM9 ROM for A10 devices, and all you need for this device are three files:

Put them on a micro SD card (or on the internal SD card), and flash them with CWM, and reboot. Remember, if anything goes wrong, you can always reflash with a stock ROM.

Christian’s ROM is pretty good, making use of the Update Me app for updates from the developer (he’s also included some of the stock applications such as Skype with camera support, and the Point of View gallery app).

Overall I’m much happier with CM9. The device feels much faster than with any of the stock ROMs. I gave it to my girlfriend and her Mum to play with and they were web browsing with multiple tabs and didn’t report any problems (I’d certainly get an ear bashing from those two if it was being slow!) My 7 year old niece took it off me once I got it back and gave it a good workout with a few websites and Angry Birds, and she was quite happy with it too.

EDIT 2013-03-27: It looks like links to some of the original files have died. Since nobody appears to be actively working on a Fusion5 version, some change to the Protab ROM stops the screen working on the Fusion5. Here are the ROM/GApps/Compat zips I was using:

cm9_nightly_20120610.zip
gapps-ics-20120429-signed.zip
protab2xxl_compatibility_1.1.0.zip

There might be newer versions out there, but I got rid of my Fusion5 when the Nexus 7 came out, so I can’t test them. A few people have reported that the 2012-06-24 ROM from UpdateMe works fine, but anything after that seems to break the screen. Happy flashing!

Flashing A1CS Fusion5 with a stock ROM

So I got one of these cheap Ice Cream Sandwich tablets to play with. The ICS ROM it came with seemed to work OK, but I got a few force close issues and Chrome would start but was almost unusable, so I decided to get tinkering.

First task was to get comfortable flashing the stock ROM, in case anything went wrong. I couldn’t find anything from A1CS, but after a few evenings I found out that the Fusion5 is actually a slightly updated and re-branded Point of View 2XXL, who have some ROMs available from their website:

There are some instructions in partially broken English, but they are still usable. The included versions of LiveSuit didn’t seem to work for me, but LiveSuit 1.0.7 did.

Although it took a lot of Googling, it’s a good job this bit is easy, because I had to repeat it a few times.

Next task: CWM Recovery and CyanogenMod.

Visual Studio Achievements now in WordPress Plugins Directory

I’ve moved my Visual Studio Achievements plugin for WordPress over to the WordPress Plugins directory, so it is more accessible to users (also gives us auto updates, sweet!)

Unfortunately it seems rather difficult to keep both Git and Subversion copies of the same repository going at the same time, so the repo over on GitHub is now obsolete, but I’ll make sure any tickets raised over there are fixed in the SVN repo.

If you want a demo of the widget, take a look in the sidebar. Check it out and let me know what you think!

NullReferenceException vs ArgumentNullException

I answered a question on StackOverflow today that unfolded into a bit of a debate about the NullReferenceException and ArgumentNullException classes in the .NET Framework.

MSDN states that the NullReferenceException

…is thrown when there is an attempt to dereference a null object reference.

While ArgumentNullException

…is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.

Konrad Rudolph (StackOverflow profile) made the point that we don’t need both types as if thrown they both logically mean that you are attempting to use a null reference, so ArgumentException is redundant. While I don’t think the documentation is completely clear (it could do with comparing each to the other to clear up any confusion), I disagree with Konrad’s assertion.

I believe that the NullReferenceException should be thrown when you are attempting to perform a dereferencing operation on a null reference, whereas the ArgumentNullException should be used when you are actively rejecting an argument because it is null. Konrad goes on to say that ultimately, the two operations are the same – i.e. “I’m trying to dereference this null reference therefore I need to throw an NRE” and “I want to dereference this null reference, so I need to throw an ANE as I cannot attempt to do this” – as they all come back to trying to dereference a null reference. However, I think Konrad is missing the difference in semantics between those two operations.

Konrad also suggests that the presence of both types is a bad decision in the design of the framework. Again, I disagree. There are actually 9 classes that inherit from ArgumentException that are there specifically to help us deal with invalid argument, i.e. the likes of ArgumentOutOfRangeException, InvalidEnumArgumentException et al.

Ultimately I expect it all comes down to a matter of taste. Personally I’d rather be told “Whoa, you can’t do that! obj is null man, wtf?” than “Object reference not set to an instance of an object”, which – let’s face it – any seasoned .NET dev has seen enough of to last a lifetime.

What do you think?

Also, thanks to asawyer who was arguing from the same position as myself.