Giter Club home page Giter Club logo

f1's Introduction

๐ŸŽ๏ธ @nberlette/f1

Scraping photos of the Las Vegas Formula 1 track construction

This is an autonomous image scraper developed using TypeScript, Deno, and GitHub Actions. It was purpose-built to document the historic Formula 1 track construction in Las Vegas, Nevada, slated to host the inaugural Heineken Silver Grand Prix on November 18th. The images will be stitched together into timelapse videos of the track's lifecycle, from start to finish ๐Ÿ.

Track Details and Statistics

Estimated Top Speed Circuit Length Corners Straights DRS Zones
212 mph โ€ข 342 km/h 3.8 miles โ€ข 6.12 km 17 3 2

๐Ÿ“ธ Latest โ€ข ๐ŸŽฌ Timelapse โ€ข ๐Ÿ—“๏ธย Previous Images โ€ข โ„น๏ธ Project Details โ€ข ๐ŸŒŸ Star It!


Latest Snapshot

The latest image scraped from the Formula 1 track build in Las Vegas


Timelapse Preview

timelapse.mp4

Note: this video was created with images from 2023-08-15 - 2023-10-12


About

The first scrape happened on June 3rd, 2023. As of October 18th it has surpassed 18,500 commits, equivalent to over 1.2GB of image data. Photos are stored in the ./assets folder of this repository, and also persisted to a Deno KV database backed by FoundationDB.

The origin of the scraped images is an real-time photo feed, sourced directly from the official Formula 1 website.

โš ๏ธ This project is for educational purposes and is not affiliated with Formula 1.

Tools Used

  • Deno v1.37.2
  • Rust-based JS runtime, sandboxed, with great TS/TSX support.
  • Provides the tools for network and file system operations.
  • TypeScript 5.2.2
  • Superset of JavaScript featuring advanced static typechecking.
  • Better type safety means more readable and maintainable code.
  • GitHub Actions
  • Provides free macOS virtual machines powering the scraper.
  • Responsible for scheduled execution of the scraper workflow
  • Temporarily stores the image artifacts
  • Deno KV (currently in beta)
  • Provides us with global data persistence and caching
  • ffmpeg (timelapse feature is unstable)
  • Leveraged to automatically generate timelapse videos

AI-generated artwork of a Formula 1 car racing down the Las Vegas Strip

AI-generated F1 art created with SDXL 1.0 and the prompt "Formula 1 cars on the Las Vegas Strip"


How it Works

The majority of the work happens in main.ts, despite it only being 3 lines of code. It is responsible for invoking the scraper located in src/scrape.ts, and is ran every 10 minutes by a GitHub Action defined by the workflow in main.yml.

Assets and Data

Images are named after their capture time as a JPEG file in UTC. For example, an image captured at 2023-07-09T04:28:57 would be saved as ./assets/2023-07-09/04_28_57.jpg. The latest image is always saved as ./assets/latest.jpg for easy access.

Scrape Process, Step-by-Step

  1. GitHub Actions runs the scrape workflow every ~10 minutes, depending on traffic.
  2. The runner checks out the repo, installs Deno, and prepares to scrape.
  3. deno task scrape is executed, which runs the main.ts file.
  4. main.ts imports scrape() from src/scrape.ts, which defines two inner functions, read and write.
    • Once it has checked that import.meta.main is set, the following steps are taken:
    1. ๐Ÿ” READ: read() is called with IMAGE_URL.
      • Internally, the Fetch API is used to download the image.
        If the request fails, it will be retried up to ATTEMPTS times, with a short pause between each successive attempt.
      • If all attempts are exhausted without success, the run will terminate.
      • Otherwise, a new instance of the Image class is returned.
    2. ๐Ÿ’พ WRITE: write() is called, with the Image as its only argument. Before writing, however, it runs through some checks:
      1. The Image.hash is checked against the hash "table" in Deno KV.
        If an entry exists, the image is stale and won't make it any further. If Deno KV is unavailable, the image data is checked against latest.jpg via a timing-safe equality comparison, avoiding exposure to timing-based attacks.
        • If they are equal, the image has not updated at the origin. The process starts over at step 4 and repeats until a new image is found.
        • If the maximum number of ATTEMPTS is reached and no new image was found, the job terminates unsuccessfully.
      2. If we've made it this far, we have a fresh image and we need to store it.
        • Image.write() persists the image to Deno KV.

          The key is generated by the Image API, using the image timestamp.

        • The image timestamp is indexed with its unique SHA-256 hash in Deno KV.

          This prevents later scrapes from duplicating this image. It also means if you try to instantiate a new Image from an old hash, it will always return the original image and its original timestamp.

        • Image.writeFile() saves it to the local file system.

          The filename is generated by the Image API, using the image timestamp.

        • Image.writeFile() also saves it to ./assets/latest.jpg,
      3. The setOutput helper pipes the image metadata to the GitHub Actions runner, to be used in the commit step.
    3. The scrape is now complete and the runner proceeds to the final steps.
  5. The photo is stored as a workflow artifact for 90 days.
  6. ๐Ÿค All changes are committed + pushed to the repository.
  7. ๐Ÿ The job finishes successfully and the runner is terminated. Hooray!

AI-generated artwork of a Formula 1 car racing down the Las Vegas Strip

Previous Snapshots

October 17th October 15th October 13th October 11th
2023-10-17T20:26:59 2023-10-15T21:38:24 2023-10-13T23:52:14 2023-10-11T21:26:47
October 9th October 7th October 5th October 3rd
2023-10-09T22:27:19 2023-10-07T22:26:51 2023-10-05T22:19:31 2023-10-03T22:20:37
October 2nd September 28th September 24th September 20th
2023-10-02T22:29:06 2023-09-28T22:24:03 2023-09-24T22:12:21 2023-09-20T22:22:10
September 16th September 12th September 8th September 4th
2023-09-04T22:20:41 2023-09-16T22:45:35 2023-09-10T22:33:07 2023-09-04T22:49:09

MIT ยฉ Nicholas Berlette โ€ข Made with โ™ฅ๏ธ in Las Vegas, NV

This project is not affiliated with Formula 1 and is for educational purposes only.

f1's People

Contributors

github-actions[bot] avatar nberlette avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

f1's Issues

TODO: remove all duplicate images

Prior to the recent merge of PR #4, the scraping process was terribly inefficient and lazy. It did not perform anything beyond a rudimentary size comparison to determing if it had encountered new content, leading to several thousand duplicate images being collected over the last couple months.

While the new logic from the recent merge addresses the root issue, and prevents any duplicates from being collected now, it did not address those 3,500ish images that had accumulated prior to it.

This issue is a reference point for an incoming PR that will remedy that, removing all duplicates and thereby reducing the project size by a couple hundred MB.

Stay tuned

[bug] stale images being treated as new content, causing duplicates

I've noticed a couple instances of the oxblue.com photo stream being down recently. During these time periods, an outdated image in the response is coupled with inaccurate header metadata, making it seem as if its new content.

I need to add a deduplication step that checks the incoming bytes themselves and only proceeds with the scrape if they are new when compared to the most recent scrape. I've had to manually disable the workflow for now until the server returns to normal operation, in the meantime I'll work on a fix for this. I'll also remove all of the duplicates that have amassed during the last couple of outages.

[bug] workflow runs are failing intermittently (and running 10x longer than intended)

It seems that about 1 in every 5-10 runs is currently failing to complete, and that's after it has run for an average of 10x minutes longer than a typical successful run.

A normal workflow run without any issues, takes about 45-60 seconds to successfully complete from start to finish. In comparison, the average failed run is currently taking over 6 minutes and 30 seconds before it gives up and fails.

This has something to do with the "retries" logic of the scraper; I have a hunch that when the first attempt fails to retrieve new content, it is running into cached content while making its additional attempts.

I'm investigating the issue currently and will be pushing through a PR to fix it as soon as I can.

TODO: add workflow for daily/weekly timelapses via ffmpeg

Already have this mostly sketched out, it just isn't tested yet. And I need to figure out what to do with the files once generated since they're quite large (easily > 100mb each for multi-day timelapses).

I know nobody is going to read this but if you have any ideas, please chime in with them. Unless it's S3. If you're going to suggest S3, do not chime in. Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.