Added fn-putsite --wiki to insert freesites from wikis.
diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py
--- a/infocalypse/__init__.py
+++ b/infocalypse/__init__.py
@@ -581,6 +581,8 @@ def infocalypse_putsite(ui_, repo, **opt
"""
if opts['createconfig']:
+ if opts['wiki']:
+ raise util.Abort("Use fn-wiki --createconfig.")
params = {'SITE_CREATE_CONFIG':True}
execute_putsite(ui_, repo, params)
return
@@ -592,6 +594,8 @@ def infocalypse_putsite(ui_, repo, **opt
params['SITE_KEY'] == 'CHK@'):
raise util.Abort("--key must be a valid SSK "
+ "insert key or CHK@.")
+
+ params['ISWIKI'] = opts['wiki']
read_freesite_cfg(ui_, repo, params, stored_cfg)
try:
@@ -728,6 +732,7 @@ cmdtable = {
[('', 'dryrun', None, "don't insert site"),
('', 'index', -1, "edition to insert"),
('', 'createconfig', None, "create default freesite.cfg"),
+ ('', 'wiki', None, "insert a wiki, requires fnwiki.cfg"),
('', 'key', '', "private SSK to insert under"),]
+ FCP_OPTS,
"[options]"),
diff --git a/infocalypse/config.py b/infocalypse/config.py
--- a/infocalypse/config.py
+++ b/infocalypse/config.py
@@ -381,12 +381,20 @@ class Config:
# the ConfigParser import hack. See top of file.
def read_freesite_cfg(ui_, repo, params, stored_cfg):
""" Read param out of the freesite.cfg file. """
- cfg_file = os.path.join(repo.root, 'freesite.cfg')
+
+ fname = 'freesite.cfg'
+ # Hack to cut code paths to appease pylint. hmmmm....
+ no_cfg_err = "Use fn-putsite --createconfig to create freesite.cfg"
+ if params['ISWIKI']:
+ fname = 'fnwiki.cfg'
+ no_cfg_err = "Use fn-wiki --createconfig to create fnwiki.cfg"
+ cfg_file = os.path.join(repo.root, fname)
ui_.status('Using config file:\n%s\n' % cfg_file)
if not os.path.exists(cfg_file):
ui_.warn("Can't read: %s\n" % cfg_file)
- raise util.Abort("Use --createconfig to create freesite.cfg")
+ # REDFLAG: DCI TEST
+ raise util.Abort(no_cfg_err)
parser = ConfigParser()
parser.read(cfg_file)
@@ -394,7 +402,14 @@ def read_freesite_cfg(ui_, repo, params,
raise util.Abort("Can't read default section of config file?")
params['SITE_NAME'] = parser.get('default', 'site_name')
- params['SITE_DIR'] = parser.get('default', 'site_dir')
+
+ # wiki specific
+ if params['ISWIKI']:
+ # REDFLAG: DCI test error
+ params['WIKI_ROOT'] = parser.get('default', 'wiki_root')
+ else:
+ params['SITE_DIR'] = parser.get('default', 'site_dir')
+
if parser.has_option('default','default_file'):
params['SITE_DEFAULT_FILE'] = parser.get('default', 'default_file')
else:
@@ -425,6 +440,80 @@ def read_freesite_cfg(ui_, repo, params,
if not params['SITE_KEY'].startswith('SSK@'):
raise util.Abort("Stored site key not an SSK?")
+
+
+
+def write_default_config(ui_, repo, is_wiki=False):
+ """ Write a default freesite.cfg or fnwiki.cfg file into the repository
+ root dir. """
+
+ if not is_wiki:
+ file_name = os.path.join(repo.root, 'freesite.cfg')
+ text = \
+"""# freesite.cfg used by fn-putsite
+[default]
+# Human readable site name.
+site_name = default
+# Directory to insert from relative to the repository root.
+site_dir = site_root
+# Optional external file to load the site key from, relative
+# to the directory your .infocalypse/infocalypse.ini file
+# is stored in. This file should contain ONLY the SSK insert
+# key up to the first slash.
+#
+# If this value is not set the insert SSK for the repo is
+# used.
+#site_key_file = example_freesite_key.txt
+#
+# Optional file to display by default. If this is not
+# set index.html is used.
+#default_file = index.html
+"""
+ else:
+ file_name = os.path.join(repo.root, 'fnwiki.cfg')
+ text = \
+"""# fnwiki.cfg used by fn-wiki and fn-putsite --wiki
+[default]
+# Wiki specific stuff
+#
+# The directory relative to the repository with the files
+# for the wiki. The directory layout is as follows:
+# <wiki_root>/wikitext/ -- contains wiki text file
+# <wiki_root>/www/piki.css -- contains the css for the wiki/freesite.
+# <wiki_root>/www/pikipiki-logo.png -- png diplayed in wiki headers.
+wiki_root = wiki_root
+#
+# freesite insertion stuff
+#
+# Human readable site name.
+site_name = default
+# site_dir = ignored # NOT USED for wikis
+# Optional external file to load the site key from, relative
+# to the directory your .infocalypse/infocalypse.ini file
+# is stored in. This file should contain ONLY the SSK insert
+# key up to the first slash.
+#
+# If this value is not set the insert SSK for the repo is
+# used.
+#site_key_file = example_freesite_key.txt
+#
+# File to display by default.
+default_file = FrontPage
+"""
+ if os.path.exists(file_name):
+ raise util.Abort("Already exists: %s" % file_name)
+
+
+ out_file = open(file_name, 'w')
+ try:
+ out_file.write(text)
+ finally:
+ out_file.close()
+
+ ui_.status('Created config file:\n%s\n' % file_name)
+ ui_.status('You probably want to edit at least the site_name.\n')
+
+
def known_hashes(trust_map):
""" Return all repo hashes in the trust map. """
ret = set([])
diff --git a/infocalypse/sitecmds.py b/infocalypse/sitecmds.py
--- a/infocalypse/sitecmds.py
+++ b/infocalypse/sitecmds.py
@@ -21,44 +21,28 @@
import os
+import shutil
+import sys # REDFLAG: DCI
from mercurial import util
from fcpconnection import FCPError
from fcpclient import FCPClient, get_file_infos, set_index_file
-def write_default_config(ui_, repo):
- """ Write a default freesite.cfg file into the repository root dir. """
- file_name = os.path.join(repo.root, 'freesite.cfg')
+#------------------------------------------------------------
+# REDFLAG: DCI path hacks
+import validate
+ADD_DIR = os.path.join(os.path.dirname(
+ os.path.dirname(os.path.dirname(validate.__file__))),
+ 'clean_piki')
+sys.path.append(ADD_DIR)
- if os.path.exists(file_name):
- raise util.Abort("Already exists: %s" % file_name)
+import servepiki
- out_file = open(file_name, 'w')
- try:
- out_file.write("""[default]
-# Human readable site name.
-site_name = default
-# Directory to insert from relative to the repository root.
-site_dir = site_root
-# Optional external file to load the site key from, relative
-# to the directory your .infocalypse/infocalypse.ini file
-# is stored in. This file should contain ONLY the SSK insert
-# key up to the first slash.
-#
-# If this value is not set the insert SSK for the repo is
-# used.
-#site_key_file = example_freesite_key.txt
-#
-# Optional file to display by default. If this is not
-# set index.html is used.
-#default_file = index.html
-""")
- finally:
- out_file.close()
+#------------------------------------------------------------
- ui_.status('Created config file:\n%s\n' % file_name)
- ui_.status('You probably want to edit at least the site_name.\n')
+# REDFLAG: DCI deal with loading hacks for config
+from config import write_default_config
def get_insert_uri(params):
""" Helper function builds the insert URI. """
@@ -78,27 +62,43 @@ def show_request_uri(ui_, params, uri):
request_uri = uri
ui_.status('RequestURI:\n%s\n' % request_uri)
-def execute_putsite(ui_, repo, params):
- """ Run the putsite command. """
- def progress(dummy, msg):
- """ Message callback which writes to the hg ui instance."""
+def dump_wiki_html(wiki_root, staging_dir):
+ """ Dump the wiki as flat directory of html.
- if msg[0] == 'SimpleProgress':
- ui_.status("Progress: (%s/%s/%s)\n" % (msg[1]['Succeeded'],
- msg[1]['Required'],
- msg[1]['Total']))
- else:
- ui_.status("Progress: %s\n" % msg[0])
+ wiki_root is the directory containing the wikitext and www dirs.
+ staging_dir MUST contain the substring 'deletable'.
+ """
+ # i.e. so you can't delete your home directory by mistake.
+ if not staging_dir.find("deletable"):
+ raise ValueError("staging dir name must contain 'deletable'")
- if params.get('SITE_CREATE_CONFIG', False):
- write_default_config(ui_, repo)
- return
+ if os.path.exists(staging_dir):
+ shutil.rmtree(staging_dir)
+ assert not os.path.exists(staging_dir)
- # Remove trailing /
- params['SITE_KEY'] = params['SITE_KEY'].split('/')[0].strip()
- insert_uri = get_insert_uri(params)
- site_root = os.path.join(repo.root, params['SITE_DIR'])
+ os.makedirs(staging_dir)
+
+ # REDFLAG: DCI, should be piki.
+ servepiki.dump(staging_dir, wiki_root)
+
+TMP_DUMP_DIR = '_tmp_wiki_html_deletable'
+# Hmmmm... broken out to appease pylint
+def do_freenet_insert(ui_, repo, params, insert_uri, progress_func):
+ """ INTERNAL: Helper does the actual insert. """
+ default_mime_type = "text/plain" # put_complex_dir() default. Hmmmm..
+ if not params['ISWIKI']:
+ site_root = os.path.join(repo.root, params['SITE_DIR'])
+ else:
+ # REDFLAG: DCI temp file cleanup on exception
+
+ # Because wiki html files have no extension to guess from.
+ default_mime_type = 'text/html'
+
+ ui_.status("Dumping wiki as HTML...\n")
+ site_root = os.path.join(params['TMP_DIR'], TMP_DUMP_DIR)
+ dump_wiki_html(os.path.join(repo.root, params['WIKI_ROOT']),
+ site_root)
ui_.status('Default file: %s\n' % params['SITE_DEFAULT_FILE'])
ui_.status('Reading files from:\n%s\n' % site_root)
@@ -124,11 +124,12 @@ def execute_putsite(ui_, repo, params):
client = FCPClient.connect(params['FCP_HOST'],
params['FCP_PORT'])
client.in_params.default_fcp_params['DontCompress'] = False
- client.message_callback = progress
+ client.message_callback = progress_func
try:
ui_.status('Inserting to:\n%s\n' % insert_uri)
try:
- request_uri = client.put_complex_dir(insert_uri, infos)[1]['URI']
+ request_uri = client.put_complex_dir(insert_uri, infos,
+ default_mime_type)[1]['URI']
show_request_uri(ui_, params, request_uri)
except FCPError, err:
if err.is_code(9): # magick number for collision
@@ -141,6 +142,36 @@ def execute_putsite(ui_, repo, params):
finally:
client.close()
+def execute_putsite(ui_, repo, params):
+ """ Run the putsite command. """
+ def progress(dummy, msg):
+ """ Message callback which writes to the hg ui instance."""
+
+ if msg[0] == 'SimpleProgress':
+ ui_.status("Progress: (%s/%s/%s)\n" % (msg[1]['Succeeded'],
+ msg[1]['Required'],
+ msg[1]['Total']))
+ else:
+ ui_.status("Progress: %s\n" % msg[0])
+
+
+ if params.get('SITE_CREATE_CONFIG', False):
+ write_default_config(ui_, repo)
+ return
+
+ # Remove trailing /
+ params['SITE_KEY'] = params['SITE_KEY'].split('/')[0].strip()
+ try:
+ do_freenet_insert(ui_, repo, params,
+ get_insert_uri(params),
+ progress)
+ finally:
+ tmp_dump = os.path.join(params['TMP_DIR'], TMP_DUMP_DIR)
+ if os.path.exists(tmp_dump):
+ # REDFLAG: DCI, failure here is horrible.
+ # i.e. untrusted unencrypted data on your disk
+ shutil.rmtree(tmp_dump)
+
MSG_FMT = """InsertURI:
%s
RequestURI:
diff --git a/infocalypse/wikicmds.py b/infocalypse/wikicmds.py
--- a/infocalypse/wikicmds.py
+++ b/infocalypse/wikicmds.py
@@ -35,6 +35,9 @@ from servepiki import serve_wiki, create
from mercurial import util
+from config import write_default_config
+
+# REDFLAG: DCI path hacks
# piki's required files are in that directory.
import servepiki
PIKI_WWW_SRC = os.path.dirname(servepiki.__file__)
@@ -62,14 +65,8 @@ def execute_wiki(ui_, repo, params):
"Move it out of the way to continue.")
create_empty_wiki(os.path.join(repo.root, 'wiki_root'), PIKI_WWW_SRC)
- out = open(os.path.join(repo.root, 'fnwiki.cfg'), 'w')
- out.write("""[default]
-# fniki.cfg tells piki where to read the wiki data from.
-[default]
-root_dir = wiki_root
-""")
- out.close()
- ui_.status("Created fnwiki.cfg and skeleton wiki_root dir.\n")
+ ui_.status("Created skeleton wiki_root dir.\n")
+ write_default_config(ui_, repo, True)
return
raise util.Abort("Unsupported subcommand: " + params.get('WIKI', 'unknown'))