Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ generate:
python3 projectIndexer.py generate --hide-private --compile-tailwind --verbose

serve:
python3 projectIndexer.py serve
python3 projectIndexer.py serve --host 0.0.0.0

serve-no-livereload:
python3 projectIndexer.py serve --no-livereload
python3 projectIndexer.py serve --no-livereload --host 0.0.0.0
828 changes: 613 additions & 215 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"author": "RoboticsBrno",
"license": "MIT",
"dependencies": {
"preline": "^1.8.0",
"tailwindcss": "^3.3.2"
"preline": "^2.7.0",
"tailwindcss": "^3.4.17"
}
}
6 changes: 3 additions & 3 deletions projectIndexer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
from os import path, chdir
import click
from src.fetch_data import FetchData
from src.generate_web import GenerateWeb
Expand Down Expand Up @@ -97,7 +96,8 @@ def generate(github_token: str, fetch_directly: bool, input_repos: str, input_re

repos = [repo for repo, t in sorted_repos]

generate_web = GenerateWeb(repos, readme, contributors, about_info, team, build_dir, path.abspath(template_dir), static_dir, project_dir, hide_private, verbose, compile_tailwind)
generate_web = GenerateWeb(repos, readme, contributors, about_info, team, hide_private, verbose, compile_tailwind)
# generate_web = GenerateWeb(repos, readme, contributors, about_info, team, build_dir, template_dir, static_dir, project_dir, hide_private, verbose, compile_tailwind)

generate_web.generate()
print(f"Generated web to {build_dir} directory in {time() - start:.2f} seconds")
Expand All @@ -109,7 +109,7 @@ def generate(github_token: str, fetch_directly: bool, input_repos: str, input_re
@click.option('--build-dir', default='build', help='build directory (default is build)')
@click.option('--no-livereload', default=False, is_flag=True, help='Disable live reload and serve only once')
def serve(port: int, host: str, build_dir: str, no_livereload: bool):
chdir(build_dir)
os.chdir(build_dir)
if no_livereload:
import http.server
import socketserver
Expand Down
9 changes: 8 additions & 1 deletion src/fetch_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ def fetch_about_info(self) -> dict:
if int(r.status_code) == 200:
readme = {p[0]: [v for v in p[1:]] for p in [s.split("\n") for s in r.content.decode().strip().replace(" --->", "").split("<!--- ")][1:]}

cs_r = requests.get("https://raw.githubusercontent.com/RoboticsBrno/.github/main/profile/README.cs.md")
if int(cs_r.status_code) == 200:
cs_readme = {p[0]: [v for v in p[1:]] for p in [s.split("\n") for s in cs_r.content.decode().strip().replace(" --->", "").split("<!--- ")][1:]}


info = {}

titles = ["Website","RoboCamp","Instagram","Facebook","YouTube","Twitter"]
Expand All @@ -52,7 +57,9 @@ def fetch_about_info(self) -> dict:
info.update({"contacts":contacts})

info.update({"readme_1":readme["readme_1"],
"readme_2":readme["readme_2"]})
"readme_2":readme["readme_2"],
"readme_1_cs":cs_readme["readme_1"],
"readme_2_cs":cs_readme["readme_2"]})

info.update({"images":[s[s.find('src="')+5:s.find('"', s.find('src="')+5)] for s in readme["images"] if 'src="' in s]})

Expand Down
146 changes: 82 additions & 64 deletions src/generate_web.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import os
import random
import re
import requests
from datetime import datetime
from os import path, makedirs
from pprint import pprint
from typing import Union

from github import Repository
Expand All @@ -13,14 +10,13 @@
import subprocess
import logging

from markdown import markdown

