fix: some bugs
This commit is contained in:
+3
-3
@@ -4,8 +4,8 @@ GIT_BRANCH=main
|
|||||||
GIT_REPO_URL=https://github.com/your-org/your-repo.git
|
GIT_REPO_URL=https://github.com/your-org/your-repo.git
|
||||||
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
|
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
|
||||||
|
|
||||||
# Nextcloud Drive (WebDAV)
|
# Nextcloud Drive (public share WebDAV)
|
||||||
NEXTCLOUD_URL=https://cloud.example.com
|
NEXTCLOUD_URL=https://cloud.example.com
|
||||||
NEXTCLOUD_USER=your-nextcloud-username
|
NEXTCLOUD_SHARE_TOKEN=your-public-share-token
|
||||||
NEXTCLOUD_PASSWORD=your-nextcloud-password
|
NEXTCLOUD_SHARE_PASSWORD=
|
||||||
NEXTCLOUD_BASE_PATH=Models
|
NEXTCLOUD_BASE_PATH=Models
|
||||||
@@ -36,10 +36,10 @@ GIT_BRANCH=main
|
|||||||
GIT_REPO_URL=https://github.com/your-org/your-repo.git
|
GIT_REPO_URL=https://github.com/your-org/your-repo.git
|
||||||
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
|
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
|
||||||
|
|
||||||
# Nextcloud Drive (WebDAV)
|
# Nextcloud Drive (public share WebDAV)
|
||||||
NEXTCLOUD_URL=https://cloud.example.com
|
NEXTCLOUD_URL=https://cloud.example.com
|
||||||
NEXTCLOUD_USER=your-nextcloud-username
|
NEXTCLOUD_SHARE_TOKEN=your-public-share-token
|
||||||
NEXTCLOUD_PASSWORD=your-nextcloud-password
|
NEXTCLOUD_SHARE_PASSWORD=
|
||||||
NEXTCLOUD_BASE_PATH=Models
|
NEXTCLOUD_BASE_PATH=Models
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -51,8 +51,8 @@ NEXTCLOUD_BASE_PATH=Models
|
|||||||
| `GIT_REPO_URL` | Target GitHub repository URL | Yes |
|
| `GIT_REPO_URL` | Target GitHub repository URL | Yes |
|
||||||
| `BLENDER_PATH` | Path to Blender binary (default: `blender`) | No |
|
| `BLENDER_PATH` | Path to Blender binary (default: `blender`) | No |
|
||||||
| `NEXTCLOUD_URL` | Nextcloud instance URL | Yes |
|
| `NEXTCLOUD_URL` | Nextcloud instance URL | Yes |
|
||||||
| `NEXTCLOUD_USER` | Nextcloud username (Basic auth) | Yes |
|
| `NEXTCLOUD_SHARE_TOKEN` | Public share token (the part after `/s/` in the share link) | Yes |
|
||||||
| `NEXTCLOUD_PASSWORD` | Nextcloud password (Basic auth) | Yes |
|
| `NEXTCLOUD_SHARE_PASSWORD` | Public share password (empty if none) | No |
|
||||||
| `NEXTCLOUD_BASE_PATH` | Root folder on the Drive (default: `Models`) | No |
|
| `NEXTCLOUD_BASE_PATH` | Root folder on the Drive (default: `Models`) | No |
|
||||||
|
|
||||||
> To create a GitHub token: GitHub > Settings > Developer settings > Fine-grained personal access tokens > select the target repo > Permissions > Contents: Read and write.
|
> To create a GitHub token: GitHub > Settings > Developer settings > Fine-grained personal access tokens > select the target repo > Permissions > Contents: Read and write.
|
||||||
@@ -78,8 +78,7 @@ docker run -p 3000:3000 \
|
|||||||
-e GITHUB_TOKEN=ghp_xxx \
|
-e GITHUB_TOKEN=ghp_xxx \
|
||||||
-e GIT_REPO_URL=https://github.com/org/repo.git \
|
-e GIT_REPO_URL=https://github.com/org/repo.git \
|
||||||
-e NEXTCLOUD_URL=https://cloud.example.com \
|
-e NEXTCLOUD_URL=https://cloud.example.com \
|
||||||
-e NEXTCLOUD_USER=user \
|
-e NEXTCLOUD_SHARE_TOKEN=your-share-token \
|
||||||
-e NEXTCLOUD_PASSWORD=pass \
|
|
||||||
upload-gltf
|
upload-gltf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ export async function POST(req: NextRequest) {
|
|||||||
if (authError) return authError
|
if (authError) return authError
|
||||||
|
|
||||||
// --- Check Nextcloud config ---
|
// --- Check Nextcloud config ---
|
||||||
if (!process.env.NEXTCLOUD_URL || !process.env.NEXTCLOUD_USER || !process.env.NEXTCLOUD_PASSWORD) {
|
if (!process.env.NEXTCLOUD_URL || !process.env.NEXTCLOUD_SHARE_TOKEN) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ success: false, error: 'Nextcloud non configure sur le serveur' },
|
{ success: false, error: 'Nextcloud non configure sur le serveur (NEXTCLOUD_URL, NEXTCLOUD_SHARE_TOKEN)' },
|
||||||
{ status: 500 },
|
{ status: 500 },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,9 +108,11 @@ export async function POST(req: NextRequest) {
|
|||||||
const isModel = MODEL_EXTENSIONS.has(ext)
|
const isModel = MODEL_EXTENSIONS.has(ext)
|
||||||
|
|
||||||
if (isModel) {
|
if (isModel) {
|
||||||
// Model: always re-push since compression makes size comparison unreliable
|
// Model: always re-push since compression makes size comparison unreliable.
|
||||||
|
// Mark as 'unchanged' for the commit message when the folder already exists,
|
||||||
|
// because we can't know if the model really changed after Blender compression.
|
||||||
const remoteSize = remoteFileMap.get(filename.toLowerCase())
|
const remoteSize = remoteFileMap.get(filename.toLowerCase())
|
||||||
fileChanges.set(filename.toLowerCase(), remoteSize === undefined ? 'new' : 'changed')
|
fileChanges.set(filename.toLowerCase(), remoteSize === undefined ? 'new' : 'unchanged')
|
||||||
changedFilesToPush.push(f)
|
changedFilesToPush.push(f)
|
||||||
} else {
|
} else {
|
||||||
// Texture: compare by size
|
// Texture: compare by size
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ export default function UploadZone() {
|
|||||||
// ---- Step 1: Drive upload ----
|
// ---- Step 1: Drive upload ----
|
||||||
updateEntry(i, {
|
updateEntry(i, {
|
||||||
status: 'uploading',
|
status: 'uploading',
|
||||||
progress: 0,
|
progress: 1,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
driveStatus: 'uploading',
|
driveStatus: 'uploading',
|
||||||
driveError: undefined,
|
driveError: undefined,
|
||||||
@@ -300,7 +300,7 @@ export default function UploadZone() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEntry(i, { driveStatus: 'success' })
|
updateEntry(i, { driveStatus: 'success', progress: 50 })
|
||||||
|
|
||||||
// ---- Step 2: Git upload ----
|
// ---- Step 2: Git upload ----
|
||||||
await pushGit(i, controller.signal)
|
await pushGit(i, controller.signal)
|
||||||
@@ -314,13 +314,11 @@ export default function UploadZone() {
|
|||||||
const pushGit = async (index: number, signal?: AbortSignal) => {
|
const pushGit = async (index: number, signal?: AbortSignal) => {
|
||||||
const folderEntry = entries[index]
|
const folderEntry = entries[index]
|
||||||
|
|
||||||
updateEntry(index, { progress: 5 })
|
|
||||||
|
|
||||||
const gitResult = await uploadGit(
|
const gitResult = await uploadGit(
|
||||||
folderEntry,
|
folderEntry,
|
||||||
secret,
|
secret,
|
||||||
destination!,
|
destination!,
|
||||||
(pct) => updateEntry(index, { progress: pct }),
|
(pct) => updateEntry(index, { progress: 50 + Math.round(pct / 2) }),
|
||||||
signal,
|
signal,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export default function FolderCard({ entry, index, onToggleViewer, onRemove }: F
|
|||||||
<span className="shrink-0 text-xs px-1.5 py-0.5 rounded-full bg-gray-700 text-gray-300">Dossier</span>
|
<span className="shrink-0 text-xs px-1.5 py-0.5 rounded-full bg-gray-700 text-gray-300">Dossier</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 mt-0.5">
|
<div className="flex items-center gap-2 mt-0.5">
|
||||||
<span className="text-xs text-gray-500">modele : {entry.modelFile.name}</span>
|
<span className="text-xs text-gray-500">model : {entry.modelFile.name}</span>
|
||||||
{entry.status === 'error' && entry.error && (
|
{entry.status === 'error' && entry.error && (
|
||||||
<span className="text-xs text-red-400 truncate">{entry.error}</span>
|
<span className="text-xs text-red-400 truncate">{entry.error}</span>
|
||||||
)}
|
)}
|
||||||
@@ -71,8 +71,8 @@ export default function FolderCard({ entry, index, onToggleViewer, onRemove }: F
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Drive status sub-line */}
|
{/* Drive status sub-line (only during upload, not after success) */}
|
||||||
{entry.driveStatus && entry.driveStatus !== 'pending' && (
|
{entry.status !== 'success' && entry.driveStatus && entry.driveStatus !== 'pending' && (
|
||||||
<div className="flex items-center gap-1.5 mt-0.5">
|
<div className="flex items-center gap-1.5 mt-0.5">
|
||||||
{entry.driveStatus === 'uploading' && (
|
{entry.driveStatus === 'uploading' && (
|
||||||
<>
|
<>
|
||||||
@@ -80,15 +80,16 @@ export default function FolderCard({ entry, index, onToggleViewer, onRemove }: F
|
|||||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span className="text-xs text-gray-400">Drive en cours...</span>
|
<span className="text-xs text-gray-400">Upload Drive en cours...</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{entry.driveStatus === 'success' && (
|
{entry.driveStatus === 'success' && (
|
||||||
<>
|
<>
|
||||||
<svg className="w-3 h-3 text-green-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
|
<svg className="w-3 h-3 text-gray-400 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||||||
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span className="text-xs text-green-400">Drive OK</span>
|
<span className="text-xs text-gray-400">Upload Git en cours...</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{entry.driveStatus === 'error' && (
|
{entry.driveStatus === 'error' && (
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export function buildCommitMessage(
|
|||||||
|
|
||||||
const lines: string[] = [title, '']
|
const lines: string[] = [title, '']
|
||||||
|
|
||||||
// Model section — only show if changed or new
|
// Model section — show status for new, changed, or unchanged
|
||||||
const modelChange = fileChanges.get(modelFilename.toLowerCase())
|
const modelChange = fileChanges.get(modelFilename.toLowerCase())
|
||||||
if (modelChange === 'new') {
|
if (modelChange === 'new') {
|
||||||
lines.push('📦 Model')
|
lines.push('📦 Model')
|
||||||
@@ -34,6 +34,9 @@ export function buildCommitMessage(
|
|||||||
} else if (modelChange === 'changed') {
|
} else if (modelChange === 'changed') {
|
||||||
lines.push('📦 Model')
|
lines.push('📦 Model')
|
||||||
lines.push(` 🔄 ${modelFilename}${compressed ? ' (compressed)' : ''}`)
|
lines.push(` 🔄 ${modelFilename}${compressed ? ' (compressed)' : ''}`)
|
||||||
|
} else if (modelChange === 'unchanged') {
|
||||||
|
lines.push('📦 Model')
|
||||||
|
lines.push(` ↔️ ${modelFilename} (inchange)`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Textures section — only show lines that have changes
|
// Textures section — only show lines that have changes
|
||||||
|
|||||||
+7
-7
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
function getConfig() {
|
function getConfig() {
|
||||||
const url = process.env.NEXTCLOUD_URL
|
const url = process.env.NEXTCLOUD_URL
|
||||||
const user = process.env.NEXTCLOUD_USER
|
const token = process.env.NEXTCLOUD_SHARE_TOKEN
|
||||||
const password = process.env.NEXTCLOUD_PASSWORD
|
const password = process.env.NEXTCLOUD_SHARE_PASSWORD || ''
|
||||||
const basePath = process.env.NEXTCLOUD_BASE_PATH || 'Models'
|
const basePath = process.env.NEXTCLOUD_BASE_PATH || 'Models'
|
||||||
|
|
||||||
if (!url || !user || !password) {
|
if (!url || !token) {
|
||||||
throw new Error('Nextcloud non configure (NEXTCLOUD_URL, NEXTCLOUD_USER, NEXTCLOUD_PASSWORD)')
|
throw new Error('Nextcloud non configure (NEXTCLOUD_URL, NEXTCLOUD_SHARE_TOKEN)')
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebDAV base: https://cloud.example.com/remote.php/dav/files/{user}/
|
// Public share WebDAV: https://cloud.example.com/public.php/webdav/
|
||||||
const davBase = `${url.replace(/\/+$/, '')}/remote.php/dav/files/${encodeURIComponent(user)}`
|
const davBase = `${url.replace(/\/+$/, '')}/public.php/webdav`
|
||||||
const auth = 'Basic ' + Buffer.from(`${user}:${password}`).toString('base64')
|
const auth = 'Basic ' + Buffer.from(`${token}:${password}`).toString('base64')
|
||||||
|
|
||||||
return { davBase, auth, basePath }
|
return { davBase, auth, basePath }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user