def get_args(): _args = sys.argv[1:] if not _args: print ( "[{NAME}]\n\n" "Usage:\n" "python {NAME}.py folder\n" "python {NAME}.py path/to/folder\n" "python {NAME}.py folder1 folder2 ... folderN\n" ).format(NAME=NAME) status.stop(NAME) elif not all(os.path.isdir(_arg) for _arg in _args): dirs_available = [i for i in os.listdir(os.getcwd()) if (os.path.isdir(i) and not i.startswith('.') and not i.startswith('_'))] status.important(NAME,( 'Arguments must be directories from the repo root.\n\n' 'The available directories are:\n' ' {}'.format('\n '.join(dirs_available)) )) status.stop(NAME) else: args = [os.path.dirname(_arg+'/') for _arg in _args] return args
def print_flags(flags, config, path_html, tree): for flag in flags: if flag=='show-config': status.log(NAME,( "{}/config.json ['tutorial_name']:\n\t'{}'" ).format(tree,config['tutorial_name'])) status.log(NAME,( "{}/config.json ['tags']['title']:\n\t'{}'" ).format(tree,config['tags']['title'])) status.log(NAME,( "{}/config.json ['tags']['meta_description']:\n\t'{}'" ).format(tree,config['tags']['meta_description'])) elif flag=='no-title': status.important(NAME,( "There is no <title>\nin `{}`.\n" "Please fill in\n`{}/config.json`" ).format(path_html,tree)) elif flag=='multiple-title': status.important(NAME,( "There is more than one <title>\nin `{}`.\n" "Picking the last one for\n`{}/config.json`" ).format(path_html,tree)) status.log(NAME,( 'With last <title> tag, set meta' 'title to "{}"' ).format(config['tags']['title'])) elif flag=='no-meta_description': status.important(NAME,( "There is more than one <meta name='description'> in\n`{}`.\n" "Please fill in\n`{}/config.json`" ).format(path_html,tree)) elif flag=='multiple-meta_descriptions': status.important(NAME,( "There is more than one <meta name='description'> in\n`{}`.\n" "Picking the last one for\n`{}/config.json`" ).format(path_html,tree)) status.log(NAME,( 'With last <meta name="description"> tag, ' 'set meta description to "{}"' ).format(config['tags']['meta_description'])) elif flag=='no-tutorial_name': status.important(NAME,( "Please fill 'tutorial_name' in\n`{}/config.json`" ).format(tree)) else: status.log(NAME,( 'With <title> tag, set meta title to:\n\t"{}"' ).format(config['tags']['title'])) status.log(NAME,( 'With <meta name="description"> tag, set meta description to:\n\t"{}"' ).format(config['tags']['meta_description'])) return
def check_translate(folder, paths_html, translate_filename_url): files_html_translate = translate_filename_url.keys() files_html = [os.path.split(path_html)[1] for path_html in paths_html] # Case 0: if .json and raw/ align, return paths_html if set(files_html_translate) == set(files_html): return paths_html # Case 1: if .json < raw/, return part of paths_html contained in .json elif len(files_html_translate) < len(files_html): diff = list(set(files_html) - set(files_html_translate)) to_be = 'was' if len(diff) == 1 else 'were' to_have = 'has' if len(diff) == 1 else 'have' status.important(NAME, ("File(s): \n\n {diff}\n\n" "{to_be} found from `{folder}/raw/` but {to_have} " "no correspondence\n" "in `{folder}/translate_filename_url.json`.\n\n" "Note that files not listed in " "`{folder}/translate_filename_url.json`\n" "will NOT be published").format(diff='\n'.join(diff), folder=folder, to_be=to_be, to_have=to_have)) return [ path_html for path_html in paths_html if (os.path.split(path_html)[1] in files_html_translate) ] # Case 2: if .json > raw/, stop execution else: diff = list(set(files_html_translate) - set(files_html)) to_be = 'is' if len(diff) == 1 else 'are' to_have = 'has' if len(diff) == 1 else 'have' status.important( NAME, ("File(s): \n\n {diff}\n\n" "{to_be} listed in " "`{folder}/translate_filename_url.json` but {to_have} " "no correspondence\n" "in `{folder}/raw/`.\n\n" "Note that files not found in " "`{folder}/raw` CANNOT be published").format(diff='\n'.join(diff), folder=folder, to_be=to_be, to_have=to_have)) status.stop(NAME) return
def check_published_subdirectories(folder, translate_filename_url): path_includes = os.path.join(folder, 'published', 'includes') path_images = os.path.join(folder, 'published', 'static', 'images') try: subdirectories_includes = os.listdir(path_includes) except: subdirectories_includes = [] try: subdirectories_images = os.listdir(path_images) except: subdirectories_images = [] dirs_url = translate_filename_url.values() if set(subdirectories_includes) != set(subdirectories_images): status.important( NAME, ("Directories `{folder}/published/includes/`\n" "and `{folder}/published/static/images/`\n" "do not have to same subdirectories.\n\n" "Please investigate (that's a weird one).").format(folder=folder)) elif len(subdirectories_includes) > len(dirs_url): diff = list(set(subdirectories_includes) - set(dirs_url)) to_be = 'is' if len(diff) == 1 else 'are' status.important(NAME, ( "Subdirectory(ies):\n\n {diff}\n\n" "from `{folder}/published/includes/`\n" "and `{folder}/published/static/images/`\n" "{to_be} not listed in `{folder}/translate_filename_url.json`.\n\n" "Please investigate:\n\n" " - Did you change a url in " "{folder}/translate_filename_url.json\n" " not meant to be redirected (e.g. you fixed a typo)?\n\n" " - Or, did you remove a url in " "{folder}/translate_filename_url.json\n" " so that some raw/ HTML file is not published just yet?\n\n" " Then, please remove\n" " {folder}/published/includes/{diff}/ and\n" " {folder}/published/static/images/{diff}/ !\n\n" " If you don't, $ make push-to-streambed will copy\n" " unnecessary files over to streambed/ !").format( diff='\n'.join(diff), folder=folder, to_be=to_be)) elif not len(subdirectories_includes) <= len(dirs_url): pass return
def check_published_subdirectories(folder, translate_filename_url): path_includes = os.path.join(folder, 'published', 'includes') path_images = os.path.join(folder, 'published', 'static', 'images') try: subdirectories_includes = os.listdir(path_includes) except: subdirectories_includes = [] try: subdirectories_images = os.listdir(path_images) except: subdirectories_images = [] dirs_url = translate_filename_url.values() if set(subdirectories_includes) != set(subdirectories_images): status.important(NAME, ( "Directories `{folder}/published/includes/`\n" "and `{folder}/published/static/images/`\n" "do not have to same subdirectories.\n\n" "Please investigate (that's a weird one)." ).format(folder=folder)) elif len(subdirectories_includes) > len(dirs_url): diff = list(set(subdirectories_includes) - set(dirs_url)) to_be = 'is' if len(diff) == 1 else 'are' status.important(NAME, ( "Subdirectory(ies):\n\n {diff}\n\n" "from `{folder}/published/includes/`\n" "and `{folder}/published/static/images/`\n" "{to_be} not listed in `{folder}/translate_filename_url.json`.\n\n" "Please investigate:\n\n" " - Did you change a url in " "{folder}/translate_filename_url.json\n" " not meant to be redirected (e.g. you fixed a typo)?\n\n" " - Or, did you remove a url in " "{folder}/translate_filename_url.json\n" " so that some raw/ HTML file is not published just yet?\n\n" " Then, please remove\n" " {folder}/published/includes/{diff}/ and\n" " {folder}/published/static/images/{diff}/ !\n\n" " If you don't, $ make push-to-streambed will copy\n" " unnecessary files over to streambed/ !" ).format(diff='\n'.join(diff), folder=folder, to_be=to_be)) elif not len(subdirectories_includes) <= len(dirs_url): pass return
def get_translate_filename_url(folder): file_path = os.path.join(folder, 'translate_filename_url.json') with open(file_path) as f: translate = json.load(f) translate_filename_url = dict() translate_redirects = dict() for k, v in translate.items(): if isinstance(v, list) and isinstance(v[-1], (str, unicode)): translate_filename_url[k] = v[-1] translate_redirects[v[-1]] = v[0:-1] elif isinstance(v, (str, unicode)): translate_filename_url[k] = v else: status.important(NAME, ( "object values in {}/translate_filename_url.json\n" "must be either a string (the urls)\n" "or a list of strings (to handle redirects)" ).format(folder)) status.stop(NAME) return translate_filename_url, translate_redirects
def get_translate_filename_url(folder): file_path = os.path.join(folder, 'translate_filename_url.json') with open(file_path) as f: translate = json.load(f, object_pairs_hook=OrderedDict) translate_filename_url = OrderedDict() translate_redirects = OrderedDict() for k, v in translate.items(): if isinstance(v, list) and isinstance(v[-1], (str, unicode)): translate_filename_url[k] = v[-1] translate_redirects[v[-1]] = v[0:-1] elif isinstance(v, (str, unicode)): translate_filename_url[k] = v else: status.important(NAME, ( "object values in {}/translate_filename_url.json\n" "must be either a string (the urls)\n" "or a list of strings (to handle redirects)" ).format(folder)) status.stop(NAME) return translate_filename_url, translate_redirects
def check_translate(folder, paths_html, translate_filename_url): files_html_translate = translate_filename_url.keys() files_html = [os.path.split(path_html)[1] for path_html in paths_html] # Case 0: if .json and raw/ align, return paths_html if set(files_html_translate) == set(files_html): return paths_html # Case 1: if .json < raw/, return part of paths_html contained in .json elif len(files_html_translate) < len(files_html): diff = list(set(files_html) - set(files_html_translate)) to_be = 'was' if len(diff)==1 else 'were' to_have = 'has' if len(diff)==1 else 'have' status.important(NAME,( "File(s): \n\n {diff}\n\n" "{to_be} found from `{folder}/raw/` but {to_have} " "no correspondence\n" "in `{folder}/translate_filename_url.json`.\n\n" "Note that files not listed in " "`{folder}/translate_filename_url.json`\n" "will NOT be published" ).format(diff='\n'.join(diff),folder=folder, to_be=to_be,to_have=to_have)) return [path_html for path_html in paths_html if (os.path.split(path_html)[1] in files_html_translate)] # Case 2: if .json > raw/, stop execution else: diff = list(set(files_html_translate) - set(files_html)) to_be = 'is' if len(diff)==1 else 'are' to_have = 'has' if len(diff)==1 else 'have' status.important(NAME,( "File(s): \n\n {diff}\n\n" "{to_be} listed in " "`{folder}/translate_filename_url.json` but {to_have} " "no correspondence\n" "in `{folder}/raw/`.\n\n" "Note that files not found in " "`{folder}/raw` CANNOT be published" ).format(diff='\n'.join(diff),folder=folder, to_be=to_be,to_have=to_have)) status.stop(NAME) return
def get_paths_html(folder): paths_html = [] folder_raw = os.path.join(folder,'raw') if not os.path.isdir(folder_raw): status.important(NAME,( 'Folder `{}` must contain a `raw/` subfolder'.format(folder) )) status.stop(NAME) for path_folder, subfolders, files in os.walk(folder_raw): for subfolder in subfolders: if subfolder == '__MACOSX': path_MACOSX = os.path.join(path_folder, subfolder) status.important(NAME,( "Removing `{}`\n - Not needed (this is no big deal)" ).format(path_MACOSX)) shutil.rmtree(path_MACOSX) for path_folder, subfolders, files in os.walk(folder_raw): for f in files: if f.endswith('.html'): path_html = os.path.join(path_folder,f) paths_html.append(path_html) if not paths_html: status.important(NAME,( 'No .html files located inside `{}`'.format(folder) )) status.stop(NAME) return paths_html
def get_paths_html(folder): paths_html = [] folder_raw = os.path.join(folder, 'raw') if not os.path.isdir(folder_raw): status.important( NAME, ('Folder `{}` must contain a `raw/` subfolder'.format(folder))) status.stop(NAME) for path_folder, subfolders, files in os.walk(folder_raw): for subfolder in subfolders: if subfolder == '__MACOSX': path_MACOSX = os.path.join(path_folder, subfolder) status.important( NAME, ("Removing `{}`\n - Not needed (this is no big deal)" ).format(path_MACOSX)) shutil.rmtree(path_MACOSX) for path_folder, subfolders, files in os.walk(folder_raw): for f in files: if f.endswith('.html'): path_html = os.path.join(path_folder, f) paths_html.append(path_html) if not paths_html: status.important(NAME, ('No .html files located inside `{}`'.format(folder))) status.stop(NAME) return paths_html
def get_args(): _args = sys.argv[1:] if not _args: print( "[{NAME}]\n\n" "Usage:\n" "python {NAME}.py folder\n" "python {NAME}.py path/to/folder\n" "python {NAME}.py folder1 folder2 ... folderN\n").format(NAME=NAME) status.stop(NAME) elif not all(os.path.isdir(_arg) for _arg in _args): dirs_available = [ i for i in os.listdir(os.getcwd()) if (os.path.isdir(i) and not i.startswith('.') and not i.startswith('_')) ] status.important( NAME, ('Arguments must be directories from the repo root.\n\n' 'The available directories are:\n' ' {}'.format('\n '.join(dirs_available)))) status.stop(NAME) else: args = [os.path.dirname(_arg + '/') for _arg in _args] return args
def print_flags(flags, config, path_html, tree): for flag in flags: if flag == 'show-config': status.log(NAME, ( "{}/config.json ['tutorial_name']:\n\t'{}'" ).format(tree, config['tutorial_name'])) status.log(NAME, ( "{}/config.json ['banner_image']:\n\t'{}'" ).format(tree, config['banner_image'])) status.log(NAME, ( "{}/config.json ['tags']['title']:\n\t'{}'" ).format(tree, config['tags']['title'])) status.log(NAME, ( "{}/config.json ['tags']['meta_description']:\n\t'{}'" ).format(tree, config['tags']['meta_description'])) elif flag == 'no-title': status.important(NAME, ( "There is no <title>\nin `{}`.\n" "Please fill in\n`{}/config.json`" ).format(path_html, tree)) elif flag == 'multiple-title': status.important(NAME, ( "There is more than one <title>\nin `{}`.\n" "Picking the last one for\n`{}/config.json`" ).format(path_html, tree)) status.log(NAME, ( 'With last <title> tag, set meta' 'title to "{}"' ).format(config['tags']['title'])) elif flag == 'no-meta_description': status.important(NAME, ( "There is more than one <meta name='description'> in\n`{}`.\n" "Please fill in\n`{}/config.json`" ).format(path_html, tree)) elif flag == 'multiple-meta_descriptions': status.important(NAME, ( "There is more than one <meta name='description'> in\n`{}`.\n" "Picking the last one for\n`{}/config.json`" ).format(path_html, tree)) status.log(NAME, ( 'With last <meta name="description"> tag, ' 'set meta description to "{}"' ).format(config['tags']['meta_description'])) elif flag == 'no-tutorial_name': status.important(NAME, ( "Please fill 'tutorial_name' in\n`{}/config.json`" ).format(tree)) elif flag == 'no-banner_image': status.important(NAME, ( "Please fill 'banner_image' in\n`{tree}/config.json`:\n" "- For an iframe: set 'banner_image' to the url\n" "- For a static image: set 'banner_image' " "to the image file name\n" " AND copy the image to:\n" " ``{tree_image}``/\n" "- For no banner image, set 'banner_image' to false" ).format(tree=tree, tree_image=tree.replace('includes', 'static/images'))) elif flag == 'missing-banner_image': status.important(NAME, ( "The static banner image linked to 'banner_image' " "({image}) in\n " "`{tree}/config.json`\n " "is not found in\n " "`{tree_image}`/\n " "Please copy it over." ).format(image=config['banner_image'], tree=tree, tree_image=tree.replace('includes', 'static/images'))) else: status.log(NAME, ( 'With <title> tag, set meta title to:\n\t"{}"' ).format(config['tags']['title'])) status.log(NAME, ( 'With <meta name="description"> tag, ' 'set meta description to:\n\t"{}"' ).format(config['tags']['meta_description'])) return
def print_flags(flags, config, path_html, tree): for flag in flags: if flag == 'show-config': status.log(NAME, ("{}/config.json ['tutorial_name']:\n\t'{}'").format( tree, config['tutorial_name'])) status.log(NAME, ("{}/config.json ['banner_image']:\n\t'{}'").format( tree, config['banner_image'])) status.log(NAME, ("{}/config.json ['tags']['title']:\n\t'{}'").format( tree, config['tags']['title'])) status.log(NAME, ( "{}/config.json ['tags']['meta_description']:\n\t'{}'").format( tree, config['tags']['meta_description'])) elif flag == 'no-title': status.important(NAME, ("There is no <title>\nin `{}`.\n" "Please fill in\n`{}/config.json`").format( path_html, tree)) elif flag == 'multiple-title': status.important( NAME, ("There is more than one <title>\nin `{}`.\n" "Picking the last one for\n`{}/config.json`").format( path_html, tree)) status.log(NAME, ('With last <title> tag, set meta' 'title to "{}"').format(config['tags']['title'])) elif flag == 'no-meta_description': status.important( NAME, ("There is more than one <meta name='description'> in\n`{}`.\n" "Please fill in\n`{}/config.json`").format(path_html, tree)) elif flag == 'multiple-meta_descriptions': status.important( NAME, ("There is more than one <meta name='description'> in\n`{}`.\n" "Picking the last one for\n`{}/config.json`").format( path_html, tree)) status.log(NAME, ('With last <meta name="description"> tag, ' 'set meta description to "{}"').format( config['tags']['meta_description'])) elif flag == 'no-tutorial_name': status.important( NAME, ("Please fill 'tutorial_name' in\n`{}/config.json`" ).format(tree)) elif flag == 'no-banner_image': status.important( NAME, ("Please fill 'banner_image' in\n`{tree}/config.json`:\n" "- For an iframe: set 'banner_image' to the url\n" "- For a static image: set 'banner_image' " "to the image file name\n" " AND copy the image to:\n" " ``{tree_image}``/\n" "- For no banner image, set 'banner_image' to false").format( tree=tree, tree_image=tree.replace('includes', 'static/images'))) elif flag == 'missing-banner_image': status.important( NAME, ("The static banner image linked to 'banner_image' " "({image}) in\n " "`{tree}/config.json`\n " "is not found in\n " "`{tree_image}`/\n " "Please copy it over.").format( image=config['banner_image'], tree=tree, tree_image=tree.replace('includes', 'static/images'))) else: status.log(NAME, ('With <title> tag, set meta title to:\n\t"{}"').format( config['tags']['title'])) status.log(NAME, ('With <meta name="description"> tag, ' 'set meta description to:\n\t"{}"').format( config['tags']['meta_description'])) return