Compare commits

...

1 Commits

Author SHA1 Message Date
0be687b89b feat(hexojs): Add Build & Publish LuCI interface for Gitea workflow
- Add publish_to_www RPCD method to publish static files to /www/blog
- Add Build & Publish card in sync.js with configurable publish path
- Add generate RPC call for building site
- Fix file permissions for all RPCD scripts and init.d scripts
- Bump luci-app-hexojs to 1.0.0-r3

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:18:40 +01:00
30 changed files with 153 additions and 3 deletions

View File

View File

View File

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-hexojs
PKG_VERSION:=1.0.0
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_ARCH:=all
PKG_LICENSE:=MIT

View File

@ -154,6 +154,13 @@ var callDeployStatus = rpc.declare({
expect: {}
});
var callPublishToWww = rpc.declare({
object: 'luci.hexojs',
method: 'publish_to_www',
params: ['path'],
expect: {}
});
// ============================================
// Preview
// ============================================
@ -478,6 +485,7 @@ return baseclass.extend({
clean: callClean,
deploy: callDeploy,
getDeployStatus: callDeployStatus,
publishToWww: callPublishToWww,
// Preview
previewStart: callPreviewStart,

View File

@ -28,6 +28,19 @@ var callGiteaSaveConfig = rpc.declare({
params: ['enabled', 'gitea_url', 'gitea_user', 'gitea_token', 'content_repo', 'content_branch', 'auto_sync']
});
var callBuild = rpc.declare({
object: 'luci.hexojs',
method: 'generate',
expect: {}
});
var callPublishToWww = rpc.declare({
object: 'luci.hexojs',
method: 'publish_to_www',
params: ['path'],
expect: {}
});
return view.extend({
title: _('Content Sync'),
wizardStep: 0,
@ -210,6 +223,50 @@ return view.extend({
});
},
// ============================================
// Build & Publish Actions
// ============================================
handleBuild: function() {
ui.showModal(_('Building Site'), [
E('p', { 'class': 'spinning' }, _('Generating static files...'))
]);
callBuild().then(function(result) {
ui.hideModal();
if (result.success) {
ui.addNotification(null, E('p', _('Site built successfully!')), 'info');
} else {
ui.addNotification(null, E('p', result.error || _('Build failed')), 'error');
}
}).catch(function(err) {
ui.hideModal();
ui.addNotification(null, E('p', _('Error: %s').format(err.message || err)), 'error');
});
},
handlePublish: function() {
var self = this;
var path = document.querySelector('#publish-path');
var publishPath = path ? path.value : '/www/blog';
ui.showModal(_('Publishing Site'), [
E('p', { 'class': 'spinning' }, _('Building and publishing to %s...').format(publishPath))
]);
callPublishToWww(publishPath).then(function(result) {
ui.hideModal();
if (result.success) {
ui.addNotification(null, E('p', _('Published to %s!').format(result.path || publishPath)), 'info');
} else {
ui.addNotification(null, E('p', result.error || _('Publish failed')), 'error');
}
}).catch(function(err) {
ui.hideModal();
ui.addNotification(null, E('p', _('Error: %s').format(err.message || err)), 'error');
});
},
// ============================================
// Gitea Actions
// ============================================
@ -297,6 +354,49 @@ return view.extend({
]) : ''
]),
// Build & Publish Card
E('div', { 'class': 'hexo-card' }, [
E('div', { 'class': 'hexo-card-header' }, [
E('div', { 'class': 'hexo-card-title' }, [
E('span', { 'style': 'margin-right: 8px;' }, '\uD83D\uDE80'),
_('Build & Publish')
])
]),
E('p', { 'style': 'margin-bottom: 16px; color: var(--hexo-text-muted);' },
_('Build static files and publish to web server.')),
E('div', { 'style': 'display: grid; grid-template-columns: 1fr 1fr; gap: 16px;' }, [
// Build Section
E('div', { 'class': 'hexo-card', 'style': 'background: var(--hexo-bg-input);' }, [
E('h4', { 'style': 'margin-bottom: 8px;' }, ['\uD83D\uDD28 ', _('Build')]),
E('p', { 'style': 'font-size: 13px; color: var(--hexo-text-muted); margin-bottom: 12px;' },
_('Generate static HTML files from your content.')),
E('button', {
'class': 'hexo-btn hexo-btn-primary',
'click': function() { self.handleBuild(); }
}, _('Build Site'))
]),
// Publish Section
E('div', { 'class': 'hexo-card', 'style': 'background: var(--hexo-bg-input);' }, [
E('h4', { 'style': 'margin-bottom: 8px;' }, ['\uD83C\uDF10 ', _('Publish')]),
E('p', { 'style': 'font-size: 13px; color: var(--hexo-text-muted); margin-bottom: 12px;' },
_('Copy built files to web server directory.')),
E('div', { 'class': 'hexo-form-group', 'style': 'margin-bottom: 8px;' }, [
E('input', {
'type': 'text',
'id': 'publish-path',
'class': 'hexo-input',
'value': '/www/blog',
'placeholder': '/www/blog'
})
]),
E('button', {
'class': 'hexo-btn hexo-btn-success',
'click': function() { self.handlePublish(); }
}, _('Publish to Web'))
])
])
]),
// Gitea Integration Card
E('div', { 'class': 'hexo-card' }, [
E('div', { 'class': 'hexo-card-header' }, [

View File

@ -1544,6 +1544,45 @@ gitea_save_config() {
json_dump
}
# Publish to /www (portal)
publish_to_www() {
read input
json_load "$input"
json_get_var path path
json_init
if ! is_running; then
json_add_boolean "success" 0
json_add_string "error" "Container not running"
json_dump
return
fi
# Default path is /www/blog
[ -z "$path" ] && path="/www/blog"
# Set portal path in UCI for hexoctl
uci set hexojs.portal=hexojs
uci set hexojs.portal.path="$path"
uci commit hexojs
# Run publish command
local output=$("$HEXOCTL" publish 2>&1)
local result=$?
if [ "$result" -eq 0 ]; then
json_add_boolean "success" 1
json_add_string "message" "Published to $path"
json_add_string "path" "$path"
else
json_add_boolean "success" 0
json_add_string "error" "$output"
fi
json_dump
}
# ============================================
# Service Control
# ============================================
@ -1634,7 +1673,8 @@ case "$1" in
"gitea_setup": {},
"gitea_clone": {},
"gitea_sync": {},
"gitea_save_config": {"enabled": "bool", "gitea_url": "str", "gitea_user": "str", "gitea_token": "str", "content_repo": "str", "content_branch": "str", "auto_sync": "bool"}
"gitea_save_config": {"enabled": "bool", "gitea_url": "str", "gitea_user": "str", "gitea_token": "str", "content_repo": "str", "content_branch": "str", "auto_sync": "bool"},
"publish_to_www": {"path": "str"}
}
EOF
;;
@ -1686,6 +1726,7 @@ EOF
gitea_clone) gitea_clone ;;
gitea_sync) gitea_sync ;;
gitea_save_config) gitea_save_config ;;
publish_to_www) publish_to_www ;;
*) echo '{"error": "Unknown method"}' ;;
esac
;;

View File

@ -56,7 +56,8 @@
"gitea_setup",
"gitea_clone",
"gitea_sync",
"gitea_save_config"
"gitea_save_config",
"publish_to_www"
]
},
"uci": ["hexojs"]

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

0
package/secubox/secubox-app-mmpm/files/etc/init.d/mmpm Normal file → Executable file
View File

View File

View File

View File

View File