Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3b009ec
Fix Beatport search after __NEXT_DATA__ removal
Simon-Zwa May 18, 2026
bc1541b
Update README with temporary Beatport fix note
Simon-Zwa May 18, 2026
63dfdfb
Update macOS runner to use latest version
Simon-Zwa May 18, 2026
4f82b27
Refactor Beatsource token management and search parameters
rosgr100 May 19, 2026
27c96bc
Update build.yml
rosgr100 May 19, 2026
48a6312
Upgrade GitHub Actions to latest versions
rosgr100 May 19, 2026
23aad90
Upgrade GitHub Actions to latest versions
rosgr100 May 19, 2026
99c2663
Fix YAML syntax in build workflow
rosgr100 May 19, 2026
c1b9080
Set environment variable for Node.js version
rosgr100 May 19, 2026
01902bf
Modernize workspace dependencie, Fixed album art file persistence bug…
rosgr100 May 20, 2026
415aef2
Fix duplicate custom tags and standardize ID3 date formats
rosgr100 May 21, 2026
f2d83b7
Prevent API decoding errors in Beatsource search queries
rosgr100 May 21, 2026
0593240
Delete client/pnpm-workspace.yaml
rosgr100 May 21, 2026
83a4ead
Improved Beatport and Beatsource Track Search earch
rosgr100 May 22, 2026
f2f808a
Refactor AutotaggerStatus.vue layout
rosgr100 May 24, 2026
0d99300
Add environment variable for PNPM configuration
rosgr100 May 24, 2026
d086c22
Refactor build workflow to install NodeJS and pnpm separately
rosgr100 May 24, 2026
c737add
Corrected tag frames for Date tags
rosgr100 Jun 5, 2026
3077df0
Merge branch 'master' of https://github.com/rosgr100/onetagger
rosgr100 Jun 5, 2026
d5a01fd
Corrected id3 Tags frames for date tags to support DJ apps
rosgr100 Jun 5, 2026
05cca45
Corrected id3 Tags frames for date tags to support DJ apps, Refactor…
rosgr100 Jun 5, 2026
a11d4b5
Refactor macOS build job to support universal binaries
rosgr100 Jun 5, 2026
a5b3533
Delete crates/onetagger-tag/id3.rs
rosgr100 Jun 6, 2026
d0562e6
Delete crates/onetagger-tag/lib.rs
rosgr100 Jun 6, 2026
050b304
Update Beatport matching logic to independently grade mix names
rosgr100 Jun 7, 2026
f674f66
Update Beatport matching logic to independently grade mix names
rosgr100 Jun 7, 2026
2770234
feat(beatport): implement semantic fallback engine for DJ mix taxonom…
rosgr100 Jun 7, 2026
6e3fc21
Fix(Beatport): Improve match accuracy for featured artists, fix Autot…
rosgr100 Jun 9, 2026
59b007f
Fix(Beatport): Resolve token deadlock and prevent ISRC search hard cr…
rosgr100 Jun 11, 2026
9021567
Add bounded retry loop for token updates
rosgr100 Jun 12, 2026
31354c8
Switch client to pnpm workspace and update files
Jun 16, 2026
c1ab6cd
Remove JunoDownload and improve platform ordering
Jun 17, 2026
d446813
Update pnpm workspace configuration
rosgr100 Jun 21, 2026
cb2459f
Update NodeJS version to 22 in build workflow
rosgr100 Jun 23, 2026
5a4486c
Update NodeJS version to 22 in build workflow
rosgr100 Jun 23, 2026
b4c85ce
Upgrade Node.js version from 18 to 22
rosgr100 Jun 23, 2026
f7adb26
Merge pull request #2 from benjaminlewandowski/master
rosgr100 Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
411 changes: 225 additions & 186 deletions .github/workflows/build.yml

Large diffs are not rendered by default.

2,636 changes: 1,790 additions & 846 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
<h3 align='center'><b></b></h3>
<hr>

Temporary Beatport fix build May 2026
Cross-platform music tagger.
It can fetch metadata from Beatport, Traxsource, Juno Download, Discogs, Musicbrainz and Spotify.
It can fetch metadata from Beatport, Traxsource, Discogs, Musicbrainz and Spotify.
It is also able to fetch Spotify's Audio Features based on ISRC & exact match.
There is a manual tag editor and quick tag editor which lets you use keyboard shortcuts. Written in Rust, Vue.js and Quasar.

