Hemanth.HM

A Computer Polyglot, CLI + WEB ♥'r.

Detecting File Type in Node and Browser

| Comments

Detecting a file type is pretty easy, it's all about knowing the File Signatures aka "magic numbers"! of the file.

Magic number are bytes within a file used to identify the format of the file; generally a short sequence of bytes (most are 2-4 bytes long) placed at the beginning of the file;

Normally on CLI one would use file command to determine file type. For example:

1
2
3
$ file meow.ogg

Ogg data, Vorbis audio, stereo, 44100 Hz, ~64000 bps, created by: Xiph.Org libVorbis I (1.1.0 RC1)

The mime type detection will file would be like:

1
2
3
$ file --mime-type -b ~/labs/npm/is-ogg/fixture.ogg

application/ogg

One could easily do a npm install mime mime

1
2
> require('mime').lookup("meow.ogg").split("/")[1]
'ogg'

Or install

1
2
3
4
5
6
7
 var mmm = require('mmmagic'),
      Magic = mmm.Magic;
  var magic = new Magic(mmm.MAGIC_MIME);
  magic.detectFile('meow.ogg', function(err, result) {
      if (err) throw err;
      console.log(result);
  });

But would not it be fun to have a simple module that could read buffer as well as Buffer/Uint8Array ?

Well, here it is file-type detects the file type of a Buffer/Uint8Array!

P.R are welcome to that project and /me contributed audio-type to it.

So the logic behind is to read the required bytes using read-chunk and check for the required bytes, for example have a look at is-ogg.

The project is nicely aligned with the Unix Philosophy of doing one thing and doing it in the best way, each of the file types are broken down in the individual modules like:

And it also has a nice little CLI util as well:

1
$ npm install --global file-type
1
2
3
4
5
6
7
8
9
$ file-type --help

Usage
  $ cat <filename> | file-type
  $ file-type <filename>

Example
  $ cat unicorn.png | file-type
  png

Do feel free to send new suggestion/PR to this project and hope this helped you!

Prime Number Generation With ES6 Generators

| Comments

Well, there are many effective prime number generation alogrithms out there, but I got lazy and tried something like:

primes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function isPrime(n) {
   if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
   var m = Math.sqrt(n);
   for (var i=2;i<=m;i++) if (n%i==0) return false;
   return true;
}

function *genPrime() {
   var count = 0;
   while(1) {
    if(isPrime(count)) yield count;
    count++;
   }
}

Now, keep generating them!

1
2
3
4
var meh = genPrime();
while(1) {
 console.log(meh.next().value);
}

BTW one more intresting read

Grunt-usemin Example

| Comments

grunt-usemin example.

P.S: This is a minimalist usage of grunt-usemin, do read the usemin README for more details.

The directory structure looks like:

1
2
3
4
5
6
7
8
9
10
.
├── assets
│   ├── css
│   │   └── style.css
│   └── js
│       ├── bar.js
│       └── foo.js
├── gruntfile.js
├── index.html
└── package.json

Where style.css includes bare minimal CSS and bar.js and foo.js are simple javascript files.

The index.html looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
  <head>
    <title>Usemin test</title>
    <!-- build:css assets/css/style.min.css -->
      <link rel="stylesheet" type="text/css" href="./assets/css/styles.css" media="screen" />
    <!-- endbuild -->
  </head>
  <body>

  </body>
  <!-- build:js assets/js/optimized.js -->
    <script src="./assets/js/foo.js"></script>
    <script src="./assets/js/bar.js"></script>
  <!-- endbuild -->
</html>

On Grunting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$ grunt
Running "copy:html" (copy) task
Copied 1 file

Running "useminPrepare:html" (useminPrepare) task
Going through index.html to update the config
Looking for build script HTML comment blocks

Configuration is now:

  concat:
  { generated:
   { files:
      [ { dest: '.tmp/concat/assets/css/style.min.css',
          src: [ 'assets/css/style.css' ] },
        { dest: '.tmp/concat/assets/js/optimized.js',
          src: [ 'assets/js/foo.js', 'assets/js/bar.js' ] } ] } }

  uglify:
  { generated:
   { files:
      [ { dest: 'dist/assets/js/optimized.js',
          src: [ '.tmp/concat/assets/js/optimized.js' ] } ] } }

  cssmin:
  { generated:
   { files:
      [ { dest: 'dist/assets/css/style.min.css',
          src: [ '.tmp/concat/assets/css/style.min.css' ] } ] } }

Running "concat:generated" (concat) task
File ".tmp/concat/assets/css/style.min.css" created.
File ".tmp/concat/assets/js/optimized.js" created.

Running "uglify:generated" (uglify) task
File dist/assets/js/optimized.js created: 75 B → 58 B

