예제 #1
0
def start_tests(path='.', log_level=default_log_level):
    """
		Function to run tests at chosen directory
		Params:
			path: string 		- path to chosen directory
			log_level?: string 	- one of ERROR, WARNING, INFO, SUCCESS
				The system logs messages with level not bigger than chosen log_level.
				For example if chosen level is WARNING - the system will show ERROR
				and WARNING messages.
	"""

    set_log_level(log_level)

    print_info('Starting...')
    tests = Test.collect_tests(path)
    Test.run_tests(tests)
    failed_tests = Test.get_failed_tests(tests)
    print_info('Finished!')

    if len(failed_tests):
        print_error('Not all tests successfully passed :(')
        print_error('Failed tests:')
        for test in failed_tests:
            print_error(test)
    else:
        print_success('All tests successfully pased!')
예제 #2
0
def compile_book():
    """
    Executes actions to compile a book
    """

    # Look for project in cwd
    if is_project_directory() is False:
        logging.print_info('No Tanagra project found in ' + cwd)
        exit(0)

    # Look for converted outline in content/
    if is_converted() is False:
        logging.print_info('Converted outline not found in ' + content_path)
        exit(0)

    global args
    import compile_book

    if len(args) == 1:
        output_format = str(args[0])
        compile_book.compile_book_init(output_format)
    else:
        compile_book.compile_book_prompt()

    compile_book.compile_book()
예제 #3
0
 def run(self):
     print_info('RUNNING TEST: {} ({})'.format(self.filename, self.command))
     result = os.system(self.command)
     if is_command_result_successfull(result):
         print_success('SUCCESS')
         self.status = Status.SUCCESS
     else:
         print_error('ERROR: {}'.format(result))
         self.status = Status.ERROR
예제 #4
0
def build_template_prompt():
    global book_name

    logging.print_info(
        'What is a short name for your book project? This is not your title. ['
        + DEFAULT_BOOK_NAME + ']')
    book_name = str(input())

    if not book_name:
        book_name = DEFAULT_BOOK_NAME

    book_name = cleanup_book_name(book_name)
예제 #5
0
def compile_book():
    cleanup_media()
    copy_media_cwd()

    global output_format
    output_file_name = 'output'  # TODO: replace with book name

    file_list = [
        os.path.join(dp, f) for dp, dn, filenames in os.walk(content_path)
        for f in filenames if os.path.splitext(f)[1] == '.md'
    ]

    file_list = sorted(file_list)

    output_format_path = str(output_path) + '/' + \
        str(output_format.value) + '/'

    try:
        cleanup_output(str(output_format.value))

        # create content directory
        if not os.path.exists(output_format_path):
            os.makedirs(output_format_path)
    except OSError:
        sys.exit('Output format directory "' + output_format_path +
                 '" does not exist and cannot be created')

    output_file = output_format_path + 'output.' + str(output_format.value)

    # leave out the file list
    if output_format.value == Format.PDF.value:
        args = ['pandoc', '--pdf-engine=xelatex', '-s', '-o', str(output_file)]
    else:
        args = ['pandoc', '-s', '-o', str(output_file)]
    # splice in the file list to avoid Pandoc weirdness
    args[2:2] = file_list

    try:
        # run pandoc with the parameters
        subprocess.check_output(args)
    except subprocess.CalledProcessError as e:
        cleanup_media()
        logging.print_error(e.output)
        logging.print_error("Pandoc converstion failed: ", str(args))

    if (output_format == Format.HTML):
        copy_media_html()

    cleanup_media()

    logging.print_info("Markdown book compiled into " +
                       str(output_format.value).upper() + ": " + output_file)
예제 #6
0
def cleanup_output(format=None):
    """
    Removes compiled output for the specified format or all output when no format is provided.

    Parameters:
        format  PDF, EPUB, or HTML; null will empty the entire output directory
    """
    # Execute specified command
    if format == Format.PDF.value:
        logging.print_info("Deleting output for PDF.")
    elif format == Format.EPUB.value:
        logging.print_info("Deleting output for EPUB.")
    elif format == Format.HTML.value:
        logging.print_info("Deleting output for HTML.")
    else:
        logging.print_info("Deleting output for all formats.")

    # cleanup output directories
    try:
        cleanup_path = cwd + '/output/' + format

        if os.path.isdir(cleanup_path) and os.path.exists(cleanup_path):
            shutil.rmtree(cleanup_path)
    # except OSError:
    except OSError as err:
        logging.print_error("OS error: {0}".format(err))
        sys.exit('Output directory cleanup failed:', cleanup_path)
예제 #7
0
def is_project_directory():
    """
    Determine if the current directory is a Tanagra project directory

    Returns:
        True if current working directory is a Tanagra project directory
        False otherwise
    """
    global command
    result = False

    logging.print_info('Checking current working directory (' + cwd +
                       ') for project...')

    metadata_found = os.path.exists(metadata_path)
    outline_found = os.path.exists(outline_path)
    content_found = os.path.exists(content_path)
    output_found = os.path.exists(output_path)

    if ((metadata_found is False) and (outline_found is False)
            and (metadata_found is False) and (outline_found is False)):
        logging.print_warning(
            'Tanagra project not found in current directory: ' + cwd)
    elif ((metadata_found is False) or (outline_found is False)
          or (metadata_found is False) or (outline_found is False)):
        # project not properly initialized
        logging.print_error('Tanagra project not properly initialized.')

        if metadata_found is False:
            logging.print_error('  - metadata.md file not found.')

        if outline_found is False:
            logging.print_error('  - outline.md file not found.')

        if content_found is False:
            logging.print_error('  - content/ directory not found.')

        if output_found is False:
            logging.print_error('  - output/ directory not found.')

        logging.print_warning(
            'Please run Tanagra to build new book template or attempt to resolve issues manually.'
        )
        print('')
    else:
        result = True

    return result
예제 #8
0
def get_command():
    """
    Determine that the user is trying to do
    """
    global args

    command = None

    if len(sys.argv) > 0:
        # get the command argument (build, convert, compile)
        command_arg = str(sys.argv.pop(0)).lower()  # get 1

        if command_arg == 'build':
            command = Command.BUILD
        elif command_arg == 'convert':
            command = Command.CONVERT
        elif command_arg == 'compile':
            command = Command.COMPILE
        else:
            logging.print_error('Command arugment is not valid.')
            exit(1)

        args = sys.argv  # get arguments
    else:
        # command argument not provided
        logging.print_info('Please enter a number to specify a command.')
        logging.print_info(' [1] Build a new book template')
        logging.print_info(' [2] Convert outline into file structure')
        logging.print_info(' [3] Compile markdown files and media into a book')
        logging.print_info(' [4] Exit Tanagra')
        command_choice = str(input())
        args = []  # make args list empty set as there have been none provided

        if command_choice == '1':
            command = Command.BUILD
        elif command_choice == '2':
            command = Command.CONVERT
        elif command_choice == '3':
            command = Command.COMPILE
        elif command_choice == '4':
            exit(0)
        else:
            logging.print_error('Failed to enter a valid command selection.')
            exit(1)

    return command
예제 #9
0
def build_template():
    """
    Executes actions build a new book template
    """
    global args

    # Look for project in cwd
    if is_project_directory() is True:
        logging.print_info('Existing Tanagra project found in ' + cwd)
        exit(0)

    import build_template

    if len(args) == 1:
        book_name = str(args[0])
        build_template.build_template_init(book_name)
    else:
        build_template.build_template_prompt()

    build_template.build_template()
예제 #10
0
def cleanup_media():
    """
    Removes copies of media directories from root following compilation
    """
    media_root_dirs = []

    for child in next(os.walk(cwd))[1]:
        if (os.path.isdir(child)) and child.endswith('_media'):
            media_root_dirs.append(child)

    # cleanup media directories from root
    try:
        for media_root_dir in media_root_dirs:
            if os.path.isdir(cwd + '/' + media_root_dir) and os.path.exists(
                    cwd + '/' + media_root_dir):
                logging.print_info('Cleanup: ' + cwd + '/' + media_root_dir)
                shutil.rmtree(cwd + '/' + media_root_dir)
    # except OSError:
    except OSError as err:
        logging.print_error("OS error: {0}".format(err))
        sys.exit('Media directory cleanup failed.')
예제 #11
0
def convert_outline():
    """
    Executes actions to convert an outline to files in content directory
    """

    # Look for project in cwd
    if is_project_directory() is False:
        logging.print_info('No Tanagra project found in ' + cwd)
        exit(0)

    # Look for converted outline in content/
    if is_converted() is True:
        logging.print_info(
            'Converted outline already found in content directory (' +
            content_path + '). Type "confirm" to overwrite content directory.')

        response = str(input()).lower()

        if response != "confirm":
            logging.print_info('Content directory overwrite not confirmed.')
            exit(1)

    # Convert outline
    import convert_outline
    convert_outline.convert_outline()
예제 #12
0
def main():
    """
    Main function
    """
    global script
    global command
    global args

    script = str(sys.argv.pop(0))  # get 0

    # Welcome
    logging.print_welcome()

    # Get the intended command
    command = get_command()

    # Execute specified command
    if command == Command.BUILD:
        logging.print_info('Building book template.')
        build_template()
    elif command == Command.CONVERT:
        logging.print_info('Converting outline into file structure.')
        convert_outline()
    elif command == Command.COMPILE:
        logging.print_info('Compiling markdown into book.')
        compile_book()
    else:
        logging.print_error('Command selection failed for: ', command)
예제 #13
0
def compile_book_prompt():
    global output_format

    logging.print_info(
        'Please select the output format for your rendered book.')
    logging.print_info(' [1] PDF')
    logging.print_info(' [2] EPUB')
    logging.print_info(' [3] HTML')
    output_format_choice = str(input())

    if not output_format_choice:
        logging.print_error('Failed to enter a command selection.')
        exit(1)
    elif output_format_choice == '1':
        output_format = Format.PDF
    elif output_format_choice == '2':
        output_format = Format.EPUB
    elif output_format_choice == '3':
        output_format = Format.HTML
    else:
        logging.print_error('Failed to enter a valid output format selection.')
        exit(1)
