#! /usr/bin/env python3 #=============================== # # html # # 2019/02/18 Kuninori Morimoto #=============================== import textile import sys import os import re import base import find import view import datetime #==================================== # # html # #==================================== class html(base.base): __head = 0 __noclose = ["input", "frame", "link", "br", ] #-------------------- # option #-------------------- def option(self, dic): if (dic): self.dic.update(dic) #-------------------- # __init__ #-------------------- def __init__(self, mark, dic = None): super().__init__() self.dic = {} self.mark = mark self.option(dic) self.txt = "" #-------------------- # open #-------------------- def open(self, ret = 0): self.txt = "" if (ret): for i in range(html.__head): self.txt += "\t" self.txt += "<{}".format(self.mark) for d in self.dic: self.txt += " {}=\"{}\"".format(d, self.dic[d]) self.txt += ">" html.__head += 1 #-------------------- # close #-------------------- def close(self, ret = 0): html.__head -= 1 # no end-mark if (self.mark in html.__noclose): return if (ret): for i in range(html.__head): self.txt += "\t" self.txt += "".format(self.mark) #-------------------- # text #-------------------- def text(self, txt = ""): self.open() self.txt += txt self.close() return self.txt #-------------------- # print #-------------------- def print(self, txt = ""): self.open(1) self.txt += txt self.close(0) print(self.txt) #-------------------- # for with #-------------------- def __enter__(self): self.open(1) print(self.txt) self.txt = "" return self def __exit__(self, exception_type, exception_value, traceback): self.close(1) print(self.txt) self.txt = "" #==================================== # # periject_html # #==================================== class periject_html(base.base): def __init__(self): super().__init__() self.git = self.config("git-linux") def relpath(self, path, frm): return os.path.relpath("{}/{}".format(self.top(), path), frm) def relpath_y2h(self, file, frm): return os.path.relpath(file.replace("yaml", "html").replace("projects", "html"), frm) def git_title(self, id): return self.run("git -C {} log -1 {} --format=%s".format(self.git, id)) def bsp_url(self, id): return "https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas-bsp.git/commit/?id={}".format(id) def upstream_url(self, id): return "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id={}".format(id) #-------------------- # print_css #-------------------- def print_css(self, dir): html("link", {"rel":"stylesheet", "type":"text/css", "href":self.relpath("scripts/css", dir)}).print() #-------------------- # index #-------------------- def index(self): # | | | # |menu|body| # | | | with html("frameset", {"cols":"{},*".format(self.config("html-default-cols"))}): html("frame", {"src":"./html/menu.html", "name":"menu"}).print() html("frame", {"src":"./html/subindex.html", "name":"body"}).print() #-------------------- # summary #-------------------- def subindex(self): # ------- # summary # ------- # body # ------- with html("frameset", {"rows":"{},*".format(self.config("html-default-rows"))}): html("frame", {"src":"./summary.html", "name":"summary"}).print() html("frame", {"src":"./body.html", "name":"subbody"}).print() #-------------------- # summary #-------------------- def ___summary(self, status, dir, files): if (not len(files)): return html("h3").print(html("a", {"target":"summary", "href":self.relpath("html/{}.html".format(status), dir)}).text(status)) with html("table", {"border":"1"}): with html("tr"): html("th").print("file") html("th").print("team") html("th").print("assignee") html("th").print("title") files.sort() for file in files: v = view.viewer([file]) v.set_data(file) subbody = html("a", {"target":"subbody"}) summary = html("a", {"target":"summary"}) with html("tr"): subbody.option({"href":self.relpath_y2h(file, dir)}) html("td").print(subbody.text(os.path.basename(file).replace(".yaml", ""))) team = v.get_data("team") summary.option({"href":self.relpath("html/{}.html".format(team), dir)}) html("td").print(summary.text(team)) assignee = v.get_data("assignee") if (not len(assignee)): assignee = "NoAssignee" summary.option({"href":self.relpath("html/{}.html".format(assignee), dir)}) html("td").print(summary.text(assignee)) html("td").print(v.get_data("title")) #-------------------- # summary #-------------------- def __summary(self, title, dir, files): # ------- # summary # ------- # # ------- if (title): html("h2").print(title) new = [] active = [] blocked = [] paused = [] done = [] abandoned = [] for file in files: v = view.viewer([file]) v.set_data(file) status = v.get_data("status") if (status == "New"): new.append(file) elif (status == "Active"): active.append(file) elif (status == "Blocked"): blocked.append(file) elif (status == "Paused"): paused.append(file) elif (status == "Done"): done.append(file) else: abandoned.append(file) self.___summary("New", dir, new) self.___summary("Active", dir, active) self.___summary("Blocked", dir, blocked) self.___summary("Paused", dir, paused) self.___summary("Done", dir, done) self.___summary("Abandoned", dir, abandoned) #-------------------- # summary #-------------------- def summary(self, argv): dir = os.path.normpath(argv[0]) # ------- # summary # ------- # # ------- self.print_css(dir) with html("body"): self.__summary(dir, self.top() + "/" + dir, find.find([dir]).get()) #-------------------- # menu_wiki #-------------------- def menu_wiki(self): html("a", {"target":"_blank", "href":"./wiki/top.html"}).print("Peri Peri Wiki") #-------------------- # menu_folder #-------------------- def menu_folder(self, current): folders = self.runl("cd {}; ls -F | grep /".format(current)) path = current.replace("./projects", ".") link = html("a", {"target":"summary", "href":"{}/summary.html".format(path)}) html("li").print(link.text(os.path.basename(current))) if (not folders): return with html("ul"): for folder in folders: dir = os.path.basename(folder) self.menu_folder("{}/{}".format(current, folder[:-1])) #-------------------- # menu_assignee #-------------------- def menu_assignee(self): # from project.schema.yaml with html("ul"): for assignee in ['BSP', 'Geert', 'Jacopo', 'Kaneko', 'Kieran', 'Laurent', 'Magnus', 'Marek', 'Morimoto', 'Niklas', 'Shimoda', 'Simon', 'Ulrich', 'Wolfram', "NoAssignee"]: html("li").print(html("a", {"target":"summary", "href":"./{}.html".format(assignee)}).text(assignee)) #-------------------- # menu_status #-------------------- def menu_status(self): # from project.schema.yaml with html("ul"): for status in ['New', 'Active', 'Blocked', 'Paused', 'Done', 'Abandoned']: html("li").print(html("a", {"target":"summary", "href":"./{}.html".format(status)}).text(status)) #-------------------- # menu_team #-------------------- def menu_team(self): # from project.schema.yaml with html("ul"): for status in ['Core', 'IO', 'MM']: html("li").print(html("a", {"target":"summary", "href":"./{}.html".format(status)}).text(status)) #-------------------- # menu_bsp #-------------------- def menu_bsp(self): html("a", {"target":"summary", "href":"./bsp.html"}).print("BSP patch list") #-------------------- # menu #-------------------- def menu(self): self.print_css("html") with html("body"): html("h1").print("Wiki") self.menu_wiki() html("h1").print("Folder") with html("ul"): self.menu_folder("./projects") html("h1").print("Assignee") self.menu_assignee() html("h1").print("Status") self.menu_status() html("h1").print("Team") self.menu_team() html("h1").print("BSP") self.menu_bsp() html("div").print("

update
{}".format( datetime.datetime.now().strftime("%Y/%m/%d %H:%M"))) #-------------------- # wiki #-------------------- def wiki(self, argv): with open(argv[0], "r") as f: text = f.read() # parse http[s] text = re.sub(r'(\s+)http://(.*)(\s+)', r'\1"http://\2":http://\2\3', text) text = re.sub(r'(\s+)https://(.*)(\s+)', r'\1"https://\2":https://\2\3', text) # parse img text = re.sub(r'!(\S+)!', r'!../../wiki/\1!', text) # [[foo bar]] # -> "foo bar":foo_bar.html while 1: hit = re.search(r'\[\[.*\]\]', text) if (not hit): break; link = text[hit.start()+2:hit.end()-2] link = "\"{}\":{}.html".format(link, re.sub(r' ', r'_', link)) text = text[:hit.start()] + link + text[hit.end():] # textile self.print_css("html/wiki") with html("body"): print(textile.textile(text)) #-------------------- # body #-------------------- def body(self): self.print_css("html") with html("body"): html("div").print("select tasks from menu") #-------------------- # task_status #-------------------- def task_status(self, v): dir = os.path.dirname(v.file) assignee = v.get_data("assignee") status = v.get_data("status") team = v.get_data("team") if (not len(assignee)): assignee = "NoAssignee" with html("table", {"border":"1"}): with html("tr"): html("th").print("file") html("th").print("status") html("th").print("team") html("th").print("assignee") html("th").print("key") with html("tr"): html("td").print(os.path.relpath(v.file, self.top())) html("td").print(html("a", {"target":"summary", "href":self.relpath("html/{}.html".format(status), dir)}).text(status)) html("td").print(html("a", {"target":"summary", "href":self.relpath("html/{}.html".format(team), dir)}).text(team)) html("td").print(html("a", {"target":"summary", "href":self.relpath("html/{}.html".format(assignee), dir)}).text(assignee)) html("td").print(v.get_data("key")) #-------------------- # _task_relation #-------------------- def _task_relation(self, relationship, v, item): current_dir = os.path.dirname(v.file) related_file = v.get_related_file(relationship[item]) if (not os.path.exists(related_file)): with html("tr"): html("td").print(item) html("td").print("Unknown({})".format(related_file)) return rv = view.viewer([related_file]) rv.set_data(related_file) with html("tr"): html("td").print(item) html("td").print(html("a", {"href": self.relpath_y2h(related_file, current_dir)}).text(rv.get_data("title"))) #-------------------- # task_relation #-------------------- def task_relation(self, v): relationships = v.get_data("relationships") if (not relationships): return current_dir = os.path.dirname(v.file) with html("table", {"border":"1"}): for relationship in relationships: if ("parent" in relationship): self._task_relation(relationship, v, "parent") if ("depends" in relationship): self._task_relation(relationship, v, "depends") if ("blocks" in relationship): self._task_relation(relationship, v, "blocks") #-------------------- # task_head #-------------------- def task_head(self, v): with html("table"): with html("tr"): with html("td"): self.task_status(v) with html("td"): self.task_relation(v) #-------------------- # task_commit_bsp #-------------------- def task_commit_bsp(self, bsp_list): cnt = 0 with html("ul"): for bsp in bsp_list: cnt += 1 html("li").print(html("a", {"href":self.bsp_url(bsp), "target":"subbody"}).text(self.git_title(bsp))) return cnt #-------------------- # __task_commit_upstream #-------------------- def __task_commit_upstream(self, v, upstream, item): if (not item in upstream): return 0 commit = upstream[item] with html("tr"): html("th").print(item) html("td").print(html("a", {"href":self.upstream_url(commit), "target":"subbody"}).text(self.git_title(commit))) return 1 #-------------------- # task_commit_upstream #-------------------- def task_commit_upstream(self, v): done = 0 cnt = 0 status = v.get_data("status") if (status == "Done" or status == "Abandoned"): done = 1 upstream = v.get_data("upstream") if (not len(upstream)): if (done): html("p").print("ignored") cnt = 1 else: with html("table"): for up in upstream: cnt += self.__task_commit_upstream(v, up, "torvalds") for up in upstream: cnt += self.__task_commit_upstream(v, up, "next") return (done, cnt) #-------------------- # task_commit #-------------------- def task_commit(self, v): bsp = v.get_data("bsp-commits") with html("table", {"border":"1"}): with html("tr"): if (bsp): html("th").print("BSP") html("th").print("upstream") with html("tr"): if (bsp): with html("td"): self.task_commit_bsp(bsp) with html("td"): self.task_commit_upstream(v) #-------------------- # task_comment #-------------------- def task_comment(self, v): comments = v.get_data("comments") if (not comments): return with html("ul"): for comment in comments: str = re.search(r'(https?://[\w/:%#\$&\?\(\)~\.=\+\-]+)', comment) if (str): a = html("a", {"href":str.group(), "target":"_blank"}) comment = str.string[:str.start()] + a.text(str.group()) + str.string[str.end():] html("li").print(comment) #-------------------- # task #-------------------- def task(self, argv): v = view.viewer([argv[0]]) v.set_data(argv[0]) dir = os.path.dirname(argv[0].replace("projects", "html")) self.print_css(dir) with html("body"): html("h2").print(v.get_data("title")) self.task_head(v) self.task_commit(v) self.task_comment(v) #-------------------- # member #-------------------- def member(self, argv): mem = argv.pop(0) dir = "{}/html".format(self.top()) self.print_css(dir) with html("body"): self.__summary(mem, dir, argv) #-------------------- # status #-------------------- def status(self, argv): argv.pop(0) dir = "{}/html".format(self.top()) self.print_css(dir) with html("body"): self.__summary(None, dir, argv) #-------------------- # team #-------------------- def team(self, argv): team = argv.pop(0) dir = "{}/html".format(self.top()) self.print_css(dir) with html("body"): self.__summary(team, dir, argv) #-------------------- # bsp #-------------------- def bsp(self, argv): a = html("a", {"target":"subbody"}) cnt_bsp = 0 cnt_up = 0 cnt_upd = 0 cnt_all = 0 cnt_done= 0 tmp = 0 self.print_css("html") with html("body"): html("h2").print("BSP patch list") with html("table", {"border":"1"}): with html("tr"): html("th").print("file") html("th").print("BSP") html("th").print("upstream") for file in argv: v = view.viewer([file]) v.set_data(file) bsp = v.get_data("bsp-commits") if (not len(bsp)): continue cnt_all += 1 with html("tr"): a.option({"href": self.relpath_y2h(file, "{}/html".format(self.top()))}) html("th").print("{}
({})".format( a.text(os.path.basename(file).replace(".yaml", "")), v.get_data("status"))) with html("td"): tmp = self.task_commit_bsp(bsp) cnt_bsp += tmp with html("td"): (done, cnt) = self.task_commit_upstream(v) if (cnt): cnt_up += tmp if (done): cnt_done += 1 cnt_upd += tmp html("p").print("bsp:{}/upstream:{} = {:.1f}%".format(cnt_bsp, cnt_up, cnt_up * 100 /cnt_bsp)) html("p").print("task:{}/done:{} = {:.1f}% (bsp:{}/upstream:{} = {:.1f}%)".format(cnt_all, cnt_done, cnt_done * 100 /cnt_all, cnt_bsp, cnt_upd, cnt_upd * 100 /cnt_bsp)) #-------------------- # print #-------------------- def print(self, argv): # remove this script argv.pop(0) cmd = sys.argv.pop(0) with html("html"): if (cmd == "index"): # html.py index self.index() elif(cmd == "subindex"): # html.py subindex self.subindex() elif (cmd == "body"): # html.py body self.body() elif (cmd == "menu"): # html.py menu self.menu() elif (cmd == "summary"): # html.py summary projects/linux/io self.summary(sys.argv) elif (cmd == "task"): # html.py task projects/linux/io/xxx.yaml self.task(sys.argv) elif (cmd == "member"): # ./script/find.py -a Wolfram | xargs ./script/html.py menber Wolfram self.member(sys.argv) elif (cmd == "status"): # ./script/find.py -s Active | xargs ./script/html.py status Active self.status(sys.argv) elif (cmd == "team"): # ./script/find.py -t Core | xargs ./script/html.py status Core self.team(sys.argv) elif (cmd == "bsp"): # ./script/find.py -a | xargs ./script/html.py bsp self.bsp(sys.argv) elif (cmd == "wiki"): self.wiki(sys.argv) #==================================== # # As command # #==================================== if __name__=='__main__': periject_html().print(sys.argv)