feat(preferences): Update settings page to include missing preferences (#1296)

This commit is contained in:
Rémi Marseault 2023-11-12 03:38:59 +01:00 committed by GitHub
parent 9a80ea5c66
commit e0340710cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 369 additions and 178 deletions

View file

@ -89,7 +89,8 @@ const onCategoryChanged = () => {
<v-card-text>
<v-row>
<v-col>
<v-file-input v-model="navbarStore.addTorrentDialogFiles" :label="t('dialogs.add.files')" :show-size="vueTorrentStore.useBinarySize ? 1024 : 1000"
<v-file-input v-model="navbarStore.addTorrentDialogFiles" :label="t('dialogs.add.files')"
:show-size="vueTorrentStore.useBinarySize ? 1024 : 1000"
accept=".torrent" counter multiple
persistent-clear persistent-hint prepend-icon="" variant="outlined">
<template v-slot:prepend>
@ -184,23 +185,28 @@ const onCategoryChanged = () => {
<v-col>
<v-list>
<v-list-item>
<v-checkbox v-model="navbarStore.addTorrentDialogForm.startNow" :label="t('dialogs.add.startNow')" density="compact"
<v-checkbox v-model="navbarStore.addTorrentDialogForm.startNow" :label="t('dialogs.add.startNow')"
density="compact"
hide-details />
</v-list-item>
<v-list-item>
<v-checkbox v-model="navbarStore.addTorrentDialogForm.skipChecking" :label="t('dialogs.add.skipChecking')" density="compact"
<v-checkbox v-model="navbarStore.addTorrentDialogForm.skipChecking"
:label="t('dialogs.add.skipChecking')" density="compact"
hide-details />
</v-list-item>
<v-list-item>
<v-checkbox v-model="navbarStore.addTorrentDialogForm.autoTMM" :label="t('dialogs.add.autoTMM')" density="compact"
<v-checkbox v-model="navbarStore.addTorrentDialogForm.autoTMM" :label="t('dialogs.add.autoTMM')"
density="compact"
hide-details />
</v-list-item>
<v-list-item>
<v-checkbox v-model="navbarStore.addTorrentDialogForm.sequentialDownload" :label="t('dialogs.add.sequentialDownload')" density="compact"
<v-checkbox v-model="navbarStore.addTorrentDialogForm.sequentialDownload"
:label="t('dialogs.add.sequentialDownload')" density="compact"
hide-details />
</v-list-item>
<v-list-item>
<v-checkbox v-model="navbarStore.addTorrentDialogForm.firstLastPiecePrio" :label="t('dialogs.add.firstLastPiecePrio')" density="compact"
<v-checkbox v-model="navbarStore.addTorrentDialogForm.firstLastPiecePrio"
:label="t('dialogs.add.firstLastPiecePrio')" density="compact"
hide-details />
</v-list-item>
</v-list>
@ -209,7 +215,8 @@ const onCategoryChanged = () => {
</v-card-text>
<v-card-actions class="justify-center">
<v-btn :disabled="!isFormValid" :loading="isLoading" color="accent" variant="elevated" :text="$t('dialogs.add.submit')" @click="submit" />
<v-btn :disabled="!isFormValid" :loading="isLoading" color="accent" variant="elevated"
:text="$t('dialogs.add.submit')" @click="submit" />
<v-btn color="error" variant="flat" :text="$t('common.close')" @click="close" />
</v-card-actions>
</v-card>

View file

@ -1,56 +1,77 @@
<script setup lang="ts">
import { DiskIOMode, DiskIOType, UploadChokingAlgorithm, UploadSlotsBehavior, UtpTcpMixedMode } from '@/constants/qbit/AppPreferences'
import {
DiskIOMode,
DiskIOType,
ResumeDataStorageType,
UploadChokingAlgorithm,
UploadSlotsBehavior,
UtpTcpMixedMode
} from '@/constants/qbit/AppPreferences'
import { qbit } from '@/services'
import { usePreferenceStore } from '@/stores/preferences'
import { onBeforeMount, ref } from 'vue'
import { computed, onBeforeMount } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const preferenceStore = usePreferenceStore()
const networkInterfaceOptions = ref([{ title: t('settings.advanced.qbittorrent.networking.networkInterfaces.any'), value: '' }])
const ipAddressesOptions = ref([
const resumeDataStorageTypeOptions = [
{ title: t('settings.advanced.qbittorrent.resumeDataStorageType.legacy'), value: ResumeDataStorageType.LEGACY },
{ title: t('settings.advanced.qbittorrent.resumeDataStorageType.sqlite'), value: ResumeDataStorageType.SQLITE }
]
const networkInterfaceOptions = [{
title: t('settings.advanced.qbittorrent.networking.networkInterfaces.any'),
value: ''
}]
const ipAddressesOptions = [
{ title: t('settings.advanced.qbittorrent.networking.ipAddress.all'), value: '' },
{ title: t('settings.advanced.qbittorrent.networking.ipAddress.allIPv4'), value: '0.0.0.0' },
{ title: t('settings.advanced.qbittorrent.networking.ipAddress.allIPv6'), value: '::' }
])
const diskIoTypeOptions = ref([
]
const diskIoTypeOptions = [
{ title: t('constants.diskIoType.default'), value: DiskIOType.DEFAULT },
{ title: t('constants.diskIoType.memoryMappedFiles'), value: DiskIOType.MEMORY_MAPPED_FILES },
{ title: t('constants.diskIoType.posixCompliant'), value: DiskIOType.POSIX_COMPLIANT }
])
const diskIoModeReadOptions = ref([
]
const diskIoModeReadOptions = [
{ title: t('constants.diskIoMode.disableOsCache'), value: DiskIOMode.DISABLE_OS_CACHE },
{ title: t('constants.diskIoMode.enableOsCache'), value: DiskIOMode.ENABLE_OS_CACHE }
])
const diskIoModeWriteOptions = ref([
]
const diskIoModeWriteOptions = [
{ title: t('constants.diskIoMode.disableOsCache'), value: DiskIOMode.DISABLE_OS_CACHE },
{ title: t('constants.diskIoMode.enableOsCache'), value: DiskIOMode.ENABLE_OS_CACHE },
{ title: t('constants.diskIoMode.writeThrough'), value: DiskIOMode.WRITE_THROUGH }
])
const utpTcpMixedModeOptions = ref([
]
const utpTcpMixedModeOptions = [
{ title: t('constants.utpTcpMixedMode.preferTcp'), value: UtpTcpMixedMode.PREFER_TCP },
{ title: t('constants.utpTcpMixedMode.peerProportional'), value: UtpTcpMixedMode.PEER_PROPORTIONAL }
])
const uploadSlotsBehaviorOptions = ref([
]
const uploadSlotsBehaviorOptions = [
{ title: t('constants.uploadSlotsBehavior.fixedSlots'), value: UploadSlotsBehavior.FIXED_SLOTS },
{ title: t('constants.uploadSlotsBehavior.uploadRateBased'), value: UploadSlotsBehavior.UPLOAD_RATE_BASED }
])
const uploadChokingAlgorithmOptions = ref([
]
const uploadChokingAlgorithmOptions = [
{ title: t('constants.uploadChokingAlgorithm.roundRobin'), value: UploadChokingAlgorithm.ROUND_ROBIN },
{ title: t('constants.uploadChokingAlgorithm.fastestUpload'), value: UploadChokingAlgorithm.FASTEST_UPLOAD },
{ title: t('constants.uploadChokingAlgorithm.antiLeech'), value: UploadChokingAlgorithm.ANTI_LEECH }
])
]
const torrentFileSizeLimit = computed({
get: () => preferenceStore.preferences!.torrent_file_size_limit / 1024 / 1024,
set: (value: number) => {
preferenceStore.preferences!.torrent_file_size_limit = value * 1024 * 1024
}
})
onBeforeMount(async () => {
const networkInterfaces = await qbit.getNetworkInterfaces()
for (const networkInterface of networkInterfaces) {
networkInterfaceOptions.value.push({ title: networkInterface.name, value: networkInterface.value })
networkInterfaceOptions.push({ title: networkInterface.name, value: networkInterface.value })
}
const ipAddresses = await qbit.getAddresses(preferenceStore.preferences!.current_network_interface)
for (const ipAddress of ipAddresses) {
ipAddressesOptions.value.push({ title: ipAddress, value: ipAddress })
ipAddressesOptions.push({ title: ipAddress, value: ipAddress })
}
})
</script>
@ -68,12 +89,9 @@ onBeforeMount(async () => {
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="preferenceStore.preferences!.memory_working_set_limit"
type="number"
hide-details
suffix="MiB"
:label="t('settings.advanced.qbittorrent.allocatedRam')" />
<v-select v-model="preferenceStore.preferences!.resume_data_storage_type" hide-details
:items="resumeDataStorageTypeOptions"
:label="$t('settings.advanced.qbittorrent.resumeDataStorageType.label')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field
@ -85,7 +103,24 @@ onBeforeMount(async () => {
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.recheck_completed_torrents" hide-details :label="t('settings.advanced.qbittorrent.recheckOnCompletion')" />
<v-text-field
v-model="preferenceStore.preferences!.memory_working_set_limit"
type="number"
hide-details
suffix="MiB"
:label="t('settings.advanced.qbittorrent.allocatedRam')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="torrentFileSizeLimit"
type="number"
hide-details
suffix="MiB"
:label="$t('settings.advanced.qbittorrent.torrentFileSizeLimit')" />
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.recheck_completed_torrents" hide-details
:label="t('settings.advanced.qbittorrent.recheckOnCompletion')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field
@ -97,10 +132,12 @@ onBeforeMount(async () => {
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.resolve_peer_countries" hide-details :label="t('settings.advanced.qbittorrent.resolveCountries')" />
<v-checkbox v-model="preferenceStore.preferences!.resolve_peer_countries" hide-details
:label="t('settings.advanced.qbittorrent.resolveCountries')" />
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.reannounce_when_address_changed" hide-details :label="t('settings.advanced.qbittorrent.reannounceOnIpPortChanged')" />
<v-checkbox v-model="preferenceStore.preferences!.reannounce_when_address_changed" hide-details
:label="t('settings.advanced.qbittorrent.reannounceOnIpPortChanged')" />
</v-col>
</v-row>
</v-list-item>
@ -133,7 +170,8 @@ onBeforeMount(async () => {
<v-list-item>
<v-row>
<v-col cols="12" class="py-0">
<v-checkbox v-model="preferenceStore.preferences!.enable_embedded_tracker" hide-details :label="t('settings.advanced.qbittorrent.embeddedTracker.enable')" />
<v-checkbox v-model="preferenceStore.preferences!.enable_embedded_tracker" hide-details
:label="t('settings.advanced.qbittorrent.embeddedTracker.enable')" />
</v-col>
<v-col cols="12" class="py-0">
<v-text-field
@ -167,14 +205,17 @@ onBeforeMount(async () => {
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.async_io_threads" type="number" hide-details :label="t('settings.advanced.libtorrent.threads.asyncIoThreads')" />
<v-text-field v-model="preferenceStore.preferences!.async_io_threads" type="number" hide-details
:label="t('settings.advanced.libtorrent.threads.asyncIoThreads')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.hashing_threads" type="number" hide-details :label="t('settings.advanced.libtorrent.threads.hashingThreads')" />
<v-text-field v-model="preferenceStore.preferences!.hashing_threads" type="number" hide-details
:label="t('settings.advanced.libtorrent.threads.hashingThreads')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.file_pool_size" type="number" hide-details :label="t('settings.advanced.libtorrent.threads.filePoolSize')" />
<v-text-field v-model="preferenceStore.preferences!.file_pool_size" type="number" hide-details
:label="t('settings.advanced.libtorrent.threads.filePoolSize')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field
@ -193,7 +234,8 @@ onBeforeMount(async () => {
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.disk_cache" type="number" hide-details suffix="MiB" :label="t('settings.advanced.libtorrent.disk.diskCache')" />
<v-text-field v-model="preferenceStore.preferences!.disk_cache" type="number" hide-details suffix="MiB"
:label="t('settings.advanced.libtorrent.disk.diskCache')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field
@ -214,7 +256,8 @@ onBeforeMount(async () => {
</v-col>
<v-col cols="12" sm="4">
<v-select v-model="preferenceStore.preferences!.disk_io_type" hide-details :items="diskIoTypeOptions" :label="t('settings.advanced.libtorrent.disk.diskIoType')" />
<v-select v-model="preferenceStore.preferences!.disk_io_type" hide-details :items="diskIoTypeOptions"
:label="t('settings.advanced.libtorrent.disk.diskIoType')" />
</v-col>
<v-col cols="12" sm="4">
<v-select
@ -233,18 +276,30 @@ onBeforeMount(async () => {
</v-row>
</v-list-item>
<v-divider class="mx-10 mt-3" />
<v-divider class="mx-10 my-3" />
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.bdecode_depth_limit" type="number" hide-details
:label="t('settings.advanced.libtorrent.threads.bdecodeDepthLimit')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.bdecode_token_limit" type="number" hide-details
:label="t('settings.advanced.libtorrent.threads.bdecodeTokenLimit')" />
</v-col>
<v-col cols="12" sm="4">
<v-checkbox v-model="preferenceStore.preferences!.enable_coalesce_read_write" hide-details :label="t('settings.advanced.libtorrent.coalesceReadsWrites')" />
<v-checkbox v-model="preferenceStore.preferences!.enable_coalesce_read_write" hide-details
:label="t('settings.advanced.libtorrent.coalesceReadsWrites')" />
</v-col>
<v-col cols="12" sm="4">
<v-checkbox v-model="preferenceStore.preferences!.enable_piece_extent_affinity" hide-details :label="t('settings.advanced.libtorrent.pieceExtentAffinity')" />
<v-checkbox v-model="preferenceStore.preferences!.enable_piece_extent_affinity" hide-details
:label="t('settings.advanced.libtorrent.pieceExtentAffinity')" />
</v-col>
<v-col cols="12" sm="4">
<v-checkbox v-model="preferenceStore.preferences!.enable_upload_suggestions" hide-details :label="t('settings.advanced.libtorrent.sendUploadPieceSuggestions')" />
<v-checkbox v-model="preferenceStore.preferences!.enable_upload_suggestions" hide-details
:label="t('settings.advanced.libtorrent.sendUploadPieceSuggestions')" />
</v-col>
<v-col cols="12" sm="4">
@ -272,15 +327,29 @@ onBeforeMount(async () => {
:label="t('settings.advanced.libtorrent.sendBufferWatermarkFactor')" />
</v-col>
<v-col cols="12" sm="6">
<v-col cols="12">
<v-text-field
v-model="preferenceStore.preferences!.connection_speed"
type="number"
hide-details
:label="t('settings.advanced.libtorrent.outgoingConnectionsPerSecond')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.socket_backlog_size" type="number" hide-details :label="t('settings.advanced.libtorrent.socketBacklogSize')" />
<v-col cols="12" sm="4">
<v-text-field v-model="preferenceStore.preferences!.socket_send_buffer_size" type="number"
:label="t('settings.advanced.libtorrent.socketSendBufferSize')"
:hint="$t('settings.advanced.libtorrent.socketSendBufferSizeHint')"
suffix="kiB" />
</v-col>
<v-col cols="12" sm="4">
<v-text-field v-model="preferenceStore.preferences!.socket_receive_buffer_size" type="number"
:label="t('settings.advanced.libtorrent.socketReceiveBufferSize')"
:hint="$t('settings.advanced.libtorrent.socketReceiveBufferSizeHint')"
suffix="kiB" />
</v-col>
<v-col cols="12" sm="4">
<v-text-field v-model="preferenceStore.preferences!.socket_backlog_size" type="number" hide-details
:label="t('settings.advanced.libtorrent.socketBacklogSize')" />
</v-col>
</v-row>
</v-list-item>
@ -313,7 +382,8 @@ onBeforeMount(async () => {
:label="t('settings.advanced.libtorrent.networking.upnpLeaseDuration')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.peer_tos" type="number" hide-details :label="t('settings.advanced.libtorrent.networking.peerTos')" />
<v-text-field v-model="preferenceStore.preferences!.peer_tos" type="number" hide-details
:label="t('settings.advanced.libtorrent.networking.peerTos')" />
</v-col>
<v-col cols="12">
@ -332,7 +402,8 @@ onBeforeMount(async () => {
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.idn_support_enabled" hide-details :label="t('settings.advanced.libtorrent.security.idnSupport')" />
<v-checkbox v-model="preferenceStore.preferences!.idn_support_enabled" hide-details
:label="t('settings.advanced.libtorrent.security.idnSupport')" />
</v-col>
<v-col cols="12" sm="6">
<v-checkbox
@ -348,7 +419,8 @@ onBeforeMount(async () => {
:label="t('settings.advanced.libtorrent.security.validateHTTPSTrackerCertificate')" />
</v-col>
<v-col cols="12" sm="4">
<v-checkbox v-model="preferenceStore.preferences!.ssrf_mitigation" hide-details :label="t('settings.advanced.libtorrent.security.mitigateSSRF')" />
<v-checkbox v-model="preferenceStore.preferences!.ssrf_mitigation" hide-details
:label="t('settings.advanced.libtorrent.security.mitigateSSRF')" />
</v-col>
<v-col cols="12" sm="4">
<v-checkbox
@ -379,14 +451,17 @@ onBeforeMount(async () => {
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.announce_to_all_trackers" hide-details :label="t('settings.advanced.libtorrent.announceAllTrackers')" />
<v-checkbox v-model="preferenceStore.preferences!.announce_to_all_trackers" hide-details
:label="t('settings.advanced.libtorrent.announceAllTrackers')" />
</v-col>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.announce_to_all_tiers" hide-details :label="t('settings.advanced.libtorrent.announceAllTiers')" />
<v-checkbox v-model="preferenceStore.preferences!.announce_to_all_tiers" hide-details
:label="t('settings.advanced.libtorrent.announceAllTiers')" />
</v-col>
<v-col cols="12">
<v-text-field v-model="preferenceStore.preferences!.announce_ip" type="number" hide-details :label="t('settings.advanced.libtorrent.announceIP')" />
<v-text-field v-model="preferenceStore.preferences!.announce_ip" type="number" hide-details
:label="t('settings.advanced.libtorrent.announceIP')" />
</v-col>
<v-col cols="12" sm="6">
@ -397,11 +472,13 @@ onBeforeMount(async () => {
:label="t('settings.advanced.libtorrent.maxConcurrentHTTPAnnounces')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.stop_tracker_timeout" type="number" hide-details :label="t('settings.advanced.libtorrent.stopTrackerTimeout')" />
<v-text-field v-model="preferenceStore.preferences!.stop_tracker_timeout" type="number" hide-details
:label="t('settings.advanced.libtorrent.stopTrackerTimeout')" />
</v-col>
<v-col cols="12" sm="4">
<v-text-field v-model="preferenceStore.preferences!.peer_turnover" type="number" hide-details suffix="%" :label="t('settings.advanced.libtorrent.peerTurnover')" />
<v-text-field v-model="preferenceStore.preferences!.peer_turnover" type="number" hide-details suffix="%"
:label="t('settings.advanced.libtorrent.peerTurnover')" />
</v-col>
<v-col cols="12" sm="4">
<v-text-field
@ -421,7 +498,8 @@ onBeforeMount(async () => {
</v-col>
<v-col cols="12">
<v-text-field v-model="preferenceStore.preferences!.request_queue_size" type="number" hide-details :label="t('settings.advanced.libtorrent.requestQueueSize')" />
<v-text-field v-model="preferenceStore.preferences!.request_queue_size" type="number" hide-details
:label="t('settings.advanced.libtorrent.requestQueueSize')" />
</v-col>
</v-row>
</v-list-item>

View file

@ -0,0 +1,82 @@
<script setup lang="ts">
import { FileLogAgeType } from '@/constants/qbit/AppPreferences'
import { usePreferenceStore } from '@/stores/preferences'
const preferenceStore = usePreferenceStore()
const fileLogAgeTypeOptions = [
{ title: 'days', value: FileLogAgeType.DAYS },
{ title: 'months', value: FileLogAgeType.MONTHS },
{ title: 'years', value: FileLogAgeType.YEARS }
]
</script>
<template>
<v-list>
<v-list-subheader>{{ $t('settings.behavior.logs.subheader') }}</v-list-subheader>
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.file_log_enabled" hide-details
:label="$t('settings.behavior.logs.file_log_enabled')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.file_log_path"
:disabled="!preferenceStore.preferences!.file_log_enabled"
hide-details :label="$t('settings.behavior.logs.file_log_path')" />
</v-col>
</v-row>
</v-list-item>
<v-divider class="mx-10 my-3" />
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-checkbox v-model="preferenceStore.preferences!.file_log_backup_enabled"
:disabled="!preferenceStore.preferences!.file_log_enabled"
hide-details
:label="$t('settings.behavior.logs.file_log_backup_enabled')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.file_log_max_size"
:disabled="!preferenceStore.preferences!.file_log_enabled || !preferenceStore.preferences!.file_log_backup_enabled"
type="number"
hide-details
:label="$t('settings.behavior.logs.file_log_max_size')"
suffix="kiB" />
</v-col>
<v-col cols="6">
<v-checkbox v-model="preferenceStore.preferences!.file_log_delete_old"
:disabled="!preferenceStore.preferences!.file_log_enabled"
hide-details
:label="$t('settings.behavior.logs.file_log_delete_old')" />
</v-col>
<v-col cols="3">
<v-text-field v-model="preferenceStore.preferences!.file_log_age"
:disabled="!preferenceStore.preferences!.file_log_enabled || !preferenceStore.preferences!.file_log_delete_old"
hide-details :label="$t('settings.behavior.logs.file_log_age')" />
</v-col>
<v-col cols="3">
<v-select v-model="preferenceStore.preferences!.file_log_age_type"
:disabled="!preferenceStore.preferences!.file_log_enabled || !preferenceStore.preferences!.file_log_delete_old"
:items="fileLogAgeTypeOptions"
hide-details />
</v-col>
</v-row>
</v-list-item>
<v-divider class="mt-3" />
<v-list-item>
<v-checkbox v-model="preferenceStore.preferences!.performance_warning" hide-details
:label="$t('settings.behavior.performance_warning')" />
</v-list-item>
</v-list>
</template>
<style scoped>
</style>

View file

@ -141,6 +141,7 @@ const thenTypes = ref([
</v-col>
</v-row>
</v-list-item>
<v-list-item>
<v-row>
<v-col cols="6">
@ -151,10 +152,27 @@ const thenTypes = ref([
v-model="preferenceStore.preferences!.max_seeding_time"
:disabled="!preferenceStore.preferences!.max_seeding_time_enabled"
type="number"
hide-details
:suffix="t('units.minutes')" />
</v-col>
</v-row>
</v-list-item>
<v-list-item>
<v-row>
<v-col cols="6">
<v-checkbox v-model="preferenceStore.preferences!.max_inactive_seeding_time_enabled" hide-details :label="t('settings.bittorrent.seedLimits.whenInactiveSeedingTimeReaches')" />
</v-col>
<v-col cols="6">
<v-text-field
v-model="preferenceStore.preferences!.max_inactive_seeding_time"
:disabled="!preferenceStore.preferences!.max_inactive_seeding_time_enabled"
type="number"
:suffix="t('units.minutes')" />
</v-col>
</v-row>
</v-list-item>
<v-list-item>
<v-row>
<v-col>
@ -170,7 +188,7 @@ const thenTypes = ref([
</v-row>
</v-list-item>
<v-divider />
<v-divider class="mt-3" />
<v-list-item>
<v-checkbox v-model="preferenceStore.preferences!.add_trackers_enabled" hide-details :label="t('settings.bittorrent.autoAddTrackers')" />

View file

@ -2,18 +2,21 @@
import PasswordField from '@/components/Core/PasswordField.vue'
import { BitTorrentProtocol, ProxyType } from '@/constants/qbit/AppPreferences'
import { usePreferenceStore } from '@/stores/preferences'
import { onBeforeMount, ref, watch } from 'vue'
import { computed, onBeforeMount, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const preferenceStore = usePreferenceStore()
const proxyTypes = ref([
{ title: '(None)', value: 'none' },
{ title: 'SOCKS4', value: 'socks4' },
{ title: 'SOCKS5', value: 'socks5' },
{ title: 'HTTP', value: 'http' }
{ title: t('common.none'), value: ProxyType.NONE },
{ title: 'SOCKS4', value: ProxyType.SOCKS4 },
{ title: 'SOCKS5', value: ProxyType.SOCKS5 },
{ title: 'HTTP', value: ProxyType.HTTP }
])
const isProxyDisabled = computed(() => preferenceStore.preferences!.proxy_type === ProxyType.NONE)
const isProxySocks4 = computed(() => preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4)
const bittorrent_protocol = ref([
{ title: t('constants.bittorrentProtocols.tcp_utp'), value: BitTorrentProtocol.TCP_uTP },
{ title: t('constants.bittorrentProtocols.tcp'), value: BitTorrentProtocol.TCP },
@ -23,8 +26,6 @@ const max_conn_enabled = ref(false)
const max_conn_per_torrent_enabled = ref(false)
const max_uploads_enabled = ref(false)
const max_uploads_per_torrent_enabled = ref(false)
const proxyType = ref('none')
const proxyAuth = ref(false)
const generateRandomPort = () => {
// source: https://github.com/qbittorrent/qBittorrent/blob/d83b2a61311b0dc3bc31ee52d1b9eaac715c3cdf/src/webui/www/private/views/preferences.html#L1729-L1734
@ -32,50 +33,12 @@ const generateRandomPort = () => {
const max = 65535
preferenceStore.preferences!.listen_port = Math.floor(Math.random() * (max - min + 1) + min)
}
const updateProxyType = () => {
switch (proxyType.value) {
case 'socks5':
preferenceStore.preferences!.proxy_type = proxyAuth ? ProxyType.SOCKS5_PW : ProxyType.SOCKS5
preferenceStore.preferences!.proxy_auth_enabled = proxyAuth.value
break
case 'http':
preferenceStore.preferences!.proxy_type = proxyAuth ? ProxyType.HTTP_PW : ProxyType.HTTP
preferenceStore.preferences!.proxy_auth_enabled = proxyAuth.value
break
case 'socks4':
preferenceStore.preferences!.proxy_type = ProxyType.SOCKS4
preferenceStore.preferences!.proxy_auth_enabled = false
break
case 'none':
default:
preferenceStore.preferences!.proxy_type = ProxyType.DISABLED
preferenceStore.preferences!.proxy_auth_enabled = false
break
}
}
onBeforeMount(async () => {
max_conn_enabled.value = preferenceStore.preferences!.max_connec > 0
max_conn_per_torrent_enabled.value = preferenceStore.preferences!.max_connec_per_torrent > 0
max_uploads_enabled.value = preferenceStore.preferences!.max_uploads > 0
max_uploads_per_torrent_enabled.value = preferenceStore.preferences!.max_uploads_per_torrent > 0
switch (preferenceStore.preferences!.proxy_type) {
case ProxyType.SOCKS4:
proxyType.value = 'socks4'
break
case ProxyType.SOCKS5:
case ProxyType.SOCKS5_PW:
proxyType.value = 'socks5'
break
case ProxyType.HTTP:
case ProxyType.HTTP_PW:
proxyType.value = 'http'
break
default:
proxyType.value = 'none'
}
proxyAuth.value = preferenceStore.preferences!.proxy_auth_enabled
})
watch(
@ -102,24 +65,13 @@ watch(
preferenceStore.preferences!.max_uploads_per_torrent = newValue ? preferenceStore.preferences!.max_uploads_per_torrent : -1
}
)
watch(
() => proxyType.value,
() => {
updateProxyType()
}
)
watch(
() => proxyAuth.value,
() => {
updateProxyType()
}
)
</script>
<template>
<v-list>
<v-list-item>
<v-select v-model="preferenceStore.preferences!.bittorrent_protocol" hide-details :items="bittorrent_protocol" :label="t('settings.connection.protocol')" />
<v-select v-model="preferenceStore.preferences!.bittorrent_protocol" hide-details :items="bittorrent_protocol"
:label="t('settings.connection.protocol')" />
</v-list-item>
<v-divider class="mt-3" />
@ -128,16 +80,21 @@ watch(
<v-list-item>
<v-row>
<v-col cols="12" sm="6">
<v-text-field v-model="preferenceStore.preferences!.listen_port" type="number" hide-details :label="t('settings.connection.listeningPort.incomingConnectionPort')" />
<v-text-field v-model="preferenceStore.preferences!.listen_port" type="number" hide-details
:label="t('settings.connection.listeningPort.incomingConnectionPort')" />
</v-col>
<v-col cols="12" sm="6" class="d-flex align-center justify-center">
<v-btn color="primary" @click="generateRandomPort">{{ t('settings.connection.listeningPort.randomPort') }}</v-btn>
<v-btn color="primary" @click="generateRandomPort">{{
t('settings.connection.listeningPort.randomPort')
}}
</v-btn>
</v-col>
</v-row>
</v-list-item>
<v-list-item>
<v-checkbox v-model="preferenceStore.preferences!.upnp" hide-details :label="t('settings.connection.listeningPort.useUPnP')" />
<v-checkbox v-model="preferenceStore.preferences!.upnp" hide-details
:label="t('settings.connection.listeningPort.useUPnP')" />
</v-list-item>
<v-divider />
@ -198,19 +155,19 @@ watch(
<v-list-item>
<v-row>
<v-col cols="12" md="4">
<v-select v-model="proxyType" hide-details :items="proxyTypes" />
<v-select v-model="preferenceStore.preferences!.proxy_type" hide-details :items="proxyTypes" />
</v-col>
<v-col cols="6" md="4">
<v-text-field
v-model="preferenceStore.preferences!.proxy_ip"
:disabled="preferenceStore.preferences!.proxy_type === ProxyType.DISABLED"
:disabled="isProxyDisabled"
hide-details
:label="t('settings.connection.proxy.host')" />
</v-col>
<v-col cols="6" md="4">
<v-text-field
v-model="preferenceStore.preferences!.proxy_port"
:disabled="preferenceStore.preferences!.proxy_type === ProxyType.DISABLED"
:disabled="isProxyDisabled"
type="number"
hide-details
:label="t('settings.connection.proxy.port')" />
@ -220,26 +177,33 @@ watch(
<v-list-item>
<v-row no-gutters>
<v-col cols="12" md="4">
<v-col cols="12" sm="6" md="3">
<v-checkbox
v-model="preferenceStore.preferences!.proxy_bittorrent"
:disabled="isProxyDisabled"
hide-details
:label="t('settings.connection.proxy.bittorrent')" />
</v-col>
<v-col cols="12" sm="6" md="3">
<v-checkbox
v-model="preferenceStore.preferences!.proxy_peer_connections"
:disabled="preferenceStore.preferences!.proxy_type === ProxyType.DISABLED"
:disabled="isProxyDisabled || !preferenceStore.preferences!.proxy_bittorrent"
hide-details
:label="t('settings.connection.proxy.peerConnections')" />
</v-col>
<v-col cols="12" md="4">
<v-col cols="12" sm="6" md="3">
<v-checkbox
v-model="preferenceStore.preferences!.proxy_torrents_only"
:disabled="preferenceStore.preferences!.proxy_type === ProxyType.DISABLED || preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4"
v-model="preferenceStore.preferences!.proxy_rss"
:disabled="isProxyDisabled || isProxySocks4"
hide-details
:label="t('settings.connection.proxy.torrentOnly')" />
:label="t('settings.connection.proxy.rss')" />
</v-col>
<v-col cols="12" md="4">
<v-col cols="12" sm="6" md="3">
<v-checkbox
v-model="preferenceStore.preferences!.proxy_hostname_lookup"
:disabled="preferenceStore.preferences!.proxy_type === ProxyType.DISABLED || preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4"
v-model="preferenceStore.preferences!.proxy_misc"
:disabled="isProxyDisabled || isProxySocks4"
hide-details
:label="t('settings.connection.proxy.hostNameLookup')" />
:label="t('settings.connection.proxy.misc')" />
</v-col>
</v-row>
</v-list-item>
@ -248,19 +212,23 @@ watch(
<v-row>
<v-col cols="12">
<v-checkbox
v-model="proxyAuth"
:disabled="preferenceStore.preferences!.proxy_type === ProxyType.DISABLED || preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4"
v-model="preferenceStore.preferences!.proxy_hostname_lookup"
:disabled="isProxyDisabled || isProxySocks4"
hide-details
:label="t('settings.connection.proxy.hostNameLookup')" />
</v-col>
<v-col cols="12">
<v-checkbox
v-model="preferenceStore.preferences!.proxy_auth_enabled"
:disabled="isProxyDisabled || isProxySocks4"
hide-details
:label="t('settings.connection.proxy.auth.subtitle')" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="preferenceStore.preferences!.proxy_username"
:disabled="
preferenceStore.preferences!.proxy_type === ProxyType.DISABLED ||
preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4 ||
!preferenceStore.preferences!.proxy_auth_enabled
"
:disabled="isProxyDisabled || !preferenceStore.preferences!.proxy_auth_enabled"
dense
hide-details
:label="t('settings.connection.proxy.auth.username')" />
@ -268,16 +236,8 @@ watch(
<v-col cols="12" sm="6">
<PasswordField
v-model="preferenceStore.preferences!.proxy_password"
:hide-icon="
preferenceStore.preferences!.proxy_type === ProxyType.DISABLED ||
preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4 ||
!preferenceStore.preferences!.proxy_auth_enabled
"
:disabled="
preferenceStore.preferences!.proxy_type === ProxyType.DISABLED ||
preferenceStore.preferences!.proxy_type === ProxyType.SOCKS4 ||
!preferenceStore.preferences!.proxy_auth_enabled
"
:hide-icon="isProxyDisabled || !preferenceStore.preferences!.proxy_auth_enabled"
:disabled="isProxyDisabled || !preferenceStore.preferences!.proxy_auth_enabled"
:label="t('settings.connection.proxy.auth.password')" />
</v-col>
</v-row>
@ -291,12 +251,15 @@ watch(
<v-list-subheader>{{ t('settings.connection.ipFiltering.subheader') }}</v-list-subheader>
<v-list-item>
<v-checkbox v-model="preferenceStore.preferences!.ip_filter_enabled" hide-details :label="t('settings.connection.ipFiltering.filterPath')" />
<v-text-field v-model="preferenceStore.preferences!.ip_filter_path" :disabled="!preferenceStore.preferences!.ip_filter_enabled" hide-details />
<v-checkbox v-model="preferenceStore.preferences!.ip_filter_enabled" hide-details
:label="t('settings.connection.ipFiltering.filterPath')" />
<v-text-field v-model="preferenceStore.preferences!.ip_filter_path"
:disabled="!preferenceStore.preferences!.ip_filter_enabled" hide-details />
</v-list-item>
<v-list-item>
<v-checkbox v-model="preferenceStore.preferences!.ip_filter_trackers" hide-details :label="t('settings.connection.ipFiltering.applyToTrackers')" />
<v-checkbox v-model="preferenceStore.preferences!.ip_filter_trackers" hide-details
:label="t('settings.connection.ipFiltering.applyToTrackers')" />
</v-list-item>
<v-list-item>
@ -304,7 +267,8 @@ watch(
</v-list-item>
<v-list-item>
<v-textarea v-model="preferenceStore.preferences!.banned_IPs" auto-grow clearable persistent-hint :hint="t('settings.connection.ipFiltering.bannedIpsHint')" />
<v-textarea v-model="preferenceStore.preferences!.banned_IPs" auto-grow clearable persistent-hint
:hint="t('settings.connection.ipFiltering.bannedIpsHint')" />
</v-list-item>
</v-list>
</template>

View file

@ -149,6 +149,10 @@ const closeDeleteDialog = async () => {
<v-list-item>
<v-select v-model="preferenceStore.preferences!.torrent_content_layout" hide-details :items="contentLayoutOptions" :label="t('constants.contentLayout.title')" />
<v-checkbox v-model="preferenceStore.preferences!.add_to_top_of_queue" hide-details :label="t('settings.downloads.whenAddTorrent.addToTopOfQueue')" />
<v-checkbox v-model="preferenceStore.preferences!.merge_trackers" hide-details :label="t('settings.downloads.whenAddTorrent.mergeTrackers')" />
<v-checkbox v-model="preferenceStore.preferences!.start_paused_enabled" hide-details :label="t('settings.downloads.whenAddTorrent.doNotAutoStart')" />
<v-select v-model="preferenceStore.preferences!.torrent_stop_condition" hide-details :items="stopConditionOptions" :label="t('constants.stopCondition.title')" />

View file

@ -12,7 +12,8 @@ export enum ContentLayout {
export enum DynDnsService {
USE_DYNDNS,
USE_NOIP
USE_NOIP,
USE_NONE = -1
}
export enum Encryption {
@ -21,6 +22,12 @@ export enum Encryption {
FORCE_OFF
}
export enum FileLogAgeType {
DAYS,
MONTHS,
YEARS
}
export enum MaxRatioAction {
PAUSE_TORRENT = 0,
REMOVE_TORRENT = 1,
@ -29,18 +36,22 @@ export enum MaxRatioAction {
}
export enum ProxyType {
DISABLED = 0,
HTTP = 1,
SOCKS5 = 2,
HTTP_PW = 3,
SOCKS5_PW = 4,
SOCKS4 = 5
NONE = 'None',
SOCKS4 = 'SOCKS4',
SOCKS5 = 'SOCKS5',
HTTP = 'HTTP'
}
export enum ResumeDataStorageType {
LEGACY = 'Legacy',
SQLITE = 'SQLite'
}
export enum ScanDirsEnum {
MONITORED_FOLDER,
DEFAULT_SAVE_PATH
}
export type ScanDirs = ScanDirsEnum | string
export enum SchedulerDays {

View file

@ -1,4 +1,5 @@
<script setup lang="ts">
import Behavior from '@/components/Settings/Behavior.vue'
import { useDialogStore } from '@/stores/dialog'
import { usePreferenceStore } from '@/stores/preferences'
import { onBeforeUnmount, onMounted, ref } from 'vue'
@ -85,6 +86,7 @@ onBeforeUnmount(() => {
<v-row class="ma-0 pa-0">
<v-tabs v-model="tab" bg-color="primary" grow show-arrows>
<v-tab value="vuetorrent">{{ t('settings.tabs.vuetorrent') }}</v-tab>
<v-tab value="behavior">{{ t('settings.tabs.behavior') }}</v-tab>
<v-tab value="downloads">{{ t('settings.tabs.downloads') }}</v-tab>
<v-tab value="connection">{{ t('settings.tabs.connection') }}</v-tab>
<v-tab value="speed">{{ t('settings.tabs.speed') }}</v-tab>
@ -116,6 +118,10 @@ onBeforeUnmount(() => {
</v-window>
</v-window-item>
<v-window-item value="behavior">
<Behavior />
</v-window-item>
<v-window-item value="downloads">
<Downloads />
</v-window-item>

View file

@ -1,3 +1,4 @@
import { FileLogAgeType, ResumeDataStorageType } from '@/constants/qbit/AppPreferences'
import type {
BitTorrentProtocol,
ContentLayout,
@ -20,12 +21,8 @@ export interface NetworkInterface {
value: string
}
export interface NetworkInterface {
name: string
value: string
}
export default interface AppPreferences {
add_to_top_of_queue: boolean
/** List of trackers to add to new torrent */
add_trackers: string
/** Enable automatic adding of trackers to new torrents */
@ -53,14 +50,16 @@ export default interface AppPreferences {
auto_tmm_enabled: boolean
/** True if external program should be run after torrent has finished downloading */
autorun_enabled: boolean
/** Program path/name/arguments to run if autorun_enabled is enabled; path is separated by slashes; you can use %f and %n arguments, which will be expanded by qBittorent as path_to_torrent_file and torrent_name (from the GUI; not the .torrent file name) respectively */
autorun_program: string
/** True if external program should be run after torrent has been added */
autorun_on_torrent_added_enabled: boolean
/** Program path/name/arguments to run if autorun_on_torrent_added_enabled is enabled; path is separated by slashes; you can use %f and %n arguments, which will be expanded by qBittorent as path_to_torrent_file and torrent_name (from the GUI; not the .torrent file name) respectively */
autorun_on_torrent_added_program: string
/** Program path/name/arguments to run if autorun_enabled is enabled; path is separated by slashes; you can use %f and %n arguments, which will be expanded by qBittorent as path_to_torrent_file and torrent_name (from the GUI; not the .torrent file name) respectively */
autorun_program: string
/** List of banned IPs */
banned_IPs: string
bdecode_depth_limit: number
bdecode_token_limit: number
/** Bittorrent Protocol to use (see list of possible values below) */
bittorrent_protocol: BitTorrentProtocol
block_peers_on_privileged_ports: boolean
@ -77,6 +76,8 @@ export default interface AppPreferences {
connection_speed: number
/** IP Address to bind to. Empty String means All addresses */
current_interface_address: string
/** Current network interface name used. readonly field */
readonly current_interface_name: string
/** Network Interface used */
current_network_interface: string
/** True if DHT is enabled */
@ -124,6 +125,13 @@ export default interface AppPreferences {
export_dir: string
/** Path to directory to copy .torrent files of completed downloads to. Slashes are used as path separators */
export_dir_fin: string
file_log_age: number
file_log_age_type: FileLogAgeType
file_log_backup_enabled: boolean
file_log_delete_old: boolean
file_log_enabled: boolean
file_log_max_size: number
file_log_path: string
/** File pool size */
file_pool_size: number
hashing_threads: number
@ -176,6 +184,8 @@ export default interface AppPreferences {
max_connec: number
/** Maximum number of simultaneous connections per torrent */
max_connec_per_torrent: number
max_inactive_seeding_time: number
max_inactive_seeding_time_enabled: boolean
/** Get the global share ratio limit */
max_ratio: number
/** Action performed when a torrent reaches the maximum share ratio. See list of possible values here below. */
@ -191,6 +201,7 @@ export default interface AppPreferences {
/** Maximum number of upload slots per torrent */
max_uploads_per_torrent: number
memory_working_set_limit: number
merge_trackers: boolean
/** Maximal outgoing port (0: Disabled) */
outgoing_ports_max: number
/** Minimal outgoing port (0: Disabled) */
@ -206,17 +217,18 @@ export default interface AppPreferences {
preallocate_all: boolean
/** True proxy requires authentication; doesn't apply to SOCKS4 proxies */
proxy_auth_enabled: boolean
proxy_bittorrent: boolean
proxy_hostname_lookup: boolean
/** Proxy IP address or domain name */
proxy_ip: string
proxy_misc: boolean
/** Password for proxy authentication */
proxy_password: string
/** True if peer and web seed connections should be proxified; this option will have any effect only in qBittorent built against libtorrent version 0.16.X and higher */
proxy_peer_connections: boolean
/** Proxy port */
proxy_port: number
/** True if proxy is only used for torrents */
proxy_torrents_only: boolean
proxy_rss: boolean
/** See list of possible values here below */
proxy_type: ProxyType
/** Username for proxy authentication */
@ -232,6 +244,7 @@ export default interface AppPreferences {
request_queue_size: number
/** True resolves peer countries */
resolve_peer_countries: boolean
resume_data_storage_type: ResumeDataStorageType
/** Enable auto-downloading of torrents from the RSS feeds */
rss_auto_downloading_enabled: boolean
/** For API ≥ v2.5.1: Enable downloading of repack/proper Episodes */
@ -278,6 +291,8 @@ export default interface AppPreferences {
slow_torrent_ul_rate_threshold: number
/** Socket backlog size */
socket_backlog_size: number
socket_receive_buffer_size: number
socket_send_buffer_size: number
ssrf_mitigation: boolean
/** True if torrents should be added in a Paused state */
start_paused_enabled: boolean
@ -291,6 +306,7 @@ export default interface AppPreferences {
torrent_changed_tmm_enabled: boolean
/** Default content layout to select when adding a new torrent */
torrent_content_layout: ContentLayout
torrent_file_size_limit: number
/** Default stop condition to select when adding a new torrent */
torrent_stop_condition: StopCondition
/** Global upload speed limit in KiB/s; 0 means no limit is applied */
@ -306,6 +322,7 @@ export default interface AppPreferences {
use_category_paths_in_manual_mode: boolean
/** True if WebUI HTTPS access is enabled */
use_https: boolean
use_subcategories: boolean
/** μTP-TCP mixed mode algorithm (see list of possible values below) */
utp_tcp_mixed_mode: UtpTcpMixedMode
validate_https_tracker_certificate: boolean

View file

@ -3,7 +3,6 @@ import type { ConnectionStatus } from '@/constants/qbit'
export default interface ServerState {
alltime_dl: number
alltime_ul: number
alltime_ratio: number
average_time_queue: number
connection_status: ConnectionStatus
dht_nodes: number
@ -25,5 +24,6 @@ export default interface ServerState {
up_info_speed: number
up_rate_limit: number
use_alt_speed_limits: boolean
use_subcategories: boolean
write_cache_overload: string
}

View file

@ -1,24 +1,26 @@
import type { BasePayload } from './index'
import { ContentLayout, StopCondition } from '@/constants/qbit/AppPreferences'
export default interface AddTorrentPayload extends BasePayload {
export default interface AddTorrentPayload {
addToTopOfQueue?: boolean
/** Whether Automatic Torrent Management should be used */
autoTMM?: boolean
/** Category for the torrent */
category?: string
contentLayout?: ContentLayout
/** Cookie sent to download the .torrent file */
cookie?: string
/** Set torrent download speed limit. Unit in bytes/second */
dlLimit?: number
downloadPath?: string
/** Prioritize download first last piece. Possible values are true, false (default) */
firstLastPiecePrio?: boolean
inactiveSeedingTimeLimit?: number
/** Add torrents in the paused state. Possible values are true, false (default) */
paused?: boolean
/** Set torrent share ratio limit */
ratioLimit?: number
/** Rename torrent */
rename?: string
/** Create the root folder. Possible values are true, false, unset (default) */
root_folder?: boolean
/** Download folder */
savepath?: string
/** Set torrent seeding time limit. Unit in minutes */
@ -27,10 +29,12 @@ export default interface AddTorrentPayload extends BasePayload {
sequentialDownload?: boolean
/** Skip hash checking. Possible values are true, false (default) */
skip_checking?: boolean
stopCondition?: StopCondition
/** Tags for the torrent, split by ',' */
tags?: string
/** Set torrent upload speed limit. Unit in bytes/second */
upLimit?: number
/** URLs separated with newlines */
urls?: string
useDownloadPath?: boolean
}