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