Compare commits

...
2 Commits
Author SHA1 Message Date
luzadev 9d21ca051f v1.7.4: DMG macOS con Fix Gatekeeper integrato
Macos ora viene distribuito come .dmg invece di .zip:
- contiene MusicTools.app + alias Applicazioni + "Fix Gatekeeper.command"
- doppio click sullo script rimuove com.apple.quarantine senza
  Terminal manuale -> niente piu' "App non verificata"

Backend: /api/download serve .dmg con Content-Type
application/x-apple-diskimage. Landing /download aggiornata
con il nuovo flusso (3 step).
2026-06-09 11:53:37 +02:00
luzadev 05ea4c6181 v1.7.3: nuova icona app + landing chiarisce limiti senza chiavi Spotify
Icona: rigenerati icon.icns (macOS multi-size) e icon.ico (Windows
multi-size 16-256) dalla sorgente assets/icon_1024.png.

Landing: nuovo box "Per sfruttare al massimo MusicTools serve un
account Spotify" + FAQ esplicita su cosa funziona senza setup
e dove servono le chiavi.
2026-06-09 11:43:20 +02:00
10 changed files with 178 additions and 12 deletions

No files matched your search

+27 -6
View File
@@ -33,17 +33,38 @@ jobs:
- name: Build app - name: Build app
run: python build_macos.py run: python build_macos.py
- name: Package .app -> zip - name: Create DMG
run: | run: |
cd dist STAGING="dmg_staging"
ditto -c -k --sequesterRsrc --keepParent MusicTools.app ../MusicTools-macOS.zip rm -rf "$STAGING"
ls -lh ../MusicTools-macOS.zip mkdir -p "$STAGING"
cp -R dist/MusicTools.app "$STAGING/"
cp "assets/Fix Gatekeeper.command" "$STAGING/"
chmod +x "$STAGING/Fix Gatekeeper.command"
ln -s /Applications "$STAGING/Applications"
cat > "$STAGING/LEGGIMI.txt" <<'EOF'
INSTALLAZIONE MusicTools
========================
1) Trascina MusicTools.app sulla cartella "Applicazioni"
(l'alias e' qui dentro nel DMG)
2) Doppio click su "Fix Gatekeeper.command"
Rimuove la quarantena macOS Gatekeeper (una sola volta).
3) Apri MusicTools dalle Applicazioni e attiva con email + chiave.
Problemi? scrivici a info@djluza.com
EOF
hdiutil create -volname "MusicTools" -srcfolder "$STAGING" \
-ov -format UDZO MusicTools-macOS.dmg
ls -lh MusicTools-macOS.dmg
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: MusicTools-macOS name: MusicTools-macOS
path: MusicTools-macOS.zip path: MusicTools-macOS.dmg
retention-days: 14 retention-days: 14
# ========================================================= # =========================================================
@@ -107,5 +128,5 @@ jobs:
generate_release_notes: true generate_release_notes: true
fail_on_unmatched_files: true fail_on_unmatched_files: true
files: | files: |
artifacts/macos/MusicTools-macOS.zip artifacts/macos/MusicTools-macOS.dmg
artifacts/windows/MusicTools-Windows.zip artifacts/windows/MusicTools-Windows.zip
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
# Rimuove la quarantena Gatekeeper da MusicTools.app
# Doppio click in macOS apre Terminal ed esegue questo script.
set -e
APP_NAME="MusicTools.app"
# Cerca l'app in /Applications, poi nella stessa cartella del DMG montato.
if [ -d "/Applications/${APP_NAME}" ]; then
APP="/Applications/${APP_NAME}"
elif [ -d "$(dirname "$0")/${APP_NAME}" ]; then
APP="$(dirname "$0")/${APP_NAME}"
else
osascript -e "display alert \"${APP_NAME} non trovata\" message \"Trascina MusicTools.app nella cartella Applicazioni prima di eseguire questo script.\" as critical"
exit 1
fi
echo "Rimuovo la quarantena da: ${APP}"
xattr -dr com.apple.quarantine "${APP}" 2>/dev/null || true
# Notifica visuale
osascript -e "display notification \"MusicTools puo' essere aperta normalmente con doppio click.\" with title \"Fix completato\""
echo ""
echo "Fatto. Ora puoi aprire MusicTools normalmente con doppio click."
echo "Puoi chiudere questa finestra."
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 61 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 207 KiB

