Esempio n. 1
0
def get_record_extremes(type_):
    ''' Get global date/data min/max. type_ can be "time" or "data"
        status: finished
        return: tuple
        raise: IndexError, ValueError
    '''
    try:
        minimum = skj_std.arguments_values['source'][0][type_ + '_min']
        maximum = minimum
    except (IndexError, KeyError) as exception_msg:
        raise IndexError(skj_std.create_error_msg("INTERNAL", exception_msg))

    for f in skj_std.arguments_values['source']:
        maximum = max(maximum, f[type_ + '_max'])
        minimum = min(minimum, f[type_ + '_min'])
        
    if type_ == "time":
        from time import strftime
        try:      
            maximum = strftime(skj_std.arguments_values['timeformat'], maximum)
            minimum = strftime(skj_std.arguments_values['timeformat'], minimum)
        except (ValueError, TypeError) as exception_msg:
            raise ValueError(skj_std.create_error_msg("INTERNAL", exception_msg))

    return maximum, minimum
Esempio n. 2
0
def check_effects_syntax():
    ''' Check for allowed syntax
        status: finished
        return: dict
        raise: ValueError
    '''
    valid_effects = dict()

    f = skj_std.arguments_values['effectparams'] # wtf is this mess, right?
    u = [l.split(":") for l in f] # well, if I'll ever want to piss someone in team...
    c = [f for l in u for f in l] # ... i'll play on stubborn, selfish asshole ...
    k = [f.split("=") for f in c] # ... and write my code just like folks at MFF ...
    _ = {e[0]:e[1] for e in k if len(e) > 1} # ... write math!

    parsed_effects = _ # ouky douky, lets get back to work
    for effect in parsed_effects:
        if effect in skj_std.allowed_effects:
            if parsed_effects[effect] in skj_std.allowed_effects[effect]:
                valid_effects[effect] = parsed_effects[effect]
                continue

        if skj_std.arguments_values['ignoreerrors']:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("INVALID_VALUE", effect))
        else:
            raise ValueError(skj_std.create_error_msg("INVALID_VALUE", effect))

    return valid_effects
Esempio n. 3
0
def check_file(file_, ignorable_=True, verbose_=True):
    ''' Check if file exists && is readable && not empty
        status: finished
        return: file_ / None
        raise: IOError
    '''
    try:
        with open(file_, mode="r", encoding="utf-8") as f: # If file exists && is readable...
            from os.path import isfile 
            if not isfile(file_): # ... && is a normal file (no block device, etc) ...
                raise OSError("File " + file_ + " is not a regular file")

            from os import stat
            if stat(f.fileno()).st_size <= 0: # ... && is not empty ... 
                raise OSError("File " + file_ + " is empty")

            f.readline() # ... && is really an unicode file ... 
    except (IOError, TypeError, OSError, UnicodeDecodeError) as exception_msg:
        if skj_std.arguments_values['ignoreerrors'] and ignorable_ == True:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("PYTHON", exception_msg))
            return None
        else:
            raise IOError(skj_std.create_error_msg("PYTHON", exception_msg, False))
    else:
        return file_  # ... then it has passed all basic tests
Esempio n. 4
0
def determine_anim_type():
    ''' Decide whether animation is multiplot type or oneline
        status: finished
        return: str
        raise: IndexError
    '''
    try:
        time_max = skj_std.arguments_values['source'][0]
        time_min = skj_std.arguments_values['source'][0]
    except IndexError as exception_msg:
        raise IndexError(skj_std.create_error_msg("INTERNAL", exception_msg))

    for source_file in skj_std.arguments_values['source']:
        if source_file['time_min'] < time_min['time_min']:
            time_min = source_file
            if source_file['time_max'] >= time_max['time_max']:
                time_max = source_file # If the file with new min can also have new max, use it ...
        elif source_file['time_max'] > time_max['time_max']:
            time_max = source_file
            if source_file['time_min'] <= time_min['time_min']:
                time_min = source_file # ... because of correct anim type detection

    if time_max["path"] == time_min["path"] and len(skj_std.arguments_values['source']) != 1: # Hope this works 
        return "multiplot"
    return "oneline"
Esempio n. 5
0
def set_animation_properties():
    ''' Set properties of animation like speed, time, num of frames, num of records, type, etc
        status: finished
        return: None
        raise: TypeError, IndexError, ValueError
    '''
    # Get animation type
    skj_std.arguments_values['animation_type'] = determine_anim_type() # raise IndexError

    # Then calculate the number of valid lines (valid line is also called 'record')
    skj_std.arguments_values['records'] = 0 # File with zero records should never exist
    for lines_file in get_anim_records():
        if skj_std.arguments_values['animation_type'] == "multiplot":
            # Multiplot animation has as many records as the longest file has lines
            if lines_file > skj_std.arguments_values['records']:
                skj_std.arguments_values['records'] = lines_file
        else:
            # Oneline animation has sum(all_lines) records
            skj_std.arguments_values['records'] += lines_file

    # Calculate correct speed && fps && frames && time
    calculate_sfft() # raise VauleError, ArithmeticError (catch AE? => if ignoreerrors: speed = 0 (see code below))
    
    # Correct speed/fps if it is too low (< 1), cause that leads to crazy long create_speed_seq() && generate_anim()
    if skj_std.arguments_values['speed'] < 1 or skj_std.arguments_values['fps'] < 1:
        if skj_std.arguments_values['ignoreerrors']:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("TOO_SMALL_ANIM", \
                                     str(skj_std.arguments_values['speed']) + \
                                     "/" + str(skj_std.arguments_values['fps'])))
            skj_std.arguments_values['speed'] = skj_std.arguments_defaults['speed']
            skj_std.arguments_values['fps'] = skj_std.arguments_defaults['fps']
            skj_std.arguments_values['time'] = skj_std.arguments_defaults['time']
            calculate_sfft()
        else:
            raise ValueError(skj_std.create_error_msg("TOO_SMALL_ANIM", \
                            str(skj_std.arguments_values['speed']) + "/" + str(skj_std.arguments_values['fps'])))

    # Create sequence of records added to every created frame
    from math import modf
    try: # Divide the speed on it's integer and fractional parts
        speed_fraction = modf(skj_std.arguments_values['speed'])[0]
        speed_integer = int(modf(skj_std.arguments_values['speed'])[1])
    except TypeError as exception_msg:
        raise TypeError(skj_std.create_error_msg("INTERNAL", exception_msg))
    for source_file in skj_std.arguments_values['source']: # Add the sequence to each file's properties
        source_file['adding_seq'] = create_speed_seq(file_=source_file, int_=speed_integer, frac_=speed_fraction)
Esempio n. 6
0
def check_time_format(datetime_, ignorable_=True, verbose_=True):
    ''' Check if string containing date and time is in the specified format.
        status: finished
        return: time_struct / None
        raise: ValueError
    '''
    from time import strptime
    try:
        ret = strptime(datetime_[0], datetime_[1])
    except (ValueError, TypeError, IndexError) as exception_msg:
        if skj_std.arguments_values['ignoreerrors'] and ignorable_ == True:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("PYTHON", exception_msg))
            return None
        else:
            raise ValueError(skj_std.create_error_msg("PYTHON", exception_msg, False))
    else:
        return ret
Esempio n. 7
0
def check_command_exists(command_, ignorable_=True):
    ''' Check for command_ existence && executability
        status: finished
        return: command_ / None
        raise: OSError
    '''
    import subprocess
    try:
        subprocess.call(command_, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, timeout=5)
    except (subprocess.TimeoutExpired, subprocess.SubprocessError, OSError, ValueError, TypeError) as exception_msg:
        if skj_std.arguments_values['ignoreerrors'] and ignorable_ == True:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("PYTHON", exception_msg))
            return None
        else:
            raise OSError(skj_std.create_error_msg("PYTHON", exception_msg, False))
    else:
        return command_
