def makePersonIndex(self, p, path): dc = ft_otherfiles.DirCat(self.pf.root) htmlText = [ MOTW, '<html><head>\n', '<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">\n' ] ftBuilderRoot = fwdslash(relpath(os.path.join(self.pf.root,'..','ftb','dist'), path)) htmlText.append('<script defer type="text/javascript" src="%s/js/ftb.js"></script>\n' % (ftBuilderRoot)) htmlText.append('<link rel="stylesheet" href="%s/css/ftb.css" type="text/css" />\n' % (ftBuilderRoot)) htmlText.append('<title>%s</title></head><body>\n' % (p.name())) htmlText.append("<h2>Vital Records</h2>\n") htmlText.append('<table style="text-align: left; width: 700px;" border="0" cellpadding="2" cellspacing="2"><tbody>\n') self.personName(p, htmlText) self.personBirth(p, htmlText) self.personDeath(p, htmlText) self.personMf(p, 'Father', htmlText) self.personMf(p, 'Mother', htmlText) self.personMarriages(p, htmlText) htmlText.append('</tbody></table>\n') self.personChildren(p, htmlText) census = p.getCensusSearches() other = p.getOtherNotes() if census or other: htmlText.append("<h2>Secondary Records</h2><ul>\n") if census: htmlText.append('<li><a href="%s">Census Searches</a></li>\n' % (fwdslash(relpath(census, p.path)))) if other: htmlText.append('<li><a href="%s">Other Notes</a><br></li>\n' % (fwdslash(relpath(other, p.path)))) htmlText.append('</ul>\n') numOtherFiles, otherFilesHtml = dc.cat(path) if (numOtherFiles > 0): htmlText.append("<h3>Other Files</h3>\n") htmlText.append(otherFilesHtml) #htmlText.append('<br><br>\n') htmlText.append('</body></html>\n') with open(os.path.join(path, PERSON_IDX_), "w") as fs: fs.write("".join(htmlText))
def personMarriages(self, p, htmlText): if (p.marriageVrs is None): return spouses = p.spouses() if len(spouses) > 0: htmlText.append('<tr><td><br></td></tr>') multipleMarriages = (len(spouses) > 1) num = 1 for s, mr in zip(spouses, p.marriageVrs): if s.isPrivate(): continue if multipleMarriages: t = "Marriage %d" % (num) else: t = "Marriage" if mr is None: url = t + ":" else: searchDoc = fwdslash(relpath(mr.getFile(), p.path)) url = '<a href="%s">%s</a>:' % (searchDoc, t) htmlText.append('<tr><td style=" font-style: italic;">%s</td>' % (url)) htmlText.append('<td>') if mr is not None and mr.date is not None: htmlText.append('%s ' % (mr.date)) if s.fake: url = s.name() else: sidx = os.path.join(s.path, PERSON_IDX) sidx = urllib.parse.quote(fwdslash(relpath(sidx, p.path))) url = '<a href="%s" target="_top">%s</a>' % (sidx, s.name()) htmlText.append('to %s' % url) if mr is not None and mr.where is not None: htmlText.append(' in %s' % (mr.where)) htmlText.append('</td>') if mr is not None: cert = mr.getCert() if cert is not None: url = '<a href="%s">certificate</a>' % (fwdslash(relpath(cert, p.path))) htmlText.append('<td>%s</td>' % url) htmlText.append('</tr>') num += 1
def makeIndividuals(self): personIndexTempl = os.path.join(THIS_DIR,'..','html','person_index_templ.htm') with open(personIndexTempl, "r") as fs: personIndexTempl = fs.read() for path, p in self.pf.people.items(): if p.fake or p.isPrivate(): continue # Navigator Bar clanTree = os.path.join(self.pf.root, p.surname(), "_clanTree.htm") person_index = personIndexTempl parent = p.parent() if parent is None: parent = clanTree parentTxt = 'top' else: sex = parent.getSex() parent = os.path.join(parent.path, PERSON_IDX) if sex is None: parentTxt = 'parent' elif sex == 'M': parentTxt = 'Father' elif sex == 'F': parentTxt = 'Mother' person_index = person_index.replace("__PATH_TO_PERSON__", fwdslash(path[len(self.pf.root) + 1:])) replPath = FT_ROOT_subst_leader + fwdslash(relpath(os.path.join(self.pf.root,'..','ftb','dist'), path)) + '/' person_index = person_index.replace(FTB_ROOT_subst, replPath) replPath = FT_ROOT_subst_leader + fwdslash(relpath(os.path.join(self.pf.root), path)) + '/' person_index = person_index.replace(TREE_ROOT_subst, replPath) person_index = person_index.replace("__P_TY__", parentTxt) person_index = person_index.replace("__GOTO_P__", fwdslash(relpath(parent, path))) person_index = person_index.replace("__GOTO_ME_IN_TREE__", fwdslash(relpath(clanTree + "#" + p.getIdStr(), path))) person_index = person_index.replace("__CLAN_NAME__", p.surname()) person_index = person_index.replace("__MY_NAME__", p.name()) print("write", PERSON_IDX, path) with open(os.path.join(path, PERSON_IDX), "w") as fs: fs.write(person_index) self.makePersonIndex(p, path)
def exportHtmlFile(self, src, dst): with open(src, "r") as fs: text = fs.read() doc = lxml.html.fromstring(text) # e, src/href, url, for el, attrib, lnk, pos in doc.iterlinks(): lnk = urllib.parse.urlsplit(lnk) if (lnk.scheme == "file" or len(lnk.scheme) == 0) and len(lnk.path) > 0: path = urllib.parse.unquote(lnk.path) if path[0] == '/': # absolute path = path[1:] else: # relative path = os.path.join(os.path.dirname(src), path) path = os.path.normpath(path) pPathItem = self.splitPersonPath(path) if pPathItem is not None: p, pathSeg = pPathItem path = os.path.join(self.expRoot, p.surname(), p.getIdStr()) path = os.path.join(path, pathSeg) else: path = os.path.join(self.expRoot, path[len(self.srcRoot) + 1:]) path = fwdslash(relpath(path, os.path.dirname(dst))) lnk = urllib.parse.urlunparse( ('', '', urllib.parse.quote(path), '', lnk.query, lnk.fragment)) el.attrib[attrib] = lnk with open(dst, "w") as fs: fs.write(MOTW) fs.write(lxml.html.tostring(doc))
def makeSearchIndex(self, obsfuc = False): indexFile = os.path.join(self.root,"searchRecs.js") with open(indexFile, "w") as fh: fh.write("profiles = new Array();\n") idx = 0 for path, p in self.pf.people.items(): if p.fake or p.isPrivate(): continue path = path[len(self.pf.root)+1:] if obsfuc: url = os.path.join(p.surname(), p.getIdStr(), PERSON_IDX) else: url = os.path.join(path, PERSON_IDX) url = fwdslash(url) path = fwdslash(path) fh.write('profiles[%d] = ["%s", "%s", "Path: %s"]\n' % (idx, url, p.name(), path)) idx += 1
def selectFile(self, f): comps = urllib.parse.urlparse(f) f = comps[2] if comps[0] == '': pass elif comps[0] == 'file': f = fwdslash(relpath(f, self.localDir)) else: f = None return f
def personDeath(self, p, htmlText): if p.deathVr is None: return searchDoc = fwdslash(relpath(p.deathVr.getFile(), p.path)) url = '<a href="%s">Death</a>:' % (searchDoc) htmlText.append('<tr><td style=" font-style: italic;">%s</td><td>' % (url)) if p.deathVr.date is not None: htmlText.append('%s ' % (p.deathVr.date)) if p.deathVr.age is not None: htmlText.append('(age %s) ' % (p.deathVr.age)) if p.deathVr.where is not None: htmlText.append('in %s' % (p.deathVr.where)) htmlText.append('</td>') cert = p.deathVr.getCert() if cert is not None: url = '<a href="%s">certificate</a>' % (fwdslash(relpath(cert, p.path))) htmlText.append('<td>%s</td>' % url) htmlText.append('</tr>')
def row(self, path, item, isDir): rowText = ['<tr>'] if isDir: rowText.append('<td><img src="%s" alt="Dir:" border="0"></td>' % (fwdslash(relpath(self.FOLDER_ICON, path)))) else: rowText.append('<td><br></td>') rowText.append('<td><a href="%s">%s</a></td>' % (urllib.parse.quote(item), item)) rowText.append("</tr>") return rowText
def personBirth(self, p, htmlText): date = p.getBirthDate() if date is None: return if p.birthVr is None: htmlText.append('<tr><td style=" font-style: italic;">Birth:</td>') htmlText.append('<td>%s</td>' % (date)) else: searchDoc = fwdslash(relpath(p.birthVr.getFile(), p.path)) url = '<a href="%s">Birth</a>:' % (searchDoc) htmlText.append('<tr><td style=" font-style: italic;">%s</td>' % (url)) htmlText.append('<td>%s' % (date)) if p.birthVr.where is not None: htmlText.append(' in %s' % (p.birthVr.where)) htmlText.append('</td>') cert = p.birthVr.getCert() if cert is not None: url = '<a href="%s">certificate</a>' % (fwdslash(relpath(cert, p.path))) htmlText.append('<td>%s</td>' % url) htmlText.append('</tr>')
def personChildren(self, p, htmlText): withBD = [] withoutBD = [] for c in p.children(): bd = c.getBirthDate() if bd is None: withoutBD.append(c) else: withBD.append( (c, bd.date) ) # Now check spouses for s in p.spouses(): for c in s.children(): if p.isMother(): parent = c.getMother() elif p.isFather(): parent = c.getFather() else: continue if parent is not None and p.nameMatch(parent.name()): bd = c.getBirthDate() if bd is None: withoutBD.append(c) else: withBD.append( (c, bd.date) ) if len(withBD) == 0 and len(withoutBD) == 0: return withBD.sort(key=lambda c: c[1]) children = [c[0] for c in withBD] children.extend(withoutBD) htmlText.append('<h2>Children</h2><table class="children">') idx = 1 for c in children: bd = c.getBirthDate() if bd is None: htmlText.append('<tr><td class="children-ra"><br></td>') else: htmlText.append('<tr><td class="children-ra">%d.</td>' % (idx)) idx += 1 cidx = os.path.join(c.path, PERSON_IDX) cidx = urllib.parse.quote(fwdslash(relpath(cidx, p.path))) url = '<a href="%s" target="_top">%s</a>' % (cidx, c.name()) if bd is not None: url += ' b. %s' % (bd) if c.birthVr is not None and c.birthVr.where is not None: url += ' in %s' % (c.birthVr.where) htmlText.append('<td class="children">%s</td></tr>' % (url)) htmlText.append('</table>')
def personMf(self, p, parentType, htmlText): if (parentType.upper() == 'FATHER'): parent = p.getFather() else: parent = p.getMother() if parent is None: return htmlText.append('<tr><td style=" font-style: italic;">%s:</td>' % (parentType)) if parent.fake: url = parent.name() else: pidx = os.path.join(parent.path, PERSON_IDX) pidx = urllib.parse.quote(fwdslash(relpath(pidx, p.path))) url = '<a href="%s" target="_top">%s</a>' % (pidx, parent.name()) htmlText.append('<td>%s</td>' % (url)) htmlText.append('<td></td>') # blank htmlText.append('</tr>')
def convert_links(self): numLinks = 0 noTarget = [] if os.name == 'posix': # This was originally /dev/null. Meld, however doesn't see it! NULL_LINK_TGT = '/tmp/'+NULL_LNK else: NULL_LINK_TGT = os.path.join(self.rootPath, '_'+NULL_LNK) for root, dirs, files in os.walk(self.rootPath): # The templates dir contains example links: don't convert these if 'templates' in dirs: dirs.remove('templates') # In linux, symlinks pointing to directories are treated by os.walk # as directories, so we identify them here and append to the files list for d in dirs: fullPath = os.path.join(root, d) if os.path.islink(fullPath): files.append(d) for f in files: # Get full path to link lnkName = os.path.join(root, f) # NF_DEBUG: SHOULD WE LOOK FOR SPOUSE LINKS ONLY? i.e 'w. ' etc if f.startswith(BCKf) or f.startswith(TMPf): # might want to delete these now #os.remove(lnkName) continue tgt = readLink(lnkName) if tgt is None: continue numLinks += 1 #print("FOUND", lnkName) if tgt.endswith(NULL_LNK): newTgt = NULL_LINK_TGT else: # Discard any windows drive tgt = ntpath.splitdrive(tgt)[1] # Normalise the path to use the os.sep for this OS tgt = fwdslash(tgt) tgt = os.path.normpath(tgt) # Try rebase rebased = tryRebaseLink(tgt, self.rootPath, treeRootNode = self.oldRootNode) if rebased is not None: newTgt = rebased else: # If we've not managed to rebase by this point then the only valid # case is a link is a relative pointing to something WITHIN # its parent CLAN directory if not os.path.isabs(tgt): # make it absolute newTgt = os.path.normpath(os.path.join(root, tgt)) else: # Very probably junk; just preserve it as is newTgt = tgt if not os.path.exists(newTgt): # The target doesn't exist. Make note of it, but plough on noTarget.append( (lnkName, newTgt) ) else: # Don't convert non-existent targets to relative - it'll # just confuse things further when attemping to manually fix if not self.absLinks: # make relative newTgt = os.path.relpath(newTgt, root) makelink_withbck(newTgt, lnkName, self.mklnk, self.newLnkSuffix, self.dryrun) print("numLinks", numLinks) if len(noTarget) != 0: print("WARN: The following %d targets don't exist:" % (len(noTarget))) for lnk, tgt in noTarget: print("%s from %s" % (tgt, lnk))
def makeHtml(self, title, dotFile): d = os.path.dirname(dotFile) bn = os.path.basename(dotFile) bn = os.path.splitext(bn)[0] # The bitmap file imageType = 'png' imageFile = bn + "." + imageType imageFilePath = os.path.join(d, imageFile) htmlFilePath = os.path.join(d, bn + ".htm") cmd = [ findDotExe(), '-T', imageType, '-o', imageFilePath, '-Tcmapx', '-o', htmlFilePath, dotFile ] subprocess.call(cmd) with open(htmlFilePath, "r") as fs: text = fs.read() origMapDoc = lxml.html.fromstring(text) with open(self.templ, "r") as fs: text = fs.read() text = text.replace("__TITLE__", title) replPath = FT_ROOT_subst_leader + fwdslash( relpath(os.path.join(self.peopleFact.root, '..', 'ftb', 'dist'), d)) + '/' text = text.replace(FTB_ROOT_subst, replPath) replPath = FT_ROOT_subst_leader + fwdslash( relpath(os.path.join(self.peopleFact.root), d)) + '/' text = text.replace(TREE_ROOT_subst, replPath) opDoc = lxml.html.fromstring(text) bitmap = opDoc.get_element_by_id("relationships") bitmap.attrib["src"] = imageFile eMapTempl = opDoc.get_element_by_id("TREEMAP") # Create new map element eMap = lxml.html.Element("map") eMap.attrib.update(iter(eMapTempl.attrib.items())) for c in origMapDoc: #c.attrib["onMouseOut"] = "clearFocus(this);" path = url2path(c.attrib["href"]) c.attrib["href"] = fwdslash(relpath(path, self.opDir)) if c.attrib["shape"] == "rect": #c.attrib["onMouseOver"] = "setFocus(this);" # Update id # Extract the person from the ABSOLUTE URL p = os.path.dirname(path) p = self.peopleFact.getPerson(p) c.attrib["id"] = p.getIdStr() c.attrib["title"] = self.getTitle(p) else: del c.attrib["title"] eMap.append(c) # Remove the template map & replace it with the 'real' one container = eMapTempl.getparent() container.remove(eMapTempl) container.append(eMap) with open(htmlFilePath, "wb") as fd: #fd.write(MOTW) fd.write(lxml.html.tostring(opDoc, pretty_print=True))