Source

geomena / sinatra / lib / geomena / web.rb

module Geomena
  class Web < Sinatra::Base
    set :views, settings.root + '/../../views'
    configure do
      set :sessions, true
      @@log = Logger.new(STDOUT)
      Version = File.open(File.dirname(__FILE__)+"/../../public/version") {|f| f.read } rescue Errno::ENOTDIR
    end

    get '/' do
      erb :index, :locals => {:ocount => GCouch.count, :aplast => GCouch.last}
    end

    get '/api' do
      redirect "http://bitbucket.org/donpdonp/geomena/wiki/APIReference"
    end

    get '/search' do
      if mac_valid?(params[:q])
        mac = mac_clean(params[:q])
        redirect "/ap/#{mac}"
      else
        redirect "/essid/#{params[:q]}"
      end
    end

    get '/locate' do
      erb :locate
    end

    post '/' do
      geodata = JSON.parse(request.body.read)
      @@log.info("W3C Lookup: #{geodata}")
      towers = geodata["wifi_towers"]
      return if towers.nil? || towers.size == 0
      towers.each do |tower|
        macaddr = mac_clean(tower["mac_address"])
        response = GCouch.get_by_mac(macaddr)
        ap = first_ap(response)
        if ap
          answer = {"location" => {"latitude" => ap["latitude"],
                                   "longitude" => ap["longitude"],
                                   "accuracy" => 150},
                                   "access_token" => "abc123"}
          GCouch.log(macaddr,"success")
          return answer.to_json
        else
          GCouch.log(macaddr,"failure")
        end
      end
      return ""
    end

    get '/ap/:mac' do |mac|
      response = GCouch.get_by_mac(mac)
puts "response #{response.inspect}"
      ap = first_ap(response)
      ocount = GCouch.get_observation_count_for_mac(mac)
puts ":locals => {:ap => #{ap}, :mac => #{mac}, :ocount => #{ocount}}"
      erb :apshow, :locals => {:ap => ap, :mac => mac, :ocount => ocount}
    end

    post '/ap/:mac' do |mac|
      payload = {:mac => mac_clean(mac),
                 :essid => params[:essid],
                 :latitude => params[:latitude],
                 :longitude => params[:longitude],
                 :essid => params[:essid]}
      if params[:id]
        payload.merge!({:id => params[:id], :_rev => params[:rev]})
        GCouch.put(payload)
      else
        payload.merge!({:created_at => Time.now.utc.iso8601})
        GCouch.put(payload)
      end
      redirect "/ap/#{params[:mac]}"
    end

    get '/essid/:essid' do |essid|
      essids = GCouch.get_by_essid(essid)["rows"]
      if essids.size > 1
        erb :essids, :locals => {:essids => essids, :essid => essid}
      elsif essids.size == 1
        redirect "/ap/#{essids[0]["value"]["mac"]}"
      elsif essids.size == 0
        session[:searchmsg] = "Network name not found. Use the mac address to create a new record."
        redirect "/"
      end

    end

    post '/bitbucket' do
      system("./stop.sh; hg pull; hg update; hg log -l 1|head -1|cut -d' ' -f4 > public/version; ./start.sh")
    end

    get '/about' do
      erb :about
    end

    get '/clients' do
      erb :clients
    end

    get '/data' do
      erb :data
    end

    get '/data/heatmap' do
      erb :heatmap
    end

    private

    def first_ap(aps)
      if aps["rows"].size > 0
        aps["rows"].first["value"]
      end
    end

    def mac_clean(mac)
      # take off leading and trailing space
      mac = mac.strip
      # fill in "0"s if needed
      mac = mac.split(':').map {|m| if m.length == 1; "0"+m; else m; end }.join
      # remove the ":" or "-" seperators
      mac = mac.gsub(':','').gsub('-','')
      # lowercase
      mac = mac.downcase
    end

    def mac_valid?(mac)
      !!mac.match(/^\s*..:..:..:..:..:..\s*$/)
    end

  end
end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.