예제 #14
0
    def collect_tests(path='.'):
        print_info('Collecting tests...')

        all_filenames = get_filenames(path)

        tests = []
        for filename in all_filenames:
            path_to_file = os.path.join(path, filename)
            if not is_python_source(filename):
                continue

            print_info('Searching at {}...'.format(filename))
            commands = find_commands_at_file(path_to_file)

            if not len(commands):
                print_warning('No test commands for {}'.format(filename))
                continue

            print_info('{} command was found:'.format(len(commands)))
            for current_command in commands:
                print_info('command: {}'.format(current_command))
                tests.append(Test(path_to_file, current_command))

        return tests
예제 #15
0
def build_template():
    global book_name

    # create book directory
    book_path = cwd + '/' + book_name

    try:
        if not os.path.exists(book_path):
            os.makedirs(book_path)
    except OSError:
        sys.exit('Book directory "' + book_path +
                 '" does not exist and cannot be created')

    # create content path
    content_path = book_path + '/content'

    try:
        # create content directory
        if not os.path.exists(content_path):
            os.makedirs(content_path)
    except OSError:
        sys.exit('Content directory "' + content_path +
                 '" does not exist and cannot be created')

    # create output path
    output_path = book_path + '/output'

    try:
        # create content directory
        if not os.path.exists(output_path):
            os.makedirs(output_path)
    except OSError:
        sys.exit('Output directory "' + output_path +
                 '" does not exist and cannot be created')

    # copy template files
    try:
        # copy outline.md
        shutil.copy(SCRIPT_PATH + '/templates/outline.md',
                    book_path + '/outline.md')

        # copy metadata.md
        shutil.copy(SCRIPT_PATH + '/templates/metadata.md',
                    book_path + '/metadata.md')

        # copy README files for allowing empty directories to be committed
        shutil.copy(SCRIPT_PATH + '/templates/README',
                    content_path + '/README')
        shutil.copy(SCRIPT_PATH + '/templates/README', output_path + '/README')
    except OSError:
        sys.exit('Template file copy failed.')

    logging.print_info('Template creation completed.')
    logging.print_info(content_path)
    logging.print_info(output_path)
    logging.print_info(book_path + '/metadata.md')
    logging.print_info(book_path + '/outlne.md')
    print('\n')
    logging.print_info(
        'Your book template is now ready. You may populate your metadata.md and outline.md files.'
    )
예제 #16
0
def convert_outline():
    logging.print_info('Content directory: ' + content_path)
    logging.print_info('Outline file: ' + output_path)

    # make sure outline file exists
    logging.print_info('Loading ' + outline_path + '...')
    if path.exists(outline_path):
        logging.print_info('Reading ' + outline_path + '...')
    else:
        logging.print_info(outline_path + ' does not exist.')
        sys.exit(1)

    # read the outline file
    with open(outline_path) as f:
        content = f.readlines()

    structure = []

    # build up structure list with valid lines
    for line in content:
        # only grab the line if it starts with markdown list item 1. XXXX
        if line.lstrip(' ')[0:3] == '1. ':
            structure.append(line.strip('\n'))

    # clean out the content structure
    if os.path.isdir(content_path):
        for file in os.listdir(content_path):
            file_path = os.path.join(content_path, file)
            try:
                if os.path.isfile(file_path):
                    os.unlink(file_path)
                elif os.path.isdir(file_path):
                    shutil.rmtree(file_path)
            except Exception as e:
                logging.print_error(e)

        logging.print_info(content_path + ' emptied.')

    depth = 0
    part = ''
    chapter = ''
    section = ''
    subsection = ''

    for item in structure:
        if item:
            depth = (len(item) - len(item.lstrip(' '))) / 3
            item = item.lstrip(' ').lstrip('1. ')

            if depth == 0:
                # Part
                part = content_path + '/' + item
                if not os.path.exists(part):
                    os.makedirs(part)
                    logging.print_info(part)
                    # media folder
                    os.makedirs(part + '/' + item + '_media')
            if depth == 1:
                # Chapter
                logging.print_info(item)
                chapter = part + '/' + item + '.md'
                logging.print_info(chapter)

                mode = 'a+' if os.path.exists(chapter) else 'w+'
                with open(chapter, mode) as file:
                    file.write('# ' + item + "\n\n")
            if depth == 2:
                # Section
                section = '## ' + item
                logging.print_info(section)

                mode = 'a+' if os.path.exists(chapter) else 'w+'
                with open(chapter, mode) as file:
                    file.write('## ' + item + "\n\n\n")
            if depth == 3:
                # Subsection
                subsection = '### ' + item
                logging.print_info(subsection)

                mode = 'a+' if os.path.exists(chapter) else 'w+'
                with open(chapter, mode) as file:
                    file.write('### ' + item + "\n\n\n")