This is an useful pattern to avoid circular dependencies while requiring other files in node.
Circular dependencies manifest when a require returns an empty object: "the circular dependency means that other code receives an incomplete module object"
The solution is to 'augment' the exports instead of replacing it.
So, if another module got a reference to the exported members they are eventually completed.
//requires at the beginning, as usual
//..
const PublicMethods = {
method1: () => {},
method2: (x) => {...},
...
];
// -- private & other methods
...
...
//augment the exports at the end of the file:
Object.assign(module.exports, PublicMethods);
gsusmonzon
Wednesday, October 23, 2019
Wednesday, August 23, 2017
Get Response Time with Curl - curltime
Save this script in your path (echo $PATH) as curltime:
#!/bin/bash
/usr/bin/curl -o /dev/null \
-s -w " time_namelookup: %{time_namelookup}\n time_connect: %{time_connect}\n time_appconnect: %{time_appconnect}\n time_pretransfer: %{time_pretransfer}\n time_redirect: %{time_redirect}\n time_starttransfer: %{time_starttransfer}\n ----------\n time_total: %{time_total}\n" \
$1
Make it executable
chmod 0755 /usr/local/bin/curltime
Now you can use it to check the response time of an url. Ex:
curltime https://marca.com
Source: based on https://viewsby.wordpress.com/2013/01/07/get-response-time-with-curl/
#!/bin/bash
/usr/bin/curl -o /dev/null \
-s -w " time_namelookup: %{time_namelookup}\n time_connect: %{time_connect}\n time_appconnect: %{time_appconnect}\n time_pretransfer: %{time_pretransfer}\n time_redirect: %{time_redirect}\n time_starttransfer: %{time_starttransfer}\n ----------\n time_total: %{time_total}\n" \
$1
Make it executable
chmod 0755 /usr/local/bin/curltime
Now you can use it to check the response time of an url. Ex:
curltime https://marca.com
Source: based on https://viewsby.wordpress.com/2013/01/07/get-response-time-with-curl/
Wednesday, June 14, 2017
Merge 2 commits when there are commits in between
Super handy trick based on based on https://stackoverflow.com/questions/30704254/merge-two-commits-where-commits-are-between
Lets say we have 2 commit we want to merge
f68ffb5 commit 6
...
d294fac commit 1
This is important: you have to give reference to a commit before the first one involved (in this case, the one that you want to squash to). Here we make the "before" reference with ^.
# rebase to the commit **before** commit 1
git rebase -i d294fac^
You invoked an interactive rebase. An editor window opens. Rearrange commits as desired (read the notes in the editor that opens)
In this list the commits go in reverse order (not as in git log): from the earliest to the latest.
Rearrange lines in the following way:
pick d294fac //--- commit 1
squash f68ffb5 //--- commit 6
pick //--- commit 2
pick //--- ommit 3
pick //--- commit 4
pick //--- commit 5
or (leave the squashed commits in last place)
pick d294fac //--- commit 1
squash f68ffb5 //--- commit 6
pick //--- commit 2
pick //--- ommit 3
pick //--- commit 4
pick //--- commit 5
Lets say we have 2 commit we want to merge
f68ffb5 commit 6
...
d294fac commit 1
This is important: you have to give reference to a commit before the first one involved (in this case, the one that you want to squash to). Here we make the "before" reference with ^.
# rebase to the commit **before** commit 1
git rebase -i d294fac^
You invoked an interactive rebase. An editor window opens. Rearrange commits as desired (read the notes in the editor that opens)
In this list the commits go in reverse order (not as in git log): from the earliest to the latest.
Rearrange lines in the following way:
pick d294fac //--- commit 1
squash f68ffb5 //--- commit 6
pick
pick
pick
pick
or (leave the squashed commits in last place)
pick d294fac //--- commit 1
squash f68ffb5 //--- commit 6
pick
pick
pick
pick
Tuesday, September 6, 2016
Back In Time: Backups for your personal computer
'Back in Time' ( http://backintime.le-web.org/ ) is a linux program to make regular backups. I recommend it.
Why?
- simple. Linux only.
- it uses incremental backups and hardlinks, saving time and space between 'snapshots'
- 'snapshots' are saved as folders. Each snapshot is seen as a 'copy' of the system at a given time, but you still can get the 3-weeks ago version of a file, just by moving inside the file-tree of the snapshot. This is key: you can plug your backup drive to another computer and access the snapshots from the file explorer. No need to install anything to read the backup
- autoremove old backups based on age or free space
- backups are made to a drive or a remove machine (ssh). No cloud storage option (S3, box, etc)
- handles backups of several machines with no extra configuration. Snapshots of different machines are stored in different folders
- Just works
How I use it
(for all my computers) I run Back in time backups on demand (not scheduled) and unencrypted. Both options are available if needed.Backups are stored in a ext4 external drive (ext4 is linux native but still read-accessible from OSX and Windows)
Install
This works for ubuntu. For others, go to the original http://backintime.le-web.org/
sudo add-apt-repository ppa:bit-team/stable
sudo apt-get update
sudo apt-get install backintime-gnome
Note: latest versions are only qt-based. You could install the `backintime-qt4` package instead `backintime-gnome`
Configure
Connect the external drive for the backups, and launch Back in Time. The first time you need to configure how to make backups for the computer (accessible from settings / preferences as well).
In the settings, you need to set where and when to save snapshots. For example I choose
[General] tab
- Profile: Main profile
- Mode: local (or local encrypted)
- Where to save snapshots / destination: your drive , partition or subfolder.
- Schedule disabled. I will save a new snapshot on demand

I usually include the home folder, or just the Documents, Pictures and .ssh folder. I exclude the Music and Videos folder.
[Autoremove]
defaults are good for me
[Options]
- Check Use checksum to detect changes
- Check Full rsync mode (or not)
- Check Backup replaced files on restore
- Uncheck 'continue on errors'

[Expert options]
- Uncheck any option related to cron
- Check ‘Run ionice’ when taking a manual snapshot
- you may check 'Preserve ACL' ( as src and dst are Ext4, otherwise uncheck ). I finally uncheck it since gave me errors for some of my files

-
Save configuration > OK
Save configuration > OK
New backup
You can make a new backup clicking on the 'disk' icon on the main toolbar. The first backup might take some minutes. Newer snapshots execute faster.
In case you need to back up files with special permission, you might need to run your backintime with sudo. The profile id is in the Settings > General , in the Advanced section
sudo -i backintime-qt4 --config ~/.config/backintime/config --profile-id 1
Uninstall
sudo ppa-purge ppa:bit-team/stable
sudo apt-get remove backintime-*Saturday, September 3, 2016
Nautilus: Add touch action in context menu
This is a modification I make to nautilus in every computer I own.
Just make a 'touch' option available when you select a file or folder. This tutorial can be modified to include other commands as well. I have used it for Ubuntu 12.04, 14.04 and 16.04.

First, install nautilus actions
sudo apt-get install nautilus-actions
and launch it.
nautilus-actions
(1) Create a new item

(2) Right click on the new action that appeared in the Item list area
Restart Nautilus
pkill nautilus
Well done!
Just make a 'touch' option available when you select a file or folder. This tutorial can be modified to include other commands as well. I have used it for Ubuntu 12.04, 14.04 and 16.04.

First, install nautilus actions
sudo apt-get install nautilus-actions
and launch it.
nautilus-actions
(1) Create a new item
- Create the item using the '+' icon and name the action (Ex: 'Touch'). Use a short name, since it is used in teh context menu
- Edit Action and Command tabs accordingliy. Ex:
- Path: /usr/bin/touch
- Parameters: %F (see Legend button to get more options)
- Working directory: %d
- Save (icon save)

(2) Right click on the new action that appeared in the Item list area
- go to preferences
- Ensure the 'Nautilus menu layout' > 'Create a root...' is disabled
Restart Nautilus
pkill nautilus
Well done!
Sunday, July 19, 2015
How to determine the time zone of an IP in Ruby
In ruby / Rails, you may need to get the timezone of an ip address.
One of the best options is the Maxmind.com GeoIP . The solution provided here applies to geolocate an IP address to get the timezone, country, city etc
The service is not free but you can pay 20$ for 50K resolutions. Fair enough.
I write a new post on how to query the web service.
Another option is to resolve the geolocation locally. Maxmind provides a free database that is updated every month. As a free product, it is less accurate than the web service but gives good results. http://dev.maxmind.com/geoip/legacy/geolite/
- download the database
- include the `geoip` gem, that will read the database
- our code to query the geoip gem
- link back to Maxmind
cd /tmp
wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz
mv GeoLiteCity.dat /usr/local/share/GeoIP/
I recommend you to make a bash script with these commands and run a cron once a month
To read the legacy GeoIP database I recommend the pure ruby geoip gem. Just include in your Gemfile
gem 'geoip'
or
gem install geoip
When a ip resolves to a location without timezone, the best trick I found was to try with 'enclosing' networks (bigger supernets) until a result has timezone. That is: first try a perfect match, then try for the network with the last bit of the address masked, then mask 2 bits ... https://en.wikipedia.org/wiki/Subnetwork#Subnet_and_host_counts
To resolve the ip
This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com
One of the best options is the Maxmind.com GeoIP . The solution provided here applies to geolocate an IP address to get the timezone, country, city etc
Local or Remote
For better results I recommend to use their web service to geolocate a city : http://dev.maxmind.com/geoip/geoip2/web-services .The service is not free but you can pay 20$ for 50K resolutions. Fair enough.
I write a new post on how to query the web service.
Another option is to resolve the geolocation locally. Maxmind provides a free database that is updated every month. As a free product, it is less accurate than the web service but gives good results. http://dev.maxmind.com/geoip/legacy/geolite/
Local set up
We need:- download the database
- include the `geoip` gem, that will read the database
- our code to query the geoip gem
- link back to Maxmind
Download database
Read http://dev.maxmind.com/geoip/legacy/install/city/ for instructions. It boils down to:cd /tmp
wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz
mv GeoLiteCity.dat /usr/local/share/GeoIP/
I recommend you to make a bash script with these commands and run a cron once a month
Required gem
To read the legacy GeoIP database I recommend the pure ruby geoip gem. Just include in your Gemfile
gem 'geoip'
or
gem install geoip
Boilerplate
The interface of GeoiP gem is really simple however, as we are using a database with less than 100% accuracy, we should account for cases where timezone is not available.When a ip resolves to a location without timezone, the best trick I found was to try with 'enclosing' networks (bigger supernets) until a result has timezone. That is: first try a perfect match, then try for the network with the last bit of the address masked, then mask 2 bits ... https://en.wikipedia.org/wiki/Subnetwork#Subnet_and_host_counts
class Ip2Geo DB_PATH = '/usr/local/share/GeoIP/GeoLiteCity.dat' def timezone(ipv4) if ipv4.present? addr = IPAddr.new(ipv4.to_s.strip) 32.downto(16).map do |mask| #if an address fails, test with enclosing network X.X.X.X , X.X.X.0 , X.X.0.0 ... network = addr.mask(mask).to_i c = db.city(network) if c && c.timezone return c.timezone end end end nil end #a similar pattern can be re-used def country_code(ipv4) if ipv4.present? candidate = ipv4.to_s.strip addr = IPAddr.new(ipv4.to_s.strip) 32.downto(16).map do |mask| network = addr.mask(mask).to_i c = db.city(network) if c && c.country_code2 return c.country_code2 end end end nil end def location(ipv4) if ipv4.present? candidate = ipv4.to_s.strip addr = IPAddr.new(ipv4.to_s.strip) 32.downto(16).map do |mask| network = addr.mask(mask).to_i c = db.city(network) return c if c end end nil end def db @db ||= GeoIP.new(DB_PATH) end end
To resolve the ip
locator = Ip2Geo.new
locator.timezone('193.110.128.199')
Attribution
Remember that the use of the free database requires an attribution: The attribution requirement may be met by including the following in all advertising and documentation mentioning features of or use of this databaseThis product includes GeoLite data created by MaxMind, available from http://www.maxmind.com
Friday, June 12, 2015
Canon lide 220 in Ubuntu 14.04
Last week I bought a Canon lide 220 scanner. You get a decent device for the price.
(since I had to read several posts) Here are in a single page all the steps I needed to make it work in Ubuntu 14.04 (via xsane).
connect the scanner
ensure it is recognized
lsusb
in teh output, search for the Canon device
...
Bus 003 Device 003: ID 04a9:190f Canon, Inc.
...
ensure your user has access to the bus (otherwise you'll have to launch everytime xsane as root)
sudo chmod u+w /dev/bus/usb//
in my case
sudo chmod u+w /dev/bus/usb/003/003
Then, add this ppa to install latest version of xsane
sudo add-apt-repository ppa:rolfbensch/sane-git
and install xsane
sudo apt-get update && sudo apt-get install gocr libsane-extras xsane-common xsane
if you have problems, install a couple of additional packets with
sudo apt-get update && sudo apt-get install gocr libusb-dev libsane-dev libsane-extras xsane-common xsane
now you can run
xsane
and the scanner is working!
(since I had to read several posts) Here are in a single page all the steps I needed to make it work in Ubuntu 14.04 (via xsane).
connect the scanner
ensure it is recognized
lsusb
in teh output, search for the Canon device
...
Bus 003 Device 003: ID 04a9:190f Canon, Inc.
...
ensure your user has access to the bus (otherwise you'll have to launch everytime xsane as root)
sudo chmod u+w /dev/bus/usb/
in my case
sudo chmod u+w /dev/bus/usb/003/003
Then, add this ppa to install latest version of xsane
sudo add-apt-repository ppa:rolfbensch/sane-git
and install xsane
sudo apt-get update && sudo apt-get install gocr libsane-extras xsane-common xsane
if you have problems, install a couple of additional packets with
sudo apt-get update && sudo apt-get install gocr libusb-dev libsane-dev libsane-extras xsane-common xsane
now you can run
xsane
Subscribe to:
Posts (Atom)