26 August 2017

500 Commits of Summer: My story of FOSS and GSoC

This story of summer started in a dull grey winter at home. Bored, I started lingering around IRC channels and much like the Alice of Wonderland, stumbled into the wonderful world of FOSS. Little did I know, it was gonna be one of the best things that happened to me. Below is a story of bugs, PRs , repos, commits, and some more commits. But it is also a story of curiosity, learning,  frustrations (a lot of it), resilience (more than you think) and some amazing amazing people of the community. If I have to sum it up for you, I couldn’t think of a way better than this. So here it goes..

Disclaimer: It was a long journey, hence the long blog. 


The Story

#1 PICARD-851: Correctly update parent items on save

I started out slow. Figuring things out. Picard has a nicely organized and pretty code-base in python. Something that I have always admired and what motivated me to contribute to this project. I went through the tickets and found something I figured I could fix. It took me a complete day to figure my head around the code. Although there was a time when I felt helpless and was about to lose my patience, I  was finally able to find where the logic broke and fix it. It felt amazing making my first contribution to Picard.

#7 PICARD-546,287: Add support for tag removal

My first big pull request, where I was actually implementing a feature rather than fixing a bug. The entire pull request took a week to complete including the code reviews. I had to delve and add code across the file and tag handling module of Picard.

#120 Return empty metadata instead of empty dictionary

It was finally a month since I had started contributing to Picard. One of my biggest motivations to contributing regularly was this post by our org admin ruaok before the start of GSoC '15.  I wanted to hold myself to the same standard, and so I did, 1 PR a day. I was quickly fixing up as many tickets as I could, making sure I kept my mentor, zas' hands full with code reviews. Everyday was exciting for me as I would skim through Jira looking for tickets I could fix for the day. I managed to fix over 20 tickets in my first month.

#228 Add Picard 1.4 release notes

It was Valentine's Day and man o' man was it memorable day for my code-valentine - Picard. We finally released a major Picard version after more than 2 years and over 1000 commits. I also got featured on the release blog-post, something that made me feel really proud of all the work I had done so far. This was also the time that I had started to visualize how my GSoC project would look like. I started pitching proposals of a v2 for Picard and I got a lot of support for the direction that I wanted to head in. If you want a detailed look into what my final GSoC proposal looked like, click here.

#249 Merge pull request #632 from lalinsky/master

A few days, later another surprise awaited me - I finally got push access to the main Picard repo. This was the first pull request I merged. This pull request along with PR #633 was my first time foraying into the world of cross-platform issues. This I believe is the first OSX related bug I fixed, with help from luks and his trusty ol' Mac. After hours of remote sessions on the Mac that luks had setup for me, we were finally able to resolve a nasty bug that was affecting the OSX build.

#279 Update Qt5 port

This was around the time that I had started to work according to my proposal. We had already released Picard 1.4.1 to fix day 0 bugs that came with 1.4. The development efforts had started to shift toward Picard 2.0.

The first major GSoC task was up - Porting the entire code-base to Qt5.

It took a mammoth of a pull-request and multiple subsequent patches to finally have Picard up and running on Qt5. Major challenges to this port was the lack of documentation on porting for PyQt5. Apart from the PyQt porting guide, I also had to rely on the Qt5 porting guide written for C++ and figure out the equivalent python bindings. Lucky for me, the guys over at Riverbank (the people who made the PyQt bindings) have done a wonderful job at keeping the bindings as close to the C++ API as possible. This along with stack-overflow and the wonderfully documented Qt5 code, made the porting job much much easier.

Another challenge that I faced was making sure that the above code passed tests on our CI. Picard uses Travis CI, which uses Ubuntu 14.04 containers to build the code. Unfortunately, 14.04 does not have the PyQt5 package for Py2 and building it from source takes forever. As a result, I had to dockerize the repo and run the tests in Ubuntu 16.04 in docker in a Trusty container over at Travis CI. Talk about code-ception.

#280 Replace deprecated __builtin__

Next task on my GSoC checklist was equally big. I had to port all of the code to Py3. I was targeting Python 3.5 for the port. Of much help to me this time were the python tools, pylint and python-modernize. I used them to figure out the pieces of Py2 code that had been deprecated and to replace them with equivalent Py3 code. Major part of the problems I faced here were encoding issues. And believe me, they only get magnified if your app is cross-platform and multi-lingual.

Couple the above with PyQt5 behaving slightly differently for Py3, I had to plow through a lot of encoding/decoding/string/bytes issues. Pile Mutagen (a python audio tagging library that Picard depends on) on top of this mess and you have a recipe for an encoding-decoding disaster.

After lots of string/bytes fixes and banging my head against the wall porting this black magic code, I finally managed to port Picard to Py3 with all tests passing \o/.

You can find all the above commits in this massive PR.

#382 Update setup script to allow submitting pip packages

Next, to weed out further bugs, I wanted as many alpha testers as possible. To make their task easier, I packaged Picard into a pip package and released it on PyPi.

#393 PICARD-817: Enable high DPI support for Picard

I further tackled the issue of Picard not rendering properly on High-DPI screens. This issue mainly affected our OSX users and with the port to Qt5, it was easy to alleviate. Although not mentioned explicitly in the Qt5 documentation, I was able to find a couple of blog posts that helped me successfully implement it. Basically I needed to add up-scaled versions of the icons used by Picard in the Qt resources with a special suffix and Qt took care of the rest.

Since the upscaled version of the icons used by Picard were missing, I ended up designing the entire icon-set for Picard myself. This was my first time with tweaking with InkScape, but I think I managed fine. You can find the new icons here.

