Monday, December 10, 2018

Final PRs for DPS909





Focus

As I stated in my previous blog entry, there was a feature that I decided to work on for the Focus browser on iOS that I personally wanted to see implemented. I ended up finishing the fix and hope to see it implemented into the release version soon. The fix had to do with how the application was setting the user agent. To fix the issue, I implemented a function to the user agent class that would allow it to persist its desktop user agent state.

Brave

I decided to work on another issue for the Brave browser on iOS. This issue had to do with the favourite's view showing a lower resolution icon for some sites. After some digging around, I noticed that the code that they were using had them passing in the favicon manually and then upscaling it to fit the size of the favourites icon view. Since a lot of the codebase is based off of the Firefox application, I decided to take a look at how Firefox implements this functionality. I found that instead of passing in the favicon manually, they were using a function to get it from the website instead. I then changed the code to work more similarly to how firefox was doing it and ended up correcting the error.

Monday, December 3, 2018

Major apollo Milestone and a Change That Impacts Me





apollo

A big milestone that I wanted to complete was to change the legacy code that I had before deciding to open source apollo into a working codebase with the new database architecture. Previously - for the sake of simplicity - I stored all of the recording information in one table. This means that every new instance would have the recording name, artist name, label name, genres, etc. in one table. Moving forward, I decided to create seperate tables for Recording, Artist, Genre, Label, and Producer. This means that my old code that would fetch and input information wouldn't work anymore and would have to be changed to reflect the new architecture.

In my previous major commit, I added the functionality to input new recordings. In this commit, I added the functionality to update recordings that may already be present in the database.

Now that this milestone is finished, I am comfertable with being able to introduce this project to others. While it is still in its early infancy stages, riddled with bugs, I hope that I'll be able to get a working version up soon to be able to attract people to my project.

Focus

While using Focus as my goto browser, I noticed something about one of their features that I didn't like. When browsing a site, such as github, I would turn on the "Request Destop Version" for an easier browsing experience. What I don't like is that whenever you go to a subdomain of the website, the destop version does not persist - you have to continuously request for the desktop version whenever you go to a new page. I was going to file an issue on the github but found that one has already been made months before. I am planning on fixing this issue. This is the first issue that I'll be fixing that will actually change the way that I want to use the application. It's a good feeling to be able to change something about an app that you use daily.

Monday, November 26, 2018

Getting apollo working





apollo

I've been working on getting apollo to work for existing records that are found from the HTML. As it currently stands, apollo will only append to the database if it finds a new record in the HTML. This is a good first step but I need to get the application to the point to it updating existing records as well. I already have some legacy code set up for doing this but it only works with an older, unused, database architecture. With the change to the new architecture, I need to reformat a lot of the functionalities to make it work.

I'm trying to make the new functionality very basic and continue improving it after I get it actually working. For example, if apollo finds a record for a new recording in the HTML, and the genre is "Electronic, House, Trance" - the way that I'm currently building it would store that entire string as its own Genre. This is fine for now but in the future, I'd want to seperate the records into 3 different genres. As it is right now, I'm only worried about getting a one-to-one relation between the Recording table and other tables. As the code evolves and becomes ready for beta, I'm planning on creating many-to-many relationships instead. I've already created bridges for this to be possible in the future. My plan is to work my way up, starting from the very basic functionality into more specific functionalities in the future.

I think this is the most important step I can take right now - getting the project working at its minimum. After that, I will want to focus on adding more tools to the project, such as improving Travis, adding test cases, etc. to get the project going and easier for potential contributors to contribute to.

Sunday, November 18, 2018

Introducing Travis to apollo & Reformatting UIKit's Cells





apollo

I was recommended to set up Travis CI for my project. This was something that I've been curious about setting up before so I thought it would be a great time to learn how to. Setting up Travis wasn't as easy as I thought it would be. The documentation wasn't too helpful - although I might have just been looking at the wrong parts. I changed the Travis config file dozens of times with different techniques that I found online to try to get it to work. After hours of failing, I finally got it to build successfuly. Right now, the file is very basic so I am planning to look at examples of other open source projects' Travis config files as a reference on how to improve my own.

Something that I found really cool about Travis is the ability to have it email you when a test fails. This a pretty useful just-in-case feature that could prove to be useful in the future.

focus

The issue that I fixed for the focus iOS browser was one where the settings view would have missaligned labels in the newly added cells that had a Learn More button appended to them. After tinkering around with the code, I found out that the reason for this happening was because of the way the Swift framework responsible for the layout of the cell (UIKit) handles their internal labels. The code wanted to reposition the new labels to make room for the added Learn More button and ended up hardcoding the value for the left margin. This doesn't work because of the different widths of iPhone - a margin of 14 will not stay consistantly aligned for the different widths of different iPhones and therefore the width needs to be set dynamically.

The fix for this issue was to create a new cell object and add custom labels. Luckily for me, the view was already doing that for some views so I had a reference to how to create these new cells. I made the custom layout for the cell and adjusted the old code for cell layout to work with the new cell view.

In the below images, note the layout of the labels for the cells with the Learn More button underneath. This issue that looks like an easy fix actually required a lot of effort due to the way the cell's internal label layout behaves. Creating a non-hackish fix for this issue required a complete redesign of the cell's structure to work dynamically.

Before

After

Sunday, November 11, 2018

Introducing apollo



The issue for focus-iOS that I was planning on working on ended up being taken. Because of this, I decided to work on one of my own projects instead. Over the summer, I was working on a personal closed-source project. I didn't get too far with it so I decided that it would be a great opportunity to open source it and see if anyone would want to contribute.

apollo

apollo is a webscraper written in C++ using the cURL library. It scrapes and stores information about upcoming music albums in a local postgreSQL database. The goal of this project is to create an internal database that holds information about artists, recordings, genres, etc. - similar to that of Discoggs but available to anyone. I'm hoping on using this as the backend of an iOS application that I'm planning on writing as a compliment to apollo. That application will act as a calendar for upcoming albums. I'm hoping to create an application that can track releases as well as recommend upcoming releases.

What I Worked On

To start off the project, I had to add the README and make sure that any potential contributors know how build and run apollo. To do this, I included the steps to take to build the project. I left some contribution notes to make some parts of the codebase clearer for new contributors. To make it easier, I made a bash shell script to create a user and database, as well as populate the database with tables needed to run the application.

A lot of the code that I was working on had to be changed because I restructured the database. I realized that the codebase as it was initially would not run properly with the new database so I set out on fixing it. I created an issue to log my progress of restructuring the code base. Fixing everything at once would have taken too long and I didn't want that to put off new contributors so I focued primarily on getting the base of the code to work. With this fix, new contributors will be able to run apollo without any errors and would be free to help contribute to the project.

I also made sure to make some issue that others can take. I'm hoping to get this project to a point where others will want to contribute.

Monday, November 5, 2018

Focusing on Focus



I've had a lot of fun contributing to Mozilla's focus browser for iOS and have learned a lot while contributing to the project so I decided to continue along the path and tackle larger issues. I've mostly been fixing bugs while trying to get familiar with the inner-workings of the application but now I've decided to work on something more visible.

What I'll be working on

The issue I decided to pick up deals with a new feature being introduced in an upcoming release. I'll have to look into how the search suggestions are triggered by the search engine to be able to complete this feature.

There is already code in place for the layout of the views and search suggestions which makes it much easier for me to complete my contribution. I can use code that is already implemented as a reference for how to also include site suggestions, instead of only search suggestions.

This functionality was something that I was curious about so I'm excited to begin working on it. Working on an application that I use daily all while learning new techniques and skills is the main reason that I enjoy working on OSS so much and plan on doing so for the forseeable future.

Tuesday, October 30, 2018

Hacktober Summary



Hacktoberfest was a really fun introduction into contributing to open source projects. It was a great learning experience. I've always had an interest in contributing to open source software but was always a bit too nervous about getting started with a new project - it was intimidating to ask to work on an issue as someone completely new to the codebase. Hacktoberfest forces you to step out of your comfort zone and work on 5 issues in a month, right off the bat.

What I Learned Through Each Pull Request

My first pull request tackled a layout problem for the focus-iOS web browser by Mozilla. Working on this issue taught me to take my time reading through a codebase that I am unfamiliar with - I shouldn't rush into a new project expecting to fix the issue quickly if I don't know the inner workings of the application.
After completing my first pull request, I noticed a new issue that dealt very closely with my previous fix. Because of my previous knowledge with the code surrounding the issue, I was able to quickly make the fix and submit my second pull request. Going from not knowing anything about the codebase whatsoever from the start of my first pull request to knowing exactly how to apply a fix for my second pull request was a really satisfying fealing. Working on this project allowed me to quickly learn that there's no reason to be nervous about starting on a new project if you take your take learning relevant parts of the codebase.
The third issue I worked on was for the Brave iOS browser. I thought it would be a good idea to work on a similar project to the one that I previously worked on. This was the first pull request where I had my code reviewed. This was a great introduction to the community aspect of working on open source projects.
I came back to focus-iOS for my fourth issue to work on another layout issue - this time more difficult and more critical than the others. I wanted to challenge myself going forward. At first glance, I had no idea where to start but after talking with the community and digging through the code, the fix became clear. Working on this issue taught me that just because something may look challenging, it only looks that way because you haven't read through the code yet. Once you do, the factors that play into the fix should become apparent.
For my last issue, I decided to work on a feature, rather than just fixing a bug. The fix itself wasn't too complicated because I knew what to look for because of my previous contributions. The problem was that the fix was supposed to mimic the functionality with the Android version of the browser but because I didn't have an Android device, I had to rely on the help of the community to guide me on the right path for this fix.

What I Learned

Hacktoberfest was a great learning experience. Because of it, I am no longer anxious about joining new projects. I have already experienced what it takes to begin contributing to a new project and know what to do for the next time that I choose to send in my first pull request to a project. Hacktoberfest also taught me about the community aspect of open source - there are people of all levels of experience working on open source projects. If you get stuck on something, you can rely on others to help fix the issue.


Hacktoberfest introduced me to projects that I see myself contributing to on my free time. This was a great experience to be a part of and I am looking forward to joining again next year.



My Pull Requests

Monday, October 29, 2018

Hacktober V

This is my fifth blog post in my Hacktober Series. Throughout these 5 blog posts I hope to explain my introductory work into contributing to Open Source Software.

What I Worked On

I continued to work on the focus iOS browser for my fifth contribution for Hacktoberfest. This time, I decided to tackle implementing a new feature rather than fixing a bug. Due to the iOS and Android versions being made seperately, their codebase differs. The issue I decided to work on would try to lessen the differences between the two. I chose to work on adding a quick add to autocomplete tab. This would allow a user to add a website to their autocomplete list without having to go through the settings.

The Feature

The great thing about working with open source software is that a lot of the code has already been written for you. I researched how the layout is done for the already existing button in the dropdown under the URL bar. I added another copy, tweaked some parts, and created the functions called by pressing the button. To create the function, I referenced another part of the project. There is already a method for saving new URLs to the custom autocomplete list so I just had to copy and modify the already existing code to work in this scenario. Contributing to a project this size allows me to make valuable contributions by referencing existing code, all while learning.



Closing Thoughts

Hacktoberfest was a really fun experience for me. I got to contribute to projects that interest me and I'm sure I'll continue to contribute to these projects in my free time. This was a great introduction to contributing to the world of FOSS - something that I see myself doing more of in the future.

My Pull Requests

Thursday, October 25, 2018

Hacktober IV

This is my fourth blog post in my Hacktober Series. Throughout these 5 blog posts I hope to explain my introductory work into contributing to Open Source Software.

What I Worked On

I went back to the focus iOS browser for my fourth pull request. This time around, I decided to tackle an issue where pressing on the settings button would break the layout for the web view. The reason I chose this bug in particular is because of the needs investigating label attached to the issue. I figured it'd be a great issue to try to fix in order to continue learning about the codebase. To fix this problem, I had to investigate the cause for the broken layout.



The Fix

The fix itself was easy. Just like in my second commit, this fix was a line long.



The real challenge behind this pull request was trying to figure out what was causing the problem. After some digging around, I found out that the code was setting urlBar.shouldPresent to false when opening the settings popup (see code above). This caused the urlBar object to never call any of its delegate methods to active. Since it never activates, its layout remained deactivated as well. The webview bases its bounds based on the bottom of the urlBar - since the urlBar's overwritten constraints were never turned back on by the delegate methods, the webview used the urlBar's default constraints to base its own bounds on. This is what created the layout issue.

After looking through older commits for the functionality, I found that the reason that urlBar.shouldPresent was originally set to false was to prevent the application from displaying the overlay when launching from an extension. After failing to be able to reproduce this, I decided to ask the community and received a reply pointing me to the right direction.

After checking the history on git, I realized that the settings view controller was not originally presented modally and that's why the urlBar was turned of when viewing the settings. Since the change, the bug that setting urlBar.shouldPresent to false was supposed to fix was no longer possible to reproduce - instead of a fix, it itself became the cause of a new bug - so it was safe to delete.

My Pull Requests

Hacktober III

This is my third blog post in my Hacktober Series. Throughout these 5 blog posts I hope to explain my introductory work into contributing to Open Source Software.

What I Worked On

This time around I decided to try out another open source Swift project. After some digging around Github, I found the repository for the Brave iOS browser. This felt like the perfect second project to work on since my first two contributions for Hacktoberfest were for the focus iOS browser. This would allow me to transfer my knowledge between the two iOS browser projects.

After looking through some of the posted issues I ended up finding one that I wanted to work on. It was a layout issue where a popup would clip off the phone's screen if it was in landscape mode. Instead of rushing into the problem, I decided to take my time and read through the relevant codebase - as I learned to do after my first Hacktoberfest contribution - to figure out an approach on how to tackle this problem.


The Fix

I had to work out a simple algorithm to layout the subviews to change their sizes proportionally to shrink the container to fit in the bounds of the screen. Initially, the code would set the heights of the views based on the available width and font size.



To fix the issue, I had to figure out the amount that every element had to be resized by to allow for the entire popup to fit on a compact screen. To do this, I had to take the external heights of the popup into consideration, including the buttons and the padding between the views. The following is the formula used to determine the resize percentage to fit:



The code was then changed to take the resize percentage into consideration.



Code Review

This was my first commit during Hacktoberfest to recieve a code review. The comments were mostly about best practics to follow and code cleanup. For example, one of the comments was about potential recursion within my code. After reading the comment I began to work on a method to avoid having to use recursion and reduced the risk of a potential bug arrising in the future. Having my code reviewed with suggestions on how to alter it makes me feel like part of a community. It's more than just a collection of people pushing code to a project - it's a community that works together to create the best codebase possible. Being able to have a back-and-forth discussion with my reviewers makes me feel like an equal even though I'm new to the project.

My Pull Requests

Saturday, October 13, 2018

Hacktober II

This is my second blog post in my Hacktober Series. Throughout these 5 blog posts I hope to explain my introductory work into contributing to Open Source Software.

What I Worked On

After my first Pull Request to Mozilla's focus browser for iOS, I saw that a new issue was opened in the repo - one that was very similar to the bug that I just fixed.

I made a comment on the issue that I could work on it as it related very closely to my previous pull request and began to look through it. Unlike my previous work that took me a couple days to fix, this one took me less that 10 minutes. It was so closely linked to what I previously worked on that I immediately knew what the problem was and how to fix it.

The fix itself was less than a line long - all I had to do was change the object that was being affected by the functions. I changed the code from addGestureRecognizer(singleTap) to textAndLockContainer.addGestureRecognizer(singleTap).

When I first sent in the pull request, I undervalued the work a lot. I didn't think that a commit this small was anything to be proud of. But then I realized that this fix that took me less than 10 minutes to fix was only possible because of my past commit that took over 2 days to fix. If I tried to fix this bug without having fixed the previous bug, I'm sure it would have taken me much longer to figure out.

Through this fix, I've learned that what may seem and look like a simple fix to someone who has worked with the code before, may not be as simple to someone coming in for the first time. It was also a very good introduction to how previous fixes are great at paving the road for future fixes.

The more you work, the more you learn, the quicker and more simple fixes seem to be. The more you work on a project, the more familiar you become with how to continue improving it.

My Pull Requests

Friday, October 5, 2018

Hacktober I

This is my first blog post in my Hacktober Series. Throughout the next 5 blog posts, I hope to explain my introductory work into contributing to Open Source Software.

What I Worked On

For my first Hacktober Pull Request, I decided to contribute to Mozilla's focus browser for iOS. This is a browser written in the Swift programming language with the intent of an increased anonymized browsing experience. I looked through the issues and found one that I thought was simple enough to do within a week yet would provide a challenge. Fixing the bug wasn't as easy as I thought it would be - the solution wasn't too straightforward - but with the help of the existing code as reference, I was able to find a solution.

I Think I'm Too Used To School Work

When working on a project at school, the instructions are laid out for you. You know which functions to work on, what they should do, and what they shouldn't do. Working on OSS was a completely different experience. School work is straightforward and because of that I'd be able to jump straight in and code. Being used to coding in this way made my first day trying to fix the bug very frustrating. After a day of trying to fix functions that looked as if they could be related to the bug without success, I decided to look at it again the next day.
This time, I decided to take my time. I removed all of my edits to the code and spent around an hour just reading the code and drawing out the dependencies. This finally allowed me to find a solution. In the future, I plan on spending a majority of my time reading the code, as opposed to my previous strategy of code first, read later.

My Pull Requests

Tuesday, September 25, 2018

My First Pull Request to an Open Source Project

I've worked with GitHub before for private projects but have always wanted to contribute to an Open Source project. The problem was that I didn't know how to start. All these projects that I have looked at seemed way too complicated - I didn't want to spend hours learning the codebase. My problem wasn't not knowing the where to start, it was not knowing how to start. Thanks to my Open Source elective in school, I learned what to look for to get started in a larger project. I shouldn't be trying to learn the entire codebase - that would take way too long - instead, I should learn how to read smaller chunks of code in a way efficient for an issue that I would want to tackle.


What I Worked On

I contributed to an Open Source Node.js project called filer. This was a great first project to work on because of how much I learned. I wrote a [f]chmod test for Node.js's Promises module. Note that I have not coded in Node.js before, so I was a bit intimidated coming into this project. But having access to other tests helped me a lot - I didn't have to actually learn the language at a professional level to be able to contribute - I was able to see what the other tests did and mimic that style, applying it to my objective.


Trial and .catch( error )

After I studied the other test function, I began on working on the chmod and fchmod Promise tests. I quickly ran into a problem. Having to create a file, change its mode with chmod and fchmod, and then check if the mode was actually changed with stat and fstat required me to nest my function - doesn't sound too difficult but since I never used Promises. When purposly changing some values to see what it would do if it would ever fail, I found out that the way that I wrote my function did not call the done() function which signalled the end of the test. Something weird was happening, it would catch the error (I think?) but wouldn't print the error or call done() -- instead it would time out. Luckily, filer has a helpful community around it. I saw someone was having a similar issue to mine where their Promise function wouldn't hit the done() block either. Lucky for them - and me - someone commented that done() was going to be deprecated anyways and provided a different strategy to tackling the problem. Using this information, I was able to finally fix my test case and create a pull request for it in hopes of it getting merged in.


The Pull Request

I also learned about what happens after the actual coding. I had my code reviewed, and reviewed someone elses code. I used Slack to ask questions and help others with their questions. The community aspect behind working on Open Source projects is really appealing to me.

The open source method of working as a team was a really fun experience for me and I really enjoyed it. I'm excited to continue contibuting to open source projects in the future - maybe even starting one of my own.

Wednesday, September 12, 2018

How 'chmod' Works In Node.js

Everyone experienced with a Linux environment should be familiar with the chmod command. Whether you're an administrator setting permissions for your users or a developer creating files through your Node.js server, this simple command will help you protect your restricted files from any unauthorized user.

In this blog post, I hope to cover the difference between chmod and fchmod and how they can be used in Node.js to work with your server.


chmod vs fchmod

To use these commands in Node.js, you must access them through the File System module's API.

The chmod and fchmod functions ran on a Node.js server are actually calls to the Linux versions by the same names. In standard Node.js fashion, the chmod commands are executed asynchronously and therefore require a callback function to be used as a parameter. Apart from the callback, the other two parameters of the functions remain the same.

The two commands follow a similar syntax. The only differences being chmod using a path to a file while fchmod using a file descriptor.


// chmod.js
// fs.chmod(path,mode,callback)
// path <string, Buffer, or URL>
// mode <integer>
// callback <Function> => err <Error>

const fs = require('fs');
fs.chmod('private.txt', 0o740, (err) => {
if (err) throw err;
  console.log('[chmod] Success');
});


// fchmod.js
// fs.fchmod(fd,mode,callback)
// fd <integer>
// mode <integer>
// callback <Function> => err <Error>

const fs = require('fs');
fs.open('private.txt', 'r', (err, fd) => {
  if (err) throw err;
  fs.fchmod(fd, 0o740, (err) => {
    if (err) throw err;
    console.log('[fchmod] Success');
  });
});


Note

If you use fs.open to create a file, you can also set the permissions inline by using the optional mode parameter. For example:

fs.open('newfile.txt', 'a', 0o740, (err, fd) => {...});


Promises

With the introduction of Promises into Node.js, v10.0.0 provided us with a Promise version of using the chmod command asynchronously.

// chmodPromises.js
// fsPromises.chmod(path,mode)
// path <string, Buffer, or URL>
// mode <integer>

const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.chmod('private.txt', 0o740)
  .then(() => console.log('[chmod Promises] Success'));


Synchronization

Since both functions run asynchronously, you may run into a bit of trouble if you need them to run synchronously. Node.js provides a synchronous alternative to both functions. To run chmod and fchmod synchronously, you can use the fs.chmodSync and fs.fchmodSync commands respectively. These commands, being synchronous, do not require a callback function. Any error checking will have to be done manually.


// chmodSync.js
// fs.chmodSync(path,mode)
// path <string, Buffer, or URL>
// mode <integer>

const fs = require('fs');
fs.chmodSync('private.txt', 0o740);
console.log('[chmodSync] Success');


// fchmodSync.js
// fs.fchmodSync(fd,mode)
// fd <integer>
// mode <integer>

const fs = require('fs');
fs.open('private.txt', 'r', (err, fd) => {
  if (err) throw err;
  fs.fchmod(fd, 0o740);
  console.log('[fchmodSync] Success');
});


Note

Node.js provides a few alternatives to how to input a file mode for the chmod and fchmod commands. The file system provides you with a few constants to use in place of manually inputing octal numbers.

Constant Octal
fs.constants.S_IRUSR 0o400
fs.constants.S_IWUSR 0o200
fs.constants.S_IXUSR 0o100
fs.constants.S_IRGRP 0o40
fs.constants.S_IWGRP 0o20
fs.constants.S_IXGRP 0o10
fs.constants.S_IROTH 0o4
fs.constants.S_IWOTH 0o2
fs.constants.S_IXOTH 0o1