summaryrefslogtreecommitdiff
path: root/yarns/lib.py
diff options
context:
space:
mode:
Diffstat (limited to 'yarns/lib.py')
-rw-r--r--yarns/lib.py165
1 files changed, 165 insertions, 0 deletions
diff --git a/yarns/lib.py b/yarns/lib.py
new file mode 100644
index 0000000..d7c8a13
--- /dev/null
+++ b/yarns/lib.py
@@ -0,0 +1,165 @@
+# Copyright 2019 Lars Wirzenius
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+
+import base64
+import errno
+import json
+import os
+import random
+import re
+import signal
+import socket
+import subprocess
+import sys
+import time
+import urllib
+
+import cliapp
+import requests
+
+from yarnutils import *
+
+
+
+class EffiAPI:
+
+ config_filename = 'effiapi.json'
+
+ def __init__(self, variables):
+ self.v = variables
+
+ def write_config(self):
+ with open(self.config_filename, 'w') as f:
+ json.dump(self.get_config(), f, indent=4)
+
+ def get_config(self):
+ return {
+ 'faks': True,
+ 'muck-url': 'xxx',
+ 'log': 'effiapi.log',
+ 'pid': 'effiapi.pid',
+ 'host': '127.0.0.1',
+ 'port': 8080,
+ }
+
+ def start(self):
+ config = self.get_config()
+ self.v['baseurl'] = 'http://{}:{}'.format(
+ config['host'], config['port'])
+
+ effiapi = os.path.join(srcdir, 'effiapi')
+ self.daemonize([effiapi, self.config_filename])
+
+ self.wait_for_port(config['host'], config['port'])
+
+ def terminate(self):
+ config = self.get_config()
+ with open(config['pid']) as f:
+ pid = int(f.read().strip())
+ os.kill(pid, signal.SIGTERM)
+
+ def daemonize(self, argv):
+ prefix = [
+ '/usr/sbin/daemonize', '-o', 'stdout', '-e', 'stderr', '-c', '.'
+ ]
+ subprocess.check_call(prefix + argv)
+
+ def wait_for_port(self, host, port):
+ MAX = 5
+ t = time.time()
+ while time.time() < t + MAX:
+ try:
+ s = socket.socket()
+ s.connect((host, port))
+ except socket.error:
+ time.sleep(0.1)
+ except OSError as e:
+ raise
+ else:
+ return
+
+ def POST(self, path, headers, body):
+ headers['Content-Type'] = 'application/json'
+ body = json.dumps(body)
+ self.request(requests.post, path, headers, body)
+
+ def GET(self, path, headers, body):
+ self.request(requests.get, path, headers, body)
+
+ def request(self, func, path, headers, body):
+ url = '{}{}'.format(self.v['baseurl'], path)
+ self.v['request'] = {
+ 'url': url,
+ 'func': repr(func),
+ 'headers': headers,
+ 'body': body,
+ }
+
+ r = func(url, headers=headers, data=body)
+ self.v['response'] = {
+ 'status_code': r.status_code,
+ 'body': r.text,
+ 'headers': dict(r.headers),
+ }
+
+ def get_status_code(self):
+ r = self.v['response']
+ return r['status_code']
+
+ def get_header(self, name):
+ r = self.v['response']
+ return r['headers'].get(name, '')
+
+ def get_json_body(self):
+ r = self.v['response']
+ return json.loads(r['body'])
+
+
+def get_json_match():
+ match = get_next_match()
+ return json.loads(match)
+
+
+def save_for_expansion(name, value):
+ V[name] = value
+
+
+def get_expanded_match():
+ match = get_next_match()
+ print 'match', match
+ return expand(match, V)
+
+
+def expand(text, variables):
+ result = ''
+ while text:
+ print 'expand: text=%r' % text
+ m = re.search(r'\${(?P<name>[^}]+)}', text)
+ if not m:
+ result += text
+ break
+ name = m.group('name')
+ print('expanding ', name, repr(variables[name]))
+ result += text[:m.start()] + variables[name]
+ text = text[m.end():]
+ print 'expand: result=%r' % result
+ return result
+
+
+srcdir = os.environ['SRCDIR']
+datadir = os.environ['DATADIR']
+V = Variables(datadir)
+effiapi = EffiAPI(V)