Skip to content

Instantly share code, notes, and snippets.

@briantist
Created September 11, 2012 20:35
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save briantist/3701814 to your computer and use it in GitHub Desktop.
Save briantist/3701814 to your computer and use it in GitHub Desktop.
Fixes incorrect Added On and Completed On dates in uTorrent.
#############################
# fixutdates.rb
# Fixes uTorrent added on / completed on dates
#
# by Brian Scholer
# http://www.briantist.com/
#
#############################
require 'rubygems'
require 'bencode'
require 'pp'
require 'win32ole'
require 'fileutils'
def isUtRunning?
wmi = WIN32OLE.connect("winmgmts://")
procs = wmi.ExecQuery("SELECT * FROM win32_process WHERE Name = 'utorrent.exe'")
return true if procs.Count > 0
return false
end
def yayNay(userPrompt, defaultIsYes=true)
resp = ''
rv = defaultIsYes
begin
puts "\n"
print userPrompt
if defaultIsYes then
print ' [Y/n] '
else
print ' [y/N] '
end
resp = gets
end until resp =~ /^($|[yn]|yes|no)$/i
rv = true if resp =~ /^y/i
rv = false if resp =~ /^n/i
return rv
end
def prompt(userPrompt, default=nil)
resp = ''
rv = default
begin
puts "\n"
print userPrompt
unless default.nil? or default.empty? then
print " [#{default}] "
else
print ' '
end
resp = gets
break unless resp.chomp.empty?
break unless default.nil? or default.empty?
end while true
rv = resp unless resp.chomp.empty?
return rv.chomp
end
def getResumeDat(datpath = "#{ENV['APPDATA']}\\uTorrent\\resume.dat")
default = nil
default = datpath if File.exists?(datpath)
finalpath = ''
begin
finalpath = prompt("Where is uTorrent's resume.dat file?", default)
break if File.exists?(finalpath)
puts "\"#{finalpath}\" does not exist."
end while true
return finalpath
end
def backupResumeDat(datpath)
newname = ''
begin
newname = "#{datpath}.#{Time.now.strftime("%Y-%m-%d.%H-%M-%S.bak")}"
end while File.exists?(newname)
FileUtils.cp(datpath, newname)
end
if isUtRunning? then
puts "uTorrent is still running! Close it and wait for the process to disappear before running this again."
exit -1
end
datpath = getResumeDat
print "Backing up dat file..."
backupResumeDat(datpath)
puts "complete."
print "Parsing dat file..."
q = BEncode.load_file(datpath)
puts "complete."
puts "Looking for torrents with dates in the future..."
q.each do |k, v|
next unless v.is_a?(Hash)
next unless v.has_key?('caption')
next unless v.has_key?('added_on')
next unless v.has_key?('completed_on')
cap = v['caption']
ao = v['added_on'].to_i
co = v['completed_on'].to_i
aot = Time.at(ao)
cot = Time.at(co)
if aot > Time.now or cot > Time.now then
tf = "#{File.dirname(datpath)}\\#{v['caption']}.torrent"
next unless File.exists?(tf)
tdb = BEncode.load_file(tf)
fi = tdb['info']
latest = nil
latedate = nil
if fi.has_key?('files') then
fi['files'].each do |item|
thisitem = item['path'].join("\\")
if thisitem =~ /^[[:print:]]+$/ then
thispath = File.join("#{v['path']}\\", thisitem)
thismtime = nil
next unless File.exists?(thispath)
begin
thismtime = File.mtime(thispath)
rescue
puts "`````` #{thispath.inspect}"
next
end
if thismtime.nil? or latedate.nil? or thismtime > latedate then
latest = thispath
latedate = thismtime
end
else
#~ puts "~~ #{thisitem.inspect} ~~"
end
end
if latest.nil? or latedate.nil? then
latest = v['path']
#~ next unless File.exists?(latest)
latedate = File.mtime(latest)
end
else
latest = v['path']
#~ next unless File.exists?(latest)
latedate = File.mtime(latest)
end
latecreate = File.ctime(latest)
#~ puts "-- Latest: #{latest}"
puts "Correcting #{v['caption']}"
#~ puts "--- Created: #{latecreate} => #{latecreate.to_i}"
#~ puts "--- Modified: #{latedate} => #{latedate.to_i}"
#~ puts "\n\n"
q[k]['added_on'] = latecreate.to_i
q[k]['completed_on'] = latedate.to_i
end
end
puts "Removing .fileguard"
q.delete(".fileguard")
print "Writing final result in place..."
f = File.new(datpath, "wb")
f.write(q.bencode)
f.close
puts "complete."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment