(Arne Babenhauserheide)
2011-10-06: overview should work. overview should work.
diff --git a/static.py b/static.py new file mode 100644 --- /dev/null +++ b/static.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# encoding: utf-8 + +"""static + +Create and/or upload a static copy of the repository. + +The main goal is sharing Mercurial on servers with only FTP access and +statically served files, while providing the same information as hg +serve and full solutions like bitbucket and gitorious (naturally +without the interactivity). +""" + +__plan__ = """ + +* Create the static-dir in the repo: + - Overview: Readme + commits + template + - Changes: Commit-Log + each commit as changeset/<hex> + - source: a filetree, shown as sourcecode: src/<path> and raw/<path> + - if b is used: a bugtracker: issue/<id>/<name> + - fork-/clone-info for each entry in [paths] with its incoming data (if it has some): + clone/<pathname>/ → commit log + possibly an associated issue in b. + +* Usage: + - hg static [--name] [-r] [folder] → parse the static folder for the current revision. + Mimic pull and clone wherever possible: This is a clone to <repo>/static + - hg static --upload <FTP-path> [folder] → update and upload the folder == clone/push + +* Idea: hg clone/push ftp://host.tld/path/to/repo → hg static --upload + +* Setup a new static repo or update an existing one: hg static --upload ftp://host.tld/path/to/repo + +""" + +import os +from os.path import join, isdir, isfile +import shutil +import mercurial.cmdutil +from mercurial import commands + +_staticidentifier = ".statichgrepo" + +templates = { + "head": """<!DOCTYPE html> +<html><head> + <meta charset="utf-8" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!--duplicate for older browsers--> + <link rel="stylesheet" href="style.css" type="text/css" media="screen" /> + <link rel="stylesheet" href="print.css" type="text/css" media="print" /> + <title>REPO_NAME</title> +</head> +<body> +""", + "foot": "</body></html>", + "screenstyle": """ """, + "printstyle": """ """ +} + + +def parsereadme(filepath): + """Parse the readme file""" + with open(filepath) as r: + return r.read() + + +def parsesite(ui, repo, target, **opts): + """Create the static folder.""" + idfile = join(target, _staticidentifier) + if not isdir(target): + # make sure the target exists + os.makedirs(target) + else: # make sure it is a staticrepo + if not isfile(idfile): + if not ui.prompt("The target folder exists is no static repo. Really use it?", default="n").lower() in ["y", "yes"]: + return + with open(idfile, "w") as i: + i.write("") + + # first the stylesheets + screenstyle = opts["screenstyle"] + if screenstyle: + shutil.copyfile(screenstyle, join(target, "style.css")) + else: + with open(join(target, "style.css"), "w") as f: + f.write(templates["screenstyle"]) + printstyle = opts["printstyle"] + if printstyle: + shutil.copyfile(printstyle, join(target, "print.css")) + else: + with open(join(target, "print.css"), "w") as f: + f.write(templates["printstyle"]) + + # then the overview + overview = open(join(target, "index.html"), "w") + overview.write(templates["head"]) + # add a readme, if it exists # TODO: Parse different types of readme files + for f in os.listdir(target): + if f.lower().startswith("readme"): + overview.write(parsereadme(f)) + # now add the 5 most recent log entries + # divert all following ui output to a string, so we can just use standard functions + #ui.pushbuffer() + commands.log(ui, repo, template="""<div style='float: right; padding-left: 0.5em'><em>({author|person})</em></div> + +g<p><strong> {date|shortdate}: <a href='commits/{node}.html'>{desc|strip|fill68|firstline}</a> <span style='font-size: xx-small'>{branches} {tags}</span></p><p>{desc|escape}</p>""", date="") + #overview.write(ui.popbuffer()) + # finish the overview + overview.write(templates["foot"]) + + + +def static(ui, repo, target=None, **opts): + """Create a static copy of the repository and/or upload it to an FTP server.""" + if not target: + target = "static" + parsesite(ui, repo, target, **opts) + + + +cmdtable = { + # "command-name": (function-call, options-list, help-string) + "static": (static, + [('r', 'rev', None, 'parse the given revision'), + ('a', 'all', None, 'parse all revisions (requires much space)'), + ('n', 'name', None, 'the repo name. Default: folder or last segment of the repo-path.'), + ('u', 'upload', None, 'upload the repo'), + ('s', 'screenstyle', None, 'use a custom stylesheet for display on screen'), + ('p', 'printstyle', None, 'use a custom stylesheet for printing')], + "[options] [folder]") +}