Skip to content

Commit

Permalink
完成基本功能
Browse files Browse the repository at this point in the history
  • Loading branch information
azicen committed Jun 27, 2024
1 parent 94686d8 commit 78de9d6
Show file tree
Hide file tree
Showing 10 changed files with 512 additions and 0 deletions.
20 changes: 20 additions & 0 deletions create_dev_link.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@echo off
set BASEDIR=%~dp0
set BASEDIR=%BASEDIR:~0,-1%
if [%1]==[] (
set CONFIG_DIR=C:\Users\strluck\AppData\Roaming\deluge
) else (
set CONFIG_DIR=%1
)
if not exist %CONFIG_DIR%\plugins (
echo Config dir %CONFIG_DIR% is either not a directory or is not a proper deluge config directory. Exiting
exit /b 1
)
cd %BASEDIR%
if not exist %BASEDIR%\temp (
md %BASEDIR%\temp
)
set PYTHONPATH=%BASEDIR%/temp
C:\Users\strluck\AppData\Local\Programs\Python\Python310\python.exe setup.py build develop --install-dir %BASEDIR%\temp
copy "%BASEDIR%\temp\*.egg-link" "%CONFIG_DIR%\plugins"
rd /s /q %BASEDIR%\temp
33 changes: 33 additions & 0 deletions deluge_peerbanhelperadapter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2024 azicen <[email protected]>
#
# Basic plugin template created by the Deluge Team.
#
# This file is part of PeerBanHelperAdapter and is licensed under MIT license, or later,
# with the additional special exception to link portions of this program with
# the OpenSSL library. See LICENSE for more details.
from deluge.plugins.init import PluginInitBase


class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as PluginClass

self._plugin_cls = PluginClass
super(CorePlugin, self).__init__(plugin_name)


class Gtk3UIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtk3ui import Gtk3UI as PluginClass

self._plugin_cls = PluginClass
super(Gtk3UIPlugin, self).__init__(plugin_name)


class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as PluginClass

self._plugin_cls = PluginClass
super(WebUIPlugin, self).__init__(plugin_name)
17 changes: 17 additions & 0 deletions deluge_peerbanhelperadapter/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2024 azicen <[email protected]>
#
# Basic plugin template created by the Deluge Team.
#
# This file is part of PeerBanHelperAdapter and is licensed under MIT license, or later,
# with the additional special exception to link portions of this program with
# the OpenSSL library. See LICENSE for more details.
from __future__ import unicode_literals

import os.path

from pkg_resources import resource_filename


def get_resource(filename):
return resource_filename(__package__, os.path.join("data", filename))
235 changes: 235 additions & 0 deletions deluge_peerbanhelperadapter/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2024 azicen <[email protected]>
#
# Basic plugin template created by the Deluge Team.
#
# This file is part of PeerBanHelperAdapter and is licensed under MIT license, or later,
# with the additional special exception to link portions of this program with
# the OpenSSL library. See LICENSE for more details.
from __future__ import unicode_literals

import logging

from deluge._libtorrent import lt
import deluge.component as component
from deluge.core.filtermanager import FilterManager
from deluge.core.torrentmanager import TorrentManager
import deluge.configmanager
from deluge.core.rpcserver import export
from deluge.plugins.pluginbase import CorePluginBase
from deluge.common import decode_bytes

log = logging.getLogger(__name__)

DEFAULT_PREFS = {
"blocklist": [],
}


class Core(CorePluginBase):
filtermanager: FilterManager = None
torrentmanager: TorrentManager = None

blocklist: set[str] = set()

def enable(self):
log.debug("PeerBanHelperAdapter: Plugin enabled...")

# 获取 libtorrent.session
self.session = component.get("Core").session
# 获取 deluge.core.filtermanager.FilterManager 实例
self.filtermanager = component.get("FilterManager")
# 获取 deluge.core.torrentmanager.TorrentManager 实例
self.torrentmanager = component.get("TorrentManager")

self.config = deluge.configmanager.ConfigManager(
"peerbanhelper_adapter.conf", DEFAULT_PREFS
)

if "blocklist" not in self.config:
self.config["blocklist"] = []

self.blocklist = set(self.config["blocklist"])

# 恢复 blocklist
ip_filter = self.session.get_ip_filter()
for ip in self.blocklist:
ip_filter.add_rule(ip, ip, 1)
self.session.set_ip_filter(ip_filter)

def disable(self):
self.config["blocklist"] = list(self.blocklist)
self.config.save()

def update(self):
pass

@export
def set_config(self, config):
"""Sets the config dictionary"""
for key in config:
self.config[key] = config[key]
self.config.save()

@export
def get_config(self):
"""Returns the config dictionary"""
status = {}
status["blocklist"] = self.blocklist
return status

@export
def get_active_torrents_info(self):
"""返回活跃种子的列表"""

# 获取活跃的种子列表
filter_dict = {}
filter_dict["state"] = ["Active"]
torrent_ids = self.filtermanager.filter_torrent_ids(filter_dict)

infos = []

for torrent_id in torrent_ids:
info = {}
torrent = self.torrentmanager[torrent_id]
info["id"] = torrent_id
info["name"] = torrent.get_name()
info["info_hash"] = torrent_id
info["progress"] = torrent.get_progress()
info["size"] = torrent.status.total_wanted
info["upload_payload_rate"] = torrent.status.upload_payload_rate
info["download_payload_rate"] = torrent.status.download_payload_rate
peers = torrent.handle.get_peer_info()
peer_infos = []
for peer in peers:
log.debug("peer_id: %s", str(peer.pid))
# 必须排除半连接状态节点,否则可能进入等待阻塞
if peer.flags & peer.connecting or peer.flags & peer.handshake:
continue
try:
client_name = decode_bytes(peer.client)
except UnicodeDecodeError:
client_name = "unknown"

