The following is the beginning of a series of posts with detailed information on my open source personal projects. The intention is to provide information about the application, development, design decisions and lessons learned. Enjoy!
I don’t recall exactly when I started working on SuperSecretary, but I originally looked at a folder of various photos on my machine and set out to look for a way to keep them under control. I looked for software to sort photos by date taken and couldn’t find anything to meet my criteria. It didn’t seem that there were any options that were user-friendly, and there certainly weren’t any that were free.
I started building SuperSecretary specifically as an app to manage photos, but quickly realized that the concept could be expanded upon to manage all types of files. There are even some features, such as sorting music files by ID3 tags that are on my to-do list for future versions.
I knew from the beginning that I wanted the application to eventually support plugins for users to handle files in any matter that they deemed necessary. This led me to the creation of the “Handler” in SuperSecretary. It is essentially just a simple, verbatim implementation of the Strategy pattern. Each handler has a Do method that passes in the path to the file that is being acted upon, along with some options that have been selected by the user. The handler returns the name of the folder that the file should be sorted into.
For example, when the user chooses to sort a photo by the Date taken attribute, the system uses a DateTakenHandler. The sorting engine loops through the files that need to be sorted and runs the DateTakenHandler for each one. The DateTakenHandler will retrieve the Date taken property from the EXIF data and format it based on the format selected by user. For cases when the user chooses to sort based on multiple attributes, the system will return and then move on to the next Handler. The handlers all inherit from the same interface, allowing a plugin system to be implemented.
The only thing I dislike about this design is that it is not the most efficient option. The system loops through each file, then loops through each of the handlers and acts before moving on to the next. However, some processes are more efficient when grouped together. For example, if the user chooses to sort on two EXIF attributes, say Camera Model and Camera Maker, it makes sense to retrieve that information together. However, batching these operations together makes the system less extensible. Ultimately I chose the more modular approach.
I started development on a proof of concept right away. Since the application was meant to be a small utility that I used myself, I did not put much effort into researching features or deciding on what options to provide right off the bat. I kept the user interface compact and simplified as possible.
After completing the proof of concept, I began to think about the bigger picture of all of the things that could be possible. I pondered on a plugin system and the possibility of multiple interfaces, including a console front end for automating the application as a scheduled task. I even started building a WinRT front-end, which didn’t go so well. More on that in another post.
All of these more end user focused features led to many development decisions. I re-factored the application into two projects, a core library and the Windows Forms application. I focused on keeping the Windows Forms view as thin as possible and moved all of the logic to the core library. I moved detailed output of the results of each run to an update event that could be implemented in to display information in the UI, a log file, or any manner that is specific to the target platform.
Releasing a desktop application as a product was an entirely new concept for me. All applications need a few common elements, one of which is a deployment package. I had very little knowledge on creating a Windows installer. I really only knew that Visual Studio Installer Projects had been recently discontinued and that I needed to find a new option.
I discovered the WiX Toolset, a fantastic framework for building MSI installers. I admit that my implementation is very simple, but to this point I have not run into anything that I needed that I could not achieve using WiX.
The other common element that an application needs is assets and branding. I come from a primarily web focused background and working as a part of a team, so I had never had the complete responsibility of creating assets for a project. Icons, logos, screenshots and information were all things that I had never created and compiled from scratch. I am not a designer so I tackled those to the best of my ability. Paint.NET became my friend.
I initially built the Razium web site specifically for hosting an installer for SuperSecretary. I created the site in a format that was more focused on the end user as a target audience, rather than toward developers. I will do a post in the future entirely focused on the creation of the Razium site, since there are some interesting tidbits there.
Originally I hosted the files there as well, but I have since moved those to Sourceforge. Hosting on Sourceforge obviously requires that your application be open source, but for those that are, it provides the added benefits of handling bandwidth costs and also the exposure that you get from being included in their library. In the first day on Sourceforge I had more downloads than the whole time that SuperSecretary was up on the Razium site.