Expand Down
26 changes: 13 additions & 13 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@
"preview": "vite preview"
},
"dependencies": {
"@quasar/extras": "1.16.16",
"axios": "1.8.2",
"@quasar/extras": "2.0.1",
"axios": "1.18.0",
"compare-versions": "6.1.1",
"quasar": "2.17.7",
"vue": "3.5.13",
"vue-router": "4.5.0",
"quasar": "2.20.1",
"vue": "3.5.38",
"vue-router": "5.1.0",
"vuedraggable": "4.1.0"
},
"devDependencies": {
"@quasar/vite-plugin": "1.9.0",
"@vitejs/plugin-vue": "5.2.4",
"path": "^0.12.7",
"sass": "1.83.4",
"typescript": "5.7.3",
"vite": "6.3.5",
"vue-tsc": "3.0.5"
"@quasar/vite-plugin": "1.12.0",
"@vitejs/plugin-vue": "6.0.7",
"path": "0.12.7",
"sass": "1.101.0",
"typescript": "6.0.3",
"vite": "8.0.16",
"vue-tsc": "3.3.5"
}
}
}
18 changes: 18 additions & 0 deletions client/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
packages:
- 'client'

allowBuilds:
'@parcel/watcher': true
esbuild: true
minimumReleaseAgeExclude:
- '@vue/compiler-core@3.5.38'
- '@vue/compiler-dom@3.5.38'
- '@vue/compiler-sfc@3.5.38'
- '@vue/compiler-ssr@3.5.38'
- '@vue/reactivity@3.5.38'
- '@vue/runtime-core@3.5.38'
- '@vue/runtime-dom@3.5.38'
- '@vue/server-renderer@3.5.38'
- '@vue/shared@3.5.38'
- vue@3.5.38
- quasar@2.20.1
52 changes: 42 additions & 10 deletions client/src/components/AutotaggerPlatforms.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class='row justify-center'>
<draggable v-model='$1t.info.value.platforms' @update='syncPlatforms' item-key='id'>
<draggable v-model='localPlatforms' @change='syncPlatforms' item-key='platform.id' :animation='200'>
<template #item='{ element: platform }'>
<q-card flat class='card q-ma-md'>
<q-card-section horizontal class='row justify-between'>
Expand Down Expand Up @@ -80,7 +80,7 @@
</template>

<script lang='ts' setup>
import { onMounted, ref } from 'vue';
import { onMounted, ref, watch } from 'vue';
import { get1t } from '../scripts/onetagger.js';
import draggable from 'vuedraggable';
import { AutotaggerPlatform, SupportedTag } from '../scripts/autotagger';
Expand All @@ -91,6 +91,21 @@ const { dense } = defineProps({
});
const $1t = get1t();
const platformsRepoButtonLoading = ref(false);
const localPlatforms = ref<AutotaggerPlatform[]>([]);
const isSyncing = ref(false);

function sortPlatforms() {
console.log('sortPlatforms() called');
localPlatforms.value = $1t.info.value.platforms.slice();
localPlatforms.value.sort((a, b) => {
let x = $1t.config.value.platforms.indexOf(a.platform.id);
let y = $1t.config.value.platforms.indexOf(b.platform.id);
if (x == -1) x = 1000;
if (y == -1) y = 1000;
return x - y;
});
console.log('Sorted platforms:', localPlatforms.value.map(p => p.platform.id));
}

// Update config
function update(platform: string) {
Expand All @@ -99,6 +114,7 @@ function update(platform: string) {
$1t.config.value.platforms.push(platform);
else
$1t.config.value.platforms.splice(i, 1);
$1t.saveSettings(false);
}

// Is platform enabled
Expand All @@ -108,7 +124,19 @@ function isEnabled(platform: string) {

// Sync platforms order to config
function syncPlatforms() {
$1t.config.value.platforms = $1t.info.value.platforms.map((p) => p.platform.id).filter((p) => $1t.config.value.platforms.includes(p));
console.log('syncPlatforms called from draggable, platforms:', localPlatforms.value.map(p => p.platform.id));
// Set flag to prevent re-sort from watcher
isSyncing.value = true;
// Update config with new order - only keep enabled platforms in the new order
const newOrder = localPlatforms.value.map((p) => p.platform.id).filter((p) => $1t.config.value.platforms.includes(p));
console.log('New config order:', newOrder, 'Old order:', $1t.config.value.platforms);
$1t.config.value.platforms = newOrder;
$1t.saveSettings(false);
console.log('Settings saved');
// Reset flag after a tick
setTimeout(() => {
isSyncing.value = false;
}, 0);
}

/// Does the platform have lyrics
Expand All @@ -126,15 +154,19 @@ function openPlatformsRepo() {
}

onMounted(() => {
$1t.info.value.platforms.sort((a, b) => {
let x = $1t.config.value.platforms.indexOf(a.platform.id);
let y = $1t.config.value.platforms.indexOf(b.platform.id);
if (x == -1) x = 1000;
if (y == -1) y = 1000;
return x - y;
});
sortPlatforms();
});

// Watch for changes to the platform list or config order
watch(() => [$1t.info.value.platforms, $1t.config.value.platforms], () => {
if (isSyncing.value) {
console.log('Skipping re-sort because syncing');
return;
}
console.log('Platforms or config changed externally, re-sorting');
sortPlatforms();
}, { deep: true });

</script>

<style lang='scss'>
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/HelpButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
It reads the <q-badge outline color='primary'><span class='text-uppercase text-grey-3'>Artist</span></q-badge> & <q-badge outline color='primary'><span class='text-uppercase text-grey-3'>Title</span></q-badge> tag from your local MP3, AIFF, FLAC & M4A files (or filename or playlist), <br>feeds it into the search engine of the selected platforms, fetches the tags & writes it to your files.<p></p>
When no tags or proper filename is present, you can enable <span @click='$1t.url("https://shazam.com")' class='clickable doc-link'>Shazam</span> to identify the track & still fetch tags.<br>

<span @click='$1t.url("https://beatport.com")' class='clickable doc-link'>Beatport</span> , <span @click='$1t.url("https://junodownload.com")' class='clickable doc-link'>Juno Download</span> & <span @click='$1t.url("https://traxsource.com")' class='clickable doc-link'>Traxsource</span> are based on a method called scraping. <br>
<span @click='$1t.url("https://beatport.com")' class='clickable doc-link'>Beatport</span> & <span @click='$1t.url("https://traxsource.com")' class='clickable doc-link'>Traxsource</span> are based on a method called scraping. <br>
<span @click='$1t.url("https://beatsource.com")' class='clickable doc-link'>Beatsource</span> , <span @click='$1t.url("https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/index.html")' class='clickable doc-link'>iTunes</span> & <span @click='$1t.url("https://musicbrainz.org")' class='clickable doc-link'>MusicBrainz</span> are based on their API.
<span @click='$1t.url("https://discogs.com")' class='clickable doc-link'>Discogs</span> & <span @click='$1t.url("https://spotify.com")' class='clickable doc-link'>Spotify</span> too, but need a free account.

Expand Down Expand Up @@ -85,7 +85,7 @@
<div class='col-3 q-mt-xs'><q-badge outline color='primary'><span class='text-uppercase text-grey-3'>Album</span></q-badge></div>
<div class='col-3 q-mt-xs'><q-badge outline color='primary'><span class='text-uppercase text-grey-3'>BPM</span></q-badge>
<q-icon name='mdi-help-circle-outline text-grey-6' class='onetagger-tooltip q-mx-xs'>
<q-tooltip>Available from: • Beatport • Beatsource  • Juno Download  • Traxsource</q-tooltip>
<q-tooltip>Available from: • Beatport • Beatsource • Traxsource</q-tooltip>
</q-icon>
</div>
<div class='col-3 q-mt-xs'><q-badge outline color='primary'><span class='text-uppercase text-grey-3'>Genre</span></q-badge> , <q-badge outline color='primary'><span class='text-uppercase text-grey-3'>Style / Subgenre</span></q-badge>
Expand Down
4 changes: 2 additions & 2 deletions client/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { createApp } from 'vue';
import { Quasar, Dialog, Notify } from 'quasar';
import { get1t } from './scripts/onetagger';
import router from './scripts/router';
import iconSet from 'quasar/icon-set/mdi-v6';
import iconSet from 'quasar/icon-set/mdi-v7';

// Style
import '@quasar/extras/mdi-v6/mdi-v6.css';
import '@quasar/extras/mdi-v7/mdi-v7.css';
import 'quasar/src/css/index.sass';
import './style/app.scss';

Expand Down
Loading
Loading