(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]")
+}