Advertisement
Guest User

Untitled

a guest
May 22nd, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.00 KB | None | 0 0
  1. require 'net/http'
  2. require 'json'
  3. require 'pp'
  4.  
  5. class StiftungAPI
  6. attr_reader :params, :languages, :specialties, :special_requests, :special_services,
  7. :base_uri, :payment_services
  8.  
  9. def initialize
  10. @base_uri = URI(ENV['stiftung_base_url'])
  11. @params = {
  12. akey: ENV['stiftung_key'],
  13. }
  14. # Fine for now, only from English. Should have multilingual support
  15. # Move to .json files
  16. @languages = {
  17. 'arabic': '256',
  18. 'spanish': '102',
  19. 'french': '86',
  20. 'english': '36',
  21. 'chinese': '1449',
  22. 'turkish': '285',
  23. 'portuguese': '779',
  24. 'polish': '37',
  25. 'italian': '153',
  26. 'dutch': '1316',
  27. 'greek': '1030',
  28. 'japanese': '1103',
  29. 'norwegian': '1529',
  30. 'romanian': '471',
  31. 'russian': '38',
  32. 'indonesian': '1684',
  33. 'finnish': '419',
  34. 'hindi': '1767',
  35. 'korean': '1332'
  36. }
  37. @special_requests = {
  38. 'evening_hours': '120',
  39. 'weekend_hours': '46',
  40. 'house_visit': '29'
  41. }
  42. @specialties = {
  43. 'dentist': 'zahnmedizin',
  44. 'doctor': 'allgemeinmedizin',
  45. 'general_practicioner': 'allgemeinmedizin',
  46. 'oftalmologist': 'augenarzt',
  47. 'gynecologist': 'frauenarzt'
  48. }
  49. @special_services = {
  50. 'Abendsprechstunden': :evening_hours,
  51. 'Wochenendsprechstunden': :weekend_hours,
  52. 'Termine nur nach Vereinbarung': :appointment_only,
  53. 'weitere Sprechzeiten nach Vereinbarung': :extra_hours_with_appointment,
  54. 'mit Bus und Bahn erreichbar': :bus_and_metro,
  55. 'Parkplätze nahe der Praxis': :parking,
  56. 'Erinnerung an Vorsorge': :appointment_periodical_reminder,
  57. 'Hausbesuche': :house_visit,
  58. 'Homepage angegeben': :homepage,
  59. 'Services im Wartezimmer': :waiting_room_services
  60. }
  61. @payment_services = {
  62. 'Kasse, Privat und Selbstzahler': :all,
  63. 'gesetzlich Versicherte (nur bestimmte Therapien)': :publicly_insured,
  64. 'nur Privatpatienten/Selbstzahler': :only_private,
  65. 'Kasse mit Einschränkungen': :copayment,
  66. 'Privatpatienten/ Kostenerstattungsverfahren': :partially_refunded
  67. }
  68. end
  69.  
  70. def self.get_doctor_details(query)
  71. @api ||= StiftungAPI.new
  72. @api.get_doctor_details(query)
  73. end
  74.  
  75. # Returns the details on a doctor
  76. def get_doctor_details(query)
  77. # Checks whether doctor is available in database with all data loaded
  78. doctor = Doctor.find_by(doctor_id: query[:doctor_id])
  79.  
  80. if doctor.nil? || doctor.patient_services.nil?
  81. doctor = request({
  82. a: 'DD',
  83. e_id: query[:doctor_id],
  84. userip: query[:user_ip] || ENV['stiftung_default_user_ip']
  85. })
  86. end
  87.  
  88. # TODO: remove this line
  89. {doctor: doctor.attributes.except("id").merge(id: doctor.doctor_id)}
  90. end
  91.  
  92. def self.get_api_details(query)
  93. @api ||= StiftungAPI.new
  94. @api.get_api_details(query)
  95. end
  96.  
  97. # Returns the details on a doctor
  98. def get_api_details(query)
  99. request({
  100. a: 'FS1',
  101. userip: query[:user_ip] || ENV['stiftung_default_user_ip']
  102. })
  103. end
  104.  
  105. def self.get_doctors_list(query)
  106. @api ||= StiftungAPI.new
  107. @api.get_doctors_list(query)
  108. end
  109.  
  110. def get_doctors_list(query)
  111. adapted_query = {
  112. a: 'DL',
  113. Lng: languages[query.dig(:language).to_sym],
  114. Ft: specialties[query.dig(:specialty)&.to_sym]|| 'Allgemeinmedizin',
  115. Ftg: query.dig(:location),
  116. userip: query[:user_ip] || ENV['stiftung_default_user_ip']
  117. }
  118. request(adapted_query)
  119. end
  120.  
  121. private
  122.  
  123. # Sends formatted request to API
  124. def request(query)
  125. p "MAKING QUERY"
  126. pp query
  127. base_uri.query = URI.encode_www_form(params.merge(query))
  128. res = Net::HTTP.get_response(base_uri)
  129. format_result(res.body)
  130. end
  131.  
  132. # Cleans up the result
  133. def format_result(body)
  134. result = JSON.parse(body)
  135. pp result
  136. if result.has_key?('entry')
  137. format_doctor_details(result)
  138. elsif result.has_key?('entry_List')
  139. format_doctors_list(result)
  140. else
  141. {}
  142. end
  143. end
  144.  
  145. # Formats details of a doctor
  146. def format_doctor_details(result)
  147. entry = result['entry']
  148. get_doctor(entry)
  149. end
  150.  
  151. def format_doctors_list(result)
  152. entries = result['entry_List']
  153. entries.each_with_object([]) do |entry, list|
  154. # TODO: change this ASAP, when controllers are refactored
  155. # list.push(get_doctor(entry))
  156. doctor = get_doctor(entry)
  157. list.push(doctor.attributes.except("id").merge(id: doctor.doctor_id))
  158. end
  159. end
  160.  
  161. # Given an entry from API extract information
  162. # and return a doctor, or find a new one
  163. def get_doctor(entry)
  164. doctor = Doctor.find_or_create_by(doctor_id: entry["e_id"]) do |doctor|
  165. doctor.doctor_id = entry["e_id"]
  166. doctor.name = "#{entry['title']} #{entry['firstname']} #{entry['lastname']}"
  167. doctor.clinic = entry["business"]
  168. doctor.clinic_title = entry["nameExtension"]
  169. doctor.latitude = entry["geoLat"]
  170. doctor.longitude = entry["geoLong"]
  171. doctor.postal_code = entry["zipCode"]
  172. doctor.city = entry["place"]
  173. doctor.address = entry["street"]
  174. doctor.phone = entry["phone1"]
  175. doctor.languages = unpack_languages(entry) if entry.key?("orientation_List")
  176. doctor.patient_services = unpack_patient_services(entry) if entry.key?("indicator_List")
  177. doctor.payment_services = unpack_payment_services(entry) if entry.key?("indicator_List")
  178. end
  179.  
  180. # If record was loaded from list request and we perform a detail
  181. # request update doctor information with detail information
  182. doctor.tap do |selected_doctor|
  183. if (selected_doctor.patient_services.nil? && entry.key?("indicator_List"))
  184. selected_doctor.update_attributes({
  185. languages: unpack_languages(entry),
  186. patient_services: unpack_patient_services(entry),
  187. payment_services: unpack_payment_services(entry)
  188. })
  189. end
  190. end
  191. end
  192.  
  193. # These methods deal with the strange and convoluted API format
  194. # If you think you can NOT codegolf your way around it, good luck
  195. # And Fuck you also, smartass.
  196. def unpack_languages(entry)
  197. entry["orientation_List"].select { |i| i["type"] == '6' }.first["lbl_List"].map(&:values).flatten
  198. end
  199.  
  200. # Nice, uh?
  201. def unpack_patient_services(entry)
  202. services = entry["indicator_List"].select { |i| i["name"] == 'Ic3' }.first["lbl_List"]
  203. services.map(&:values).map do |service|
  204. [special_services[service[0].to_sym], service[1] == '1']
  205. end.to_h
  206. end
  207.  
  208. def unpack_payment_services(entry)
  209. services = entry["indicator_List"].select { |i| i["name"] == 'Ic1' }.first["lbl_List"]
  210. services.map(&:values).map do |service|
  211. [payment_services[service[0].to_sym], service[1] == '1']
  212. end.to_h
  213. end
  214. end
  215.  
  216. # pp StiftungAPI.get_doctor_details(doctor_id: '617549')
  217. # 617549
  218. # pp StiftungAPI.get_doctors_list(language: 'italian',specialty: 'doctor',location: '04179')
  219.  
  220.  
  221. # TODO:
  222. # - Abstract unpacking for Icn
  223. # - Maybe this stuff should be moved to the database?
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement