While qBittorrent might be missing an unessential feature or two that uTorrent has, there is no doubt it is a lot lighter, snappier, and I can live without all the advertising. I like it...
[ Direct Link ]
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[Metadata]
Name=qBT
Author=JSMorley
Information=Skin to display torrent information from the WebUI interface for qBittorrent
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Version=Apr 23, 2016
[Variables]
; qBittorrent info you MUST set
WebUIPort=8088
PathToqBittorrent="C:\Program Files (x86)\qBittorrent\qbittorrent.exe"
;End of qBittorrent info
;Colors you can change
ListFontColor=237,242,247,255
HeaderColor=201,218,242,255
qBittorrentColor=239,219,137
;PanelColor=2,14,31,180
PanelColor=10,10,10,200
ProgressBarColor=138,168,209,255
SeparatorLineColor=150,150,150,255
GreyColor=180,180,180,255
;End of colors
;Don't change these
ProcessName=qbittorrent
WebUIURL=http://localhost:#WebUIPort#/query/torrents
BackgroundHeight=230
Bar1Calc=0
Bar2Calc=0
Bar3Calc=0
Bar4Calc=0
Bar5Calc=0
;End of [Variables]
;[Create interface]==================================================
[ListStyle]
FontColor=#ListFontColor#
FontFace=Arial
FontSize=10
StringStyle=Normal
StringAlign=LEFT
AntiAlias=1
[MeterTopBackground]
Meter=Image
SolidColor=#PanelColor#
W=545
H=25
X=0
Y=0
[MeterLabelBackground]
Group=Body
Meter=Image
SolidColor=#PanelColor#
W=545
H=30
X=0
Y=25
Hidden=1
[MeterBodyBackground]
Group=Body
Meter=Image
SolidColor=#PanelColor#
W=545
H=#BackgroundHeight#
X=0
Y=55
Hidden=1
DynamicVariables=1
[MeterTopLabel]
Meter=String
MeterStyle=ListStyle
X=5
Y=5
FontColor=#HeaderColor#
SolidColor=0,0,0,1
InlineSetting=GradientColor | 180 | #ListFontColor# ; 0.1 | #HeaderColor# ; 0.5 | #ProgressBarColor# ; 1.0
InlinePattern=.*
Text=qBT - qBittorrent
[MeterRefresh]
Meter=Image
ImageName=#@#Images\refresh.png
W=18
H=18
PreserveAspectRatio=1
X=495
Y=4
Greyscale=1
ImageTint=#HeaderColor#
ToolTipText="Refresh Skin"
LeftMouseUpAction=!Refresh
[MeterPowerButton]
Meter=Image
ImageName=#@#Images\Power.png
W=18
H=18
PreserveAspectRatio=1
X=520
Y=4
Greyscale=1
ImageTint=#HeaderColor#
[MeterHeaders]
Group=Body
Meter=String
MeterStyle=ListStyle
FontColor=#HeaderColor#
W=545
H=19
X=0
Y=25
Text=" Name | Size | DL Speed | Seeds | Status"
Hidden=1
;[Check qbittorrent process]===========================================
[MeasureProcess]
Measure=Plugin
Plugin=Process.dll
ProcessName=#ProcessName#.exe
UpdateDivider=2
IfAboveValue=0
IfAboveAction=[!EnableMeasure MeasureWebUI][!SetOption MeterPowerButton ImageTint 93,242,85,255][!SetOption MeterPowerButton ToolTipText "Close uTorrent application"][!SetOption MeterPowerButton LeftMouseUpAction """["#@#Addons\KillqBittorrent.exe"]"""]
IfBelowValue=0
IfBelowAction=[!DisableMeasure MeasureWebUI][!SetOption MeterPowerButton ImageTint #HeaderColor#][!SetOption MeterPowerButton ToolTipText "Run uTorrent application"][!SetOption MeterPowerButton LeftMouseUpAction """["#PathToqBittorrent#"]"""]
;[Get torrent info from WebUI]=====================================
[MeasureWebUI]
Group=AllMeasures
Measure=Plugin
Plugin=WebParser.dll
URL=#WebUIURL#
RegExp="(?siU)^(.*)$"
ForceReload=1
UpdateRate=2
Disabled=1
FinishAction=[!EnableMeasure MeasureLua]
;[Lua Measure]===============================================================
[MeasureLua]
Measure=Script
ScriptFile=qBittorrent.lua
maxTorrents=5
UpdateDivider=2
Disabled=1
;[Torrent Meters]=============================================================
[Meter1Name]
Group=Torrent1
Meter=String
MeterStyle=ListStyle
W=185
H=15
ClipString=1
ToolTipType=1
ToolTipIcon=#@#Images\qbittorrent.ico
X=5
Y=55
[Meter1Size]
Group=Torrent1
Meter=String
MeterStyle=ListStyle
X=201
Y=55
[Meter1DLSpeed]
Group=Torrent1
Meter=String
MeterStyle=ListStyle
X=274
Y=55
[Meter1Seeds]
Group=Torrent1
Meter=String
MeterStyle=ListStyle
X=365
Y=55
[Meter1Status]
Group=Torrent1
Meter=String
MeterStyle=ListStyle
X=436
Y=55
[Meter1Line]
Group=Torrent1
Meter=Image
SolidColor=#SeparatorLineColor#
W=507
H=1
X=5
Y=74
Hidden=1
[Measure1BarCalc]
Group=Torrent1
Measure=Calc
Formula=#Bar1Calc#
MinValue=0
MaxValue=100
DynamicVariables=1
[Meter1Bar]
Group=Torrent1
Meter=Bar
MeasureName=Measure1BarCalc
BarColor=#ProgressBarColor#
BarOrientation=Horizontal
W=507
H=3
X=5
Y=73
[Meter1Percent]
Group=Torrent1
Meter=String
MeterStyle=ListStyle
FontSize=7
StringAlign=RIGHT
X=541
Y=-4r
;=============================================
[Meter2Name]
Group=Torrent2
Meter=String
MeterStyle=ListStyle
W=185
H=15
ClipString=1
ToolTipType=1
ToolTipIcon=#@#Images\qbittorrent.ico
X=5
Y=15r
[Meter2Size]
Group=Torrent2
Meter=String
MeterStyle=ListStyle
X=201
Y=0r
[Meter2DLSpeed]
Group=Torrent2
Meter=String
MeterStyle=ListStyle
X=274
Y=0r
[Meter2Seeds]
Group=Torrent2
Meter=String
MeterStyle=ListStyle
X=365
Y=0r
[Meter2Status]
Group=Torrent2
Meter=String
MeterStyle=ListStyle
X=436
Y=0r
[Meter2Line]
Group=Torrent2
Meter=Image
SolidColor=#SeparatorLineColor#
W=507
H=1
X=5
Y=20r
Hidden=1
[Measure2BarCalc]
Group=Torrent2
Measure=Calc
Formula=#Bar2Calc#
MinValue=0
MaxValue=100
DynamicVariables=1
[Meter2Bar]
Group=Torrent2
Meter=Bar
MeasureName=Measure2BarCalc
BarColor=#ProgressBarColor#
BarOrientation=Horizontal
W=507
H=3
X=5
Y=-1r
[Meter2Percent]
Group=Torrent2
Meter=String
MeterStyle=ListStyle
FontSize=7
StringAlign=RIGHT
X=541
Y=-4r
;=============================================
[Meter3Name]
Group=Torrent3
Meter=String
MeterStyle=ListStyle
W=185
H=15
ClipString=1
ToolTipType=1
ToolTipIcon=#@#Images\qbittorrent.ico
X=5
Y=15r
[Meter3Size]
Group=Torrent3
Meter=String
MeterStyle=ListStyle
X=201
Y=0r
[Meter3DLSpeed]
Group=Torrent3
Meter=String
MeterStyle=ListStyle
X=274
Y=0r
[Meter3Seeds]
Group=Torrent3
Meter=String
MeterStyle=ListStyle
X=365
Y=0r
[Meter3Status]
Group=Torrent3
Meter=String
MeterStyle=ListStyle
X=436
Y=0r
[Meter3Line]
Group=Torrent3
Meter=Image
SolidColor=#SeparatorLineColor#
W=507
H=1
X=5
Y=20r
Hidden=1
[Measure3BarCalc]
Group=Torrent3
Measure=Calc
Formula=#Bar3Calc#
MinValue=0
MaxValue=100
DynamicVariables=1
[Meter3Bar]
Group=Torrent3
Meter=Bar
MeasureName=Measure3BarCalc
BarColor=#ProgressBarColor#
BarOrientation=Horizontal
W=507
H=3
X=5
Y=-1r
[Meter3Percent]
Group=Torrent3
Meter=String
MeterStyle=ListStyle
FontSize=7
StringAlign=RIGHT
X=541
Y=-4r
;=============================================
[Meter4Name]
Group=Torrent4
Meter=String
MeterStyle=ListStyle
W=185
H=15
ClipString=1
ToolTipType=1
ToolTipIcon=#@#Images\qbittorrent.ico
X=5
Y=15r
[Meter4Size]
Group=Torrent4
Meter=String
MeterStyle=ListStyle
X=201
Y=0r
[Meter4DLSpeed]
Group=Torrent4
Meter=String
MeterStyle=ListStyle
X=274
Y=0r
[Meter4Seeds]
Group=Torrent4
Meter=String
MeterStyle=ListStyle
X=365
Y=0r
[Meter4Status]
Group=Torrent4
Meter=String
MeterStyle=ListStyle
X=436
Y=0r
[Meter4Line]
Group=Torrent4
Meter=Image
SolidColor=#SeparatorLineColor#
W=507
H=1
X=5
Y=20r
Hidden=1
[Measure4BarCalc]
Group=Torrent4
Measure=Calc
Formula=#Bar4Calc#
MinValue=0
MaxValue=100
DynamicVariables=1
[Meter4Bar]
Group=Torrent4
Meter=Bar
MeasureName=Measure4BarCalc
BarColor=#ProgressBarColor#
BarOrientation=Horizontal
W=507
H=3
X=5
Y=-1r
[Meter4Percent]
Group=Torrent4
Meter=String
MeterStyle=ListStyle
FontSize=7
StringAlign=RIGHT
X=541
Y=-4r
;=============================================
[Meter5Name]
Group=Torrent5
Meter=String
MeterStyle=ListStyle
W=185
H=15
ClipString=1
ToolTipType=1
ToolTipIcon=#@#Images\qbittorrent.ico
X=5
Y=15r
[Meter5Size]
Group=Torrent5
Meter=String
MeterStyle=ListStyle
X=201
Y=0r
[Meter5DLSpeed]
Group=Torrent5
Meter=String
MeterStyle=ListStyle
X=274
Y=0r
[Meter5Seeds]
Group=Torrent5
Meter=String
MeterStyle=ListStyle
X=365
Y=0r
[Meter5Status]
Group=Torrent5
Meter=String
MeterStyle=ListStyle
X=436
Y=0r
[Meter5Line]
Group=Torrent5
Meter=Image
SolidColor=#SeparatorLineColor#
W=507
H=1
X=5
Y=20r
Hidden=1
[Measure5BarCalc]
Group=Torrent5
Measure=Calc
Formula=#Bar5Calc#
MinValue=0
MaxValue=100
DynamicVariables=1
[Meter5Bar]
Group=Torrent5
Meter=Bar
MeasureName=Measure5BarCalc
BarColor=#ProgressBarColor#
BarOrientation=Horizontal
W=507
H=3
X=5
Y=-1r
[Meter5Percent]
Group=Torrent5
Meter=String
MeterStyle=ListStyle
FontSize=7
StringAlign=RIGHT
X=541
Y=-4r
Code: Select all
function Initialize()
normalColor = SKIN:GetVariable('ListFontColor')
greyColor = SKIN:GetVariable('GreyColor')
maxTorrents = SELF:GetNumberOption('MaxTorrents')
runningState = SKIN:GetMeasure('MeasureProcess')
measureWebUI = SKIN:GetMeasure('MeasureWebUI')
torrentPattern = '{"added_on".-upspeed":.-}'
namePattern = '"name":"(.-)",'
sizePattern = '"size":(.-),'
speedPattern = '"dlspeed":(.-),'
progressPattern = '"progress":(.-),'
etaPattern = '"eta":(.-),'
seedsPattern = '"num_seeds":(.-),'
peersPattern = '"num_leechs":(.-),'
statePattern = '"state":"(.-)",'
end
function Update()
isRunning = runningState:GetValue()
if isRunning == 1 then
entireHTML = measureWebUI:GetStringValue()
dummyString, fullCount = string.gsub(entireHTML, torrentPattern, '')
torrentCount = (fullCount <= maxTorrents) and fullCount or maxTorrents
startPos = 0
for i = 1, torrentCount do
torrentStart, torrentEnd = string.find(entireHTML, torrentPattern, startPos)
oneTorrent = string.sub(entireHTML, torrentStart, torrentEnd)
torrentName = string.match(oneTorrent, namePattern)
torrentSize = tonumber(string.match(oneTorrent, sizePattern))
torrentSpeed = tonumber(string.match(oneTorrent, speedPattern))
torrentProgress = tonumber(string.match(oneTorrent, progressPattern))
torrentETA = tonumber(string.match(oneTorrent, etaPattern))
torrentSeeds = tonumber(string.match(oneTorrent, seedsPattern))
torrentPeers = tonumber(string.match(oneTorrent, peersPattern))
torrentState = string.match(oneTorrent, statePattern)
startPos = torrentEnd + 1
SKIN:Bang('!ShowMeterGroup', 'Torrent'..i)
SKIN:Bang('!SetOption', 'Meter'..i..'Name', 'Text', torrentName)
sizeScaled, sizeScale = AutoScale(torrentSize, 1)
SKIN:Bang('!SetOption', 'Meter'..i..'Size', 'Text', sizeScaled..' '..sizeScale)
speedScaled, speedScale = AutoScale(torrentSpeed, 1)
SKIN:Bang('!SetOption', 'Meter'..i..'DLSpeed', 'Text', speedScaled..' '..speedScale..'/s')
if torrentSpeed == 0 then
SKIN:Bang('!SetOption', 'Meter'..i..'DLSpeed', 'FontColor', greyColor)
else
SKIN:Bang('!SetOption', 'Meter'..i..'DLSpeed', 'FontColor', normalColor)
end
downloadedScaled, downloadedScale = AutoScale((torrentSize * torrentProgress), 1)
progressPercent = Round((torrentProgress * 100), 0)
SKIN:Bang('!SetOption', 'Meter'..i..'Percent', 'Text', progressPercent..'%')
SKIN:Bang('!SetVariable', 'Bar'..i..'Calc', progressPercent)
SKIN:Bang('!SetOption', 'Meter'..i..'Seeds', 'Text', torrentSeeds)
if torrentSeeds == 0 then
SKIN:Bang('!SetOption', 'Meter'..i..'Seeds', 'FontColor', greyColor)
else
SKIN:Bang('!SetOption', 'Meter'..i..'Seeds', 'FontColor', normalColor)
end
torrentState = string.gsub(torrentState, 'downloading', 'Download')
torrentState = string.gsub(torrentState, 'queued.+', 'Queued')
torrentState = string.gsub(torrentState, 'meta.+', 'Metadata')
torrentState = string.gsub(torrentState, 'stalled.+', 'Stalled')
torrentState = string.gsub(torrentState, 'paused.+', 'Paused')
torrentState = string.gsub(torrentState, 'uploading', 'Seeding')
if torrentProgress == 1 then torrentState = 'Completed' end
SKIN:Bang('!SetOption', 'Meter'..i..'Status', 'Text', torrentState)
etaFormated = FormatSeconds(torrentETA)..' remaining'
if torrentETA == 8640000 then
if torrentState == 'Completed' then
etaFormated = 'Completed'
else
etaFormated = 'Unknown'
end
end
SKIN:Bang('!SetOption', 'Meter'..i..'Name', 'ToolTipTitle', torrentName)
SKIN:Bang('!SetOption', 'Meter'..i..'Name', 'ToolTipText', 'Torrent: '..i..' of '..fullCount..'#CRLF#'..'Seeds: '..torrentSeeds..' Peers: '..torrentPeers..'#CRLF#'..'Status: '..torrentState..'#CRLF#'..'Downloaded: '..downloadedScaled..' '..downloadedScale..' of '..sizeScaled..' '..sizeScale..'#CRLF#'..'Speed '..speedScaled..' '..speedScale..'/s'..'#CRLF#'..'Estimate: '..etaFormated)
end
SKIN:Bang('!EnableMeasureGroup', 'AllMeasures')
if torrentCount == 0 then
SKIN:Bang('!HideMeterGroup', 'Body')
else
SKIN:Bang('!ShowMeterGroup', 'Body')
end
SKIN:Bang('!SetVariable', 'BackgroundHeight', tostring(torrentCount * 31))
if torrentCount < maxTorrents then
for i = torrentCount + 1, maxTorrents do
SKIN:Bang('!HideMeterGroup', 'Torrent'..i)
end
end
else
SKIN:Bang("!DisableMeasureGroup AllMeasures")
SKIN:Bang("!HideMeterGroup Body")
for i = 1, maxTorrents do
SKIN:Bang("!HideMeterGroup Torrent"..i)
end
end
return fullCount
end
function FormatSeconds(inputSeconds)
local tableWeeks = inputSeconds / 604800
local weeksRemainder = inputSeconds % 604800
local tableDays = weeksRemainder / 86400
local daysRemainder = weeksRemainder % 86400
local tableHours = daysRemainder / 3600
local hoursRemainder = daysRemainder % 3600
local tableMinutes = hoursRemainder / 60
local minutesRemainder = hoursRemainder % 60
local tableSeconds = minutesRemainder % 60
local formatTable = {}
formatTable['weeks'] = math.floor(tableWeeks)
formatTable['days'] = math.floor(tableDays)
formatTable['hours'] = math.floor(tableHours)
formatTable['mins'] = math.floor(tableMinutes)
formatTable['secs'] = math.floor(tableSeconds)
if formatTable['weeks'] == 1 then weekText = 'week' else weekText = 'weeks' end
if formatTable['days'] == 1 then dayText = 'day' else dayText = 'days' end
if formatTable['hours'] == 1 then hourText = 'hour' else hourText = 'hours' end
if formatTable['mins'] == 1 then minText = 'minute' else minText = 'minutes' end
if formatTable['secs'] == 1 then secText = 'second' else secText = 'seconds' end
if inputSeconds >= 604800 then
outputString = formatTable['weeks']..' '..weekText..' '..formatTable['days']..' '..dayText..' '..formatTable['hours']..' '..hourText..' '..formatTable['mins']..' '..minText..' '..formatTable['secs']..' '..secText
elseif inputSeconds >= 86400 then
outputString = formatTable['days']..' '..dayText..' '..formatTable['hours']..' '..hourText..' '..formatTable['mins']..' '..minText..' '..formatTable['secs']..' '..secText
elseif inputSeconds >= 3600 then
outputString = formatTable['hours']..' '..hourText..' '..formatTable['mins']..' '..minText..' '..formatTable['secs']..' '..secText
elseif inputSeconds >= 60 then
outputString = formatTable['mins']..' '..minText..' '..formatTable['secs']..' '..secText
else
outputString = formatTable['secs']..' '..secText
end
return outputString
end
function AutoScale(num, idp)
assert(tonumber(num), 'AutoScale expects a number.')
local scales = {'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'}
local places = idp or 0
local scale = ""
local scaled = 0
for i, v in ipairs(scales) do
if (num < (1024 ^ i)) or (i == #scales) then
scale = v
scaled = Round(num / 1024 ^ (i - 1), places)
break
end
end
return scaled, scale
end
function Round(num, idp)
assert(tonumber(num), 'Round expects a number.')
local mult = 10 ^ (idp or 0)
if num >= 0 then
return math.floor(num * mult + 0.5) / mult
else
return math.ceil(num * mult - 0.5) / mult
end
end