anonymized data

This commit is contained in:
remimarseault 2024-10-24 10:35:01 +02:00
parent 6e6cc4848d
commit 6938d0efe2
5 changed files with 44 additions and 17 deletions

View file

@ -198,15 +198,19 @@ function openBackendHelp() {
<v-checkbox v-model="vueTorrentStore.isShutdownButtonVisible" hide-details density="compact" :label="t('settings.vuetorrent.general.isShutdownButtonVisible')" />
</v-col>
<v-col cols="12" sm="6" md="4">
<v-col cols="12" sm="6">
<v-checkbox v-model="vueTorrentStore.useBinarySize" hide-details density="compact" :label="t('settings.vuetorrent.general.useBinarySize')" />
</v-col>
<v-col cols="12" sm="6" md="4">
<v-col cols="12" sm="6">
<v-checkbox v-model="vueTorrentStore.useBitSpeed" hide-details density="compact" :label="t('settings.vuetorrent.general.useBitSpeed')" />
</v-col>
<v-col cols="12" sm="6" md="4">
<v-col cols="12" sm="6">
<v-checkbox v-model="vueTorrentStore.useEmojiState" hide-details density="compact" :label="t('settings.vuetorrent.general.useEmojiState')" />
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="vueTorrentStore.useAnonymizedData" hide-details density="compact" :label="t('settings.vuetorrent.general.useAnonymizedData')" />
</v-col>
</v-row>
</v-list-item>

View file

@ -1111,6 +1111,7 @@
"showSessionStat": "Show Session Stats",
"showSpeedGraph": "Show Speed Graph",
"tip": "These settings are for the custom WebUI itself",
"useAnonymizedData": "Anonymize data (for sending reports)",
"useBinarySize": "Replace data sizes by binary units (kB -> KiB)",
"useBitSpeed": "Replace speed values by bits (kB/s -> kbps)",
"useEmojiState": "Prepend torrent states with emojis",

View file

@ -1,6 +1,7 @@
import { comparators } from '@/helpers'
import qbit from '@/services/qbit'
import { Category } from '@/types/qbit/models'
import { faker } from '@faker-js/faker/locale/en'
import { useSorted } from '@vueuse/core'
import { acceptHMRUpdate, defineStore } from 'pinia'
import { shallowRef, triggerRef } from 'vue'
@ -8,6 +9,8 @@ import { shallowRef, triggerRef } from 'vue'
export const useCategoryStore = defineStore('categories', () => {
/** Key: Category name */
const _categoryMap = shallowRef<Map<string, Category>>(new Map())
const anonymizedMap = shallowRef(new Map<string, string>())
const categories = useSorted(
() => Array.from(_categoryMap.value.values()),
(a, b) => comparators.text.asc(a.name, b.name)
@ -16,26 +19,26 @@ export const useCategoryStore = defineStore('categories', () => {
function syncFromMaindata(fullUpdate: boolean, entries: [string, Partial<Category>][], removed?: string[]) {
if (fullUpdate) {
_categoryMap.value = new Map(entries as [string, Category][])
anonymizedMap.value = new Map(entries.map(([name]) => [name, faker.word.sample()]))
return
}
for (const [catName, qbitCat] of entries) {
const oldCat = _categoryMap.value.get(catName)
if (oldCat) {
const newCat = {
name: qbitCat.name ?? oldCat.name,
savePath: qbitCat.savePath ?? oldCat.savePath
}
_categoryMap.value.set(catName, newCat)
} else {
_categoryMap.value.set(catName, {
name: qbitCat.name ?? catName,
savePath: qbitCat.savePath ?? ''
})
if (qbitCat.name) {
anonymizedMap.value.set(qbitCat.name, faker.word.sample())
}
_categoryMap.value.set(catName, {
name: qbitCat.name ?? oldCat?.name ?? catName,
savePath: qbitCat.savePath ?? oldCat?.savePath ?? ''
})
}
removed?.forEach(c => _categoryMap.value.delete(c))
removed?.forEach(c => {
_categoryMap.value.delete(c)
anonymizedMap.value.delete(c)
})
triggerRef(_categoryMap)
triggerRef(anonymizedMap)
}
function getCategoryFromName(categoryName?: string) {
@ -77,6 +80,7 @@ export const useCategoryStore = defineStore('categories', () => {
}
return {
anonymizedMap,
categories,
syncFromMaindata,
getCategoryFromName,
@ -85,7 +89,9 @@ export const useCategoryStore = defineStore('categories', () => {
deleteCategories,
$reset: () => {
_categoryMap.value.clear()
anonymizedMap.value.clear()
triggerRef(_categoryMap)
triggerRef(anonymizedMap)
}
}
})

View file

@ -1,22 +1,32 @@
import { comparators } from '@/helpers'
import qbit from '@/services/qbit'
import { faker } from '@faker-js/faker/locale/en'
import { useSorted } from '@vueuse/core'
import { acceptHMRUpdate, defineStore } from 'pinia'
import { shallowRef, triggerRef } from 'vue'
export const useTagStore = defineStore('tags', () => {
const _tags = shallowRef<Set<string>>(new Set())
const anonymizedMap = shallowRef(new Map<string, string>())
const tags = useSorted(() => Array.from(_tags.value.values()), comparators.text.asc)
function syncFromMaindata(fullUpdate: boolean, values: string[], removed?: string[]) {
if (fullUpdate) {
_tags.value = new Set(values)
anonymizedMap.value = new Map(values.map(v => [v, faker.word.sample()]))
return
}
values.forEach(tag => _tags.value.add(tag))
removed?.forEach(tag => _tags.value.delete(tag))
values.forEach(tag => {
_tags.value.add(tag)
anonymizedMap.value.set(tag, faker.word.sample())
})
removed?.forEach(tag => {
_tags.value.delete(tag)
anonymizedMap.value.delete(tag)
})
triggerRef(_tags)
triggerRef(anonymizedMap)
}
async function createTags(tags: string[]) {
@ -47,6 +57,7 @@ export const useTagStore = defineStore('tags', () => {
}
return {
anonymizedMap,
tags,
syncFromMaindata,
createTags,
@ -54,7 +65,9 @@ export const useTagStore = defineStore('tags', () => {
deleteTags,
$reset: () => {
_tags.value.clear()
anonymizedMap.value.clear()
triggerRef(_tags)
triggerRef(anonymizedMap)
}
}
})

View file

@ -57,6 +57,7 @@ export const useVueTorrentStore = defineStore(
const hideColoredChip = ref(false)
const displayGraphLimits = ref(true)
const useEmojiState = ref(true)
const useAnonymizedData = ref(false)
const _busyProperties = ref<PropertyData>(JSON.parse(JSON.stringify(propsData)))
const _doneProperties = ref<PropertyData>(JSON.parse(JSON.stringify(propsData)))
@ -274,6 +275,7 @@ export const useVueTorrentStore = defineStore(
isInfiniteScrollActive,
displayGraphLimits,
useEmojiState,
useAnonymizedData,
setLanguage,
updateTheme,
toggleTheme,
@ -320,6 +322,7 @@ export const useVueTorrentStore = defineStore(
hideColoredChip.value = false
displayGraphLimits.value = true
useEmojiState.value = true
useAnonymizedData.value = false
_busyProperties.value = JSON.parse(JSON.stringify(propsData))
_doneProperties.value = JSON.parse(JSON.stringify(propsData))