shopli 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +56 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +2 -0
- data/bin/daemon.rb +10 -0
- data/lib/shopli.rb +7 -0
- data/lib/shopli/barcode.rb +35 -0
- data/lib/shopli/barcode_reader.rb +14 -0
- data/lib/shopli/device.rb +27 -0
- data/lib/shopli/mode.rb +15 -0
- data/lib/shopli/open_food_facts.rb +28 -0
- data/lib/shopli/product.rb +10 -0
- data/lib/shopli/version.rb +3 -0
- data/shopli.gemspec +27 -0
- data/spec/3029330003533.json +1 -0
- data/spec/barcode_spec.rb +39 -0
- data/spec/integration/open_food_facts_spec.rb +13 -0
- data/spec/open_food_facts_spec.rb +39 -0
- data/spec/spec_helper.rb +8 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 99ca4e3245d6953d6d110daff6ef93d351206645
|
4
|
+
data.tar.gz: 295de735a0669259ab46b20b70e4d4f85e31aed5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8848f63c961791887f46ce62e47859385a6122011c95fc5a4f4e11a5fc3a05a51edcd0458f8790e85b733562343355710d67838a05b93ff170ab4d89c336ff46
|
7
|
+
data.tar.gz: e9825e439ac413a3b714e2ffd8432aede793cd07664379d6de4b9ba54471578c58592eccffe78570ac675977bcaefb704441005a47c101fa3989546734642218
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/kamaradclimber/libdevinput.git
|
3
|
+
revision: 2b5a4df98eef7d794fe44d4e98742c5bb6d32631
|
4
|
+
specs:
|
5
|
+
libdevinput (0.0.2)
|
6
|
+
|
7
|
+
PATH
|
8
|
+
remote: .
|
9
|
+
specs:
|
10
|
+
shopli (0.0.1)
|
11
|
+
rest-client
|
12
|
+
|
13
|
+
GEM
|
14
|
+
remote: https://rubygems.org/
|
15
|
+
specs:
|
16
|
+
coveralls (0.7.0)
|
17
|
+
multi_json (~> 1.3)
|
18
|
+
rest-client
|
19
|
+
simplecov (>= 0.7)
|
20
|
+
term-ansicolor
|
21
|
+
thor
|
22
|
+
diff-lcs (1.2.5)
|
23
|
+
docile (1.1.3)
|
24
|
+
mime-types (2.1)
|
25
|
+
multi_json (1.9.0)
|
26
|
+
rake (10.3.1)
|
27
|
+
rest-client (1.6.7)
|
28
|
+
mime-types (>= 1.16)
|
29
|
+
rspec (2.14.1)
|
30
|
+
rspec-core (~> 2.14.0)
|
31
|
+
rspec-expectations (~> 2.14.0)
|
32
|
+
rspec-mocks (~> 2.14.0)
|
33
|
+
rspec-core (2.14.8)
|
34
|
+
rspec-expectations (2.14.5)
|
35
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
36
|
+
rspec-mocks (2.14.6)
|
37
|
+
simplecov (0.8.2)
|
38
|
+
docile (~> 1.1.0)
|
39
|
+
multi_json
|
40
|
+
simplecov-html (~> 0.8.0)
|
41
|
+
simplecov-html (0.8.0)
|
42
|
+
term-ansicolor (1.3.0)
|
43
|
+
tins (~> 1.0)
|
44
|
+
thor (0.18.1)
|
45
|
+
tins (1.0.0)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
bundler (~> 1.6)
|
52
|
+
coveralls
|
53
|
+
libdevinput!
|
54
|
+
rake
|
55
|
+
rspec
|
56
|
+
shopli!
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Gregoire Seux
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Shopli
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/kamaradclimber/shopli.png?branch=master)](https://travis-ci.org/kamaradclimber/shopli)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/shopli.png)](http://badge.fury.io/rb/shopli)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/kamaradclimber/shopli/badge.png)](https://coveralls.io/r/kamaradclimber/shopli)
|
6
|
+
|
7
|
+
Using a barcode reader, scan all item you put in the trash.
|
8
|
+
Shopli will use that list of barcodes and generate a shopping list.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'shopli'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install shopli
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
TODO: Write usage instructions here
|
27
|
+
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
1. Fork it ( https://github.com/kamaradclimber/shopli/fork )
|
31
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
33
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
34
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/daemon.rb
ADDED
data/lib/shopli.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Shopli
|
2
|
+
class Barcode
|
3
|
+
|
4
|
+
BARCODE_SIZE = 13
|
5
|
+
|
6
|
+
def ==(other)
|
7
|
+
other && @barcode == other.barcode
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.read(events)
|
11
|
+
events.lazy.select do |event|
|
12
|
+
is_release = (event.type == 1) && (event.value_str.eql? 'Release')
|
13
|
+
is_release
|
14
|
+
end.lazy.slice_before do |event|
|
15
|
+
event.code_str.eql? 'Enter'
|
16
|
+
end.lazy.map do |cons_events|
|
17
|
+
cons_events.reject { |e| e.code_str.eql? 'Enter' }
|
18
|
+
end.lazy.reject do |cons_events|
|
19
|
+
cons_events.empty?
|
20
|
+
end.map do |cons_events|
|
21
|
+
barcode = cons_events.map { |e| e.code_str }.join.to_i
|
22
|
+
Barcode.new barcode
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(barcode)
|
27
|
+
@barcode = barcode
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
@barcode.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Shopli
|
2
|
+
class Device
|
3
|
+
|
4
|
+
attr_reader :current_mode
|
5
|
+
|
6
|
+
TRASH_MODE = Mode.new 'trash'
|
7
|
+
SHOP_MODE = Mode.new 'shop'
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@current_mode = TRASH_MODE
|
11
|
+
end
|
12
|
+
|
13
|
+
def read(stream)
|
14
|
+
Barcode.read(stream).each do |barcode|
|
15
|
+
process barcode
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
private
|
21
|
+
def process(barcode)
|
22
|
+
puts "#{Time.now.to_i} #{barcode.to_s}"
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/shopli/mode.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
|
3
|
+
class Shopli
|
4
|
+
class OpenFoodFacts
|
5
|
+
|
6
|
+
API_URL = 'http://fr.openfoodfacts.org/api'
|
7
|
+
API_VERSION = 'v0'
|
8
|
+
API_ENDPOINT = 'produit'
|
9
|
+
|
10
|
+
def fetch_product(barcode)
|
11
|
+
url = [API_URL, API_VERSION, API_ENDPOINT, barcode + '.json'].join '/'
|
12
|
+
resource = RestClient::Resource.new url
|
13
|
+
resource.get
|
14
|
+
end
|
15
|
+
|
16
|
+
def product(barcode)
|
17
|
+
json = fetch_product(barcode)
|
18
|
+
p = JSON.parse(json)
|
19
|
+
if p['status'] == 1
|
20
|
+
product = Product.new p['product']['_id']
|
21
|
+
product.name = p['product']['generic_name']
|
22
|
+
product
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/shopli.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'shopli/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "shopli"
|
8
|
+
spec.version = Shopli::VERSION
|
9
|
+
spec.authors = ["Gregoire Seux"]
|
10
|
+
spec.email = ["shopli@familleseux.net"]
|
11
|
+
spec.summary = %q{Generate a shop list from a list of barcodes scanned before trash}
|
12
|
+
spec.description = %q{If you get the barcode of all things you put to the trash, shopli will generate your next shop list}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File. basename(f) }
|
18
|
+
spec.test_files = `git ls-files -- spec/*`.split("\n")
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'rest-client'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "coveralls"
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"status_verbose":"product found","status":1,"product":{"labels_hierarchy":[],"_id":"3029330003533","categories_hierarchy":["fr:pains-de-mie","fr:pains-de-mie-complet","en:breads"],"checkers_tags":[],"labels_tags":[],"image_small_url":"http://fr.openfoodfacts.org/images/products/302/933/000/3533/front.9.200.jpg","code":"3029330003533","lang":"fr","traces_tags":["lait","oeufs","sesame","soja"],"photographers":["manu1400"],"generic_name":"Pain complet en tranche","ingredients_that_may_be_from_palm_oil_tags":["e471-mono-et-diglycerides-d-acides-gras-alimentaires"],"_keywords":["pain","crousti","france","mie","en","de","moelleux","jacquet","complet","tranche"],"rev":17,"editors":["manu1400","andre","stephane"],"emb_codes":"","max_imgid":"4","additives_tags":["e575","e282","e471","e300"],"emb_codes_orig":"","informers_tags":["andre","manu1400","stephane"],"nutrient_levels_tags":["fat-in-low-quantity","saturated-fat-in-low-quantity","sugars-in-moderate-quantity","salt-in-moderate-quantity"],"additives_n":4,"photographers_tags":["andre"],"unknown_nutrients_tags":[],"packaging_tags":["sac-plastique"],"nutriments":{"sodium":0.44,"sugars":6.5,"fat_unit":"g","carbohydrates_unit":"g","proteins_unit":"g","fat":2.5,"proteins_serving":12.8,"sodium_serving":0.535,"proteins":10.5,"fat_serving":3.04,"sugars_unit":"g","sugars_100g":"6.5","sodium_unit":"g","saturated-fat_unit":"g","saturated-fat_serving":0.608,"sodium_100g":0.44,"fiber_unit":"g","energy":1067,"energy_unit":"kJ","sugars_serving":7.9,"carbohydrates_100g":44,"proteins_100g":10.5,"fiber_serving":7.29,"carbohydrates_serving":53.5,"energy_serving":1300,"fat_100g":"2.5","saturated-fat_100g":"0.5","fiber":6,"salt_100g":"1.1176","carbohydrates":44,"fiber_100g":6,"energy_100g":1067,"saturated-fat":0.5},"countries_tags":["en:france"],"ingredients_from_palm_oil_tags":[],"brands_tags":["jacquet"],"emb_codes_tags":[],"purchase_places":"","traces":"lait,oeufs,sésame,soja","countries_hierarchy":["en:france"],"categories":"Pain de mie complet,Pain,Pain de mie","ingredients_text":"Pain de mie complet : Farine complète de blé (61%), eau, levure, sucre, huile de colza, sel, arôme, dextrose, levain de blé déshydraté et dévitalisé, gluten de blé, Correcteur d'acidité: E575, Conservateur: E282, farine de blé, émulsifiant: E471, fibres végétales (avoine et/ou pois et/ou maïs), Agent de traitement de la farine: E300.","product_name":"Crousti Moelleux Complet","created_t":1338046925,"ingredients_from_or_that_may_be_from_palm_oil_n":1,"creator":"andre","no_nutrition_data":null,"serving_size":"2 tranches 121.5g","last_modified_by":"stephane","completed_t":1350567513,"origins":"France","stores":"","nutrient_levels":{"salt":"moderate","fat":"low","sugars":"moderate","saturated-fat":"low"},"stores_tags":[],"id":"3029330003533","countries":"France","purchase_places_tags":[],"interface_version_modified":"20120622","sortkey":1350576360,"last_modified_t":1350576360,"countries.20131227":null,"correctors_tags":["manu1400"],"correctors":["manu1400"],"brands":"Jacquet","ingredients_tags":["pain-de-mie-complet","eau","levure","sucre","huile-de-colza","sel","arome","dextrose","levain-de-ble-deshydrate-et-devitalise","gluten-de-ble","correcteur-d-acidite","e575","conservateur","e282","farine-de-ble","emulsifiant","e471","fibres-vegetales","avoine-et-ou-pois-et-ou-mais","agent-de-traitement-de-la-farine","e300","farine-complete-de-ble"],"status":"A vérifier, Complet, Informations nutritionnelles complétées, Ingrédients complétés, Date limite à compléter, Caractéristiques complétées, Photos validées, Photos envoyées","informers":["manu1400","stephane"],"packaging":"sac plastique","serving_quantity":"121.5","origins_tags":["france"],"nutrition_data_per":"100g","labels":"","cities_tags":[],"categories_tags":["fr:pains-de-mie","fr:pains-de-mie-complet","en:breads"],"quantity":"12 Tranches","expiration_date":"","status_tags":["a-verifier","complet","informations-nutritionnelles-completees","ingredients-completes","date-limite-a-completer","caracteristiques-completees","photos-validees","photos-envoyees"],"ingredients_that_may_be_from_palm_oil_n":1,"emb_code":"","ingredients_from_palm_oil_n":0,"image_url":"http://fr.openfoodfacts.org/images/products/302/933/000/3533/front.9.400.jpg","ingredients":[{"text":"Pain de mie complet","id":"pain-de-mie-complet","rank":1},{"text":"eau","id":"eau","rank":2},{"text":"levure","id":"levure","rank":3},{"text":"sucre","id":"sucre","rank":4},{"text":"huile de colza","id":"huile-de-colza","rank":5},{"text":"sel","id":"sel","rank":6},{"text":"arôme","id":"arome","rank":7},{"text":"dextrose","id":"dextrose","rank":8},{"text":"levain de blé déshydraté et dévitalisé","id":"levain-de-ble-deshydrate-et-devitalise","rank":9},{"text":"gluten de blé","id":"gluten-de-ble","rank":10},{"text":"Correcteur d'acidité","id":"correcteur-d-acidite","rank":11},{"text":"E575","id":"e575","rank":12},{"text":"Conservateur","id":"conservateur","rank":13},{"text":"E282","id":"e282","rank":14},{"text":"farine de blé","id":"farine-de-ble","rank":15},{"text":"émulsifiant","id":"emulsifiant","rank":16},{"text":"E471","id":"e471","rank":17},{"text":"fibres végétales","id":"fibres-vegetales","rank":18},{"text":"avoine et/ou pois et/ou maïs","id":"avoine-et-ou-pois-et-ou-mais","rank":19},{"text":"Agent de traitement de la farine","id":"agent-de-traitement-de-la-farine","rank":20},{"text":"E300.","id":"e300","rank":21},{"text":"Farine complète de blé","percent":"61","id":"farine-complete-de-ble"},{"text":"Pain de mie complet","id":"pain-de-mie-complet","rank":1},{"text":"eau","id":"eau","rank":2},{"text":"levure","id":"levure","rank":3},{"text":"sucre","id":"sucre","rank":4},{"text":"huile de colza","id":"huile-de-colza","rank":5},{"text":"sel","id":"sel","rank":6},{"text":"arôme","id":"arome","rank":7},{"text":"dextrose","id":"dextrose","rank":8},{"text":"levain de blé déshydraté et dévitalisé","id":"levain-de-ble-deshydrate-et-devitalise","rank":9},{"text":"gluten de blé","id":"gluten-de-ble","rank":10},{"text":"Correcteur d'acidité","id":"correcteur-d-acidite","rank":11},{"text":"E575","id":"e575","rank":12},{"text":"Conservateur","id":"conservateur","rank":13},{"text":"E282","id":"e282","rank":14},{"text":"farine de blé","id":"farine-de-ble","rank":15},{"text":"émulsifiant","id":"emulsifiant","rank":16},{"text":"E471","id":"e471","rank":17},{"text":"fibres végétales","id":"fibres-vegetales","rank":18},{"text":"avoine et/ou pois et/ou maïs","id":"avoine-et-ou-pois-et-ou-mais","rank":19},{"text":"Agent de traitement de la farine","id":"agent-de-traitement-de-la-farine","rank":20},{"text":"E300.","id":"e300","rank":21},{"percent":"61","text":"Farine complète de blé","id":"farine-complete-de-ble"},{"text":"Pain de mie complet","id":"pain-de-mie-complet","rank":1},{"text":"eau","id":"eau","rank":2},{"text":"levure","id":"levure","rank":3},{"text":"sucre","id":"sucre","rank":4},{"text":"huile de colza","id":"huile-de-colza","rank":5},{"text":"sel","id":"sel","rank":6},{"text":"arôme","id":"arome","rank":7},{"text":"dextrose","id":"dextrose","rank":8},{"text":"levain de blé déshydraté et dévitalisé","id":"levain-de-ble-deshydrate-et-devitalise","rank":9},{"text":"gluten de blé","id":"gluten-de-ble","rank":10},{"text":"Correcteur d'acidité","id":"correcteur-d-acidite","rank":11},{"text":"E575","id":"e575","rank":12},{"text":"Conservateur","id":"conservateur","rank":13},{"text":"E282","id":"e282","rank":14},{"text":"farine de blé","id":"farine-de-ble","rank":15},{"text":"émulsifiant","id":"emulsifiant","rank":16},{"text":"E471","id":"e471","rank":17},{"text":"fibres végétales","id":"fibres-vegetales","rank":18},{"text":"avoine et/ou pois et/ou maïs","id":"avoine-et-ou-pois-et-ou-mais","rank":19},{"text":"Agent de traitement de la farine","id":"agent-de-traitement-de-la-farine","rank":20},{"text":"E300.","id":"e300","rank":21},{"text":"Farine complète de blé","percent":"61","id":"farine-complete-de-ble"},{"text":"Pain de mie complet","id":"pain-de-mie-complet","rank":1},{"text":"eau","id":"eau","rank":2},{"text":"levure","id":"levure","rank":3},{"text":"sucre","id":"sucre","rank":4},{"text":"huile de colza","id":"huile-de-colza","rank":5},{"text":"sel","id":"sel","rank":6},{"text":"arôme","id":"arome","rank":7},{"text":"dextrose","id":"dextrose","rank":8},{"text":"levain de blé déshydraté et dévitalisé","id":"levain-de-ble-deshydrate-et-devitalise","rank":9},{"text":"gluten de blé","id":"gluten-de-ble","rank":10},{"text":"Correcteur d'acidité","id":"correcteur-d-acidite","rank":11},{"text":"E575","id":"e575","rank":12},{"text":"Conservateur","id":"conservateur","rank":13},{"text":"E282","id":"e282","rank":14},{"text":"farine de blé","id":"farine-de-ble","rank":15},{"text":"émulsifiant","id":"emulsifiant","rank":16},{"text":"E471","id":"e471","rank":17},{"text":"fibres végétales","id":"fibres-vegetales","rank":18},{"text":"avoine et/ou pois et/ou maïs","id":"avoine-et-ou-pois-et-ou-mais","rank":19},{"text":"Agent de traitement de la farine","id":"agent-de-traitement-de-la-farine","rank":20},{"text":"E300.","id":"e300","rank":21},{"percent":"61","text":"Farine complète de blé","id":"farine-complete-de-ble"}],"lc":"fr","checkers":[],"complete":1},"code":"3029330003533"}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Shopli::Barcode do
|
4
|
+
describe '.to_s' do
|
5
|
+
it 'returns the barcode figure' do
|
6
|
+
b = Shopli::Barcode.new 123456
|
7
|
+
expect(b.to_s).to eq '123456'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_events(code)
|
12
|
+
press = DevInput::Event.new 1,0,1,code, 1
|
13
|
+
release = DevInput::Event.new 1,0,1,code, 0
|
14
|
+
scan = DevInput::Event.new 1,0,4,4, 0
|
15
|
+
[scan, press, release]
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:barcode1_events) do
|
19
|
+
[
|
20
|
+
(2..10).map { |i| generate_events(i) },
|
21
|
+
generate_events(28)
|
22
|
+
].flatten
|
23
|
+
end
|
24
|
+
let(:barcode2_events) do
|
25
|
+
[
|
26
|
+
(2..10).map { |i| generate_events(12 - i) },
|
27
|
+
generate_events(28)
|
28
|
+
].flatten
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
describe '.read' do
|
33
|
+
it 'finds barcodes' do
|
34
|
+
events = [barcode1_events, barcode2_events].flatten
|
35
|
+
barcodes = Shopli::Barcode.read(events).to_a
|
36
|
+
expect(barcodes).to have(2).barcodes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Shopli::OpenFoodFacts do
|
4
|
+
describe 'products' do
|
5
|
+
|
6
|
+
it 'can call openfoodfacts.org' do
|
7
|
+
off = Shopli::OpenFoodFacts.new
|
8
|
+
expect{ @product = off.fetch_product('3029330003533') }.not_to raise_error
|
9
|
+
expect{ JSON.parse(@product) }.not_to raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Shopli::OpenFoodFacts do
|
4
|
+
describe '.fetch_product' do
|
5
|
+
|
6
|
+
it 'calls the correct url' do
|
7
|
+
rest_client = double('rest_client')
|
8
|
+
allow(RestClient::Resource).to receive(:new).
|
9
|
+
with('http://fr.openfoodfacts.org/api/v0/produit/3029330003533.json').
|
10
|
+
and_return(rest_client)
|
11
|
+
allow(rest_client).to receive(:get)
|
12
|
+
off = Shopli::OpenFoodFacts.new
|
13
|
+
off.fetch_product('3029330003533')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.product' do
|
18
|
+
it 'return nil when product does not exist' do
|
19
|
+
rest_client = double('rest_client')
|
20
|
+
allow(RestClient::Resource).to receive(:new).and_return(rest_client)
|
21
|
+
allow(rest_client).to receive(:get).and_return('{"status_verbose":"product not found","status":0,"code":"302933678560003533"}')
|
22
|
+
off = Shopli::OpenFoodFacts.new
|
23
|
+
expect(off.product('inexistant_product')).to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'return a product otherwise' do
|
27
|
+
rest_client = double('rest_client')
|
28
|
+
allow(RestClient::Resource).to receive(:new).and_return(rest_client)
|
29
|
+
allow(rest_client).to receive(:get).and_return(File.read(File.join(File.dirname(__FILE__), '3029330003533.json')))
|
30
|
+
off = Shopli::OpenFoodFacts.new
|
31
|
+
product = off.product('3029330003533')
|
32
|
+
expect(product).to be_a(Shopli::Product)
|
33
|
+
expect(product.id).to eq '3029330003533'
|
34
|
+
expect(product.name).to eq 'Pain complet en tranche'
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shopli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gregoire Seux
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: If you get the barcode of all things you put to the trash, shopli will
|
84
|
+
generate your next shop list
|
85
|
+
email:
|
86
|
+
- shopli@familleseux.net
|
87
|
+
executables:
|
88
|
+
- daemon.rb
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- Gemfile.lock
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- bin/daemon.rb
|
100
|
+
- lib/shopli.rb
|
101
|
+
- lib/shopli/barcode.rb
|
102
|
+
- lib/shopli/barcode_reader.rb
|
103
|
+
- lib/shopli/device.rb
|
104
|
+
- lib/shopli/mode.rb
|
105
|
+
- lib/shopli/open_food_facts.rb
|
106
|
+
- lib/shopli/product.rb
|
107
|
+
- lib/shopli/version.rb
|
108
|
+
- shopli.gemspec
|
109
|
+
- spec/3029330003533.json
|
110
|
+
- spec/barcode_spec.rb
|
111
|
+
- spec/integration/open_food_facts_spec.rb
|
112
|
+
- spec/open_food_facts_spec.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
homepage: ''
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.2.2
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: Generate a shop list from a list of barcodes scanned before trash
|
138
|
+
test_files:
|
139
|
+
- spec/3029330003533.json
|
140
|
+
- spec/barcode_spec.rb
|
141
|
+
- spec/integration/open_food_facts_spec.rb
|
142
|
+
- spec/open_food_facts_spec.rb
|
143
|
+
- spec/spec_helper.rb
|