Example #1
0
def create_base_folder(path, package_name):
    """
        Create base directory if needed
    """

    basePath = pathlib.Path(path).parent

    # Check if the base folder is a file
    if basePath.exists():
        # Check if the parent is a file or if its a symlink
        if basePath.is_file() or basePath.is_symlink():
            logging.print_error(
                "Base directory is a file or link: {}".format(basePath),
                package_name)
            return False
        # If not, it must be a directory, so we are ok
        else:
            return True

    # Create path and parents (or ignore if folder already exists)
    try:
        basePath.mkdir(parents=True, exist_ok=True)
    except Exception as error:
        logging.print_error(
            "Could not create parent folder \"{}\" due to following error: {}".
            format(basePath, error), package_name)
        return False
    else:
        logging.print_verbose(
            "Parent folder dosent exist and was created: {}".format(basePath),
            package_name)

    return True
Example #2
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)
Example #3
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)
Example #4
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
Example #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)
Example #6
0
def create_symlink(source, destination, package_name=None):
    """
        Creates symlink from source to destination
    """

    try:
        os.symlink(source, destination)
    except OSError as error:
        logging.print_error("Unable to create symlink: {}".format(error),
                            package_name)
    else:
        logging.print_verbose("Linking {} <-> {}".format(source, destination),
                              package_name)
Example #7
0
def compile_book_init(p_output_format):
    global output_format

    if p_output_format == Format.PDF.value:
        output_format = Format.PDF
    elif p_output_format == Format.EPUB.value:
        output_format = Format.EPUB
    elif p_output_format == Format.HTML.value:
        output_format = Format.HTML
    else:
        logging.print_error('Invalid option for output format provided: ' +
                            p_output_format)
        exit(1)
Example #8
0
def create_folder(path, package_name):
    """
        Creates a folder
    """
    try:
        os.makedirs(path)
    except OSError as error:
        logging.print_error(
            "Could not create folder \"{}\" due to following error: {}".format(
                path, error), package_name)
    else:
        logging.print_verbose(
            "Folder doesn't exist and was created: {}".format(path),
            package_name)
Example #9
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
Example #10
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
Example #11
0
def copy_media_html():
    """
    Copies media folders from cwd to output for HTML post 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)

    # copy media folders to output
    try:
        for media_dir in media_root_dirs:
            dir_name = os.path.basename(os.path.normpath(media_dir))
            shutil.copytree(media_dir, output_path + '/html/' + dir_name)
    # except OSError:
    except OSError as err:
        logging.print_error("OS error: {0}".format(err))
        sys.exit('Media directory copy to output failed.')
Example #12
0
def copy_media_cwd():
    """
    Copies media folders from content/ to cwd for compilation
    """
    media_dirs = []

    for (root, dirs, files) in os.walk(content_path):
        if (root.endswith('_media')):
            media_dirs.append(root)

    # copy media folders to root
    try:
        for media_dir in media_dirs:
            dir_name = os.path.basename(os.path.normpath(media_dir))
            shutil.copytree(media_dir, cwd + '/' + dir_name)
    # except OSError:
    except OSError as err:
        logging.print_error("OS error: {0}".format(err))
        sys.exit('Media directory copy to cwd failed.')
Example #13
0
def is_converted():
    """
    Determine if the content directory has already been populated (outline already converted)

    Returns:
        True if files exist in the content directory
        False otherwise
    """

    result = False

    if os.path.exists(content_path) and os.path.isdir(content_path):
        if os.listdir(content_path):
            result = True
            logging.print_warning('Warning: Content directory is not empty.')
    else:
        result = True
        logging.print_error('Error: Content directory does not exist.')

    return result
Example #14
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.')
Example #15
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!')
Example #16
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)
Example #17
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")