from src.jinja_extensions.color_extension import ColorExtension
from src.web_helpers import load_projects, fix_readme_relative_images, conv_markdown

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class GenerateWeb:
def __init__(
self,
Expand All @@ -29,10 +25,10 @@ def __init__(
contributors: dict[str, list],
about_info: dict,
team: dict,
build_dir: str = 'build',
template_dir: path = 'templates',
static_dir: path = 'static',
project_dir: path = 'projects',
# build_dir: str = 'build',
# template_dir: path = 'templates',
# static_dir: path = 'static',
# project_dir: path = 'projects',
hide_private: bool = False,
verbose: bool = False,
compile_tailwind: bool = False,
Expand All @@ -46,52 +42,58 @@ def __init__(
self.contributors = contributors
self.about_info = about_info
self.team = team
self.static_dir = static_dir
self.template_dir = template_dir
self.project_dir = project_dir
self.build_dir = build_dir
self.static_dir = "static"
self.template_dir = "templates"
self.project_dir = "projects"
self.build_dir = "build"
self.hide_private = hide_private
self.verbose = verbose
self.compile_tailwind = compile_tailwind
if not path.exists(self.build_dir):
makedirs(self.build_dir)

self.env = Environment(
loader=FileSystemLoader(template_dir),
loader=FileSystemLoader(self.template_dir),
autoescape=select_autoescape(['html', 'jinja2']),
extensions=[ColorExtension]
)

self.paths = {
"/": {"path": "index.html", "showHeader": False, "external": False},
"Repos": {"path": "repos/index.html", "showHeader": True, "external": False},
"Repo": {"path": "repos/{}/index.html", "showHeader": False, "external": False},
"Projects": {"path": "projects/index.html", "showHeader": True, "external": False},
"Project": {"path": "projects/{}/index.html", "showHeader": False, "external": False},
#"Demo": {"path": "demo/index.html", "showHeader": True, "external": False},
"About": {"path": "about/index.html", "showHeader": True, "external": False},
#"Our team": {"path": "https://team.robotikabrno.cz/", "showHeader": True, "external": True},
"Our team": {"path": "team/index.html", "showHeader": True, "external": False},
"/": {"path": "index.html", "lang":"en", "showHeader": False, "external": False},
"Repos": {"path": "repos/index.html", "lang":"en", "showHeader": True, "external": False},
"Repo": {"path": "repo/{}/index.html", "lang":"en", "showHeader": False, "external": False},
"Projects": {"path": "projects/index.html", "lang":"en", "showHeader": True, "external": False},
"Project": {"path": "project/{}/index.html", "lang":"en", "showHeader": False, "external": False},
"Our team": {"path": "team/index.html", "lang":"en", "showHeader": True, "external": False},

"/cs": {"path": "cs/index.html", "lang":"cs", "showHeader": False, "external": False},
"Repozitáře": {"path": "cs/repozitare/index.html", "lang":"cs", "showHeader": True, "external": False},
"Repo_cs": {"path": "cs/repo/{}/index.html", "lang":"cs", "showHeader": False, "external": False},
"Projekty": {"path": "cs/projekty/index.html", "lang":"cs", "showHeader": True, "external": False},
"Projekt": {"path": "cs/projekt/{}/index.html", "lang":"cs", "showHeader": False, "external": False},
"Náš tým": {"path": "cs/nas-tym/index.html", "lang":"cs", "showHeader": True, "external": False},

# "Our team": {"path": "https://team.robotikabrno.cz/", "showHeader": True, "external": True},
# "About": {"path": "about/index.html", "showHeader": True, "external": False},
}

self.env.globals['paths'] = self.paths

def generate(self):
self.copy_static_files()

self.generate_about()
self.generate_repos_list()
self.generate_repos_detail()
#self.generate_demo()
self.generate_about()
self.generate_team()

projects = load_projects(self.project_dir)
self.generate_project_list(projects)
self.generate_projects(projects)
if self.compile_tailwind:
self.compile_tailwind_css()

def copy_static_files(self):
#TODO: not working
# TODO: not working
if self.verbose:
logger.info(f"Copying static files from {self.static_dir} to {self.build_dir}")

Expand All @@ -116,39 +118,42 @@ def compile_tailwind_css(self):
except subprocess.CalledProcessError as e:
print("An error occurred while executing the command. Error: ", e)



def generate_repos_list(self):
#self.render_page('repos.html', self.paths.get("/").get("path"), repos=self.repos) # Remove when about page is made
self.render_page('repos.html', self.paths.get("Repos").get("path"), repos=self.repos)
self.render_page('repos.html', self.paths.get("Repos").get("path"), repos=self.repos, lang="en")

self.render_page('repos_cs.html', self.paths.get("Repozitáře").get("path"), repos=self.repos, lang="cs")

def generate_repos_detail(self):
repo_count = len(self.repos)
for i, repo in enumerate(self.repos):
print(f"Generating {repo.name} {i}/{repo_count}")
readme_md = self.readme.get(repo.full_name, "No readme found")
readme_fixed_images = fix_readme_relative_images(readme_md, repo.full_name, repo.default_branch)

readme_fixed_images = fix_readme_relative_images(
readme_md, repo.full_name, repo.default_branch)

list_conv = {}
for i in range(0, 5):
list_conv[f"\n{' ' * i}- "] = f"\n{' ' * (3 if i > 1 else 0)} @@"
list_conv[f"\n{' ' * i}* "] = f"\n{' ' * (3 if i > 1 else 0)} @@"
list_conv[f"\n{' ' * i}- "] = f"\n{' ' *
(3 if i > 1 else 0)} @@"
list_conv[f"\n{' ' * i}* "] = f"\n{' ' *
(3 if i > 1 else 0)} @@"

readme_fixed_lists = readme_fixed_images
for o in list_conv:
readme_fixed_lists = readme_fixed_lists.replace(o, list_conv[o])
readme_fixed_lists = readme_fixed_lists.replace(
o, list_conv[o])

readme_fixed_lists = readme_fixed_lists.replace("@@", "- ● ") # add the dot before each element of the list
# add the dot before each element of the list
readme_fixed_lists = readme_fixed_lists.replace("@@", "- ● ")

readme_html = conv_markdown(readme_fixed_lists)
path_repo = self.paths.get("Repo").get("path").format(repo.name)

repo_contrib = [[sublist[i+1] if sublist[i] is None and i+1 < len(sublist) else sublist[i] for i in range(len(sublist))] for sublist in self.contributors[repo.full_name]]

self.render_page('repoDetail.html', path_repo, repo=repo, readme=readme_html, repo_contrib = repo_contrib)


# def generate_demo(self):
# self.render_page('demo.html', self.paths.get("Demo").get("path"))
repo_contrib = [[sublist[i+1] if sublist[i] is None and i+1 < len(
sublist) else sublist[i] for i in range(len(sublist))] for sublist in self.contributors[repo.full_name]]

self.render_page('repoDetail.html', self.paths.get("Repo").get("path").format(repo.name), repo=repo, readme=readme_html, repo_contrib=repo_contrib, lang="en")
self.render_page('repoDetail_cs.html', self.paths.get("Repo_cs").get("path").format(repo.name), repo=repo, readme=readme_html, repo_contrib=repo_contrib, lang="cs")

def generate_project_list(self, projects: list):
print(projects)
Expand All @@ -171,66 +176,79 @@ def generate_project_list(self, projects: list):
else:
other_projects.append(item)

projects_list = [["Recent and frequently used projects:",both_projects],
["Frequently used projects:",frequently_used_projects],
["Recent projects:",recent_projects],
["Other projects",other_projects]]
projects_list = [["Recent and frequently used projects:", both_projects],
["Frequently used projects:", frequently_used_projects],
["Recent projects:", recent_projects],
["Other projects", other_projects]]

self.render_page('projectList.html', self.paths.get("Projects").get("path"), projects_list=projects_list, lang="en")

self.render_page('projectList.html', self.paths.get("Projects").get("path"), projects_list=projects_list)
self.render_page('projectList_cs.html', self.paths.get("Projekty").get("path"), projects_list=projects_list, lang="cs")

def generate_projects(self, projects: list):
# pprint(projects)

for project in projects:
for i, repo in enumerate(project["related_repos"]):
project["related_repos"][i]["name"] = repo["url"].split("/")[-1] # add "name" key to related_projects

readme_url = project["readme"].replace("https://github.com/", "https://raw.githubusercontent.com/").replace("/blob", "")
project["related_repos"][i]["name"] = repo["url"].split(
"/")[-1] # add "name" key to related_projects

readme_url = str(project["readme"]).replace("https://github.com/", "https://raw.githubusercontent.com/").replace("/blob", "")
readme_md = "No readme found"

r = requests.get(readme_url)
if int(r.status_code) == 200:
readme_md = r.content.decode().strip()

full_name = "/".join(project["readme"].split("/")[-5:-3])
branch = project["readme"].split("/")[-2]

readme_fixed_images = fix_readme_relative_images(readme_md, full_name, branch)
readme_fixed_lists = readme_fixed_images.replace('\n- ', '\n@@ ').replace('\n* ', '\n@@ ').replace('\n - ', '\n @@ ').replace('\n * ', '\n @@ ').replace("@@", "- ●") # add the dot before each element of the list
full_name = "/".join(str(project["readme"]).split("/")[-5:-3])
branch = str(project["readme"]).split("/")[-2]

readme_fixed_images = fix_readme_relative_images(
readme_md, full_name, branch)
readme_fixed_lists = readme_fixed_images.replace('\n- ', '\n@@ ').replace('\n* ', '\n@@ ').replace(
# add the dot before each element of the list
'\n - ', '\n @@ ').replace('\n * ', '\n @@ ').replace("@@", "- ●")

readme_html = conv_markdown(readme_fixed_lists)

path_project = self.paths.get("Project").get("path").format(project["url"])
self.render_page('projectDetail.html', path_project, project=project, readme=readme_html)
self.render_page('projectDetail.html', path_project, project=project, readme=readme_html, lang="en")
path_project = self.paths.get("Projekt").get("path").format(project["url"])
self.render_page('projectDetail_cs.html', path_project, project=project, readme=readme_html, lang="cs")

def generate_about(self):
info = self.about_info

info["readme_1"] = conv_markdown("\n".join(info["readme_1"]))
info["readme_2"] = conv_markdown("\n".join(info["readme_2"]))
info["readme_1_cs"] = conv_markdown("\n".join(info["readme_1_cs"]))
info["readme_2_cs"] = conv_markdown("\n".join(info["readme_2_cs"]))

repos = [i[0] for i in sorted([[r, r.pushed_at] for r in self.repos], key=lambda x: x[1], reverse=True)[:6]]

self.render_page('about.html', self.paths.get("/").get("path"), info=info, repos=repos)
self.render_page('about.html', self.paths.get("About").get("path"), info=info, repos=repos)
self.render_page('about.html', self.paths.get("/").get("path"), info=info, repos=repos, lang="en")

self.render_page('about_cs.html', self.paths.get("/cs").get("path"), info=info, repos=repos, lang="cs")

def generate_team(self):
team = self.team

self.render_page('team.html', self.paths.get("Our team").get("path"), team=team)

self.render_page('team.html', self.paths.get("Our team").get("path"), team=team, lang="en")

self.render_page('team_cs.html', self.paths.get("Náš tým").get("path"), team=team, lang="cs")

def render_page(self, template_name: Union[str, "Template"], path_render: str, **kwargs):
template = self.env.get_template(template_name)
full_path = os.path.join(self.build_dir, path_render)

if not path.exists(path.dirname(full_path)):
makedirs(path.dirname(full_path))
try:
with open(full_path, 'w') as f:
if self.verbose:
logger.info(f"Generating {path}")
f.write(template.render(**kwargs))
f.write(template.render(**kwargs, now=datetime.now().year))
except Exception as e:
logger.error(f"Error while generating {path_render}")
logger.error(e)
raise e
raise e
17 changes: 9 additions & 8 deletions src/jinja_extensions/color_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ def __init__(self, environment):

def colorize_filter(self, value):
# list of color classes
colors = ["bg-blue-100 text-blue-800",
"bg-green-100 text-green-800",
"bg-yellow-100 text-yellow-800",
"bg-red-100 text-red-800",
"bg-purple-100 text-purple-800",
"bg-indigo-100 text-indigo-800",
"bg-pink-100 text-pink-800",
"bg-gray-100 text-gray-800"]
colors = ["bg-blue-100 dark:bg-blue-950 text-blue-800 dark:text-blue-300 ",
"bg-green-100 dark:bg-green-950 text-green-800 dark:text-green-300 ",
"bg-yellow-100 dark:bg-yellow-950 text-yellow-800 dark:text-yellow-300 ",
"bg-red-100 dark:bg-red-950 text-red-800 dark:text-red-300 ",
"bg-purple-100 dark:bg-purple-950 text-purple-800 dark:text-purple-300 ",
"bg-indigo-100 dark:bg-indigo-950 text-indigo-800 dark:text-indigo-300 ",
"bg-pink-100 dark:bg-pink-950 text-pink-800 dark:text-pink-300 ",
#"bg-zinc-100 dark:bg-zinc-950 text-zinc-800 ",
]

# choose a color based on the hash of the value
color_class = colors[hash(value) % len(colors)]
Expand Down
1 change: 0 additions & 1 deletion src/web_helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
from typing import IO
import markdown
import yaml

Expand Down
Loading