peer_info = {
"ip": peer.ip[0],
"port": peer.ip[1],
"peer_id": str(peer.pid),
"client_name": client_name,
"up_speed": peer.up_speed, # 上传速度
"down_speed": peer.down_speed, # 下载速度
"payload_up_speed": peer.payload_up_speed, # 有效上传速度
"payload_down_speed": peer.payload_down_speed, # 有效下载速度
"total_upload": peer.total_upload, # 上传量
"total_download": peer.total_download, # 下载量
"progress": peer.progress, # 进度
"flags": peer.flags,
"source": peer.source,
"local_endpoint_ip": peer.local_endpoint[0],
"local_endpoint_port": peer.local_endpoint[1],
"queue_bytes": peer.queue_bytes, # 队列字节数
"request_timeout": peer.request_timeout, # 请求超时
"num_hashfails": peer.num_hashfails, # 哈希失败次数
"download_queue_length": peer.download_queue_length, # 下载队列长度
"upload_queue_length": peer.upload_queue_length, # 上传队列长度
"failcount": peer.failcount, # 失败次数
"downloading_block_index": peer.downloading_block_index, # 下载块索引
"downloading_progress": peer.downloading_progress, # 下载进度
"downloading_total": peer.downloading_total, # 下载总量
"connection_type": peer.connection_type, # 连接类型
"send_quota": peer.send_quota, # 发送配额
"receive_quota": peer.receive_quota, # 接收配额
"rtt": peer.rtt, # 往返时间
"num_pieces": peer.num_pieces, # 块数
"download_rate_peak": peer.download_rate_peak, # 下载速率峰值
"upload_rate_peak": peer.upload_rate_peak, # 上传速率峰值
"progress_ppm": peer.progress_ppm, # 进度每分钟百分比
}

peer_infos.append(peer_info)

info["peers"] = peer_infos
infos.append(info)

return infos

@export
def get_blocklist(self):
"""目前被封禁的所有 IP 列表"""
result = {
"size": len(self.blocklist),
"ips": list(self.blocklist),
}
return result

@export
def replace_blocklist(self, ips):
"""全量更新 IP 封禁列表
Args:
ips (list[str]): 需要封禁的所有 IP 列表
"""
pend_ips = set(ips)
# 重新构建 IP 过滤器
ip_filter = lt.ip_filter()
for ip in pend_ips:
ip_filter.add_rule(ip, ip, 1)

# 更新 LT
self.session.set_ip_filter(ip_filter)

self.blocklist.clear()
self.blocklist.update(pend_ips)
return {}

@export
def ban_ips(self, ips):
"""增量封禁 IP
Args:
ips (list[str]): 需要封禁的 IP 列表
"""
# 待处理的 ip
pend_ips = set()
for ip in ips:
if ip not in self.blocklist:
pend_ips.add(ip)

if len(pend_ips) == 0:
return {}

ip_filter = self.session.get_ip_filter()
for ip in pend_ips:
ip_filter.add_rule(ip, ip, 1) # 1 阻止通过

self.session.set_ip_filter(ip_filter)

self.blocklist.update(pend_ips)
return {}

@export
def unban_ips(self, ips):
"""增量解禁 IP
Args:
ips (list[str]): 需要解禁的 IP 列表
"""
# 待处理的 ip
pend_ips = set()
for ip in ips:
if ip in self.blocklist:
pend_ips.add(ip)

if len(pend_ips) == 0:
return {}

ip_filter = self.session.get_ip_filter()
for ip in pend_ips:
ip_filter.add_rule(ip, ip, 0) # 0 允许通过,后置规则覆盖

self.session.set_ip_filter(ip_filter)

for ip in pend_ips:
if ip in self.blocklist:
self.blocklist.remove(ip)
return {}
40 changes: 40 additions & 0 deletions deluge_peerbanhelperadapter/data/config.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkWindow" id="window1">
<child>
<object class="GtkBox" id="prefs_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="blocklist_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkTextView" id="text_blocklist">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child type="label">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Blocklist&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
30 changes: 30 additions & 0 deletions deluge_peerbanhelperadapter/data/peerbanhelperadapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Script: peerbanhelperadapter.js
* The client-side javascript code for the PeerBanHelperAdapter plugin.
*
* Copyright:
* (C) azicen 2024 <[email protected]>
*
* This file is part of PeerBanHelperAdapter and is licensed under MIT license, or
* later, with the additional special exception to link portions of this
* program with the OpenSSL library. See LICENSE for more details.
*/

PeerBanHelperAdapterPlugin = Ext.extend(Deluge.Plugin, {
constructor: function(config) {
config = Ext.apply({
name: 'PeerBanHelperAdapter'
}, config);
PeerBanHelperAdapterPlugin.superclass.constructor.call(this, config);
},

onDisable: function() {
deluge.preferences.removePage(this.prefsPage);
},

onEnable: function() {
this.prefsPage = deluge.preferences.addPage(
new Deluge.ux.preferences.PeerBanHelperAdapterPage());
}
});
new PeerBanHelperAdapterPlugin();
Loading

0 comments on commit 78de9d6

Please sign in to comment.