aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cgit/cgitrc32
-rwxr-xr-xcgit/filters/about.sh5
-rwxr-xr-xcgit/filters/html-transform.py83
-rw-r--r--cgit/nginx.conf35
-rw-r--r--cgit/static/cgit.css54
-rw-r--r--docker-compose.yml89
6 files changed, 237 insertions, 61 deletions
diff --git a/cgit/cgitrc b/cgit/cgitrc
index bed622c..935192c 100644
--- a/cgit/cgitrc
+++ b/cgit/cgitrc
@@ -5,10 +5,24 @@ root-readme=/usr/share/webapps/cgit/ediblemonad/README.md
# Theme
css=/ediblemonad/cgit.css
logo=/ediblemonad/logo.png
-head-include=/usr/share/webapps/cgit/ediblemonad/head.html
+favicon=/favicon.ico
+head-include=/usr/share/webapps/cgit/ediblemonad/header.html
+# footer= TODO: override footer
+
+# TODO: submodule links
+# module-link=/cgit/submodule/%s/commit?id=%s
source-filter=/usr/lib/cgit/filters/syntax-highlighting.py
-about-filter=/usr/lib/cgit/filters/about-formatting.sh
+about-filter=/usr/lib/cgit/filters/ediblemonad/about.sh
+
+# Mimetypes for plain files
+mimetype.gif=image/gif
+mimetype.html=text/html
+mimetype.jpg=image/jpeg
+mimetype.jpeg=image/jpeg
+mimetype.pdf=application/pdf
+mimetype.png=image/png
+mimetype.svg=image/svg+xml
# Search for these files in the root of the default branch of repositories
# for coming up with the about page:
@@ -43,17 +57,25 @@ readme=:install
# Cache
cache-root=/var/cache/cgit
-cache-size=2000
+cache-size=0
-enable-index-links=1
+enable-index-links=0
enable-index-owner=0
enable-remote-branches=1
enable-log-filecount=1
enable-log-linecount=1
+enable-tree-linenumbers=1
enable-git-config=1
+enable-commit-graph=1
+enable-follow-links=1
+enable-http-clone=1
+enable-html-serving=1
snapshots=tar.xz zip
+remove-suffix=1
+repository-sort=age
+# side-by-side-diffs=1
-robots=noindex, nofollow
+robots=index, nofollow
virtual-root=/
section-from-path=0
max-repo-count=50
diff --git a/cgit/filters/about.sh b/cgit/filters/about.sh
new file mode 100755
index 0000000..e8554b0
--- /dev/null
+++ b/cgit/filters/about.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env sh
+# About content filter
+
+/usr/lib/cgit/filters/about-formatting.sh "$@" | /usr/lib/cgit/filters/ediblemonad/html-transform.py
+
diff --git a/cgit/filters/html-transform.py b/cgit/filters/html-transform.py
new file mode 100755
index 0000000..9fc7aec
--- /dev/null
+++ b/cgit/filters/html-transform.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+# Rewrite image urls in about section
+
+import sys
+from html.parser import HTMLParser
+import html
+from urllib.parse import urljoin, urlparse
+import re
+
+def is_absolute_url(url):
+ if not url: return False
+ parsed = urlparse(url)
+ return bool(parsed.netloc or parsed.scheme)
+
+def is_relative_path(url):
+ if not url: return False
+ return not url.startswith("/") and not is_absolute_url(url)
+
+def linkify(text, make_link):
+ url_pattern = r'(?<!\S)(https?://\S+?)([.,!?;:]?(?=\s|$))'
+ def replace(m):
+ url, trail = m.group(1), m.group(2)
+ return make_link(url) + trail
+ return re.sub(url_pattern, replace, text)
+
+class LinkRewriter(HTMLParser):
+ def __init__(self):
+ super().__init__(convert_charrefs=False)
+ self.output = []
+
+ def get_html(self):
+ return "".join(self.output)
+
+ def _build_tag(self, tag, attrs, self_closing = False):
+ new_tag = tag
+ attr_map = {}
+ for name, value in attrs:
+ if name in ("href", "src") and is_relative_path(value) and not value.startswith('#'):
+ if tag == 'a':
+ value = "../" + urljoin("tree/", value)
+ else:
+ value = "../" + urljoin("plain/", value)
+ attr_map[name] = value
+ # Open in new tab
+ if tag == "a" and name == "href" and is_absolute_url(value):
+ if not 'target' in attr_map: attr_map['target'] = '_blank _parent'
+ if not 'rel' in attr_map: attr_map['rel'] = 'noopener'
+
+ attr_str = "".join(
+ f' {name}="{html.escape(value, quote=True)}"' if value is not None else f" {name}"
+ for name, value in attr_map.items()
+ )
+ return f"<{new_tag}{attr_str}{' /' if self_closing else ''}>"
+
+ def handle_starttag(self, tag, attrs):
+ self.output.append(self._build_tag(tag, attrs))
+
+ def handle_startendtag(self, tag, attrs):
+ self.output.append(self._build_tag(tag, attrs, self_closing=True))
+
+ def handle_endtag(self, tag):
+ self.output.append(f"</{tag}>")
+
+ def handle_data(self, data):
+ data_with_links = linkify(data,
+ lambda url: self._build_tag("a", [('href', url)]) + html.escape(url) + "</a>")
+ self.output.append(data_with_links)
+
+ def handle_entityref(self, name):
+ self.output.append(f"&{name};")
+
+ def handle_charref(self, name):
+ self.output.append(f"&#{name};")
+
+ def handle_comment(self, data):
+ self.output.append(f"<!--{data}-->")
+
+html_in = sys.stdin.read()
+
+parser = LinkRewriter()
+parser.feed(html_in)
+
+print(parser.get_html())
diff --git a/cgit/nginx.conf b/cgit/nginx.conf
new file mode 100644
index 0000000..a850744
--- /dev/null
+++ b/cgit/nginx.conf
@@ -0,0 +1,35 @@
+server {
+ listen 80;
+ server_name localhost;
+ root /usr/share/webapps/cgit;
+
+ location / {
+ try_files $uri @cgit;
+ }
+
+ location ~* ^.+(favicon.ico|robots.txt) {
+ root /usr/share/webapps/cgit;
+ expires 30d;
+ }
+
+ location @cgit {
+ include /etc/nginx/fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi;
+ fastcgi_param PATH_INFO $uri;
+ fastcgi_param QUERY_STRING $args;
+ fastcgi_param HTTP_HOST $server_name;
+ fastcgi_pass unix:/var/run/fcgiwrap.sock;
+ }
+
+ error_page 404 /404.html;
+ error_page 401 /401.html;
+
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+
+ location ~ /\.ht {
+ deny all;
+ }
+}
diff --git a/cgit/static/cgit.css b/cgit/static/cgit.css
index a57fa9a..8da6a9e 100644
--- a/cgit/static/cgit.css
+++ b/cgit/static/cgit.css
@@ -9,9 +9,12 @@ html, body {
input[type=search], input[type=text], select {
background-color: #111;
- color: var(--color-accent);
+ color: #eee;
border: 1px solid #333;
}
+select {
+ color: var(--color-accent);
+}
div#cgit button, div#cgit input[type=submit] {
background-color: #111;
@@ -978,6 +981,15 @@ div#cgit table.ssdiff td.space div {
#cgit a.toclink {
color: white !important;
}
+#cgit .markdown-body h1,
+#cgit .markdown-body h2,
+#cgit .markdown-body h3,
+#cgit .markdown-body h4,
+#cgit .markdown-body h5,
+#cgit .markdown-body h6 {
+ /*border-bottom: 1px solid #222;*/
+ border: none;
+}
#cgit .markdown-body pre {
background: #111;
border: 1px solid #222;
@@ -989,20 +1001,40 @@ div#cgit table.ssdiff td.space div {
background: #222;
border: none;
}
+#cgit .markdown-body table tr,
+#cgit .markdown-body table th,
+#cgit .markdown-body table td {
+ background: transparent;
+ border: 1px solid #333;
+}
+#cgit .markdown-body table img {
+ display: block;
+ margin: 0 auto;
+}
-#cgit .markdown-body pre code > span {
+#cgit .highlight pre span {
background: transparent !important;
}
+#cgit .markdown-body hr {
+ background: none;
+ border-top: 1px solid #222;
+ height: 1rem;
+ margin: 1rem 1rem 0;
+}
/* BuiltIn */
-#cgit .highlight span.cp {
+#cgit .highlight span[class^=c] {
color: #006060;
font-weight: bold;
}
-#cgit .highlight span.k, #cgit .highlight span.kr {
+#cgit .highlight span[class^=k] {
color: #006060;
font-weight: bold;
}
+#cgit .highlight span[class^=b] {
+ color: #bbeeee;
+ font-weight: bold;
+}
/* Err */
#cgit .highlight span.err {
@@ -1010,23 +1042,15 @@ div#cgit table.ssdiff td.space div {
}
/* Variables */
-#cgit .highlight span.n {
- color: #eee;
-}
-
-/* Func */
-#cgit .highlight span.nb {
- color: #eee;
-}
-#cgit .highlight span.nf {
+#cgit .highlight span[class^=n] {
color: #eee;
}
/* Literal */
-#cgit .highlight span.mi, #cgit .highlight span.mf { /* Num */
+#cgit .highlight span[class^=m] { /* Num */
color: #607020;
}
-#cgit .highlight span.s { /* Str */
+#cgit .highlight span[class^=s] { /* Str */
color: #71d2ae;
background-color: transparent;
}
diff --git a/docker-compose.yml b/docker-compose.yml
index 0216d9d..f8316af 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,37 +1,4 @@
services:
- nginx-proxy:
- profiles: [core]
- container_name: nginx-proxy
- image: 'jwilder/nginx-proxy:alpine'
- restart: always
- ports:
- - '80:80'
- - '443:443'
- environment:
- - DEFAULT_HOST=ediblemonad.dev
- - HSTS=off
- volumes:
- - /var/run/docker.sock:/tmp/docker.sock:ro
- - proxy-certs:/etc/nginx/certs:ro
- - proxy-vhost:/etc/nginx/vhost.d
- - proxy-html:/usr/share/nginx/html
-
- proxy-letsencrypt:
- profiles: [core]
- image: 'nginxproxy/acme-companion'
- restart: always
- environment:
- - DEFAULT_EMAIL=ediblemonad@gmail.com
- - NGINX_PROXY_CONTAINER=nginx-proxy
- - NGINX_DOCKER_GEN_CONTAINER=nginx-proxy
- - ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock:ro
- - proxy-certs:/etc/nginx/certs
- - proxy-vhost:/etc/nginx/vhost.d
- - proxy-html:/usr/share/nginx/html
- - acme:/etc/acme.sh
-
send:
profiles: [services]
image: 'registry.gitlab.com/timvisee/send:v3.4.27'
@@ -39,7 +6,7 @@ services:
ports:
- '1234:1234'
volumes:
- - ./uploads:/uploads
+ - /uploads:/uploads
environment:
- VIRTUAL_PORT=1234
- VIRTUAL_HOST=send.ediblemonad.dev
@@ -60,27 +27,67 @@ services:
depends_on:
- redis
- redis:
- profiles: [services]
- image: 'redis:alpine'
- restart: always
- volumes:
- - redis:/data
-
cgit:
profiles: [services]
image: 'joseluisq/alpine-cgit:2.9'
+ restart: always
ports:
- 8080:80
environment:
+ - VIRTUAL_PORT=80
+ - VIRTUAL_HOST=git.ediblemonad.dev
+ - LETSENCRYPT_HOST=git.ediblemonad.dev
+ - DHPARAM_GENERATION=false
- USE_CUSTOM_CONFIG=true
volumes:
- cgit-cache:/var/cache/cgit
- /home/imsohexy/dev/projects:/srv/git:ro
- ./cgit/cgitrc:/etc/cgitrc:ro
- ./cgit/static:/usr/share/webapps/cgit/ediblemonad:ro
+ - ./cgit/nginx.conf:/etc/nginx/conf.d/default.conf:ro
+ - ./cgit/filters:/usr/lib/cgit/filters/ediblemonad:ro
- ./favicon.ico:/usr/share/webapps/cgit/favicon.ico:ro
+ nginx-proxy:
+ profiles: [core]
+ container_name: nginx-proxy
+ image: 'jwilder/nginx-proxy:alpine'
+ restart: always
+ ports:
+ - '80:80'
+ - '443:443'
+ environment:
+ - DEFAULT_HOST=ediblemonad.dev
+ - HSTS=off
+ volumes:
+ - /var/run/docker.sock:/tmp/docker.sock:ro
+ - proxy-certs:/etc/nginx/certs:ro
+ - proxy-vhost:/etc/nginx/vhost.d
+ - proxy-html:/usr/share/nginx/html
+
+ proxy-letsencrypt:
+ profiles: [core]
+ image: 'nginxproxy/acme-companion'
+ restart: always
+ environment:
+ - DEFAULT_EMAIL=ediblemonad@gmail.com
+ - NGINX_PROXY_CONTAINER=nginx-proxy
+ - NGINX_DOCKER_GEN_CONTAINER=nginx-proxy
+ - ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - proxy-certs:/etc/nginx/certs
+ - proxy-vhost:/etc/nginx/vhost.d
+ - proxy-html:/usr/share/nginx/html
+ - acme:/etc/acme.sh
+
+ redis:
+ profiles: [services]
+ image: 'redis:alpine'
+ restart: always
+ volumes:
+ - redis:/data
+
volumes:
redis:
cgit-cache: