passifier 0.0.2 → 0.0.3
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/README.md +57 -49
- data/examples/simple.rb +4 -5
- data/lib/passifier.rb +1 -1
- data/lib/passifier/manifest.rb +4 -4
- data/lib/passifier/pass.rb +15 -15
- data/test/passifier/test_pass.rb +4 -4
- metadata +3 -3
data/README.md
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
Generate Apple Passbook passes in Ruby
|
4
4
|
|
5
|
-
Passifier does most of the hard work and will
|
6
|
-
|
7
|
-
* A Hash of metadata and layout (
|
8
|
-
* Image
|
9
|
-
* The location of your key
|
10
|
-
* Output path
|
11
|
-
|
5
|
+
Passifier does most of the hard work and will more easily allow you to automate generating pkpass files. You simply supply
|
6
|
+
|
7
|
+
* A Hash of metadata and layout (the contents of pass.json for those experienced)
|
8
|
+
* Image URLs and paths
|
9
|
+
* The location of your key and certificate .pem files
|
10
|
+
* Output path where you'd like the generated .pkpass file
|
11
|
+
|
12
12
|
## Installation
|
13
13
|
|
14
14
|
Add this line to your application's Gemfile:
|
@@ -21,43 +21,43 @@ gem 'passifier'
|
|
21
21
|
|
22
22
|
### Metadata and Layout
|
23
23
|
|
24
|
-
First, supply a bunch of pass information and styling. This will become the file pass.json within the pass archive. More
|
24
|
+
First, supply a bunch of pass information and styling. This will become the file pass.json within the pass archive. More information on pass.json and creating a layout can be found at [developers.apple.com](https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/Introduction.html).
|
25
25
|
|
26
26
|
```ruby
|
27
27
|
|
28
28
|
serial = "SO_SERIAL"
|
29
29
|
|
30
30
|
spec = {
|
31
|
-
"formatVersion"
|
32
|
-
"passTypeIdentifier"
|
33
|
-
"teamIdentifier"
|
34
|
-
"relevantDate"
|
35
|
-
"organizationName"
|
36
|
-
"serialNumber"
|
37
|
-
"description"
|
38
|
-
"labelColor"
|
39
|
-
"backgroundColor"
|
40
|
-
"foregroundColor"
|
41
|
-
"generic"
|
42
|
-
"headerFields"
|
31
|
+
"formatVersion": 1,
|
32
|
+
"passTypeIdentifier": "pass.example.example",
|
33
|
+
"teamIdentifier": "METS",
|
34
|
+
"relevantDate": "2012-07-30T14:19Z",
|
35
|
+
"organizationName": "Example Inc.",
|
36
|
+
"serialNumber": serial,
|
37
|
+
"description": "this is a pass",
|
38
|
+
"labelColor": "rgb(122, 16, 38)",
|
39
|
+
"backgroundColor": "rgb(227, 227, 227)",
|
40
|
+
"foregroundColor": "rgb(110,110,110)",
|
41
|
+
"generic": {
|
42
|
+
"headerFields": [
|
43
43
|
{
|
44
|
-
"key"
|
45
|
-
"label"
|
46
|
-
"value"
|
44
|
+
"key": "date",
|
45
|
+
"label": "Date",
|
46
|
+
"value": "October 30th"
|
47
47
|
}
|
48
48
|
],
|
49
|
-
"primaryFields"
|
49
|
+
"primaryFields": [
|
50
50
|
{
|
51
|
-
"key"
|
52
|
-
"label"
|
53
|
-
"value"
|
51
|
+
"key": "title",
|
52
|
+
"label": "",
|
53
|
+
"value": "Passifier!"
|
54
54
|
}
|
55
55
|
],
|
56
|
-
"secondaryFields"
|
56
|
+
"secondaryFields": [
|
57
57
|
{
|
58
|
-
"key"
|
59
|
-
"label"
|
60
|
-
"value"
|
58
|
+
"key": "host",
|
59
|
+
"label": "Host",
|
60
|
+
"value": "paperlesspost.com",
|
61
61
|
}
|
62
62
|
]
|
63
63
|
}
|
@@ -66,19 +66,19 @@ spec = {
|
|
66
66
|
|
67
67
|
### Images
|
68
68
|
|
69
|
-
Notice that you can use either paths or urls here
|
69
|
+
Specify a Hash of images. Notice that you can use either paths or urls here.
|
70
70
|
|
71
71
|
```ruby
|
72
72
|
|
73
|
-
|
74
|
-
"background.png"
|
75
|
-
"background@2x.png"
|
76
|
-
"icon.png"
|
77
|
-
"icon@2x.png"
|
78
|
-
"logo.png"
|
79
|
-
"logo@2x.png"
|
80
|
-
"thumbnail.png"
|
81
|
-
"thumbnail@2x.png"
|
73
|
+
assets = {
|
74
|
+
"background.png": "assets/background.png",
|
75
|
+
"background@2x.png": "assets/background@2x.png",
|
76
|
+
"icon.png": "assets/icon.png",
|
77
|
+
"icon@2x.png": "assets/icon@2x.png",
|
78
|
+
"logo.png": "http://i.imgur.com/WLUf6.png",
|
79
|
+
"logo@2x.png": "http://i.imgur.com/mOpQo.png",
|
80
|
+
"thumbnail.png": "assets/thumbnail.png",
|
81
|
+
"thumbnail@2x.png": "assets/thumbnail@2x.png"
|
82
82
|
}
|
83
83
|
```
|
84
84
|
|
@@ -89,26 +89,34 @@ Give Passifier some info about your .pem files.
|
|
89
89
|
(to-do: more info on obtaining certificates and creating pem files)
|
90
90
|
|
91
91
|
```ruby
|
92
|
-
key_pem = "
|
92
|
+
key_pem = "path/to/a/key.pem"
|
93
93
|
pass_phrase = "somethingsomething"
|
94
|
-
cert_pem = "
|
94
|
+
cert_pem = "path/to/a/certificate.pem"
|
95
|
+
|
96
|
+
# Create a Signing object
|
97
|
+
signing = Passifier::Signing.new(key_pem, pass_phrase, cert_pem)
|
95
98
|
```
|
96
99
|
|
97
100
|
### Generate!
|
98
101
|
|
99
|
-
|
100
|
-
# Create the signing
|
101
|
-
signing = Passifier::Signing.new(key_pem, pass_phrase, cert_pem)
|
102
|
+
Now it's time to create your pass.
|
102
103
|
|
103
|
-
|
104
|
-
Passifier::Pass.
|
104
|
+
```ruby
|
105
|
+
Passifier::Pass.generate("readme.pkpass", serial, spec, assets, signing)
|
105
106
|
```
|
106
107
|
|
107
108
|
Passifier will have created the file `readme.pkpass` for you. When opened in Passbook, that pass looks something like:
|
108
109
|
|
109
110
|

|
110
111
|
|
111
|
-
|
112
|
+
## Further Reading
|
113
|
+
|
114
|
+
* Find a similar example with some more explanation [here](http://github.com/paperlesspost/passifier/blob/master/examples/simple.rb)
|
115
|
+
* Read a blog post about Passifier [here]()
|
116
|
+
|
117
|
+
## Documentation
|
118
|
+
|
119
|
+
* [rubydoc](http://rubydoc.info/github/paperlesspost/passifier)
|
112
120
|
|
113
121
|
## Contributing to Passifier
|
114
122
|
|
data/examples/simple.rb
CHANGED
@@ -69,19 +69,18 @@ key_pem = "../test/assets/signing/key/key.pem"
|
|
69
69
|
pass_phrase = File.read("../test/assets/signing/pass_phrase.txt").strip.lstrip # you can just replace this with a string if you want
|
70
70
|
cert_pem = "../test/assets/signing/certificate/certificate.pem"
|
71
71
|
|
72
|
+
# Create a signing object
|
73
|
+
signing = Passifier::Signing.new(key_pem, pass_phrase, cert_pem)
|
74
|
+
|
72
75
|
#
|
73
76
|
#
|
74
77
|
# Now, generate the pass!
|
75
78
|
#
|
76
79
|
#
|
77
80
|
|
78
|
-
# Create the signing
|
79
|
-
#
|
80
|
-
signing = Passifier::Signing.new(key_pem, pass_phrase, cert_pem)
|
81
|
-
|
82
81
|
# Create the pass archive
|
83
82
|
output_file = "./simple.pkpass"
|
84
|
-
Passifier::Pass.
|
83
|
+
Passifier::Pass.generate(output_file, serial, spec, images, signing)
|
85
84
|
|
86
85
|
# Finished!
|
87
86
|
puts "Finished generating the pass archive: #{output_file}"
|
data/lib/passifier.rb
CHANGED
data/lib/passifier/manifest.rb
CHANGED
@@ -7,10 +7,10 @@ module Passifier
|
|
7
7
|
attr_reader :hash
|
8
8
|
alias_method :to_hash, :hash
|
9
9
|
|
10
|
-
# @param [Array<Passifier::StaticFile, Passifier::UrlSource>]
|
10
|
+
# @param [Array<Passifier::StaticFile, Passifier::UrlSource>] asset_files The asset files to populate the manifest with
|
11
11
|
# @param [Passifier::Signing] signing The signing to sign the images and generate the digests with
|
12
|
-
def initialize(
|
13
|
-
@
|
12
|
+
def initialize(asset_files, signing)
|
13
|
+
@asset_files = asset_files
|
14
14
|
populate_content(signing)
|
15
15
|
end
|
16
16
|
|
@@ -28,7 +28,7 @@ module Passifier
|
|
28
28
|
# @return [String] The resulting contents of the manifest file (aka Passifier::Manifest#content)
|
29
29
|
def populate_content(signing)
|
30
30
|
@hash = {}
|
31
|
-
@
|
31
|
+
@asset_files.each { |file| @hash[file.name] = signing.sha(file.content) }
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
data/lib/passifier/pass.rb
CHANGED
@@ -5,7 +5,7 @@ module Passifier
|
|
5
5
|
class Pass
|
6
6
|
|
7
7
|
attr_reader :archive,
|
8
|
-
:
|
8
|
+
:asset_files,
|
9
9
|
:manifest,
|
10
10
|
:serial_number,
|
11
11
|
:signature,
|
@@ -13,15 +13,15 @@ module Passifier
|
|
13
13
|
|
14
14
|
# @param [String] serial_number An ID for this pass, used as the serial number in pass.json
|
15
15
|
# @param [Hash] spec_hash The pass's spec (pass.json)
|
16
|
-
# @param [Hash]
|
16
|
+
# @param [Hash] assets The pass's assets (can be local files or remote urls)
|
17
17
|
# ex. { "background.png" => "https://www.google.com/images/srpr/logo3w.png",
|
18
18
|
# "thumbnail.png" => "~/thumb.png" }
|
19
19
|
# @param [Signing] signing A valid signing
|
20
|
-
def initialize(serial_number, spec_hash,
|
20
|
+
def initialize(serial_number, spec_hash, assets, signing, options = {})
|
21
21
|
@signing = signing
|
22
22
|
@spec = Spec.new(serial_number, spec_hash)
|
23
|
-
@
|
24
|
-
@manifest = Manifest.new(@
|
23
|
+
@asset_files = to_asset_files(assets)
|
24
|
+
@manifest = Manifest.new(@asset_files, signing)
|
25
25
|
@signature = ManifestSignature.new(@manifest, signing)
|
26
26
|
end
|
27
27
|
|
@@ -29,7 +29,7 @@ module Passifier
|
|
29
29
|
# @return [Array<Spec, Manifest, ManifestSignature, StaticFile, UrlSource>] File objects that will appear in
|
30
30
|
# this pass' archive
|
31
31
|
def files_for_archive
|
32
|
-
[@spec, @manifest, @signature, @
|
32
|
+
[@spec, @manifest, @signature, @asset_files].flatten.compact
|
33
33
|
end
|
34
34
|
|
35
35
|
# Create the Archive file for this Pass
|
@@ -54,25 +54,25 @@ module Passifier
|
|
54
54
|
# @param [String] path The desired path of the Archive
|
55
55
|
# @param [String] serial_number An ID for this pass, used as the serial number in pass.json
|
56
56
|
# @param [Hash] spec_hash The pass's spec (pass.json)
|
57
|
-
# @param [Hash]
|
57
|
+
# @param [Hash] assets The pass's assets (can be local files or remote urls)
|
58
58
|
# ex. { "background.png" => "https://www.google.com/images/srpr/logo3w.png",
|
59
59
|
# "thumbnail.png" => "~/thumb.png" }
|
60
60
|
# @param [Signing] signing A valid signing
|
61
61
|
# @return [Archive] The complete stored archive
|
62
|
-
def self.create_archive(path, serial_number, spec_hash,
|
63
|
-
pass = new(serial_number, spec_hash,
|
62
|
+
def self.create_archive(path, serial_number, spec_hash, assets, signing, options = {})
|
63
|
+
pass = new(serial_number, spec_hash, assets, signing, options)
|
64
64
|
pass.create_archive(path, options)
|
65
65
|
end
|
66
66
|
|
67
67
|
protected
|
68
68
|
|
69
|
-
# Convert a list of
|
70
|
-
# @param [Hash]
|
69
|
+
# Convert a list of assets sources to file objects
|
70
|
+
# @param [Hash] assets A Hash of filenames and corresponding file paths or urls
|
71
71
|
# @return [Array<StaticFile, UrlSource>] The resulting StaticFile and/or UrlSource objects
|
72
|
-
def
|
73
|
-
|
74
|
-
klass = (
|
75
|
-
klass.new(filename,
|
72
|
+
def to_asset_files(assets)
|
73
|
+
assets.map do |filename, source|
|
74
|
+
klass = (source =~ /https?:\/\/[\S]+/) ? UrlSource : StaticFile
|
75
|
+
klass.new(filename, source)
|
76
76
|
end.flatten.compact
|
77
77
|
end
|
78
78
|
|
data/test/passifier/test_pass.rb
CHANGED
@@ -4,13 +4,13 @@ class TestPass < Test::Unit::TestCase
|
|
4
4
|
|
5
5
|
include Passifier
|
6
6
|
|
7
|
-
def
|
7
|
+
def test_to_asset_files
|
8
8
|
pass = Helper.new_pass
|
9
9
|
|
10
10
|
assert_not_nil pass
|
11
|
-
assert_not_empty pass.
|
12
|
-
assert pass.
|
13
|
-
assert_equal Helper.new_images.size, pass.
|
11
|
+
assert_not_empty pass.asset_files
|
12
|
+
assert pass.asset_files.all? { |file| [StaticFile, UrlSource].include?(file.class) }
|
13
|
+
assert_equal Helper.new_images.size, pass.asset_files.size
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_files_for_archive
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -156,7 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
156
|
version: '0'
|
157
157
|
segments:
|
158
158
|
- 0
|
159
|
-
hash:
|
159
|
+
hash: 2729969815868987014
|
160
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
161
|
none: false
|
162
162
|
requirements:
|