我需要编写一个脚本来确定 uTorrent 当前是否正在下载某些内容。我宁愿它只是下载,但如果我无法区分下载和上传,那么总比什么都没有好。
一种可能的方法是检查是否有以 结尾的文件.!ut
被锁定 - 但我希望有更优雅的方法。
我选择的武器是 VBScript,但如果需要的话,我很乐意使用命令行。
答案1
这是一段 VBScript,它将连接到 uTorrent 网络服务器并确定是否有任何内容正在下载。它将显示一个带有相应消息的弹出窗口。
需要注意的几点:
- 您需要在 uTorrent 偏好设置中启用“Web UI”并设置用户名和密码。
- 然后,您需要修改此代码中的
utServer
、utUSERNAME
和 ,utPASSWORD
将其更改为正确的位置和凭据以登录。utSERVER
代码中的示例值连接到本地计算机 (127.0.0.1) 的端口 8080。 - uTorrent 需要初始调用以获取所有后续请求的有效令牌。该令牌存储在 中
utToken
。您无需担心,只需Request_uTorrent
使用正确的 URL 调用,它就会确定是否需要令牌请求/刷新。 - “主动下载”是指 ETA 大于 0 秒且未播种的下载。如果 ETA 无限长,则视为未下载。
- 在 VBScript 中解析 JSON 是可能的,但并不容易(来源)。此代码使用一些字符串操作将结果获取为 CSV,然后以此方式进行解析。
- 此代码不太擅长处理 uTorrent 未运行或不接受 Web UI 连接时导致的错误。当前的解决方案是使用粗暴的
On Error Resume Next
,但这确实应该清理。 - 如果没有令牌,则请求令牌,获取令牌,再次发出第一个请求,并且(出于某种原因)令牌无效,代码可能会陷入循环。我不确定这种情况有多大可能,但由于任何事情都可能轻易(意外地)修改,因此
utToken
可能会发生这种情况。您可能希望修改这一点,以便如果令牌第二次失败,它就会被保释。 - 提取 token 是一件要么全有要么全无的事情。如果失败,代码就会退出。这在调试时没有什么帮助。
将以下内容保存为check_downloading.vbs
并双击运行:
Option Explicit
' Configuration settings
' utSERVER = The IP address and port of the uTorrent server
' utUSERNAME = The username
' utPASSWORD = The password
Const utSERVER = "127.0.0.1:8080"
Const utUSERNAME = "yourusername"
Const utPASSWORD = "yourpassword"
Dim utToken ' Required for the uTorrent token
' == Code starts here ==
If Is_Downloading = True Then
Msgbox "Something is downloading"
Else
Msgbox "Nothing is downloading"
End If
WScript.Quit
' Is_Downloading
' Connects to uTorrent and checks to see if anything is currently downloading.
' Returns True if there is. Note: A file with an infinite ETA is considered not
' downloading.
Function Is_Downloading
Dim sContent, sItem, sLines, token
' Get a list of the torrents from uTorrent
sContent = Request_uTorrent("list=1")
' Parsing JSON isn't the easiest in VBScript, so we make some
' simple changes to the output and it looks like comma seperated
' values.
For Each sItem In Split(sContent, VbLf)
If Left(sItem, 2) = "[""" Then
' Remove spaces and the first ["
sItem = Trim(sItem) : sItem = Right(sItem, Len(sItem)-1)
' Remove the ends of lines finishing with either ]], or ],
If Right(sItem, 3) = "]]," Then sItem = Left(sItem, Len(sItem)-3)
If Right(sItem, 2) = "]," Then sItem = Left(sItem, Len(sItem)-2)
' Extract the values from the line
token = Process_CSV_Line(sItem)
' Format of the token array is:
' 0 = HASH (string),
' 1 = STATUS* (integer),
' 2 = NAME (string),
' 3 = SIZE (integer in bytes),
' 4 = PERCENT PROGRESS (integer in per mils),
' 5 = DOWNLOADED (integer in bytes),
' 6 = UPLOADED (integer in bytes),
' 7 = RATIO (integer in per mils),
' 8 = UPLOAD SPEED (integer in bytes per second),
' 9 = DOWNLOAD SPEED (integer in bytes per second),
' 10 = ETA (integer in seconds),
' 11 = LABEL (string),
' 12 = PEERS CONNECTED (integer),
' 13 = PEERS IN SWARM (integer),
' 14 = SEEDS CONNECTED (integer),
' 15 = SEEDS IN SWARM (integer),
' 16 = AVAILABILITY (integer in 1/65535ths),
' 17 = TORRENT QUEUE ORDER (integer),
' 18 = REMAINING (integer in bytes)
' The ETA (token 10) can have three values:
' -1 = The download has stalled (reported as "infinite" in the UI)
' 0 = The download has completed.
' >0 = The number of seconds left.
'
' However, the ETA also includes seeding so we need to also ensure that the percentage
' complete is less than 1000 (100%).
If IsNumeric(token(10)) And CLng(token(10)) > 0 And IsNumeric(token(4)) And CLng(token(4)) < 1000 Then
Is_Downloading = True
Exit Function
End If
End If
Next
Is_Downloading = False
End Function
' Process_CSV_Line
' Given a string, split it up into an array using the comma as the delimiter. Take into account
' that a comma inside a quote should be ignored.
Function Process_CSV_Line(sString)
Redim csv(0)
Dim iIndex : iIndex = 0
Dim bInQuote, i : bInQuote = False
For i = 1 To Len(sString)
Dim sChar : sChar = Mid(sString, i, 1)
If sChar = """" Then
bInQuote = Not bInQuote
sChar = ""
End If
If sChar = "," And Not bInQuote Then
iIndex = iIndex + 1
Redim Preserve csv(iIndex)
csv(iIndex) = ""
Else
csv(iIndex) = csv(iIndex) & sChar
End If
Next
Process_CSV_Line = csv
End Function
' Request_uTorrent
' Given a URL, append the token and download the page from uTorrent
Function Request_uTorrent(sURL)
Dim sAddress
If utToken <> "" Then
' We have a token
sAddress = "http://" & utSERVER & "/gui/?" & sURL & "&token=" & utToken
ElseIf sURL <> "token.html" Then
Call Get_uTorrent_Token
Request_uTorrent = Request_uTorrent(sURL)
Exit Function
Else
sAddress = "http://" & utSERVER & "/gui/token.html"
End If
' Error handling is required in case uTorrent isn't running. This approach works, but could be much better.
On Error Resume Next
Dim oWeb : Set oWeb = CreateObject("MSXML2.XMLHTTP")
oWeb.Open "GET", sAddress, False, utUSERNAME, utPASSWORD
oWeb.Send
Request_uTorrent = oWeb.ResponseText
On Error Goto 0
Set oWeb = Nothing
' If we get an "invalid request" then the token is out of date
If Request_uTorrent = vbcrlf & "invalid request" Then
Call Get_uTorrent_Token
Request_uTorrent = Request_uTorrent(sURL)
Exit Function
End If
End Function
' Get_uTorrent_Token
' Connects to token.html on the uTorrent webserver to get a token that enables
' further API calls to be made. Called automatically by Request_uTorrent although
' can be called manually if performance is critical (reduces the calls by 1).
Sub Get_uTorrent_Token
utToken = ""
Dim sResponse : sResponse = Request_uTorrent("token.html")
Dim re : Set re = New RegExp
re.IgnoreCase = True
re.Global = True
re.Pattern = "<div.+?>(.+?)<\/div>"
Dim m : Set m = re.Execute(sResponse)
If m.Count > 0 Then
utToken = m(0).SubMatches(0)
Else
' Unable to extract token. Bail.
WScript.Quit
End If
Set m = Nothing
Set re = Nothing
End Sub
答案2
为了详细说明iglvzx的评论,您可以使用uTorrent的Web API来获取活跃种子列表。要使用 API,您只需在设置中启用它。然后,这是一个简单的 HTTP GET 调用 - 如果您的脚本在同一台机器上运行,则可以发送到本地主机。