Пример #1
0
def start(base):
    generic.exit_cleanly()
    # http://stackoverflow.com/questions/11423225
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)

    plugins = os.path.join(base, "plugins")
    if not os.path.isdir(plugins):
        generic.error("no plugins directory: `%s`" % plugins, E_NO_PLUGINS)

    # TODO: Check for broken symlinks
    generic.populate(saxo_path, base)

    opt = configparser.ConfigParser()
    config = os.path.join(base, "config")
    opt.read(config)
    # TODO: defaulting?

    scripts = os.path.dirname(sys.modules["__main__"].__file__)
    scripts = os.path.abspath(scripts)

    sockname =  os.path.join(base, "client.sock")
    serve(sockname, incoming)
    os.chmod(sockname, 0o600)

    def remove_sock(sockname):
        os.remove(sockname)
    atexit.register(remove_sock, sockname)

    generic.thread(scheduler.start, base, incoming)

    saxo = Saxo(base, opt)
    saxo.run()
Пример #2
0
def stop(args):
    if args.directory is None:
        directory = os.path.expanduser("~/.saxo")
    else:
        directory = args.directory

    pidfile = os.path.join(directory, "pid")
    if not os.path.exists(pidfile):
        generic.error("There is no bot currently running")

    with open(pidfile, encoding="ascii") as f:
        text = f.read()
        pid = int(text.rstrip("\n"))

    # TODO: Make this less crude
    os.kill(pid, signal.SIGTERM)
    # os.kill(pid, signal.SIGKILL)

    return 0
Пример #3
0
def main(argv, v):
    # NOTE: No default for argv, because what script name would we use?

    parser = argparse.ArgumentParser(description="Control saxo irc bot instances",
        add_help=False)

    parser.add_argument("-f", "--foreground", action="store_true",
        help="run in the foreground instead of as a daemon")

    parser.add_argument("-h", "--help", action="store_true",
        help="show a short help message")

    parser.add_argument("-o", "--output", metavar="filename",
        help="redirect daemon stdout and stderr to this filename")

    parser.add_argument("-v", "--version", action="store_true",
        help="show the current saxo version")

    parser.add_argument("action", nargs="?",
        help="use --help to show the available actions")

    parser.add_argument("directory", nargs="?",
        help="the path to the saxo configuration directory")

    args = parser.parse_args(argv[1:])

    if args.help:
        help(args, v)

    elif args.version:
        version(args, v)

    elif args.action:
        if args.action in action.names:
            code = action.names[args.action](args)
            if isinstance(code, int):
                sys.exit(code)
        else:
            generic.error("unrecognised action: %s" % args.action, code=2)

    else:
        usage(args, v)
Пример #4
0
def default(base=None):
    if base is None:
        base = os.path.expanduser("~/.saxo")

    if os.path.isdir(base):
        generic.error("the directory `%s` already exists" % base,
            E_DIRECTORY_EXISTS)

    try: os.makedirs(base)
    except Exception as err:
        generic.error("could not create the directory `%s`" % base,
            E_UNMAKEABLE_DIRECTORY, err)

    config = os.path.join(base, "config")
    try:
        with open(config, "w", encoding="ascii") as f:
            # Generates a random bot name, from saxo00000 to saxo99999 inclusive
            f.write(DEFAULT_CONFIG % random.randrange(0, 100000))
    except Exception as err:
        generic.error("could not write the config file `%s`" % config,
            E_UNWRITEABLE_CONFIG, err)

    plugins = os.path.join(base, "plugins")
    os.mkdir(plugins)

    commands = os.path.join(base, "commands")
    os.mkdir(commands)

    generic.populate(saxo_path, base)

    print("Created %s" % config)
    print("Modify this file with your own settings, and then run:")
    print("")
    print("    %s start" % sys.argv[0])

    return True