#404 Add coverage reports for codacy

Part of my GSoC project included testing the Picard code extensively. To help me get on with it, I setup Codacy on the Picard repo to display coverage and linting issues for all builds. This really helped with reviewing code and keeping contributions to the Picard repo clean and upto the quality that is expected. Coverage reports also allowed us to figure out which key pieces of Picard code was untested and target them to ensure there were as less regressions as possible.

#442 Migrate code to json API

My next big challenge was moving the webservice API calls from XML to JSON. Initally it meant refactoring the spaghetti code that was the Picard webservice module. I untangled the code and split it into an easy to add upon WebService and APIHelper classes.

Next came the actual porting part. I had to manually figure out the differences in the JSON and XML outputs of all the APIs used by Picard (mainly MusicBrainz API and AcoustID API).

This port also helped in figuring out the parts of MB JSON API that was missing or behaving differently than the XML API. Bitmap, our resident MB developer was quick to fix all the issues blocking the transition JSON API for Picard. Picard switching to the JSON API also served as a good way to test our upcoming MB WebService 2.5, that is supposed to be JSON only.

#485 Add appveyor config for windows tests

Testing a cross-platform app means you need to get your hands dirty on all 3 OSes. Primarily a Linux user, I had to blindly write CI configs for Windows and OSX. For Windows testing, I have not yet found a better platform than AppVeyor. It is free for FOSS projects and down-right amazing in terms of queuing and build speeds.

I didn't have any options when it came to OSX builds. Although Travis does provide the functionality, the number of OSX containers available are scarce compared to the number of jobs that get submitted. As a result, I faced long queuing times which made the blindly-writing-configs-and-using-Travis-to-test part very difficult. I managed to do it with a wee-bit of patience and the fact the OSX has bash.

#500 Add v2 plugin manifest compatibility

All was well and I was finally on the last step of my GSoC project. All that remained was tidying up the code, fixing any remaining bugs and switching to a more robust Plugin packaging and distribution API. I wrote a CLI tool for the same, which you can find here.

You can find all the above commits here.

Afterthoughts:

By some stroke of fate, my total commits to the Picard repo are exactly 500 in number as of this post. I shook my head in disbelief and amazement as I let it sink in. I have come a long long way. During this entire journey, I have learnt a lot of new things: version control, making cross-platform desktop apps, proper unit-testing, i18n, CI, making CLI tools, designing APIs, documenting and reviewing code and most of all writing modular, manageable and maintainable code.


Expectation

Reality

Frankly, I would've never expected last year that my GitHub would look so green. I have made over 1200+ contributions this year to FOSS. My coding skills have taken a giant leap from last year. I would recommend every coder to try and contribute to a large open-source project at least once during their  lifetime. It teaches you a lot of things that can frankly never be taught anywhere else, and the entire experience is totally worth it!

GSoC is a marvellous platform to incubate contributors to the open-source world. I want to thank my mentor zas (Laurent Monin), my org admin ruaok (Robert Kaye) for helping me throughout and making sure I had an amazing GSoC experience, and Google for making this possible.

This has been an amazing opportunity for me. MetaBrainz community has been nothing short of wonderful to me and I am looking forward to contributing more to MetaBrainz and exploring other FOSS projects.

24 March 2017

Free VPN(Unlimited connections)

So, one of the many benefits of being a student is that you get free access to a lot of stuff.

One of the best such student dev. kits is the Github Student Developer Pack.

It has lots of free goodies that you can go check out in detail.

One of the best things that is included in the pack however is 50$ of Digital Ocean credits.


And this is how we will setup our own private VPS that will give us free unlimited VPN connections for about ~12 months depending on your data needs.

Here are the steps to do so -

1. Make your GH account using a .ac or .edu mail id. (So that it is eligible for the GH student pack)
2. Get your GH student pack .
3. Make a new Digital Ocean account. (DO might ask CC info for verification purposes)
  Remember to use the following referral link while signing up to get free 10$ of Digital Ocean credits - https://m.do.co/c/0fb06a5c5cf9

4. Once you have created the account, create a support ticket to apply the GH promo code since only customer support executives can apply it to an account. Just keep the ticket title as "Help with applying GH student Promo code" and paste the promo code you got from GH student pack in the body asking them to apply the code for 50$ of credit. They will reply back in ~1 hrs with the promo applied.
5. Once you are signed up and ready to roll, create a droplet
6. Choose a config according to your needs, I prefer the 5$/pm droplet since it has about 1000gigs of bandwidth and running a VPN barely costs any RAM or CPU. Also choose a Data center region, I am using a US based data center since it allows me to access US only websites. You can choose Indian servers for better ping. Use Ubuntu 16.04 as your OS.

7. Once it is up and running, SSH into the droplet.
8. Run the following script in command-line -

wget https://git.io/vpn -O openvpn-install.sh && bash openvpn-install.sh

9.  Follow the interactive tutorial upon the execution of the above script. Use the default values except for the following options:
a. Which protocol do you want for OpenVPN connections?
  - TCP
b. What port do you want OpenVPN listening to?
  - 443
c. Which DNS do you want to use with the VPN?
 - Google
10. Copy the generated client.ovpn file to your client.
10. Install an open-vpn client (either on your phone or your Desktop) and run from the generated config.
 For ubuntu you can do this via -
sudo apt install openvpn network-manager-openvpn-gnome
11. Et. Voila, unrestricted unlimited VPN. (Also helps get past pesky proxy issues on your phone)


Have fun with your free VPN connection ;)

P.S. - You can also use the above droplet to host your own websites and other cool stuff. You basically have your own VPS! :D