brarcher / loyalty-card-locker

Stores your barcode-based store/loyalty cards on your phone
GNU General Public License v3.0
171 stars 29 forks source link

Pkpass file support #309

Open jeroenev opened 5 years ago

jeroenev commented 5 years ago

.pkpass is a file format specifically for "tickets, passes, coupons or member cards, and also student IDs, loyalty cards"

https://www.file-extension.info/format/pkpass

It's supported by some other popular apps like StoCard, and used by airlines

brarcher commented 4 years ago

This app uses the ZXing library for barcode support. Looking at the list of formats supported by that library:

https://github.com/zxing/zxing/#supported-formats

it does not appear that it is supported. If that project supported the format, there may be a case for adding support for it here also. That project is in maintenance mode, though, so I'm not sure how likely it is.

jeroenev commented 4 years ago

Pkpass is not directly a barcode format, but a file format containing info card-ids/private keys instead of a numeric barcode, which would make it outside of the scope of the zxing project

brarcher commented 4 years ago

Ah. If that is the case, what specifically is the ask? Is it to display the barcode data differently if it is pkpass?

TheLastProject commented 4 years ago

I've done a bit of research on this. Pkpass is commonly used for tickets (think plane tickets or CCC). They're actually zip files containing a pass.json file together with some other to us unimportant stuff.

Taking as example https://github.com/keefmoon/Passbook-Example-Code/blob/master/Pass-Example-Generic/Pass-Example-Generic.pkpass

The pass.json file looks as follows:

{
  "passTypeIdentifier" : "pass.keefmoon.example-generic",
  "formatVersion" : 1,
  "teamIdentifier" : "YAXJZJ267E",
  "organizationName" : "Passbook Example Company",
  "serialNumber" : "0000001",
  "description" : "Staff Pass for Employee Number 001",
  "associatedStoreIdentifiers" : [
     284971959
  ],
  "locations" : [
    {"latitude" : 51.50506, "longitude" : -0.01960, "relevantText" : "Company Offices" }
  ],
  "foregroundColor" : "rgb(255, 255, 255)",
  "backgroundColor" : "rgb(90, 90, 90)",
  "labelColor" : "rgb(255, 255, 255)",
  "logoText" : "Company Staff ID",
  "barcode" : {
        "format" : "PKBarcodeFormatQR",
        "message" : "0000001",
        "messageEncoding" : "iso-8859-1",
        "altText" : "Staff ID 0000001"
   },
  "generic" : {
    "headerFields" : [
        {
            "key" : "staffNumber",
            "label" : "Staff Number",
            "value" : "001"
        }
    ],
    "primaryFields" : [
      {
        "key" : "staffName",
        "label" : "Name",
        "value" : "Peter Brooke"
      }
    ],
    "secondaryFields" : [
      {
        "key" : "telephoneExt",
        "label" : "Extension",
        "value" : "9779"
      },
      {
        "key" : "jobTitle",
        "label" : "Job Title",
        "value" : "Chief Pass Creator"
      }
    ],
    "auxiliaryFields" : [
      {
        "key" : "expiryDate",
        "dateStyle" : "PKDateStyleShort",
        "label" : "Expiry Date",
        "value" : "2013-12-31T00:00-23:59"
      }
    ],
    "backFields" : [
      {
        "key" : "managersName",
        "label" : "Manager's Name",
        "value" : "Paul Bailey"
      },
      {
        "key" : "managersExt",
        "label" : "Manager's Extension",
        "value" : "9673"
      }
    ]
  }
}

While containing a lot more info than a loyalty card, we could most likely just use the description as name and the info in the barcode JSON field to generate the barcode. And maybe somehow put some of the other info in notes after supporting multiline notes first.

So, supporting this would be:

  1. Unzip .pkpass file
  2. Parse relevant info from pass.json
  3. Maybe put some stuff in notes
  4. Discard the rest(?)

Actually not super hard. I think it makes sense to support, although probably only in a basic form. There are other apps like PassAndroid which support this format fully and are better suited for the more complex cases.

TheLastProject commented 4 years ago

I started with this in #327.

@jeroen7s As you requested this feature, is there any way you could possibly supply me with some pkpass files and screenshots of how they look like in other apps, if you have any you are willing to share? That will help me ensure the best possible result as I know better what to work towards.

jeroenev commented 4 years ago

Thanks for working on this, much appreciated. Found an old plane ticket in my Signal conversations you can use. Here's the File: https://intuxikated.stackstorage.com/s/LbC7LhgNnvF6CPzz And a screenshot of how it looks in the "StoCard" app on the play store: signal-2019-09-07-161903

P.s. I wasn't aware there was already an open source app for this, couldn't find "PassBook" at the time, though having it inside the same app as my loyalty cards would be really nice :)

TheLastProject commented 4 years ago

Would it be acceptable if I add your flight ticket as a test case? I assume you're not worried about privacy risks because you already posted it on a public bugtracker, but I'd like to make sure just in case.

TheLastProject commented 4 years ago

On an unrelated note, I absolutely love how the first in-the-wild card I get sent to test with violates the spec every so slightly (incorrect colour code format). Good job, Eurowings!

jeroenev commented 4 years ago

You can use it for a test-case, however i'd prefer it if you blank out my name tho :D, aside from that you can use it.

TheLastProject commented 4 years ago

Just sharing some progress. Still quite a lot of work left, especially because of the whole i18n system.

photo_2019-12-14_20-58-59

jeroenev commented 4 years ago

Looks like a great start. Do you really need the i18n tho? I think you could add it without translations as a first step and then add translations later?

TheLastProject commented 4 years ago

Basic i18n is already working, see pull request :)

jeroenev commented 4 years ago

cool, nice work :+1:

devurandom commented 4 years ago

Have a look at https://github.com/ligi/PassAndroid, maybe you can borrow / share some code.