|
Packit Service |
48484a |
#!/usr/bin/env python3
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#======================================================================
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
import subprocess, os, glob, datetime, tempfile, argparse
|
|
Packit Service |
48484a |
from xml.etree import ElementTree
|
|
Packit Service |
48484a |
import re
|
|
Packit Service |
48484a |
import argparse
|
|
Packit Service |
48484a |
import shutil
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#======================================================================
|
|
Packit Service |
48484a |
# Function and class definitions
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
def find_best(root, tagname):
|
|
Packit Service |
48484a |
texts = [(len(element.text), element.text) for element in root.findall(tagname) if element.attrib.get("lang") == "en"]
|
|
Packit Service |
48484a |
if texts:
|
|
Packit Service |
48484a |
return sorted(texts)[0][1]
|
|
Packit Service |
48484a |
texts = [(len(element.text), element.text) for element in root.findall(tagname)]
|
|
Packit Service |
48484a |
if texts:
|
|
Packit Service |
48484a |
return sorted(texts)[0][1]
|
|
Packit Service |
48484a |
else:
|
|
Packit Service |
48484a |
return None
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
def print_x(value):
|
|
Packit Service |
48484a |
return ' class="lenslist-highlight lenslist-check">yes' if value else ' class="lenslist-check">no'
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
# class to hold camera information
|
|
Packit Service |
48484a |
class Camera:
|
|
Packit Service |
48484a |
camera_makers = {}
|
|
Packit Service |
48484a |
def __init__(self, element):
|
|
Packit Service |
48484a |
self.maker = find_best(element, "maker")
|
|
Packit Service |
48484a |
self.model = find_best(element, "model")
|
|
Packit Service |
48484a |
variant = find_best(element, "variant");
|
|
Packit Service |
48484a |
if variant:
|
|
Packit Service |
48484a |
self.model = self.model + " " + variant
|
|
Packit Service |
48484a |
self.crop = float(element.find("cropfactor").text)
|
|
Packit Service |
48484a |
self.camera_makers.setdefault(self.maker, set()).add(self.model)
|
|
Packit Service |
48484a |
def __lt__(self, other):
|
|
Packit Service |
48484a |
return (self.maker, self.model) < (other.maker, other.model)
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
# class to hold lens information
|
|
Packit Service |
48484a |
class Lens:
|
|
Packit Service |
48484a |
def __init__(self, element, root, camtype):
|
|
Packit Service |
48484a |
self.maker = find_best(element, "maker")
|
|
Packit Service |
48484a |
self.model = find_best(element, "model")
|
|
Packit Service |
48484a |
if camtype == "compact":
|
|
Packit Service |
48484a |
mount = element.find("mount").text
|
|
Packit Service |
48484a |
for camera in root.findall("camera"):
|
|
Packit Service |
48484a |
if camera.find("mount").text == mount:
|
|
Packit Service |
48484a |
self.maker = find_best(camera, "maker")
|
|
Packit Service |
48484a |
camname = find_best(camera, "model")
|
|
Packit Service |
48484a |
variant = find_best(camera, "variant");
|
|
Packit Service |
48484a |
if variant:
|
|
Packit Service |
48484a |
camname = camname + " " + variant
|
|
Packit Service |
48484a |
break
|
|
Packit Service |
48484a |
self.model = "Fixed lens {}".format(camname)
|
|
Packit Service |
48484a |
try:
|
|
Packit Service |
48484a |
self.crop = float(element.find("cropfactor").text)
|
|
Packit Service |
48484a |
except:
|
|
Packit Service |
48484a |
self.crop = None
|
|
Packit Service |
48484a |
self.distortion = element.find("calibration/distortion") is not None
|
|
Packit Service |
48484a |
self.tca = element.find("calibration/tca") is not None
|
|
Packit Service |
48484a |
self.vignetting = element.find("calibration/vignetting") is not None
|
|
Packit Service |
48484a |
def __lt__(self, other):
|
|
Packit Service |
48484a |
return (self.maker, self.model, self.crop) < (other.maker, other.model, self.crop)
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#======================================================================
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#======================================================================
|
|
Packit Service |
48484a |
# Main routine
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
# set up the commandline parser and define some arguemnts
|
|
Packit Service |
48484a |
parser = argparse.ArgumentParser(description='Create a list of all cameras and lenses in the Lensfun database.')
|
|
Packit Service |
48484a |
parser.add_argument('db_path', metavar='DB_PATH', help='path to the Lensfun database', default='/usr/share/lensfun/', nargs='?')
|
|
Packit Service |
48484a |
parser.add_argument('-g', dest='git', action='store_true', help='use current database from git repository')
|
|
Packit Service |
48484a |
parser.add_argument('-t', dest='table_only', action='store_true', help='pure table/list without surrounding header and description')
|
|
Packit Service |
48484a |
parser.add_argument('-m', dest='markdown', action='store_true', help='output markdown instead of HTML')
|
|
Packit Service |
48484a |
parser.add_argument('-o', dest='outfile', action='store', help='output filename and path', default='./lensfun_coverage.html')
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
cmdline_args = vars(parser.parse_args())
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
# decide wether to get the most up to date database from git or use the locally installed database
|
|
Packit Service |
48484a |
if cmdline_args['git']==True:
|
|
Packit Service |
48484a |
XmlDBPath = os.path.join(tempfile.gettempdir(), "lensfun")
|
|
Packit Service |
48484a |
print("~ Lensfun database is retrieved directly from git")
|
|
Packit Service |
48484a |
if os.path.isdir(XmlDBPath):
|
|
Packit Service |
48484a |
shutil.rmtree(XmlDBPath)
|
|
Packit Service |
48484a |
subprocess.check_output(["git", "clone", "http://git.code.sf.net/p/lensfun/code", XmlDBPath])
|
|
Packit Service |
48484a |
XmlDBPath = os.path.join(XmlDBPath, "data", "db")
|
|
Packit Service |
48484a |
else:
|
|
Packit Service |
48484a |
XmlDBPath = cmdline_args['db_path']
|
|
Packit Service |
48484a |
print("~ Lensfun database is searched in "+XmlDBPath)
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
# parse the database create a list of camera and lens objects
|
|
Packit Service |
48484a |
cameras, lenses = [], []
|
|
Packit Service |
48484a |
for filename in glob.glob(os.path.join(XmlDBPath,"*.xml")):
|
|
Packit Service |
48484a |
root = ElementTree.parse(filename)
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
camtype_search = re.search('.*/([^-]*)-(.*).xml', filename, re.IGNORECASE)
|
|
Packit Service |
48484a |
if camtype_search:
|
|
Packit Service |
48484a |
camtype = camtype_search.group(1)
|
|
Packit Service |
48484a |
else:
|
|
Packit Service |
48484a |
camtype = 'generic'
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
cameras.extend(Camera(camera_element) for camera_element in root.findall("camera"))
|
|
Packit Service |
48484a |
lenses_list = [Lens(lens_element, root, camtype) for lens_element in root.findall("lens")]
|
|
Packit Service |
48484a |
lenses.extend(lens for lens in lenses_list if lens.distortion or lens.tca or lens.vignetting)
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
cameras.sort()
|
|
Packit Service |
48484a |
lenses.sort(key=lambda Lens: Lens.model.lower())
|
|
Packit Service |
48484a |
lenses.sort(key=lambda Lens: Lens.maker.lower())
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
# finally write the table into the output file
|
|
Packit Service |
48484a |
outfile = open(cmdline_args['outfile'], "w")
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
# write HTML table or markdown formatted list
|
|
Packit Service |
48484a |
if cmdline_args['markdown'] == False:
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
# HTML table
|
|
Packit Service |
48484a |
if cmdline_args['table_only'] == False:
|
|
Packit Service |
48484a |
outfile.write("<html><head><title>Lensfun's coverage</title></head><body>Lensfun coverageLenses (count: {})"
|
|
Packit Service |
48484a |
"This table was generated on {} from current Lensfun sources. Your Lensfun version may be older, resulting in "
|
|
Packit Service |
48484a |
"less coverage. If your lens is not included, see
|
|
Packit Service |
48484a |
"Lens calibration for Lensfun\n".format(
|
|
Packit Service |
48484a |
len(lenses), datetime.date.today()))
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
outfile.write(""manufacturer | model | crop | dist. | TCA |
---|
|
|
Packit Service |
48484a |
"vign.\n")
|
|
Packit Service |
48484a |
number_of_makers = 0
|
|
Packit Service |
48484a |
previous_maker = None
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
for lens in lenses:
|
|
Packit Service |
48484a |
if lens.maker.lower() != previous_maker:
|
|
Packit Service |
48484a |
number_of_makers += 1
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
outfile.write("""<tr{}>{}{}{}<td{}</td><td{}</td><td{}</td>\n""".format(
|
|
Packit Service |
48484a |
' class="lenslist-bg1"' if number_of_makers % 2 else ' class="lenslist-bg2"',
|
|
Packit Service |
48484a |
lens.maker if lens.maker.lower() != previous_maker else "", lens.model, lens.crop or "?",
|
|
Packit Service |
48484a |
print_x(lens.distortion), print_x(lens.tca), print_x(lens.vignetting)))
|
|
Packit Service |
48484a |
previous_maker = lens.maker.lower()
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
outfile.write("CamerasNote that new camera models can be added very easily. "
|
|
Packit Service |
48484a |
"Contact the Lensfun maintainers for this.")
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
for maker, cameras in sorted(Camera.camera_makers.items()):
|
|
Packit Service |
48484a |
outfile.write("{}: {} ".format(maker, ", ".join(sorted(cameras))))
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if cmdline_args['table_only'] == False:
|
|
Packit Service |
48484a |
outfile.write("</body></html>")
|
|
Packit Service |
48484a |
else:
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
#----------------------------------------------------------------------
|
|
Packit Service |
48484a |
# Markdown list
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if cmdline_args['table_only'] == False:
|
|
Packit Service |
48484a |
outfile.write("= Lensfun's coverage = \n\n == Lenses (count: {}) ==\n\n"
|
|
Packit Service |
48484a |
"This list was generated on {} from current Lensfun sources. Your Lensfun version may be older, resulting in "
|
|
Packit Service |
48484a |
"less coverage. \nIf your lens is not included, see \n\n* Upload calibration pictures\n"
|
|
Packit Service |
48484a |
"* Lens calibration for Lensfun\n\n".format(
|
|
Packit Service |
48484a |
len(lenses), datetime.date.today()))
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
number_of_makers = 0
|
|
Packit Service |
48484a |
previous_maker = None
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
for lens in lenses:
|
|
Packit Service |
48484a |
if lens.maker.lower() != previous_maker:
|
|
Packit Service |
48484a |
number_of_makers += 1
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
if lens.maker.lower() != previous_maker:
|
|
Packit Service |
48484a |
outfile.write("\n== {} ==\n\n".format(lens.maker))
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
outfile.write("* {} ({}, {}/{}/{})\n".format(lens.model, lens.crop or "?",
|
|
Packit Service |
48484a |
"D" if lens.distortion else "-",
|
|
Packit Service |
48484a |
"T" if lens.tca else "-",
|
|
Packit Service |
48484a |
"V" if lens.vignetting else "-"))
|
|
Packit Service |
48484a |
previous_maker = lens.maker.lower()
|
|
Packit Service |
48484a |
|
|
Packit Service |
48484a |
outfile.close()
|
|
Packit Service |
48484a |
print("~ List of lenses was written to "+cmdline_args['outfile'])
|