+1 -1
View File
@@ -5,7 +5,7 @@ import os
import sys import sys
from pathlib import Path from pathlib import Path
VERSION = "v1.7.2" VERSION = "v1.7.4"
APP_NAME = "MusicTools" APP_NAME = "MusicTools"
+63
View File
@@ -601,6 +601,69 @@ a { color: inherit; text-decoration: none; }
text-align: center; text-align: center;
} }
/* Box informativo sulle chiavi API Spotify */
.spotify-note {
max-width: 900px;
margin: 48px auto 0;
padding: 28px 32px;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 18px;
}
.spotify-note h3 {
margin: 0 0 10px;
font-size: 19px;
font-weight: 800;
}
.spotify-note > p {
margin: 0 0 18px;
color: var(--text-muted);
font-size: 15px;
line-height: 1.55;
}
.spotify-note-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
margin: 18px 0 14px;
}
@media (max-width: 640px) {
.spotify-note-grid { grid-template-columns: 1fr; }
}
.sn-col {
padding: 18px 20px;
border-radius: 12px;
border: 1px solid var(--border);
}
.sn-with {
background: rgba(29, 185, 84, 0.08);
border-color: rgba(29, 185, 84, 0.3);
}
.sn-without {
background: rgba(120, 120, 120, 0.06);
}
.sn-title {
font-weight: 800;
font-size: 14.5px;
margin-bottom: 8px;
color: var(--text);
}
.sn-col ul {
margin: 0;
padding-left: 18px;
color: var(--text-muted);
font-size: 14px;
line-height: 1.55;
}
.sn-col li { margin-bottom: 4px; }
.sn-col strong { color: var(--text); }
.spotify-note-fine {
margin-top: 12px;
font-size: 12.5px;
color: var(--text-dim);
text-align: center;
}
/* ============================================================ /* ============================================================
FAQ FAQ
============================================================ */ ============================================================ */
+4 -4
View File
@@ -175,10 +175,10 @@
<div class="dl-steps"> <div class="dl-steps">
<h2>Installazione macOS</h2> <h2>Installazione macOS</h2>
<ol> <ol>
<li>Apri il file <code>.zip</code> scaricato — viene estratto in <code>MusicTools.app</code></li> <li>Apri il file <code>.dmg</code> scaricato — si monta come volume "MusicTools"</li>
<li>Trascina <strong>MusicTools.app</strong> nella cartella <strong>Applicazioni</strong></li> <li>Trascina <strong>MusicTools.app</strong> sull'alias <strong>Applicazioni</strong> dentro il DMG</li>
<li>Vai in Applicazioni, <strong>tasto destro</strong> su MusicTools → <strong>Apri</strong> → <strong>Apri</strong> (solo la prima volta, e' la procedura standard per app non firmate)</li> <li>Doppio click su <strong>Fix Gatekeeper.command</strong> (dentro il DMG): autorizza l'app in 1 click. Si chiude da sola appena finito.</li>
<li>Inserisci email e chiave per attivare</li> <li>Apri MusicTools dalle Applicazioni, inserisci email e chiave per attivare</li>
</ol> </ol>
</div> </div>
+49
View File
@@ -284,6 +284,39 @@
</p> </p>
</div> </div>
<div class="spotify-note">
<h3>Per sfruttare al massimo MusicTools serve un account Spotify</h3>
<p>
L'app raggiunge il <strong>100% delle sue funzioni</strong> quando colleghi
le tue <strong>chiavi API Spotify</strong>. Sono <strong>gratuite</strong>:
basta un account Spotify (anche <strong>quello gratis</strong>, niente
Premium richiesto) e bastano <strong>2 minuti</strong> per generarle dalla
Developer Dashboard. La guida passo-passo e' integrata nell'app.
</p>
<div class="spotify-note-grid">
<div class="sn-col sn-with">
<div class="sn-title">✓ Con chiavi API Spotify (consigliato)</div>
<ul>
<li>Scarichi <strong>playlist intere</strong> e <strong>album</strong> da Spotify</li>
<li>Brani con <strong>metadati e copertine</strong> ufficiali</li>
<li>Tutte le altre fonti restano sempre attive</li>
</ul>
</div>
<div class="sn-col sn-without">
<div class="sn-title">Senza chiavi (modalita' base)</div>
<ul>
<li>Da Spotify scarichi <strong>un brano alla volta</strong></li>
<li>YouTube, SoundCloud, TikTok, IG, FB: <strong>nessuna limitazione</strong></li>
<li>Ricerca per "Artista - Titolo" sempre attiva</li>
</ul>
</div>
</div>
<p class="spotify-note-fine">
MusicTools non e' affiliato a Spotify. Le chiavi API restano sul tuo
dispositivo, non passano per i nostri server.
</p>
</div>
<div class="use-policy"> <div class="use-policy">
<h3>Uso responsabile</h3> <h3>Uso responsabile</h3>
<p> <p>
@@ -347,6 +380,22 @@
<p>No. Per Spotify ti basta un account gratuito (serve solo per ottenere le credenziali API dal loro dashboard, è gratis). YouTube non richiede account.</p> <p>No. Per Spotify ti basta un account gratuito (serve solo per ottenere le credenziali API dal loro dashboard, è gratis). YouTube non richiede account.</p>
</details> </details>
<details class="faq-item">
<summary>Cosa posso fare senza configurare le chiavi API Spotify?</summary>
<p>
<strong>Da YouTube, SoundCloud, TikTok, Instagram, Facebook</strong>:
scarichi senza limiti, link diretti e ricerca per titolo. Senza setup.
</p>
<p>
<strong>Da Spotify</strong>: senza chiavi puoi scaricare <strong>un
brano alla volta</strong> incollando il link al singolo brano (l'app
estrae artista e titolo dai metadati pubblici di Spotify e cerca su
YouTube). Per <strong>album e playlist</strong> servono le chiavi API
— sono gratis (anche con account Spotify free) e la procedura guidata
nell'app ci mette 2 minuti.
</p>
</details>
<details class="faq-item"> <details class="faq-item">
<summary>Posso registrare l'audio di Spotify mentre suona?</summary> <summary>Posso registrare l'audio di Spotify mentre suona?</summary>
<p>Sì, con BlackHole (macOS) o la scheda audio virtuale di Windows. La tab Registra ti guida nel setup passo-passo.</p> <p>Sì, con BlackHole (macOS) o la scheda audio virtuale di Windows. La tab Registra ti guida nel setup passo-passo.</p>
+7 -1
View File
@@ -89,7 +89,13 @@ export async function download(req, res) {
} }
const name = path.basename(abs); const name = path.basename(abs);
res.setHeader("Content-Type", "application/zip"); const ext = path.extname(name).toLowerCase();
const contentType = ext === ".dmg"
? "application/x-apple-diskimage"
: ext === ".exe"
? "application/vnd.microsoft.portable-executable"
: "application/zip";
res.setHeader("Content-Type", contentType);
res.setHeader("Content-Disposition", `attachment; filename="${name}"`); res.setHeader("Content-Disposition", `attachment; filename="${name}"`);
fs.createReadStream(abs).pipe(res); fs.createReadStream(abs).pipe(res);
} }