class Galerts::Manager

Public Class Methods

new(email, password) click to toggle source
# File lib/galerts/manager.rb, line 5
def initialize(email, password)
  @email = email
  @password = password
  init_agent
  login
end

Public Instance Methods

alerts() click to toggle source
# File lib/galerts/manager.rb, line 43
def alerts
  result = []
  contents = alerts_page.css('div#gb-main div.main-page script').text
  contents = contents.gsub('null', 'nil')
  contents = eval(contents.gsub("window.STATE = ", ""))

  if contents[1]
    contents[1][1].each do |alert|
      result << Alert.new(alert[2][3][1], {
        id:           alert[2][6][0][11],
        query: alert[2][3][1],
        feed_url:     "#{ALERTS_URL}/feeds/#{alert.last}/#{alert[2][6][0][11]}",
        data_id:      alert[1],
        data_id_2:    alert[2][6][0].last,
        domain:       alert[2][3][2],
        language:     alert[2][3][3][1],
        region:       alert[2][3].last == 1 ? alert[2][3][3][2] : ANYWHERE,
        frequency:    FREQ_TYPES.invert[alert[2][6][0][4]],
        sources:      SOURCES_TYPES.invert[alert[2][4]],
        how_many:     HOW_MANY_TYPES.invert[alert[2][5]],
        delivery:     DELIVERY_TYPES.invert[alert[2][6][0][1]]
      })
    end
  end
  result
end
alerts_page() click to toggle source
# File lib/galerts/manager.rb, line 39
def alerts_page
  Nokogiri::HTML(@agent.get(ALERTS_URL).body, nil, 'utf-8')
end
build_params(alert, action) click to toggle source
# File lib/galerts/manager.rb, line 70
def build_params(alert, action)
  # set delivery and frequency parameters
  if alert.delivery == EMAIL
    if alert.frequency == DAILY
      delivery_and_frequency = "#{DELIVERY_TYPES[EMAIL]},\"#{@email}\",[null,null,11],#{FREQ_TYPES[DAILY]}"
    elsif alert.frequency == WEEKLY
      delivery_and_frequency = "#{DELIVERY_TYPES[EMAIL]},\"#{@email}\",[null,null,11,1],#{FREQ_TYPES[WEEKLY]}"
    elsif alert.frequency == RT
      delivery_and_frequency = "#{DELIVERY_TYPES[EMAIL]},\"#{@email}\",[],#{FREQ_TYPES[RT]}"
    end
  elsif alert.delivery == RSS
    delivery_and_frequency = "#{DELIVERY_TYPES[RSS]},\"\",[],#{FREQ_TYPES[RT]}"
  end

  if alert.sources.empty?
    sources_text = 'null'
  else
    sources_text = "["
    alert.sources.collect do |source|
      raise "Unknown alert source" unless SOURCES_TYPES.has_key?(source)
      sources_text += SOURCES_TYPES[source].to_s + ','
    end
    sources_text = sources_text.chop + ']'
  end

  if alert.region == ANYWHERE
    region = REGION
    anywhere = true
  else
    region = alert.region
    anywhere = false
  end

  # TODO: need more readable
  if action == 0 # create
    params = {
      'params' => "[null,[null,null,null,[null,\"#{alert.query}\",\"#{alert.domain}\",[null,\"#{alert.language}\",\"#{region}\"],null,null,null,#{anywhere ? 0 : 1},1],#{sources_text},#{HOW_MANY_TYPES[alert.how_many]},[[null,#{delivery_and_frequency},\"#{alert.language + '-' + region.upcase}\",null,null,null,null,null,'0',null,null,\"#{alert.data_id_2}\"]]]]"
    }
    return URI.encode_www_form(params)
  elsif action == 1 # edit
    params = {
      'params' => "[null,\"#{alert.data_id}\",[null,null,null,[null,\"#{alert.query}\",\"#{alert.domain}\",[null,\"#{alert.language}\",\"#{region}\"],null,null,null,#{anywhere ? 0 : 1},1],#{sources_text},#{HOW_MANY_TYPES[alert.how_many]},[[null,#{delivery_and_frequency},\"#{alert.language + '-' + region.upcase}\",null,null,null,null,null,\"#{alert.id}\",null,null,\"#{alert.data_id_2}\"]]]]"
    }
    return URI.encode_www_form(params)
  elsif action == 2 # delete
    params = {
      'params' => "[null,\"#{alert.data_id}\"]"
    }
    return URI.encode_www_form(params)
  end
