External Pull Request and Creating a Spam Checker for Telescope

This week I was working on two projects: fixing an error with Pokemon Showdown's downloaded match replays, and creating a spam checker for Telescope

Pokemon Showdown Client

The Issue

 
Resume button appears under Play button on launch


The external issue I worked on was preventing the Resume button from appearing behind the Play button when viewing a downloaded replay from Pokemon Showdown: something I thought would be more complex than it ended up being, having worked with Pokemon Showdown before.

The Fix

After finding the class I had to work on, replay-embed.js,  I had to figure out how downloaded replays worked with replay-embed. While waiting for a response from Zarel, I tried generating a replay using my cloned version for Pokemon Showdown Client to no avail. Eventually, I learned from Zarel that the replay file has to be edited so that the script source points to my version of replay-embed. I changed the path to the filepath to my copy of replay-embed, but the battle display stopped showing up.

Initially, I thought this was an issue with my version or replay-embed, so I compared the version of replay embed on the Pokemon Showdown website, but I couldn't find any differences. I then realized that the '/' character required an escape character and that the filepath was not appearing properly, so I added in the necessary characters, fixing the filepath. However, even with the filepath being correct I was having the same issue. Eventually, I noticed that opening replay-embed.js in a browser gave a different filepath, so on a whim I tried entering that as the source, which fixed my issue.

The URL-style filepath
Having gotten a replay to work with my version of replay-embed, I could finally start working on fixing the issue. Looking through replay embed, I could not find where the resume button's HTML was being generated, which lead me to believe that the issue was somewhere else. However, I could not find any HTML for the resume button. Eventually, I found a battle.resumeButton in init() which I tried moving to pause(). To my surprise, just moving battle.resumeButton this fixed the issue.

Opening replay shows play without Resume

Pausing replay shows only Resume

Submitting the Pull Request and Community Interaction



Conversation with Zarel

After submitting my pull request, I received a comment from Zarel asking if the resume button was even necessary. Eventually, Zarel closed my pull request and fixed the issue on his own, with the issue apparently being an outdated API.

Telescope

The Issue

For my contribution to Telescope, I decided to create a spam/empty post checker. However, as I was reading up on spam checking strategies, I noticed that they all use a machine learning framework, so I settled on creating a set of basic rule for blog posts. The rules I decided on were:
-The blog post must have a title
-The blog post must have 20 words or more
-The blog post cannot be in all caps
When I started work on my spam checker, I wasn't sure if there was a way to get only the body contents of a blog post, as different sites use a different tag name for post bodies. Initially, I was planning to use the parsed blog from the Telescope site itself, but since the Telescope webpage itself is not up yet, I had to find a way to parse blogs on my own.

Eventually, I found feedparser-promised and used that to parse blogs from an rss feed.
After getting feedparser to work, the next step was to create the rule checks. I created functions for removing tags (which I later replaced with text-parser.js), getting word count, and checking for capital letters. Once that was done I tested them to make sure they worked, then began to write tests for my code.

Word count, capital letter count, and total letter count functions

A big issue I ran into while creating tests was that I didn't know what feedparser was returning, so I couldn't create an instance of that object for the purpose of testing. I figured out that individual blog posts can be accessed by indexing the returned object, so I created a blog with posts for test data and based my tests of that. I also had to figure out how to parse the test data before running tests, and I learned about the beforeAll() function.

Unit tests
Once all my tests were passing, I created a pull request for my branch.

The Pull Request and Changes

I received several change requests after creating my pull request. The first major change I worked on was implementing a fully featured spam filtering service. At first I tried using the spam-detection package, but after running into issues with a missing dataset, I decided to use spam-filter, a spam filtering package that has been trained with spam SMS data adding it on top of my existing checks. I then created another blog post with spam text, and created a new test to make sure spam-filter was working as intended.
The next major change I implemented was using text-parser.js instead of creating my own function to remove HTML tags from text. Since text-parser.js is an async  function, I had to change spam-checker to be async as well, which also required me to change my tests. I push the changes once I thought it was working, but as one of my reviewers was testing my code, he revealed that the function was not working properly outside of the tests I wrote, and that it was returning undefined. Eventually I was told that the way I was handing the returns from the async function text-parser was weird, and the function was fixed once I changed it.

Suggestion about how I handled textParser

Experience and Lessons Learned

While working on the Pokemon Showdown Client, I learned that sometimes the project owner won't like your solution, and may even take the issue into their own hands instead of giving suggestions. I feel like this experience was an extension of my last contribution to the Pokemon Showdown Client during Hacktoberfest, where my initial suggestions were rejected and I eventually just had to follow what the owner wanted

Working on the spam checker for Telescope, I learned how difficult it is to work on a project when there isn't much to look at or get examples from. Even with the basic concept in my head, I wasn't sure of the specifics of how the website would work, and eventually had to work on my own assumptions. I also learned that in a project with so many contributors at once, what one person does can radically affect your own work, even if they're separate components.

On the technical side, I learned more about writing unit tests and a lot more about handling async functions. I hardly ever use async in my own work, so being forced to use it for telescope was a pretty new experience. I also learned that there are nodes for most things, and that I should probably look online for packages that do what I need before making it on my own.

Overall, my experience with these projects was pretty stressful, partially because I didn't leave myself a lot of time to finish the work, but I feel like I learned a lot from it..

Comments

Popular posts from this blog

Adding 'Favorite' System to Pokemon Showdown: External Pull Request and Final Week of OSD600

Reading Level in Telescope: Internal Contribution