Jekyll2023-11-25T20:43:54+05:30https://prdpx7.github.io/feed.xmlprdpx7’s blogArticles, personal projects and other things from Pradeep KhileriPradeep KhileriLearning and having fun on weekends2023-10-29T00:00:00+05:302023-10-29T00:00:00+05:30https://prdpx7.github.io/life/weekend-project-1<aside class="sidebar__right">
<nav class="toc">
<header><h4 class="nav__title"><i class="fas fa-bars"></i> Table of Contents</h4></header>
<ul class="toc__menu" id="markdown-toc">
<li><a href="#to-my-future-self" id="markdown-toc-to-my-future-self">To my future self:</a></li>
</ul>
</nav>
</aside>
<blockquote>
<p>As Long as You Live, Keep Learning How to Live - Seneca</p>
</blockquote>
<p>Do you ever get that feeling that you are getting old but still there are thousands of things which you want(ed) to do but now you’re feeling “i’m too old for that shit”.</p>
<p>I have been feeling this for a long time. I started going to BJJ(Brazilian Jiu-Jitsu) classes three months ago because i wanted to learn this when i started watching UFC fights and keep hearing about BJJ again and again on Joe Rogan Podcast.</p>
<p>I started Kickboxing one month ago when i enrolled into local Kickboxing tournament even though i <em>nothing</em> about kickboxing. I started learning 2 weeks before the competition and somehow managed to win the fight just out of pure aggression.</p>
<p>One day, i’ll become a father and i’ll have kids. I want to play and learn with them - differnt kinds of sports, want to teach them musical instruments, try to solves puzzles, play chess, draw sketches and write stories togeher. do backflips, surfing, skiing and lots and lots of other things - together.</p>
<p>One day, i’ll get old and i just want to minimize the regrets - the regret of not doing/learning when i had the time.</p>
<p>So, with this, i am starting The Weekend Project.</p>
<p>Every weekend, i will try to do something. Learn something new or old. Try to explore new things and maybe brush up hobbies left in the past.</p>
<h2 id="to-my-future-self">To my future self:</h2>
<p>You don’t have to force yourself every weekend. Try to learn when you have the curiousity. try to push sometimes when you can’t. But remember, do take rest and recharge yourself.</p>
<p>Do journling if you can. When you get old, you will look at all these words again - it will be portal to your past - to see how much you outgrew yourself and a reminder that tough time does’t last.</p>
<p>As Matthew McConaughey says “Just Keep Livin’”.</p>Pradeep KhileriWeekend Project #1The One Cool Thing About Nautilus2018-07-17T00:00:00+05:302018-07-17T00:00:00+05:30https://prdpx7.github.io/linux/the-one-cool-thing-about-nautilus<aside class="sidebar__right">
<nav class="toc">
<header><h4 class="nav__title"><i class="fas fa-bars"></i> Table of Contents</h4></header>
<ul class="toc__menu" id="markdown-toc">
<li><a href="#nautilus" id="markdown-toc-nautilus">Nautilus</a></li>
<li><a href="#nautilus-script" id="markdown-toc-nautilus-script">Nautilus Script</a> <ul>
<li><a href="#the-script" id="markdown-toc-the-script">The Script</a></li>
</ul>
</li>
<li><a href="#demo" id="markdown-toc-demo">Demo</a></li>
<li><a href="#resources" id="markdown-toc-resources">Resources</a></li>
</ul>
</nav>
</aside>
<h2 id="nautilus">Nautilus</h2>
<blockquote>
<p>Nautilus is the default file manager in Ubuntu <a href="https://help.ubuntu.com/community/DefaultFileManager">Gnome</a>.</p>
</blockquote>
<p>Now they just call it <code class="language-plaintext highlighter-rouge">Gnome Files</code> but still use <code class="language-plaintext highlighter-rouge">nautilus</code> name in settings and config files <a href="https://wiki.archlinux.org/index.php/GNOME/Files">etc</a>.<br />
Forget about this naming debate or which desktop environment is better?<br />
(it’s gnome btw but nvm).</p>
<h2 id="nautilus-script">Nautilus Script</h2>
<p>The one thing where Linux haven’t disappointed us, is that there is always scope of tweaking our OS.
Now the cool thing with nautilus scripts is, we can customize things/operation we can do with right click of mouse.</p>
<p>All you need to do is:</p>
<ul>
<li>write a cool script.</li>
<li>save it as <code class="language-plaintext highlighter-rouge">~/.local/share/nautilus/scripts/cool-script.sh</code> .</li>
<li><code class="language-plaintext highlighter-rouge">chmod +x ~/.local/share/nautilus/scripts/cool-script.sh</code> .</li>
</ul>
<p>You can automate lot of stuff like sending selected file as an email attachment or
something fun like <strong>downloading subtitle</strong> of selected movie file(s).<br />
we’ll do the latter one!</p>
<h3 id="the-script">The Script</h3>
<script src="https://gist.github.com/prdpx7/bcd732b364cacc92fbc09f6414cfb79c.js"> </script>
<ul>
<li>You need to install some dependency to run this:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install notify-osd
sudo pip install subliminal
</code></pre></div> </div>
</li>
</ul>
<h2 id="demo">Demo</h2>
<p><img src="/assets/images/nautilus-script.gif" alt="demo" height="550" width="700" /></p>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://help.ubuntu.com/community/NautilusScriptsHowto">NautilusScriptsHowto</a></li>
<li><a href="http://mundogeek.net/nautilus-scripts/">Nautilus Scripts Collection</a></li>
<li><a href="https://github.com/Diaoul/subliminal">Subliminal</a></li>
</ul>Pradeep Khilerinautilus scripts FTW!Stuff i learned while fixing brightness on Ubuntu2018-05-27T00:00:00+05:302018-05-27T00:00:00+05:30https://prdpx7.github.io/linux/stuff-i-learned-while-fixing-brightness-on-ubuntu<aside class="sidebar__right">
<nav class="toc">
<header><h4 class="nav__title"><i class="fas fa-bars"></i> Table of Contents</h4></header>
<ul class="toc__menu" id="markdown-toc">
<li><a href="#tldr" id="markdown-toc-tldr">TL;DR</a></li>
<li><a href="#sysfs" id="markdown-toc-sysfs">Sysfs</a></li>
<li><a href="#the-script" id="markdown-toc-the-script">The Script</a></li>
<li><a href="#etcrclocal" id="markdown-toc-etcrclocal">/etc/rc.local</a></li>
<li><a href="#but-why-all-this" id="markdown-toc-but-why-all-this">But why all this?</a></li>
<li><a href="#references" id="markdown-toc-references">References:</a></li>
</ul>
</nav>
</aside>
<p>Yeah the obvious solution doesn’t work (which is googling and click on the first two links):</p>
<ul>
<li><a href="https://itsfoss.com/fix-brightness-ubuntu-1310/">https://itsfoss.com/fix-brightness-ubuntu-1310/</a></li>
<li><a href="https://askubuntu.com/questions/762764/cant-change-brightness-in-ubuntu-16-04-lts">https://askubuntu.com/questions/762764/cant-change-brightness-in-ubuntu-16-04-lts</a></li>
</ul>
<p>So I tempted to look for more like how the hell can i actually control the brightness?<br />
(or how my os do it like it used to do, before?)</p>
<h2 id="tldr">TL;DR</h2>
<p>There is a text file named brightness, deep inside /sys/ dir contains a number which is proportional to the intensity of light coming out of monitor.</p>
<h2 id="sysfs">Sysfs</h2>
<blockquote>
<p>Sysfs is a virtual filesystem exported by the kernel, similar to /proc. The files in Sysfs contain information about devices and drivers.
Some files in Sysfs are even writable, for configuration and control of devices attached to the system. Sysfs is always mounted on /sys. <a href="http://www.signal11.us/oss/udev/">[1]</a></p>
</blockquote>
<p>Inside /sys/ there are multiple dirs like block,class, devices, firmware etc.<br />
The thing which we are looking for is, some config file which somehow controls brightness!<br /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ls /sys/
block class devices fs kernel power
bus dev firmware hypervisor module
$ ls /sys/class/backlight/intel_backlight/ -lah
total 0
drwxr-xr-x 3 root root 0 May 28 21:46 .
drwxr-xr-x 4 root root 0 May 28 21:46 ..
-r--r--r-- 1 root root 4.0K May 28 21:46 actual_brightness
-rw-r--r-- 1 root root 4.0K May 28 21:46 bl_power
-r--r--r-- 1 root root 4.0K May 28 20:26 brightness
lrwxrwxrwx 1 root root 0 May 28 21:46 device -> ../../card0-eDP-1
-r--r--r-- 1 root root 4.0K May 28 21:46 max_brightness
drwxr-xr-x 2 root root 0 May 28 21:46 power
lrwxrwxrwx 1 root root 0 May 28 21:46 subsystem -> ../../../../../../../class/backlight
-r--r--r-- 1 root root 4.0K May 28 21:46 type
-rw-r--r-- 1 root root 4.0K May 28 21:46 uevent
</code></pre></div></div>
<p>Woah! there are so many files here, but the one we are looking for is <code class="language-plaintext highlighter-rouge">brightness</code>.<br />
more precisely <code class="language-plaintext highlighter-rouge">/sys/class/backlight/intel_backlight/brightness</code> file.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat /sys/class/backlight/intel_backlight/brightness
10
$ cat /sys/class/backlight/intel_backlight/max_brightness
937
</code></pre></div></div>
<p>Yeah these files just contain a number that’s it. the max_brightness my laptop can have is <code class="language-plaintext highlighter-rouge">937</code> and current brightness is <code class="language-plaintext highlighter-rouge">10</code>. <br />
Imagine it like this, 1% of brightness level is equivalent to 9.37 ;)</p>
<h2 id="the-script">The Script</h2>
<p>Now that we have found the brightness file, we can just change the number in it and adjust the brightness accordingly.<br />
Interesting thing is that, we can put only integers in it(<code class="language-plaintext highlighter-rouge">0 <= brightness <= 937</code>) <br />
and need root permission to edit the file.
So, i created a script which works like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ brightness 100 # set brightness value to 100 in that file
$ brightness asdf # also shows warnings
brighness value should be an +integer
</code></pre></div></div>
<p>The script is pretty simple but i learned some things like:</p>
<ul>
<li>Bash and zsh does not work the same way as i used to think.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ zsh
$ x=123
$ # here is snippet to check for integer, notice the '' with regex
$ if [[ $x =~ '^[0-9]+$' ]]; then
echo "this is a number";
else
echo "not a number";
fi;
this is a number
$ bash # let do samething in bash
$ x=123
$ if [[ $x =~ '^[0-9]+$' ]]; then
echo "this is a number";
else
echo "not a number";
fi;
not a number
$ # wtf
$ # let do that again without '' in regex
$ if [[ $x =~ ^[0-9]+$ ]]; then
echo "this is a number";
else
echo "not a number";
fi;
this is a number
$ # so bash and zsh if conditions doesn't always match
$ # this will work in zsh also, because for zsh 'regex' and regex are the same thing.
</code></pre></div> </div>
</li>
<li>here is the final script:</li>
</ul>
<script src="https://gist.github.com/prdpx7/51fd3fb2f994c43593e9dc2cf70e88d4.js"> </script>
<h2 id="etcrclocal">/etc/rc.local</h2>
<p>So far we have solved our problem but we always need to change the permission of file to run the script without sudo, because <code class="language-plaintext highlighter-rouge">/sys/class/</code> files permissions resets to root user on every boot.</p>
<p>So all we need is to automate this task of changing <code class="language-plaintext highlighter-rouge">brightness</code> file permission after every boot.</p>
<p>Turns out that <code class="language-plaintext highlighter-rouge">/etc/rc.local</code> is just kind of thing which do similar things
like running a script or starting a service after every boot.(<code class="language-plaintext highlighter-rouge">rc</code> denotes <code class="language-plaintext highlighter-rouge">run-control</code> btw)
<a href="https://unix.stackexchange.com/questions/49626/purpose-and-typical-usage-of-etc-rc-local">[2]</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo vim /etc/rc.local
# see the gist
</code></pre></div></div>
<script src="https://gist.github.com/prdpx7/921d9c7ab24fc4ad8bc21392e7b8e95e.js"> </script>
<h2 id="but-why-all-this">But why all this?</h2>
<p>Because i don’t have anything else to do on weekend!</p>
<h2 id="references">References:</h2>
<ul>
<li><a href="http://www.signal11.us/oss/udev/">http://www.signal11.us/oss/udev/</a></li>
<li><a href="https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt">https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt</a></li>
<li><a href="https://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html">https://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html</a></li>
</ul>Pradeep Khileriabout /sys/, bash stuff and wtf is /etc/rc.local?Rendering Django CKeditor content in AMP page2018-05-12T00:00:00+05:302018-05-12T00:00:00+05:30https://prdpx7.github.io/django/rendering-django-ckeditor-content-in-amp<aside class="sidebar__right">
<nav class="toc">
<header><h4 class="nav__title"><i class="fas fa-bars"></i> Table of Contents</h4></header>
<ul class="toc__menu" id="markdown-toc">
<li><a href="#prelude" id="markdown-toc-prelude">Prelude</a></li>
<li><a href="#amp" id="markdown-toc-amp">AMP</a></li>
<li><a href="#problem" id="markdown-toc-problem">Problem</a></li>
<li><a href="#our-solution" id="markdown-toc-our-solution">Our Solution</a></li>
</ul>
</nav>
</aside>
<h2 id="prelude">Prelude</h2>
<p>So our team is struggling with CKEditor, not because it’s used heavily for publishing blog pages in our product but because it renders html which can’t be used for amp page.</p>
<h2 id="amp">AMP</h2>
<p>You know AMP right? the thing that google created so that your page loads faster in mobile.<br />
The problem is that, An amp page have limited html tags, no inline style and <a href="https://www.ampproject.org/learn/overview/">other weird rules</a>.</p>
<p>Suppose you have to render your blog content with django template engine, this is how you’ll do generally</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="c"><!--
https://www.ampproject.org/docs/fundamentals/discovery
!--></span>
<span class="nt"><link</span> <span class="na">href=</span><span class="s">"https://some-random-blog.com/the-blog-post/"</span> <span class="na">rel=</span><span class="s">"canonical"</span><span class="nt">/></span>
<span class="nt"><title></span>{{blog.title}}<span class="nt"></title></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><h3></span>{{blog.title}}<span class="nt"></h3></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"blog-short-description"</span><span class="nt">></span>
{{blog.short_description}}
<span class="nt"></div></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"blog-content"</span><span class="nt">></span>
<span class="c"><!-- this is the blog content written by content writer !--></span>
{{blog.content|safe}}
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</code></pre></div></div>
<h2 id="problem">Problem</h2>
<p>Now the thing is our blog’s content which is written by some content writer who is using ckeditor, will render perfectly in normal webpages.<br />
But for an amp page, we have to change html content of that particular blog which is in Database, so how could we do that?</p>
<p>Also CKEditor don’t have any amp plugins otherwise i won’t be writing this post!</p>
<h2 id="our-solution">Our Solution</h2>
<p>So what we did is created a custom django template filter for all our amp pages, which will convert our blog’s content into amp compatible html.</p>
<p>So here it is:
<script src="https://gist.github.com/prdpx7/f67ce628558b7872d6040aa25f75a292.js"> </script></p>
<p>So to use this in amp page we will do just this:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
{% load ampconvert %}
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="c"><!--
https://www.ampproject.org/docs/fundamentals/discovery
!--></span>
<span class="nt"><link</span> <span class="na">href=</span><span class="s">"https://some-random-blog.com/the-blog-post/"</span> <span class="na">rel=</span><span class="s">"canonical"</span><span class="nt">/></span>
<span class="nt"><title></span>{{blog.title}}<span class="nt"></title></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><h3></span>{{blog.title}}<span class="nt"></h3></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"blog-short-description"</span><span class="nt">></span>
{{blog.short_description}}
<span class="nt"></div></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"blog-content"</span><span class="nt">></span>
{{blog.content|ampconvert|safe}}
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</code></pre></div></div>
<p>It’s not a perfect solution but since there isn’t any solution around we are going with it.</p>
<p>Before implementing, you might want to read some official <a href="https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/">docs</a>.</p>Pradeep Khileriall thanks to django template filterPublish Your First Node Module2017-03-29T00:00:00+05:302017-03-29T00:00:00+05:30https://prdpx7.github.io/nodejs/publish-your-first-node-module<aside class="sidebar__right">
<nav class="toc">
<header><h4 class="nav__title"><i class="fas fa-bars"></i> Table of Contents</h4></header>
<ul class="toc__menu" id="markdown-toc">
<li><a href="#publish-your-first-node-module" id="markdown-toc-publish-your-first-node-module">Publish Your First Node Module</a> <ul>
<li><a href="#pre-requisite" id="markdown-toc-pre-requisite">Pre-requisite</a></li>
<li><a href="#npm-configuration" id="markdown-toc-npm-configuration">NPM configuration</a></li>
<li><a href="#lets-create-our-node-module" id="markdown-toc-lets-create-our-node-module">Let’s create our node module</a></li>
<li><a href="#writing-test-for-our-module" id="markdown-toc-writing-test-for-our-module">Writing Test for our Module</a></li>
<li><a href="#publishing-our-node-module" id="markdown-toc-publishing-our-node-module">Publishing our node module.</a></li>
<li><a href="#final-note" id="markdown-toc-final-note">Final Note</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
<h1 id="publish-your-first-node-module">Publish Your First Node Module</h1>
<h2 id="pre-requisite">Pre-requisite</h2>
<ul>
<li>Install <a href="https://nodejs.org/en/download/">Nodejs</a>.</li>
<li>Create an account on <a href="https://github.com/">GitHub</a> & <a href="https://www.npmjs.com/signup">NPM</a>.</li>
<li>Basic knowledge of JS & git.</li>
</ul>
<h2 id="npm-configuration">NPM configuration</h2>
<p>After installing nodejs and creating npm account, go to the terminal and run these commands.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm set init.author.name "Pradeep Khileri"
npm set init.author.email "pradeepchoudhary009@gmail.com"
npm set init.author.url "https://prdpx7.github.io"
</code></pre></div></div>
<h2 id="lets-create-our-node-module">Let’s create our node module</h2>
<ul>
<li>before naming your module, check if there is already a node module of same name!.</li>
<li>
<p>here our sample node module’s objective is to extract json data of python package from pypi registry.</p>
</li>
<li>Create project dir and follow these steps.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> mkdir pkgstat #let us name our project 'pkgstat'
cd pkgstat
npm init # do as it says and it will create package.json(a configuration file for your node module).
</code></pre></div> </div>
</li>
<li>Install dependencies for our project.
we will use <code class="language-plaintext highlighter-rouge">got</code> module which will be used for making http request and extracting json content from web.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> npm install --save got # this will be installed locally,used only for current project.
</code></pre></div> </div>
</li>
<li>Read more about <a href="https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md">installing npm packages globally without sudo</a>.</li>
<li>Write the code for our module in <code class="language-plaintext highlighter-rouge">index.js</code>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="dl">'</span><span class="s1">use strict</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">got</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">got</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">pypi</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://pypi.python.org/pypi/pkg_name/json</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">extractMetaData</span><span class="p">(</span><span class="nx">jsonData</span><span class="p">,</span> <span class="nx">language</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">pkgMeta</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">if</span><span class="p">(</span><span class="nx">language</span> <span class="o">==</span> <span class="dl">'</span><span class="s1">python</span><span class="dl">'</span><span class="p">){</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">author</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">author</span><span class="p">;</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">description</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">summary</span><span class="p">;</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">url</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">package_url</span><span class="p">;</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">home_page</span><span class="p">;</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">license</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">license</span><span class="p">;</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">version</span> <span class="o">=</span> <span class="nx">jsonData</span><span class="p">.</span><span class="nx">info</span><span class="p">.</span><span class="nx">version</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">pkgMeta</span><span class="p">.</span><span class="nx">status</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">pkgMeta</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">setpkgURL</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span><span class="nx">language</span><span class="p">){</span>
<span class="nx">language</span> <span class="o">=</span> <span class="nx">language</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">""</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="nx">language</span> <span class="o">==</span> <span class="dl">'</span><span class="s1">python</span><span class="dl">'</span><span class="p">){</span>
<span class="nx">url</span> <span class="o">=</span> <span class="nx">pypi</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="dl">'</span><span class="s1">pkg_name</span><span class="dl">'</span><span class="p">,</span> <span class="nx">name</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="nx">url</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">language not supported</span><span class="dl">"</span><span class="p">;</span> <span class="c1">//'got' will handle invalid http request.</span>
<span class="k">return</span> <span class="nx">url</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span><span class="nx">language</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="nx">setpkgURL</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">language</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">headers</span> <span class="o">=</span> <span class="p">{</span><span class="dl">'</span><span class="s1">User-Agent</span><span class="dl">'</span><span class="p">:</span><span class="dl">'</span><span class="s1">got node module</span><span class="dl">'</span><span class="p">};</span>
<span class="k">return</span> <span class="nx">got</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="p">{</span><span class="na">json</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span> <span class="nx">headers</span><span class="p">})</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">resp</span><span class="o">=></span><span class="p">{</span>
<span class="k">return</span> <span class="nx">extractMetaData</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">body</span><span class="p">,</span> <span class="nx">language</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="nx">err</span> <span class="o">=></span><span class="p">{</span>
<span class="k">return</span> <span class="p">{</span><span class="na">status</span><span class="p">:</span><span class="mi">404</span><span class="p">};</span>
<span class="p">})</span>
<span class="p">}</span>
</code></pre></div> </div>
</li>
</ul>
<h2 id="writing-test-for-our-module">Writing Test for our Module</h2>
<ul>
<li>testing is important because otherwise you have to manually test it again and again in node(repl) after making some changes in module.</li>
<li>other developers can also test your module with <code class="language-plaintext highlighter-rouge">npm test</code> without headache.</li>
<li>it’s a good habit, so shut up and write tests for your node module.</li>
<li>you can use <a href="http://mochajs.org/">mocha</a>, <a href="https://github.com/avajs/ava">ava</a> or any other node testing module.(we will use <a href="https://github.com/avajs/ava">ava</a>).
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> npm install -g ava
ava --init #make sure you are in our project directory where our module resides.
</code></pre></div> </div>
</li>
<li>write your test in <code class="language-plaintext highlighter-rouge">test.js</code>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">import</span> <span class="nx">test</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">ava</span><span class="dl">'</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">pkgstat</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">.</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">cleanslate pkg in python(pip)</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="nx">t</span> <span class="o">=></span><span class="p">{</span>
<span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">pkgstat</span><span class="p">(</span><span class="dl">'</span><span class="s1">cleanslate</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">python</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">is</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">author</span><span class="p">,</span><span class="dl">'</span><span class="s1">Pradeep Khileri</span><span class="dl">'</span><span class="p">);</span><span class="c1">//matching response(since we know the returned json object(data) contents).</span>
<span class="p">})</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">somePkgWhichDoesNotExist in SomeLanguageWhichDoesNotExist</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="nx">t</span> <span class="o">=></span><span class="p">{</span>
<span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">pkgstat</span><span class="p">(</span><span class="dl">'</span><span class="s1">somePkgWhichDoesNotExist</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">SomeLanguageWhichDoesNotExist</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">is</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">status</span><span class="p">,</span> <span class="mi">404</span><span class="p">);</span>
<span class="p">})</span>
</code></pre></div> </div>
</li>
<li>run this test script.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> npm test # it will show which test was passed and which one didn't
</code></pre></div> </div>
</li>
<li>write documentation for your node module.
<ul>
<li><a href="https://guides.github.com/features/mastering-markdown/">guide</a> on writing markdown.</li>
<li>write your documentation in readme.md file.</li>
<li><a href="https://github.com/prdpx7/pkgstat/blob/master/readme.md">this</a> is sample documentation of our node module.</li>
</ul>
</li>
<li>final project structure(more or less) will look like this.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> projectDirOfOurNodeModule
|__node_modules/
|__readme.md
|__index.js
|__test.js
|__license
|__package.json
</code></pre></div> </div>
</li>
</ul>
<h2 id="publishing-our-node-module">Publishing our node module.</h2>
<ul>
<li>Publish your module to NPM (make sure you’re in project directory).
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm login
# fill out username,password and email
npm publish
</code></pre></div> </div>
</li>
<li>Create a github repo and push your code.</li>
<li>you don’t want to push <code class="language-plaintext highlighter-rouge">node_modules/</code> to github because these dependencies will be installed when someone will install your module.</li>
<li>use tool like <a href="https://github.com/prdpx7/GiG">GiG</a> for generating .gitignore files for your project.</li>
<li><a href="https://guides.github.com/activities/hello-world/">read</a> more about github.</li>
</ul>
<h2 id="final-note">Final Note</h2>
<ul>
<li>this is just a smaller version of <code class="language-plaintext highlighter-rouge">pkgstat</code> module.</li>
<li>the full source code of <code class="language-plaintext highlighter-rouge">pkgstat</code> is <a href="https://github.com/prdpx7/pkgstat">here</a>.</li>
<li>other useful links -
<ul>
<li>an awesome tutorial on <a href="https://github.com/workshopper/learnyounode#learn-you-the-nodejs-for-much-win">node</a></li>
<li>more about <a href="https://docs.npmjs.com/getting-started/">npm</a></li>
<li><a href="https://quickleft.com/blog/creating-and-publishing-a-node-js-module/">publishing node modules</a></li>
<li><a href="https://darrenderidder.github.io/talks/ModulePatterns/#/">Node Module Patterns</a></li>
<li>collection of resources on <a href="https://github.com/sindresorhus/awesome-nodejs#awesome-nodejs-">nodejs</a></li>
</ul>
</li>
</ul>Pradeep Khilerifirst steps with node,npm and git