Пример #5
0
def test_logging():
    from generic import log,message,warn,error
    from generic import generic_settings,NexusError

    # send messages to object rather than stdout
    divert_nexus_log()

    logfile = generic_settings.devlog

    # test log
    #   simple message
    s = 'simple message'
    logfile.reset()
    log(s)
    assert(logfile.s==s+'\n')

    #   list of items
    items = ['a','b','c',1,2,3]
    logfile.reset()
    log(*items)
    assert(logfile.s=='a b c 1 2 3 \n')

    #   message with indentation
    s = 'a message\nwith indentation'
    logfile.reset()
    log(s,indent='  ')
    assert(logfile.s=='  a message\n  with indentation\n')

    logfile.reset()
    log(s,indent='msg: ')
    assert(logfile.s=='msg: a message\nmsg: with indentation\n')
    
    #   writing to separate log files
    logfile2 = FakeLog()
    s1 = 'message to log 1'
    s2 = 'message to log 2'
    logfile.reset()
    logfile2.reset()
    log(s1)
    assert(logfile.s==s1+'\n')
    assert(logfile2.s=='')

    logfile.reset()
    logfile2.reset()
    log(s2,logfile=logfile2)
    assert(logfile.s=='')
    assert(logfile2.s==s2+'\n')
    

    # test warn
    logfile.reset()
    s = 'this is a warning'
    warn(s)
    so = '''
  warning:
    this is a warning
'''
    assert(logfile.s==so)
    logfile.reset()
    s = 'this is a warning'
    warn(s,header='Special')
    so = '''
  Special warning:
    this is a warning
'''
    assert(logfile.s==so)

    # test error
    #   in testing environment, should raise an error
    try:
        error('testing environment')
        raise FailedTest
    except NexusError:
        None
    except FailedTest:
        failed()
    except Exception as e:
        failed(str(e))
    #end try
    #   in standard/user environment, should print message
    generic_settings.raise_error = False
    logfile.reset()
    error('this is an error',header='User',exit=False)
    so = '''
  User error:
    this is an error
'''
    assert(logfile.s==so)
    generic_settings.raise_error = True
    #   in testing environment, should raise an error
    try:
        error('testing environment')
        raise FailedTest
    except NexusError:
        None
    except FailedTest:
        failed()
    except Exception as e:
        failed(str(e))
    #end try

    restore_nexus_log()
Пример #6
0
 def on_background_change(self, base_path):
     error("NOTE: I3WM has not been implemented yet. ")
     pass
Пример #7
0
 def write_colours_to_file(self, colours, _ ):
     error("NOTE: I3WM has not been implemented yet. ")
     pass
Пример #8
0
 def format_colours_for_file(self, colours):
     error("NOTE: I3WM has not been implemented yet. ")
     pass
Пример #9
0
 def __init__(self):
     super(I3wm, self).__init__("I3 Window Manager")
     error("NOTE: I3WM has not been implemented yet. ")
Пример #10
0
    import generic

E_PYTHON_VERSION = """
Your version of the python programming language is too old to run saxo. Use a
newer version if available. Otherwise you can get a newer version from here:

    http://www.python.org/

Or install one using your system's package manager. If you are using OS X for
example, python3 can be installed using homebrew:

    http://mxcl.github.io/homebrew/
"""

if sys.version_info < (3, 3):
    generic.error("requires python 3.3 or later", E_PYTHON_VERSION)

def action(function):
    action.names[function.__name__] = function
    return function
action.names = {}

# Options

def version(args, v):
    print("saxo %s" % v)

USAGE = """
Usage:
    saxo -v
    saxo create [ directory ]
Пример #11
0
def check_keyspec_groups():
    from generic import error, warn

    groups = GamessInput.keyspec_groups
    group_order = GamessInput.group_order
    glist = []
    for group_name in group_order:
        if group_name in groups:
            glist.append(group_name)
        #end if
    #end for

    err = ''
    wrn = ''

    #check for unrecognized groups
    extra_groups = set(groups.keys()) - set(group_order)
    if len(extra_groups) > 0:
        err += '  encountered unrecognized keyspec groups: {0}\n'.format(
            sorted(extra_groups))
    #end if

    #check that integers, reals, bools, strings, and arrays are non-overlapping subsets of keywords
    #check that allowed_values are a subset of keywords and values specified are of the correct type
    for group_name in glist:
        g = groups[group_name]
        go = obj(integers=g.integers,
                 reals=g.reals,
                 bools=g.bools,
                 strings=g.strings,
                 arrays=g.arrays)
        overlaps = obj()
        for tname1, tset1 in go.items():
            for tname2, tset2 in go.items():
                if tname1 != tname2:
                    overlap = tset1 & tset2
                    if len(overlap) > 0:
                        overlaps[tname1, tname2] = sorted(overlap)
                    #end if
                #end if
            #end for
        #end for
        if len(overlaps) > 0:
            msg = '  keyspec group {0} has overlapping keywords'.format(
                g.__name__)
            for tname1, tname2 in sorted(overlaps.keys()):
                msg += '    \n {0} {1} overlap: {2}\n'.format(
                    tname1, tname2, overlaps[tname1, tname2])
            #end for
            err += msg
        #end if
        for tname in sorted(go.keys()):
            extra_keys = go[tname] - g.keywords
            if len(extra_keys) > 0:
                err += '  keyspec group {0} has unrecognized {1} keywords:\n    {2}\n'.format(
                    g.__name__, tname, sorted(extra_keys))
            #end if
        #end for
        extra_keys = set(g.allowed_values.keys()) - g.keywords
        if len(extra_keys) > 0:
            err += '  keyspec group {0} has unrecognized allowed_value keywords:\n    {1}\n'.format(
                g.__name__, sorted(extra_keys))
        #end if
        type_keys = set()
        for keys in go:
            type_keys |= keys
        #end for
        undefined = g.keywords - type_keys
        if len(undefined) > 0:
            err += '  keyspec group {0} has keywords w/o type assignment:\n    {1}\n'.format(
                g.__name__, sorted(undefined))
        #end if

        #check that allowed values for each keyword have the right type
        to = obj(integers=int,
                 reals=float,
                 bools=bool,
                 strings=str,
                 arrays=ndarray)
        for tname in sorted(go.keys()):
            type = to[tname]
            for kw in sorted(go[tname]):
                if kw in g.allowed_values:
                    for val in g.allowed_values[kw]:
                        if not isinstance(val, type):
                            err += '  allowed values of {0} keyword {1} are not all {2}: {3}\n'.format(
                                g.__name__, kw, tname,
                                sorted(g.allowed_values[kw]))
                            break
                        #end if
                    #end for
                #end if
            #end for
        #end for
    #end for

    #note any overlapping keywords between groups (this is a feature, not an error)
    overlaps = obj()
    for gname1 in glist:
        kw1 = groups[gname1].keywords
        for gname2 in glist:
            kw2 = groups[gname2].keywords
            if gname1 != gname2:
                overlap = kw1 & kw2
                if len(overlap) > 0:
                    tup = tuple(sorted((gname1, gname2)))
                    overlaps[tup] = sorted(overlap)
                #end if
            #end if
        #end for
    #end for
    if len(overlaps) > 0:
        wrn += '\n  Note: some groups have overlapping keywords\n'
        for gname1, gname2 in sorted(overlaps.keys()):
            wrn += '    groups {0} and {1} have overlapping keywords:\n      {2}\n'.format(
                gname1, gname2, overlaps[gname1, gname2])
        #end for
    #end if

    #note any overlapping keyword and group names (also a feature)
    overlap = GamessInput.all_keywords & set(GamessInput.group_order)
    if len(overlap) > 0:
        wrn += '\n  Note: some group names overlap with keywords:\n    {0}\n'.format(
            sorted(overlap))
    #end if

    if len(err) > 0:
        error(err)
    #end if
    if len(wrn) > 0:
        warn(wrn)