1
0
Fork 0
mirror of https://github.com/sbrl/Pepperminty-Wiki.git synced 2024-11-25 05:22:59 +00:00

Work on automatic theme index & preview generation

This commit is contained in:
Starbeamrainbowlabs 2019-08-25 21:38:28 +01:00
parent 1bd91ad7e0
commit 45befb5ff1
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
5 changed files with 77 additions and 19 deletions

View file

@ -58,7 +58,11 @@ task_setup() {
check_command jq true optional; check_command jq true optional;
[[ "$?" -eq 0 ]] || echo -e "${FYEL}${HC}Warning: jq is required to update the theme index.${RS}"; [[ "$?" -eq 0 ]] || echo -e "${FYEL}${HC}Warning: jq is required to update the theme index.${RS}";
check_command firefox true optional; check_command firefox true optional;
[[ "$?" -eq 0 ]] || echo -e "${FYEL}${HC}Warning: firefox is required to generate the theme previews.${RS}"; [[ "$?" -eq 0 ]] || echo -e "${FYEL}${HC}Warning: firefox is required to generate theme previews.${RS}";
check_command convert true optional;
[[ "$?" -eq 0 ]] || echo -e "${FYEL}${HC}Warning: The convert imagemagick command is required to generate theme previews.${RS}";
check_command nproc true optional;
[[ "$?" -eq 0 ]] || echo -e "${FYEL}${HC}Warning: nproc is required to generate theme previews.${RS}";
task_end $?; task_end $?;
@ -90,17 +94,28 @@ task_build() {
task_themes() { task_themes() {
if [[ ! -f "${server_pid_file}" ]]; then if [[ ! -f "${server_pid_file}" ]]; then
tasks_run start-server; # TODO: Change this to call PHP directly, so we don't open the browser? Or maybe add an environment variable to start-server. NO_BROWSER=true tasks_run start-server;
fi fi
task_begin "Updating theme index"; stage_begin "Updating theme index";
cp "themes/themeindex.json" "themes/themeindex.json.old";
# Temporary firefox profile
task_begin "Preparing";
[ -f "themes/themeindex.json" ] && cp "themes/themeindex.json" "themes/themeindex.json.old";
# Temporary firefox profile directory
tmp_profile="$(mktemp -d /tmp/peppermint-firefox-profile-XXXXXXX)"; tmp_profile="$(mktemp -d /tmp/peppermint-firefox-profile-XXXXXXX)";
while read filename; do # Temporary file for theme index items
subtask_begin "Processing ${filename}"; tmp_themeindex_parts="$(mktemp /tmp/peppermint-themeindex-items-XXXXXXX)";
task_end $?;
preview_regen=false;
while read -r filename; do
task_begin "Processing ${filename}";
hash="$(sha256sum "${filename}" | cut -d' ' -f1)"; hash="$(sha256sum "${filename}" | cut -d' ' -f1)";
read -r -d "" awk_script <<'AWK' read -r -d "" awk_script <<'AWK'
@ -125,27 +140,58 @@ END {
} }
AWK AWK
# TODO: Consider mapping it out as TSV, then using JQ to generate the object # TODO: Consider mapping it out as TSV, then using JQ to generate the object
awk -v prop_hash="${hash}" "${awk_script}" <"${filename}"; subtask_begin "Generating index entry";
awk -v prop_hash="${hash}" "${awk_script}" <"${filename}" >>"${tmp_themeindex_parts}";
subtask_end "$?";
# Capture the screenshot # Capture the screenshot
if [ -f "themes/themeindex.json.old" ]; then
theme_id="$(awk '/@id/ { print $3 }' <"${filename}")";
old_hash="$(jq --raw-output --arg theme_id "${theme_id}" '.[] | select(.id == $theme_id).hash' <"themes/themeindex.json")";
# If the hash is the same as last time, don't bother to retake the screenshot
if [[ "${hash}" = "${hash_old}" ]]; then
continue;
fi
fi
preview_regen=true;
screenshot_loc_full="$(dirname "${filename}")/preview_full.png"; screenshot_loc_full="$(dirname "${filename}")/preview_full.png";
screenshot_loc_small="$(dirname "${filename}")/preview_small.png"; screenshot_loc_small="$(dirname "${filename}")/preview_small.png";
# Set the theme # Set the theme
cp "build/peppermint.json" "build/peppermint.json.bak";
tmp_file="$(mktemp /tmp/peppermint-json-XXXXXXX)"; tmp_file="$(mktemp /tmp/peppermint-json-XXXXXXX)";
jq --arg theme_css "$(cat "${filename}")" '.css = $theme_css' <"build/peppermint.json" >"${tmp_file}"; jq --arg theme_css "$(cat "${filename}")" '.css = $theme_css' <"build/peppermint.json" >"${tmp_file}";
mv "${tmp_file}" "build/peppermint.json"; mv "${tmp_file}" "build/peppermint.json";
# Capture the full-res screenshot # Capture the full-res screenshot
firefox --new-instance --headless --profile "${tmp_profile}" --window-size 1920x1080 --screenshot "${screenshot_loc_full}" "http://[::1]:35623/index.php"; execute firefox --new-instance --headless --profile "${tmp_profile}" --window-size 1920,1080 --screenshot "${screenshot_loc_full}" "http://[::1]:35623/index.php";
subtask_end "$?"; # Resize to get the smaller preview
done < <(find themes -type f -name "theme.css") | jq --tab --slurp . >themes/themeindex.json; execute convert "${screenshot_loc_full}" -resize 512x512 "${screenshot_loc_small}";
mv "build/peppermint.json.bak" "build/peppermint.json";
rm -r "${tmp_profile}"; task_end "$?";
rm "themes/themeindex.json.old"; done < <(find themes -type f -name "theme.css");
task_begin "Optimising new previews";
find "themes/" -iname "*.png" -print0 | xargs -0 -P"$(nproc)" -n1 optipng -preserve;
task_end "$?";
task_begin "Generating theme index";
jq --tab --slurp . <"${tmp_themeindex_parts}" >"themes/themeindex.json"
task_end "$?";
# Clean up
task_begin "Cleaning up";
[[ -d "${tmp_profile}" ]] && rm -r "${tmp_profile}";
[[ -f "themes/themeindex.json.old" ]] && rm "themes/themeindex.json.old";
task_end 0;
stage_end 0;
} }
task_docs() { task_docs() {
@ -198,9 +244,11 @@ task_start-server() {
echo "${pid}" >"${server_pid_file}"; echo "${pid}" >"${server_pid_file}";
task_end "${exit_code}" ""; task_end "${exit_code}" "";
if [[ -z "${NO_BROWSER}" ]]; then
task_begin "Opening Browser"; task_begin "Opening Browser";
sensible-browser [::]:35623; sensible-browser [::]:35623;
task_end $?; task_end $?;
fi
} }
task_stop-server() { task_stop-server() {

View file

@ -292,7 +292,7 @@ class page_renderer
*/ */
public static function is_css_url() { public static function is_css_url() {
global $settings; global $settings;
return preg_match("/^[^\/]*\/\/|^\//", $settings->css); return preg_match("/^[^\/]*\/\/|^\/[^\*]/", $settings->css);
} }
/** /**
* Renders all the CSS as HTML. * Renders all the CSS as HTML.

@ -1 +1 @@
Subproject commit 7365f7d156a049d6f13987bbe55ff917e2a05254 Subproject commit 5cf2cfebf0ee66db9167eadaa8e1956bba58a730

View file

@ -149,6 +149,16 @@
"optional": false, "optional": false,
"extra_data": [] "extra_data": []
}, },
{
"id": "feature-theme-gallery",
"name": "Theme Gallery",
"version": "0.1",
"author": "Starbeamrainbowlabs",
"description": "Adds a theme gallery page and optional automatic theme updates.",
"lastupdate": 1566733743,
"optional": false,
"extra_data": []
},
{ {
"id": "feature-upload", "id": "feature-upload",
"name": "Uploader", "name": "Uploader",

View file

@ -180,7 +180,7 @@
"disable_peppermint_access_check": { "type": "checkbox", "description": "Disables the access check for peppermint.json on first-run. <strong>VERY DANGEROUS</strong>. Use only for development. Note that it's recommend to block access to peppermint.json for a reason - it contains your site secret and password hashes, so an attacker could do all <em>sorts</em> of nefarious things if it's left unblocked.", "default": false }, "disable_peppermint_access_check": { "type": "checkbox", "description": "Disables the access check for peppermint.json on first-run. <strong>VERY DANGEROUS</strong>. Use only for development. Note that it's recommend to block access to peppermint.json for a reason - it contains your site secret and password hashes, so an attacker could do all <em>sorts</em> of nefarious things if it's left unblocked.", "default": false },
"css_theme_autoupdate_url": { "type": "url", "description": "A url that points to the css theme file to check for updates. If blank, then automatic updates are disabled.", "default": "" }, "css_theme_autoupdate_url": { "type": "url", "description": "A url that points to the css theme file to check for updates. If blank, then automatic updates are disabled.", "default": "" },
"css_theme_autoupdate_interval": { "type": "number", "description": "The interval, in seconds, that updates to the theme should be checked for. Defaults to every week. A value of -1 disables automatic updates.", "default": 604800 }, "css_theme_autoupdate_interval": { "type": "number", "description": "The interval, in seconds, that updates to the theme should be checked for. Defaults to every week. A value of -1 disables automatic updates.", "default": 604800 },
"css_theme_gallery_index_url": { "type": "text", "description": "A url that points to an index file that contains a list of themes. Used to populate the gallary. Multiple urls are allowed - separate them with a space." }, "css_theme_gallery_index_url": { "type": "text", "description": "A url that points to an index file that contains a list of themes. Used to populate the gallary. Multiple urls are allowed - separate them with a space.", "default": "https://starbeamrainbowlabs.com/labs/peppermint/themes/themeindex.php" },
"css_theme_gallery_selected_id": { "type": "text", "description": "The id of the currently selected theme. Defaults to the internal default theme.", "default": "default" }, "css_theme_gallery_selected_id": { "type": "text", "description": "The id of the currently selected theme. Defaults to the internal default theme.", "default": "default" },
"css": { "type": "textarea", "description": "A string of css to include. Will be included in the &lt;head&gt; of every page inside a &lt;style&gt; tag. This may also be an absolute url - urls will be referenced via a &lt;link rel='stylesheet' /&gt; tag. If the theme gallery is installed and automatic updates enabled, then the value of this property is managed by the theme gallery and changes may be overwritten (try the css_custom setting instead).", "default": "auto" }, "css": { "type": "textarea", "description": "A string of css to include. Will be included in the &lt;head&gt; of every page inside a &lt;style&gt; tag. This may also be an absolute url - urls will be referenced via a &lt;link rel='stylesheet' /&gt; tag. If the theme gallery is installed and automatic updates enabled, then the value of this property is managed by the theme gallery and changes may be overwritten (try the css_custom setting instead).", "default": "auto" },
"css_custom": { "type": "textarea", "description": "A string of custom CSS to include on top of the base theme css. Allows for theme customisations while still enabling automatic updates :D Just like the css setting, this one can also be a url.", "default": "/* Enter your custom css here. */" } "css_custom": { "type": "textarea", "description": "A string of custom CSS to include on top of the base theme css. Allows for theme customisations while still enabling automatic updates :D Just like the css setting, this one can also be a url.", "default": "/* Enter your custom css here. */" }