Пример #1
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
Пример #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
Пример #3
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)
Пример #4
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
Пример #5
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_
Пример #6
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_)
Пример #7
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))
Пример #8
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)
Пример #9
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'])