Created
October 14, 2020 13:06
-
-
Save daddykotex/3a885e6cc14303a814b772bd1c92d574 to your computer and use it in GitHub Desktop.
Allows you to download the higher resolution photos from a lightroom album (not original resolution).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import $ivy.`co.fs2::fs2-io:2.3.0`, fs2.io._ | |
import $ivy.`co.fs2::fs2-core:2.3.0`, fs2._ | |
import ammonite.ops._ | |
import upickle.default.{ReadWriter => RW, macroRW} | |
import upickle._ | |
import cats.effect._ | |
import scala.concurrent.duration._ | |
/** | |
LOG INTO LIGHTROOM AND GO TO THE ALBUM YOU WANT TO DOWNLOAD | |
- GRAB THE COOKIE FROM ONE OF THE REQUESTS | |
- DOWNLOAD THE RESPONSES TO XHR CALLS TO https://lightroom.adobe.com/v2/spaces/5be0bbc946d041de932c483f73e14a6d/albums/70c589d0859d492194da57b80efd4ce0/assets... | |
- THIS WILL BE A JSON FILE WITH A DEAD FIRST LINE: `while(true) {}` | |
- REMOVE THE FIRST LINE AND PUT THE FILE INTO A JSON FILE. | |
- IT LOOKS LIKE THIS | |
{ | |
"base": "https://photos.adobe.io/v2/spaces/5be0bbc946d041de932c483f73e14a6d/", | |
"album": { | |
"id": "70c589d0859d492194da57b80efd4ce0", | |
"links": { | |
"self": { | |
"href": "albums/70c589d0859d492194da57b80efd4ce0" | |
} | |
} | |
}, | |
"resources": [ | |
{ | |
"id": "bc1112fec85847ce9e21dc939b1eeae3", | |
"type": "album_asset", | |
"created": "0000-00-00T00:00:00", | |
"updated": "0000-00-00T00:00:00", | |
"revision_ids": [ | |
"36eea278167c4bcf8f1f91cf39e97a17" | |
], | |
"links": { | |
"self": { | |
"href": "albums/70c589d0859d492194da57b80efd4ce0/assets/608c005d7d934c1ab18ea4b6cf8ea136" | |
} | |
}, | |
"asset": { | |
"id": "608c005d7d934c1ab18ea4b6cf8ea136", | |
"type": "asset", | |
"subtype": "image", | |
"created": "2020-02-06T01:34:56.431636Z", | |
"updated": "2020-02-06T01:46:35.773254Z", | |
"revision_ids": [ | |
"a5970d08065944ecb618673db22e2d5c", | |
"a07a0a0edd2c8acfb314b2c2077256bf", | |
"888b25a3574520a202bc77294e281ab4", | |
"a68a19336658ab900929238ae094bc6f" | |
], | |
"links": { | |
"self": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136" | |
}, | |
"/rels/comments": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136/comments", | |
"count": 0 | |
}, | |
"/rels/favorites": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136/favorites", | |
"count": 0 | |
}, | |
"/rels/rendition_type/2048": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136/revisions/a5970d08065944ecb618673db22e2d5c/renditions/74289892102452cb92155e94fc4c08bd" | |
}, | |
"/rels/rendition_type/1280": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136/revisions/a5970d08065944ecb618673db22e2d5c/renditions/820dbc22334846a383b6af7275bccef5" | |
}, | |
"/rels/rendition_type/640": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136/revisions/a5970d08065944ecb618673db22e2d5c/renditions/7cdcc08f64d620805ba197c8eade6e59" | |
}, | |
"/rels/rendition_type/thumbnail2x": { | |
"href": "assets/608c005d7d934c1ab18ea4b6cf8ea136/revisions/a5970d08065944ecb618673db22e2d5c/renditions/725e6233a5ce9e3eba9bbd8a701222d3" | |
} | |
} | |
... | |
}, | |
"payload": { | |
"userCreated": "2020-02-06T01:34:39.374Z", | |
"userUpdated": "2020-02-06T01:34:39.374Z" | |
} | |
} | |
] | |
} | |
- RUN THIS PROGRAM WITH AMMONIOTE: | |
`amm fetch-lightroom-album.sc photos1.json photos2.json [more files...]` | |
*/ | |
final case class PhotoFile(base: String, resources: Seq[Resource]) | |
object PhotoFile { | |
implicit val rw: RW[PhotoFile] = macroRW | |
} | |
final case class Resource(`type`: String, asset: Asset) | |
object Resource { | |
implicit val rw: RW[Resource] = macroRW | |
} | |
final case class Asset(id: String, links: Links) | |
object Asset { | |
implicit val rw: RW[Asset] = macroRW | |
} | |
final case class Links(@upickle.implicits.key("/rels/rendition_type/2048") large: Href) | |
object Links { | |
implicit val rw: RW[Links] = macroRW | |
} | |
final case class Href(href: String) | |
object Href { | |
implicit val rw: RW[Href] = macroRW | |
} | |
val cookie = """COOKIE_HERE""" | |
def photosFromFile(fileName: Path): IO[PhotoFile] = { | |
IO.delay(upickle.default.read[PhotoFile](fileName.toNIO)) | |
} | |
def downloadResource(base: String, resource: Resource): IO[Unit] = { | |
IO.delay { | |
val url = s"${base}${resource.asset.links.large.href}" | |
.replace("photos.adobe.io/v2/", "lightroom.adobe.com/v2c/") | |
os.write( | |
os.pwd / "photos" / s"${resource.asset.id}.jpg", | |
requests.get.stream( | |
url, | |
headers = Map("Cookie" -> cookie) | |
) | |
) | |
} | |
} | |
@main | |
def downloadPhotos(photoFiles: Path*) = { | |
implicit val ioTimer: Timer[IO] = IO.timer(scala.concurrent.ExecutionContext.Implicits.global) | |
fs2.Stream | |
.emits(photoFiles) | |
.evalMap(photosFromFile) | |
.flatMap { photoFile => | |
fs2.Stream | |
.emits(photoFile.resources) | |
.map(resource => photoFile.base -> resource) | |
} | |
.evalMap { case (base, resource) => downloadResource(base, resource) } | |
.metered(1.second) | |
.compile | |
.drain | |
.unsafeRunSync() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment