#!/usr/bin/python3 # # This file is part of Plinth. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # """ Configuration helper for ikiwiki """ import argparse import os import shutil import subprocess CONFIG_ENABLE = '/etc/apache2/conf-enabled/ikiwiki.conf' CONFIG_FILE = '/etc/apache2/conf-available/ikiwiki.conf' SETUP_WIKI = '/etc/ikiwiki/plinth-wiki.setup' SETUP_BLOG = '/etc/ikiwiki/plinth-blog.setup' SITE_PATH = '/var/www/ikiwiki' WIKI_PATH = '/var/ikiwiki' def parse_arguments(): """Return parsed command line arguments as dictionary.""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') # Get whether ikiwiki site is enabled subparsers.add_parser('get-enabled', help='Get whether ikiwiki site is enabled') # Enable ikiwiki site subparsers.add_parser('enable', help='Enable ikiwiki site') # Disable ikiwiki site subparsers.add_parser('disable', help='Disable ikiwiki site') # Get wikis and blogs subparsers.add_parser('get-sites', help='Get wikis and blogs') # Create a wiki create_wiki = subparsers.add_parser('create-wiki', help='Create a wiki') create_wiki.add_argument('--wiki_name', help='Name of new wiki') create_wiki.add_argument('--admin_name', help='Administrator account name') create_wiki.add_argument('--admin_password', help='Administrator account password') # Create a blog create_blog = subparsers.add_parser('create-blog', help='Create a blog') create_blog.add_argument('--blog_name', help='Name of new blog') create_blog.add_argument('--admin_name', help='Administrator account name') create_blog.add_argument('--admin_password', help='Administrator account password') # Delete a wiki or blog delete = subparsers.add_parser('delete', help='Delete a wiki or blog.') delete.add_argument('--name', help='Name of wiki or blog to delete.') return parser.parse_args() def subcommand_get_enabled(_): """Get whether ikiwiki site is enabled.""" if os.path.isfile(CONFIG_ENABLE): print('yes') else: print('no') def subcommand_enable(_): """Enable ikiwiki site.""" if not os.path.isfile(CONFIG_FILE): setup() subprocess.check_call(['a2enconf', 'ikiwiki']) subprocess.check_call(['service', 'apache2', 'restart']) else: subprocess.check_call(['a2enconf', 'ikiwiki']) subprocess.check_call(['service', 'apache2', 'reload']) def subcommand_disable(_): """Disable ikiwiki site.""" subprocess.check_call(['a2disconf', 'ikiwiki']) subprocess.check_call(['service', 'apache2', 'reload']) def subcommand_get_sites(_): """Get wikis and blogs.""" try: sites = os.listdir(SITE_PATH) print('\n'.join(sites)) except FileNotFoundError: pass def subcommand_create_wiki(arguments): """Create a wiki.""" pw_bytes = arguments.admin_password.encode() proc = subprocess.Popen( ['ikiwiki', '-setup', SETUP_WIKI, arguments.wiki_name, arguments.admin_name], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) outs, errs = proc.communicate(input=pw_bytes + b'\n' + pw_bytes) print(outs) print(errs) def subcommand_create_blog(arguments): """Create a blog.""" pw_bytes = arguments.admin_password.encode() proc = subprocess.Popen( ['ikiwiki', '-setup', SETUP_BLOG, arguments.blog_name, arguments.admin_name], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) outs, errs = proc.communicate(input=pw_bytes + b'\n' + pw_bytes) print(outs) print(errs) def subcommand_delete(arguments): """Delete a wiki or blog.""" html_folder = os.path.join(SITE_PATH, arguments.name) wiki_folder = os.path.join(WIKI_PATH, arguments.name) try: shutil.rmtree(html_folder) shutil.rmtree(wiki_folder) shutil.rmtree(wiki_folder + '.git') os.remove(wiki_folder + '.setup') print('Deleted %s' % arguments.name) except FileNotFoundError: print('Error: %s not found.' % arguments.name) exit(1) def setup(): """Initial setup""" if not os.path.exists(SITE_PATH): os.makedirs(SITE_PATH) subprocess.check_call(['a2enmod', 'cgi']) with open(CONFIG_FILE, 'w') as conffile: conffile.writelines([ 'Alias /ikiwiki /var/www/ikiwiki\n', 'AddHandler cgi-script .cgi\n', '\n', '\n', ' Options +ExecCGI\n', '\n' ]) with open(SETUP_WIKI, 'w') as setupfile: setupfile.writelines([ '#!/usr/bin/perl\n', '# Ikiwiki setup automator for Plinth.\n', '\n', 'require IkiWiki::Setup::Automator;\n', '\n', 'our $wikiname=$ARGV[0];\n', 'our $admin=$ARGV[1];\n', 'if (($wikiname eq "") || ($admin eq "")) {\n', ' print "Usage: ikiwiki -setup /etc/ikiwiki/plinth-wiki.setup ', 'wiki_name admin_name";\n', ' exit;\n', '}\n', '\n', 'our $wikiname_short=IkiWiki::Setup::Automator::sanitize_wikiname', '($wikiname);\n', '\n', 'IkiWiki::Setup::Automator->import(\n', ' wikiname => $wikiname,\n', ' adminuser => [$admin],\n', ' rcs => "git",\n', ' srcdir => "/var/ikiwiki/$wikiname_short",\n', ' destdir => "/var/www/ikiwiki/$wikiname_short",\n', ' repository => "/var/ikiwiki/$wikiname_short.git",\n', ' dumpsetup => "/var/ikiwiki/$wikiname_short.setup",\n', ' url => "/ikiwiki/$wikiname_short",\n', ' cgiurl => "/ikiwiki/$wikiname_short/ikiwiki.cgi",\n', ' cgi_wrapper => "/var/www/ikiwiki/$wikiname_short/ikiwiki.cgi",' '\n', ' add_plugins => [qw{goodstuff websetup httpauth}],\n', ' rss => 1,\n', ' atom => 1,\n', ' syslog => 1,\n', ')\n', ]) with open(SETUP_BLOG, 'w') as setupfile: setupfile.writelines([ '#!/usr/bin/perl\n', '# Ikiwiki setup automator for Plinth (blog version).\n', '\n', 'require IkiWiki::Setup::Automator;\n', '\n', 'our $wikiname=$ARGV[0];\n', 'our $admin=$ARGV[1];\n', 'if (($wikiname eq "") || ($admin eq "")) {\n', ' print "Usage: ikiwiki -setup /etc/ikiwiki/plinth-blog.setup ', 'blog_name admin_name";\n', ' exit;\n', '}\n', '\n', 'our $wikiname_short=IkiWiki::Setup::Automator::sanitize_wikiname', '($wikiname);\n', '\n', 'IkiWiki::Setup::Automator->import(\n', ' wikiname => $wikiname,\n', ' adminuser => [$admin],\n', ' rcs => "git",\n', ' srcdir => "/var/ikiwiki/$wikiname_short",\n', ' destdir => "/var/www/ikiwiki/$wikiname_short",\n', ' repository => "/var/ikiwiki/$wikiname_short.git",\n', ' dumpsetup => "/var/ikiwiki/$wikiname_short.setup",\n', ' url => "/ikiwiki/$wikiname_short",\n', ' cgiurl => "/ikiwiki/$wikiname_short/ikiwiki.cgi",\n', ' cgi_wrapper => "/var/www/ikiwiki/$wikiname_short/ikiwiki.cgi",' '\n', ' add_plugins => [qw{goodstuff websetup comments calendar ' 'sidebar trail httpauth}],\n', ' rss => 1,\n', ' atom => 1,\n', ' syslog => 1,\n', '\n', ' example => "blog",\n', ' comments_pagespec => "posts/* and !*/Discussion",\n', ' archive_pagespec => "page(posts/*) and !*/Discussion",\n', ' global_sidebars => 0,\n', ' discussion => 0,\n', ' tagbase => "tags",\n', ')\n', ]) def main(): """Parse arguments and perform all duties.""" arguments = parse_arguments() subcommand = arguments.subcommand.replace('-', '_') subcommand_method = globals()['subcommand_' + subcommand] subcommand_method(arguments) if __name__ == '__main__': main()