[motorola-security] Add auto method (#475)
Based on https://gist.github.com/ab/67c6343530c6b8e599f07cedccbcba3d. Closes #277.
This commit is contained in:
59
src/motorola-security.py
Normal file
59
src/motorola-security.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
from common import dates, endoflife, http
|
||||
from common.releasedata import ProductData, config_from_argv
|
||||
|
||||
|
||||
def extract_data(url: str, key_to_search_for: str) -> dict | None:
|
||||
"""Extract JSON data from Motorola Mobility security updates page."""
|
||||
html = http.fetch_html(url)
|
||||
|
||||
# find all script tags with no src attribute and containing a CDATA section.
|
||||
all_scripts = [str(t.getText) for t in html.find_all("script", src=False)]
|
||||
candidate_scripts = [s for s in all_scripts if key_to_search_for in s]
|
||||
if len(candidate_scripts) != 1:
|
||||
msg = f"Expected exactly one script containing {key_to_search_for}, found {len(candidate_scripts)}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Ideally, we would use an actual JavaScript parser to find our desired content.
|
||||
lines = candidate_scripts[0].split("\n")
|
||||
candidate_lines = [line for line in lines if key_to_search_for in line]
|
||||
if len(candidate_lines) != 1:
|
||||
msg = f"Expected exactly one containing {key_to_search_for} in JS, got {len(candidate_lines)}"
|
||||
raise ValueError(msg)
|
||||
|
||||
candidate_line = candidate_lines[0]
|
||||
raw_json = re.search(r"\{.+}", candidate_line)
|
||||
if not raw_json:
|
||||
msg = f"Failed to find JSON in {candidate_line}"
|
||||
raise ValueError(msg)
|
||||
|
||||
logging.debug(f"Found : {raw_json}")
|
||||
return json.loads(raw_json.group(0))
|
||||
|
||||
config = config_from_argv()
|
||||
with ProductData(config.product) as product_data:
|
||||
json_data = extract_data(config.url, "guidedAssistant")
|
||||
|
||||
for question in json_data["j"]["guidedAssistant"]["questions"]:
|
||||
if not question.get("responses") or question["responses"][0].get("text") != "Security patch details for all Motorola products":
|
||||
logging.debug(f"Skipping {question}")
|
||||
continue
|
||||
|
||||
lines = question["taglessText"].replace("\xa0", " ").split("\n")
|
||||
logging.debug(lines)
|
||||
|
||||
product_id = question["agentText"]
|
||||
label = lines[0].strip()
|
||||
name = endoflife.to_identifier(label)
|
||||
release = product_data.get_release(name)
|
||||
release.set_field("link", f"https://en-us.support.motorola.com/app/software-security-update/g_id/7112/productid/{product_id}")
|
||||
for line in lines:
|
||||
if (m := re.search(r"^Device launched on (.*)$", line)):
|
||||
date = dates.parse_date_or_month_year_date(m.group(1).strip()).replace(day=1)
|
||||
release.set_release_date(date)
|
||||
if (m := re.search(r"^Security updates will stop on (.*)$", line)):
|
||||
eol = dates.parse_date_or_month_year_date(m.group(1).strip())
|
||||
release.set_eol(eol)
|
||||
Reference in New Issue
Block a user