Skip to content

Instantly share code, notes, and snippets.

@gorenje
Created March 4, 2012 10:53
Show Gist options
  • Save gorenje/1972384 to your computer and use it in GitHub Desktop.
Save gorenje/1972384 to your computer and use it in GitHub Desktop.
Generating a qrcode in a terminal window
rvm use --create ruby-1.9.2-p180@grcode
# -*- ruby -*-
source 'http://rubygems.org'
gem 'term-ansicolor'
gem 'cheat'
gem 'pry'
gem 'highline'
gem 'rqrcode'
git clone git://gist.github.com/1972384.git
cd 1972384/
## ensure that rvm automagically uses the .rvmrc defined in the gist
gem install bundler
bundle
bundle exec ruby qrcode.rb
# -*- coding: utf-8 -*-
require 'rqrcode'
require 'term/ansicolor'
require 'highline/import'
require 'optparse'
require 'cgi'
@size = 4
@quality = 'q'
@password = false
@smsnum = nil
@binary = nil
@filename = nil
@tweet = false
opts = OptionParser.new do |o|
o.program_name = 'ruby qrcode.rb'
o.separator 'Options:'
o.on('--size NUM', '-s', 'Size Default: %d' % @size) { |a| @size = a }
o.on('--level NUM', '-l', 'Quality level: %s (possible values l,m,q,h)' % @quality) { |a| @quality = a }
o.on('--password', '-p', 'Password entry') { @password = true }
o.on('--binary', '-b', 'Use binary representation') { @binary = true }
o.on('--file NAME', '-f', 'Read from file') { |a| @filename = a }
o.on('--sms NUM', '-t', 'Create an SMS code to given number') { |a| @smsnum = a }
o.on('--tweet', nil, 'Create twitter qrcode') { @tweet = true }
o.on_tail('--help', '-h', 'Show this message') do
puts opts
exit
end
end
opts.parse!(ARGV)
class String
include Term::ANSIColor
# my terminal is black background, so space comes out as black and to have
# white, need to have bright-white.
def dark_if(yes_or_no)
yes_or_no ? ' ' : on_white.white.bold
end
end
ary = nil
pword = if ARGV.length > 0
ARGV[0]
elsif @filename
File.open(@filename).read
else
ask("Enter the magic: "){ |q| q.echo = !@password }
end
pword = "sms:#{@smsnum}?body=#{pword}" unless @smsnum.nil?
pword = "twitter://post?message=#{CGI.escape(pword).gsub(/[+]/,'%20')}" if @tweet
# Generate the qrcode but store it in an 2D array that is 2 pixels too bigger
# so that we can get a white border around the qrcode. this allows the
# scanner to pickup the code if the terminal window has a black (or dark) background.
qrcode = nil
3.times do
begin
qrcode = RQRCode::QRCode.
new(pword, :size => @size.to_i, :level => @quality.to_sym)
rescue RQRCode::QRCodeRunTimeError => e
@size = (@size.to_i + 1).to_s
end
end
ary_size = qrcode.module_count + 2
ary = Array.new(ary_size) { |_| [false]*ary_size }
qrcode.modules.each_index do |x|
qrcode.modules.each_index do |y|
ary[x+1][y+1] = qrcode.dark?(x,y)
end
end
def dump(yes_or_no)
print '██'.dark_if(yes_or_no)
STDERR.print(yes_or_no ? "1" : "0") if @binary
end
# because of the font setting on my terminal, to get a square qrcode, need to use
# ██ instead of just █ ...
(0...ary.size).to_a.tap do |loopidx|
loopidx.each do |xidx|
loopidx.each do |yidx|
# print '██'.dark_if(ary[xidx][yidx])
dump(ary[xidx][yidx])
end
puts ""
STDERR.puts "" if @binary
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment