Recurring Things

"oops I did it again"

gem recurrence

gem chronic

            
unless params[:more]
  if Time.now.friday?
    cutoff = Chronic.parse('today 18:00')
  else
    cutoff = Chronic.parse('friday 18:00')
  end
  now = Time.now
  base = {every: :week, on: product.delivery_day, repeat: 4}
  if(cutoff-now > 0)
    r = Recurrence.new(base.merge! starts: cutoff)
  else
    r = Recurrence.new(base.merge! starts: Chronic.parse("1 week hence #{product.delivery_day}") )
  end
else
  r = Recurrence.new(base.merge!(repeat: 10, starts: Date.strptime(params[:more], '%m/%d/%Y')+7 )
end  
            
          

Recurring Things

"oops I did it again"

gem ice_cube

            

schedule = Schedule.new(Time.parse(params[:date]))
hod = DateTime.parse(params[:date]).hour
day = Date.parse(@event_date).cwday
count = params[:duration].to_i
case params[:frequency]
  when "hourly"
    schedule.rrule Rule.hourly.count(count).hour_of_day(hod)
  when "daily"
    schedule.rrule Rule.daily.count(count).hour_of_day(hod)
  when "weekly"
    schedule.rrule Rule.weekly.count(count).day(day).hour_of_day(hod)
  when "biweekly"
    schedule.rrule Rule.weekly(2).count(count).day(day).hour_of_day(hod)
  when "monthly"
    schedule.rrule Rule.monthly.count(count).day(day).hour_of_day(hod)
end
schedule.all_occurrences

            
          

This code made 250,000 discount codes

    
    def enter_magic_land
      agent = Mechanize.new
      base = 'fizzbuzz.myshopify.com'
      page = agent.get("https://#{base}/admin/auth/login")
      form = page.forms.first
      form.login = "fizz@buzz.com"
      form.password = "fizzbuzz"
      agent.submit(page.forms.first)
      page = agent.get("https://#{base}/admin/marketing")
      csv = CSV.read("codes.csv")
      csv.each do |code|
        page.form_with(:action => "https://#{base}/admin/discounts") do |f|
          f.encoding = 'utf-8'
          f['discount[code]'] = code.first
          discount_value_fields = f.fields_with(:id => 'discount_value')
          discount_value_fields.each do |textfield|
            textfield.value = 24.95
          end
          f["discount[starts_at]"] = ''
          f["discount[ends_at]"] = ''
          f["discount[usage_limit]"] = 1
          f["discount[discount_type]"] = 'fixed_amount'
          f["discount[minimum_order_amount]"] = 0.00
          agent.submit(f)
        end
      end
    end

Bank websites - a fun scrape

    
def banking
  results = []
  a = Mechanize.new { |agent|agent.follow_meta_refresh = true }
  page = a.get("https://xyz.banksouth.com.au/BWLogin/bib.aspx")
  form = page.form('Form1')
  unless form.nil?
    form.fields.each { |f| puts f.name }
    form['AuthUC$txtUserID'] = @user
    form['AuthUC$txtData'] = @pwd
    form['__EVENTTARGET'] = 'AuthUC$btnLogin'
    form.submit
    page = a.page.links.find { |l| l.text == '302-162 0372760' }.click
    el = page.search("//table[@id='_ctl0_ContentMain_grdTransactionList']/tbody")
    tr_elements = el.search("tr")
    tr_elements.each do |tr|
      els = tr.search("td")
      results << {
        :date => els[0].content,
        :narrative => els[1].content,
        :credit => els[4].content,
        :balance => els[5].content
      }
    end
  end
  results
end      
    
  

Writing XML is easy enough

    
def change_plan mdn, plan
  builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
    xml.methodCall {
      xml.methodName "service.changeplan"
      xml.params {
        xml.param {
          xml.value {
            xml.struct {
              xml.member {
                xml.name "apiKey"
                xml.value { xml.string @api_key }
              }
              xml.member {
                xml.name "mdn"
                xml.value { xml.string mdn }
              }
              xml.member {
                xml.name "newPlan"
                xml.value { xml.string plan }
              }
            }
          }
        }
      }
    }
  end
  builder.to_xml
end      
    
  
    



  service.changeplan
  
    
      
        
          
            apiKey
            
              123456
            
          
          
            mdn
            
              123456
            
          
          
            newPlan
            
              fizzbuzz
            
          
        
      
    
  
      

    
  

Using Saleforce, or force.com

gem HTTParty

Salesforce accepts XML via HTTP

hook up Shopify to the force

    
class SalesForce

  include HTTParty

  base_uri "http://fizzbuzz.force.com"

  def self.change_plan data
    post('/change_plan', :body => data)  # <=== we can HTTP POST data
  end

end      

SalesForce.change_plan xml_data

    
  

Working the cloud with Heroku

gem fog

Heroku is a read-only file system, so we use AWS

    
# assume my class provides filename and data
def process_list
  storage = Fog::Storage.new(
    :provider => 'AWS', 
    :aws_access_key_id => ENV['AWS_ACCESS_KEY'], 
    :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
  )
  directory = storage.directories.get 'my_directory'
  file = directory.files.get filename 
  CSV.generate(file.body) do |csv|      
      csv << [ data[:name], data[:email] ]             
  end
  file.save
end      
    
  

Sinatra and CORS

gem 'sinatra-cross_origin'

Knock knock, who is there?

JSONP is a last resort

    
get '/customer' do
  halt unless request.env['HTTP_ORIGIN']
  origin = request.env['HTTP_ORIGIN']
  if origin =~ /swift\-braun3430/
    cross_origin :allow_origin => origin   # <== can tighten things up here

    # I can do whatever I want here. nanny nanny booboo

    content_type :json
    {message: "CORS call to /customer worked"}.to_json
  else
    halt 401, "Illegal CORS call from #{origin}"
  end
end

THE END

Dave Lazar / resistorsoftware.com

@hunkybill