Subject: "PhotoStory - Devlog #1"

Hey, it's been a month since I last posted here. I haven't forgetten about Monospace but I've been quite busy with school work. I've also been working on something on the side. Today I'll be revealing 'PhotoStory,' my brand new project. It's supposed to be a simple and private photo gallery app that lets you store all your images safely and securely. There's still a lot of work going on and it's currently incomplete, hence the devlog moniker instead of a full on reveal.

I want to keep the devlogs short and sweet instead of full on technical breakdowns which is worthy of talking about upon a full release. I'll go about some of the features and stuff I have developed as part of this project over the last week and hopefully give more insight into the project.

Reverse Geocoding Support

Most photo apps provide details as to when and where a photo was taken. Each image contains extra metadata known as EXIF which stores information regarding the camera specifications and details while taking that shot. Along with this, some cameras optionally came equipped with a GPS sensor that provides precise coordinates. Now normally, most services query a large navigation data provider such as Google or Apple Maps to get the information but I had made a limitation that my app should be usable offline so that would be impossible.

I decided to opt for a more interesting approach that some other apps use. It is a data structure known as a KD-Tree that allows you to perform a nearest neighbour search on a set of points across *k* dimensions. Thankfully, due to Python's strong data science background, there are already a handful of libraries such as SciPy that implement the code for it in optimised C code which meant that I could integrate it fairly easily into my app since my whole backend is written in Python.

For the coordinate data, I used the cities500 dataset provided by GeoNames. It contains roughly 185,000 city and town names that have a population greater than 500 people. It covers a lot of the world and I'm quite satisfied. It's accurate enough to about the closest town name which is good enough for an offline app. While the coordinates present in EXIF tags are sub-meter precise, I didn't want my app to have that much precision. I was pretty satisfied having town-level precision. I also had quite some fun testing this because I could see where a lot of the sample pictures I supplied were taken.

Silent Deduplication

With how expensive hardware in general has become, it has become ever more important to optimise the usage of resources available in a system. I implemented a system to check file hashes and verify for duplicates upon upload. This ensures that large photos that you might get from DSLR cameras that could weigh in at 20MB and such would not be duplicated and instead just assign the existing image to the new user instead.

While it might seem like a small feature, it will prove extremely beneficial if you have a large number of images and you don't exactly know which of them are duplicates. It will also be useful when syncing functionality is implemented later on which can help prevent duplication of the same images across different devices and users.

Lightweight Client

Following the trend of optimized resource usage, PhotoStory uses Svelte for the frontend. It compiles the code down into simple HTML, CSS and Javascript allowing for static serving of web files. The application only consumes about ~15 MB of browser heap memory. While this is not representative of the whole usage with images, it does show that the underlying bundle is quite lean. This ensures a fast and snappy experience for anybody using the browser app.

Images are also lazy loaded in using IntersectionObserver which means it only allows batches of images to be loaded in with each trigger, reducing I/O and networking burden. As a side effect, this also makes the app quick and snappy to load upon launch. The frontend code isn't perfect yet and there are some flaws that need to be fixed such as code duplication but work is still in progress and can be patched in a future update.

What's Next?

There are still some backend issues that need to be sorted such as the dreaded n+1 queries and TOCTOU bugs. However, I've postponed these to a later time to solve some glaring security flaws in the application. I've made it my current priority to improve user security and data privacy as of now. I'm planning to include a simple server-side sessions system to allow for integrity as well as the identification of session cookies along with adding URL flexibility so HTTPS connections would also work.

I'm also planning to use a lightweight but secure encryption scheme such as AES-GCM to allow for storage-level encryption. This ensures any bad actors cannot decipher the photos that are stored by PhotoStory on the local device without prior knowledge of the secret key. It is also a meaningful improvement to privacy and security without massive performance drawbacks. Encryption and decryption only add approximately 10-15ms of extra processing time which is worth the sacrifice.

I also need to refactor some frontend code, especially for the image preview component. There is too much code duplication currently present which I'm not particularly a big fan of. I'm planning to use Svelte's built-in {#snippets ... } and {@render ... } functionality to make the code more easier to reuse and maintain down the line.

I hope to make these devlogs a recurring thing. I love talking about technology and would love to share what I'm doing with others as well. I've been rushing to push features because I have exams coming up soon which could make work really slow or even halt it. If you are interested in the project. Do have a look at my Github, everything is open-source and Apache licensed. I don't earn a single dime from this and it would mean a lot to me if you guys can star my repository. That's about it. See you next week.