Initial release
This commit is contained in:
parent
4686803b27
commit
3bc189c592
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.swp
|
33
README.md
33
README.md
@ -1,3 +1,32 @@
|
||||
# gitea_external_renderers
|
||||
# External rendering scripts for Gitea
|
||||
|
||||
External rendering scripts for various file types
|
||||
These scripts attempt to render several documents so viewing them in Gitea is actually informative. Most are a work in progress. As some files can take a very long time to render, caching is used by leaving the generated images in the Gitea custom assets directory (if present and writable). You'd probably want to clean that out now and then.
|
||||
|
||||
List of renderers:
|
||||
- LibreOffice
|
||||
- KiCad
|
||||
|
||||
TODO:
|
||||
- 3D models (STL, STEP, etc)
|
||||
- Gerber files
|
||||
|
||||
## Prerequists
|
||||
|
||||
The KiCad renderers assume KiCad (9 or newer) is installed. They also need Inkscape (to properly fit the images). Libreoffice is required for the LO renderers.
|
||||
|
||||
The SVG Pan & Zoom library is loaded from a CDN.
|
||||
|
||||
`mktemp` is used to create a temporary directory.
|
||||
|
||||
## Installation & Configuration
|
||||
|
||||
1. Link the scripts in some place Gitea can execute them
|
||||
2. Add the content of the `.ini` files to your `app.ini` file
|
||||
3. Edit the new script path entries in `app.ini` to match your system
|
||||
4. Copy / merge the contents of the `custom` dir with the custom dir in your Gitea root
|
||||
|
||||
## Repo and License
|
||||
|
||||
Feel free to copy and share this under the terms of the Apache 2.0 license.
|
||||
Original author: Stefan Hamminga <stefan@rbts.co>
|
||||
Original repo: https://git.rbts.co/rbts.co/gitea_external_renderers
|
||||
|
25
config/kicad_pcb.ini
Normal file
25
config/kicad_pcb.ini
Normal file
@ -0,0 +1,25 @@
|
||||
[markup.kicad_pcb]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .kicad_pcb,.kicad_pcb.1,.kicad_pcb.2,.kicad_pcb.3,.kicad_pcb.4,.kicad_pcb.5,.kicad_pcb.6,.kicad_pcb.7,.kicad_pcb.8,.kicad_pcb.9
|
||||
RENDER_COMMAND = /usr/local/bin/gitea_render_kicad_pcb.sh
|
||||
IS_INPUT_FILE = true
|
||||
NEED_POSTPROCESS = false
|
||||
;RENDER_CONTENT_MODE = no-sanitizer
|
||||
|
||||
[markup.sanitizer.kicad_pcb.1]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = div
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
||||
|
||||
[markup.sanitizer.kicad_pcb.2]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = img
|
||||
ALLOW_ATTR = src
|
||||
REGEXP =
|
||||
|
||||
[markup.sanitizer.kicad_pcb.3]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = img
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
25
config/kicad_sch.ini
Normal file
25
config/kicad_sch.ini
Normal file
@ -0,0 +1,25 @@
|
||||
[markup.kicad_sch]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .kicad_sch,.kicad_sch.1,.kicad_sch.2,.kicad_sch.3,.kicad_sch.4,.kicad_sch.5,.kicad_sch.6,.kicad_sch.7,.kicad_sch.8,.kicad_sch.9
|
||||
RENDER_COMMAND = /usr/local/bin/gitea_render_kicad_sch.sh
|
||||
IS_INPUT_FILE = true
|
||||
NEED_POSTPROCESS = false
|
||||
;RENDER_CONTENT_MODE = no-sanitizer
|
||||
|
||||
[markup.sanitizer.kicad_sch.1]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = div
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
||||
|
||||
[markup.sanitizer.kicad_sch.2]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = img
|
||||
ALLOW_ATTR = src
|
||||
REGEXP =
|
||||
|
||||
[markup.sanitizer.kicad_sch.3]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = img
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
23
config/libreoffice.ini
Normal file
23
config/libreoffice.ini
Normal file
@ -0,0 +1,23 @@
|
||||
[markup.libreoffice]
|
||||
ENABLED = true
|
||||
FILE_EXTENSIONS = .odt,.ods,.odg,.docx,.ppt
|
||||
RENDER_COMMAND = /usr/local/bin/gitea_render_libreoffice.sh
|
||||
IS_INPUT_FILE = true
|
||||
NEED_POSTPROCESS = false
|
||||
|
||||
[markup.sanitizer.libreoffice.1]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = img
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
||||
|
||||
[markup.sanitizer.libreoffice.2]
|
||||
ALLOW_DATA_URI_IMAGES = true
|
||||
ELEMENT = src
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
||||
|
||||
[markup.sanitizer.libreoffice.3]
|
||||
ELEMENT = div
|
||||
ALLOW_ATTR = class
|
||||
REGEXP =
|
20
custom/public/assets/css/renderers.css
Normal file
20
custom/public/assets/css/renderers.css
Normal file
@ -0,0 +1,20 @@
|
||||
.file-view.markup .full_width {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.file-view.markup.kicad_sch,
|
||||
.file-view.markup.kicad_pcb,
|
||||
.file-view.markup.libreoffice
|
||||
{
|
||||
background-color: rgba(127, 127, 127, 0.05);
|
||||
}
|
||||
|
||||
.file-view.markup .page {
|
||||
background-color: white;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.file-view.markup .page + .page {
|
||||
margin-top: 1em;
|
||||
}
|
0
custom/public/assets/img/.gitkeep
Normal file
0
custom/public/assets/img/.gitkeep
Normal file
15
custom/templates/custom/footer.tmpl
Normal file
15
custom/templates/custom/footer.tmpl
Normal file
@ -0,0 +1,15 @@
|
||||
<script src="https://unpkg.com/@panzoom/panzoom@4.6.0/dist/panzoom.min.js"></script>
|
||||
<script>
|
||||
try {
|
||||
document.querySelectorAll('img.pan_zoom').forEach((img) => {
|
||||
const panzoom = Panzoom(img, {
|
||||
maxScale: 5
|
||||
});
|
||||
img.parentElement.addEventListener('wheel', evt => evt.preventDefault());
|
||||
img.parentElement.addEventListener('wheel', panzoom.zoomWithWheel)
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Error loading Panzoom:', e);
|
||||
}
|
||||
</script>
|
||||
|
1
custom/templates/custom/header.tmpl
Normal file
1
custom/templates/custom/header.tmpl
Normal file
@ -0,0 +1 @@
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/assets/css/renderers.css" />
|
67
scripts/kicad_pcb.sh
Normal file
67
scripts/kicad_pcb.sh
Normal file
@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
INPUT="$*"
|
||||
OUTDIR=$(mktemp -d)
|
||||
IMGDIR="$GITEA_WORK_DIR/custom/public/assets/img"
|
||||
|
||||
KIOPTS=(
|
||||
# --subtract-soldermask
|
||||
--mode-single
|
||||
--exclude-drawing-sheet
|
||||
--page-size-mode 2
|
||||
--sketch-pads-on-fab-layers
|
||||
)
|
||||
|
||||
ln -s "$INPUT" "$OUTDIR"/pcb.kicad_pcb
|
||||
|
||||
if [[ -d "$IMGDIR" && -w "$IMGDIR" ]]; then
|
||||
# We can use caching
|
||||
HASH=$(sha256sum "$INPUT" | cut -c1-64)
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
|
||||
if [ ${#IMAGES[@]} -le 0 ]; then
|
||||
kicad-cli pcb export svg "${KIOPTS[@]}" --layers Edge.Cuts,F.Cu,F.Mask,F.Silkscreen,F.Adhesive,F.Paste --output "${OUTDIR}/${HASH}.1.svg" "$OUTDIR"/pcb.kicad_pcb >/dev/null
|
||||
kicad-cli pcb export svg "${KIOPTS[@]}" --mirror --layers Edge.Cuts,B.Cu,B.Mask,B.Silkscreen,B.Adhesive,B.Paste --output "${OUTDIR}/${HASH}.2.svg" "$OUTDIR"/pcb.kicad_pcb >/dev/null
|
||||
|
||||
inkscape --actions="page-fit-to-selection" -o "${IMGDIR}/${HASH}.1.svg" "${OUTDIR}/${HASH}.1.svg"
|
||||
inkscape --actions="page-fit-to-selection" -o "${IMGDIR}/${HASH}.2.svg" "${OUTDIR}/${HASH}.2.svg"
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
fi
|
||||
|
||||
echo '<div class="file">'
|
||||
for IMG in "${IMAGES[@]}"; do
|
||||
echo '<div class="page">'
|
||||
# echo "bla"
|
||||
echo -n '<img src="/assets/img/'
|
||||
echo -n "$(basename "${IMG}")"
|
||||
echo -n '"'
|
||||
echo -n ' class="full_width kicad_pcb pan_zoom"'
|
||||
echo '/>'
|
||||
echo '</div>'
|
||||
done
|
||||
echo '</div></div>'
|
||||
|
||||
else
|
||||
echo "<p>Error: Unable to write to $IMGDIR. Please check permissions.</p>"
|
||||
# TODO: Implement base64 method
|
||||
# We'll be generating the images on the fly, including them as base64
|
||||
# mapfile -t FILES \
|
||||
# < <(kicad-cli sch export svg --exclude-drawing-sheet --no-background-color --output "$OUTDIR" "$OUTDIR/pcb.kicad_pcb" | grep -E 'Plotted to' | sed -r "s/^[^']+'|'[^']+$//g" )
|
||||
# for FILE in "${FILES[@]}"; do
|
||||
# echo -n '<div class="file"><div class="page">'
|
||||
# echo -n '<img src="data:image/svg+xml;base64,'
|
||||
# inkscape --actions="page-fit-to-selection" -o - "$FILE" | base64 --wrap=0
|
||||
# echo -n '"'
|
||||
# echo -n ' class="full_width kicad_pcb pan_zoom"'
|
||||
# echo -n '/>'
|
||||
# echo '</div></div>'
|
||||
# done
|
||||
fi
|
||||
|
||||
rm -R "$OUTDIR"
|
62
scripts/kicad_sch.sh
Normal file
62
scripts/kicad_sch.sh
Normal file
@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
INPUT="$*"
|
||||
OUTDIR=$(mktemp -d)
|
||||
IMGDIR="$GITEA_WORK_DIR/custom/public/assets/img"
|
||||
|
||||
ln -s "$INPUT" "$OUTDIR"/schematic.kicad_sch
|
||||
|
||||
if [[ -d "$IMGDIR" && -w "$IMGDIR" ]]; then
|
||||
# We can use caching
|
||||
HASH=$(sha256sum "$INPUT" | cut -c1-64)
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
|
||||
if [ ${#IMAGES[@]} -le 0 ]; then
|
||||
mapfile -t FILES \
|
||||
< <(kicad-cli sch export svg --exclude-drawing-sheet --no-background-color --output "$OUTDIR" "$OUTDIR/schematic.kicad_sch" | grep -E 'Plotted to' | sed -r "s/^[^']+'|'[^']+$//g" )
|
||||
|
||||
file_num=1
|
||||
for FILE in "${FILES[@]}"; do
|
||||
FN="${IMGDIR}/${HASH}.${file_num}.svg"
|
||||
inkscape --actions="page-fit-to-selection" -o "$FN" "$FILE"
|
||||
file_num=$((file_num + 1))
|
||||
break # TODO: find some way to handle related (hierarchical) schematic files, as currently only the active file is made available
|
||||
done
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
fi
|
||||
|
||||
for FILE in "${IMAGES[@]}"; do
|
||||
echo '<div class="file"><div class="page">'
|
||||
# echo "bla"
|
||||
echo -n '<img src="/assets/img/'
|
||||
echo -n "$(basename "${FILE}")"
|
||||
echo -n '"'
|
||||
echo -n ' class="full_width kicad_sch pan_zoom"'
|
||||
echo '/>'
|
||||
echo '</div></div>'
|
||||
done
|
||||
|
||||
else
|
||||
# We'll be generating the images on the fly, including them as base64
|
||||
mapfile -t FILES \
|
||||
< <(kicad-cli sch export svg --exclude-drawing-sheet --no-background-color --output "$OUTDIR" "$OUTDIR/schematic.kicad_sch" | grep -E 'Plotted to' | sed -r "s/^[^']+'|'[^']+$//g" )
|
||||
for FILE in "${FILES[@]}"; do
|
||||
echo -n '<div class="file"><div class="page">'
|
||||
echo -n '<img src="data:image/svg+xml;base64,'
|
||||
inkscape --actions="page-fit-to-selection" -o - "$FILE" | base64 --wrap=0
|
||||
echo -n '"'
|
||||
echo -n ' class="full_width kicad_sch pan_zoom"'
|
||||
echo -n '/>'
|
||||
echo '</div></div>'
|
||||
|
||||
break # TODO: find some way to handle related (hierarchical) schematic files, as currently only the active file is made available
|
||||
done
|
||||
fi
|
||||
|
||||
rm -R "$OUTDIR"
|
72
scripts/libreoffice.sh
Normal file
72
scripts/libreoffice.sh
Normal file
@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
INPUT="$*"
|
||||
OUTDIR=$(mktemp -d)
|
||||
IMGDIR="$GITEA_WORK_DIR/custom/public/assets/img"
|
||||
|
||||
if [[ -d "$IMGDIR" && -w "$IMGDIR" ]]; then
|
||||
# We can use caching
|
||||
HASH=$(sha256sum "$INPUT" | cut -c1-64)
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
|
||||
if [ ${#IMAGES[@]} -le 0 ]; then
|
||||
libreoffice --headless --convert-to pdf --outdir "$OUTDIR" $INPUT >/dev/null
|
||||
|
||||
PDF_FILE="$OUTDIR/$(basename "${INPUT%.*}".pdf)"
|
||||
|
||||
NUM_PAGES=$(pdfinfo "$PDF_FILE" | grep Pages | awk '{print $2}')
|
||||
|
||||
for (( i=1; i<=$NUM_PAGES; i++ )); do
|
||||
FN="${IMGDIR}/${HASH}.${i}.svg"
|
||||
pdftocairo -svg -f $i -l $i "$PDF_FILE" "${FN}"
|
||||
done
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
fi
|
||||
|
||||
echo '<div class="file">'
|
||||
for IMG in "${IMAGES[@]}"; do
|
||||
echo '<div class="page">'
|
||||
echo -n '<img src="/assets/img/'
|
||||
echo -n "$(basename "${IMG}")"
|
||||
echo -n '"'
|
||||
echo -n ' class="full_width libreoffice pan_zoom"'
|
||||
echo '/>'
|
||||
echo '</div>'
|
||||
done
|
||||
echo '</div>'
|
||||
|
||||
else
|
||||
# We'll be generating the images on the fly, including them as base64
|
||||
libreoffice --headless --convert-to pdf --outdir "$OUTDIR" $INPUT >/dev/null
|
||||
PDF_FILE="$OUTDIR/$(basename "${INPUT%.*}".pdf)"
|
||||
NUM_PAGES=$(pdfinfo "$PDF_FILE" | grep Pages | awk '{print $2}')
|
||||
|
||||
for (( i=1; i<=$NUM_PAGES; i++ )); do
|
||||
FN="${IMGDIR}/${HASH}.${i}.svg"
|
||||
pdftocairo -svg -f $i -l $i "$PDF_FILE" "${FN}"
|
||||
done
|
||||
|
||||
shopt -s nullglob
|
||||
IMAGES=("${IMGDIR}"/${HASH}.*.svg)
|
||||
shopt -u nullglob
|
||||
|
||||
echo '<div class="file">'
|
||||
for IMG in "${IMAGES[@]}"; do
|
||||
echo '<div class="page">'
|
||||
echo -n '<img src="/assets/img/'
|
||||
base64 --wrap=0 < "${IMG}"
|
||||
echo -n '"'
|
||||
echo -n ' class="full_width libreoffice pan_zoom"'
|
||||
echo '/>'
|
||||
echo '</div>'
|
||||
done
|
||||
echo '</div>'
|
||||
fi
|
||||
|
||||
rm -R "$OUTDIR"
|
Loading…
x
Reference in New Issue
Block a user