dubai 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dubai (0.0.1)
5
+ commander (~> 4.1.2)
6
+ json (~> 1.7.3)
7
+ rubyzip
8
+ sinatra
9
+ terminal-table (~> 1.4.5)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ commander (4.1.3)
15
+ highline (~> 1.6.11)
16
+ diff-lcs (1.1.3)
17
+ highline (1.6.15)
18
+ json (1.7.7)
19
+ multi_json (1.6.1)
20
+ rack (1.5.2)
21
+ rack-protection (1.3.2)
22
+ rack
23
+ rake (10.0.3)
24
+ rspec (2.12.0)
25
+ rspec-core (~> 2.12.0)
26
+ rspec-expectations (~> 2.12.0)
27
+ rspec-mocks (~> 2.12.0)
28
+ rspec-core (2.12.2)
29
+ rspec-expectations (2.12.1)
30
+ diff-lcs (~> 1.1.3)
31
+ rspec-mocks (2.12.2)
32
+ rubyzip (0.9.9)
33
+ simplecov (0.7.1)
34
+ multi_json (~> 1.0)
35
+ simplecov-html (~> 0.7.1)
36
+ simplecov-html (0.7.1)
37
+ sinatra (1.3.4)
38
+ rack (~> 1.4)
39
+ rack-protection (~> 1.3)
40
+ tilt (~> 1.3, >= 1.3.3)
41
+ terminal-table (1.4.5)
42
+ tilt (1.3.3)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ dubai!
49
+ rake
50
+ rspec
51
+ simplecov
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 Mattt Thompson (http://mattt.me/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Dubai
2
+ **Generate and Preview Passbook Passes**
3
+
4
+ ## Installation
5
+
6
+ $ gem install dubai
7
+
8
+
9
+ ## Comand Line Interface
10
+
11
+ Dubai also comes with the `pk` binary, which provides a convenient way to generate and preview passes
12
+
13
+
14
+ $ pk generate mypass
15
+ $ pk serve mypass
16
+ $ open http://localhost:4000
17
+
18
+ ## Contact
19
+
20
+ Mattt Thompson
21
+
22
+ - http://github.com/mattt
23
+ - http://twitter.com/mattt
24
+ - m@mattt.me
25
+
26
+ ## License
27
+
28
+ Dubai is available under the MIT license. See the LICENSE file for more info.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ gemspec = eval(File.read("dubai.gemspec"))
5
+
6
+ task :build => "#{gemspec.full_name}.gem"
7
+
8
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["dubai.gemspec"] do
9
+ system "gem build dubai.gemspec"
10
+ system "gem install dubai-#{Dubai::VERSION}.gem"
11
+ end
data/bin/pk ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'commander/import'
4
+ require 'terminal-table'
5
+
6
+ $:.push File.expand_path("../../lib", __FILE__)
7
+ require 'dubai'
8
+
9
+ HighLine.track_eof = false # Fix for built-in Ruby
10
+ Signal.trap("INT") {} # Suppress backtrace when exiting command
11
+
12
+ program :version, Dubai::VERSION
13
+ program :description, 'A command-line interface for generating and previewing passbook passes'
14
+
15
+ program :help, 'Author', 'Mattt Thompson <m@mattt.me>'
16
+ program :help, 'Website', 'https://github.com/mattt'
17
+ program :help_formatter, :compact
18
+
19
+ default_command :help
20
+
21
+ require 'dubai/commands'
data/dubai.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dubai"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dubai"
7
+ s.authors = ["Mattt Thompson"]
8
+ s.email = "m@mattt.me"
9
+ s.homepage = "http://github.com/mattt/dubai"
10
+ s.version = Dubai::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.summary = "Passbook pass generation and preview"
13
+ s.description = ""
14
+
15
+ s.add_dependency "json", "~> 1.7.3"
16
+ s.add_dependency "commander", "~> 4.1.2"
17
+ s.add_dependency "terminal-table", "~> 1.4.5"
18
+ s.add_dependency "sinatra"
19
+ s.add_dependency "rubyzip"
20
+
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rake"
23
+ s.add_development_dependency "simplecov"
24
+
25
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ["lib"]
29
+ end
data/lib/dubai.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Dubai
2
+ VERSION = "0.0.1"
3
+ end
4
+
5
+ require 'dubai/pass'
6
+ require 'dubai/server'
@@ -0,0 +1,5 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+
3
+ require 'commands/build'
4
+ require 'commands/generate'
5
+ require 'commands/serve'
@@ -0,0 +1,39 @@
1
+ command :build do |c|
2
+ c.syntax = 'pk build [PASSNAME]'
3
+ c.summary = 'Creates a .pkpass archive'
4
+ c.description = ''
5
+
6
+ c.example 'description', 'pk archive mypass -o mypass.pkpass'
7
+ c.option '-c', '--certificate /path/to/cert.pem', 'Pass certificate'
8
+ c.option '-p', '--[no]-password', 'Prompt for certificate password'
9
+ c.option '-o', '--output /path/to/out.pkpass', '.pkpass output filepath'
10
+
11
+ c.action do |args, options|
12
+ determine_directory! unless @directory = args.first
13
+ validate_directory!
14
+
15
+ @filepath = options.output || "#{@directory}.pkpass"
16
+ validate_output_filepath!
17
+
18
+ @certificate = options.certificate
19
+ validate_certificate!
20
+
21
+ @password = ask("Enter certificate password:"){|q| q.echo = false} if options.password
22
+
23
+ Dubai::Passbook.certificate, Dubai::Passbook.password = @certificate, @password
24
+
25
+ File.open(@filepath, 'w') do |f|
26
+ f.write Dubai::Passbook::Pass.new(@directory).pkpass.string
27
+ end
28
+ end
29
+ end
30
+
31
+ # alias_command :build, :archive
32
+ # alias_command :build, :b
33
+
34
+ private
35
+
36
+ def validate_output_filepath!
37
+ say_error "Filepath required" and abort if @filepath.nil? or @filepath.empty?
38
+ say_error "#{@filepath} already exists" and abort if File.exist?(@filepath)
39
+ end
@@ -0,0 +1,44 @@
1
+ require 'fileutils'
2
+
3
+ command :generate do |c|
4
+ c.syntax = 'pk generate PASSNAME'
5
+ c.summary = 'Generates a template pass directory'
6
+ c.description = ''
7
+
8
+ c.example 'description', 'pk generate mypass'
9
+ c.option '-T', '--type [boardingPass|coupon|eventTicket|storeCard|generic]', 'Type of pass'
10
+
11
+ c.action do |args, options|
12
+ @directory = args.first
13
+ @directory ||= ask "Enter a passbook name: "
14
+
15
+ say_error "Missing pass name" and abort if @directory.nil? or @directory.empty?
16
+ say_error "Directory #{@directory} already exists" and abort if File.directory?(@directory)
17
+ say_error "File exists at #{@directory}" and abort if File.exist?(@directory)
18
+
19
+ @type = options.type
20
+ determine_type! unless @type
21
+ validate_type!
22
+
23
+ FileUtils.mkdir_p @directory
24
+ FileUtils.cp File.join(File.dirname(__FILE__), '..', 'templates', "#{@type}.json"), File.join(@directory, 'pass.json')
25
+ ['icon.png', 'icon@2x.png'].each do |file|
26
+ FileUtils.touch File.join(@directory, file)
27
+ end
28
+
29
+ say_ok "Pass generated in #{@directory}"
30
+ end
31
+ end
32
+
33
+ # alias_command :generate, :new
34
+ # alias_command :generate, :g
35
+
36
+ private
37
+
38
+ def determine_type!
39
+ @type ||= choose "Select a pass type", *Dubai::Passbook::Pass::TYPES
40
+ end
41
+
42
+ def validate_type!
43
+ say_error %{Invalid type: "#{@type}", expected one of: [#{Dubai::Passbook::Pass::TYPES.join(', ')}]} unless Dubai::Passbook::Pass::TYPES.include?(@type)
44
+ end
@@ -0,0 +1,49 @@
1
+ command :serve do |c|
2
+ c.syntax = 'pk serve [PASSNAME]'
3
+ c.summary = 'Creates a .pkpass archive'
4
+ c.description = ''
5
+
6
+ c.example 'description', 'pk archive mypass'
7
+ c.option '-c', '--certificate /path/to/cert.pem', 'Pass certificate'
8
+ c.option '-p', '--[no]-password', 'Prompt for certificate password'
9
+
10
+ c.action do |args, options|
11
+ determine_directory! unless @directory = args.first
12
+ validate_directory!
13
+
14
+ @certificate = options.certificate
15
+ validate_certificate!
16
+
17
+ @password = ask("Enter certificate password:"){|q| q.echo = false} if options.password
18
+
19
+ Dubai::Passbook.certificate, Dubai::Passbook.password = @certificate, @password
20
+
21
+ Dubai::Server.set :directory, @directory
22
+ Dubai::Server.run!
23
+ end
24
+ end
25
+
26
+ # alias_command :serve, :preview
27
+ # alias_command :serve, :s
28
+
29
+ private
30
+
31
+ def determine_directory!
32
+ files = Dir['*/pass.json']
33
+ @directory ||= case files.length
34
+ when 0 then nil
35
+ when 1 then File.dirname(files.first)
36
+ else
37
+ @directory = choose "Select a directory:", *files.collect{|f| File.dirname(f)}
38
+ end
39
+ end
40
+
41
+ def validate_directory!
42
+ say_error "Missing argument" and abort if @directory.nil?
43
+ say_error "Directory #{@directory} does not exist" and abort unless File.directory?(@directory)
44
+ say_error "Directory #{@directory} is not valid pass" and abort unless File.exist?(File.join(@directory, "pass.json"))
45
+ end
46
+
47
+ def validate_certificate!
48
+ say_error "Missing or invalid certificate file" and abort if @certificate.nil? or not File.exist?(@certificate)
49
+ end
data/lib/dubai/pass.rb ADDED
@@ -0,0 +1,96 @@
1
+ require 'digest/sha1'
2
+ require 'openssl'
3
+ require 'base64'
4
+ require 'json'
5
+ require 'zip/zip'
6
+
7
+ module Dubai
8
+ module Passbook
9
+ WWDR_CERTIFICATE = <<-EOF
10
+ -----BEGIN CERTIFICATE-----
11
+ MIIEIzCCAwugAwIBAgIBGTANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET
12
+ MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv
13
+ biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDgwMjE0MTg1
14
+ NjM1WhcNMTYwMjE0MTg1NjM1WjCBljELMAkGA1UEBhMCVVMxEzARBgNVBAoMCkFw
15
+ cGxlIEluYy4xLDAqBgNVBAsMI0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVs
16
+ YXRpb25zMUQwQgYDVQQDDDtBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0
17
+ aW9ucyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQAD
18
+ ggEPADCCAQoCggEBAMo4VKbLVqrIJDlI6Yzu7F+4fyaRvDRTes58Y4Bhd2RepQcj
19
+ tjn+UC0VVlhwLX7EbsFKhT4v8N6EGqFXya97GP9q+hUSSRUIGayq2yoy7ZZjaFIV
20
+ PYyK7L9rGJXgA6wBfZcFZ84OhZU3au0Jtq5nzVFkn8Zc0bxXbmc1gHY2pIeBbjiP
21
+ 2CsVTnsl2Fq/ToPBjdKT1RpxtWCcnTNOVfkSWAyGuBYNweV3RY1QSLorLeSUheHo
22
+ xJ3GaKWwo/xnfnC6AllLd0KRObn1zeFM78A7SIym5SFd/Wpqu6cWNWDS5q3zRinJ
23
+ 6MOL6XnAamFnFbLw/eVovGJfbs+Z3e8bY/6SZasCAwEAAaOBrjCBqzAOBgNVHQ8B
24
+ Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUiCcXCam2GGCL7Ou6
25
+ 9kdZxVJUo7cwHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wNgYDVR0f
26
+ BC8wLTAroCmgJ4YlaHR0cDovL3d3dy5hcHBsZS5jb20vYXBwbGVjYS9yb290LmNy
27
+ bDAQBgoqhkiG92NkBgIBBAIFADANBgkqhkiG9w0BAQUFAAOCAQEA2jIAlsVUlNM7
28
+ gjdmfS5o1cPGuMsmjEiQzxMkakaOY9Tw0BMG3djEwTcV8jMTOSYtzi5VQOMLA6/6
29
+ EsLnDSG41YDPrCgvzi2zTq+GGQTG6VDdTClHECP8bLsbmGtIieFbnd5G2zWFNe8+
30
+ 0OJYSzj07XVaH1xwHVY5EuXhDRHkiSUGvdW0FY5e0FmXkOlLgeLfGK9EdB4ZoDpH
31
+ zJEdOusjWv6lLZf3e7vWh0ZChetSPSayY6i0scqP9Mzis8hH4L+aWYP62phTKoL1
32
+ fGUuldkzXfXtZcwxN8VaBOhr4eeIA0p1npsoy0pAiGVDdd3LOiUjxZ5X+C7O0qmS
33
+ XnMuLyV1FQ==
34
+ -----END CERTIFICATE-----
35
+ EOF
36
+
37
+ class << self
38
+ attr_accessor :certificate, :password
39
+ end
40
+
41
+ class Pass
42
+ attr_reader :pass, :assets
43
+
44
+ TYPES = ['boarding-pass', 'coupon', 'event-ticket', 'store-card', 'generic']
45
+
46
+ def initialize(directory)
47
+ @assets = Dir[File.join(directory, '*')]
48
+ @pass = File.read(@assets.delete(@assets.detect{|file| File.basename(file) == 'pass.json'}))
49
+ end
50
+
51
+ def manifest
52
+ checksums = {}
53
+ checksums['pass.json'] = Digest::SHA1.hexdigest(@pass)
54
+
55
+ @assets.each do |file|
56
+ checksums[File.basename(file)] = Digest::SHA1.file(file).hexdigest
57
+ end
58
+
59
+ checksums.to_json
60
+ end
61
+
62
+ def pkpass
63
+ Zip::ZipOutputStream.write_buffer do |zip|
64
+ zip.put_next_entry 'pass.json' and zip.write @pass
65
+ zip.put_next_entry 'manifest.json' and zip.write manifest
66
+ zip.put_next_entry 'signature' and zip.write signature(manifest)
67
+
68
+ @assets.each do |file|
69
+ zip.put_next_entry File.basename(file) and zip.print IO.read(file)
70
+ end
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def signature(manifest)
77
+ pk7 = OpenSSL::PKCS7.sign(p12.certificate, p12.key, manifest, [wwdr], OpenSSL::PKCS7::BINARY | OpenSSL::PKCS7::DETACHED)
78
+ data = OpenSSL::PKCS7.write_smime(pk7)
79
+
80
+ start = %{filename=\"smime.p7s"\n\n}
81
+ finish = "\n\n------"
82
+ data = data[(data.index(start) + start.length)...(data.rindex(finish) + finish.length)]
83
+
84
+ Base64.decode64(data)
85
+ end
86
+
87
+ def p12
88
+ OpenSSL::PKCS12.new(File.read(Passbook.certificate), Passbook.password)
89
+ end
90
+
91
+ def wwdr
92
+ OpenSSL::X509::Certificate.new(WWDR_CERTIFICATE)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,12 @@
1
+ require 'sinatra/base'
2
+
3
+ module Dubai
4
+ class Server < Sinatra::Base
5
+ get '/pass.pkpass' do
6
+ content_type 'application/vnd.apple.pkpass'
7
+ attachment "pass.pkpass"
8
+
9
+ Passbook::Pass.new(settings.directory).pkpass.string
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,56 @@
1
+ {
2
+ "formatVersion" : 1,
3
+ "passTypeIdentifier" : "pass.com.example.boarding-pass",
4
+ "description" : "Example Boarding Pass",
5
+ "teamIdentifier": "Example",
6
+ "organizationName": "Example",
7
+ "serialNumber" : "123456",
8
+ "foregroundColor": "#866B23",
9
+ "backgroundColor": "#FFD248",
10
+ "boardingPass" : {
11
+ "primaryFields" : [
12
+ {
13
+ "key" : "origin",
14
+ "label" : "San Francisco",
15
+ "value" : "SFO"
16
+ },
17
+ {
18
+ "key" : "destination",
19
+ "label" : "London",
20
+ "value" : "LHR"
21
+ }
22
+ ],
23
+ "secondaryFields" : [
24
+ {
25
+ "key" : "boarding-gate",
26
+ "label" : "Gate",
27
+ "value" : "F12"
28
+ }
29
+ ],
30
+ "auxiliaryFields" : [
31
+ {
32
+ "key" : "seat",
33
+ "label" : "Seat",
34
+ "value" : "7A"
35
+ },
36
+ {
37
+ "key" : "passenger-name",
38
+ "label" : "Passenger",
39
+ "value" : "John Appleseed"
40
+ }
41
+ ],
42
+ "transitType" : "PKTransitTypeAir",
43
+ "barcode" : {
44
+ "message" : "ABC123",
45
+ "format" : "PKBarcodeFormatQR",
46
+ "messageEncoding" : "iso-8859-1"
47
+ },
48
+ "backFields" : [
49
+ {
50
+ "key" : "terms",
51
+ "label" : "Terms and Conditions",
52
+ "value" : "Lorem ipsum dolar sit amet"
53
+ }
54
+ ]
55
+ }
56
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "formatVersion" : 1,
3
+ "passTypeIdentifier" : "pass.com.example.coupon",
4
+ "description" : "Example Coupon",
5
+ "teamIdentifier": "Example",
6
+ "organizationName": "Example",
7
+ "serialNumber" : "123456",
8
+ "foregroundColor": "#FFFFFF",
9
+ "backgroundColor": "#C799FF",
10
+ "generic" : {
11
+ "primaryFields" : [
12
+
13
+ ],
14
+ "secondaryFields" : [
15
+
16
+ ],
17
+ "auxiliaryFields" : [
18
+
19
+ ],
20
+ "barcode" : {
21
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
22
+ "format" : "PKBarcodeFormatPDF417",
23
+ "messageEncoding" : "iso-8859-1"
24
+ },
25
+ "backFields" : [
26
+ {
27
+ "key" : "terms",
28
+ "label" : "Terms and Conditions",
29
+ "value" : "Lorem ipsum dolar sit amet"
30
+ }
31
+ ]
32
+ }
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "formatVersion" : 1,
3
+ "passTypeIdentifier" : "pass.com.example.event-ticket",
4
+ "description" : "Example Event Ticket",
5
+ "teamIdentifier": "Example",
6
+ "organizationName": "Example",
7
+ "serialNumber" : "123456",
8
+ "foregroundColor": "#FFFFFF",
9
+ "backgroundColor": "#FF5453",
10
+ "generic" : {
11
+ "primaryFields" : [
12
+
13
+ ],
14
+ "secondaryFields" : [
15
+
16
+ ],
17
+ "auxiliaryFields" : [
18
+
19
+ ],
20
+ "barcode" : {
21
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
22
+ "format" : "PKBarcodeFormatPDF417",
23
+ "messageEncoding" : "iso-8859-1"
24
+ },
25
+ "backFields" : [
26
+ {
27
+ "key" : "terms",
28
+ "label" : "Terms and Conditions",
29
+ "value" : "Lorem ipsum dolar sit amet"
30
+ }
31
+ ]
32
+ }
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "formatVersion" : 1,
3
+ "passTypeIdentifier" : "pass.com.example.generic",
4
+ "description" : "Example Generic Pass",
5
+ "teamIdentifier": "Example",
6
+ "organizationName": "Example",
7
+ "serialNumber" : "123456",
8
+ "foregroundColor": "#FFFFFF",
9
+ "backgroundColor": "#444444",
10
+ "generic" : {
11
+ "primaryFields" : [
12
+
13
+ ],
14
+ "secondaryFields" : [
15
+
16
+ ],
17
+ "auxiliaryFields" : [
18
+
19
+ ],
20
+ "barcode" : {
21
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
22
+ "format" : "PKBarcodeFormatPDF417",
23
+ "messageEncoding" : "iso-8859-1"
24
+ },
25
+ "backFields" : [
26
+ {
27
+ "key" : "terms",
28
+ "label" : "Terms and Conditions",
29
+ "value" : "Lorem ipsum dolar sit amet"
30
+ }
31
+ ]
32
+ }
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "formatVersion" : 1,
3
+ "passTypeIdentifier" : "pass.com.example.store-card",
4
+ "description" : "Example Store Card",
5
+ "teamIdentifier": "Example",
6
+ "organizationName": "Example",
7
+ "serialNumber" : "123456",
8
+ "foregroundColor": "#FFFFFF",
9
+ "backgroundColor": "#AFC1E3",
10
+ "generic" : {
11
+ "primaryFields" : [
12
+
13
+ ],
14
+ "secondaryFields" : [
15
+
16
+ ],
17
+ "auxiliaryFields" : [
18
+
19
+ ],
20
+ "barcode" : {
21
+ "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP",
22
+ "format" : "PKBarcodeFormatPDF417",
23
+ "messageEncoding" : "iso-8859-1"
24
+ },
25
+ "backFields" : [
26
+ {
27
+ "key" : "terms",
28
+ "label" : "Terms and Conditions",
29
+ "value" : "Lorem ipsum dolar sit amet"
30
+ }
31
+ ]
32
+ }
33
+ }
@@ -0,0 +1,11 @@
1
+ unless ENV['CI']
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start do
5
+ add_filter 'spec'
6
+ add_filter '.bundle'
7
+ end
8
+ end
9
+
10
+ require 'dubai'
11
+ require 'rspec'
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dubai
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mattt Thompson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &70231892501860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.7.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70231892501860
25
+ - !ruby/object:Gem::Dependency
26
+ name: commander
27
+ requirement: &70231892497740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 4.1.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70231892497740
36
+ - !ruby/object:Gem::Dependency
37
+ name: terminal-table
38
+ requirement: &70231892496260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.4.5
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70231892496260
47
+ - !ruby/object:Gem::Dependency
48
+ name: sinatra
49
+ requirement: &70231884046780 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70231884046780
58
+ - !ruby/object:Gem::Dependency
59
+ name: rubyzip
60
+ requirement: &70231884045400 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70231884045400
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: &70231884044780 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70231884044780
80
+ - !ruby/object:Gem::Dependency
81
+ name: rake
82
+ requirement: &70231884043820 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70231884043820
91
+ - !ruby/object:Gem::Dependency
92
+ name: simplecov
93
+ requirement: &70231884042620 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70231884042620
102
+ description: ''
103
+ email: m@mattt.me
104
+ executables:
105
+ - pk
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - ./dubai.gemspec
110
+ - ./Gemfile
111
+ - ./Gemfile.lock
112
+ - ./lib/dubai/commands/build.rb
113
+ - ./lib/dubai/commands/generate.rb
114
+ - ./lib/dubai/commands/serve.rb
115
+ - ./lib/dubai/commands.rb
116
+ - ./lib/dubai/pass.rb
117
+ - ./lib/dubai/server.rb
118
+ - ./lib/dubai/templates/boarding-pass.json
119
+ - ./lib/dubai/templates/coupon.json
120
+ - ./lib/dubai/templates/event-ticket.json
121
+ - ./lib/dubai/templates/generic.json
122
+ - ./lib/dubai/templates/store-card.json
123
+ - ./lib/dubai.rb
124
+ - ./LICENSE
125
+ - ./Rakefile
126
+ - ./README.md
127
+ - spec/spec_helper.rb
128
+ - bin/pk
129
+ homepage: http://github.com/mattt/dubai
130
+ licenses: []
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ segments:
142
+ - 0
143
+ hash: -3634839724726580605
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ segments:
151
+ - 0
152
+ hash: -3634839724726580605
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 1.8.15
156
+ signing_key:
157
+ specification_version: 3
158
+ summary: Passbook pass generation and preview
159
+ test_files:
160
+ - spec/spec_helper.rb