mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Delete pelican/tools directory
This commit is contained in:
parent
dd6338e387
commit
143bec67e2
8 changed files with 0 additions and 2038 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,354 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import locale
|
||||
import os
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
import pytz
|
||||
|
||||
try:
|
||||
import readline # NOQA
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import tzlocal
|
||||
_DEFAULT_TIMEZONE = tzlocal.get_localzone().zone
|
||||
except ImportError:
|
||||
_DEFAULT_TIMEZONE = 'Europe/Paris'
|
||||
|
||||
from pelican import __version__
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
try:
|
||||
_DEFAULT_LANGUAGE = locale.getlocale()[0]
|
||||
except ValueError:
|
||||
# Don't fail on macosx: "unknown locale: UTF-8"
|
||||
_DEFAULT_LANGUAGE = None
|
||||
if _DEFAULT_LANGUAGE is None:
|
||||
_DEFAULT_LANGUAGE = 'en'
|
||||
else:
|
||||
_DEFAULT_LANGUAGE = _DEFAULT_LANGUAGE.split('_')[0]
|
||||
|
||||
_TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"templates")
|
||||
_jinja_env = Environment(
|
||||
loader=FileSystemLoader(_TEMPLATES_DIR),
|
||||
trim_blocks=True,
|
||||
)
|
||||
|
||||
|
||||
_GITHUB_PAGES_BRANCHES = {
|
||||
'personal': 'main',
|
||||
'project': 'gh-pages'
|
||||
}
|
||||
|
||||
CONF = {
|
||||
'pelican': 'pelican',
|
||||
'pelicanopts': '',
|
||||
'basedir': os.curdir,
|
||||
'ftp_host': 'localhost',
|
||||
'ftp_user': 'anonymous',
|
||||
'ftp_target_dir': '/',
|
||||
'ssh_host': 'localhost',
|
||||
'ssh_port': 22,
|
||||
'ssh_user': 'root',
|
||||
'ssh_target_dir': '/var/www',
|
||||
's3_bucket': 'my_s3_bucket',
|
||||
'cloudfiles_username': 'my_rackspace_username',
|
||||
'cloudfiles_api_key': 'my_rackspace_api_key',
|
||||
'cloudfiles_container': 'my_cloudfiles_container',
|
||||
'dropbox_dir': '~/Dropbox/Public/',
|
||||
'github_pages_branch': _GITHUB_PAGES_BRANCHES['project'],
|
||||
'default_pagination': 10,
|
||||
'siteurl': '',
|
||||
'lang': _DEFAULT_LANGUAGE,
|
||||
'timezone': _DEFAULT_TIMEZONE
|
||||
}
|
||||
|
||||
# url for list of valid timezones
|
||||
_TZ_URL = 'https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'
|
||||
|
||||
|
||||
# Create a 'marked' default path, to determine if someone has supplied
|
||||
# a path on the command-line.
|
||||
class _DEFAULT_PATH_TYPE(str):
|
||||
is_default_path = True
|
||||
|
||||
|
||||
_DEFAULT_PATH = _DEFAULT_PATH_TYPE(os.curdir)
|
||||
|
||||
|
||||
def ask(question, answer=str, default=None, length=None):
|
||||
if answer == str:
|
||||
r = ''
|
||||
while True:
|
||||
if default:
|
||||
r = input('> {} [{}] '.format(question, default))
|
||||
else:
|
||||
r = input('> {} '.format(question))
|
||||
|
||||
r = r.strip()
|
||||
|
||||
if len(r) <= 0:
|
||||
if default:
|
||||
r = default
|
||||
break
|
||||
else:
|
||||
print('You must enter something')
|
||||
else:
|
||||
if length and len(r) != length:
|
||||
print('Entry must be {} characters long'.format(length))
|
||||
else:
|
||||
break
|
||||
|
||||
return r
|
||||
|
||||
elif answer == bool:
|
||||
r = None
|
||||
while True:
|
||||
if default is True:
|
||||
r = input('> {} (Y/n) '.format(question))
|
||||
elif default is False:
|
||||
r = input('> {} (y/N) '.format(question))
|
||||
else:
|
||||
r = input('> {} (y/n) '.format(question))
|
||||
|
||||
r = r.strip().lower()
|
||||
|
||||
if r in ('y', 'yes'):
|
||||
r = True
|
||||
break
|
||||
elif r in ('n', 'no'):
|
||||
r = False
|
||||
break
|
||||
elif not r:
|
||||
r = default
|
||||
break
|
||||
else:
|
||||
print("You must answer 'yes' or 'no'")
|
||||
return r
|
||||
elif answer == int:
|
||||
r = None
|
||||
while True:
|
||||
if default:
|
||||
r = input('> {} [{}] '.format(question, default))
|
||||
else:
|
||||
r = input('> {} '.format(question))
|
||||
|
||||
r = r.strip()
|
||||
|
||||
if not r:
|
||||
r = default
|
||||
break
|
||||
|
||||
try:
|
||||
r = int(r)
|
||||
break
|
||||
except ValueError:
|
||||
print('You must enter an integer')
|
||||
return r
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
'Argument `answer` must be str, bool, or integer')
|
||||
|
||||
|
||||
def ask_timezone(question, default, tzurl):
|
||||
"""Prompt for time zone and validate input"""
|
||||
lower_tz = [tz.lower() for tz in pytz.all_timezones]
|
||||
while True:
|
||||
r = ask(question, str, default)
|
||||
r = r.strip().replace(' ', '_').lower()
|
||||
if r in lower_tz:
|
||||
r = pytz.all_timezones[lower_tz.index(r)]
|
||||
break
|
||||
else:
|
||||
print('Please enter a valid time zone:\n'
|
||||
' (check [{}])'.format(tzurl))
|
||||
return r
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="A kickstarter for Pelican",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('-p', '--path', default=_DEFAULT_PATH,
|
||||
help="The path to generate the blog into")
|
||||
parser.add_argument('-t', '--title', metavar="title",
|
||||
help='Set the title of the website')
|
||||
parser.add_argument('-a', '--author', metavar="author",
|
||||
help='Set the author name of the website')
|
||||
parser.add_argument('-l', '--lang', metavar="lang",
|
||||
help='Set the default web site language')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print('''Welcome to pelican-quickstart v{v}.
|
||||
|
||||
This script will help you create a new Pelican-based website.
|
||||
|
||||
Please answer the following questions so this script can generate the files
|
||||
needed by Pelican.
|
||||
|
||||
'''.format(v=__version__))
|
||||
|
||||
project = os.path.join(
|
||||
os.environ.get('VIRTUAL_ENV', os.curdir), '.project')
|
||||
no_path_was_specified = hasattr(args.path, 'is_default_path')
|
||||
if os.path.isfile(project) and no_path_was_specified:
|
||||
CONF['basedir'] = open(project).read().rstrip("\n")
|
||||
print('Using project associated with current virtual environment. '
|
||||
'Will save to:\n%s\n' % CONF['basedir'])
|
||||
else:
|
||||
CONF['basedir'] = os.path.abspath(os.path.expanduser(
|
||||
ask('Where do you want to create your new web site?',
|
||||
answer=str, default=args.path)))
|
||||
|
||||
CONF['sitename'] = ask('What will be the title of this web site?',
|
||||
answer=str, default=args.title)
|
||||
CONF['author'] = ask('Who will be the author of this web site?',
|
||||
answer=str, default=args.author)
|
||||
CONF['lang'] = ask('What will be the default language of this web site?',
|
||||
str, args.lang or CONF['lang'], 2)
|
||||
|
||||
if ask('Do you want to specify a URL prefix? e.g., https://example.com ',
|
||||
answer=bool, default=True):
|
||||
CONF['siteurl'] = ask('What is your URL prefix? (see '
|
||||
'above example; no trailing slash)',
|
||||
str, CONF['siteurl'])
|
||||
|
||||
CONF['with_pagination'] = ask('Do you want to enable article pagination?',
|
||||
bool, bool(CONF['default_pagination']))
|
||||
|
||||
if CONF['with_pagination']:
|
||||
CONF['default_pagination'] = ask('How many articles per page '
|
||||
'do you want?',
|
||||
int, CONF['default_pagination'])
|
||||
else:
|
||||
CONF['default_pagination'] = False
|
||||
|
||||
CONF['timezone'] = ask_timezone('What is your time zone?',
|
||||
CONF['timezone'], _TZ_URL)
|
||||
|
||||
automation = ask('Do you want to generate a tasks.py/Makefile '
|
||||
'to automate generation and publishing?', bool, True)
|
||||
|
||||
if automation:
|
||||
if ask('Do you want to upload your website using FTP?',
|
||||
answer=bool, default=False):
|
||||
CONF['ftp'] = True,
|
||||
CONF['ftp_host'] = ask('What is the hostname of your FTP server?',
|
||||
str, CONF['ftp_host'])
|
||||
CONF['ftp_user'] = ask('What is your username on that server?',
|
||||
str, CONF['ftp_user'])
|
||||
CONF['ftp_target_dir'] = ask('Where do you want to put your '
|
||||
'web site on that server?',
|
||||
str, CONF['ftp_target_dir'])
|
||||
if ask('Do you want to upload your website using SSH?',
|
||||
answer=bool, default=False):
|
||||
CONF['ssh'] = True,
|
||||
CONF['ssh_host'] = ask('What is the hostname of your SSH server?',
|
||||
str, CONF['ssh_host'])
|
||||
CONF['ssh_port'] = ask('What is the port of your SSH server?',
|
||||
int, CONF['ssh_port'])
|
||||
CONF['ssh_user'] = ask('What is your username on that server?',
|
||||
str, CONF['ssh_user'])
|
||||
CONF['ssh_target_dir'] = ask('Where do you want to put your '
|
||||
'web site on that server?',
|
||||
str, CONF['ssh_target_dir'])
|
||||
|
||||
if ask('Do you want to upload your website using Dropbox?',
|
||||
answer=bool, default=False):
|
||||
CONF['dropbox'] = True,
|
||||
CONF['dropbox_dir'] = ask('Where is your Dropbox directory?',
|
||||
str, CONF['dropbox_dir'])
|
||||
|
||||
if ask('Do you want to upload your website using S3?',
|
||||
answer=bool, default=False):
|
||||
CONF['s3'] = True,
|
||||
CONF['s3_bucket'] = ask('What is the name of your S3 bucket?',
|
||||
str, CONF['s3_bucket'])
|
||||
|
||||
if ask('Do you want to upload your website using '
|
||||
'Rackspace Cloud Files?', answer=bool, default=False):
|
||||
CONF['cloudfiles'] = True,
|
||||
CONF['cloudfiles_username'] = ask('What is your Rackspace '
|
||||
'Cloud username?', str,
|
||||
CONF['cloudfiles_username'])
|
||||
CONF['cloudfiles_api_key'] = ask('What is your Rackspace '
|
||||
'Cloud API key?', str,
|
||||
CONF['cloudfiles_api_key'])
|
||||
CONF['cloudfiles_container'] = ask('What is the name of your '
|
||||
'Cloud Files container?',
|
||||
str,
|
||||
CONF['cloudfiles_container'])
|
||||
|
||||
if ask('Do you want to upload your website using GitHub Pages?',
|
||||
answer=bool, default=False):
|
||||
CONF['github'] = True,
|
||||
if ask('Is this your personal page (username.github.io)?',
|
||||
answer=bool, default=False):
|
||||
CONF['github_pages_branch'] = \
|
||||
_GITHUB_PAGES_BRANCHES['personal']
|
||||
else:
|
||||
CONF['github_pages_branch'] = \
|
||||
_GITHUB_PAGES_BRANCHES['project']
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.join(CONF['basedir'], 'content'))
|
||||
except OSError as e:
|
||||
print('Error: {}'.format(e))
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.join(CONF['basedir'], 'output'))
|
||||
except OSError as e:
|
||||
print('Error: {}'.format(e))
|
||||
|
||||
try:
|
||||
with open(os.path.join(CONF['basedir'], 'pelicanconf.py'),
|
||||
'w', encoding='utf-8') as fd:
|
||||
conf_python = dict()
|
||||
for key, value in CONF.items():
|
||||
conf_python[key] = repr(value)
|
||||
|
||||
_template = _jinja_env.get_template('pelicanconf.py.jinja2')
|
||||
fd.write(_template.render(**conf_python))
|
||||
fd.close()
|
||||
except OSError as e:
|
||||
print('Error: {}'.format(e))
|
||||
|
||||
try:
|
||||
with open(os.path.join(CONF['basedir'], 'publishconf.py'),
|
||||
'w', encoding='utf-8') as fd:
|
||||
_template = _jinja_env.get_template('publishconf.py.jinja2')
|
||||
fd.write(_template.render(**CONF))
|
||||
fd.close()
|
||||
except OSError as e:
|
||||
print('Error: {}'.format(e))
|
||||
|
||||
if automation:
|
||||
try:
|
||||
with open(os.path.join(CONF['basedir'], 'tasks.py'),
|
||||
'w', encoding='utf-8') as fd:
|
||||
_template = _jinja_env.get_template('tasks.py.jinja2')
|
||||
fd.write(_template.render(**CONF))
|
||||
fd.close()
|
||||
except OSError as e:
|
||||
print('Error: {}'.format(e))
|
||||
try:
|
||||
with open(os.path.join(CONF['basedir'], 'Makefile'),
|
||||
'w', encoding='utf-8') as fd:
|
||||
py_v = 'python3'
|
||||
_template = _jinja_env.get_template('Makefile.jinja2')
|
||||
fd.write(_template.render(py_v=py_v, **CONF))
|
||||
fd.close()
|
||||
except OSError as e:
|
||||
print('Error: {}'.format(e))
|
||||
|
||||
print('Done. Your new project is available at %s' % CONF['basedir'])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
|
||||
def err(msg, die=None):
|
||||
"""Print an error message and exits if an exit code is given"""
|
||||
sys.stderr.write(msg + '\n')
|
||||
if die:
|
||||
sys.exit(die if type(die) is int else 1)
|
||||
|
||||
|
||||
try:
|
||||
import pelican
|
||||
except ImportError:
|
||||
err('Cannot import pelican.\nYou must '
|
||||
'install Pelican in order to run this script.',
|
||||
-1)
|
||||
|
||||
|
||||
global _THEMES_PATH
|
||||
_THEMES_PATH = os.path.join(
|
||||
os.path.dirname(
|
||||
os.path.abspath(pelican.__file__)
|
||||
),
|
||||
'themes'
|
||||
)
|
||||
|
||||
__version__ = '0.2'
|
||||
_BUILTIN_THEMES = ['simple', 'notmyidea']
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""Install themes for Pelican""")
|
||||
|
||||
excl = parser.add_mutually_exclusive_group()
|
||||
excl.add_argument(
|
||||
'-l', '--list', dest='action', action="store_const", const='list',
|
||||
help="Show the themes already installed and exit")
|
||||
excl.add_argument(
|
||||
'-p', '--path', dest='action', action="store_const", const='path',
|
||||
help="Show the themes path and exit")
|
||||
excl.add_argument(
|
||||
'-V', '--version', action='version',
|
||||
version='pelican-themes v{}'.format(__version__),
|
||||
help='Print the version of this script')
|
||||
|
||||
parser.add_argument(
|
||||
'-i', '--install', dest='to_install', nargs='+', metavar="theme path",
|
||||
help='The themes to install')
|
||||
parser.add_argument(
|
||||
'-r', '--remove', dest='to_remove', nargs='+', metavar="theme name",
|
||||
help='The themes to remove')
|
||||
parser.add_argument(
|
||||
'-U', '--upgrade', dest='to_upgrade', nargs='+',
|
||||
metavar="theme path", help='The themes to upgrade')
|
||||
parser.add_argument(
|
||||
'-s', '--symlink', dest='to_symlink', nargs='+', metavar="theme path",
|
||||
help="Same as `--install', but create a symbolic link instead of "
|
||||
"copying the theme. Useful for theme development")
|
||||
parser.add_argument(
|
||||
'-c', '--clean', dest='clean', action="store_true",
|
||||
help="Remove the broken symbolic links of the theme path")
|
||||
|
||||
parser.add_argument(
|
||||
'-v', '--verbose', dest='verbose',
|
||||
action="store_true",
|
||||
help="Verbose output")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
to_install = args.to_install or args.to_upgrade
|
||||
to_sym = args.to_symlink or args.clean
|
||||
|
||||
if args.action:
|
||||
if args.action == 'list':
|
||||
list_themes(args.verbose)
|
||||
elif args.action == 'path':
|
||||
print(_THEMES_PATH)
|
||||
elif to_install or args.to_remove or to_sym:
|
||||
if args.to_remove:
|
||||
if args.verbose:
|
||||
print('Removing themes...')
|
||||
|
||||
for i in args.to_remove:
|
||||
remove(i, v=args.verbose)
|
||||
|
||||
if args.to_install:
|
||||
if args.verbose:
|
||||
print('Installing themes...')
|
||||
|
||||
for i in args.to_install:
|
||||
install(i, v=args.verbose)
|
||||
|
||||
if args.to_upgrade:
|
||||
if args.verbose:
|
||||
print('Upgrading themes...')
|
||||
|
||||
for i in args.to_upgrade:
|
||||
install(i, v=args.verbose, u=True)
|
||||
|
||||
if args.to_symlink:
|
||||
if args.verbose:
|
||||
print('Linking themes...')
|
||||
|
||||
for i in args.to_symlink:
|
||||
symlink(i, v=args.verbose)
|
||||
|
||||
if args.clean:
|
||||
if args.verbose:
|
||||
print('Cleaning the themes directory...')
|
||||
|
||||
clean(v=args.verbose)
|
||||
else:
|
||||
print('No argument given... exiting.')
|
||||
|
||||
|
||||
def themes():
|
||||
"""Returns the list of the themes"""
|
||||
for i in os.listdir(_THEMES_PATH):
|
||||
e = os.path.join(_THEMES_PATH, i)
|
||||
|
||||
if os.path.isdir(e):
|
||||
if os.path.islink(e):
|
||||
yield (e, os.readlink(e))
|
||||
else:
|
||||
yield (e, None)
|
||||
|
||||
|
||||
def list_themes(v=False):
|
||||
"""Display the list of the themes"""
|
||||
for t, l in themes():
|
||||
if not v:
|
||||
t = os.path.basename(t)
|
||||
if l:
|
||||
if v:
|
||||
print(t + (" (symbolic link to `" + l + "')"))
|
||||
else:
|
||||
print(t + '@')
|
||||
else:
|
||||
print(t)
|
||||
|
||||
|
||||
def remove(theme_name, v=False):
|
||||
"""Removes a theme"""
|
||||
|
||||
theme_name = theme_name.replace('/', '')
|
||||
target = os.path.join(_THEMES_PATH, theme_name)
|
||||
|
||||
if theme_name in _BUILTIN_THEMES:
|
||||
err(theme_name + ' is a builtin theme.\n'
|
||||
'You cannot remove a builtin theme with this script, '
|
||||
'remove it by hand if you want.')
|
||||
elif os.path.islink(target):
|
||||
if v:
|
||||
print('Removing link `' + target + "'")
|
||||
os.remove(target)
|
||||
elif os.path.isdir(target):
|
||||
if v:
|
||||
print('Removing directory `' + target + "'")
|
||||
shutil.rmtree(target)
|
||||
elif os.path.exists(target):
|
||||
err(target + ' : not a valid theme')
|
||||
else:
|
||||
err(target + ' : no such file or directory')
|
||||
|
||||
|
||||
def install(path, v=False, u=False):
|
||||
"""Installs a theme"""
|
||||
if not os.path.exists(path):
|
||||
err(path + ' : no such file or directory')
|
||||
elif not os.path.isdir(path):
|
||||
err(path + ' : not a directory')
|
||||
else:
|
||||
theme_name = os.path.basename(os.path.normpath(path))
|
||||
theme_path = os.path.join(_THEMES_PATH, theme_name)
|
||||
exists = os.path.exists(theme_path)
|
||||
if exists and not u:
|
||||
err(path + ' : already exists')
|
||||
elif exists and u:
|
||||
remove(theme_name, v)
|
||||
install(path, v)
|
||||
else:
|
||||
if v:
|
||||
print("Copying '{p}' to '{t}' ...".format(p=path,
|
||||
t=theme_path))
|
||||
try:
|
||||
shutil.copytree(path, theme_path)
|
||||
|
||||
try:
|
||||
if os.name == 'posix':
|
||||
for root, dirs, files in os.walk(theme_path):
|
||||
for d in dirs:
|
||||
dname = os.path.join(root, d)
|
||||
os.chmod(dname, 493) # 0o755
|
||||
for f in files:
|
||||
fname = os.path.join(root, f)
|
||||
os.chmod(fname, 420) # 0o644
|
||||
except OSError as e:
|
||||
err("Cannot change permissions of files "
|
||||
"or directory in `{r}':\n{e}".format(r=theme_path,
|
||||
e=str(e)),
|
||||
die=False)
|
||||
except Exception as e:
|
||||
err("Cannot copy `{p}' to `{t}':\n{e}".format(
|
||||
p=path, t=theme_path, e=str(e)))
|
||||
|
||||
|
||||
def symlink(path, v=False):
|
||||
"""Symbolically link a theme"""
|
||||
if not os.path.exists(path):
|
||||
err(path + ' : no such file or directory')
|
||||
elif not os.path.isdir(path):
|
||||
err(path + ' : not a directory')
|
||||
else:
|
||||
theme_name = os.path.basename(os.path.normpath(path))
|
||||
theme_path = os.path.join(_THEMES_PATH, theme_name)
|
||||
if os.path.exists(theme_path):
|
||||
err(path + ' : already exists')
|
||||
else:
|
||||
if v:
|
||||
print("Linking `{p}' to `{t}' ...".format(
|
||||
p=path, t=theme_path))
|
||||
try:
|
||||
os.symlink(path, theme_path)
|
||||
except Exception as e:
|
||||
err("Cannot link `{p}' to `{t}':\n{e}".format(
|
||||
p=path, t=theme_path, e=str(e)))
|
||||
|
||||
|
||||
def is_broken_link(path):
|
||||
"""Returns True if the path given as is a broken symlink"""
|
||||
path = os.readlink(path)
|
||||
return not os.path.exists(path)
|
||||
|
||||
|
||||
def clean(v=False):
|
||||
"""Removes the broken symbolic links"""
|
||||
c = 0
|
||||
for path in os.listdir(_THEMES_PATH):
|
||||
path = os.path.join(_THEMES_PATH, path)
|
||||
if os.path.islink(path):
|
||||
if is_broken_link(path):
|
||||
if v:
|
||||
print('Removing {}'.format(path))
|
||||
try:
|
||||
os.remove(path)
|
||||
except OSError:
|
||||
print('Error: cannot remove {}'.format(path))
|
||||
else:
|
||||
c += 1
|
||||
|
||||
print("\nRemoved {} broken links".format(c))
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
PY?={{py_v}}
|
||||
PELICAN?={{pelican}}
|
||||
PELICANOPTS={{pelicanopts}}
|
||||
|
||||
BASEDIR=$(CURDIR)
|
||||
INPUTDIR=$(BASEDIR)/content
|
||||
OUTPUTDIR=$(BASEDIR)/output
|
||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||
|
||||
{% if ftp %}
|
||||
FTP_HOST={{ftp_host}}
|
||||
FTP_USER={{ftp_user}}
|
||||
FTP_TARGET_DIR={{ftp_target_dir}}
|
||||
|
||||
{% endif %}
|
||||
{% if ssh %}
|
||||
SSH_HOST={{ssh_host}}
|
||||
SSH_PORT={{ssh_port}}
|
||||
SSH_USER={{ssh_user}}
|
||||
SSH_TARGET_DIR={{ssh_target_dir}}
|
||||
|
||||
{% endif %}
|
||||
{% if s3 %}
|
||||
S3_BUCKET={{s3_bucket}}
|
||||
|
||||
{% endif %}
|
||||
{% if cloudfiles %}
|
||||
CLOUDFILES_USERNAME={{cloudfiles_username}}
|
||||
CLOUDFILES_API_KEY={{cloudfiles_api_key}}
|
||||
CLOUDFILES_CONTAINER={{cloudfiles_container}}
|
||||
|
||||
{% endif %}
|
||||
{% if dropbox %}
|
||||
DROPBOX_DIR={{dropbox_dir}}
|
||||
|
||||
{% endif %}
|
||||
{% if github %}
|
||||
GITHUB_PAGES_BRANCH={{github_pages_branch}}
|
||||
|
||||
{% endif %}
|
||||
|
||||
DEBUG ?= 0
|
||||
ifeq ($(DEBUG), 1)
|
||||
PELICANOPTS += -D
|
||||
endif
|
||||
|
||||
RELATIVE ?= 0
|
||||
ifeq ($(RELATIVE), 1)
|
||||
PELICANOPTS += --relative-urls
|
||||
endif
|
||||
|
||||
SERVER ?= "0.0.0.0"
|
||||
|
||||
PORT ?= 0
|
||||
ifneq ($(PORT), 0)
|
||||
PELICANOPTS += -p $(PORT)
|
||||
endif
|
||||
|
||||
|
||||
help:
|
||||
@echo 'Makefile for a pelican Web site '
|
||||
@echo ' '
|
||||
@echo 'Usage: '
|
||||
@echo ' make html (re)generate the web site '
|
||||
@echo ' make clean remove the generated files '
|
||||
@echo ' make regenerate regenerate files upon modification '
|
||||
@echo ' make publish generate using production settings '
|
||||
@echo ' make serve [PORT=8000] serve site at http://localhost:8000'
|
||||
@echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 '
|
||||
@echo ' make devserver [PORT=8000] serve and regenerate together '
|
||||
@echo ' make devserver-global regenerate and serve on 0.0.0.0 '
|
||||
{% if ssh %}
|
||||
@echo ' make ssh_upload upload the web site via SSH '
|
||||
@echo ' make rsync_upload upload the web site via rsync+ssh '
|
||||
{% endif %}
|
||||
{% if dropbox %}
|
||||
@echo ' make dropbox_upload upload the web site via Dropbox '
|
||||
{% endif %}
|
||||
{% if ftp %}
|
||||
@echo ' make ftp_upload upload the web site via FTP '
|
||||
{% endif %}
|
||||
{% if s3 %}
|
||||
@echo ' make s3_upload upload the web site via S3 '
|
||||
{% endif %}
|
||||
{% if cloudfiles %}
|
||||
@echo ' make cf_upload upload the web site via Cloud Files'
|
||||
{% endif %}
|
||||
{% if github %}
|
||||
@echo ' make github upload the web site via gh-pages '
|
||||
{% endif %}
|
||||
@echo ' '
|
||||
@echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html '
|
||||
@echo 'Set the RELATIVE variable to 1 to enable relative urls '
|
||||
@echo ' '
|
||||
|
||||
html:
|
||||
"$(PELICAN)" "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
clean:
|
||||
[ ! -d "$(OUTPUTDIR)" ] || rm -rf "$(OUTPUTDIR)"
|
||||
|
||||
regenerate:
|
||||
"$(PELICAN)" -r "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
serve:
|
||||
"$(PELICAN)" -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
serve-global:
|
||||
"$(PELICAN)" -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS) -b $(SERVER)
|
||||
|
||||
devserver:
|
||||
"$(PELICAN)" -lr "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
devserver-global:
|
||||
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -b 0.0.0.0
|
||||
|
||||
publish:
|
||||
"$(PELICAN)" "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(PUBLISHCONF)" $(PELICANOPTS)
|
||||
|
||||
{% set upload = [] %}
|
||||
{% if ssh %}
|
||||
{% set upload = upload + ["ssh_upload"] %}
|
||||
ssh_upload: publish
|
||||
scp -P $(SSH_PORT) -r "$(OUTPUTDIR)"/* "$(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)"
|
||||
|
||||
{% set upload = upload + ["rsync_upload"] %}
|
||||
rsync_upload: publish
|
||||
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --include tags --cvs-exclude --delete "$(OUTPUTDIR)"/ "$(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)"
|
||||
|
||||
{% endif %}
|
||||
{% if dropbox %}
|
||||
{% set upload = upload + ["dropbox_upload"] %}
|
||||
dropbox_upload: publish
|
||||
cp -r "$(OUTPUTDIR)"/* "$(DROPBOX_DIR)"/
|
||||
|
||||
{% endif %}
|
||||
{% if ftp %}
|
||||
{% set upload = upload + ["ftp_upload"] %}
|
||||
ftp_upload: publish
|
||||
lftp ftp://$(FTP_USER)@$(FTP_HOST) -e "mirror -R $(OUTPUTDIR) $(FTP_TARGET_DIR) ; quit"
|
||||
|
||||
{% endif %}
|
||||
{% if s3 %}
|
||||
{% set upload = upload + ["s3_upload"] %}
|
||||
s3_upload: publish
|
||||
aws s3 sync "$(OUTPUTDIR)"/ s3://$(S3_BUCKET) --acl public-read --delete
|
||||
|
||||
{% endif %}
|
||||
{% if cloudfiles %}
|
||||
{% set upload = upload + ["cf_upload"] %}
|
||||
cf_upload: publish
|
||||
cd "$(OUTPUTDIR)" && swift -v -A https://auth.api.rackspacecloud.com/v1.0 -U $(CLOUDFILES_USERNAME) -K $(CLOUDFILES_API_KEY) upload -c $(CLOUDFILES_CONTAINER) .
|
||||
|
||||
{% endif %}
|
||||
{% if github %}
|
||||
{% set upload = upload + ["github"] %}
|
||||
github: publish
|
||||
ghp-import -m "Generate Pelican site" -b $(GITHUB_PAGES_BRANCH) "$(OUTPUTDIR)"
|
||||
git push origin $(GITHUB_PAGES_BRANCH)
|
||||
|
||||
{% endif %}
|
||||
|
||||
.PHONY: html help clean regenerate serve serve-global devserver publish {{ upload|join(" ") }}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*- #
|
||||
|
||||
AUTHOR = {{author}}
|
||||
SITENAME = {{sitename}}
|
||||
SITEURL = ''
|
||||
|
||||
PATH = 'content'
|
||||
|
||||
TIMEZONE = {{timezone}}
|
||||
|
||||
DEFAULT_LANG = {{lang}}
|
||||
|
||||
# Feed generation is usually not desired when developing
|
||||
FEED_ALL_ATOM = None
|
||||
CATEGORY_FEED_ATOM = None
|
||||
TRANSLATION_FEED_ATOM = None
|
||||
AUTHOR_FEED_ATOM = None
|
||||
AUTHOR_FEED_RSS = None
|
||||
|
||||
# Blogroll
|
||||
LINKS = (('Pelican', 'https://getpelican.com/'),
|
||||
('Python.org', 'https://www.python.org/'),
|
||||
('Jinja2', 'https://palletsprojects.com/p/jinja/'),
|
||||
('You can modify those links in your config file', '#'),)
|
||||
|
||||
# Social widget
|
||||
SOCIAL = (('You can add links in your config file', '#'),
|
||||
('Another social link', '#'),)
|
||||
|
||||
DEFAULT_PAGINATION = {{default_pagination}}
|
||||
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
#RELATIVE_URLS = True
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*- #
|
||||
|
||||
# This file is only used if you use `make publish` or
|
||||
# explicitly specify it as your config file.
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.curdir)
|
||||
from pelicanconf import *
|
||||
|
||||
# If your site is available via HTTPS, make sure SITEURL begins with https://
|
||||
SITEURL = '{{siteurl}}'
|
||||
RELATIVE_URLS = False
|
||||
|
||||
FEED_ALL_ATOM = 'feeds/all.atom.xml'
|
||||
CATEGORY_FEED_ATOM = 'feeds/{slug}.atom.xml'
|
||||
|
||||
DELETE_OUTPUT_DIRECTORY = True
|
||||
|
||||
# Following items are often useful when publishing
|
||||
|
||||
#DISQUS_SITENAME = ""
|
||||
#GOOGLE_ANALYTICS = ""
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
from invoke import task
|
||||
from invoke.main import program
|
||||
from invoke.util import cd
|
||||
from pelican import main as pelican_main
|
||||
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
|
||||
from pelican.settings import DEFAULT_CONFIG, get_settings_from_file
|
||||
|
||||
OPEN_BROWSER_ON_SERVE = True
|
||||
SETTINGS_FILE_BASE = 'pelicanconf.py'
|
||||
SETTINGS = {}
|
||||
SETTINGS.update(DEFAULT_CONFIG)
|
||||
LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
|
||||
SETTINGS.update(LOCAL_SETTINGS)
|
||||
|
||||
CONFIG = {
|
||||
'settings_base': SETTINGS_FILE_BASE,
|
||||
'settings_publish': 'publishconf.py',
|
||||
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
|
||||
'deploy_path': SETTINGS['OUTPUT_PATH'],
|
||||
{% if ssh %}
|
||||
# Remote server configuration
|
||||
'ssh_user': '{{ssh_user}}',
|
||||
'ssh_host': '{{ssh_host}}',
|
||||
'ssh_port': '{{ssh_port}}',
|
||||
'ssh_path': '{{ssh_target_dir}}',
|
||||
{% endif %}
|
||||
{% if cloudfiles %}
|
||||
# Rackspace Cloud Files configuration settings
|
||||
'cloudfiles_username': '{{cloudfiles_username}}',
|
||||
'cloudfiles_api_key': '{{cloudfiles_api_key}}',
|
||||
'cloudfiles_container': '{{cloudfiles_container}}',
|
||||
{% endif %}
|
||||
{% if github %}
|
||||
# Github Pages configuration
|
||||
'github_pages_branch': '{{github_pages_branch}}',
|
||||
'commit_message': "'Publish site on {}'".format(datetime.date.today().isoformat()),
|
||||
{% endif %}
|
||||
# Host and port for `serve`
|
||||
'host': 'localhost',
|
||||
'port': 8000,
|
||||
}
|
||||
|
||||
@task
|
||||
def clean(c):
|
||||
"""Remove generated files"""
|
||||
if os.path.isdir(CONFIG['deploy_path']):
|
||||
shutil.rmtree(CONFIG['deploy_path'])
|
||||
os.makedirs(CONFIG['deploy_path'])
|
||||
|
||||
@task
|
||||
def build(c):
|
||||
"""Build local version of site"""
|
||||
pelican_run('-s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def rebuild(c):
|
||||
"""`build` with the delete switch"""
|
||||
pelican_run('-d -s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def regenerate(c):
|
||||
"""Automatically regenerate site upon file modification"""
|
||||
pelican_run('-r -s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def serve(c):
|
||||
"""Serve site at http://$HOST:$PORT/ (default is localhost:8000)"""
|
||||
|
||||
class AddressReuseTCPServer(RootedHTTPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
server = AddressReuseTCPServer(
|
||||
CONFIG['deploy_path'],
|
||||
(CONFIG['host'], CONFIG['port']),
|
||||
ComplexHTTPRequestHandler)
|
||||
|
||||
if OPEN_BROWSER_ON_SERVE:
|
||||
# Open site in default browser
|
||||
import webbrowser
|
||||
webbrowser.open("http://{host}:{port}".format(**CONFIG))
|
||||
|
||||
sys.stderr.write('Serving at {host}:{port} ...\n'.format(**CONFIG))
|
||||
server.serve_forever()
|
||||
|
||||
@task
|
||||
def reserve(c):
|
||||
"""`build`, then `serve`"""
|
||||
build(c)
|
||||
serve(c)
|
||||
|
||||
@task
|
||||
def preview(c):
|
||||
"""Build production version of site"""
|
||||
pelican_run('-s {settings_publish}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def livereload(c):
|
||||
"""Automatically reload browser tab upon file modification."""
|
||||
from livereload import Server
|
||||
|
||||
def cached_build():
|
||||
cmd = '-s {settings_base} -e CACHE_CONTENT=True LOAD_CONTENT_CACHE=True'
|
||||
pelican_run(cmd.format(**CONFIG))
|
||||
|
||||
cached_build()
|
||||
server = Server()
|
||||
theme_path = SETTINGS['THEME']
|
||||
watched_globs = [
|
||||
CONFIG['settings_base'],
|
||||
'{}/templates/**/*.html'.format(theme_path),
|
||||
]
|
||||
|
||||
content_file_extensions = ['.md', '.rst']
|
||||
for extension in content_file_extensions:
|
||||
content_glob = '{0}/**/*{1}'.format(SETTINGS['PATH'], extension)
|
||||
watched_globs.append(content_glob)
|
||||
|
||||
static_file_extensions = ['.css', '.js']
|
||||
for extension in static_file_extensions:
|
||||
static_file_glob = '{0}/static/**/*{1}'.format(theme_path, extension)
|
||||
watched_globs.append(static_file_glob)
|
||||
|
||||
for glob in watched_globs:
|
||||
server.watch(glob, cached_build)
|
||||
|
||||
if OPEN_BROWSER_ON_SERVE:
|
||||
# Open site in default browser
|
||||
import webbrowser
|
||||
webbrowser.open("http://{host}:{port}".format(**CONFIG))
|
||||
|
||||
server.serve(host=CONFIG['host'], port=CONFIG['port'], root=CONFIG['deploy_path'])
|
||||
|
||||
{% if cloudfiles %}
|
||||
@task
|
||||
def cf_upload(c):
|
||||
"""Publish to Rackspace Cloud Files"""
|
||||
rebuild(c)
|
||||
with cd(CONFIG['deploy_path']):
|
||||
c.run('swift -v -A https://auth.api.rackspacecloud.com/v1.0 '
|
||||
'-U {cloudfiles_username} '
|
||||
'-K {cloudfiles_api_key} '
|
||||
'upload -c {cloudfiles_container} .'.format(**CONFIG))
|
||||
{% endif %}
|
||||
|
||||
@task
|
||||
def publish(c):
|
||||
"""Publish to production via rsync"""
|
||||
pelican_run('-s {settings_publish}'.format(**CONFIG))
|
||||
c.run(
|
||||
'rsync --delete --exclude ".DS_Store" -pthrvz -c '
|
||||
'-e "ssh -p {ssh_port}" '
|
||||
'{} {ssh_user}@{ssh_host}:{ssh_path}'.format(
|
||||
CONFIG['deploy_path'].rstrip('/') + '/',
|
||||
**CONFIG))
|
||||
|
||||
{% if github %}
|
||||
@task
|
||||
def gh_pages(c):
|
||||
"""Publish to GitHub Pages"""
|
||||
preview(c)
|
||||
c.run('ghp-import -b {github_pages_branch} '
|
||||
'-m {commit_message} '
|
||||
'{deploy_path} -p'.format(**CONFIG))
|
||||
{% endif %}
|
||||
|
||||
def pelican_run(cmd):
|
||||
cmd += ' ' + program.core.remainder # allows to pass-through args to pelican
|
||||
pelican_main(shlex.split(cmd))
|
||||
Loading…
Add table
Add a link
Reference in a new issue