Running "cssmin:generated" (cssmin) task
File dist/assets/css/style.min.css created: 48 B → 39 B

Running "usemin:html" (usemin) task

Processing as HTML - dist/index.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input

Done, without errors.

Do notice that default task:

1
2
3
4
5
6
7
8
grunt.registerTask('default',[
  'copy:html',
  'useminPrepare',
  'concat',
  'uglify',
    'cssmin',
  'usemin'
]);

The new dir structure will be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.
├── assets
│   ├── css
│   │   └── style.css
│   └── js
│       ├── bar.js
│       └── foo.js
├── dist
│   ├── assets
│   │   ├── css
│   │   │   └── style.min.css
│   │   └── js
│   │       └── optimized.js
│   └── index.html
├── gruntfile.js
├── index.html

dist/index.html would now look like:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
  <head>
    <title>Usemin Example</title>
    <link rel="stylesheet" href="assets/css/style.min.css" media="screen"/>
  </head>
  <body>

  </body>
  <script src="assets/js/optimized.js"></script>
</html>

css is minifed and js is concated and minifed. Have a look the dist dir.

Hope this helped you to get started with usemin!

Tree Traversal With ES6 Generator

| Comments

Here is Depth first Tree traversals using ES6 generators, influenced by pep-0255

Currently you must use the --harmony-generators flag when running node 0.11.x to get access to generators.

Depth first traversals:

Pre-order:

  • Visit the root.

  • Traverse the left subtree.

  • Traverse the right subtree.

In-order:

  • Traverse the left subtree.

  • Visit root.

  • Traverse the right subtree.

Post-order:

  • Traverse the left subtree.

  • Traverse the right subtree.

  • Visit the root.

Show me the code!

1
2
3
4
5
6
7
var inorder = function* inorder(node) {
  if (node) {
    yield* inorder(node.left);
    yield node.label;
    yield* inorder(node.right);
  }
}
1
2
3
4
5
6
7
var preorder = function* preorder(node) {
  if (node) {
    yield node.label;
    yield* preorder(node.left);
    yield* preorder(node.right);
  }
}
1
2
3
4
5
6
7
var postorder = function* postorder(node) {
  if (node) {
    yield* postorder(node.left);
    yield* postorder(node.right);
    yield node.label;
  }
}

Let's create a tree:

1
2
3
4
5
function Tree(label, left, right) {
  this.label = label;
  this.left = left;
  this.right = right;
}
1
2
3
4
5
6
7
8
var tree = function tree(list) {
  var n = list.length;
  if (n == 0) {
    return null;
  }
  var i = Math.floor(n / 2);
  return new Tree(list[i], tree(list.slice(0, i)), tree(list.slice(i + 1)));
}

Now if we need to traverse the tree:

1
2
3
4
5
6
7
8
9
var root = tree(['A','B','C','D','E','F','G','H','I']);
var results = [];

for (let value of gntr.preorder(root)) {
    results.push(value);
}

console.log(results);
// Would log  ['F', 'B', 'A', 'D', 'C', 'E', 'G', 'I', 'H']

To make it easier, I created a node moudle gntr hope it helps, happy hacking!

Clone All Official Yeoman Generators

| Comments

I'm sure you are hungry for contributing to Yeoman, here is a simple script to clone all of the officially maintained yeoman generators.

To clone them all, just go to your bash shell, switch to a empty dir and fire:

