#!/usr/bin/make -sf # to debug: make -f windows-iso-url v=1 user_agent := Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 SHELL := bash -o pipefail session_id := $(shell uuidgen) all: step6 check:; type uuidgen dialog curl nokogiri ruby > /dev/null step0-windows.txt: check echo "https://www.microsoft.com/en-us/software-download/windows11" 11 \ "https://www.microsoft.com/en-us/software-download/windows10ISO" 10 | \ $(call dialog,Select Windows version) 2>$@ step1-editions.html: step0-windows.txt; cat $< | xargs $(curl) > $@ # extract the list of editions, then a user selects 1 edition step2-edition.txt: step1-editions.html nokogiri -e 'puts $$_.css("select#product-edition").children.select {|v| v.name == "option" && v["value"] != "null" }.map {|v| [v["value"], v.text.strip.shellescape]}.flatten.join " "' < $< | $(call dialog,Select edition) 2>$@ # fetch product languages step3-lang.json: step2-edition.txt # fetch some junk providing our session_id to the endpoint, otherwise # we get 400 in subsequent requests $(curl) 'https://vlscppe.microsoft.com/fp/tags.js?org_id=y6jn8c31&session_id=$(session_id)' > /dev/null $(curl) "https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=606624d44113&ProductEditionId=`cat $<`&Locale=en-US&sessionID=$(session_id)" > $@ # extract the list of languages, then the user selects 1 language step4-lang.txt: step3-lang.json ruby -rjson -rshellwords -e 'puts JSON.parse(STDIN.read).dig("Skus").map {|v| [v["Id"], v["Language"].shellescape]}.flatten.join " "' < $< | $(call dialog,Select languages) 2>$@ # fetch iso urls step5-urls.json: step4-lang.txt $(curl) "https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=606624d44113&SKU=`cat $<`&Locale=en-US&sessionID=$(session_id)" > $@ # extract iso urls step6: step5-urls.json ruby -rjson -e 'j=JSON.parse(STDIN.read); e=j.dig("Errors", 0, "Value"); abort e.to_s if e; j.dig("ProductDownloadOptions").each {|v| puts v["Uri"]}' < $< .DELETE_ON_ERROR: dialog = xargs dialog --keep-tite --no-tags --menu "$1" 0 0 0 curl = curl -sf --referer "`cat step0-windows.txt`" -A '$(user_agent)' ifndef v .INTERMEDIATE: step0-windows.txt step1-editions.html step2-edition.txt step3-lang.json step4-lang.txt step5-urls.json endif