From 66d1ca3827cd4c83c7fc93c7c10148263ce3680f Mon Sep 17 00:00:00 2001 From: oysteini Date: Sat, 8 Oct 2011 10:13:32 +0000 Subject: [PATCH] Fisket inn litt mer kode fra forrige inkarnasjon. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Har nĂ¥ kommandolinjetolking, men implementasjonene av kommandoene er tomme. --- cli/util.py | 20 ++++++ cli/worblehat.py | 161 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 180 insertions(+), 1 deletion(-) diff --git a/cli/util.py b/cli/util.py index 9c0cda1..a4504e6 100644 --- a/cli/util.py +++ b/cli/util.py @@ -63,3 +63,23 @@ def cut_str(string, length, ellipsis='...'): if len(string) < length: return string return string[0:length-len(ellipsis)]+ellipsis + +def combine_dicts(*dicts): + res = {} + for d in dicts: + res.update(d) + return res + +def run_editor(filename): + if os.path.exists(filename): + os.system("%s %s || /usr/bin/env vi %s" % + (os.getenv("EDITOR"), filename, filename)) + else: + exit("Error: %s: File does not exist!" % filename) + +def write_tmpfile(pfix='', content=''): + file = tempfile.NamedTemporaryFile(prefix=pfix+'-', dir='/tmp', delete=False) + file.write(content.encode(file_encoding)) + name = file.name + file.close() + return name diff --git a/cli/worblehat.py b/cli/worblehat.py index 316bc76..834dd93 100644 --- a/cli/worblehat.py +++ b/cli/worblehat.py @@ -1,3 +1,8 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import getopt import pgdb from fileformat import read_actionlist, write_actionlist from util import * @@ -8,5 +13,159 @@ connection = pgdb.connect(database='oysteini_pbb2', host='postgres.pvv.ntnu.no'); c = connection.cursor() -c.execute('SELECT * from bok') +c.execute('SELECT * from book') print fetchall_dict(c) + +def show(ids, commit_format=False, tmp_file=False): + pass + +def list_cmd(what): + pass + +def search_book(search_strings, search_description=False): + pass + +def search_person(search_strings): + pass + +def commit(filename=None): + pass + +def edit(ids): + pass + +def map_cmd(shelfname=None, category=None): + pass + +commands = { 'show': + { 'args': [('ids', (1,None))], + 'options': ['commit_format', 'tmp_file'], + 'fun': show }, + 'list': + { 'args': [('what', (1,1))], + 'options': [], + 'fun': list_cmd }, + 'search': + { 'args': [('search_strings', (1,None))], + 'options': ['search_description'], + 'fun': search_book }, + 'search-person': + { 'args': [('search_strings', (1,None))], + 'options': [], + 'fun': search_person }, + 'commit': + { 'args': [('filename', (0,1))], + 'options': [], + 'fun': commit }, + 'edit': + { 'args': [('ids', (1,None))], + 'options': [], + 'fun': edit }, + 'map': + { 'args': [('shelfname', (0,1)), ('category', (0,1))], + 'options': [], + 'fun': map_cmd } + } + +flags = { 'commit_format': + { 'help': 'output data in the format expected by the commit command' }, + 'tmp_file': + { 'help': 'output data to a new temporary file instead of to stdout' }, + 'search_description': + { 'help': 'include description field when searching' } + } + +general_options = [] # options applicable to all commands + +class BadCommandLine(Exception): + def __init__(self, msg): + Exception.__init__(self, 'Bad command line: ' + msg) + +def check_command_args(args, command): + cmd_decl = commands[command] + min_num_args = sum(map(lambda a: a[1][0], cmd_decl['args'])) + unlimited = any(map(lambda a: a[1][1] == None, cmd_decl['args'])) + if not unlimited: + max_num_args = sum(map(lambda a: a[1][1], cmd_decl['args'])) + if len(args) < min_num_args: + raise BadCommandLine('Too few arguments for command %s (expects at least %d, %d given).' + % (command, min_num_args, len(args))) + if (not unlimited) and (len(args) > max_num_args): + raise BadCommandLine('Too many arguments for command %s (expects at most %d, %d given).' + % (command, max_num_args, len(args))) + +def check_command_opts(opts, command): + cmd_decl = commands[command] + for opt,val in opts: + if ((opt not in cmd_decl['options']) and + (opt not in general_options)): + raise BadCommandLine('Option %s not applicable to command %s.' + % (opt, command)) + +def assign_command_args(args, command): + cmd_decl = commands[command] + d = {} + i = 0 + for param in cmd_decl['args']: + pname = param[0] + pmin = param[1][0] + pmax = param[1][1] + if pmax == 1: + if i < len(args): + d[pname] = args[i] + i += 1 + else: + d[pname] = None + else: + d[pname] = [] + j = 0 + while i + j < len(args) and (pmax == None or j < pmax): + d[pname].append(args[i + j]) + j += 1 + i = i + j + return d + +def assign_command_opts(opts, command): + d = {} + for option, value in opts: + if option in flags: + d[option] = True + else: + d[option] = value + return d + +def parse_cmdline(args): + def getopt_option_name(internal_name): + return internal_name.replace('_', '-') + def internal_option_name(getopt_ret_name): + return getopt_ret_name[2:].replace('-', '_') + + option_names = map(getopt_option_name, flags) + + options, args = getopt.getopt(args, '', option_names) + + if len(args) == 0: + raise BadCommandLine('No command specified.') + cmd_name = args[0] + if cmd_name not in commands: + raise BadCommandLine('Nonexisting command %s.' % cmd_name) + cmd_decl = commands[cmd_name] + cmd_args = args[1:] + cmd_opts = map(lambda (opt,val): (internal_option_name(opt), val), + options) + + check_command_args(cmd_args, cmd_name) + check_command_opts(cmd_opts, cmd_name) + + return { 'command': cmd_name, + 'args': combine_dicts(assign_command_args(cmd_args, cmd_name), + assign_command_opts(cmd_opts, cmd_name)) } + +def invoke_command(command, args): + cmd_decl = commands[command] + cmd_decl['fun'](**args) + +cmdline_parsed = parse_cmdline(sys.argv[1:]) +print 'command line parsed to:', cmdline_parsed +invoke_command(cmdline_parsed['command'], + cmdline_parsed['args'])