The following code works but is a mess. But being totally new to Ruby I have had big problems trying to refactor it into something resembling clean OOP code. Could you help with this and explain what you are doing?
require 'nokogiri'
require 'open-uri'
require_relative 'db.rb' # Not used
require 'mechanize'
require 'digest/md5'
require 'colorize'
require 'win32console'
# Get the Base URL for Groups
# baseURL = '<some site>'
# The Initial Search Point for Groups
#Base URL
baseURL = '<some site>'
pageURL = '<some site>'
doc = Nokogiri::HTML(open(pageURL))
# Search for nodes by css
pages = doc.css('.pages')
thumbs = doc.css('.thumb')
startingPages = pages.css('a').first.text
totalPages = pages.css('a').last.text.to_i
currentPage = 1
## DO THE FIRST PAGE
thumbs.each do |thumb|
imgSrc = thumb.css('.t_img').first['src']
file = open(imgSrc).read.unpack('H*').first
agent = Mechanize.new
image = agent.get(imgSrc)
md = Digest::MD5.hexdigest(*[file.to_s])
sha = Digest::SHA2.hexdigest(*[file.to_s])
title = thumb.css('.t_img').first['alt']
fileType = image.header["content-type"].to_s
lastModified = image.header["last-modified"].to_s
fileSize = image.header["content-length"].to_s
driver = "Prowler"
source = $pagesPath.to_s
binary = file
fileName = image.filename
# ||, -, *, /, <>, <, >, ,(comma), =, <=, >=, ~=, !=, ^=, (, ) Illegal characters for sql queries. Check title for these before inserting into the database
title = title.gsub("'", "")
begin
# connect to the MySQL server
dbh = DBI.connect('dbi:ODBC:DamoclesProwler', 'user', 'pw')
sqlText = "INSERT INTO prowlerRunningResults(ProwlerDriver, SourceURL, Title, DestinationURL, FileSource, FileType, FileName, LastModified, FileSize, HashMD5, HashSHA256, ImageBinary)
VALUES ('#{driver}', '#{source}', '#{title}', 'NA', '#{imgSrc}', '#{fileType}', '#{fileName}', '#{lastModified}', #{fileSize.to_i}, '#{md}', '#{sha}', '#{binary}' )"
dbh.do( sqlText )
puts "Record has been created for".green + "\t" + sha.yellow
dbh.commit
rescue DBI::DatabaseError => e
if(e.errstr == "23000 (3604) [Microsoft][ODBC SQL Server Driver][SQL Server]Duplicate key was ignored.")
puts "Ignoring Duplicate File".cyan
else
puts "An error occurred".red
puts "Error code: #{e.err}".red
puts "Error message: #{e.errstr}".red
# check update first
dbh.rollback
end
ensure
# disconnect from server
dbh.disconnect if dbh
end
end
puts "--------------------------PAGE 1-----------------------------------"
(2..totalPages-1).each do |k|
$pagesPath = URI.join(baseURL, "/category/0/All/ctr/" + k.to_s + "/")
rdoc = Nokogiri::HTML(open($pagesPath))
tthumbs = rdoc.css('.thumb')
tthumbs.each do |mthumb|
title = mthumb.css('.t_img').first['alt']
imgSrc = mthumb.css('.t_img').first['src']
file = "0x" + open(imgSrc).read.unpack('H*').first
agent = Mechanize.new
fop = agent.get(imgSrc)
md = Digest::MD5.hexdigest(*[file.to_s])
sha = Digest::SHA2.hexdigest(*[file.to_s])
fileType = agent.head(imgSrc)["content-type"].to_s
lastModified = agent.head(imgSrc)["last-modified"].to_s
fileSize = agent.head(imgSrc)["content-length"].to_s
driver = "Prowler"
source = $pagesPath.to_s
binary = file
fileName = fop.filename
title = title.gsub("'", "")
begin
# connect to the MySQL server
dbh = DBI.connect('dbi:ODBC:DamoclesProwler', 'user', 'pw')
sqlText = "INSERT INTO prowlerRunningResults(ProwlerDriver, SourceURL, Title, DestinationURL, FileSource, FileType, FileName, LastModified, FileSize, HashMD5, HashSHA256, ImageBinary)
VALUES ('#{driver}', '#{source}', '#{title}', 'NA', '#{imgSrc}', '#{fileType}', '#{fileName}', '#{lastModified}', #{fileSize.to_i}, '#{md}', '#{sha}', '#{binary}' )"
dbh.do( sqlText )
puts "Record has been created for".green + "\t" + sha.yellow
dbh.commit
rescue DBI::DatabaseError => e
if(e.errstr == "23000 (3604) [Microsoft][ODBC SQL Server Driver][SQL Server]Duplicate key was ignored.")
puts "Ignoring Duplicate File".cyan
else
puts "An error occurred".red
puts "Error code: #{e.err}".red
puts "Error message: #{e.errstr}".red
# check update first
dbh.rollback
end
ensure
# disconnect from server
dbh.disconnect if dbh
end
end
puts "-----------------------------PAGE #{k.to_s}------------------------------------"
sleep(2)
end
I would normally, in other languages, have the Database code in a separate file. How would I do that in Ruby, and what else in Ruby is there that I should be doing?
The code goes to a website - hardcoded Loads the site into doc which is then parsed using nokogiri. The pagination for the site is loaded into pages so that we can work out how many pages we are going to process... this is the link at the top or bottom of the page with something like goto: page 1, 2, 3, 4, ... 600. next the page looks for any images on the page - thumbs (thumbnails) with the code put into thumbs variable. Next the first page is processed...
- go through each thumbnail
- Get its location
- download the file
- Hash it
- Get info like size, name, type
- Save the info and file into the database
- Repeat the process for pages 2 .. lastpage
each do
. \$\endgroup\$