diff options
author | 2019-12-16 01:46:47 +1100 | |
---|---|---|
committer | 2019-12-16 01:46:47 +1100 | |
commit | f43e9dbaa28ca8241b9b27d5dbbb5a6afd96553e (patch) | |
tree | e7e56370bdc98bf3cdf737ad7ed745361fa740e1 /scripts/minimaws | |
parent | b99eb3774e657f4967f4676eba9e9593cbe81ff6 (diff) |
minimaws: add software list support to web-based romident
(nw) also removed unused member that was breaking clang builds
Diffstat (limited to 'scripts/minimaws')
-rw-r--r-- | scripts/minimaws/lib/assets/romident.js | 213 | ||||
-rw-r--r-- | scripts/minimaws/lib/dbaccess.py | 8 | ||||
-rw-r--r-- | scripts/minimaws/lib/htmltmpl.py | 1 | ||||
-rw-r--r-- | scripts/minimaws/lib/wsgiserve.py | 10 |
4 files changed, 214 insertions, 18 deletions
diff --git a/scripts/minimaws/lib/assets/romident.js b/scripts/minimaws/lib/assets/romident.js index 20d5d2c2ba6..0dca192094e 100644 --- a/scripts/minimaws/lib/assets/romident.js +++ b/scripts/minimaws/lib/assets/romident.js @@ -5,6 +5,8 @@ var matched_names = new Array(); var unmatched_names = new Array(); var dump_info = Object.create(null); var machine_info = Object.create(null); +var softwarelist_info = Object.create(null); +var software_info = Object.create(null); var crc_table = new Uint32Array(256); for (var i = 0; i < 256; i++) @@ -97,6 +99,34 @@ function add_matches(table, names, matches) } +function add_software_matches(table, names, part, matches) +{ + for (var i = 0; i < names.length; i++) + { + var row = table.appendChild(document.createElement('tr')); + var name = row.appendChild(document.createElement('th')); + name.textContent = names[i]; + if (matches !== null) + { + name.setAttribute('rowspan', matches.length); + row.appendChild(document.createElement('td')).textContent = part; + row.appendChild(document.createElement('td')).textContent = matches[0].name; + var bad = row.appendChild(document.createElement('td')); + if (matches[0].bad) + bad.textContent = 'BAD'; + for (var j = 1; j < matches.length; j++) + { + row = table.appendChild(document.createElement('tr')); + row.appendChild(document.createElement('td')).textContent = matches[j].name; + bad = row.appendChild(document.createElement('td')); + if (matches[j].bad) + bad.textContent = 'BAD'; + } + } + } +} + + function add_unmatched(names, crc, sha1) { var table; @@ -159,6 +189,53 @@ function get_machine_table(shortname, description) } +function get_softwarelist_div(shortname, description) +{ + if (Object.hasOwnProperty.call(softwarelist_info, shortname)) + { + return softwarelist_info[shortname]; + } + else + { + software_info[shortname] = Object.create(null) + var div = document.getElementById('div-software'); + if (!div.hasChildNodes()) + { + var heading = div.appendChild(document.createElement('h2')); + heading.textContent = 'Software'; + } + div = div.appendChild(document.createElement('div')); + var heading = div.appendChild(document.createElement('h3')); + var link = heading.appendChild(document.createElement('a')); + link.textContent = description; + link.setAttribute('href', appurl + 'softwarelist/' + encodeURIComponent(shortname)); + softwarelist_info[shortname] = div; + return div; + } +} + + +function get_software_table(softwarelist, shortname, description) +{ + if (Object.hasOwnProperty.call(software_info, softwarelist) && Object.hasOwnProperty.call(software_info[softwarelist], shortname)) + { + return software_info[softwarelist][shortname]; + } + else + { + var div = softwarelist_info[softwarelist]; + var heading = div.appendChild(document.createElement('h4')); + var link = heading.appendChild(document.createElement('a')); + link.textContent = description; + link.setAttribute('href', appurl + 'softwarelist/' + encodeURIComponent(softwarelist) + '/' + encodeURIComponent(shortname)); + var table = div.appendChild(document.createElement('table')); + software_info[softwarelist][shortname] = table; + add_software_matches(table, matched_names, null, null); + return table; + } +} + + function request_dumps(name, group, crc, sha1, url, progress) { var req = new XMLHttpRequest(); @@ -169,34 +246,123 @@ function request_dumps(name, group, crc, sha1, url, progress) if (req.status == 200) { var machines = Object.create(null); + var software = Object.create(null); var matched = Object.keys(req.response.machines); + var softwarelists = Object.keys(req.response.software); + if (matched.length > 0) { Object.keys(machine_info).forEach( function (shortname) { - var table = machine_info[shortname]; + var machine_table = machine_info[shortname]; if (Object.hasOwnProperty.call(req.response.machines, shortname)) { machines[shortname] = req.response.machines[shortname].matches; - add_matches(table, group.names, req.response.machines[shortname].matches); + add_matches(machine_table, group.names, req.response.machines[shortname].matches); } else { - add_matches(table, group.names, null); + add_matches(machine_table, group.names, null); } }); + if (softwarelists.length <= 0) + { + Object.keys(software_info).forEach( + function (listname) + { + Object.keys(software_info[listname]).forEach( + function (softwarename) + { + var software_table = software_info[listname][softwarename]; + add_software_matches(software_table, group.names, null, null); + }); + }); + } matched.forEach( function (shortname) { if (!Object.hasOwnProperty.call(machine_info, shortname)) { - var info = req.response.machines[shortname]; - var table = get_machine_table(shortname, info.description); + var machine_details = req.response.machines[shortname]; + var machine_table = get_machine_table(shortname, machine_details.description); machines[shortname] = req.response.machines[shortname].matches; - add_matches(table, group.names, info.matches); + add_matches(machine_table, group.names, machine_details.matches); } }); + } + + if (softwarelists.length > 0) + { + if (matched.length <= 0) + { + Object.keys(machine_info).forEach( + function (shortname) + { + var machine_table = machine_info[shortname]; + add_matches(machine_table, group.names, null); + }); + } + Object.keys(software_info).forEach( + function (listname) + { + var haslist = Object.hasOwnProperty.call(req.response.software, listname); + Object.keys(software_info[listname]).forEach( + function (softwarename) + { + var software_table = software_info[listname][softwarename]; + if (haslist && Object.hasOwnProperty.call(req.response.software[listname].software, softwarename)) + { + if (!Object.hasOwnProperty.call(software, listname)) + software[listname] = Object.create(null); + if (!Object.hasOwnProperty.call(software[listname], softwarename)) + software[listname][softwarename] = Object.create(null); + var software_details = req.response.software[listname].software[softwarename]; + Object.keys(software_details.parts).forEach( + function (partname) + { + var matches = software_details.parts[partname].matches; + software[listname][softwarename][partname] = matches; + add_software_matches(software_table, group.names, partname, matches); + }); + } + else + { + add_software_matches(software_table, group.names, null, null); + } + }); + }); + softwarelists.forEach( + function (listname) + { + var haslist = Object.hasOwnProperty.call(software_info, listname); + var softwarelist_details = req.response.software[listname]; + var softwarelist_div = get_softwarelist_div(listname, softwarelist_details.description); + Object.keys(softwarelist_details.software).forEach( + function (softwarename) + { + if (!haslist || !Object.hasOwnProperty.call(software_info[listname], softwarename)) + { + if (!Object.hasOwnProperty.call(software, listname)) + software[listname] = Object.create(null); + if (!Object.hasOwnProperty.call(software[listname], softwarename)) + software[listname][softwarename] = Object.create(null); + var software_details = softwarelist_details.software[softwarename]; + var software_table = get_software_table(listname, softwarename, software_details.description); + Object.keys(software_details.parts).forEach( + function (partname) + { + var matches = software_details.parts[partname].matches; + software[listname][softwarename][partname] = matches; + add_software_matches(software_table, group.names, partname, matches); + }); + } + }); + }); + } + + if ((matched.length > 0) | (softwarelists.length > 0)) + { for (var i = 0; i < group.names.length; i++) matched_names.push(group.names[i]); } @@ -204,7 +370,9 @@ function request_dumps(name, group, crc, sha1, url, progress) { add_unmatched(group.names, crc, sha1); } + group.machines = machines; + group.software = software; progress.parentNode.removeChild(progress); } else @@ -247,18 +415,43 @@ function add_name(group, name, crc, sha1) if (group.hasOwnProperty('machines')) { var machines = group.machines; + var software = group.software; var names = [ name ]; - if (Object.keys(machines).length > 0) + if ((Object.keys(machines).length > 0) || (Object.keys(software).length > 0)) { Object.keys(machine_info).forEach( function (shortname) { - var table = machine_info[shortname]; + var machine_table = machine_info[shortname]; if (Object.hasOwnProperty.call(machines, shortname)) - add_matches(table, names, machines[shortname]); + add_matches(machine_table, names, machines[shortname]); else - add_matches(table, names, null); + add_matches(machine_table, names, null); }); + + Object.keys(software_info).forEach( + function (listname) + { + var haslist = Object.hasOwnProperty.call(software, listname); + Object.keys(software_info[listname]).forEach( + function (softwarename) + { + var software_table = software_info[listname][softwarename]; + if (haslist && Object.hasOwnProperty.call(software[listname], softwarename)) + { + Object.keys(software[listname][softwarename]).forEach( + function (partname) + { + add_software_matches(software_table, names, partname, software[listname][softwarename][partname]); + }); + } + else + { + add_software_matches(software_table, names, null, null); + } + }); + }); + matched_names.push(name); } else diff --git a/scripts/minimaws/lib/dbaccess.py b/scripts/minimaws/lib/dbaccess.py index 80bfabb92a5..68bdc98901b 100644 --- a/scripts/minimaws/lib/dbaccess.py +++ b/scripts/minimaws/lib/dbaccess.py @@ -716,15 +716,15 @@ class QueryCursor(object): def get_softwarelist_software(self, id, pattern): if pattern is not None: return self.dbcurs.execute( - 'SELECT software.shortname AS shortname, software.description AS description, software.year AS year, software.publisher AS publisher, software.supported AS supported, COUNT(*) AS parts ' \ - 'FROM software JOIN softwarepart ON software.id = softwarepart.software ' \ + 'SELECT software.shortname AS shortname, software.description AS description, software.year AS year, software.publisher AS publisher, software.supported AS supported, COUNT(DISTINCT softwarepart.id) AS parts, COUNT(softwareromdump.rom) + COUNT(softwarediskdump.disk) AS baddumps ' \ + 'FROM software JOIN softwarepart ON software.id = softwarepart.software LEFT JOIN softwareromdump ON softwarepart.id = softwareromdump.part AND softwareromdump.bad = 1 LEFT JOIN softwarediskdump ON softwarepart.id = softwarediskdump.part AND softwarediskdump.bad = 1 ' \ 'WHERE software.softwarelist = ? AND software.shortname GLOB ? ' \ 'GROUP BY software.id', (id, pattern)) else: return self.dbcurs.execute( - 'SELECT software.shortname AS shortname, software.description AS description, software.year AS year, software.publisher AS publisher, software.supported AS supported, COUNT(*) AS parts ' \ - 'FROM software JOIN softwarepart ON software.id = softwarepart.software ' \ + 'SELECT software.shortname AS shortname, software.description AS description, software.year AS year, software.publisher AS publisher, software.supported AS supported, COUNT(DISTINCT softwarepart.id) AS parts, COUNT(softwareromdump.rom) + COUNT(softwarediskdump.disk) AS baddumps ' \ + 'FROM software JOIN softwarepart ON software.id = softwarepart.software LEFT JOIN softwareromdump ON softwarepart.id = softwareromdump.part AND softwareromdump.bad = 1 LEFT JOIN softwarediskdump ON softwarepart.id = softwarediskdump.part AND softwarediskdump.bad = 1 ' \ 'WHERE software.softwarelist = ? ' \ 'GROUP BY software.id', (id, )) diff --git a/scripts/minimaws/lib/htmltmpl.py b/scripts/minimaws/lib/htmltmpl.py index 5ba004a03b2..b7354ae403a 100644 --- a/scripts/minimaws/lib/htmltmpl.py +++ b/scripts/minimaws/lib/htmltmpl.py @@ -241,6 +241,7 @@ SOFTWARELIST_ROW = string.Template( ' <td>${publisher}</td>\n' \ ' <td>${supported}</td>\n' \ ' <td style="text-align: right">${parts}</td>\n' \ + ' <td style="text-align: right">${baddumps}</td>\n' \ ' </tr>\n') diff --git a/scripts/minimaws/lib/wsgiserve.py b/scripts/minimaws/lib/wsgiserve.py index cbf4888e511..2a6a2e35325 100644 --- a/scripts/minimaws/lib/wsgiserve.py +++ b/scripts/minimaws/lib/wsgiserve.py @@ -47,7 +47,7 @@ class HandlerBase(object): self.start_response = start_response def error_page(self, code): - yield htmltmpl.ERROR_PAGE.substitute(code=cgi.escape('%d' % code), message=cgi.escape(self.STATUS_MESSAGE[code])).encode('utf-8') + yield htmltmpl.ERROR_PAGE.substitute(code=cgi.escape('%d' % (code, )), message=cgi.escape(self.STATUS_MESSAGE[code])).encode('utf-8') class ErrorPageHandler(HandlerBase): @@ -371,7 +371,7 @@ class SourceFileHandler(QueryPageHandler): for filename, machines in self.dbcurs.get_sourcefiles(pattern): yield htmltmpl.SOURCEFILE_LIST_ROW.substitute( sourcefile=self.linked_title(filename, True), - machines=cgi.escape('%d' % machines)).encode('utf-8') + machines=cgi.escape('%d' % (machines, ))).encode('utf-8') yield ' </tbody>\n</table>\n<script>make_table_sortable(document.getElementById("tbl-sourcefiles"));</script>\n</body>\n</html>\n'.encode('utf-8') def sourcefile_page(self, id): @@ -486,7 +486,7 @@ class SoftwareListHandler(QueryPageHandler): href=self.softwarelist_href(shortname), shortname=cgi.escape(shortname), description=cgi.escape(description), - total=cgi.escape('%d' % total), + total=cgi.escape('%d' % (total, )), supported=cgi.escape('%.1f%%' % (supported * 100.0 / (total or 1), )), partiallysupported=cgi.escape('%.1f%%' % (partiallysupported * 100.0 / (total or 1), )), unsupported=cgi.escape('%.1f%%' % (unsupported * 100.0 / (total or 1), ))).encode('utf-8') @@ -525,6 +525,7 @@ class SoftwareListHandler(QueryPageHandler): ' <th>Publisher</th>\n' \ ' <th>Supported</th>\n' \ ' <th class="numeric">Parts</th>\n' \ + ' <th class="numeric">Bad dumps</th>\n' \ ' </tr>\n' \ ' </thead>\n' \ ' <tbody>\n'.encode('utf-8') @@ -573,7 +574,8 @@ class SoftwareListHandler(QueryPageHandler): year=cgi.escape(software_info['year']), publisher=cgi.escape(software_info['publisher']), supported=cgi.escape('Yes' if software_info['supported'] == 0 else 'Partial' if software_info['supported'] == 1 else 'No'), - parts=cgi.escape('%d' % software_info['parts'])).encode('utf-8') + parts=cgi.escape('%d' % (software_info['parts'], )), + baddumps=cgi.escape('%d' % (software_info['baddumps'], ))).encode('utf-8') class RomIdentHandler(QueryPageHandler): |