{"@attributes":{"version":"2.0"},"channel":{"title":"Blogs on Gary Kim: Website","link":"https:\/\/garykim.dev\/blog\/","description":"Recent content in Blogs on Gary Kim: Website","generator":"Hugo -- gohugo.io","managingEditor":"gary@garykim.dev (Gary Kim)","webMaster":"gary@garykim.dev (Gary Kim)","copyright":"\u00a9 2019-2020 Gary Kim,<br \/>All Rights Reserved<br \/>Content licensed <a href=\"https:\/\/github.com\/gary-kim\/website\/blob\/master\/LICENSE\" target=\"_blank\" rel=\"noopener noreferrer\">CC-BY-SA-4.0<\/a>","lastBuildDate":"Thu, 10 Sep 2020 00:00:00 +0000","item":[{"title":"Go Nextcloud Talk Library Release","link":"https:\/\/garykim.dev\/blog\/2020\/09\/10\/go-nextcloud-talk-library-release\/","pubDate":"Thu, 10 Sep 2020 00:00:00 +0000","author":"gary@garykim.dev (Gary Kim)","guid":"https:\/\/garykim.dev\/blog\/2020\/09\/10\/go-nextcloud-talk-library-release\/","description":"<p>If you want to interact with <a href=\"https:\/\/nextcloud.com\/talk\">Nextcloud Talk<\/a> easily in a Go project, you can use the Go Nextcloud Talk library.<\/p>\n<p>You can find the godoc documentation <a href=\"https:\/\/pkg.go.dev\/gomod.garykim.dev\/nc-talk?tab=doc\">here<\/a>.<\/p>\n<p>Relevant Links:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/gary-kim\/go-nc-talk\">Source Code<\/a><\/li>\n<li><a href=\"https:\/\/pkg.go.dev\/gomod.garykim.dev\/nc-talk?tab=doc\">godoc<\/a><\/li>\n<\/ul>\n<h3 id=\"how-to-use\">How to use<\/h3>\n<h4 id=\"add-the-library-to-your-project\">Add the library to your project<\/h4>\n<pre tabindex=\"0\"><code>GO111MODULE=on go get gomod.garykim.dev\/nc-talk\n<\/code><\/pre><h3 id=\"current-usage\">Current Usage<\/h3>\n<p><a href=\"https:\/\/github.com\/42wim\/matterbridge\">Matterbridge<\/a> from version 1.18.0 onwards includes support for Nextcloud Talk. This is done using the Go Nextcloud Talk library.<\/p>"},{"title":"SAS Powerschool Enhancement Suite has a new maintainer","link":"https:\/\/garykim.dev\/blog\/2020\/09\/08\/sas-powerschool-enhancement-suite-has-a-new-maintainer\/","pubDate":"Tue, 08 Sep 2020 00:00:00 +0000","author":"gary@garykim.dev (Gary Kim)","guid":"https:\/\/garykim.dev\/blog\/2020\/09\/08\/sas-powerschool-enhancement-suite-has-a-new-maintainer\/","description":"<h3 id=\"what-is-sas-powerschool-enhancement-suite\">What is SAS Powerschool Enhancement Suite<\/h3>\n<p>SAS Powerschool Enhancement Suite (better known as SAS PES) is a browser extension for Firefox and Chromium-based browsers that adds many convenient features when using Powerschool at <a href=\"https:\/\/www.sas.edu.sg\/\">Singapore American School<\/a> as a student. The extension was originally for use by only high school students but is now also used by middle school students and parents alike. If you want to learn more about the project, please visit our <a href=\"https:\/\/github.com\/sas-fossdev\/saspes#readme\">README<\/a>.<\/p>\n<p>Relevant links:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/sas-fossdev\/saspes\">Source Code<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/sas-fossdev\/saspes\/releases\">Firefox Extension Download<\/a><\/li>\n<li><a href=\"https:\/\/chrome.google.com\/webstore\/detail\/sas-powerschool-enhanceme\/ehnkngeidilnoabcjjimkomcggndbhnk\">Chrome Web Store Entry<\/a><\/li>\n<\/ul>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:center\"><\/th>\n<th style=\"text-align:center\"><\/th>\n<th style=\"text-align:center\"><\/th>\n<th style=\"text-align:center\"><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:center\"><figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/projects\/saspes\/1.png\"\nalt=\"Main Screenshot\"\/>\n<\/figure>\n<\/td>\n<td style=\"text-align:center\"><figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/projects\/saspes\/2.png\"\nalt=\"Second Screenshot\"\/>\n<\/figure>\n<\/td>\n<td style=\"text-align:center\"><figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/projects\/saspes\/3.png\"\nalt=\"Third Screenshot\"\/>\n<\/figure>\n<\/td>\n<td style=\"text-align:center\"><figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/passing-saspes-maintainership\/image1.png\"\nalt=\"Forth Screenshot\"\/>\n<\/figure>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"new-maintainer\">New Maintainer<\/h3>\n<p>As I am no longer associated with the school, I felt that it would be better if someone that was still associated with the school continued to maintain the project. Someone that is still in touch with the students, faculty, and environment of the school would be far better suited to continue to evolve the project to serve its users best. To that end, I have passed the role of maintainer onto <a href=\"https:\/\/github.com\/suhas-13\">Suhas Hariharan<\/a>. Suhas has made several new features and fixes in the extension that many users actively use.<\/p>\n<p>I will still be available as a co-maintainer to advise and help fix issues but Suhas is now the primary maintainer.<\/p>\n<h3 id=\"some-history\">Some History<\/h3>\n<p>Developing this extension has been quite the journey for me. I started the project while learning Javascript and the project evolved with me. As I learned more about Javascript and the tooling available, the project gradually became more capable and more complex in both its code and its tooling.<\/p>\n<p>The idea for the extension was originally by <a href=\"https:\/\/tcode2k16.github.io\/blog\/\">Alan Chang<\/a> (<a href=\"https:\/\/twitter.com\/tcode2k16\">@tcode2k16<\/a>), a great friend of mine. The idea for the extension at first was rather simple. There was no way to view the current semester GPA in Powerschool but everyone knew how to calculate it themselves. That calculation was simple so why not do it automatically and put it in the page using an extension? Alan quickly made a prototype of this idea.<\/p>\n<p>I was very intrigued when I saw the extension and the idea to improve the experience of students using extensions. I started working on an extension to do something similar for Schoology, another service that Singapore American Students used (You can still see the remnants of this attempt <a href=\"https:\/\/github.com\/gary-kim\/sasses\">here<\/a>). After a while, it became clear that maintaining this extension was going to be painful due to the way that Schoology is built, especially with my limited knowledge in Javascript at the time. I gave up on the idea for a bit thinking that I&rsquo;d come back to it later. I asked Alan at this point if he was planning to release the extension publicly and, if not, if I could use his idea for a Powerschool extension and try to develop it further. He said he&rsquo;d be fine with me developing his idea further so I got to work.<\/p>\n<p>I came up with some ideas about features that I thought people would find useful and implemented a few basic ones. I quickly got a few friends to be beta testers for my extension. They would provide me feedback in the form of ideas and bugs. Their help, ideas, and bug reports were invaluable. I implemented many of these ideas and continued to improve upon features already in the extension with the help of my beta testers such as Sanjo Ray. Thank you for helping make the project so much more successful by giving valuable feedback.<\/p>\n<p>The extension was then publicly released in November of 2018. News of the release spread by word of mouth between students and within 2 weeks, more than 100 people had installed the extension. Within half a year, more than half the students in the high school had the extension and it became more common to see students with the extension than without.<\/p>\n<p>The project kept evolving from that point as I learned more about Javascript, its tooling, and its community. I learned about the more modern Javascript features I could use if I migrated to using <a href=\"https:\/\/babeljs.io\/\">Babel<\/a>, so I did. I learned about how <a href=\"https:\/\/webpack.js.org\/\">Webpack<\/a> could simplify my dependency situation, so the project migrated to it. I learned how to use <a href=\"https:\/\/vuejs.org\">Vue<\/a> as I got involved in the <a href=\"https:\/\/nextcloud.com\">Nextcloud<\/a> project, so large parts of the extension was migrated to <a href=\"https:\/\/vuejs.org\">VueJS<\/a>.<\/p>\n<p>In early 2019, I realized that development could be much quicker and better with more people involved so started working to make the project more inviting to potential contributors. Suhas was one of the people that started contributing significantly.<\/p>\n<p>It was a fun and exceptionally educational ride that taught me Javascript in production, continuous integration, and the development cycle\/relationship that consisted of not just me, but the testers and users that provided the insight needed to improve the project.<\/p>\n<p><strong>Thank you to everyone that contributed code to the project. Thank you to everyone that provided me ideas, gave me feedback, and tested the project. Thank you to everyone that used the project and made it such a success! It has been a fun ride and one that I would repeat in a heartbeat. Have fun and stay safe!<\/strong><\/p>\n<h3 id=\"milestones\">Milestones<\/h3>\n<p>A lot of the milestones are visible in the project <a href=\"https:\/\/github.com\/sas-fossdev\/saspes\/blob\/master\/CHANGELOG.md\">changelog<\/a>.<\/p>\n<ul>\n<li>2018-09-15: First Version with semester GPA display. At this point, the project was in a private repo.<\/li>\n<li>2018-09-25: Ability to view final percent of classes<\/li>\n<li>2018-09-25: Around this time, the first beta testers came on. The project was in a closed alpha state at this point but having beta testers to tell me how useful the features I was developing were and what new features would be nice to have was invaluable.<\/li>\n<li>2018-11-02: Addition of the hypothetical grade calculator<\/li>\n<li>2018-11-04: First formal bug report form a tester. A beta tester informed me that the extension would fail to work properly if they took a course that had more than one instructor.<\/li>\n<li>2018-11-07: Addition of final percent indicators on the main page<\/li>\n<li>2018-11-15: First logo design. I originally tried to find a graphics designer that would be willing to design a logo for the extension but could not find one so I made a simple one in photoshop.<\/li>\n<li>2018-11-18: Logo design finalized.<\/li>\n<li><strong>2018-11-19: PUBLIC RELEASE!!!!<\/strong><\/li>\n<li>2018-12-25: Public release of source code. The source code was now visible for everyone but was not yet open source as the code was distributed unlicensed.<\/li>\n<li>2019-01-22: <strong>Open sourced!<\/strong> Source code relicensed to GPL-3.0.<\/li>\n<li>2019-04-24: Addition of the hypothetical assignment calculator.<\/li>\n<li>2019-09-18: Many important things got released on this date\n<ul>\n<li>Migration to use npm for dependencies<\/li>\n<li>Migration to Webpack<\/li>\n<li>Beginning of migration to VueJS<\/li>\n<li>Relicensed source code to AGPL-3.0-only<\/li>\n<\/ul>\n<\/li>\n<li>2019-10-07: First pull request from another developer<\/li>\n<li>2020-04-17: Suhas added the ability to calculate cumulative GPA including the effect of the current semester.<\/li>\n<li>2020-09-25: Primary Maintainership officially passed to Suhas.<\/li>\n<\/ul>"},{"title":"Personal F-Droid Repository","link":"https:\/\/garykim.dev\/blog\/2020\/04\/14\/personal-f-droid-repository\/","pubDate":"Tue, 14 Apr 2020 05:23:20 +0000","author":"gary@garykim.dev (Gary Kim)","guid":"https:\/\/garykim.dev\/blog\/2020\/04\/14\/personal-f-droid-repository\/","description":"<p>On my Android phone, most of the apps installed are open source ones installed from the <a href=\"https:\/\/f-droid.org\">F-Droid<\/a> repository.\nOne of these apps that I use everyday is <a href=\"https:\/\/github.com\/teamnewpipe\/newpipe\">NewPipe<\/a>, an <cite href=\"https:\/\/github.com\/teamnewpipe\/newpipe\">libre lightweight streaming front-end<\/cite>, mainly used for watching Youtube.<\/p>\n<p>One of the things that makes NewPipe special is that it does not rely on the YouTube API. By not relying on the YouTube API, the amount of data that Google can collect about your video watching habits on YouTube is reduced.\nUnfortunately, it also means that any change to the YouTube frontend is likely to break NewPipe until the next update. Fortunately, thanks to the amazing work of everyone involved in the NewPipe project, whenever a change to the YouTube frontend does break the app, an update is soon to follow to use the new frontend.<\/p>\n<p>There is one slight issue though: F-Droid can be slow with fetching updates and making it available in their repository.\nThe people working on F-Droid have been working to address this issue but still, with the current setup, it can take several days for an update to be available in the repository which means a few days of NewPipe not working.<\/p>\n<p>Around January 2020, another update to the YouTube frontend broke NewPipe. Okay, not uncommon, there should be an update to fix the issue pretty soon. I checked the issue tracker to make sure that it was a known issue then decided to wait for a fix.\nI waited a couple days and didn&rsquo;t find an update in F-Droid. I checked the repository for NewPipe and found an update with the fix but that update was not yet available in the F-Droid repository.<\/p>\n<p>This was the point at which I decided it would make sense for me to create my own F-Droid repository so I can make faster updates for the apps that I do use.<\/p>\n<p>I had been wanting to do this for a while anyways so I can have apps such as Signal through F-Droid as well (<a href=\"https:\/\/github.com\/signalapp\/Signal-Android\/issues\/127\">Moxie has held strong in the opinion that it would not be wise to distribute Signal through any repository other than the Google Play Store<\/a>) since I leave Google Play Store and Google Play Services disabled on all my devices.<\/p>\n<h3 id=\"making-an-f-droid-repo\">Making an F-Droid Repo<\/h3>\n<p>Making your own F-Droid repo is a relatively simply process. An F-Droid repo, similar to other Linux software repositories, is a directory of packages and metadata about those packages which can then be served with any web server. This could also be done through S3 if that&rsquo;s more your boat.<\/p>\n<p>There&rsquo;s a simple to use script for this called <a href=\"https:\/\/gitlab.com\/fdroid\/fdroidserver\">fdroidserver<\/a>.<\/p>\n<p>You can create a new fdroid repo running the following in an empty directory.<\/p>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>fdroid init\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>3 important directories will be created: <code>repo<\/code>, <code>archive<\/code>, <code>tmp<\/code>. These are the directories that you must serve. <a href=\"https:\/\/gitlab.com\/fdroid\/fdroidserver\">fdroidserver<\/a> actually includes functionality for moving these directories onto a web server, although I personally find that it is easier to handle this with <a href=\"https:\/\/github.com\/rclone\/rclone\">Rclone<\/a>.<\/p>\n<p>To add a new app into your repository, move your apk file into your F-Droid repo directory and run <code>fdroid update -c<\/code> to create skeleton config files for your the apps you just added. It is also possible to have <a href=\"https:\/\/gitlab.com\/fdroid\/fdroidserver\">fdroidserver<\/a> compile apps for you with the proper libraries and the Android SDK.<\/p>\n<p>Once your config files are created, you can generate your final repository by running the following command:<\/p>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>fdroid update --use-date-from-apk --rename-apks\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>The <code>--use-date-from-apk --rename-apks<\/code> flags, do what you&rsquo;d expect them to, although if you don&rsquo;t want to use those flags, that also works great.<\/p>\n<p>Once you have set up the repo, simply move the <code>repo<\/code> and <code>archive<\/code> directories onto a web server and add a url to those directories into the F-Droid app and you have a working F-Droid repo!<\/p>\n<h3 id=\"automating-the-repos-updates\">Automating the Repo&rsquo;s Updates<\/h3>\n<p>Now obviously, no one want to have to do this whenever they want an update to one of their apps. In my case, I made the updates a CI run.<\/p>\n<p>I have a self-hosted instance of the proprietary version of Drone CI that I use for many of my projects. I used to use the open source version of Drone but the open source version is very limited in features. Unfortunately, anything beyond to most basic CI features are part of the proprietary version. If a community driven open source CI project starts that is even half as intuitive and easy to use as Drone, I would switch to it in a second.<\/p>\n<p>I already had a way to publish websites on a subdomain from a CI run set up.<\/p>\n<figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/personal-fdroid-repo\/fdroid-drone.png\"\nalt=\"Drone CI Screenshot\"\/>\n<\/figure>\n<p>The CI is set up to run 4 main steps and runs every night to check for updates to apps in the repo.<\/p>\n<h5 id=\"download-the-repo\">Download the Repo<\/h5>\n<p>The first step is downloading the current state of the repo from the host. This is done via <a href=\"https:\/\/github.com\/rclone\/rclone\">Rclone<\/a>.<\/p>\n<h5 id=\"update-apps\">Update Apps<\/h5>\n<p>During this step, the CI downloads the current versions of all the apps in the repo.<\/p>\n<p>After downloading current versions of all the apps, the apps are deduplicated using <code>rdfind<\/code>.<\/p>\n<h5 id=\"update-repo\">Update Repo<\/h5>\n<p><code>fdroidserver<\/code> is run to generate new indexes for updates to apps.<\/p>\n<h5 id=\"push-repo\">Push Repo<\/h5>\n<p>The final step is to push the new repo to the host using <a href=\"https:\/\/github.com\/rclone\/rclone\">Rclone<\/a>.<\/p>\n<h3 id=\"final-words\">Final Words<\/h3>\n<p>In the end, this is what I ended up with:<\/p>\n<figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/personal-fdroid-repo\/screenshot-1.png\"\nalt=\"Screenshot on Phone\"\/>\n<\/figure>\n<p>The funny thing at the end of all this was that it turns out there is already an F-Droid repo by the NewPipe developers that is updated faster then the official F-Droid repo. The repo is not yet public but you can ask around on the NewPipe IRC and they&rsquo;ll give it to you.\nThe main problem I was attempting to address by creating my own F-Droid Repo could have been addressed in a way that was much easier but it was still a very nice learning experience.<\/p>\n<p>I now have a personal F-Droid repo with NewPipe and a couple other apps that are not available through the F-Droid repos at <a href=\"https:\/\/f-droid.garykim.dev\/fdroid\/repo\/\">https:\/\/f-droid.garykim.dev\/fdroid\/repo\/<\/a>.<\/p>"},{"title":"Scrapdash - Hack & Roll 2020","link":"https:\/\/garykim.dev\/blog\/2020\/02\/01\/scrapdash-hack-roll-2020\/","pubDate":"Sat, 01 Feb 2020 02:50:13 +0000","author":"gary@garykim.dev (Gary Kim)","guid":"https:\/\/garykim.dev\/blog\/2020\/02\/01\/scrapdash-hack-roll-2020\/","description":"<p>Recently, I had the opportunity to go to <a href=\"https:\/\/hacknroll.nushackers.org\">Hack &amp; Roll 2020<\/a> (<a href=\"https:\/\/hacknroll2020.devpost.com\">Devpost<\/a>), hosted by annually <a href=\"http:\/\/nus.edu.sg\/\">NUS (National University of Singapore)<\/a> and organized by <a href=\"https:\/\/www.nushackers.org\/\">NUS Hackers<\/a> in Singapore.<\/p>\n<p>So first thing&rsquo;s first, what did we make? We made a browser extension called Scrapdash. The repository for it can be found <a href=\"https:\/\/github.com\/gary-kim\/scrapdash\">here<\/a> and the Devpost can be found <a href=\"https:\/\/devpost.com\/software\/scrapdash\">here<\/a>.<\/p>\n<figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/hack-n-roll-2020\/scrapdash-1.jpg\"\nalt=\"Scrapdash Screenshot 1\"\/>\n<\/figure>\n<figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/hack-n-roll-2020\/scrapdash-2.jpg\"\nalt=\"Scrapdash Screenshot 2\"\/>\n<\/figure>\n<figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/hack-n-roll-2020\/scrapdash-3.jpg\"\nalt=\"Scrapdash Screenshot 3\"\/>\n<\/figure>\n<h3 id=\"scrapdash\">Scrapdash<\/h3>\n<p>The name Scrapdash is actually a shortened version of <code>Scraper Dashboard<\/code>. Scrapdash let&rsquo;s you select an element in a site that you&rsquo;d like to keep track of and provides a dashboard in which you can see the current state of these sites. You can also decide if you&rsquo;d like just the text or a screenshot.<\/p>\n<p>The screenshot functionality made it difficult to make an entirely self-contained extension. Even though it would be possible, we decided instead to make a server component to the extension that could do the actual scraping of sites off-site if configured.<\/p>\n<p>Currently, only a development version of Scrapdash is available. There&rsquo;s quite a few issues to be fixed and features to be added before the first release. You can see the progress of that <a href=\"https:\/\/github.com\/gary-kim\/scrapdash\/issues\/2\">here<\/a>. If you would like to play with it now, you can find the code <a href=\"https:\/\/github.com\/gary-kim\/scrapdash\">on GitHub<\/a>.<\/p>\n<h3 id=\"installing-scrapdash\">Installing Scrapdash<\/h3>\n<p>To install Scrapdash, first clone the <a href=\"https:\/\/github.com\/gary-kim\/scrapdash\">GitHub repo<\/a> the run the following commands inside to create an unpacked version that you can load into your browser of choice.<\/p>\n<p>For Chromium based browsers such as Chrome, run the following commands<\/p>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>npm i\n<\/span><\/span><span style=\"display:flex;\"><span>npm run clean\n<\/span><\/span><span style=\"display:flex;\"><span>npm run webpack:build:chromium\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>For Firefox based browsers, run the following commands<\/p>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>npm i\n<\/span><\/span><span style=\"display:flex;\"><span>npm run clean\n<\/span><\/span><span style=\"display:flex;\"><span>npm run webpack:build:firefox\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>This will create a a folder called <code>dist<\/code> in the directory that has the built extension, ready to install. If you&rsquo;d like to make a <code>.zip<\/code> that can be submitted to extension repositories, you can run <code>npm run package<\/code>.<\/p>\n<p>You can then install the extension as you normally would for unpacked extensions.<\/p>\n<h3 id=\"scrapdash-server\">Scrapdash Server<\/h3>\n<p>Scrapdash is made of two components, the extension and a server that can be hosted on the same system as the extension or, if you&rsquo;d like, a remote server.<\/p>\n<p>The easiest way to install is using the container image <a href=\"https:\/\/hub.docker.com\/r\/garykim\/scrapdash-server\">available on Docker Hub<\/a>. You can run this on a system with Docker installed with the following command:<\/p>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>docker run -p 3000:3000 --cap-add<span style=\"color:#f92672\">=<\/span>SYS_ADMIN -d -e SCRAPDASH_SHARED_PASSWORD<span style=\"color:#f92672\">=<\/span>sharedsecret garykim\/scrapdash-server\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>You can also run the Node server directly by running the following commands in the host directory that you&rsquo;ll find in the project directory:<\/p>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span>npm i\n<\/span><\/span><span style=\"display:flex;\"><span>node main.js &amp;\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>.<\/p>\n<p><strong>If you set it up on a remote machine, make sure to put it behind a reverse proxy with <code>https<\/code> as your cookies will be sent to the server as well.<\/strong><\/p>\n<p>You can then set up your Scrapdash server url and shared secret in the <code>Remotes<\/code> tab of your Scrapdash page.<\/p>\n<figure class=\"centered\"><img src=\"https:\/\/garykim.dev\/res\/large\/hack-n-roll-2020\/scrapdash-remotes.png\"\nalt=\"Scrapdash Remotes Page\"\/>\n<\/figure>"},{"title":"Constructions with Manim","link":"https:\/\/garykim.dev\/blog\/2019\/12\/03\/constructions-with-manim\/","pubDate":"Tue, 03 Dec 2019 02:20:25 +0000","author":"gary@garykim.dev (Gary Kim)","guid":"https:\/\/garykim.dev\/blog\/2019\/12\/03\/constructions-with-manim\/","description":"<p>Just a few fun constructions made in <a href=\"https:\/\/github.com\/3b1b\/manim\">Manim<\/a>. Manim (Math Animation Engine) <cite href=\"https:\/\/github.com\/3b1b\/manim\">is an animation engine for explanatory math videos<\/cite> made by <a href=\"https:\/\/www.3blue1brown.com\">3Blue1Brown<\/a> (Grant Sanderson) and available under the MIT license.<\/p>\n<p><strong>There&rsquo;s a few more that I&rsquo;m currently working on. I&rsquo;ll add them here as they get finished.<\/strong><\/p>\n<p>All the scripts used to make these videos are available <a href=\"https:\/\/git.garykim.dev\/gary-kim\/trying-manim\">here<\/a>.<br>\nThe commands to generate each video is written under most of the videos.<\/p>\n<h2 id=\"compass-and-straight-edge\">Compass and Straight Edge<\/h2>\n<h4 id=\"perpendicular-bisector\">Perpendicular Bisector<\/h4>\n<p>Given a line, draw its perpendicular bisector.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/PerpendicularBisector.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim constructions.py PerpendicularBisector\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"parallel-line-on-a-point\">Parallel Line on a Point<\/h4>\n<p>Given a line and a point not on the line, draw a line that is parallel and goes through the give point.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/ParallelLine.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim constructions.py ParallelLine\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"angle-bisector\">Angle Bisector<\/h4>\n<p>Given an angle, draw its bisector.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/AngleBisector.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim constructions.py AngleBisector\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"regular-pentagon-starting-with-a-side\">Regular Pentagon Starting With a Side<\/h4>\n<p>Given a line, draw a regular pentagon for which the given line would be a side.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/RegularPentagonWithSide.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim constructions.py RegularPentagonWithSide\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><hr>\n<h2 id=\"3d-constructions\">3D Constructions<\/h2>\n<p>What can you make in 3 dimensions with just spheres?<\/p>\n<h4 id=\"plane-to-perpendicular-line\">Plane to Perpendicular Line<\/h4>\n<p>Given a plane, draw a line that is perpendicular to the plane.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/PlaneToPerpendicularLine.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim constructions.py PlaneToPerpendicularLine\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"line-to-perpendicular-plane\">Line to Perpendicular Plane<\/h4>\n<p>Given a line, draw a plane that is perpendicular to the line.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/PerpendicularPlane.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim constructions.py PerpendicularPlane\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><hr>\n<h2 id=\"trying-to-figure-out-how-to-use-manim\">Trying to figure out how to use Manim<\/h2>\n<h4 id=\"following-getting-started\">Following Getting Started<\/h4>\n<p>Just trying to figure out what is possible with Manim. Mostly following the getting started guides.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/EnterScene.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim enter-scene.py EnterScene\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"graphscene-example\">GraphScene Example<\/h4>\n<p>Messing with <code>GraphScene<\/code> in Manim.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/Graphing.mp4\" type=\"video\/mp4\">\n<\/video>\n<div class=\"highlight\"><div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;\"><tr><td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre><\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"><code class=\"language-bash\" data-lang=\"bash\"><span style=\"display:flex;\"><span><span style=\"color:#75715e\"># To generate<\/span>\n<\/span><\/span><span style=\"display:flex;\"><span>manim enter-scene.py Graphing\n<\/span><\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"trying-to-make-a-3d-scene-didnt-really-work\">Trying to Make a 3D Scene (didn&rsquo;t really work)<\/h4>\n<p>First attempt at trying to use <code>Special3DScene<\/code>.<\/p>\n<video controls>\n<source src=\"https:\/\/garykim.dev\/res\/large\/manim-constructions\/ThreeDObjects.mp4\" type=\"video\/mp4\">\n<\/video>"},{"title":"First Post","link":"https:\/\/garykim.dev\/blog\/2019\/11\/30\/first-post\/","pubDate":"Sat, 30 Nov 2019 08:04:56 +0000","author":"gary@garykim.dev (Gary Kim)","guid":"https:\/\/garykim.dev\/blog\/2019\/11\/30\/first-post\/","description":"<p>Initial commit.<\/p>\n<p>This is my personal blog. This blog is unlikely to ever have anything interesting but if you want to visit it occasionally for whatever reason, thank you.<\/p>"}]}}