Beispiel #1
0
def show(identifiers, uuid, print_groups):
    from aiida.common.exceptions import NotExistent
    from aiida.common.exceptions import MultipleObjectsError

    if not is_dbenv_loaded():
        load_dbenv()

    for id in identifiers:
        try:
            if uuid:
                try:
                    n = load_node(uuid=id)
                except MultipleObjectsError:
                    click.echo("More than one node found. Please provide "
                               "longer starting pattern for uuid.", err=True)
                    return
            else:
                try:
                    ids = int(id)
                except ValueError:
                    click.echo("The pk/id can not be a string. Please provide "
                               "an integer.", err=True)
                    return
                n = load_node(pk=int(ids))
            print_node_info(n, print_groups=print_groups)
        except NotExistent as e:
            click.echo(e.message, err=True)
            sys.exit(1)

        if len(identifiers) > 1:
            click.echo("")
Beispiel #2
0
    def calculation_gotocomputer(self, *args):
        """
        Open a shell to the calc folder on the cluster

        This command opens a ssh connection to the scratch folder on the remote
        computer on which the calculation is being/has been executed.
        """
        from aiida.common.exceptions import NotExistent
        if not is_dbenv_loaded():
            load_dbenv()

        try:
            calc_id = args[0]
        except IndexError:
            print >> sys.stderr, "Pass as further argument a calculation ID or UUID."
            sys.exit(1)
        try:
            pk = int(calc_id)
            is_pk = True
        except ValueError:
            uuid = calc_id
            is_pk = False

        print "Loading environment..."
        from aiida.orm import JobCalculation

        try:
            if is_pk:
                calc = load_node(pk)
            else:
                calc = load_node(uuid)
        except NotExistent:
            print >> sys.stderr, "No node exists with ID={}.".format(calc_id)
            sys.exit(1)

        if not isinstance(calc, JobCalculation):
            print >> sys.stderr, "Node with ID={} is not a calculation; it is a {}".format(
                calc_id, calc.__class__.__name__)
            sys.exit(1)

        # get the transport
        try:
            t = calc._get_transport()
        except NotExistent as e:
            print >> sys.stderr, e.message
            sys.exit(1)
        # get the remote directory
        remotedir = calc._get_remote_workdir()
        if not remotedir:
            print >> sys.stderr, "No remote work directory is set for this calculation!"
            print >> sys.stderr, "(It is possible that the daemon did not submit the calculation yet)"
            sys.exit(1)

        # get the command to run (does not require to open the connection!)
        cmd_to_run = t.gotocomputer_command(remotedir)
        # Connect (execute command)
        print "Going the the remote folder..."
        # print cmd_to_run
        os.system(cmd_to_run)
Beispiel #3
0
    def calculation_outputls(self, *args):
        """
        Show the list of output files of a calculation node.

        It lists the files in the 'path' subdirectory of the output node
        of files retrieved by the parser. Therefore, this will not work
        before files are retrieved by the daemon.
        Use the -h option for more help on the command line options.
        """
        import argparse
        from aiida.common.exceptions import NotExistent
        from aiida.cmdline.commands.node import list_repo_files

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='List ourput files in the repository folder.')

        parser.add_argument('calc',
                            metavar='PK',
                            type=int,
                            help='The pk of the calculation')
        parser.add_argument('-p',
                            '--path',
                            type=str,
                            default='',
                            nargs='?',
                            help="The relative path of the file you "
                            "want to show. If not specified, show content"
                            " of all the 'path' directory")
        parser.add_argument('-c',
                            '--color',
                            action='store_true',
                            help="Color folders with a different color")

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        try:
            calc = load_node(parsed_args.calc)
        except NotExistent as e:
            print >> sys.stderr, e.message
            sys.exit(1)

        try:
            parsed_node = calc.out.retrieved
        except AttributeError:
            print >> sys.stderr, ("No 'retrieved' node found. Have the "
                                  "calculation files already been retrieved?")
            sys.exit(1)

        try:
            list_repo_files(parsed_node, os.path.join('path',
                                                      parsed_args.path),
                            parsed_args.color)
        except ValueError as e:
            print >> sys.stderr, e.message
            sys.exit(1)
Beispiel #4
0
    def run(self, *args):
        """
        Show node information.
        """
        import argparse
        from aiida.common.exceptions import NotExistent

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Show information of a node.')
        parser.add_argument('pk', type=int, default=None, nargs="+",
                            help="ID of the node.")
        parser.add_argument('-d', '--depth', action='store', default=1,
                            metavar="N", type=int,
                            help="Add children of shown nodes up to Nth "
                                 "level. Default 0")

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        for pk in parsed_args.pk:
            try:
                n = load_node(pk)
                self.print_node_tree(n, parsed_args.depth)
            except NotExistent as e:
                print >> sys.stderr, e.message
                sys.exit(1)

            if len(parsed_args.pk) > 1:
                print ""
Beispiel #5
0
    def comment_remove(self, *args):
        """
        Remove comments. The user can only remove its own comments
        """
        # Note: in fact, the user can still manually delete any comment
        import argparse
        from aiida.backends.utils import get_automatic_user

        if not is_dbenv_loaded():
            load_dbenv()
        user = get_automatic_user()

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Remove comments of a node.')
        parser.add_argument('pk', metavar='PK', type=int,
                            help='The pk (an integer) of the node')
        parser.add_argument('id', metavar='ID', type=int, default=None, nargs='?',
                            help='#ID of the comment to be removed from node #PK')
        parser.add_argument('-a', '--all', action='store_true', default=False,
                            help='If used, deletes all the comments of the active user attached to the node')
        parsed_args = parser.parse_args(args)

        if parsed_args.id is None and not parsed_args.all:
            print "One argument between -a and ID must be provided"
            sys.exit(1)
        if parsed_args.id is not None and parsed_args.all:
            print "Only one between -a and ID should be provided"
            sys.exit(1)

        node = load_node(parsed_args.pk)

        allowed_trues = ['1', 't', 'true', 'y', 'yes']
        if parsed_args.all:
            sys.stdout.write("Delete all comments of user {}? ".format(user))
            inpread = sys.stdin.readline()
            do_I_delete = True if inpread.strip().lower() in allowed_trues else False

            if not do_I_delete:
                print "Not deleting comment. Aborting."
                sys.exit(1)
            else:
                comments = node.get_comment_obj(user=user)
                for comment in comments:
                    comment.delete()
                print("Deleted {} comments.".format(len(comments)))

        else:
            sys.stdout.write("Delete comment? ")
            inpread = sys.stdin.readline()
            do_I_delete = True if inpread.strip().lower() in allowed_trues else False

            if not do_I_delete:
                print "Not deleting comment. Aborting."
                sys.exit(1)
            else:
                from aiida.orm.implementation import Comment as CommentOrm
                c = CommentOrm(id=parsed_args.id, user=user)
                c.delete()
Beispiel #6
0
    def calculation_inputcat(self, *args):
        """
        Show an input file of a calculation node.

        It shows the files in the raw_input subdirectory.
        Use the -h option for more help on the command line options.
        """
        from aiida.cmdline.commands.node import cat_repo_files
        from aiida.common.exceptions import NotExistent

        import argparse

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Output the content of a file in the repository folder.')
        parser.add_argument('calc', metavar='PK', type=int,
                            help='The pk of the calculation')
        parser.add_argument('-p', '--path', type=str, default=None, nargs='?',
                            help="The relative path of the file you "
                                 "want to show. Take the default input file if "
                                 "it is not specified")

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()
        from aiida.common.old_pluginloader import get_class_typestring

        try:
            calc = load_node(parsed_args.calc)
        except NotExistent as e:
            print >> sys.stderr, e.message
            sys.exit(1)

        path = parsed_args.path
        if path is None:
            path = calc._DEFAULT_INPUT_FILE
            if path is None:
                base_class, plugin_string, class_name = get_class_typestring(
                    calc._plugin_type_string)
                print >> sys.stderr, ("Calculation '{}' does not define a "
                                      "default input file. Please specify a path "
                                      "explicitly".format(plugin_string))
                sys.exit(1)

        try:
            cat_repo_files(calc, os.path.join('raw_input', path))
        except ValueError as e:
            print >> sys.stderr, e.message
            sys.exit(1)
        except IOError as e:
            import errno
            # Ignore Broken pipe errors, re-raise everything else
            if e.errno == errno.EPIPE:
                pass
            else:
                raise
Beispiel #7
0
    def calculation_res(self, *args):
        """
        Print all or somoe data from the "res" output node.
        """
        from aiida.common.exceptions import NotExistent
        from aiida.cmdline import print_dictionary

        import argparse

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Show calculation results (from calc.res)')
        parser.add_argument('PK',
                            type=int,
                            default=None,
                            help="PK of the calculation object whose results "
                            "must be shown.")
        parser.add_argument('-f',
                            '--format',
                            type=str,
                            default='json+date',
                            help="Format for the output.")
        parser.add_argument('-k',
                            '--keys',
                            nargs='+',
                            type=str,
                            help="Show only the selected keys.")
        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        try:
            calc = load_node(int(parsed_args.PK))
        except ValueError:
            print >> sys.stderr, "*** {}: Not a valid PK".format(
                parsed_args.PK)
            sys.exit(1)
        except NotExistent:
            print >> sys.stderr, "*** {}: Not a valid calculation".format(
                parsed_args.PK)
            sys.exit(1)

        full_dict = calc.res._get_dict()
        if parsed_args.keys:
            try:
                the_dict = {k: full_dict[k] for k in parsed_args.keys}
            except KeyError as e:
                print >> sys.stderr, ("The key '{}' was not found in the .res "
                                      "dictionary".format(e.message))
                sys.exit(1)
        else:
            # Return all elements
            the_dict = full_dict

        print_dictionary(the_dict, format=parsed_args.format)
Beispiel #8
0
    def comment_update(self, *args):
        """
        Update a comment
        """
        import argparse
        from aiida.backends.utils import get_automatic_user

        if not is_dbenv_loaded():
            load_dbenv()
        user = get_automatic_user()

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Add a comment to a node in the database.')
        parser.add_argument('pk',
                            metavar='PK',
                            type=int,
                            help='The pk (an integer) of the node')
        parser.add_argument('id',
                            metavar='ID',
                            type=int,
                            help='Identify the comment to update by ID')
        parser.add_argument(
            '-c',
            '--comment',
            type=str,
            default=None,
            help='The comment (a string) to be added to the node')
        parsed_args = parser.parse_args(args)

        # read the comment from terminal if it is not on command line
        if parsed_args.comment is None:
            print "Write below the comment that you want to save in the database."
            print "   # This is a multiline input, press CTRL+D on a"
            print "   # empty line when you finish"
            try:
                newlines = []
                while True:
                    input_txt = raw_input()
                    if input_txt.strip() == '?':
                        print "\n".join([
                            "  > {}".format(descl)
                            for descl in "HELP: {}".format(desc).split('\n')
                        ])
                        continue
                    else:
                        newlines.append(input_txt)
            except EOFError:
                # Ctrl+D pressed: end of input.
                pass
            the_comment = "\n".join(newlines)
        else:
            the_comment = parsed_args.comment

        node = load_node(parsed_args.pk)
        node._update_comment(the_comment, parsed_args.id, user)
Beispiel #9
0
    def calculation_logshow(self, *args):
        from aiida.common.exceptions import NotExistent
        from aiida.backends.utils import get_log_messages
        from aiida.common.datastructures import calc_states

        if not is_dbenv_loaded():
            load_dbenv()

        for calc_pk in args:
            try:
                calc = load_node(int(calc_pk))
            except ValueError:
                print "*** {}: Not a valid PK".format(calc_pk)
                continue
            except NotExistent:
                print "*** {}: Not a valid calculation".format(calc_pk)
                continue

            log_messages = get_log_messages(calc)
            label_string = " [{}]".format(calc.label) if calc.label else ""
            state = calc.get_state()
            if state == calc_states.WITHSCHEDULER:
                sched_state = calc.get_scheduler_state()
                if sched_state is None:
                    sched_state = "(unknown)"
                state += ", scheduler state: {}".format(sched_state)
            print "*** {}{}: {}".format(calc_pk, label_string, state)

            sched_out = calc.get_scheduler_output()
            sched_err = calc.get_scheduler_error()
            if sched_out is None:
                print "*** Scheduler output: N/A"
            elif sched_out:
                print "*** Scheduler output:"
                print sched_out
            else:
                print "*** (empty scheduler output file)"

            if sched_err is None:
                print "*** Scheduler errors: N/A"
            elif sched_err:
                print "*** Scheduler errors:"
                print sched_err
            else:
                print "*** (empty scheduler errors file)"

            if log_messages:
                print "*** {} LOG MESSAGES:".format(len(log_messages))
            else:
                print "*** 0 LOG MESSAGES"

            for log in log_messages:
                print "+-> {} at {}".format(log['levelname'], log['time'])
                # Print the message, with a few spaces in front of each line
                print "\n".join(
                    ["|   {}".format(_) for _ in log['message'].splitlines()])
Beispiel #10
0
    def calculation_kill(self, *args):
        """
        Kill a calculation.

        Pass a list of calculation PKs to kill them.
        If you also pass the -f option, no confirmation will be asked.
        """
        if not is_dbenv_loaded():
            load_dbenv()

        from aiida.cmdline import wait_for_confirmation
        from aiida.orm.calculation.job import JobCalculation as Calc
        from aiida.common.exceptions import NotExistent, InvalidOperation, \
            RemoteOperationError

        import argparse

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Kill AiiDA calculations.')
        parser.add_argument(
            'calcs',
            metavar='PK',
            type=int,
            nargs='+',
            help='The principal key (PK) of the calculations to kill')
        parser.add_argument('-f',
                            '--force',
                            help='Force the kill of calculations',
                            action="store_true")
        args = list(args)
        parsed_args = parser.parse_args(args)

        if not parsed_args.force:
            sys.stderr.write(
                "Are you sure to kill {} calculation{}? [Y/N] ".format(
                    len(parsed_args.calcs),
                    "" if len(parsed_args.calcs) == 1 else "s"))
            if not wait_for_confirmation():
                sys.exit(0)

        counter = 0
        for calc_pk in parsed_args.calcs:
            try:
                c = load_node(calc_pk, parent_class=Calc)

                c.kill()  # Calc.kill(calc_pk)
                counter += 1
            except NotExistent:
                print >> sys.stderr, ("WARNING: calculation {} "
                                      "does not exist.".format(calc_pk))
            except (InvalidOperation, RemoteOperationError) as e:
                print >> sys.stderr, (e.message)
        print >> sys.stderr, "{} calculation{} killed.".format(
            counter, "" if counter == 1 else "s")
Beispiel #11
0
    def comment_show(self, *args):
        """
        Show the comments of a node
        """
        import argparse
        from aiida.backends.utils import get_automatic_user

        if not is_dbenv_loaded():
            load_dbenv()
        user = get_automatic_user()

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Show the comments of a node in the database.')
        parser.add_argument('-u', '--user', type=str, default=None,
                            help='Show only the comments of a given user (optional).')
        parser.add_argument('pk', metavar='PK', type=int,
                            help='The pk (an integer) of the node.')
        parser.add_argument('id', metavar='ID', type=int, default=None, nargs='?',
                            help='The id (an integer) of the comment.')
        # Note that this is a false description, I'm using the DBComment.pk
        parsed_args = parser.parse_args(args)

        node = load_node(parsed_args.pk)
        all_comments = node.get_comments(pk=parsed_args.id)

        if parsed_args.user is not None:
            to_print = [i for i in all_comments if i['user__email'] == parsed_args.user]
            if not to_print:
                print "Nothing found for user '{}'.".format(parsed_args.user)
                print "Valid users found for Node {} are: {}.".format(parsed_args.pk,
                                                                      ", ".join(set(
                                                                          ["'" + i['user__email'] + "'" for i in
                                                                           all_comments])))
        else:
            to_print = all_comments

        if parsed_args.id is not None:
            to_print = [i for i in to_print if i['pk'] == parsed_args.id]

        for i in to_print:
            print "***********************************************************"
            print "Comment of '{}' on {}".format(i['user__email'],
                                                 i['ctime'].strftime("%Y-%m-%d %H:%M"))
            print "ID: {}. Last modified on {}".format(i['pk'],
                                                       i['mtime'].strftime("%Y-%m-%d %H:%M"))
            print ""
            print "{}".format(i['content'])
            print ""

        # If there is nothing to print, print a message
        if not to_print:
            print "No comment found."
Beispiel #12
0
    def calculation_inputls(self, *args):
        """
        Show the list of input files of a calculation node.

        It shows the files in the raw_input subdirectory.
        Use the -h option for more help on the command line options.
        """
        import argparse
        from aiida.common.exceptions import NotExistent
        from aiida.cmdline.commands.node import list_repo_files

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='List input files in the repository folder.')

        parser.add_argument('calc',
                            metavar='PK',
                            type=int,
                            help='The pk of the calculation')
        parser.add_argument('-p',
                            '--path',
                            type=str,
                            default='',
                            nargs='?',
                            help="The relative path of the file you "
                            "want to show. If not specified, show content"
                            " of all the 'raw_input' directory")
        parser.add_argument('-c',
                            '--color',
                            action='store_true',
                            help="Color folders with a different color")

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        try:
            calc = load_node(parsed_args.calc)
        except NotExistent as e:
            print >> sys.stderr, e.message
            sys.exit(1)

        try:
            list_repo_files(calc, os.path.join('raw_input', parsed_args.path),
                            parsed_args.color)
        except ValueError as e:
            print >> sys.stderr, e.message
            sys.exit(1)
Beispiel #13
0
    def ls(self, *args):
        """
        List the files in the repository folder.
        """
        import argparse
        from aiida.common.exceptions import NotExistent

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='List files in the repository folder.')

        parser.add_argument('-c',
                            '--color',
                            action='store_true',
                            help="Color folders with a different color")
        parser.add_argument('-p',
                            '--pk',
                            type=int,
                            required=True,
                            help='The pk of the node')
        parser.add_argument('path',
                            type=str,
                            default='.',
                            nargs='?',
                            help='The relative path of the file you '
                            'want to show')
        # parser.add_argument('-d', '--with-description',
        #                    dest='with_description',action='store_true',
        #                    help="Show also the description for the UPF family")
        # parser.set_defaults(with_description=False)

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        try:
            n = load_node(parsed_args.pk)
        except NotExistent as e:
            print >> sys.stderr, e.message
            sys.exit(1)

        try:
            list_repo_files(n, parsed_args.path, parsed_args.color)
        except ValueError as e:
            print >> sys.stderr, e.message
            sys.exit(1)
Beispiel #14
0
    def cat(self, *args):
        """
        Output the content of a file in the repository folder.
        """
        import argparse
        from aiida.common.exceptions import NotExistent

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Output the content of a file in the repository folder.'
        )
        parser.add_argument('-p',
                            '--pk',
                            type=int,
                            required=True,
                            help='The pk of the node')
        parser.add_argument('path',
                            type=str,
                            help='The relative path of the file you '
                            'want to show')

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        try:
            n = load_node(parsed_args.pk)
        except NotExistent as e:
            print >> sys.stderr, e.message
            sys.exit(1)

        try:
            cat_repo_files(n, parsed_args.path)
        except ValueError as e:
            print >> sys.stderr, e.message
            sys.exit(1)
        except IOError as e:
            import errno
            # Ignore Broken pipe errors, re-raise everything else
            if e.errno == errno.EPIPE:
                pass
            else:
                raise
Beispiel #15
0
    def run(self, *args):
        """
        Show node information.
        """
        import argparse
        from aiida.common.exceptions import NotExistent

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Show information of a node.')
        parser.add_argument('pk',
                            type=int,
                            default=None,
                            nargs="+",
                            help="ID of the node.")
        parser.add_argument('--print-groups',
                            action='store_true',
                            dest='print_groups',
                            default=False,
                            help="Show groups containing the nodes.")
        parser.add_argument('--no-print-groups',
                            '--dont-print-groups',
                            action='store_false',
                            dest='print_groups',
                            default=False,
                            help="Do not show groups containing the nodes"
                            "output. Default behaviour.")

        args = list(args)
        parsed_args = parser.parse_args(args)

        if not is_dbenv_loaded():
            load_dbenv()

        for pk in parsed_args.pk:
            try:
                n = load_node(pk)
                self.print_node_info(n, print_groups=parsed_args.print_groups)
            except NotExistent as e:
                print >> sys.stderr, e.message
                sys.exit(1)

            if len(parsed_args.pk) > 1:
                print ""
Beispiel #16
0
    def calculation_show(self, *args):
        from aiida.common.exceptions import NotExistent
        from aiida.cmdline.common import print_node_info

        if not is_dbenv_loaded():
            load_dbenv()

        table_headers = ['Link label', 'PK', 'Type']
        for calc_pk in args:
            try:
                calc = load_node(int(calc_pk))
            except ValueError:
                print "*** {}: Not a valid PK".format(calc_pk)
                continue
            except NotExistent:
                print "*** {}: Not a valid calculation".format(calc_pk)
                continue

            print_node_info(calc)
Beispiel #17
0
    def group_list(self, *args):
        """
        Print a list of groups in the DB.
        """
        if not is_dbenv_loaded():
            load_dbenv()

        import datetime
        from aiida.utils import timezone
        from aiida.orm.group import get_group_type_mapping
        from aiida.backends.utils import get_automatic_user
        from tabulate import tabulate

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='List AiiDA user-defined groups.')
        exclusive_group = parser.add_mutually_exclusive_group()
        exclusive_group.add_argument('-A', '--all-users',
                                     dest='all_users', action='store_true',
                                     help="Show groups for all users, rather than only for the current user")
        exclusive_group.add_argument('-u', '--user', metavar='USER_EMAIL',
                                     help="Add a filter to show only groups belonging to a specific user",
                                     action='store', type=str)
        parser.add_argument('-t', '--type', metavar='TYPE',
                            help="Show groups of a specific type, instead of user-defined groups",
                            action='store', type=str)
        parser.add_argument('-d', '--with-description',
                            dest='with_description', action='store_true',
                            help="Show also the group description")
        parser.add_argument('-p', '--past-days', metavar='N',
                            help="add a filter to show only groups created in the past N days",
                            action='store', type=int)
        parser.add_argument('-s', '--startswith', metavar='STRING',
                            default=None,
                            help="add a filter to show only groups for which the name begins with STRING",
                            action='store', type=str)
        parser.add_argument('-e', '--endswith', metavar='STRING', default=None,
                            help="add a filter to show only groups for which the name ends with STRING",
                            action='store', type=str)
        parser.add_argument('-c', '--contains', metavar='STRING', default=None,
                            help="add a filter to show only groups for which the name contains STRING",
                            action='store', type=str)
        parser.add_argument('-n', '--node', metavar='PK', default=None,
                            help="Show only the groups that contain the node specified by PK",
                            action='store', type=int)
        parser.set_defaults(all_users=False)
        parser.set_defaults(with_description=False)

        args = list(args)
        parsed_args = parser.parse_args(args)

        if parsed_args.all_users:
            user = None
        else:
            if parsed_args.user:
                user = parsed_args.user
            else:
                # By default: only groups of this user
                user = get_automatic_user()

        type_string = ""
        if parsed_args.type is not None:
            try:
                type_string = get_group_type_mapping()[parsed_args.type]
            except KeyError:
                print >> sys.stderr, "Invalid group type. Valid group types are:"
                print >> sys.stderr, ",".join(sorted(
                    get_group_type_mapping().keys()))
                sys.exit(1)

        name_filters = dict((k, getattr(parsed_args, k))
                            for k in ['startswith', 'endswith', 'contains'])

        n_days_ago = None
        if parsed_args.past_days:
            n_days_ago = (timezone.now() -
                          datetime.timedelta(days=parsed_args.past_days))

        # Depending on --nodes option use or not key "nodes"
        from aiida.orm.implementation import Group
        from aiida.orm import load_node

        node_pk = parsed_args.node
        if node_pk is not None:
            try:
                node = load_node(node_pk)
            except NotExistent as e:
                print >> sys.stderr, "Error: {}.".format(e.message)
                sys.exit(1)
            res = Group.query(user=user, type_string=type_string, nodes=node,
                              past_days=n_days_ago, name_filters=name_filters)
        else:
            res = Group.query(user=user, type_string=type_string,
                              past_days=n_days_ago, name_filters=name_filters)

        groups = tuple([(str(g.pk), g.name, len(g.nodes), g.user.email.strip(),
                         g.description) for g in res])


        table = []
        if parsed_args.with_description:
            table_header = \
                ["PK", "GroupName", "NumNodes", "User", "Description"]
            for pk, nam, nod, usr, desc in groups:
                table.append([pk, nam, nod, usr, desc])

        else:
            table_header = ["PK", "GroupName", "NumNodes", "User"]
            for pk, nam, nod, usr, _ in groups:
                table.append([pk, nam, nod, usr])
        print(tabulate(table, headers=table_header))
Beispiel #18
0
    def group_removenodes(self, *args):
        """
        Remove nodes from a given group.
        """
        from aiida.cmdline import delayed_load_node as load_node
        from aiida.cmdline import wait_for_confirmation

        if not is_dbenv_loaded():
            load_dbenv()

        import argparse
        from aiida.common.exceptions import NotExistent
        from aiida.orm import Group as G

        parser = argparse.ArgumentParser(
            prog=self.get_full_command_name(),
            description='Remove nodes from a given AiiDA group.')
        parser.add_argument('-g', '--group',
                            dest='group',
                            required=True,
                            help="The name or PK of the group you want to "
                                 "remove a node from.")
        parser.add_argument('nodes', nargs='+',
                            help="The PK or UUID of the nodes to remove. An "
                                 "error is raised if the node does not exist. "
                                 "No message is shown if the node does not belong "
                                 "to the group.")
        parser.set_defaults(raw=False)

        args = list(args)
        parsed_args = parser.parse_args(args)

        group = parsed_args.group
        try:
            group_pk = int(group)
        except ValueError:
            group_pk = None
            group_name = group

        if group_pk is not None:
            try:
                group = G(dbgroup=group_pk)
            except NotExistent as e:
                print >> sys.stderr, "Error: {}.".format(e.message)
                sys.exit(1)
        else:
            try:
                group = G.get_from_string(group_name)
            except NotExistent as e:
                print >> sys.stderr, "Error: {}.".format(e.message)
                sys.exit(1)

        group_pk = group.pk
        group_name = group.name

        nodes = []
        for node in parsed_args.nodes:
            try:
                node = int(node)
            except ValueError:
                pass  # I leave it as a string and let load_node complain
                # if it is not a UUID
            try:
                nodes.append(load_node(node))
            except NotExistent as e:
                print >> sys.stderr, "Error: {}.".format(e.message)
                sys.exit(1)

        sys.stderr.write("Are you sure to remove {} nodes from the group "
                         "with PK = {} "
                         "({})? [Y/N] ".format(len(nodes), group_pk,
                                               group_name))
        if not wait_for_confirmation():
            sys.exit(0)

        group.remove_nodes(nodes)
Beispiel #19
0
    def run(self, *args):
        if not is_dbenv_loaded():
            load_dbenv()
        import argparse
        from aiida.cmdline import wait_for_confirmation

        parser = argparse.ArgumentParser(prog=self.get_full_command_name(),
                                         description="See description of Nodes. If no node "
                                                     "description or label is found, prints n.a.")

        # parameters for display
        parser.add_argument('-n', '--no-labels', action='store_false',
                            default=True,
                            help="Don't show the labels.")
        parser.add_argument('-r', '--raw', action='store_true', default=False,
                            help="If set, prints only the description without "
                                 "pks or labels.")
        # pks
        parser.add_argument('pks', type=int, nargs='+',
                            help="a list of node pks to show.")
        # parameters for description modifications
        parser.add_argument('-s', '--set', action='store_true', default=False,
                            help="If present, set a new label, otherwise only "
                                 "show the labels.")
        parser.add_argument('-a', '--add-to-description', action='store_true',
                            default=False,
                            help="If -s, the string passed in -d is appended "
                                 "to the current description.")
        parser.add_argument('-f', '--force', action='store_true',
                            default=False,
                            help="Force the reset of the description.")
        parser.add_argument('-d', '--description', type=str,
                            help="The new description to be set on the node. "
                                 "Note: pass it between quotes.")

        parsed_args = parser.parse_args(args)

        pks = parsed_args.pks

        if not parsed_args.set:
            also_labels = parsed_args.no_labels
            for pk in pks:
                n = load_node(pk)

                if not self._node_class_ok(n):
                    print "Node {} is not a subclass of {}. Exiting...".format(
                        pk,
                        self._node_subclass)
                    sys.exit(1)

                label = n.label
                description = n.description

                if parsed_args.raw:
                    print '"{}"'.format(n.description)
                    print ""

                else:
                    print "Node pk: {}".format(pk)
                    if also_labels:
                        if label:
                            print 'Label: "{}"'.format(label)
                        else:
                            print 'Label: n.a.'
                    if description:
                        print 'Description: "{}"'.format(description)
                    else:
                        print 'Description: n.a.'
                    print ""
        else:
            # check that only one pk is present
            if len(pks) > 1:
                sys.stderr.write(
                    "More than one node found to set one description"
                    ". Exiting...\n")
                sys.exit(1)
            else:
                pk = pks[0]

            new_description = parsed_args.description
            if new_description is None:
                sys.stderr.write("No description was found. Exiting...\n")
                sys.exit(1)

            if not parsed_args.add_to_description:
                n = load_node(pk)
                if not self._node_class_ok(n):
                    print "Node {} is not a subclass of {}. Exiting...".format(
                        pk,
                        self._node_subclass)
                    sys.exit(1)

                old_description = n.description
                if not parsed_args.force:
                    sys.stderr.write(
                        "Current description is: {}\n".format(old_description))
                    sys.stderr.write(
                        "New description is: {}\n".format(new_description))
                    sys.stderr.write(
                        "Are you sure you want to reset the description? "
                        "[Y/N] ")
                    if not wait_for_confirmation():
                        sys.exit(0)

                n.description = new_description

            else:
                n = load_node(pk)
                if not self._node_class_ok(n):
                    print "Node {} is not a subclass of {}. Exiting...".format(
                        pk,
                        self._node_subclass)
                    sys.exit(1)

                old_description = n.description
                new_description = old_description + "\n" + new_description
                n.description = new_description
Beispiel #20
0
    def run(self, *args):
        if not is_dbenv_loaded():
            load_dbenv()
        import argparse
        from aiida.cmdline import wait_for_confirmation

        parser = argparse.ArgumentParser(prog=self.get_full_command_name(),
                                         description="See/modify the labels of Nodes.")
        # display parameters
        parser.add_argument('-r', '--raw', action='store_true', default=False,
                            help="Display only the labels, without the pk.")
        # pks
        parser.add_argument('pks', type=int, nargs='+',
                            help="a list of nodes to show.")
        # parameters for label modification
        parser.add_argument('-s', '--set', action='store_true', default=False,
                            help="If present, set a new label, otherwise only "
                                 "show the labels.")
        parser.add_argument('-f', '--force', action='store_true',
                            default=False,
                            help="Force the reset of the label.")
        parser.add_argument('-l', '--label', type=str, default=None,
                            help="The new label to be set on the node. Note: "
                                 "pass it between quotes.")

        parsed_args = parser.parse_args(args)
        raw = parsed_args.raw
        pks = parsed_args.pks

        if not parsed_args.set:
            for pk in pks:
                n = load_node(pk)
                if not self._node_class_ok(n):
                    print "Node {} is not a subclass of {}. Exiting...".format(
                        pk,
                        self._node_subclass)
                    sys.exit(1)
                if raw:
                    print '"{}"'.format(n.label)
                else:
                    if not n.label:
                        print 'Node {}, label: n.a.'.format(pk)
                    else:
                        print 'Node {}, label: "{}"'.format(pk, n.label)
        else:
            if len(pks) > 1:
                sys.stderr.write("More than one node found to set one label"
                                 ". Exiting...\n")
                sys.exit(1)
            else:
                pk = pks[0]

            new_label = parsed_args.label
            if new_label is None:
                sys.stderr.write("A new label is required"
                                 ". Exiting...\n")
                sys.exit(1)

            n = load_node(pk)

            if not self._node_class_ok(n):
                print "Node {} is not a subclass of {}. Exiting...".format(pk,
                                                                           self._node_subclass)
                sys.exit(1)

            old_label = n.label
            if not parsed_args.force:
                sys.stderr.write("Current label is: {}\n".format(old_label))
                sys.stderr.write("New label is: {}\n".format(new_label))
                sys.stderr.write("Are you sure you want to reset the label? "
                                 "[Y/N] ")
                if not wait_for_confirmation():
                    sys.exit(0)

            n.label = new_label