#!/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/lib/ikiwiki' apache_cgi_configuration = ''' Alias /ikiwiki /var/www/ikiwiki AddHandler cgi-script .cgi Options +ExecCGI ''' ikiwiki_setup_automator = ''' #!/usr/bin/perl # Ikiwiki setup automator for Plinth. require IkiWiki::Setup::Automator; our $wikiname=$ARGV[0]; our $admin=$ARGV[1]; if (($wikiname eq "") || ($admin eq "")) { print "Usage: ikiwiki -setup /etc/ikiwiki/plinth-wiki.setup wiki_name admin_name"; exit; } our $wikiname_short=IkiWiki::Setup::Automator::sanitize_wikiname($wikiname); IkiWiki::Setup::Automator->import( wikiname => $wikiname, adminuser => [$admin], rcs => "git", srcdir => "/var/lib/ikiwiki/$wikiname_short", destdir => "/var/www/ikiwiki/$wikiname_short", repository => "/var/lib/ikiwiki/$wikiname_short.git", dumpsetup => "/var/lib/ikiwiki/$wikiname_short.setup", url => "/ikiwiki/$wikiname_short", cgiurl => "/ikiwiki/$wikiname_short/ikiwiki.cgi", cgi_wrapper => "/var/www/ikiwiki/$wikiname_short/ikiwiki.cgi", add_plugins => [qw{goodstuff websetup httpauth}], rss => 1, atom => 1, syslog => 1, ) ''' ikiwiki_setup_automator_blog = ''' #!/usr/bin/perl # Ikiwiki setup automator for Plinth (blog version). require IkiWiki::Setup::Automator; our $wikiname=$ARGV[0]; our $admin=$ARGV[1]; if (($wikiname eq "") || ($admin eq "")) { print "Usage: ikiwiki -setup /etc/ikiwiki/plinth-blog.setup blog_name admin_name"; exit; } our $wikiname_short=IkiWiki::Setup::Automator::sanitize_wikiname($wikiname); IkiWiki::Setup::Automator->import( wikiname => $wikiname, adminuser => [$admin], rcs => "git", srcdir => "/var/lib/ikiwiki/$wikiname_short", destdir => "/var/www/ikiwiki/$wikiname_short", repository => "/var/lib/ikiwiki/$wikiname_short.git", dumpsetup => "/var/lib/ikiwiki/$wikiname_short.setup", url => "/ikiwiki/$wikiname_short", cgiurl => "/ikiwiki/$wikiname_short/ikiwiki.cgi", cgi_wrapper => "/var/www/ikiwiki/$wikiname_short/ikiwiki.cgi", add_plugins => [qw{goodstuff websetup comments calendar sidebar trail httpauth}], rss => 1, atom => 1, syslog => 1, example => "blog", comments_pagespec => "posts/* and !*/Discussion", archive_pagespec => "page(posts/*) and !*/Discussion", global_sidebars => 0, discussion => 0, tagbase => "tags", ) ''' def parse_arguments(): """Return parsed command line arguments as dictionary.""" parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') # Setup ikiwiki site subparsers.add_parser('setup', help='Perform first time setup operations') # 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_setup(_): """Perform first time setup operations.""" setup() 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.""" 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 {0}'.format(arguments.name)) except FileNotFoundError: print('Error: {0} not found.'.format(arguments.name)) exit(1) def setup(): """Write Apache configuration and wiki/blog setup scripts.""" if not os.path.exists(SITE_PATH): os.makedirs(SITE_PATH) subprocess.check_call(['a2enmod', 'cgi']) with open(CONFIG_FILE, 'w') as conffile: conffile.write(apache_cgi_configuration) with open(SETUP_WIKI, 'w') as setupfile: setupfile.writelines(ikiwiki_setup_automator) with open(SETUP_BLOG, 'w') as setupfile: setupfile.writelines(ikiwiki_setup_automator_blog) subprocess.check_call(['service', 'apache2', 'restart']) 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()