stockr 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -2,6 +2,8 @@
2
2
  # Stockr Gems
3
3
  #
4
4
  gem "redis"
5
+ gem "eletro"
6
+ gem "multipart-post"
5
7
 
6
8
  group :development do
7
9
  gem "sinatra"
@@ -1,11 +1,15 @@
1
1
  GEM
2
2
  specs:
3
3
  diff-lcs (1.1.2)
4
+ eletro (0.1.1)
5
+ stick (>= 1.3.3)
6
+ facets (2.9.0)
4
7
  git (1.2.5)
5
8
  jeweler (1.5.1)
6
9
  bundler (~> 1.0.0)
7
10
  git (>= 1.2.5)
8
11
  rake
12
+ multipart-post (1.0.1)
9
13
  rack (1.2.1)
10
14
  rake (0.8.7)
11
15
  rcov (0.9.9)
@@ -21,6 +25,8 @@ GEM
21
25
  sinatra (1.1.0)
22
26
  rack (~> 1.1)
23
27
  tilt (~> 1.1)
28
+ stick (1.3.3)
29
+ facets (>= 2.1.0)
24
30
  tilt (1.1)
25
31
 
26
32
  PLATFORMS
@@ -28,7 +34,9 @@ PLATFORMS
28
34
 
29
35
  DEPENDENCIES
30
36
  bundler (~> 1.0.0)
37
+ eletro
31
38
  jeweler (~> 1.5.1)
39
+ multipart-post
32
40
  rcov
33
41
  redis
34
42
  rspec (~> 2.1.0)
@@ -1,19 +1,50 @@
1
1
  = stockr
2
2
 
3
3
 
4
- Keep your stock up to date.
5
- With easy bash editing, and web view.
6
- Exports to a bunch of formats too.
4
+ Keep your stock up to date with easy bash editing and web view.
5
+ Some fancy stuff, oh, and it exports to a bunch of formats too.
7
6
 
8
7
 
9
8
  == Use
10
9
 
10
+ stockr quantity name package and/or price
11
+
12
+
13
+ stockr 5 LM358
14
+ > 5x LM358
11
15
 
12
- stockr +5 LM358
13
16
  stockr -2 LM358
14
- stockr LM358
15
17
  > 3x LM358
16
18
 
