mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-31 18:55:13 +08:00
84 lines
3.7 KiB
Python
84 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate the offline subset from a local WH-2099/macdb checkout and Simple Icons 11.15.0.
|
|
|
|
No download or generation takes place on the router or during package builds.
|
|
"""
|
|
import argparse
|
|
import csv
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
import shutil
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def normalize(name):
|
|
return re.sub(r'[^a-z0-9]+', ' ', name.lower()).strip()
|
|
|
|
|
|
def vendor_for(name, vendors):
|
|
matches = [i for i, v in enumerate(vendors)
|
|
if any(re.search(p, normalize(name)) for p in v['patterns'])]
|
|
if len(matches) > 1:
|
|
raise ValueError('Ambiguous vendor: ' + name)
|
|
return matches[0] if matches else None
|
|
|
|
|
|
def generate(source, icons):
|
|
vendors = json.loads((ROOT / 'tools/vendors.json').read_text())
|
|
prefixes, all_rows, aliases = {}, {}, {}
|
|
path = source / 'mac.csv'
|
|
for row in csv.DictReader(path.open(encoding='utf-8-sig')):
|
|
assignment = row['assignment'].upper()
|
|
length = {'MA-L': 6, 'MA-M': 7, 'MA-S': 9}.get(row['registry'])
|
|
if length is None or not re.fullmatch('[0-9A-F]{%d}' % length, assignment):
|
|
raise ValueError('Invalid assignment: ' + assignment)
|
|
index = vendor_for(row['org_name'], vendors)
|
|
all_rows[assignment] = index
|
|
if index is not None:
|
|
prefixes[assignment] = index
|
|
aliases.setdefault(vendors[index]['slug'], set()).add(row['org_name'])
|
|
# An unrecognized more-specific assignment must mask a recognized parent.
|
|
for assignment, index in all_rows.items():
|
|
if index is None and any(assignment[:n] in prefixes for n in (6, 7) if n < len(assignment)):
|
|
prefixes[assignment] = None
|
|
out = ROOT / 'htdocs/luci-static/resources/oui'
|
|
out.mkdir(parents=True, exist_ok=True)
|
|
data = json.dumps({'vendors': [[v['slug'], v['name']] for v in vendors],
|
|
'prefixes': dict(sorted(prefixes.items()))}, separators=(',', ':')) + '\n'
|
|
revision = hashlib.sha256(data.encode()).hexdigest()[:12]
|
|
for old in out.glob('vendors-*.json'):
|
|
old.unlink()
|
|
(out / ('vendors-' + revision + '.json')).write_text(data)
|
|
for v in vendors:
|
|
if not v.get('supplemental'):
|
|
shutil.copyfile(icons / 'icons' / (v['slug'] + '.svg'), out / (v['slug'] + '.svg'))
|
|
elif not (out / (v['slug'] + '.svg')).is_file():
|
|
raise ValueError('Missing supplemental icon: ' + v['slug'])
|
|
shutil.copyfile(source / 'LICENSE', out / 'LICENSE.macdb')
|
|
helper = out / 'oui.js'
|
|
if helper.exists():
|
|
helper.write_text(re.sub(r'vendors-[0-9a-f]+\.json', 'vendors-' + revision + '.json', helper.read_text()))
|
|
for name in ['LICENSE.md', 'DISCLAIMER.md']:
|
|
shutil.copyfile(icons / name, out / name)
|
|
(ROOT / 'tools/sources.json').write_text(json.dumps({
|
|
'simple_icons': 'https://github.com/simple-icons/simple-icons/tree/11.15.0',
|
|
'macdb': {'url': 'https://github.com/WH-2099/macdb',
|
|
'sha256': hashlib.sha256(path.read_bytes()).hexdigest()},
|
|
'database': 'vendors-' + revision + '.json',
|
|
'assignments': len(prefixes),
|
|
'supplemental_icons': json.loads((ROOT / 'tools/supplemental.json').read_text()),
|
|
'aliases': {s: sorted(a) for s, a in sorted(aliases.items())}
|
|
}, indent=2) + '\n')
|
|
print(f'{len(vendors)} vendors, {len(prefixes)} assignments, {len(data)} bytes, revision {revision}')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('source', type=Path, help='macdb checkout containing mac.csv and LICENSE')
|
|
parser.add_argument('icons', type=Path, help='Unpacked simple-icons 11.15.0 source')
|
|
args = parser.parse_args()
|
|
generate(args.source, args.icons)
|