Как создать и настроить свой веб-сервер на VDS (05 сен 2024)

Осенью самое время заняться установкой и тюнингом своего веб-сервера. Не правда ли?

Sypex Geo на Ruby on Rails

Больше
7 года 4 мес. назад - 7 года 4 мес. назад #1 от Aleksej
Aleksej создал тему: Sypex Geo на Ruby on Rails
К материалу блога Sypex Geo на Ruby on Rails .

Отметил ряд несоответствий при использовании одной и той же базы Sypex Geo через различные адаптеры - PHP и Rails, посредством которых на одинаковый запрос БД возвращает различные значения. Списался с разработчиком гема, информация следующая: при портировании алгоритма с PHP был "зацеплен" баг с бинарным поиском, в дальнейшем баг был пофиксен одним из пользователей GitHub. На rubygems этого фикса нет, поэтому устанавливать гем оптимально именно с github (редактируем Gemfile):

Code:
gem 'sypex_geo', :git => 'git://github.com/kolesnikovde/sypex_geo.git'

Если в мастере ситуация повторится - нужно будет дебажить поиск по индексу ( github.com/kolesnikovde/sypex_geo/blob/m...geo/database.rb#L105 ), сверяясь с PHP библиотекой.

Да, ещё один момент - код ruby библиотеки соответствует SypexGeo 2.2.3 (единственная публичная, которую можно найти на сайте), и я не уверен, что она актуальна.


К сожалению, по моим наблюдениям, кардинальных улучшений это не дает. Например, старый gem определяет координаты proxy следующим образом:

Code:
176.9.161.91 [1.63333, 111.83333] Sarawak Malaysia MY

ревизия с гитхаба позволяет чуть приблизиться к реальному геотаргетингу:

Code:
176.9.161.91 [59.91273, 10.74609] Oslo County Norway NO

, и только php API дает правильный результат, причем во всех трех случаях использовалась одна и та же база данных Sypex Geo:

Code:
176.9.161.91 Координаты Lat 50.48 and Lon 12.37 Falkenstein DE

Использовать, таким образом, gem 'sypex_geo' на продакшне не представляется возможным, просьба отнестись к представленному в блоге материалу сугубо как к учебному пособию, и не более. Впрочем, есть вариант юзать на rails при определении геотаргетинга REST API Sypex Geo.

For example, убираем из Gemfile - gem 'sypex_geo' - и делаем контроллер похожим на следующие строчки кода:

Code:
class WeatherController < ApplicationController def index ip = request.remote_ip response = HTTParty.get('http://api.sypexgeo.net/json/' + ip) r = response.parsed_response.with_indifferent_access # @lat = r[:city][:lat] # @lon = r[:city][:lon] @location = r[:city][:lat],r[:city][:lon] @region = r[:city][:name_en] @country_code = r[:country][:iso] @timezone = r[:country][:timezone] @cities = "lat=#{r[:city][:lat]}&lon=#{r[:city][:lon]}" @lookup = Weather.call(@cities) @temp = Weather.max_value(Weather.make_hash(@lookup, "temp")) @pressure = Weather.max_value(Weather.make_hash(@lookup, "pressure")) @humidity = Weather.min_value(Weather.make_hash(@lookup, "humidity")) @clouds = Weather.min_value(Weather.cloud_hash(@lookup)) end end
Последнее редактирование: 7 года 4 мес. назад пользователем p.rishard. Причина: Добавлен рабочий пример использования REST API Sypex Geo

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Dev banner 2
Больше
7 года 3 мес. назад - 7 года 3 мес. назад #2 от Aleksej
Aleksej ответил в теме Sypex Geo на Ruby on Rails
Таким образом, фрагмент модели способен выглядеть теперь следующим образом (рекомендации kvokka приведены в форме комментариев):

Code:
class WeatherSxgeo < ApplicationRecord include HTTParty base_uri "http://api.openweathermap.org/data/2.5/find?&appid=*********&units=metric&cnt=10&" format :json def self.call list_ids response = HTTParty.get(base_uri + list_ids) body = JSON.parse(response.body) # Rails.logger.debug response.body # list = body["list"] # body&.fetch('list'){[]} || [] для руби 2.3+ # ну или body.try(:fetch, 'list', []) || [] # можно body.to_h.fetch 'list', [] # можно через rescue работать (но это тупо медленнее) body.fetch('list'){[]}.compact end #create a hash to store city : temp values def self.make_hash list, value hash = Hash.new list.each do |l| temp = l["main"][value] city = l["name"] hash[city] = temp end # return hash end #create hash with city: cloud cover def self.cloud_hash list hash = Hash.new list.each do |l| cloud = l["clouds"]["all"] city = l["name"] hash[city] = cloud end # return hash end #returns the highest value from a hash def self.max_value hash hash.max_by{|k,v| v} end #returns the lowest value from a hash def self.min_value hash hash.min_by{ |k,v| v} end end



JSON.parse("null") # nil , а обязана выдавать всегда Hash, соответственно, можно попробовать что-то вроде:

Code:
def response_body reload: false, reraise: false return @_response_body if !reload && @_response_body @_response_body = JSON.parse(response.body) || {} rescue => e reraise ? raise(e) : {} end

Последнее редактирование: 7 года 3 мес. назад пользователем p.rishard.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Работает на Kunena форум