Skip to content

Instantly share code, notes, and snippets.

@patricksan
Forked from odrobnik/makepass.rb
Created January 15, 2014 14:07
Show Gist options
  • Save patricksan/8436868 to your computer and use it in GitHub Desktop.
Save patricksan/8436868 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'json'
require 'digest/sha1'
require "openssl"
pass = {
"formatVersion" => 1
}
# add pass meta data
pass["passTypeIdentifier"] = "pass.com.drobnik.movienight"
pass["serialNumber"] = "001"
pass["teamIdentifier"] = "Z7L2YCUH45"
pass["organizationName"] = "Cocoanetics"
pass["logoText"] = "Cocoanetics"
pass["description"] = "VIP Movie Night Sofa Seat"
# create the barcode
barcode = {
"format" => "PKBarcodeFormatPDF417",
"messageEncoding" => "UTF8"
}
barcode["message"] = "2014-01-01T12:00 Seat 01"
pass["barcode"] = barcode
# header fields
headerFields = [{
"key" => "seat",
"label" => "Seat",
"value" => "1B"
}]
# primary fields
primaryFields = [{
"key" => "name",
"value" => "VIP Movie Night"
}]
# secondary fields
secondaryFields = [{
"key" => "location",
"label" => "Location",
"value" => "Oliver's Home Movie Theater"
}]
# auxiliary fields
auxiliaryFields = [{
"key" => "date",
"label" => "Event Date",
"dateStyle" => "PKDateStyleMedium",
"timeStyle" => "PKDateStyleShort",
"value" => "2014-07-24T18:00Z"
}]
# fields on back of pass
backFields = [
{
"key" => "phone",
"label" => "For more info",
"value" => "800-1234567890"
},
{
"key" => "terms",
"label" => "TERMS AND CONDITIONS",
"value" => "Free popcorn and drink at entrance. Please arrive sufficiently early to pick your seat and allow show to start on time."
}
]
# put ticket fields together
eventTicketFields = {
"headerFields" => headerFields,
"primaryFields" => primaryFields,
"secondaryFields" => secondaryFields,
"auxiliaryFields" => auxiliaryFields,
"backFields" => backFields
}
pass["eventTicket"] = eventTicketFields
# create pass JSON string
passJSON = JSON.pretty_generate(pass)
# get SHA1 of pass JSON
passSHA1 = Digest::SHA1.hexdigest passJSON
# files that are possible in pkpass
possibleResources = ['icon.png', 'icon@2x.png',
'thumbnail.png', 'thumbnail@2x.png',
'strip.png', 'strip@2x.png',
'logo.png', 'logo@2x.png',
'background.png', 'background@2x.png']
# filter possible resources with actual files in folder
resources = possibleResources & Dir['*']
# first file is the JSON
manifest = {"pass.json" => passSHA1}
# keep track of files to put in ZIP
zipCommand = ["zip", "-q", "new.pkpass", "pass.json", "signature", "manifest.json"]
# iterate over resources
resources.each do |resource_file|
# load file contents into variable
file = File.open(resource_file, "rb")
contents = file.read
# get resource SHA1
contents_SHA1 = Digest::SHA1.hexdigest contents
# add resource file and SHA1 to manifest hash
manifest[resource_file] = contents_SHA1
zipCommand << resource_file
end
# create manifest JSON string
manifestJSON = JSON.pretty_generate(manifest)
# write manifest to disk
manifest_file = open("manifest.json", "w")
manifest_file.write(manifestJSON)
manifest_file.close
# write pass file to disk
pass_file = open("pass.json", "w")
pass_file.write(passJSON)
pass_file.close
# create signature
root_cert = OpenSSL::X509::Certificate.new File.read('WWDR.pem')
key = OpenSSL::PKey::RSA.new File.read('passkey.pem'), '12345'
certificate = OpenSSL::X509::Certificate.new File.read('passcertificate.pem')
signature = OpenSSL::PKCS7.sign(certificate, key, manifestJSON, [root_cert], OpenSSL::PKCS7::BINARY | OpenSSL::PKCS7::DETACHED).to_der
# write signature to disk
signature_file = open("signature", "wb")
signature_file.write signature
signature_file.close
# execute zip command
system(*zipCommand)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment