feat: Add/Ban peers support (#598) @Larsluph

This commit is contained in:
Rémi Marseault 2023-01-09 09:11:13 +01:00 committed by GitHub
parent 004c8f57d2
commit 59b47dbc8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 47 deletions

View file

@ -1,33 +1,61 @@
<template>
<v-card flat>
<v-data-table v-if="peers" dense :headers="headers" :items="peers" :items-per-page="-1" :hide-default-footer="true" mobile-breakpoint="0">
<template #item="row">
<tr>
<td class="ip">
<template v-if="row.item.country_code">
<img v-if="isWindows" class="country-flag" :title="row.item.country" :alt="codeToFlag(row.item.country_code).char" :src="codeToFlag(row.item.country_code).url" />
<template v-else>
{{ codeToFlag(row.item.country_code).char }}
<v-card-text class="pa-0">
<v-data-table v-if="peers" v-model="selectedPeers" dense show-select :headers="headers" :items="peers" :items-per-page="-1" item-key="key" mobile-breakpoint="0">
<template #body="{ items }">
<tbody>
<tr v-for="item in items" :key="item.key">
<td>
<v-checkbox v-model="selectedPeers" :value="item.key" hide-details class="pa-0 ma-0" color="accent" />
</td>
<td class="ip">
<template v-if="item.country_code">
<img v-if="isWindows" class="country-flag" :title="item.country" :alt="codeToFlag(item.country_code).char" :src="codeToFlag(item.country_code).url" />
<template v-else>
{{ codeToFlag(item.country_code).char }}
</template>
</template>
</template>
{{ row.item.ip }}
<span class="grey--text">:{{ row.item.port }}</span>
</td>
<td>{{ row.item.connection }}</td>
<td :title="row.item.flags_desc">
{{ row.item.flags }}
</td>
<td>{{ row.item.client }}</td>
<td>{{ row.item.progress | progress }}</td>
<td>{{ row.item.dl_speed | networkSpeed }}</td>
<td>{{ row.item.downloaded | networkSize }}</td>
<td>{{ row.item.up_speed | networkSpeed }}</td>
<td>{{ row.item.uploaded | networkSize }}</td>
<td>{{ row.item.relevance | progress }}</td>
<td>{{ row.item.files }}</td>
</tr>
</template>
</v-data-table>
{{ item.ip }}
<span class="grey--text">:{{ item.port }}</span>
</td>
<td>{{ item.connection }}</td>
<td :title="item.flags_desc">
{{ item.flags }}
</td>
<td>{{ item.client }}</td>
<td>{{ item.progress | progress }}</td>
<td>{{ item.dl_speed | networkSpeed }}</td>
<td>{{ item.downloaded | networkSize }}</td>
<td>{{ item.up_speed | networkSpeed }}</td>
<td>{{ item.uploaded | networkSize }}</td>
<td>{{ item.relevance | progress }}</td>
<td>{{ item.files }}</td>
</tr>
</tbody>
</template>
</v-data-table>
</v-card-text>
<v-card-actions class="justify-center">
<v-btn class="error white--text elevation-0 px-4 mx-2" @click="banPeers">Ban</v-btn>
<v-dialog v-model="peersDialog" content-class="rounded-form" persistent max-width="290">
<template #activator="{ on, attrs }">
<v-btn class="accent white--text elevation-0 px-4 mx-2" v-bind="attrs" v-on="on">Add</v-btn>
</template>
<v-card>
<v-card-title class="justify-center">
<h3>Add Peers</h3>
</v-card-title>
<v-card-text>
<v-textarea v-model="newPeers" label="Peers" rows="1" required autofocus auto-grow clearable hint="One link per line" />
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="red darken-1" text @click="closeAddPeers">Cancel</v-btn>
<v-btn color="green darken-1" text @click="addPeers">Add</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-card-actions>
</v-card>
</template>
@ -42,8 +70,11 @@ export default {
mixins: [FullScreenModal],
props: { hash: String, isActive: Boolean },
data: () => ({
peersDialog: false,
refreshTimer: '',
peersObj: null
peersObj: null,
newPeers: '',
selectedPeers: []
}),
computed: {
rid: {
@ -64,10 +95,7 @@ export default {
{ text: this.$i18n.t('modals.detail.pagePeers.flags'), value: 'flags' },
{ text: this.$i18n.t('modals.detail.pagePeers.client'), value: 'client' },
{ text: this.$i18n.t('modals.detail.pagePeers.progress'), value: 'progress' },
{
text: this.$i18n.t('modals.detail.pagePeers.downloadSpeed'),
value: 'dl_speed'
},
{ text: this.$i18n.t('modals.detail.pagePeers.downloadSpeed'), value: 'dl_speed' },
{ text: this.$i18n.t('modals.detail.pagePeers.downloaded'), value: 'downloaded' },
{ text: this.$i18n.t('modals.detail.pagePeers.upSpeed'), value: 'up_speed' },
{ text: this.$i18n.t('modals.detail.pagePeers.uploaded'), value: 'uploaded' },
@ -83,9 +111,7 @@ export default {
this.refreshTimer = setInterval(
function () {
this.getTorrentPeers()
}.bind(this),
2000
)
}.bind(this), 2000)
} else {
clearTimeout(this.refreshTimer)
}
@ -106,6 +132,28 @@ export default {
this.rid = data.rid
this.peersObj = data.peers
},
async addPeers() {
if (this.newPeers.length === 0) {
this.peersDialog = false
return
}
qbit.addTorrentPeers([this.hash], this.newPeers.split('\n'))
this.newPeers = ''
await this.getTorrentPeers()
this.peersDialog = false
},
closeAddPeers() {
this.newPeers = ''
this.peersDialog = false
},
async banPeers() {
if (this.selectedPeers.length === 0) return
qbit.banPeers(this.selectedPeers)
this.selectedPeers = []
await this.getTorrentPeers()
}
}
}

View file

@ -6,7 +6,7 @@
<tbody>
<tr v-for="item in items" :key="item.url">
<td>
<v-checkbox v-if="typeof item.tier === 'number'" v-model="selectedTrackers" :value="item" hide-details class="pa-0 ma-0" color="accent" />
<v-checkbox v-if="item.isSelectable" v-model="selectedTrackers" :value="item" hide-details class="pa-0 ma-0" color="accent" />
</td>
<td>{{ item.tier }}</td>
<td>{{ item.url }}</td>
@ -22,10 +22,10 @@
</v-data-table>
</v-card-text>
<v-card-actions class="justify-center">
<v-btn class="error white--text elevation-0 px-4 mx-2" @click="DeleteTrackers"> Delete </v-btn>
<v-btn class="error white--text elevation-0 px-4 mx-2" @click="DeleteTrackers">Delete</v-btn>
<v-dialog v-model="trackerDialog" content-class="rounded-form" persistent max-width="290">
<template #activator="{ on, attrs }">
<v-btn class="accent white--text elevation-0 px-4 mx-2" v-bind="attrs" v-on="on"> Add </v-btn>
<v-btn class="accent white--text elevation-0 px-4 mx-2" v-bind="attrs" v-on="on">Add</v-btn>
</template>
<v-card>
<v-card-title class="justify-center">
@ -76,7 +76,7 @@ export default {
trackers() {
return this.tempTrackers.map(x => ({
...x,
isSelectable: typeof x.tier === 'number'
isSelectable: x.tier >= 0
}))
},
headers() {
@ -86,14 +86,8 @@ export default {
{ text: this.$i18n.t('modals.detail.pageTrackers.status'), value: 'status' },
{ text: this.$i18n.t('modals.detail.pageTrackers.peers'), value: 'num_peers' },
{ text: this.$i18n.t('modals.detail.pageTrackers.seeds'), value: 'num_seeds' },
{
text: this.$i18n.t('modals.detail.pageTrackers.leeches'),
value: 'num_leeches'
},
{
text: this.$i18n.t('modals.detail.pageTrackers.downloaded'),
value: 'num_downloaded'
},
{ text: this.$i18n.t('modals.detail.pageTrackers.leeches'), value: 'num_leeches' },
{ text: this.$i18n.t('modals.detail.pageTrackers.downloaded'), value: 'num_downloaded' },
{ text: this.$i18n.t('modals.detail.pageTrackers.message'), value: 'msg' }
]
}

View file

@ -346,6 +346,23 @@ export class QBitApi {
return this.execute('post', '/torrents/removeTrackers', params)
}
addTorrentPeers(hashes: Array<string>, peers: Array<string>) {
const params = {
hashes: hashes.join('|'),
peers: peers.join('|')
}
return this.execute('post', '/torrents/addPeers', params)
}
banPeers(peers: Array<string>) {
const params = {
peers: peers.join('|')
}
return this.execute('post', '/transfer/banPeers', params)
}
torrentAction(action, hashes, extra) {
const params = {
hashes: hashes.length ? hashes.join('|') : 'all',