Adding users from a text file into active directoy - ruby

I've been working on this code for ages and I can't get it working. It takes user information form a text file, creates user groups and puts the users in the groups. It makes the security group just fine, but it does not put the users in the groups. There is no error message but after going through the error checking is goes through the code that should add the user and puts the error at the bottom. Can anyone help please?
The usernames in the text file are setup like so:
fred,bush,1990-20-3,123456781,2008-20-3,D5,
xin,zhao,1990-20-2,123456782,2008-20-3,D5,
bobby,bob,1990-20-1,123456783,2008-20-3,D5,
john,lose,1990-20-4,123456784,2008-20-3,D5,
elly,moose,1990-20-5,123456785,2008-20-3,D5,
jackie,chan,1990-20-6,123456786,2008-20-3,D5,
katarina,lotus,1990-20-7,123456787,2008-20-3,D5,
kelly,nunu,1990-20-8,123456788,2008-20-3,D5,
lois,harris,1990-20-9,123456789,2008-20-3,D5,
gutwold,manly,1990-20-10,123456780,2008-20-3,D5,
griswold,womenly,1990-20-11,123456710,2008-20-3,D5,
bessy,horse,1990-20-12,123456711,2008-20-3,D5,
And the code is:
require 'date'
domain = "dc=TROPTRAIN,dc=net,dc=au"
ou = "ou=studentsOU"
filepath = 'C:\Documents and Settings\Administrator\My Documents\Luke Abbey Ruby Final\userfile\error_log.txt'
users = 'C:\Documents and Settings\Administrator\My Documents\Luke Abbey Ruby Final\userfile\newusers.txt'
#intro function for the program
def intro
system "cls"
puts ""
puts " Tropical Train - Adding users"
puts "====================================================================="
puts ""
end
#get user file
check = 0
while check == 0
intro
puts "Please enter the path to the user file,"
puts "or enter the the letter 's' to use the stored file location:"
puts ""
puts "#{users}"
userfile = gets.chomp.to_s
if ((userfile == 's') || (userfile == 'S'))
check = 1
userfile = users
#puts userfile
#system "pause"
elsif(test(?e,userfile))
check = 1
elsif userfile =~ (/[\x00\/\\:\*\?\"<>\|]/)
puts "The userfile contains invalid characters. Try again."
system "pause"
check = 0
elsif userfile == ""
puts "You entered nothing. Try again."
system "pause"
check = 0
elsif(!test(?e,userfile))
check = 0
puts "The file #{userfile} does not exist. Try again."
system "pause"
else
puts "Your entry is invalid. Try again."
system "pause"
check = 0
end
end
#create the security groups via DOS and check wheteher they already exist
grpC2 = 0
grpC3 = 0
grpC4 = 0
grpD5 = 0
expired = 0
students = 0
%x[dsquery group "dc=troptrain,dc=net,dc=au"].each do |line|
data = line
if line.include?("grpC2")
grpC2 = 1
end
if line.include?("grpC3")
grpC3 = 1
end
if line.include?("grpC4")
grpC4 = 1
end
if line.include?("grpD5")
grpD5 = 1
end
if line.include?("Expired")
expired = 1
end
if line.include?("Students")
students = 1
end
end
if grpC2 != 1
%x[dsadd group "cn=grpC2,ou=studentsOU,dc=troptrain,dc=net,dc=au"]
end
if grpC3 != 1
%x[dsadd group "cn=grpC3,ou=studentsOU,dc=troptrain,dc=net,dc=au"]
end
if grpC4 != 1
%x[dsadd group "cn=grpC4,ou=studentsOU,dc=troptrain,dc=net,dc=au"]
end
if grpD5 != 1
%x[dsadd group "cn=grpD5,ou=studentsOU,dc=troptrain,dc=net,dc=au"]
end
if expired != 1
%x[dsadd group "cn=Expired,ou=studentsOU,dc=troptrain,dc=net,dc=au"]
end
if students != 1
%x[dsadd group "cn=Students,ou=studentsOU,dc=troptrain,dc=net,dc=au"]
end
#open the file
f1 = File.open(userfile,"r")
#read the file line by line
count = 0
f1.each do |line|
data = line.split(',')
firstname = data[0].capitalize
surname = data[1].capitalize
dob = data[2].to_s
snumber = data[3].to_s
enddate1 = data [4].gsub!("-","/")
enddate = enddate1
area = data[5]
fullname = (firstname + (" ") + surname)
group = "cn=#{'grp'+data[5]}"
password1 = data[2].gsub("-", "")
password = password1
count = count + 1
#display values for establishing error checks
#puts ""
#puts "fullname: #{fullname}"
#puts "dob: #{dob}"
#puts "snumber: #{snumber}"
#puts "enddate: #{enddate}"
#puts "area: #{area}"
#puts "password: #{password}"
#puts "group: #{group}"
#puts "count: #{count}"
#puts ""
if ((data[2] =~ /[^0-9-]/) || (data[3] =~ /[^0-9-]/) || (data[4] =~ /[^0-9\/]/) || (data[5] =~ /[^A-Za-z0-9 ]/) || (data[0] =~ /[^A-Za-z ]/) || (data[1] =~ /[^A-Za-z ]/) || (data[0] == "") || (data[1] == "") || (data[2] == "") || (data[3] == "") || (data[4] == "") || (data[5] == "") || (data[6] == ""))
puts ""
puts "====================================================================="
puts "User account No #{count}: #{fullname} was not created."
puts ""
if (File.exist?(filepath))
file = File.open((filepath), "a+")
t = Time.now
file.puts "====================================================================="
file.puts "User account No #{count}: #{fullname} was not created."
file.puts t
file.puts ""
else
puts "Error log cannot be found!"
puts "Searched directory: #{filepath}"
end
#checking database entries for errors
if ((data[0] == "") || (data[0] =~ /[^A-Za-z ]/))
puts "No/Incorrect firstname on file."
file.puts "No/Incorrect firstname on file."
end
if ((data[1] == "") || (data[1] =~ /[^A-Za-z ]/))
puts "No/Incorrect surname on file."
file.puts "No/Incorrect surname on file."
end
if ((data[2] == "") || (data[2] =~ /[^0-9-]/))
puts "No/Incorrect birthdate on file."
file.puts "No/Incorrect birthdate on file."
end
if ((data[3] == "") || (data[3] =~ /[^0-9-]/))
puts "No/Incorrect student number on file."
file.puts "No/Incorrect student number on file."
end
if ((data[4] == "") || (data[4] =~ /[^0-9\/]/))
puts "No/Incorrect study end date on file."
file.puts "No/Incorrect study end date on file."
end
if ((data[5] == "") || (data[5] =~ /[^A-Za-z0-9 ]/))
puts "No/Incorrect study area on file."
file.puts "No/Incorrect study area on file."
end
file.close
else
begin
puts "working"
system 'pause'
ad = WIN32OLE.connect("LDAP://#{ou},#{domain}")
user = ad.create("user","cn=#{fullname}")
user.givenName = firstname
user.Sn = surname
user.SAMAccountname = "#{snumber}"
user.userPrincipalName = "#{snumber}#Troptrain.net.au"
user.displayName = fullname
user.profilePath = "c:\\profiles\\students\\logon"
user.setInfo
user_fqdn = "cn=#{fullname},#{ou},#{domain}"
user = WIN32OLE.connect("LDAP://#{user_fqdn}")
user.userPassword = Password01
user.accountDisabled = 0
user.accountExpirationDate = enddate
user.setInfo
studentgroup_fqdn = "#{group},#{ou},#{domain}"
grp = WIN32OLE.connect("LDAP://#{studentgroup_fqdn}")
grp.add("LDAP://#{user_fqdn}")
allgroup_fqdn = "cn=students,#{ou},#{domain}"
allgrp = WIN32OLE.connect("LDAP://#{allgroup_fqdn}")
allgrp.add("LDAP://#{user_fqdn}")
puts ""
puts "====================================================================="
puts "User account No #{count}: #{fullname} was created."
sleep 0.5
rescue
end
end
end
puts "====================================================================="
puts ""
puts "See Error log for details."
puts ""
puts "The program has finished creating users."
f1.close

Separate your concerns.
You need to parse a text file and retrieve users and groups from it in a structured way.
You need to import your groups and then import your users.
You then assign the users to the groups you created.
Each User and Group must be located in their own OUs to identify them.
Those OUs must be known.
Now work backward and factor out everything you need to continue with.
Find your host name, port and the credentials to bind to the LDAP server.
Find your Base DN. (DC=troptrain, DC=net, DC=au)
Find your User and Group prefixes. (the OU segments after the Base DN).
Import your data.
Verify. (This is also important!)
As LDAP can appear to be somewhat backward from the typical relational database, I recommend using the ActiveLDAP ruby gem with gem install active_ldap. It makes working with LDAP far easier.
#!/usr/bin/env ruby
require 'active_ldap'
class User < ActiveLdap::Base
ldap_mapping :dn_attribute => 'CN', :prefix => '<user-ou-prefix>',
has_many :groups, :class => 'Group', :wrap => 'memberOf', :primary_key => 'DN'
end
class Group < ActiveLdap::Base
ldap_mapping :dn_attribute => 'CN', :prefix => '<group-ou-prefix>',
has_many :members, :class => 'User', :wrap => 'member', :primary_key => 'DN'
end
ActiveLdap::Base.setup_connection(
:host => '<hostname>',
:base => '<base-dn>',
:bind_dn => '<bind-dn>',
:password => '<bind-password>',
:allow_anonymous => false,
:try_sasl => false,
:port => 389
)
From there, you should have the ability to create, read, update, and delete users using an ActiveRecord-like interface. the call to #setup_connection establishes what options are used to connect, and the has_many calls establish foreign-key-like relations between your classes.
# Find and display all users:
User.find(:all, '*') do |user|
puts user.cn
end
# Create a group with a CN of 'Anonymous'
group = Group.new('Anonymous')
group.description = "An anonymous group."
group.save
# Change the user with the CN 'Nobody' and change their displayName attribute.
user = User.find('Nobody')
user.displayName = "Nobody's Name"
user.save
# Delete a group with a CN of 'Foobar'.
group = Group.find('Foobar')
group.delete
ActiveLdap makes it extremely easy to manipulate LDAP from Ruby, I highly recommend it.

Related

Why will this not iterate through the file like I want it to?

It will just output two blank lines to the screen when it should be printing the card id and the balance
I have completely re-written the code.
I have fiddled with that code for an hour
class RBC
def initialize
#args = ["Create a new card"]
#functions = ["create_rbc"]
puts "Do you have an RBC ID yet? Yes(0) No(1)"
hasrbc = gets.chomp.to_i
if hasrbc == 1
#balance = 5
create_rbc
else
login
end
end
def create_rbc
puts "\nGenerating your rbc\n\n"
puts "\nWelcome to your Ruby Binary Card(RBC)!\n\n"
puts "Your RBC will keep track of your RubyCredits(RC).\n"
puts "You will get paid RC for work apps, and pay for game apps.\n"
puts "If you lose track of your RBC ID, you can get a new one.\n"
puts "Doing this, however, will reset your balance to the default of $5\n\n"
puts "What is your name? Do first last\n"
#fullname = gets.chomp
#card_name = get_name_codec(#fullname)
#card_cipher = "#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}#{rand(1..9)}"
#card_id = "#{#card_name} - #{#card_cipher}"
instance_variable_set("#Id#{#card_cipher}", #balance)
puts "Write down your RBC ID: #{#card_id}"
file = File.open("Cards.rbc", "w")
file.puts #card_id
file.puts #balance
end
end
def get_name_codec(name)
names = name.split(" ")
fname = names[0]
lname = names[1]
fchar = fname.split(//)
fcodec = "#{fchar[0]}#{fchar[1]}"
name_codec = "#{fcodec}#{lname}"
return name_codec
end
def login
#found = false
puts "What is your RBC Id"
input = gets.chomp
File.open("Cards.RBC", "r") do |f|
f.each_line do |line|
if input == "#{line}"
#card_id = line.to_s
#found == true
elsif #found == true
#balance = line.to_i
end
end
end
puts "#{#card_id}#{#balance}"
end
RBC.new
Then the Cards.RBC
TiLan - 1122632527
5
I want it to print the balance and card Id.
It should give me my card id and then the balance like this:
0000...etc
5
input = gets.chomp removes the newline off the input, but f.each_line does not. So input == "#{line}" is comparing, for example, "1234" with "1234\n".
Chomp the line as well.
input = gets.chomp
File.open("Cards.RBC", "r") do |f|
f.each_line do |line|
line.chomp!
if input == line
#card_id = line
#found == true
elsif #found == true
#balance = line.to_i
end
end
end
You can debug this sort of thing by printing the values with p. This will show them as quoted strings and show any special characters including newlines.
p line
p input

else without rescue is useless and expecting keyword_end

This code gives me these errors in my ruby console:
1) warning: else without rescue is useless
2) syntax error, unexpected end-of-input, expecting keyword_end
Why am I getting both of these errors at the same time?
require 'nokogiri'
require 'httparty'
require 'byebug'
require 'awesome_print'
require 'watir'
def input #takes user input and grabs the url for that particular search
puts "1) Enter the job title that you want to search for \n"
j_input = gets.chomp
job = j_input.split(/ /).join("+")
puts "================================= \n"
puts "1/2)Do you want to input city-and-state(1) or zipcode(2)? \n"
choice = gets.chomp
if choice == "1"
puts "2) Enter the city that you want to search for \n"
city_input = gets.chomp
city = city_input.split(/ /).join("+")
puts "================================= \n"
puts "3) Enter the state that you want to search for \n"
state_input = gets.chomp
state = "+" + state_input
puts target_url = "https://www.indeed.com/resumes/?q=#{job}&l=#{city}%2C#{state}&cb=jt"
elsif choice == "2"
puts "Enter the zipcode that you want to search for \n"
zipcode = gets.chomp
puts target_url = "https://www.indeed.com/resumes?q=#{job}&l=#{zipcode}&cb=jt"
else
puts "error"
end
unparsed_page = HTTParty.get(target_url)
parsed_page = Nokogiri::HTML(unparsed_page)
resume_listing = parsed_page.css('div.sre-entry')
per_page = resume_listing.count
resumes = Array.new
counter = 0
result_count = parsed_page.css('div#result_count').text.split(' ')[0].to_f
page_count = (result_count.to_f / per_page.to_f ).ceil
current_count = 0
byebug
if counter <= 0
unparsed_page = HTTParty.get(target_url)
parsed_page = Nokogiri::HTML(unparsed_page)
resume_listing = parsed_page.css('div.sre-entry')
per_page = resume_listing.count
pagination_resume_listing.each do |resume_listing|
#resume_info = {
# title:
# link:
# skills:
# education:
#}
#resumes << resume_info
puts "Added #{resume_info[:title]}"
else
while current_count <= page_count * per_page
pagination_url = "https://www.indeed.com/resumes?q=#{job}&l=#{zipcode}&co=US&cb=jt&start=#{current_count}"
unparsed_pagination_page = HTTParty.get(pagination_url)
pagination_parsed_page = Nokogiri::HTML(unparsed_pagination_page)
pagination_resume_listing = pagination_parsed_page.css('div.sre-entry')
pagination_resume_listing.each do |resume_listing|
#resume_info = {
# title:
# link:
# skills:
# education:
#}
#resumes << resume_info
puts "Added #{resume_info[:title]}"
current_count += 50
end
end
end
end
end
It won't allow me to fix the else without rescue issue without telling me that it expects an extra end at the end of my code. Of course when I put the end there it does nothing and says that it wants another end
I would say that your code is horribly formatted, but it would first have to be formatted at all to be even that much. Once you format it, the answer is quite obvious, you have a mis-placed end.
puts "Added #{resume_info[:title]}"
# Should be and end here for the "do" block above
else
Here is what it should be:
require 'nokogiri'
require 'httparty'
require 'byebug'
require 'awesome_print'
require 'watir'
def input #takes user input and grabs the url for that particular search
puts "1) Enter the job title that you want to search for \n"
j_input = gets.chomp
job = j_input.split(/ /).join("+")
puts "================================= \n"
puts "1/2)Do you want to input city-and-state(1) or zipcode(2)? \n"
choice = gets.chomp
if choice == "1"
puts "2) Enter the city that you want to search for \n"
city_input = gets.chomp
city = city_input.split(/ /).join("+")
puts "================================= \n"
puts "3) Enter the state that you want to search for \n"
state_input = gets.chomp
state = "+" + state_input
puts target_url = "https://www.indeed.com/resumes/?q=#{job}&l=#{city}%2C#{state}&cb=jt"
elsif choice == "2"
puts "Enter the zipcode that you want to search for \n"
zipcode = gets.chomp
puts target_url = "https://www.indeed.com/resumes?q=#{job}&l=#{zipcode}&cb=jt"
else
puts "error"
end
unparsed_page = HTTParty.get(target_url)
parsed_page = Nokogiri::HTML(unparsed_page)
resume_listing = parsed_page.css('div.sre-entry')
per_page = resume_listing.count
resumes = Array.new
counter = 0
result_count = parsed_page.css('div#result_count').text.split(' ')[0].to_f
page_count = (result_count.to_f / per_page.to_f ).ceil
current_count = 0
byebug
if counter <= 0
unparsed_page = HTTParty.get(target_url)
parsed_page = Nokogiri::HTML(unparsed_page)
resume_listing = parsed_page.css('div.sre-entry')
per_page = resume_listing.count
pagination_resume_listing.each do |resume_listing|
#resume_info = {
# title:
# link:
# skills:
# education:
#}
#resumes << resume_info
puts "Added #{resume_info[:title]}"
end
else
while current_count <= page_count * per_page
pagination_url = "https://www.indeed.com/resumes?q=#{job}&l=#{zipcode}&co=US&cb=jt&start=#{current_count}"
unparsed_pagination_page = HTTParty.get(pagination_url)
pagination_parsed_page = Nokogiri::HTML(unparsed_pagination_page)
pagination_resume_listing = pagination_parsed_page.css('div.sre-entry')
pagination_resume_listing.each do |resume_listing|
#resume_info = {
# title:
# link:
# skills:
# education:
#}
#resumes << resume_info
puts "Added #{resume_info[:title]}"
current_count += 50
end
end
end
end
Lesson here is to ALWAYS format your code, for everyone's sake, most of all your own. There is no excuse to not be formatted, and not doing so leads to trivial problems like this that are difficult to find.
NOTE
I did not test this or run it, simply formatted, which made the mis-matched end obvious.

How to delete a row from CSV file

I want to delete a row and write back to the file.
When I delete it deletes all contents of the CSV file.
products = {}
def menu
puts "#{'Item'.ljust(6)} #{'Description'.ljust(10)} #{'Price'.rjust(7)}"
puts '-' * 4 + ' ' + '-' * 11 + ' ' + '-' * 5
File.open('text.txt').readlines.each do |itemnumber|
puts itemnumber.gsub(/[,]/, ' ')
end
end
user_choice = 0
while user_choice !=8
puts ''
puts 'What would you like to do?'
puts '1: View all products.'
puts '2: Add a new product.'
puts '3: Delete a product.'
puts '4: Update a product.'
puts '5: View highest priced product.'
puts '6: View lowest priced product.'
puts '7: View sum of all products prices.'
puts '8: Exit.'
user_choice = gets.chomp.to_i
if user_choice == 1
menu
end
if user_choice == 2
puts ''
puts 'Enter new products description. '
new_products = gets.chomp
puts 'Enter new products price. '
price = gets.chomp.to_f
new_key = rand(100..999)
while products.has_key?(new_key)
new_key = rand(100..999)
end
puts "#{new_key},#{new_products},#{price}"
open('text.txt', 'a') { |newproduct|
newproduct.puts "#{new_key},#{new_products},#{price}"
}
end
if user_choice == 3
menu
puts ''
puts "What's the item number you wish to delete?"
item_num = gets.chomp
read_file = File.new('text.txt', "r+").read
write_file = File.new('text.txt', "w+")
read_file.each_line do |line|
write_file.write(line) unless line.include? item_num
end
end
What am I doing wrong? In the "delete" part of the program, I'm sure there are multiple things wrong.
Your delete is actually happening, but your currently running application is not aware of that yet.
You can check that by restarting the app and/or by looking at the text file.
To fix this, after writing to the file ends in the block, close the file so that the change is flushed:
read_file.each_line do |line|
write_file.write(line) unless line.include? item_num
end
write_file.close

Ruby script error

I've got a ruby script
#!/usr/bin/ruby
require 'rubygems'
require 'mechanize'
require 'nokogiri'
require 'highline/import'
require 'stringio'
#Change based on Semester
$term = '09'
$year = '2012'
$frequency = 4 #Number of Seconds between check requests
$agent = Mechanize.new
$agent.redirect_ok = true
$agent.user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.11 Safari/535.19"
$agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
#Uber simway to colorize outputin
class String
def color(c)
colors = {
:black => 30,
:red => 31,
:green => 32,
:yellow => 33,
:blue => 34,
:magenta => 35,
:cyan => 36,
:white => 37
}
return "\e[#{colors[c] || c}m#{self}\e[0m"
end
end
#Logins, Gets the Courses, Returns Courses Obj with Name/URL/Tools for each
def login(username, password)
#Login to the system!
page = $agent.get("https://auth.vt.edu/login?service=https://webapps.banner.vt.edu/banner-cas-prod/authorized/banner/SelfService")
login = page.forms.first
login.set_fields({
:username => username,
:password => password
})
if (login.submit().body.match(/Invalid username or password/)) then
return false
else
return true
end
end
#Gets Course Information
def getCourse(crn)
begin
courseDetails = Nokogiri::HTML( $agent.get(
"https://banweb.banner.vt.edu/ssb/prod/HZSKVTSC.P_ProcComments?CRN=#{crn}&TERM=#{$term}&YEAR=#{$year}"
).body)
rescue
return false #Failed to get course
end
#Flatten table to make it easier to work with
course = {}
dataSet = false
course[:title] = courseDetails.css('td.title').last.text.gsub(/-\ +/, '')
course[:crn] = crn
courseDetails.css('table table tr').each_with_index do |row|
#If we have a dataSet
case dataSet
when :rowA
[ :i, :days, :end, :begin, :end, :exam].each_with_index do |el, i|
if row.css('td')[i] then
course[el] = row.css('td')[i].text
end
end
when :rowB
[ :instructor, :type, :status, :seats, :capacity ].each_with_index do |el, i|
course[el] = row.css('td')[i].text
end
end
dataSet = false
#Is there a dataset?
row.css('td').each do |cell|
case cell.text
when "Days"
dataSet = :rowA
when "Instructor"
dataSet = :rowB
end
end
end
return course
end
#Registers you for the given CRN, returns true if successful, false if not
def registerCrn(crn)
#Follow Path
$agent.get("https://banweb.banner.vt.edu/ssb/prod/twbkwbis.P_GenMenu?name=bmenu.P_MainMnu")
reg = $agent.get("https://banweb.banner.vt.edu/ssb/prod/hzskstat.P_DispRegStatPage")
dropAdd = reg.link_with(:href => "/ssb/prod/bwskfreg.P_AddDropCrse?term_in=#{$year}#{$term}").click
#Fill in CRN Box and Submit
crnEntry = dropAdd.form_with(:action => '/ssb/prod/bwckcoms.P_Regs')
crnEntry.fields_with(:id => 'crn_id1').first.value = crn
crnEntry['CRN_IN'] = crn
add = crnEntry.submit(crnEntry.button_with(:value => 'Submit Changes')).body
if add =~ /#{crn}/ && !(add =~ /Registration Errors/) then
return true
else
return false
end
end
#Main loop that checks the availaibility of each courses and fires to registerCrn on availaibility
def checkCourses(courses)
requestCount = 0
startTime = Time.new
loop do
system("clear")
requestCount += 1
nowTime = Time.new
puts "Checking Availaibility of CRNs".color(:yellow)
puts "--------------------------------\n"
puts "Started:\t#{startTime.asctime}".color(:magenta)
puts "Now: \t#{nowTime.asctime}".color(:cyan)
puts "Request:\t#{requestCount} (Once every #{$frequency} seconds)".color(:green)
puts "--------------------------------\n\n"
courses.each_with_index do |c, i|
puts "#{c[:crn]} - #{c[:title]}".color(:blue)
course = getCourse(c[:crn])
next unless course #If throws error
puts "Availaibility: #{course[:seats]} / #{course[:capacity]}".color(:red)
if (course[:seats] =~ /Full/) then
else
if (registerCrn(c[:crn])) then
puts "CRN #{c[:crn]} Registration Sucessfull"
courses.slice!(i)
else
puts "Couldn't Register"
end
end
print "\n"
end
sleep $frequency
end
end
#Add courses to be checked
def addCourses
crns = []
loop do
system("clear")
puts "Your CRNs:".color(:red)
crns.each do |crn|
puts " -> #{crn[:title]} (CRN: #{crn[:crn]})".color(:magenta)
end
#Prompt for CRN
alt = (crns.length > 0) ? " (or just type 'start') " : " "
input = ask("\nEnter a CRN to add it#{alt}".color(:green) + ":: ") { |q| q.echo = true }
#Validate CRN to be 5 Digits
if (input =~ /^\d{5}$/) then
#Display CRN Info
c = getCourse(input.to_s)
puts "\nCourse: #{c[:title]} - #{c[:crn]}".color(:red)
puts "--> Time: #{c[:begin]}-#{c[:end]} on #{c[:days]}".color(:cyan)
puts "--> Teacher: #{c[:instructor]}".color(:cyan)
puts "--> Type: #{c[:type]} || Status: #{c[:status]}".color(:cyan)
puts "--> Availability: #{c[:seats]} / #{c[:capacity]}\n".color(:cyan)
#Add Class Prompt
add = ask("Add This Class? (yes/no)".color(:yellow) + ":: ") { |q| q.echo = true }
crns.push(c) if (add =~ /yes/)
elsif (input == "start") then
checkCourses(crns)
end
end
end
def main
system("clear")
puts "Welcome to CourseAdd by mil".color(:blue)
username = ask("PID ".color(:green) + ":: ") { |q| q.echo = true }
password = ask("Password ".color(:green) + ":: " ) { |q| q.echo = "*" }
system("clear")
if login(username, password) then
addCourses
else
puts "Invalid PID/Password"
exit
end
end
main
but when I run ruby Untitled.rb it give me this error.
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- mechanize (LoadError)
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /Users/user/Desktop/Untitled.rb:3
What does this mean and how can I fix it? I'm not sure if I need to be doing this through an IDE or if terminal works. I'm brand new to ruby so I honestly have not a clue what the issue could be.
You need to install mechanize. In your terminal, type:
gem install mechanize
Retry your script when it finishes installing. If you have other gems that are missing, you can use the same command to install them.
gem install <gem name>

Limitation on number of result in search engine scraping

I am scraping bing search engine using Mechanize. But I get only max 200 results programmatically if I execute same search query on bing.com it returns 1400 results. What is gotcha here?
def generate_profiles_from_group(options={})
raise "TypeError", "Invalid Arguments" unless options.is_a? Hash
group = options[:group] if options.has_key? :group
query = build_query(options)
page = bing_search(query)
contacts_stack = extract_contacts_from_bing_page page: page
bing_links_stack = bing_links page
return contacts_stack, bing_links_stack
end
def extract_contacts_from_bing_page(options)
page = options[:page]
company = options[:company] || nil
title = options[:title] || nil
stack = []
while true
page.parser.search('h3 a').each do |cite|
text = cite.text
unless text == ""
name_array = text.split(' ')
if name_array.size >= 2
name = name_array[0]+' '+name_array[1]
unless name=~/[^a-zA-Z',\s]/i
stack << {name: name, company: company, title: title}
end
end
end
end
keyw = page.parser.xpath('//*[contains(concat( " ", #class, " " ), concat( " ", "sb_pagN", " " ))]').text
break if keyw == ""
page = #agent.click page.link_with(text: keyw )
end
stack
end
def bing_links page
stack = []
while true
page.parser.xpath('//cite').each do |cite|
stack << cite.text unless cite.text == ""
end
keyw = page.parser.xpath('//*[contains(concat( " ", #class, " " ), concat( " ", "sb_pagN", " " ))]').text
break if keyw == ""
sleep(10+rand(40))
page = #agent.click page.link_with(text: keyw )
end
stack
end
def build_query(options)
name = options[:name] if options.has_key? :name
title = options[:title] if options.has_key? :title
company = options[:company] if options.has_key? :company
group = options[:group] if options.has_key? :group
if name && company
return "site:linkedin.com \"#{name}\" \"at #{company}\""
elsif name && title
return "site:linkedin.com \"#{name}\" \"#{title}\""
elsif title && company
return "site:linkedin.com/ \"#{title}\" \"at #{company}\""
elsif group
return "site:linkedin.com \"groups and association\" + \"#{group}\""
end
end

Resources