import logging import os import subprocess import sys import fable def _jt_path(): return os.environ['JT_PATH'] def _runcmd(ctx, argv): logging.debug('Executing %r', argv) p = subprocess.Popen( argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) out, err = p.communicate() ctx["stdout"] = out ctx["stderr"] = err ctx["exit_code"] = p.returncode logging.debug('Result: exit_code=%r', ctx['exit_code']) if ctx['exit_code'] != 0: logging.warning( 'jt failed, stdout=%r stderr=%r', ctx['stdout'], ctx['stderr']) def create_empty_journal(ctx): ctx['journal'] = os.path.abspath('journal') ctx['blog'] = os.path.join(ctx['journal'], 'blog') os.mkdir(ctx['journal']) ctx['config'] = os.path.abspath('jt.conf') with open(ctx['config'], 'w') as f: f.write('[config]\n') f.write('source = %s\n' % ctx['journal']) f.write('git = no\n') f.write('push = no\n') f.write('notes-dir = blog\n') f.write('editor = /bin/true {editor}\n') f.write('log = %s.log\n' % ctx['journal']) logging.debug('Created config file %s', ctx['config']) def run_jt(ctx, command=None): try_jt(ctx, command=command) fable.assertEqual(ctx['exit_code'], 0) def try_jt(ctx, command=None): args = command.split() assert args[0] == 'jt' opts = [ '--no-default-config', '--config', ctx['config'], ] argv = [_jt_path()] + opts + args[1:] argv = ['/bin/sh', '-c', ' '.join(argv)] _runcmd(ctx, argv) def create_empty_file(ctx, filename=None): with open(filename, 'w') as f: pass def jt_failed(ctx): fable.assertNotEqual(ctx['exit_code'], 0) def _find_drafts(ctx): draftsdir = os.path.join(ctx['journal'], 'drafts') if not os.path.isdir(draftsdir): return [] drafts = [f for f in _find_files(draftsdir) if f.endswith('.mdwn')] logging.debug('drafts = %r', drafts) return drafts def no_drafts(ctx): drafts = _find_drafts(ctx) fable.assertEqual(drafts, []) def one_draft(ctx): drafts = _find_drafts(ctx) fable.assertEqual(len(drafts), 1) def one_draft_with_attachment(ctx, filename=None): drafts = _find_drafts(ctx) fable.assertEqual(len(drafts), 1) filename = drafts[0] fable.assertTrue(filename.endswith('.mdwn')) dirname = filename[:-len('.mdwn')] fable.assertTrue(os.path.isdir(dirname)) attachment = os.path.join(dirname, filename) fable.assertTrue(os.path.exists(attachment)) def n_drafts(ctx, count=None): n = int(count) drafts = _find_drafts(ctx) fable.assertEqual(len(drafts), n) def _get_draft(ctx, id): filename = os.path.join(ctx['journal'], 'drafts', '%s.mdwn' % id) return _cat(filename) def draft_has_title(ctx, id=None, title=None): draft = _get_draft(ctx, id) fable.assertTrue(title in draft) def _find_files(dirname): for d, s, f in os.walk(dirname): for filename in f: yield os.path.join(d, filename) def _find_entries(ctx): blogdir = ctx['blog'] logging.debug('blogdir: %r', blogdir) if not os.path.isdir(blogdir): return [] entries = [f for f in _find_files(blogdir) if f.endswith('.mdwn')] logging.debug('entries = %r', entries) return entries def one_entry(ctx): entries = _find_entries(ctx) fable.assertEqual(len(entries), 1) def n_entries(ctx, count=None): n = int(count) entries = _find_entries(ctx) fable.assertEqual(len(entries), n) def no_entries(ctx): entries = _find_entries(ctx) fable.assertEqual(len(entries), 0) def _find_topics(ctx): dirname = os.path.join(ctx['journal'], 'topics') filenames = [f for f in _find_files(dirname) if f.endswith('.mdwn')] logging.debug('topics: %r', filenames) return filenames def _cat(filename): with open(filename) as f: return f.read() def one_topic(ctx, topic=None, title=None): topics = _find_topics(ctx) fable.assertEqual(len(topics), 1) topic = _cat(topics[0]) fable.assertTrue(title in topic)