postcl 0.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3a40d7ff0b0cb441c93466222593734432e962afb5dcdd1a13c79d884c3dd1f2
4
+ data.tar.gz: 964e845c9a3ca0e77f5ec591669c5a0a28201e5ae47fe252bdbc7c7af3800a31
5
+ SHA512:
6
+ metadata.gz: ce86de5496aeb0646a682a2f71b06847f9a0ba1538d16df9a3794bfb6e2a8f342e26e7d2a3dbd93960b096e44c43bd47492824a2b796d3ab2331d32bbcc98d79
7
+ data.tar.gz: a40ac71206fb4ee549b43f1b118fd73d57806d0f0eb9a7bd359a935e4e0e5d2604b460d27347c9a14f13c0f906c560f2b0c9c7c2c4a2b547343ff362d94588f5
data/.gitignore ADDED
@@ -0,0 +1,79 @@
1
+ # Environments
2
+ .env
3
+ .venv
4
+ env/
5
+ venv/
6
+ ENV/
7
+ env.bak/
8
+ venv.bak/
9
+
10
+ # Spyder project settings
11
+ .spyderproject
12
+ .spyproject
13
+
14
+ # Rope project settings
15
+ .ropeproject
16
+
17
+ # mkdocs documentation
18
+ /site
19
+
20
+ # mypy
21
+ .mypy_cache/
22
+
23
+ *.gem
24
+ *.rbc
25
+ /.config
26
+ /coverage/
27
+ /InstalledFiles
28
+ /pkg/
29
+ /spec/reports/
30
+ /spec/examples.txt
31
+ /test/tmp/
32
+ /test/version_tmp/
33
+ /tmp/
34
+
35
+ # Used by dotenv library to load environment variables.
36
+ # .env
37
+
38
+ # Ignore Byebug command history file.
39
+ .byebug_history
40
+
41
+ ## Specific to RubyMotion:
42
+ .dat*
43
+ .repl_history
44
+ build/
45
+ *.bridgesupport
46
+ build-iPhoneOS/
47
+ build-iPhoneSimulator/
48
+
49
+ ## Specific to RubyMotion (use of CocoaPods):
50
+ #
51
+ # We recommend against adding the Pods directory to your .gitignore. However
52
+ # you should judge for yourself, the pros and cons are mentioned at:
53
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
54
+ #
55
+ # vendor/Pods/
56
+
57
+ ## Documentation cache and generated files:
58
+ /.yardoc/
59
+ /_yardoc/
60
+ /doc/
61
+ /rdoc/
62
+
63
+ ## Environment normalization:
64
+ /.bundle/
65
+ /vendor/bundle
66
+ /lib/bundler/man/
67
+
68
+ # for a library or gem, you might want to ignore these files since the code is
69
+ # intended to run in multiple environments; otherwise, check them in:
70
+ # Gemfile.lock
71
+ # .ruby-version
72
+ # .ruby-gemset
73
+
74
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
75
+ .rvmrc
76
+
77
+
78
+ # VSCode
79
+ .vscode/
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [0.1.1] - 2019-08-18
6
+
7
+ ### Added
8
+
9
+ -Status command
10
+ -Package list prompt
11
+ -Auto-saving of queried packages
12
+
13
+ ## [0.1.0] - 2019-08-18
14
+
15
+ test release
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ gem 'httparty'
3
+ gem 'colorize'
4
+ gem 'terminal-table'
5
+ gem 'docopt'
6
+ gem 'tty-prompt'
7
+ gem 'tty-spinner'
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ colorize (0.8.1)
5
+ docopt (0.6.1)
6
+ equatable (0.6.1)
7
+ httparty (0.17.0)
8
+ mime-types (~> 3.0)
9
+ multi_xml (>= 0.5.2)
10
+ mime-types (3.2.2)
11
+ mime-types-data (~> 3.2015)
12
+ mime-types-data (3.2019.0331)
13
+ multi_xml (0.6.0)
14
+ necromancer (0.5.0)
15
+ pastel (0.7.3)
16
+ equatable (~> 0.6)
17
+ tty-color (~> 0.5)
18
+ terminal-table (1.8.0)
19
+ unicode-display_width (~> 1.1, >= 1.1.1)
20
+ tty-color (0.5.0)
21
+ tty-cursor (0.7.0)
22
+ tty-prompt (0.19.0)
23
+ necromancer (~> 0.5.0)
24
+ pastel (~> 0.7.0)
25
+ tty-reader (~> 0.6.0)
26
+ tty-reader (0.6.0)
27
+ tty-cursor (~> 0.7)
28
+ tty-screen (~> 0.7)
29
+ wisper (~> 2.0.0)
30
+ tty-screen (0.7.0)
31
+ tty-spinner (0.9.1)
32
+ tty-cursor (~> 0.7)
33
+ unicode-display_width (1.6.0)
34
+ wisper (2.0.0)
35
+
36
+ PLATFORMS
37
+ ruby
38
+ x64-mingw32
39
+
40
+ DEPENDENCIES
41
+ colorize
42
+ docopt
43
+ httparty
44
+ terminal-table
45
+ tty-prompt
46
+ tty-spinner
47
+
48
+ BUNDLED WITH
49
+ 2.0.2
data/README.md ADDED
Binary file
data/ascii-sym.txt ADDED
@@ -0,0 +1,26 @@
1
+ _________H
2
+ /\ \
3
+ / \ \
4
+ | | _ |
5
+ | |[] | | []|
6
+ `-_| |`| |
7
+
8
+ _________
9
+ | |_\
10
+ |PostNL \___
11
+ | |
12
+ --( )-----( )-
13
+
14
+ __________
15
+ | ~~ |
16
+ --| |--
17
+ |__________|
18
+ ================
19
+ ( ) ( ) ( )
20
+
21
+ __________
22
+ |\ \ \
23
+ | \____\____\
24
+ | | ~~ |
25
+ \ | |
26
+ \|_________|
data/bin/postcl ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'docopt'
4
+ require 'postcl'
5
+
6
+ doc = <<DOCOPT
7
+ PostCL
8
+
9
+ Usage:
10
+ postcl (info|status) (<barcode> <postcode>)... | -p <barcode>...
11
+ postcl (info|status) -l [-a]
12
+ postcl (info|status) -e
13
+ postcl volg (<barcode> <postcode>)... | -p <barcode>...
14
+ postcl -h | --help
15
+ postcl -v
16
+
17
+ Options:
18
+ -a --alles
19
+ -l --lijst
20
+ -e --eerstvolgende
21
+ -h --help
22
+ -v
23
+
24
+ DOCOPT
25
+
26
+
27
+ begin
28
+ doc_parse = Docopt::docopt(doc)
29
+ rescue Docopt::Exit => e
30
+ puts e.message
31
+ exit 1
32
+ end
33
+
34
+ # Otherwise gets won't work
35
+ ARGV.clear
36
+
37
+ PostCL::Session.new(doc_parse)
38
+
data/lib/postcl/api.rb ADDED
@@ -0,0 +1,69 @@
1
+ class PostCL::API
2
+ class InvalidRequestError < Exception
3
+ end
4
+
5
+ def self.API_URI
6
+ "https://jouw.postnl.nl/web/api/default/shipmentStatus/"
7
+ end
8
+
9
+ def self.request(b_code, p_code)
10
+ r = HTTParty.get(self.API_URI + b_code + "-NL-" + p_code, format: :plain)
11
+ raise InvalidRequestError if r.code != 200
12
+ stat_dict = JSON.parse r.body, symbolize_names: true
13
+ PostCL::API::Response.new(stat_dict)
14
+ end
15
+ end
16
+
17
+ class PostCL::API::Response
18
+ def initialize(stat_dict)
19
+ @stat_dict = stat_dict
20
+ @info = stat_dict[:shipments][stat_dict[:barcode].to_sym]
21
+ end
22
+
23
+ private
24
+
25
+ def format_location(entity)
26
+ "#{entity[:street]} #{entity[:houseNumber]}, #{entity[:postalCode]} #{entity[:town]}"
27
+ end
28
+
29
+ def format_name(entity)
30
+ name = "#{entity[]}"
31
+ end
32
+
33
+ public
34
+
35
+ def stat_dict
36
+ @stat_dict
37
+ end
38
+
39
+ def info
40
+ @info
41
+ end
42
+
43
+ def location(mode)
44
+ nil unless mode == :sender || mode == :receiver
45
+ format_location(@info[mode])
46
+ end
47
+
48
+ def name(mode)
49
+ nil unless mode == :sender || mode == :receiver
50
+ format_name(@info[mode])
51
+ end
52
+
53
+ def stat_index
54
+ @info[:delivery][:phase][:index]
55
+ end
56
+
57
+ def stat_msg
58
+ @info[:delivery][:phase][:message]
59
+ end
60
+
61
+ def delivered?
62
+ @info[:delivery][:isDelivered]
63
+ end
64
+
65
+ def delivery_date
66
+ t = Time.parse(@info[:delivery][:deliveryDate])
67
+ t.strftime("%A %d %B, om %k:%M")
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ class Status < PostCL::Command
2
+ @@ART = {
3
+ 1 => [" __________", " |\\ \\ \\", " | \\____\\____\\", " | | ~~ |", " \\ | |", " \\|_________|"],
4
+ 2 => [" __________", " | ~~ |", "--| |--", " |__________|", "================", " ( ) ( ) ( )"],
5
+ 3 => [" _________", " | |_\\", " |PostNL \\___", " | |", " --( )-----( )-", ""],
6
+ 4 => [" _________H", " /\\ \\", " / \\ \\", " | | _ |", " | |[] | | []|", " `-_| |`| |"],
7
+ }
8
+
9
+ def initialize(post)
10
+ super(post)
11
+ end
12
+
13
+ private
14
+
15
+ def stat_info(row, resp)
16
+ case row
17
+ when 1
18
+ return resp.stat_msg.bold
19
+ when 2
20
+ if resp.delivered?
21
+ return "Bezorgd op: #{resp.delivery_date}"
22
+ else
23
+ return "Bezorging verwacht op: "
24
+ end
25
+ when 3
26
+ return "Bestemming: #{resp.location(:receiver)}"
27
+ else
28
+ return ""
29
+ end
30
+ end
31
+
32
+ public
33
+
34
+ def run
35
+ @args["<barcode>"].zip(@args["<postcode>"]).each do |barcode, postcode|
36
+ spin = TTY::Spinner.new("Zending #{barcode} wordt geladen :spinner...", format: :bouncing_ball, clear: true)
37
+ spin.auto_spin
38
+ begin
39
+ resp = PostCL::API.request(barcode, postcode)
40
+ spin.stop()
41
+ rescue PostCL::API::InvalidRequestError
42
+ spin.stop("Ongeldige aanvraag met barcode: #{barcode} en postcode: #{postcode}")
43
+ next
44
+ end
45
+
46
+ @store.prompt_add(resp) unless @store.include?(barcode, postcode) || @args["-n"]
47
+
48
+ puts "Status van zending: " + barcode.bold
49
+ stat_banner = Array(6)
50
+ art = @@ART[resp.stat_index]
51
+ (0..5).each do |i|
52
+ stat_banner[i] = art[i].ljust(20, " ") + stat_info(i, resp)
53
+ end
54
+ puts stat_banner.join("\n")
55
+ # puts "Van " + resp.location(:sender).red +
56
+ # " naar " + resp.location(:receiver).green
57
+ puts
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,15 @@
1
+ class Volg < PostCL::Command
2
+ def initialize(post)
3
+ super(post)
4
+ end
5
+
6
+ private
7
+
8
+
9
+
10
+ public
11
+
12
+ def run
13
+
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+
2
+
3
+ class PostCL::Command
4
+ ARG_MATCH = {
5
+ barcode: /(3S|KG)[A-Z0-9]{13}/,
6
+ postcode: /[0-9]{4}[a-zA-Z]{2}/
7
+ }
8
+
9
+ class UnknownCommandError < Exception
10
+ end
11
+
12
+ def initialize(session)
13
+ @args = session.args
14
+ @prompt = session.prompt
15
+ @store = session.store
16
+ end
17
+
18
+ def self.validate_args(args)
19
+ args.each_key do |key|
20
+ key_sym = key[1...-1].to_sym
21
+ if ARG_MATCH.keys.include?(key_sym)
22
+ args[key].each do |arg|
23
+ next if arg.match(ARG_MATCH[key_sym])
24
+ puts "Ongeldige #{key_sym}: #{arg}"
25
+ exit 1
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.run(session)
32
+ if session.args["status"]
33
+ Status.new(session).run
34
+ # elsif post.args["info"]
35
+ # Info.new(post).run
36
+ elsif post.args["volg"]
37
+ Volg.new(session).run
38
+ else
39
+ raise UnknownCommandError
40
+ end
41
+ end
42
+ end
43
+
44
+ # Require all Command classes
45
+ Dir["#{File.expand_path("lib/postcl/command/")}/*.rb"].each { |f| require f }
@@ -0,0 +1,90 @@
1
+ class PostCL::Store
2
+ def initialize(session, name = "store.yaml", dir = "#{File.expand_path('~')}/.config/postcl/")
3
+ @session = session
4
+ @args = session.args
5
+ @prompt = session.prompt
6
+ @dir = dir
7
+ @path = dir + name
8
+ load
9
+
10
+ end
11
+
12
+ private
13
+
14
+ def load
15
+ begin
16
+ @data = YAML.load(File.open(@path))
17
+ rescue Errno::ENOENT
18
+ FileUtils.mkdir_p(@dir)
19
+ @data = { postcode: nil, packages: [] }
20
+ save
21
+ end
22
+ end
23
+
24
+ def save
25
+ File.open(@path, "w") { |f| f.write(@data.to_yaml) }
26
+ end
27
+
28
+ public
29
+
30
+ def add(resp)
31
+ p_elem = {
32
+ barcode: resp.info[:barcode],
33
+ postcode: resp.info[:postalCode],
34
+ undelivered: resp.info[:delivery][:isDelivered]
35
+ }
36
+ @data[:packages] << p_elem
37
+ save
38
+ end
39
+
40
+ def postcode
41
+ @data[:postcode]
42
+ end
43
+
44
+ def postcode=(postcode)
45
+ @data[:postcode] = postcode
46
+ save
47
+ end
48
+
49
+ def packages
50
+ @data[:packages]
51
+ end
52
+
53
+ def filter(f_proc)
54
+ @data[:packages].select(&f_proc)
55
+ end
56
+
57
+ def undelivered
58
+ filter(proc { |p| p[:undelivered] })
59
+ end
60
+
61
+ def package(barcode, postcode)
62
+ filter(proc { |p| p[:barcode].upcase == barcode.upcase && p[:postcode].upcase == postcode.upcase })[0]
63
+ end
64
+
65
+ def include?(barcode, postcode)
66
+ package(barcode, postcode) != nil
67
+ end
68
+
69
+ def prompt_add(resp)
70
+ if TTY::Prompt.new.yes?("Het lijkt er op dat deze zending nog niet is opgeslagen, wilt u hem toevoegen?")
71
+ add(resp)
72
+ end
73
+ end
74
+
75
+ def promt_list
76
+ p_list = @args["--alles"] ? packages : undelivered
77
+
78
+ @session.error_exit("Geen zendingen in huidige selectie.") unless p_list.size > 0
79
+
80
+ choices = []
81
+ p_list.each_with_index do |p, i|
82
+ choices << {name: "#{p[:barcode]}, #{p[:postcode]}", value: i}
83
+ end
84
+ input = @prompt.multi_select("Selecteer een of meerdere zendingen:", choices)
85
+ input.each do |i|
86
+ @args["<barcode>"] << p_list[i][:barcode]
87
+ @args["<postcode>"] << p_list[i][:postcode]
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module PostCL
2
+ VERSION = "0.1.1"
3
+ end
data/lib/postcl.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'colorize'
2
+ require 'fileutils'
3
+ require 'httparty'
4
+ require 'time'
5
+ require 'tty-prompt'
6
+ require 'tty-spinner'
7
+ require 'yaml'
8
+
9
+ module PostCL
10
+ class Session
11
+ attr_reader :args, :store, :prompt
12
+
13
+ def initialize(doc_parse)
14
+ @args = doc_parse
15
+ @prompt = TTY::Prompt.new
16
+ @store = Store.new(self)
17
+
18
+ @store.promt_list if @args["--lijst"]
19
+
20
+ Command.validate_args(@args)
21
+
22
+ begin
23
+ Command.run(self)
24
+ rescue Command::UnknownCommandError
25
+ puts "ongelding commando"
26
+ end
27
+ end
28
+
29
+ def error_exit(msg)
30
+ puts msg
31
+ exit 1
32
+ end
33
+ end
34
+
35
+ require_relative 'postcl/api'
36
+ require_relative 'postcl/command'
37
+ require_relative 'postcl/store'
38
+ require_relative 'postcl/version'
39
+ end
data/postcl.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "postcl/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "postcl"
7
+ spec.version = PostCL::VERSION
8
+ spec.authors = ["flevosap", "maximvdberg"]
9
+ spec.email = ["info@bami.party"]
10
+
11
+ spec.summary = %q{PostCL is een simpel terminal-script waarmee informatie een PostNL-zending opgevraagd kan worden.}
12
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
13
+ spec.homepage = "https://postcl.bami.party"
14
+
15
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/SirYuSuk/postcl"
19
+ spec.metadata["changelog_uri"] = "https://github.com/SirYuSuk/postcl/blob/master/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|dev)/}) }
25
+ end
26
+
27
+ spec.executables << "postcl"
28
+ spec.require_paths = ["lib"]
29
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postcl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - flevosap
8
+ - maximvdberg
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-08-18 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email:
16
+ - info@bami.party
17
+ executables:
18
+ - postcl
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - ".gitignore"
23
+ - CHANGELOG.md
24
+ - Gemfile
25
+ - Gemfile.lock
26
+ - README.md
27
+ - ascii-sym.txt
28
+ - bin/postcl
29
+ - lib/postcl.rb
30
+ - lib/postcl/api.rb
31
+ - lib/postcl/command.rb
32
+ - lib/postcl/command/status.rb
33
+ - lib/postcl/command/volg.rb
34
+ - lib/postcl/store.rb
35
+ - lib/postcl/version.rb
36
+ - postcl.gemspec
37
+ homepage: https://postcl.bami.party
38
+ licenses: []
39
+ metadata:
40
+ homepage_uri: https://postcl.bami.party
41
+ source_code_uri: https://github.com/SirYuSuk/postcl
42
+ changelog_uri: https://github.com/SirYuSuk/postcl/blob/master/CHANGELOG.md
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.0.4
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: PostCL is een simpel terminal-script waarmee informatie een PostNL-zending
62
+ opgevraagd kan worden.
63
+ test_files: []