19
+ stockr LM
20
+ > 3x LM358
21
+
22
+ stockr 2 LM338 DIP
23
+ stockr 2 LM338 0.50
24
+ stockr 2 LM338 SMD 0.50
25
+ ...
26
+
27
+
28
+ === Web View
29
+
30
+ stockr web
31
+
32
+ If a navigator windows doesn`t appear, try: http://localhost:4567
33
+
34
+
35
+ === Part Find
36
+
37
+ Resistors:
38
+
39
+ Supposing you got 1k and 220R resistors, when you ask for "500R" we should see:
40
+
41
+ 2x 1k Parallel
42
+ 2x 220R Serie
43
+
44
+ Alternatives ICs (TODO)
45
+
46
+ This will need human linkage? Isn't there a world database for this?
47
+
17
48
  === Shop List
18
49
 
19
50
  If stock goes under 1, shows how many of that item we need, so just ask for shop:
@@ -23,24 +54,25 @@ If stock goes under 1, shows how many of that item we need, so just ask for shop
23
54
  >2x ATMEGA8
24
55
 
25
56
 
26
- === Web View
27
-
28
- stockr web
57
+ === Export formats
29
58
 
30
- === Import formats
59
+ Export to a bunch of formats (online someday?)
31
60
 
32
- stockr [file]
61
+ stockr [format]
33
62
 
63
+ Available: txt, csv, pdf, html, xml.
34
64
 
35
65
 
36
- === Export formats
66
+ === Import formats
37
67
 
38
- stockr [format]
68
+ You can use the txt format as a backup store. And run:
39
69
 
40
- Available: txt, csv, pdf, html, xml.
70
+ stockr [file]
41
71
 
72
+ To import it.
42
73
 
43
74
 
75
+ = PT
44
76
 
45
77
  == Usar
46
78
 
@@ -50,34 +82,49 @@ sudo gem install stockr
50
82
 
51
83
  Como funfa:
52
84
 
53
- stockr +5 LM358
54
- stockr +2 LM1117
85
+ stockr +5 LM358
86
+ stockr +2 LM1117
55
87
 
56
88
  Dae tu vai, usa um LM em um circ:
57
89
 
58
- stockr -1 LM1117
90
+ stockr -1 LM1117
59
91
 
60
92
  Opa, q q eu tenho de lm?
61
93
 
62
- stockr LM
94
+ stockr LM
95
+
96
+ > 5x LM358
97
+ > 1x LM1117
63
98
 
64
- > 5x LM358
65
- > 1x LM1117
99
+ Aceita preços também:
100
+
101
+
102
+ stockr 10 LM7805 0.95
103
+ > 10x LM7805 0.95 (9.50)
66
104
 
67
105
 
68
106
  === Shop List
69
- Outra opcao eh colocar coisas negativas, ou qdo chegar em valor negativo, vc chama:
70
107
 
71
- stockr shop
108
+ Quando se adiciona peças negativas (stockr -5 LM7805, por exemplo),
109
+ ou qdo uma chega em valor negativo, executando:
110
+
111
+ stockr shop
112
+
113
+ É exibida uma listagem de coisas faltando...
114
+
115
+
116
+ === Interface Web
117
+
118
+ stockr web
119
+
120
+ Se uma janela do navegador não abrir, visite http://localhost:4567
72
121
 
73
- Vem a lista de coisas faltando...
74
122
 
75
- Tem tb `stockr web` q abre o ffox o estoque pra editar visualmente.
123
+ === Exportar Dados
76
124
 
77
- Vc pode por preco tb e calcula tudo...
125
+ stockr [FORMATO]
78
126
 
79
- Ah e tb `stockr [FORMATO]` exporta seu estoque. FORMATO podendo ser txt, csv, pdf, html.....
80
- Sugestoes/duvidas to ae.
127
+ Exporta seu estoque. FORMATO podendo ser txt, csv, pdf, html.....
81
128
 
82
129
 
83
130
 
data/Rakefile CHANGED
@@ -20,7 +20,8 @@ Jeweler::Tasks.new do |gem|
20
20
  gem.email = "x@nofxx.com"
21
21
  gem.authors = ["Marcos Piccinini"]
22
22
 
23
- gem.add_runtime_dependency 'redis'
23
+ # DEPRECATED?
24
+ # gem.add_runtime_dependency 'redis'
24
25
  # Include your dependencies below. Runtime dependencies are required when using your gem,
25
26
  # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
26
27
  # gem.add_runtime_dependency 'jabber4r', '> 0.1'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/bin/stockr CHANGED
@@ -22,5 +22,7 @@ Use:
22
22
 
23
23
  EOF
24
24
  else
25
- puts Stockr.work(ARGV)
25
+ params = ARGV.dup
26
+ ARGV.clear
27
+ Stockr.work(params)
26
28
  end
@@ -1,22 +1,55 @@
1
1
  require "rubygems"
2
2
  require "redis"
3
+ require "eletro"
3
4
 
4
5
  require "stockr/store"
5
6
  require "stockr/part"
7
+ require "stockr/import"
6
8
  require "stockr/export"
7
9
 
8
10
  module Stockr
9
11
 
10
12
  FORMATS = %w{ txt csv html pdf xml }
13
+ DOTFILE = ENV['HOME'] + "/.stockr"
14
+ # TECHUB = "http://techub.heroku.com"
15
+ TECHUB = "http://localhost:3000"
11
16
 
12
- def self.print_parts(res)
13
- return "Not found... go shop!" unless res && !res.empty?
14
- res.map(&:facts).join("\n")
15
17
 
18
+ def self.get_user
19
+ unless File.exists?(DOTFILE)
20
+ puts "What\`s your techub username?"
21
+ name = gets.chomp
22
+ puts "Password?"
23
+ pass = gets.chomp
24
+ File.open(DOTFILE, "w") { |f| f << "name: #{name}\npass: #{pass}"}
25
+ end
26
+ @conf = YAML.load(File.read(DOTFILE))
27
+ [@conf["name"], @conf["pass"]]
16
28
  end
17
29
 
30
+ def self.run(txt)
31
+ if txt.size == 1
32
+ if txt.join =~ /#{FORMATS.join('|')}/
33
+ f = Export.send(txt[0].to_sym)
34
+ "File saved! #{f}"
35
+ else
36
+ puts "Searching...#{txt.join}"
37
+ res = Part.search(txt.join.upcase)
38
+ puts (res && !res.empty?) ? Export.format(res) : "Not found... go shop!"
39
+ res
40
+ end
41
+ else
42
+ if part = Part.create_or_increment(*txt)
43
+ puts "Ok, #{part.facts}"
44
+ else
45
+ puts "Problems creating part..."
46
+ end
47
+ part
48
+ end
49
+ end
18
50
 
19
51
  def self.work(txt)
52
+ get_user
20
53
  txt = txt.split(" ") unless txt.is_a? Array
21
54
  parse = txt
22
55
  case parse.join
@@ -24,24 +57,11 @@ module Stockr
24
57
  when "web" then
25
58
  puts "Starting websever on port."
26
59
  require "stockr/web"
27
- when "shop" then print_parts(Part.missing)
28
- else
29
- if parse.size == 1
30
- if parse.join =~ /#{FORMATS.join('|')}/
31
- f = Export.send(parse[0].to_sym)
32
- "File saved! #{f}"
33
- else
34
- puts "Searching...#{txt.join}"
35
- print_parts Part.search(txt.join.upcase)
36
- end
37
- else
38
- if part = Part.create_or_increment(*parse)
39
- return "Done. #{part.facts}"
40
- else
41
- "Problems creating part..."
42
- end
43
- end
44
-
60
+ when "shop" then puts Export.format(Part.missing)
61
+ when /load.*/ then Import.from_file txt[1] #ARGF
62
+ when /pull.*/ then Import.from_web
63
+ when /push.*/ then Export.to_web
64
+ else run(txt)
45
65
  end
46
66
 
47
67
  end
@@ -3,6 +3,9 @@
3
3
  # Export Redis DB to various formats
4
4
  #
5
5
  #
6
+
7
+ require 'net/http/post/multipart'
8
+
6
9
  module Stockr
7
10
 
8
11
  class Export
@@ -17,18 +20,20 @@ module Stockr
17
20
  @ts ||= Time.now.strftime("%y-%m-%d-%H-%M-%S")
18
21
  end
19
22
 
20
- def format
23
+ def format(data = Part.all)
24
+ return "Nada." unless data && !data.empty?
21
25
  <<TXT
22
- Stockr Export
23
-
24
- #{timestamp}
25
-
26
- -------------------------------------------
26
+ #
27
+ # Stockr Export
28
+ #
29
+ # #{Time.now.strftime("%d/%b/%Y %H:%M:%S")}
30
+ #
31
+ ---------------------------------------------------------------------
27
32
 
28
- #{Part.list.join("\n")}
33
+ #{data.map(&:line).join("\n")}
29
34
 
30
- -------------------------------------------
31
- Total: #{all.size}
35
+ ---------------------------------------------------------------------
36
+ Total: #{data.size} Part(s). #{Part.sum(data)}
32
37
 
33
38
  TXT
34
39
  end
@@ -59,12 +64,32 @@ TXT
59
64
  def xml
60
65
  end
61
66
 
62
- def write(txt, ext)
67
+ def write(txt, ext, path = nil)
63
68
  fname = filename + ".#{ext}"
69
+ fname = path + fname if path
64
70
  File.open(fname, "w") { |f| f << txt }
65
71
  fname
66
72
  end
67
73
 
74
+ def to_web
75
+ user, pass = Stockr.get_user unless user
76
+ file = write(format, :txt, "/tmp/")
77
+ puts "Exporting db to techub..."
78
+ url = URI.parse(TECHUB + "/push")
79
+ File.open(file) do |f|
80
+ Net::HTTP.start(url.host, url.port) do |http|
81
+ req = Net::HTTP::Post::Multipart.new url.path, "file" => UploadIO.new(f, "text/plain", file)
82
+ req.basic_auth user, pass if pass
83
+ puts "Sending file..."
84
+ http.request(req)
85
+ puts req.body
86
+ end
87
+ puts "Done."
88
+ end
89
+
90
+
91
+ end
92
+
68
93
  end
69
94
 
70
95
  end
@@ -0,0 +1,43 @@
1
+ require "net/http"
2
+ # require "net/http"
3
+ require "uri"
4
+
5
+ module Stockr
6
+
7
+ class Import
8
+
9
+ class << self
10
+
11
+ def import(l)
12
+ puts "Importing #{l}" #if Debug
13
+ _, qty, name, price = l.match(/^\s*([0-9]*)x\s*([^\.\s]*)\s*\.*\s*(\d*\.?\d*)/).to_a
14
+ return unless qty || name
15
+ Part.find_or_create(qty, name, price)
16
+ end
17
+
18
+ def from_file(file)
19
+ File.open(file).each_line { |l| import(l) }
20
+ "Loaded"
21
+ end
22
+
23
+ def from_web(user = nil)
24
+ user, pass = Stockr.get_user unless user
25
+ puts "Downloading dump file...#{TECHUB}/#{user}.txt"
26
+ puts url = URI.parse("#{TECHUB}/#{user}.txt")
27
+ Net::HTTP.start(url.host, url.port) { |http|
28
+ req = Net::HTTP::Get.new("/#{user}.txt")
29
+ req.basic_auth user, pass if pass
30
+ res = http.request(req)
31
+ puts "File downloaded, parsing..."
32
+ res.body.each_line { |l| import(l) }
33
+ }
34
+ puts "Done"
35
+ # puts res.body
36
+
37
+
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -3,7 +3,10 @@
3
3
  module Stockr
4
4
 
5
5
  class Part
6
- attr_reader :name, :qty, :price
6
+
7
+ attr_reader :name, :qty, :price, :pkg, :kind
8
+
9
+ CASH = "$ %.3f"
7
10
 
8
11
  def initialize(name, qty = 0, pr = 0)
9
12
  @name = name.upcase
@@ -13,23 +16,31 @@ module Stockr
13
16
 
14
17
  def save
15
18
  return false unless name && !name.empty?
16
- Store.write(name, { :qty => qty, :price => price })
19
+ Store.write(name, { :qty => qty, :price => price, :pkg => pkg })
17
20
  end
18
21
 
19
- def facts
20
- out = "#{qty}x #{name}"
22
+ def line
23
+ out = "#{qty}#{' ' * (5-qty.to_s.size)}x #{name} #{pkg} "
21
24
  if price && !price.zero?
22
25
  out << ("." * (50 - out.size))
23
- out << "$ %.3f" % price
24
- out << " ($ %.3f)" % (price * qty) if qty != 1
26
+ out << CASH % price
27
+ out << " ($ %.3f)" % (price * qty) #if qty != 1
25
28
  end
26
29
  out
27
30
  end
28
31
 
32
+ def facts
33
+ out = "#{qty}x #{name} #{pkg} #{CASH} (#{CASH})" % [price, price_total]
34
+ end
35
+
29
36
  def qty=(v)
30
37
  @qty = v
31
38
  end
32
39
 
40
+ def pkg=(p)
41
+ @pkg = p
42
+ end
43
+
33
44
  def price=(pr)
34
45
  # BigDecimal.new()
35
46
  @price = pr.kind_of?(Numeric) ? pr.to_f : pr.gsub(",", ".").to_f
@@ -43,37 +54,53 @@ module Stockr
43
54
  "{name: '#{name}', qty: '#{qty}', price: '%.3f', total_price: '%.3f'}" % [price, price_total]
44
55
  end
45
56
 
46
- def self.find_or_create(q, name, pr=0, incr = false)
47
- part = search(name, true) || new(name)
48
- incr ? part.qty += q.to_i : part.qty = q.to_i
49
- part.price = pr
50
- part.save
51
- part
52
- end
57
+ class << self
53
58
 
54
- def self.create_or_increment(q, name, pr=0)
55
- find_or_create(q, name, pr, true)
56
- end
59
+ def sum(ary = search("*"))
60
+ CASH % ary.reduce(0) { |i, p| i += p.price_total }
61
+ end
57
62
 
58
- def self.search(txt, exact = false)
59
- if res = Store.find(exact ? txt : "*#{txt}*")
60
- objs = res.map do |k, r|
61
- new(k, r["qty"], r["price"])
63
+ def find_or_create(q, name, pr=0, incr = false)
64
+ part = search(name, true) || new(name)
65
+ incr ? part.qty += q.to_i : part.qty = q.to_i
66
+ if pr =~ /\d/
67
+ part.price = pr
68
+ else
69
+ part.pkg = pr
62
70
  end
63
- exact ? objs[0] : objs # FIXME: better way?
64
- else
65
- nil
71
+ part.save
72
+ part
66
73
  end
67
- end
68
74
 
69
- def self.all; search(''); end
75
+ def create_or_increment(q, name, pr=0)
76
+ find_or_create(q, name, pr, true)
77
+ end
70
78
 
71
- def self.list(txt = "*")
72
- search(txt).map(&:facts) rescue []
73
- end
79
+ def search(txt, exact = false)
80
+ if res = Store.find(exact ? txt : "*#{txt}*")
81
+ objs = res.map do |k, r|
82
+ new(k, r["qty"], r["price"])
83
+ end
84
+ exact ? objs[0] : objs # FIXME: better way?
85
+ else
86
+ nil
87
+ end
88
+ end
89
+
90
+ def all; search(''); end
91
+
92
+ def list(txt = "*")
93
+ search(txt).map(&:line) rescue []
94
+ end
95
+
96
+ def find(txt)
97
+ search(txt, true)
98
+ end
99
+
100
+ def missing
101
+ all.select { |p| p.qty <= 0 }
102
+ end
74
103
 
75
- def self.missing
76
- all.select { |p| p.qty <= 0 }
77
104
  end
78
105
 
79
106
 
@@ -11,7 +11,7 @@ get '/' do
11
11
  parts = Part.all
12
12
  @parts = parts.map(&:to_json)
13
13
  @sum = parts.reduce(0) { |n, p| n += p.price_total }
14
- p @parts
14
+
15
15
  erb <<INDEX
16
16
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
17
17
  <html class="cufon-active cufon-ready"><head>
@@ -239,5 +239,5 @@ post '/' do
239
239
  end
240
240
  end
241
241
 
242
- # Sinatra::Application.run!
242
+ Sinatra::Application.run!
243
243
 
@@ -0,0 +1,12 @@
1
+ Stockr Export
2
+
3
+ 10-12-09-19-23-51
4
+
5
+ -------------------------------------------
6
+
7
+ 100x 10K............................. 0.05 (5.00)
8
+ 50x LM7805........................... 0.10 (5.00)
9
+ 25x LM758............................ 1.00 (25.00)
10
+
11
+ -------------------------------------------
12
+ Total: 0
@@ -8,6 +8,10 @@ require 'stockr'
8
8
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
9
 
10
10
 
11
+ def run(x)
12
+ Stockr.work(x)
13
+ end
14
+
11
15
  RSpec.configure do |config|
12
16
 
13
17
  config.before(:each) do
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Export" do
4
+ include Stockr
5
+
6
+ it "should export txt file" do
7
+ Time.should_receive(:now).exactly(2).times.and_return(Time.at(1291879432))
8
+ run("4 LM448")
9
+ run("txt").should eql("File saved! my_stockr_10-12-09-05-23-52.txt")
10
+ end
11
+
12
+ it "should export to html file" do
13
+
14
+ end
15
+
16
+
17
+ it "should import txt bkp" do
18
+ run("load ./spec/data/export.txt").should eql("Loaded")
19
+ Part.find("LM7805").qty.should eql(50)
20
+ Part.find("LM758").qty.should eql(25)
21
+ end
22
+
23
+ it "should import all values" do
24
+ run("load ./spec/data/export.txt").should eql("Loaded")
25
+ Part.all.size.should eql(3)
26
+ end
27
+
28
+
29
+ end
30
+
@@ -15,5 +15,18 @@ describe "Part" do
15
15
  Part.new("IRF640", 10, "0,30").price.should be_within(0.1).of(0.3)
16
16
  end
17
17
 
18
-
18
+ it "should list all parts" do
19
+ run("-2 LM447")
20
+ run("2 LM448")
21
+ Part.all.should have(2).parts
22
+ end
23
+
24
+ it "should list missing parts" do
25
+ run("-2 LM447")
26
+ run("2 LM448")
27
+ Part.missing.should have(1).part
28
+ Part.missing[0].name.should eql("LM447")
29
+ # run("shop").should eql("-2x LM447 $ 0.000 ($ -0.000)")
30
+ end
31
+
19
32
  end
@@ -1,78 +1,82 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Stockr" do
4
+ include Stockr
4
5
 
5
- def run(x)
6
- Stockr.work(x)
6
+ def find(t)
7
+ Part.find(t)
7
8
  end
8
9
 
9
10
  it "should add parts" do
10
- run("2 LM358").should eql("Done. 2x LM358")
11
- run("LM358").should eql("2x LM358")
11
+ run("2 LM358").should be_a Part
12
+ run("LM358").should have(1).part
12
13
  end
13
14
 
14
- it "should add parts" do
15
- run("100 1K").should eql("Done. 100x 1K")
16
- run("1K").should eql("100x 1K")
15
+ it "should add part names" do
16
+ run("100 1K").name.should eql("1K")
17
+ end
18
+
19
+ it "should add part qty" do
20
+ run("100 1K").qty.should eql(100)
17
21
  end
18
22
 
19
23
  it "should increment existing parts" do
20
- run("2 ATMEGA32").should eql("Done. 2x ATMEGA32")
21
- run("2 ATMEGA32").should eql("Done. 4x ATMEGA32")
22
- run("ATMEGA32").should eql("4x ATMEGA32")
24
+ run("2 ATMEGA32").name.should eql("ATMEGA32")
25
+ run("2 ATMEGA32").qty.should eql(4)
26
+ Part.all.size.should eql(1)
27
+ find("ATMEGA32").qty.should eql(4)
23
28
  end
24
29
 
25
30
  it "should decrement existing parts" do
26
- run("4 LM447").should eql("Done. 4x LM447")
27
- run("-2 LM447").should eql("Done. 2x LM447")
31
+ run("4 LM447")
32
+ run("-2 LM447")
33
+ Part.all.size.should eql(1)
34
+ find("LM447").qty.should eql(2)
35
+ end
36
+
37
+ it "should parse nicely missing parts" do
38
+ run("-2 4N35").qty.should eql(-2)
28
39
  end
29
40
 
30
41
  it "should add missing parts" do
31
- run("-2 LM447").should eql("Done. -2x LM447")
32
- run("2 LM447").should eql("Done. 0x LM447")
42
+ run("-2 LM447")
43
+ find("LM447").qty.should eql(-2)
44
+ run("2 LM447")
45
+ find("LM447").qty.should be_zero
33
46
  end
34
47
 
35
- it "should list missing parts" do
36
- run("-2 LM447").should eql("Done. -2x LM447")
37
- run("2 LM448").should eql("Done. 2x LM448")
38
- run("shop").should eql("-2x LM447")
48
+ it "should add pkgs to parts" do
49
+ run("2 LM338 DIP").pkg.should eql("DIP")
50
+ run("2 LM338 DIP").price.should be_zero
39
51
  end
40
52
 
41
53
  it "should add prices to parts" do
42
- run("1 LM447 0.50").should eql("Done. 1x LM447..........................................$ 0.500")
54
+ run("1 LM447 1.50").price.should be_within(0.1).of(1.5)
43
55
  end
44
56
 
45
57
  it "should add prices to multiple parts (sum)" do
46
- run("2 LM447 0.50").should eql("Done. 2x LM447..........................................$ 0.500 ($ 1.000)")
58
+ run("2 LM447 0.50").price.should be_within(0.1).of(0.5)
47
59
  end
48
60
 
49
61
  it "should upcase the part name" do
50
- run("8 enc28j60").should eql("Done. 8x ENC28J60")
62
+ run("8 enc28j60").name.should eql("ENC28J60")
51
63
  end
52
64
 
53
65
  it "should be case insensitive" do
54
- run("2 LM447").should eql("Done. 2x LM447")
55
- run("lm447").should eql("2x LM447")
66
+ run("2 LM447")
67
+ run("lm447")[0].name.should eql(find("LM447").name)
56
68
  end
57
69
 
58
70
  it "should search pattern" do
59
- run("4 LM447").should eql("Done. 4x LM447")
60
- run("4 LM448").should eql("Done. 4x LM448")
71
+ run("4 LM447")
72
+ run("4 LM448")
61
73
 
62
- run("LM4").should eql("4x LM447\n4x LM448")
74
+ run("LM4").should have(2).parts
63
75
  end
64
76
 
65
77
  it "should not fault when not found" do
66
- run("DUNNO").should eql("Not found... go shop!")
67
- end
68
-
69
- it "should export txt file" do
70
- Time.should_receive(:now).and_return(Time.at(1291879432))
71
- run("4 LM448").should eql("Done. 4x LM448")
72
- run("txt").should eql("File saved! my_stockr_10-12-09-05-23-52.txt")
78
+ run("DUNNO").should be_nil
73
79
  end
74
80
 
75
- it "should export to html file" do
76
- end
77
81
 
78
82
  end
@@ -0,0 +1,88 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{stockr}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Marcos Piccinini"]
12
+ s.date = %q{2010-12-11}
13
+ s.default_executable = %q{stockr}
14
+ s.description = %q{Help keep track of stuff (good for electronics)}
15
+ s.email = %q{x@nofxx.com}
16
+ s.executables = ["stockr"]
17
+ s.extra_rdoc_files = [
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".rspec",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/stockr",
29
+ "lib/stockr.rb",
30
+ "lib/stockr/assets/bundle.js",
31
+ "lib/stockr/export.rb",
32
+ "lib/stockr/import.rb",
33
+ "lib/stockr/part.rb",
34
+ "lib/stockr/store.rb",
35
+ "lib/stockr/web.rb",
36
+ "spec/data/export.txt",
37
+ "spec/spec_helper.rb",
38
+ "spec/stockr/export_spec.rb",
39
+ "spec/stockr/part_spec.rb",
40
+ "spec/stockr_spec.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/nofxx/stockr}
43
+ s.licenses = ["MIT"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.7}
46
+ s.summary = %q{Keep track of all your stuff}
47
+ s.test_files = [
48
+ "spec/spec_helper.rb",
49
+ "spec/stockr/export_spec.rb",
50
+ "spec/stockr/part_spec.rb",
51
+ "spec/stockr_spec.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<redis>, [">= 0"])
60
+ s.add_runtime_dependency(%q<eletro>, [">= 0"])
61
+ s.add_runtime_dependency(%q<multipart-post>, [">= 0"])
62
+ s.add_development_dependency(%q<sinatra>, [">= 0"])
63
+ s.add_development_dependency(%q<rspec>, ["~> 2.1.0"])
64
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
66
+ s.add_development_dependency(%q<rcov>, [">= 0"])
67
+ else
68
+ s.add_dependency(%q<redis>, [">= 0"])
69
+ s.add_dependency(%q<eletro>, [">= 0"])
70
+ s.add_dependency(%q<multipart-post>, [">= 0"])
71
+ s.add_dependency(%q<sinatra>, [">= 0"])
72
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
73
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
74
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
75
+ s.add_dependency(%q<rcov>, [">= 0"])
76
+ end
77
+ else
78
+ s.add_dependency(%q<redis>, [">= 0"])
79
+ s.add_dependency(%q<eletro>, [">= 0"])
80
+ s.add_dependency(%q<multipart-post>, [">= 0"])
81
+ s.add_dependency(%q<sinatra>, [">= 0"])
82
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
83
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
84
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
85
+ s.add_dependency(%q<rcov>, [">= 0"])
86
+ end
87
+ end
88
+
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Marcos Piccinini
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-09 00:00:00 -02:00
17
+ date: 2010-12-11 00:00:00 -02:00
18
18
  default_executable: stockr
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -31,7 +31,7 @@ dependencies:
31
31
  prerelease: false
32
32
  version_requirements: *id001
33
33
  - !ruby/object:Gem::Dependency
34
- name: sinatra
34
+ name: eletro
35
35
  requirement: &id002 !ruby/object:Gem::Requirement
36
36
  none: false
37
37
  requirements:
@@ -40,70 +40,83 @@ dependencies:
40
40
  segments:
41
41
  - 0
42
42
  version: "0"
43
- type: :development
43
+ type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: *id002
46
46
  - !ruby/object:Gem::Dependency
47
- name: rspec
47
+ name: multipart-post
48
48
  requirement: &id003 !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ~>
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  segments:
54
- - 2
55
- - 1
56
54
  - 0
57
- version: 2.1.0
58
- type: :development
55
+ version: "0"
56
+ type: :runtime
59
57
  prerelease: false
60
58
  version_requirements: *id003
61
59
  - !ruby/object:Gem::Dependency
62
- name: bundler
60
+ name: sinatra
63
61
  requirement: &id004 !ruby/object:Gem::Requirement
64
62
  none: false
65
63
  requirements:
66
- - - ~>
64
+ - - ">="
67
65
  - !ruby/object:Gem::Version
68
66
  segments:
69
- - 1
70
- - 0
71
67
  - 0
72
- version: 1.0.0
68
+ version: "0"
73
69
  type: :development
74
70
  prerelease: false
75
71
  version_requirements: *id004
76
72
  - !ruby/object:Gem::Dependency
77
- name: jeweler
73
+ name: rspec
78
74
  requirement: &id005 !ruby/object:Gem::Requirement
79
75
  none: false
80
76
  requirements:
81
77
  - - ~>
82
78
  - !ruby/object:Gem::Version
83
79
  segments:
80
+ - 2
84
81
  - 1
85
- - 5
86
- - 1
87
- version: 1.5.1
82
+ - 0
83
+ version: 2.1.0
88
84
  type: :development
89
85
  prerelease: false
90
86
  version_requirements: *id005
91
87
  - !ruby/object:Gem::Dependency
92
- name: rcov
88
+ name: bundler
93
89
  requirement: &id006 !ruby/object:Gem::Requirement
94
90
  none: false
95
91
  requirements:
96
- - - ">="
92
+ - - ~>
97
93
  - !ruby/object:Gem::Version
98
94
  segments:
95
+ - 1
99
96
  - 0
100
- version: "0"
97
+ - 0
98
+ version: 1.0.0
101
99
  type: :development
102
100
  prerelease: false
103
101
  version_requirements: *id006
104
102
  - !ruby/object:Gem::Dependency
105
- name: redis
103
+ name: jeweler
106
104
  requirement: &id007 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ segments:
110
+ - 1
111
+ - 5
112
+ - 1
113
+ version: 1.5.1
114
+ type: :development
115
+ prerelease: false
116
+ version_requirements: *id007
117
+ - !ruby/object:Gem::Dependency
118
+ name: rcov
119
+ requirement: &id008 !ruby/object:Gem::Requirement
107
120
  none: false
108
121
  requirements:
109
122
  - - ">="
@@ -111,9 +124,9 @@ dependencies:
111
124
  segments:
112
125
  - 0
113
126
  version: "0"
114
- type: :runtime
127
+ type: :development
115
128
  prerelease: false
116
- version_requirements: *id007
129
+ version_requirements: *id008
117
130
  description: Help keep track of stuff (good for electronics)
118
131
  email: x@nofxx.com
119
132
  executables:
@@ -121,14 +134,12 @@ executables:
121
134
  extensions: []
122
135
 
123
136
  extra_rdoc_files:
124
- - LICENSE.txt
125
137
  - README.rdoc
126
138
  files:
127
139
  - .document
128
140
  - .rspec
129
141
  - Gemfile
130
142
  - Gemfile.lock
131
- - LICENSE.txt
132
143
  - README.rdoc
133
144
  - Rakefile
134
145
  - VERSION
@@ -136,12 +147,16 @@ files:
136
147
  - lib/stockr.rb
137
148
  - lib/stockr/assets/bundle.js
138
149
  - lib/stockr/export.rb
150
+ - lib/stockr/import.rb
139
151
  - lib/stockr/part.rb
140
152
  - lib/stockr/store.rb
141
153
  - lib/stockr/web.rb
154
+ - spec/data/export.txt
142
155
  - spec/spec_helper.rb
156
+ - spec/stockr/export_spec.rb
143
157
  - spec/stockr/part_spec.rb
144
158
  - spec/stockr_spec.rb
159
+ - stockr.gemspec
145
160
  has_rdoc: true
146
161
  homepage: http://github.com/nofxx/stockr
147
162
  licenses:
@@ -156,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
171
  requirements:
157
172
  - - ">="
158
173
  - !ruby/object:Gem::Version
159
- hash: -709536225112595033
174
+ hash: -51961578438735344
160
175
  segments:
161
176
  - 0
162
177
  version: "0"
@@ -177,5 +192,6 @@ specification_version: 3
177
192
  summary: Keep track of all your stuff
178
193
  test_files:
179
194
  - spec/spec_helper.rb
195
+ - spec/stockr/export_spec.rb
180
196
  - spec/stockr/part_spec.rb
181
197
  - spec/stockr_spec.rb
@@ -1,20 +0,0 @@
1
- Copyright (c) 2010 Marcos Piccinini
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.