<commit_before>#!/usr/bin/env python

import argparse
import os
import warnings
import sys

if __name__ == "__main__" and __package__ is None:
    rootdir=os.path.abspath('../..')
    sys.path.append(rootdir)

from loom.client.common import get_settings_manager
from loom.client.common import add_settings_options_to_parser
from loom.client.common import read_as_json_or_yaml
from loom.client.exceptions import *
from loom.client.upload import WorkflowUploader, FileUploader
from loom.common.filehandler import FileHandler
from loom.common.helper import get_stdout_logger
from loom.common.objecthandler import ObjectHandler


class AbstractInputProcessor(object):

    def __init__(self, objecthandler, filehandler):
        self.objecthandler = objecthandler
        self.filehandler = filehandler

    def _list_to_single(self, input_id_list):
        if len(input_id_list) != 1:
            raise Exception('Expected 1 input but found %s: "%s"'\
                            % (len(input_id_list), input_id_list))
        return input_id_list[0]

    def _create_array(self, data_objects):
        return self.objecthandler.post_data_object_array(
            {
                'data_objects': data_objects
            }
        )

    
class FileInputProcessor(AbstractInputProcessor):

    def load_data_object(self, input_id_list, convert_from_list=True):
        if convert_from_list:
            input_id = self._list_to_single(input_id_list)
        else:
            input_id = input_id_list
        return self._get_input(input_id)

    def _get_input(self, input_id):
        input_from_server = self._get_input_from_server(input_id)
        input_file = self._get_input_file(input_id)
        if not (input_from_server or input_file):
            raise Exception('Could not find input that matches "%s"' % input_id)
        if input_from_server and not input_file:
            data_object = input_from_server
            return data_object
        if input_from_server and input_file:
            warnings.warn('The input name "%s" matches both a local file and a file on the server. '\
                          'Using the local file.')
        # Input is from local source, not server. Upload it now.
        source_record_text = FileUploader.prompt_for_source_record_text(input_file)
        data_object = self.filehandler.upload_file_from_local_path(input_file, source_record=source_record_text)
        return data_object

    def _get_input_from_server(self, input_id):
        return self.objecthandler.get_file_data_object(input_id)

    def _get_input_file(self, raw_input_id):
        """If input_id is the path to a file, return that path. Otherwise None.
        """
        input_id = os.path.expanduser(raw_input_id)
        if os.path.isfile(input_id):
            return input_id
        else:
            return None

    def prompt_for_input(self, input_name, prompt):
        input_id = None
        while not input_id:
            input_id = raw_input(
                '\n"%s": "%s"\nThis input is required. Enter a file path or data identifier.\n> ' % (input_name, prompt)
            )
        data_object = self._get_input(input_id)
        return data_object

class FileArrayInputProcessor(FileInputProcessor):

    #Override
    def load_data_object(self, input_id_list, convert_from_list=True):
        file_data_objects = []<commit_msg>bugfix - loom run workflow_id input_name=input_id allows input_id to be of form name@hash<commit_after>#!/usr/bin/env python

import argparse
import os
import warnings
import sys

if __name__ == "__main__" and __package__ is None:
    rootdir=os.path.abspath('../..')
    sys.path.append(rootdir)

from loom.client.common import get_settings_manager
from loom.client.common import add_settings_options_to_parser
from loom.client.common import read_as_json_or_yaml
from loom.client.exceptions import *
from loom.client.upload import WorkflowUploader, FileUploader
from loom.common.filehandler import FileHandler
from loom.common.helper import get_stdout_logger
from loom.common.objecthandler import ObjectHandler


class AbstractInputProcessor(object):

    def __init__(self, objecthandler, filehandler):
        self.objecthandler = objecthandler
        self.filehandler = filehandler

    def _list_to_single(self, input_id_list):
        if len(input_id_list) != 1:
            raise Exception('Expected 1 input but found %s: "%s"'\
                            % (len(input_id_list), input_id_list))
        return input_id_list[0]

    def _create_array(self, data_objects):
        return self.objecthandler.post_data_object_array(
            {
                'data_objects': data_objects
            }
        )

    
class FileInputProcessor(AbstractInputProcessor):

    def load_data_object(self, input_id_list, convert_from_list=True):
        if convert_from_list:
            input_id = self._list_to_single(input_id_list)
        else:
            input_id = input_id_list
        return self._get_input(input_id)

    def _get_input(self, input_id):
        input_from_server = self._get_input_from_server(input_id)
        input_file = self._get_input_file(input_id)
        if not (input_from_server or input_file):
            raise Exception('Could not find input that matches "%s"' % input_id)
        if input_from_server and not input_file:
            data_object = input_from_server
            return data_object
        if input_from_server and input_file:
            warnings.warn('The input name "%s" matches both a local file and a file on the server. '\
                          'Using the local file.')
        # Input is from local source, not server. Upload it now.
        source_record_text = FileUploader.prompt_for_source_record_text(input_file)
        data_object = self.filehandler.upload_file_from_local_path(input_file, source_record=source_record_text)
        return data_object

    def _get_input_from_server(self, input_id):
        data_object_list = self.objecthandler.get_file_data_object_index(query_string=input_id)
        if len(data_object_list) == 0:
            raise Exception('No file input found for "%s".' % input_id)
        elif len(data_object_list) > 1:
            raise Exception('Multiple inputs found for "%s".' % input_id)
        return data_object_list[0]

    def _get_input_file(self, raw_input_id):
        """If input_id is the path to a file, return that path. Otherwise None.
        """
        input_id = os.path.expanduser(raw_input_id)
        if os.path.isfile(input_id):
            return input_id
        else:
            return None

    def prompt_for_input(self, input_name, prompt):
        input_id = None
        while not input_id:
            input_id = raw_input(
                '\n"%s": "%s"\nThis input is required. Enter a file path or data identifier.\n> ' % (input_name, prompt)
            )
        data_object = self._get_input(input_id)
        return data_object

class FileArrayInputProcessor(FileInputProcessor):

    #Override
    def load_data_object(self, input_id_list, convert_from_list=True):
        file_data_objects = []
{'fraction_non_alphanumeric': 0.07503161444428832, 'fraction_numerical': 0.0012645777715329493, 'mean_word_length': 2.889617486338798, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7085875', 'n_tokens_mistral': 2123, 'n_tokens_neox': 2089, 'n_words': 510}