It's been over a year since I really came up with the idea for KitchenOS, and not much has been actually developed. But I think as the year has continued on, I have ended up actually building out in my head what I want to do and learned quite a bit along the way specifically around Amazon Web Services (AWS), Kotlin, and Android programming. Since it's the start of the year, I figured now would be the perfect time to look at what I have accomplished and what I want to accomplish on this project in the future.
A Look Back
I admit it, I spend way too much time thinking about cooking and what I am going to make for dinner, and that drove the whole KitchenOS idea. KitchenOS, for lack of a better name right now, is an "operating system" that I would be able to use to power my cooking experience both inside and outside of the kitchen.
My overall cooking experience happens in four different places: (1) my kitchen, (2) browsing recipes on my Surface Pros, (3) at the grocery store, and (4) reading cookbooks on the couch. And while the actual process of cooking is the most important, it also misses the rest of what I do which includes meal planning, determine what every one in the family likes to eat (and that isn't easy with a toddler hanging around), and tryign to come up with new recipes that will excite me to cook and have the family eat. This is where KitchenOS came in, it gave me a project and I have a direction of what I want to do.
So what did I do last year? I thought a lot. I read a lot of different stuff on both Android and just general programming paradigms to keep my skills up to date. And then I actually spent some time building out some of the features of KitchenOS up to what I would consider prototype level.
Knowing that parsing recipes from different websites was going to be a main function of what I needed, I decided to start working on this piece first. It also had the major benefit to it that I was going to write it in Java, and I already am very familiar with Java given that it is the programming language that I use the most professionally, when I do still code. The learning points here for me were more around how to leverage "new ways" (ok, I know most of them aren't new to every one, but when I was coding every day Java 8 wasn't even around) to code in Java and then to build out an application leveraging solely AWS technologies, focusing as much as possible to make sure I am not making a monthly payment for a server which brought me to AWS Lambda and DynamoDB. Given that I can use the free tier right now, who knows if I will ever end up paying for this unless other people start to use the application.
Going back to the days of me programming new features for IlliniBoard all the time and I wanted to scrape Illinois box scores web scraping and parsing has been one of those things I always wanted to do. I just never really spent the time to actually do it, mostly because I don't think I actually understood the necessary way to do it and that I could make web calls and then just parse text. Don't ask me why I was a moron then, I just was. So now that I finally understand conceptually what it is doing, I started the process of building out my scraper.
The architecture for it is pretty simple: an AWS Lambda function that I call passing in a URL. From there, the Lambda function leverages the JSoup HTML parser to parse the data through a collection of services. Right now I only parse from one site, Food Network so this will have to change because my code is written pretty tied to the Food Network as this snippet (which is really the whole Lambda function outside of error handling) shows:
Recipe recipe = new Recipe.Builder() .ingredients(FoodNetworkRecipeScraperUtil.getIngredients(recipePage)) .directions(FoodNetworkRecipeScraperUtil.getDirections(recipePage)) .title(recipePage.title()) .categories(FoodNetworkRecipeScraperUtil.getSiteCategories(recipePage)) .needsEnhancement() .sourceUrl(in.url()) .build(); recipe.save();
I have followed the Builder pattern pretty heavily in things I do on the side because while it adds a lot of boiler plate code, I think it is easier to read and use. And now if I want to add in some sort of compiler level restrictions I can do so within the Builder when I am making an object. Yes, I know I can do it with annotations through Lombok but I don't really like the idea of annotations generating a lot of the code I would be using. It feels like I am losing some of the control there, but I really haven't dug into it too much.
I stopped working with the Recipe Parser once I got to the point where I needed to manually enhance the recipe itself to clean thing up. That is when I started to dig into the next topic, building out something that I would use in a more traditional fashion to clean up the different things that I parsed.
So ending 2018, my recipe parser will perform the following tasks:
- Take a URL from FoodNetwork.com and parse it
- Add that data into the DynamoDB with some basic fields: categories, directions, ingredients, sourceUrl, title, uuid, and whether or not the recipe has been enhanced
This is what I like to call a "working prototype". I can also invoke the lambda function by leveraging the command line through Gradle which is how I was performing all of my "unit testing".
This was my first foray into any sort of Android development, and I can say it has kicked my ass. I am a web developer (from the late aughts) by trade, and with that comes some inherent thoughts in terms of how things are done, i.e. the user clicks a button to make a call to a server, the server performs the function and then redraws the page for the user. I know there is much more you can do on the front-end with technologies like React now, but I never got into them as the commerce world is very risk averse and trails the bleeding edge by quite a bit. To get into the world of native app development, I needed to have a problem to solve, and I finally did (albeit one that I could easily have written a web page for), enhancing the recipes that I have parsed from the web.
So I did something that I don't really normally do, I went right to the official Android developer documentation and read. It was really interesting and I probably spent a good month just reading and making "My First Android App" both for Android Things and just a traditional one that I ran through the emulator. It was an eye opening experience. The most interesting thing was getting into the Android Architcture Components and the different concepts there like LiveData, ViewModels, and Navigation Components.
Putting all of this together was definitely not easy, especially while at the same time I am attempting to teach myself Kotlin. Yep, I am a masochist.
So at times I struggled with Kotlin. At times I struggled with the documentation from Google. At times I struggled with the boiler plate code added by Android Studio not aligning to the documentation provided by Google. ALl of this caused for some trying times as I was continuing to push through. But over the Christmas week and last week I think I finally hit a break through in understanding the most basic elements of what I was doing. I finally have a working Android app that does the following:
- Loads up a Main Activity with an Image
- Click on the Image to call my RESTful service to get recipes
- Display a list of Recipes on the screen
- Click on a recipe to select it and go to a detail screen
Sure, there's a ton more. It is not even prototype level, but it is to a point where I now have samples in my own code that will let me move forward. I fought with this for probably two months, but I got it to a point last week where I said to myself "I finally get this, it makes sense." And I consider that a win heading forward.
A Look Ahead
So what's next? A lot.
Is there a plan? Not really, just a lot of ideas on what I want to build. That being:
- A recipe browser that has all of the recipes I like from the Internet, things I have made, and the cookbooks I own
- A meal planner that will allow me to plan and vary my family's meals throughout the week
- Something that will help me plan out grocery shopping a bit better, be it a list of some sort of something else (this is really vague in my mind right now)
So I am goign to move forward. This week I hope to end up with a working prototype of the Android app that I have. Of course, all of this will be without an actual Chrome or Android Tablet to run it. Then I will probably want to move back to more of the web scraping and parsing, and then also do picture parsing from my cookbooks thanks to the services provided by the different cloud hosts.
I also plan to try to do more of this as I think it helps me actually think and plan things out in my head. I don't want this to be all KitchenOS, but when it comes to things that I think about which aren't my family or work (you know the stuff I won't blog much about), this is about it.