1
  bash < <(curl -s http://h3manth.com/clone-generators.bash)

Behind the scene it's a simple bash script to clone all the repos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env bash

files=$(shopt -s nullglob dotglob; echo *)

if (( ${#files} ))
then
  echo "Please run this in an empty dir!" && exit 1
else
  declare -a generators=(
      generator-angular
      generator-backbone
      generator-bootstrap
      generator-chrome-extension
      generator-chromeapp
      generator-commonjs
      generator-dummy
      generator-ember
      generator
      generator-gruntfile
      generator-gruntplugin
      generator-gulp-webapp
      generator-jasmine
      generator-jquery
      generator-karma
      generator-mobile
      generator-mocha
      generator-node
      generator-polymer
      generator-webapp
  )

  for gen in "${generators[@]}"; do
    echo "Clonning generator-$gen..."
    git clone "https://github.com/yeoman/$gen.git"
  done
  echo "Done! Enjoy :-)"
fi

If you want a more generic node solution, you could use the below package.json and fire a npm install

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"name": "yeoman-generators",
"version": "0.1.0",
"description": "Globally installs all the offical yeoman generators.",
"main": "index.js",
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "preinstall": "npm i -g generator-gruntplugin generator-angular generator-gulp-webapp generator-jquery generator-webapp generator-bootstrap generator-generator generator-backbone generator-node generator-mobile generator-polymer generator-ember generator-karma generator-gruntfile generator-mocha generator-chromeapp generator-chrome-extension generator-jasmine generator-dummy generator-commonjs"
},
"repository": {
    "type": "git",
    "url": "http://github.com/hemanth/yeoman-generators"
},
"keywords": [
    "yeoman",
    "generators"
],
"author": "Hemanth.HM",
"license": "MIT",
"bugs": {
    "url": "https://github.com/hemanth/yeoman-generators/issues"
},
"homepage": "https://github.com/hemanth/yeoman-generators"
}

Hope this helps you! Happy Hacking :-)

Clone All Official Yeoman Generators

| Comments

I'm sure you are hungry for contributing to Yeoman, here is a simple script to clone all of the officially maintained yeoman generators.

To clone them all, just go to your bash shell, switch to a empty dir and fire:

1
  bash < <(curl -s http://h3manth.com/clone-generators.bash)

Behind the scene it's a simple bash script to clone all the repos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env bash

files=$(shopt -s nullglob dotglob; echo *)

if (( ${#files} ))
then
  echo "Please run this in an empty dir!" && exit 1
else
  declare -a generators=(
      generator-angular
      generator-backbone
      generator-bootstrap
      generator-chrome-extension
      generator-chromeapp
      generator-commonjs
      generator-dummy
      generator-ember
      generator
      generator-gruntfile
      generator-gruntplugin
      generator-gulp-webapp
      generator-jasmine
      generator-jquery
      generator-karma
      generator-mobile
      generator-mocha
      generator-node
      generator-polymer
      generator-webapp
  )

  for gen in "${generators[@]}"; do
    echo "Clonning generator-$gen..."
    git clone "https://github.com/yeoman/$gen.git"
  done
  echo "Done! Enjoy :-)"
fi

If you want a more generic node solution, you could use the below package.json and fire a npm install

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"name": "yeoman-generators",
"version": "0.1.0",
"description": "Globally installs all the offical yeoman generators.",
"main": "index.js",
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "preinstall": "npm i -g generator-gruntplugin generator-angular generator-gulp-webapp generator-jquery generator-webapp generator-bootstrap generator-generator generator-backbone generator-node generator-mobile generator-polymer generator-ember generator-karma generator-gruntfile generator-mocha generator-chromeapp generator-chrome-extension generator-jasmine generator-dummy generator-commonjs"
},
"repository": {
    "type": "git",
    "url": "http://github.com/hemanth/yeoman-generators"
},
"keywords": [
    "yeoman",
    "generators"
],
"author": "Hemanth.HM",
"license": "MIT",
"bugs": {
    "url": "https://github.com/hemanth/yeoman-generators/issues"
},
"homepage": "https://github.com/hemanth/yeoman-generators"
}

Hope this helps you! Happy Hacking :-)

Npm --save to Create package.json

| Comments

Till issue npm#3576 is fixed we could use the below is our shell's rc to do the job:

1
2
3
4
5
function npms(){
    [[ -f ./package.json ]] ||
    echo {} > package.json  &&
    npm install --save $*
}

Quoting timoxley for the context:

"adds to package.json in current working directory, and creates if one is not found" is IMO conceptually simpler than the current situation.

Currently, npm install --save adds the dependency to the nearest package.json, searching up the directory tree. I doubt this is used very often, and it likely leads to more dependencies accidentally being added to the wrong package.json than the correct package.json.

npm also uses the realdir when handling symlinks, so if you're calling npm install --save from inside a symlinked dir, it'll find and add the dep the package.json in the parent real directory, rather than the symlinked one, so you now also need to worry about whether the directory you're in is a symlink or not. Maybe this feature is useful, maybe it's complicated.

The suggestion of calling npm init on missing package.json makes a lot of sense to me if we simplified the install logic to always just look in cwd.

Changing this behaviour could break a few builds, and there's also some consistency with the "find nearest package.json" logic across other npm commands, so it'd likely need to be changed there as well.

Atom Editor Packages With Yeoman

| Comments

atom editor the editor that GitHub is building the text editor we've always wanted is at a very early state and has some great potential, luckily got an invite from to paw at and it and did a silly plugin for it as well which just plays around with some text converting colors to RGB:

RGB

Lately I wrote a Yeoman generator to create packages from atom editor. You can paw at the source of generator-atom and install it npm install generator-atom

Simple demo of using generator-atom:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
[generator-atom] $ mkdir atom-plugin && cd $_
[generator-atom] $ yo atom

     _-----_
    |       |
    |--(o)--|   .--------------------------.
   `---------´  |    Welcome to Yeoman,    |
    ( _´U`_ )   |   ladies and gentlemen!  |
    /___A___\   '__________________________'
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

You're using the fantastic Atom generator.
[?] What would like name your atom package? atom-plugin
[?] Descirbe your package in one-line: My awesome atom package!
[?] What license would apply for this package? MIT
[?] What's your github username? hemanth
[?] Are you using any grammars? yes
[?] Are you using keymaps? yes
[?] Are you adding menus? yes
[?] Are you writing any snippets? yes
[?] Are you doing some stylesheets? yes
   create lib/atom-plugin.coffee
   create grammars/grammar.cson
   create keymaps/keymap.cson
   create stylesheets/style.css
   create menus/application-menu.cson
   create menus/context-menu.cson
   create snippets/language.cson
   create spec/atom-plugin_test.coffee
   create spec/fixtures/atom-plugin_fixture.coffee
   create .jshintrc
   create .gitignore
   create .travis.yml
   create README.md
   create package.json
   create index.coffee


I'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.


[generator-atom] $ tree
.
├── README.md
├── grammars
│   └── grammar.cson
├── index.coffee
├── keymaps
│   └── keymap.cson
├── lib
│   └── atom-plugin.coffee
├── menus
│   ├── application-menu.cson
│   └── context-menu.cson
├── package.json
├── snippets
│   └── language.cson
├── spec
│   ├── atom-plugin_test.coffee
│   └── fixtures
│       └── atom-plugin_fixture.coffee
└── stylesheets
    └── style.css

8 directories, 12 files

You may not need all of the directories, indeed based on your need. Each of those file will have minimal boilerplate code that would help you get started.

The index.coffee includes the file in the lib dir and it looks like:

1
2
3
module.exports = require "./lib/atom-plugin"

# Add the rest of the logic below.

The package.json would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "name": "atom-plugin",
  "main": "./lib/atom-plugin",
  "version": "0.0.0",
  "description": "My awesome atom package!",
  "license": "MIT",
  "private": true,
  "repository": "https://github.com/hemanth/atom-plugin",
  "engines": {
    "atom": ">0.61.0"
  },
  "dependencies": {
  }
}

If you notice the version is 0.0.0 and modifying the code as per the need, you could do a apm publish minor to publish the package, giving the fact that the repo is published in Github.

gif FTW?

atom

Yeoman as always been at our service to make life easier, hope this generator helps you to create atom packages with ease!

Further, it would be useful if you could read creating atom package an official documentation and their API.

Current Interface and Random Port With Nodejs

| Comments

Picking up the random port and current interface for a node.js server is pretty easy!

Fetching the address from the interface:

Just loop through the interfaces of the OS and get the IPv4 from them.

1
2
3
4
5
6
7
8
9
10
11
12
var IPv4 = (function(){
  var interfaces = require('os').networkInterfaces(),
  IP;
  for (var iface in interfaces) {
      interfaces[iface].forEach(function(addr) {
          if (addr.family == 'IPv4') {
              IP = addr.address;
          }
     });
  }
  return IP;
}());

Fetching a random port:

There are few node modules out there for getting random free ports, but there is a easier way:

1
2
3
4
5
6
var http = require('http');
var server = http.createServer();
server.listen(0,IPv4);
server.on('listening', function() {
    console.log('Server is running on: '+IPv4+':'+ server.address().port);
})

The trick is all about server.listen(0,IPv4) this will cause the server to listen on a random port unless in a cluster where each worker will receive the same "random" port each time they do a listen(0) i.e the port is random for the first time and there after it's predictable.

Well, there might be more better ways of doing this, but this was a quick hack I need to make for something I was working on.

ES6 One Liners to Show Off

| Comments

Here is a collection of ES6 one liners to show off!

NodeList to Array:

1
var headings = [ ... document.querySelectorAll('h1') ];

Unique Arrays:

1
[ ...new Set(array) ]

Destructuring:

1
2
var {foo, bar} = {foo: "lorem", bar: "ipsum"};
// foo => lorem and bar => ipsum

Swap like a snake:

1
[a,b] = [b,a]

Max in array?:

1
Math.max(...array);

List comprehension:

1
2
3
[ for (value of ["Harriet", "178"]) value ].join(" was ");
// Would give us "Harriet was 178"
// BTW it was Charles Darwin's tortoise.

_map?

1
2
[{id: 1}, {id: 2}].map(x => x.id)
// [1,2]

Object.isz!

1
2
let Object.isz = (x, y) => x === y || Object.is(x, y);
//^ Credits to Mark S. Miller.

Is it a hidden file?:

1
2
isHidden = (file) => /^\.|~$/.test(file);
isHidden(".DS_STORE") // true

Repeat with me:

1
2
(0/0+"").repeat("7")+ " BatMan!"
// "NaNNaNNaNNaNNaNNaNNaN BatMan!"

If you are using some, please do let me know!

Hope it did blew your mind! ;)

blew