instance.py

Sat, 20 Jan 2018 19:57:05 +0000

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sat, 20 Jan 2018 19:57:05 +0000
changeset 10
76dbfb06eba0
parent 7
e189d4a6cb8c
child 12
16a8c63344c0
permissions
-rw-r--r--

Semi-working menu items.

NOTES:

Python closures suck dog's balls... first and the last program I
write in Python until somebody fixes the brain-damaged scoping
that requires word _b=b hacks etc. to get normal behaviour.
See also http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/

Rumps also sucks, apparently no way to update single menu items, one
always has to rebuild the entire menu. Spent hours trying to get it to
work until giving in.

#
# Borgend borg launcher / processor
#

import json
import logging
from subprocess import Popen, PIPE
from config import settings, arglistify

necessary_opts=['--log-json', '--progress']

necessary_opts_for={
    'create': ['--json'],
    'info': ['--json'],
    'list': ['--json'],
}

class BorgInstance:
    def __init__(self, operation, archive_or_repository, args, argsl):
        self.operation=operation;
        self.args=args;
        self.archive_or_repository=archive_or_repository;
        self.argsl=argsl;

    def construct_cmdline(self):
        cmd=([settings['borg']['executable']]+necessary_opts+
             arglistify(settings['borg']['common_parameters'])+
             [self.operation])
        tmp1=self.operation+'_parameters'
        if tmp1 in settings['borg']:
            cmd=cmd+arglistify(settings['borg'][tmp1])

        if self.operation in necessary_opts_for:
            cmd=cmd+necessary_opts_for[self.operation]

        return cmd+arglistify(self.args)+[self.archive_or_repository]+self.argsl

    def launch(self):
        cmd=self.construct_cmdline()

        logging.info('Launching ' + str(cmd))

        self.proc=Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=None)

    def read_result(self):
        stream=self.proc.stdout
        line=stream.read(-1)
        if line==b'':
            logging.debug('Borg stdout pipe EOF?')
            return None

        try:
            return json.loads(line)
        except:
            logging.warning('JSON parse failed on: "%s"' % line)
            return None

    def read_log(self):
        stream=self.proc.stderr
        try:
            line=stream.readline()
        except err:
            logging.debug('Pipe read failed: %s' % str(err))

            return {'type': 'exception', 'exception': err}

        if line==b'':

            logging.debug('Borg stderr pipe EOF?')

            return None

        try:
            res=json.loads(line)
            if 'type' not in res:
                res['type']='UNKNOWN'
            return res
        except:
            logging.debug('JSON parse failed on: "%s"' % line)

            errmsg=line
            for line in iter(stream.readline, b''):
                errmsg=errmsg+line

            return {'type': 'unparsed_error', 'message': str(errmsg)}

    def terminate(self):
        self.proc.terminate()

    def wait(self):
        return self.proc.wait() is not None

    def has_terminated(self):
        return self.proc.poll() is not None

mercurial