Files
proton-stream/crates/pstr-core/Cargo.toml
T
nvrl 0b2813cd42 feat(core,stream,meta,app,android,cli): sign in to Proton and sync watch history
A Proton account is now optional alongside public links. Signing in (password,
then a second-factor code and a mailbox password where the account has them;
a CAPTCHA gate is solved in the Android app) stores one session blob in the OS
credential store under `proton-account`, writing back every refreshed token
since refresh tokens are single-use. With an account, folders of the viewer's
own Drive — My Files, other devices, shared with me — can be added as shares
through the same `ShareClient` surface as a public link.

Watch history syncs through a `proton-stream` device in that Drive: one
`watch-history/<installation>.json` per installation, so no two devices ever
write the same file. Each sync reads the others and merges per episode, newer
`updated_at` wins, with a deterministic tie-break. It runs at launch, after
sign-in, whenever the player closes and every five minutes. A session that can
no longer refresh signs the app out instead of failing on every launch.

The CLI gains `login`, `logout`, `account`, `browse` and `sync`.

Also in this change:
- Android offline downloads no longer look stuck (B64): two transfer at once,
  through a copy stream with no read-ahead, with a smoothed transfer rate.
- Choosing a metadata match by hand now enriches the title too, instead of
  keeping the old match's episodes and artwork.

The catalog schema is unchanged.
2026-10-06 13:06:54 +02:00

39 lines
1.4 KiB
TOML

[package]
name = "pstr-core"
description = "Shares, catalog model, filename parsing and persistence for proton-stream."
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
authors.workspace = true
[dependencies]
proton-sdk.workspace = true
proton-drive-rs.workspace = true
tokio.workspace = true
futures.workspace = true
serde.workspace = true
serde_json.workspace = true
thiserror.workspace = true
tracing.workspace = true
directories.workspace = true
rusqlite.workspace = true
sha2.workspace = true
parking_lot.workspace = true
getrandom.workspace = true
# The credential store, per platform. Without the target's feature `keyring`
# compiles fine and silently resolves to its in-memory `mock` store, which
# accepts every write and has forgotten it by the next `Entry` — a share that
# adds cleanly and then reports "has no stored credentials" on open. These
# blocks only add features to the dependency above.
[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))'.dependencies]
keyring = { workspace = true, features = ["sync-secret-service", "crypto-rust"] }
[target.'cfg(target_os = "windows")'.dependencies]
keyring = { workspace = true, features = ["windows-native"] }
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
keyring = { workspace = true, features = ["apple-native"] }