Esempio n. 8
0
def check_float_ok(float_, ignorable_=True, verbose_=True):
    ''' Check if string is float and not inf/nan
        status: finished
        return: float / None
        raise: ValueError
    '''
    from math import isinf, isnan
    try:
        if isnan(float(float_)) or isinf(float(float_)):
            raise ValueError("value is inf/nan in a place where actual number should be")
    except (ValueError, TypeError) as exception_msg:
        if skj_std.arguments_values['ignoreerrors'] and ignorable_ == True:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("PYTHON", exception_msg))
            return None
        else:
            raise ValueError(skj_std.create_error_msg("PYTHON", exception_msg, False))
    else:
        return float(float_)
Esempio n. 9
0
def create_animation():
    ''' Finally, call ffmpeg and let it do it's magic
        status: finished
        return: None
        raise: OSError
    '''
    import os
    import subprocess
    from sys import argv

    if skj_std.arguments_values['name'] == skj_std.arguments_defaults['name']:
        skj_std.arguments_values['name'] = os.path.split(argv[0])[1]
    output = os.path.join(os.getcwd(), skj_std.arguments_values['name']) # Output directory

    if os.path.isdir(output):
        i = 0 # If the dir already exists ...
        output = output + '_' + str(i)
        while os.path.isdir(output):
            i += 1 # ... try output_i where i = max(i,0) + 1
            output = output[:output.rfind('_')] + '_' + str(i)

    try:
        os.makedirs(output) # If we do not have write/execute in os.getcwd()...
    except OSError as exception_msg:
        if skj_std.arguments_values['ignoreerrors']:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("OUTPUT_DIR_CREATE", output))
            output = skj_std.temp_directories['root'] # ... move output to temp dir we already have ...
        else: # ... or die!
            raise OSError(skj_std.create_error_msg("OUTPUT_DIR_CREATE", output))

    filetype = ".mp4"
    codec  = "libx264"
    ffmpeg = ["ffmpeg", "-f", "image2", "-r", str(skj_std.arguments_values['fps']), "-i", \
              os.path.join(skj_std.temp_directories['gnuplot'], "g_%0" + \
              str(len(str(skj_std.arguments_values['frames']))) + "d.png"),
              "-c:v", codec, "-r", str(skj_std.arguments_values['fps']), \
               os.path.join(output, skj_std.arguments_values['name'].split('/')[-1]) + filetype]
    try:
        subprocess.check_call(ffmpeg, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    except subprocess.CalledProcessError as exception_msg:
        raise OSError(skj_std.create_error_msg("PYTHON", exception_msg))
Esempio n. 10
0
def parse_directives():
    ''' Parse configuration file directives
            status: finished
            return: None
            raise: IOError
    '''
    config_file = dict()

    for argument in skj_std.arguments_repeatable:
        config_file[argument] = list()

    try:
        with open(skj_std.arguments_values['config'], mode="r", encoding="utf-8") as cnf_file:
            for line in cnf_file:
                option = line.partition('#')[0].strip().split(None, 1)
                if len(option) > 0:
                    # Check if it is a valid directive 
                    if option[0].lower() not in skj_std.arguments_defaults:
                        raise ValueError(option[0] + " is not a configuration directive")
                    if len(option) == 1:
                        raise ValueError(option[0] + " does not have configuration value")
                    if option[0].lower() in ["speed", "fps", "time"]: # should be created as list of floats from argparse
                        from skj_checker_common import check_float_ok
                        option[1] = check_float_ok(option[1]) # Check && convert string to float if possible

                    # Store valid directives
                    if option[0].lower() in skj_std.arguments_repeatable:
                        config_file[option[0].lower()].append(option[1])
                    else:
                        config_file[option[0].lower()] = option[1]
    except (IOError, IndexError, TypeError, ValueError) as exception_msg:
        if skj_std.arguments_values['ignoreerrors']:
            skj_std.print_msg_verbose(err_=skj_std.create_error_msg("PYTHON", exception_msg))
            return
        else:
            raise IOError(skj_std.create_error_msg("PYTHON", exception_msg, False))
    else:
        add_directives_to_args(config_file, skj_std.arguments_repeatable)
Esempio n. 11
0
def check_y(type_, default_):
    ''' Check if string is "auto"/"max/min"/float.
        status: finished
        return: None
        raise: ValueError
    '''
    if type_ == "max":  # As we are checking for two values, we have to decide which one is it now first
        to_check = skj_std.arguments_values['ymax']
    elif type_ == "min":
        to_check = skj_std.arguments_values['ymin']
    else:  # This should really never happen, but just to be sure
        raise ValueError(skj_std.create_error_msg("INTERNAL", to_check, False))

    if type_ == to_check or to_check == default_:
        return  # Problem solved, value is max/min/default

    if check_float_ok(to_check) == None:
        if type_ == "max":
            skj_std.arguments_values['ymax'] = default_
        else:
            skj_std.arguments_values['ymin'] = default_
Esempio n. 12
0
def check_x(type_, default_):
    ''' Check if string is "auto"/"max/min"/time_string.
        status: finished
        return: None
        raise: ValueError
    '''
    if type_ == "max":  # As we are checking for two values, we have to decide which one is it now first
        to_check = skj_std.arguments_values['xmax']
    elif type_ == "min":
        to_check = skj_std.arguments_values['xmin']
    else:  # This should really never happen, but just to be sure
        raise ValueError(skj_std.create_error_msg("INTERNAL", to_check, False))

    if to_check == "auto" or to_check == default_:
        return  # Problem solved, value is not in date-time format

    if not check_time_format((to_check, skj_std.arguments_values['timeformat'])):
        if type_ == "max":
            skj_std.arguments_values['xmax'] = default_
        else:
            skj_std.arguments_values['xmin'] = default_
Esempio n. 13
0
def calculate_sfft():
    ''' Calculate speed (num of records read each gnuplot iteration), fps, animation duration and num of frames
        status: devel - those if-chanins should be gone
        return: None
        raise: ValueError, ArithmeticError
    '''
    # 0. No user input
    # 1. User speed && fps
    # 2. User speed
    # 3. User fps
    if  (skj_std.arguments_values['time'] == skj_std.arguments_defaults['time'] and\
        skj_std.arguments_values['speed'] == skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] == skj_std.arguments_defaults['fps']) or\
        (skj_std.arguments_values['speed'] != skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] != skj_std.arguments_defaults['fps'] and\
        skj_std.arguments_values['time'] == skj_std.arguments_defaults['time']) or\
        (skj_std.arguments_values['speed'] != skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] == skj_std.arguments_defaults['fps'] and\
        skj_std.arguments_values['time'] == skj_std.arguments_defaults['time']) or\
        (skj_std.arguments_values['speed'] == skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] != skj_std.arguments_defaults['fps'] and\
        skj_std.arguments_values['time'] == skj_std.arguments_defaults['time']):
            # Calculate animation time
            try:
                skj_std.arguments_values['time'] = skj_std.arguments_values['records'] / \
                (skj_std.arguments_values['speed'] * skj_std.arguments_values['fps'])
            except (ArithmeticError, ZeroDivisionError) as exception_msg:
                raise ArithmeticError(skj_std.create_error_msg("PYTHON", exception_msg))

    # 0. User speed && time
    # 1. User time
    elif (skj_std.arguments_values['speed'] != skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] == skj_std.arguments_defaults['fps'] and\
        skj_std.arguments_values['time'] != skj_std.arguments_defaults['time']) or\
        (skj_std.arguments_values['speed'] == skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] == skj_std.arguments_defaults['fps'] and\
        skj_std.arguments_values['time'] != skj_std.arguments_defaults['time']):
            # Calculate animation fps
            try:
                skj_std.arguments_values['fps'] = skj_std.arguments_values['records'] / \
                (skj_std.arguments_values['speed'] * skj_std.arguments_values['time'])
            except (ArithmeticError, ZeroDivisionError) as exception_msg:
                raise ArithmeticError(skj_std.create_error_msg("PYTHON", exception_msg))

    # User time && fps
    elif skj_std.arguments_values['speed'] == skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] != skj_std.arguments_defaults['fps'] and\
        skj_std.arguments_values['time'] != skj_std.arguments_defaults['time']:
            # Calculate animation speed
            try:
                skj_std.arguments_values['speed'] = skj_std.arguments_values['records'] / \
                (skj_std.arguments_values['fps'] * skj_std.arguments_values['time'])
            except (ArithmeticError, ZeroDivisionError) as exception_msg:
                raise ArithmeticError(skj_std.create_error_msg("PYTHON", exception_msg))

    # User time && speed && fps
    elif skj_std.arguments_values['time'] != skj_std.arguments_defaults['time'] and\
        skj_std.arguments_values['speed'] != skj_std.arguments_defaults['speed'] and\
        skj_std.arguments_values['fps'] != skj_std.arguments_defaults['fps']:
            # Calculate correct time
            try:
                time_check = skj_std.arguments_values['records'] / \
                (skj_std.arguments_values['speed'] * skj_std.arguments_values['fps'])
            except (ArithmeticError, ZeroDivisionError) as exception_msg:
                raise ArithmeticError(skj_std.create_error_msg("PYTHON", exception_msg))

            # Check if correct time matches user time
            if time_check != skj_std.arguments_values['time']:
                if skj_std.arguments_values['ignoreerrors']:
                    skj_std.print_msg_verbose(err_=skj_std.create_error_msg("INVALID_VALUE", \
                                                                           skj_std.arguments_values['time']))
                    skj_std.arguments_values['time'] = time_check
                else:
                    raise ValueError(skj_std.create_error_msg("INVALID_VALUE", skj_std.arguments_values['time']))

    from math import ceil
    skj_std.arguments_values['frames'] = ceil(skj_std.arguments_values['records'] / skj_std.arguments_values['speed'])
Esempio n. 14
0
from skj_checker_common import check_parsed_args
try:  # If we have alived the user input so far, now do some REAL user input checks
    check_parsed_args()
except (OSError, IOError, ValueError) as exception_msg:
    skj_std.exit_with_failure(exception_msg, "ARGS_ERR_CHECK")


from skj_subprocess_gnuplot import set_file_properties
try:  # Convert simple list of file names to more complex structures containing file properties
    for source_file in list(skj_std.arguments_values['source']):
        file_properties = set_file_properties(source_file)
        skj_std.arguments_values['source'].pop(0)
        if file_properties != None: # This filters files with only whitespaces
            skj_std.arguments_values['source'].append(file_properties)
    if not skj_std.arguments_values['source']:
        raise ValueError(skj_std.create_error_msg("NO_SOURCE", skj_std.arguments_values['source'], False))
except ValueError as exception_msg:
    skj_std.exit_with_failure(exception_msg, "SET_FILE_PROPERTIES")


from skj_animation import set_animation_properties
try: # set animation properties (S/F/T, adding seq for each file, num of frames for each file, etc)
    set_animation_properties()
except (ValueError, IndexError, TypeError, ArithmeticError) as exception_msg:
    skj_std.exit_with_failure(exception_msg, "SET_ANIM_PROPERTIES")


from skj_subprocess_gnuplot import draw_animation_frames
try: # Do not forget that this deletes the whole adding_seq for each file if type multiplot ...
    draw_animation_frames() # ... but that is okay, it will no longer be needed
except (IndexError, ValueError) as exception_msg: