#!/usr/bin/env python3 ''' script to build a html file showing flash free for current builds AP_FLAKE8_CLEAN ''' import os import argparse import fnmatch import json from datetime import datetime parser = argparse.ArgumentParser(description='create builds.html for list of builds') parser.add_argument('basedir', default=None, help='base directory (binaries directory)') parser.add_argument('--outfile', default="builds.html", help='output file') build_dirs = ['latest', 'beta', 'beta-4.3', 'stable'] builds = ['Plane', 'Copter', 'Rover', 'Sub', 'Blimp', 'AntennaTracker', 'AP_Periph'] args = parser.parse_args() warning_flash_free = 5000 warning_build_days = 3 LINUX_BINARIES = ["arduplane", "arducopter", "arducopter-heli", "ardurover", "ardusub", "antennatracker"] class APJInfo: def __init__(self, vehicle, board, githash, mtime, flash_free): self.vehicle = vehicle self.board = board self.githash = githash self.mtime = mtime self.flash_free = flash_free self.warning = 0 def firmware_list(basedir): '''list of APJInfo for one directory''' boards = [] for root, subdirs, files in os.walk(basedir): for f in files: if not fnmatch.fnmatch(f, "*.apj") and f not in LINUX_BINARIES: continue fname = os.path.join(root, f) board = os.path.basename(root) vehicle = fname.split('/')[-4] mtime = os.stat(fname).st_mtime if f in LINUX_BINARIES: git_version = os.path.join(root, "git-version.txt") try: line = open(git_version, 'r').readline() githash = line.split()[1][:8] except OSError: githash = "unknown" flash_free = 999999 else: fw_json = json.load(open(fname, "r")) githash = fw_json['git_identity'] flash_free = fw_json.get('flash_free', -1) apjinfo = APJInfo(vehicle, board, githash, mtime, flash_free) boards.append(apjinfo) return boards def write_headers(h): '''write html headers''' h.write(''' Build List

Build List

This is an auto-generated list of current builds allowing us to quickly see how close we are to running out of flash space.
This page was most recently regenerated on %s UTC.

Builds that are coloured red haven't built recently. Builds that are coloured yellow have low flash space remaining.

Click on any column header to sort by that column, or filter by entering a search term in the box above each table.

''' % datetime.now().strftime("%F %k:%M")) def write_footer(h): '''write html footer''' h.write('''
''') def write_table(h, build_type): '''write table for one build type''' boards = [] for build in builds: boards.extend(firmware_list(os.path.join(args.basedir, build, build_type))) max_mtime = 0 for apjinfo in boards: if apjinfo.mtime > max_mtime: max_mtime = apjinfo.mtime for apjinfo in boards: if apjinfo.flash_free < warning_flash_free and not apjinfo.flash_free == -1: apjinfo.warning = 1 if int(apjinfo.mtime) < int(max_mtime)-warning_build_days*86400 and build_type == "latest": apjinfo.warning = 2 boards.sort(key=lambda board: board.warning, reverse=True) try: idxs1 = [i for (i, e) in enumerate(boards) if e.warning == 1] boards[min(idxs1):max(idxs1)] = sorted(boards[min(idxs1):max(idxs1)], key=lambda board: board.flash_free) except ValueError: pass try: idxs2 = [i for (i, e) in enumerate(boards) if e.warning == 2] boards[min(idxs2):max(idxs2)] = sorted(boards[min(idxs2):max(idxs2)], key=lambda board: board.mtime) except ValueError: pass h.write('''

%s builds

''' % (build_type, build_type.capitalize(), build_type, build_type, build_type)) for apjinfo in boards: if apjinfo.warning == 1: h.write('') elif apjinfo.warning == 2: h.write('') else: h.write('') h.write('''\n''' % ( apjinfo.vehicle, apjinfo.vehicle, build_type, apjinfo.board, apjinfo.board, datetime.fromtimestamp(apjinfo.mtime).strftime("%F %k:%M"), apjinfo.githash, apjinfo.githash, apjinfo.flash_free)) h.write('''
VehicleBoardBuild Date git hashFlash Free
%s %s %s %s %u

Return to top

''') h = open(args.outfile, "w") write_headers(h) for t in build_dirs: write_table(h, t) write_footer(h)