end
create(query, options = {}) click to toggle source
# File lib/galerts/manager.rb, line 122
def create(query, options = {})
  alert = Alert.new(query, options)

  x = alerts_page.css('div#gb-main div.main-page script').text.split(',').grep(/AMJH/).first.tr('"/\"','')
  alert.data_id_2 = alerts_page.css('div#gb-main div.main-page script').text.split(',').grep(/AB2X/).first.tr('"/\"','').tr('\]','')
  response = @agent.post("#{CREATE_ALERT_URL}x=#{x}", build_params(alert, 0), {'Content-Type' => 'application/x-www-form-urlencoded'})

  if response.body == ALERT_EXIST
    find_by_query(query).first
  elsif response.body == ALERT_SOMETHING_WENT_WRONG
    raise "Something went wrong!" # internal error, html changed maybe
  elsif response.body == ALERT_LIMIT_EXCEEDED
    raise "You have exceeded the limit of 1000 alerts per account"
  else
    response_body = response.body.gsub('null', 'nil')
    created_alert = Nokogiri::HTML(eval(response_body)[4][0][2], nil, 'utf-8')

    if options[:delivery] == RSS
      alert.id = created_alert.css('a')[0]['href'].split('/').last if options[:delivery] == RSS
      alert.feed_url = GOOGLE_URL + created_alert.css('a')[0]['href']
    end
    alert.data_id = created_alert.css('li')[0]['data-id']
    alert
  end
end
delete(alert) click to toggle source
# File lib/galerts/manager.rb, line 170
def delete(alert)
  x = alerts_page.css('div#gb-main div.main-page script').text.split(',').grep(/AMJH/).first.tr('"/\"','')
  alert.data_id_2 = alerts_page.css('div#gb-main div.main-page script').text.split(',').grep(/AB2X/).first.tr('"/\"','').tr('\]','')
  response = @agent.post("#{DELETE_ALERT_URL}x=#{x}", build_params(alert, 2), {'Content-Type' => 'application/x-www-form-urlencoded'})

  if response.body == ALERT_NOT_EXIST
    raise "Alert not exist!"
  elsif response.body == ALERT_SOMETHING_WENT_WRONG
    raise "Something went wrong!" # internal error, html changed maybe
  end
  true
end
find(attrs = {}) click to toggle source
# File lib/galerts/manager.rb, line 183
def find(attrs = {})
  alerts.select{|a| attrs.keys.inject(true) {|memo,k| memo = memo && attrs[k] == a.send(k) }}
end
init_agent() click to toggle source
# File lib/galerts/manager.rb, line 12
def init_agent
  @agent = Mechanize.new
  @agent.user_agent_alias = 'Linux Mozilla'
  @agent.keep_alive = true
  @agent.redirect_ok = true
  @agent.follow_meta_refresh = true
  @agent.open_timeout=10
  @agent.read_timeout=10
end
login() click to toggle source
# File lib/galerts/manager.rb, line 22
def login
  response = @agent.get(LOGIN_URL) # get login page

  email_form = response.forms.first
  email_form["Email"] = @email
  email_response = email_form.submit

  password_form = email_response.forms.first
  password_form["Passwd"] = @password
  response = password_form.submit

  error = response.parser.css('span[id^=errormsg]')
  unless error.empty?
    raise error.text.delete("\n").strip
  end
end
read(url) click to toggle source
# File lib/galerts/manager.rb, line 187
def read(url)
  @agent.get(url).body rescue raise "An error occurred while feed reading!"
end
update(alert) click to toggle source
# File lib/galerts/manager.rb, line 148
def update(alert)
  x = alerts_page.css('div#gb-main div.main-page script').text.split(',').grep(/AMJH/).first.tr('"/\"','')
  alert.data_id_2 = alerts_page.css('div#gb-main div.main-page script').text.split(',').grep(/AB2X/).first.tr('"/\"','').tr('\]','')
  response = @agent.post("#{MODIFY_ALERT_URL}x=#{x}", build_params(alert, 1), {'Content-Type' => 'application/x-www-form-urlencoded'})

  if response.body == ALERT_EXIST
    find_by_query(alert.query).first
  elsif response.body == ALERT_SOMETHING_WENT_WRONG
    raise "Something went wrong!" # internal error, html changed maybe
  else
    response_body = response.body.gsub('null', 'nil')
    created_alert = Nokogiri::HTML(eval(response_body)[4][0][2], nil, 'utf-8')

    if alert.delivery == RSS
      alert.id = created_alert.css('a')[0]['href'].split('/').last if alert.delivery == RSS
      alert.feed_url = GOOGLE_URL + created_alert.css('a')[0]['href']
    end
    alert.data_id = created_alert.css('li')[0]['data-id']
    alert
  end
end