camaras_valencia_es 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,5 +21,7 @@ Gem::Specification.new do |s|
21
21
  # specify any dependencies here; for example:
22
22
  # s.add_development_dependency "rspec"
23
23
  s.add_runtime_dependency "httparty"
24
- s.add_runtime_dependency "active_support"
24
+ s.add_runtime_dependency "therubyracer"
25
+ s.add_runtime_dependency "proj4rb"
26
+ s.add_runtime_dependency "active_support", ">= 3.0"
25
27
  end
@@ -1,7 +1,5 @@
1
1
  require 'camaras_valencia_es/version'
2
+ require 'camaras_valencia_es/util/v8_unescaper'
3
+ require 'camaras_valencia_es/util/lat_lon_converter'
2
4
  require 'camaras_valencia_es/surveillance_post'
3
5
  require 'camaras_valencia_es/surveillance_camera'
4
-
5
- module CamarasValenciaEs
6
- # Your code goes here...
7
- end
@@ -2,26 +2,30 @@ require 'httparty'
2
2
 
3
3
  module CamarasValenciaEs
4
4
  class SurveillanceCamera
5
+ include CamarasValenciaEs::Util::V8Unescaper
6
+ include CamarasValenciaEs::Util::LatLonConverter
7
+
5
8
  attr_accessor :id, :target, :address, :x, :y, :source, :type, :icon_type
6
9
 
7
10
  def initialize(id, x, y, target, source, address, type, icon_type)
8
11
  @id, @x, @y, @target, @source, @address, @type, @icon_type = id, x, y, target, source, address, type, icon_type
12
+ convert_to_lat_long
9
13
  end
10
14
 
11
15
  # TODO: DRY. Check SurveillancePost.parse
12
16
  def self.parse(json)
13
17
  defuck_coords = ->(v) {
14
- CGI.unescape(v).gsub(/,/,".").to_f
18
+ unescape(v).gsub(/,/,".").to_f
15
19
  }
16
20
 
17
21
  serializable = JSON.parse(json)
18
22
  # This JSON structure is fucking weird just for representing
19
- # a simple array of objects. An Array of Hashe would have been more than enough.
20
- # What they call latitude, and longitude is in fact UTM X/Y.
23
+ # a simple array of objects. An Array of Hashes would have been more than enough.
24
+ # What they call latitude, and longitude is in fact EPSG 23030 - ed50 / utm zone 30n.
21
25
  attrs = serializable['datos']
22
26
  attrs['idcamara'].collect.with_index { |idgrupo, i|
23
- x, y = defuck_coords.call(attrs['latitud'][i]), defuck_coords.call(attrs['longitud'][i])
24
- target, source, address = CGI.unescape(attrs['destino'][i]), CGI.unescape(attrs['origen'][i]), CGI.unescape(attrs['direccion'][i])
27
+ x, y = defuck_coords.call(attrs['longitud'][i]), defuck_coords.call(attrs['latitud'][i])
28
+ target, source, address = unescape(attrs['destino'][i]), unescape(attrs['origen'][i]), unescape(attrs['direccion'][i])
25
29
  self.new(attrs['idcamara'][i], x, y, target, source, address, attrs['tipo'][i], attrs['tipoicono'][i])
26
30
  }
27
31
  end
@@ -35,8 +39,26 @@ module CamarasValenciaEs
35
39
  self.parse SurveillanceCamera.get('/infocamaras.asp', query: { idgrupo: post_id}).body
36
40
  end
37
41
 
38
- def image
39
- CGI.unescape SurveillanceCamera.get('/imagen.asp', query: { idcamara: self.id}).body
42
+ def filename
43
+ @flags_and_filename ||= unescape(SurveillanceCamera.get('/imagen.asp', query: { idcamara: self.id}).body).split(';')
44
+ @flags_and_filename[1]
45
+ end
46
+
47
+ def media
48
+ @flags_and_filename ||= unescape(SurveillanceCamera.get('/imagen.asp', query: { idcamara: self.id}).body).split(';')
49
+ (@flags_and_filename[0] == '0')? :image : :video
50
+ end
51
+
52
+ # TODO
53
+ def to_attributes
54
+ {
55
+ location: [self.latlon.y, self.latlon.x],
56
+ remote_id: self.id,
57
+ media: self.media,
58
+ filename: self.filename,
59
+ recording_source: self.source,
60
+ recording_target: self.target
61
+ }
40
62
  end
41
63
  end
42
64
  end
@@ -3,12 +3,17 @@ require 'httparty'
3
3
  require 'cgi'
4
4
  require 'json'
5
5
 
6
+
6
7
  module CamarasValenciaEs
7
8
  class SurveillancePost
9
+ include CamarasValenciaEs::Util::V8Unescaper
10
+ include CamarasValenciaEs::Util::LatLonConverter
11
+
8
12
  attr_accessor :id, :x, :y, :icon_type, :street_name, :camera_count, :neighbourhood
9
13
 
10
14
  def initialize(id, x, y, icon_type)
11
15
  @id, @x, @y, @icon_type = id, x, y, icon_type
16
+ convert_to_lat_long
12
17
  end
13
18
 
14
19
  #attribute :id, type: String, match: 'idgrupo'
@@ -16,7 +21,7 @@ module CamarasValenciaEs
16
21
  #attribute :y, type: defuck_coords, match: 'longitud'
17
22
  #attribute :icon_type, type: String, match: 'tipoicono'
18
23
  #
19
- #parser WhyDidntTheyUseProperJSONParser
24
+ #parser WhyDidntTheyUseProperJSON
20
25
 
21
26
  def self.parse(json)
22
27
  defuck_coords = ->(v) {
@@ -24,12 +29,12 @@ module CamarasValenciaEs
24
29
  }
25
30
 
26
31
  serializable = JSON.parse(json)
27
- # This JSON structure is fucking weird just for representing
32
+ # This JSON structure is fucking weird just to implement
28
33
  # a simple array of objects. An Array of Hashe would have been more than enough.
29
34
  # What they call latitude, and longitude is in fact UTM X/Y.
30
35
  attrs = serializable['datos']
31
36
  attrs['idgrupo'].collect.with_index { |idgrupo, i|
32
- x, y = defuck_coords.call(attrs['latitud'][i]), defuck_coords.call(attrs['longitud'][i])
37
+ x, y = defuck_coords.call(attrs['longitud'][i]), defuck_coords.call(attrs['latitud'][i])
33
38
  self.new(attrs['idgrupo'][i], x, y, attrs['tipoicono'][i])
34
39
  }
35
40
  end
@@ -43,23 +48,43 @@ module CamarasValenciaEs
43
48
  self.parse(response_body)
44
49
  end
45
50
 
46
- def find_street_name_and_neighbourhood_and_camera_count
51
+ def load_attributes
47
52
  response_body = SurveillancePost.get('/infogrupo.asp', query: {idgrupo: id}).body
48
- response_body = response_body.split(/,/)
49
- self.camera_count = response_body.pop.to_i
50
- response_body = response_body.first.split(/-/)
51
- self.neighbourhood = CGI.unescape response_body.pop || ""
52
- self.street_name = CGI.unescape response_body.pop || ""
53
+ body_parts = response_body.split(/,/)
54
+ self.camera_count = body_parts.pop.to_i
55
+ body_parts = body_parts.first.split(/-/)
56
+
57
+ self.neighbourhood = unescape(body_parts.pop)
58
+ self.street_name = unescape(body_parts.pop)
59
+
60
+ response_body
53
61
  end
54
62
 
55
63
  def cameras
56
64
  @cameras ||= SurveillanceCamera.all(self.id)
57
65
  end
58
66
 
59
- protected
60
- def self.query_params(bbox)
61
- return {} unless bbox.present?
62
- {lat1: bbox[0], long1: bbox[1], lat2: bbox[2], long2: bbox[3]}
67
+ def to_attributes
68
+ {
69
+ remote_id: self.id,
70
+ location: [self.latlon.y, self.latlon.x],
71
+ address:
72
+ {
73
+ street_name: (self.street_name || "").strip,
74
+ neighbourhood_name: (self.neighbourhood || "").strip
75
+ },
76
+ surveillance_cameras: self.cameras_to_attributes
77
+ }
78
+ end
79
+
80
+ def cameras_to_attributes
81
+ self.cameras.map(&:to_attributes)
63
82
  end
83
+
84
+ protected
85
+ def self.query_params(bbox)
86
+ return {} unless bbox.present?
87
+ {lat1: bbox[0], long1: bbox[1], lat2: bbox[2], long2: bbox[3]}
88
+ end
64
89
  end
65
90
  end
@@ -0,0 +1,21 @@
1
+ require 'proj4'
2
+
3
+ module CamarasValenciaEs
4
+ module Util
5
+ module LatLonConverter
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ attr_accessor :latlon
10
+ end
11
+
12
+ protected
13
+ def convert_to_lat_long
14
+ # http://spatialreference.org/ref/epsg/23030/proj4/
15
+ @utm ||= Proj4::Projection.new proj: "utm", zone: "30N", units: "m", ellps: 'intl'
16
+ @point = Proj4::Point.new self.x, self.y
17
+ self.latlon = @utm.inverseDeg @point
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ require 'v8'
2
+
3
+ module CamarasValenciaEs
4
+ module Util
5
+ module V8Unescaper
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ def unescape(string)
10
+ unescape_helper string
11
+ end
12
+
13
+ protected
14
+ def unescape_helper(string)
15
+ @ctx ||= V8::Context.new
16
+ @ctx.eval(js_unescape(string))
17
+ end
18
+
19
+ def js_unescape(string)
20
+ "unescape('#{string}')"
21
+ end
22
+ end
23
+
24
+ def unescape(string)
25
+ self.class.unescape string
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module CamarasValenciaEs
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1 @@
1
+ 1%3B0480220120226.flv%3B0%3B
@@ -0,0 +1 @@
1
+ 0%3B0420420120226.jpg%3B0%3B
@@ -0,0 +1 @@
1
+ {"datos": {"idcamara": ["04802","04803","04804","04805"],"origen": ["AV.%20CID","PUENTE%20DE%20XIRIVELLA","V-30","V-30"],"destino": ["NUEVE%20DE%20OCTUBRE","A-3%20%28AUTOV%CDA%20DE%20MADRID%29","PUENTE%20DE%20XIRIVELLA","A-7%20E-15%20%28CIRCUNVALACI%D3N%29"],"direccion": ["85%2C857047","278%2C174671","18%2C731315","164%2C916169"],"latitud": ["4372215%2C133316","4372215%2C133316","4372215%2C133316","4372215%2C133316"],"longitud": ["722081%2C372995","722081%2C372995","722081%2C372995","722081%2C372995"],"tipo": [2,2,2,2],"tipoicono": ["1","1","1","1"]}}
@@ -0,0 +1 @@
1
+ MAESTRO%20RODRIGO%20-%20CAMP%20DEL%20TURIA,3
@@ -0,0 +1 @@
1
+ {"datos": {"idgrupo": ["001","002","003","004","005","006","007","008","009","010","011","012","013","014","015","016","017","018","019","020","021","022","023","024","025","026","027","028","029","030","031","032","033","034","035","036","037","038","039","040","041","042","043","044","045","046","047","048","049","050","051","052","053","054","055","056","057","058","059","060","061","062","063","064","065","066","067","068","069","070","071","072","073","074","075","076","077","078","079","080","081","082","083","084","085","086","087","088","089","090","091","092","093","094","095","096","097","098","099","100","101","102","103","108","109","110","111","112","113","114","115","116","117","118","119","120","121","122","123","124","125","126","127","128","129","130","131","132","133","134","135","136","137","140","141","142","143","144","145","146","147","148","149","150","151","152","153","154","155","156","157","158","159","160","161","162","163","169","171","172","243","244","245","255","256","257","258"],"latitud": ["4371877%2C3","4372054%2C26","4372155%2C288984","4372082%2C819854","4373730%2C818054","4371930%2C4865","4372107%2C38","4372302%2C927471","4372226%2C576425","4372140%2C740677","4372273%2C691468","4372338%2C848792","4372477%2C288347","4372204%2C954819","4372105%2C386876","4373072%2C555509","4373487%2C664822","4372448%2C605721","4372336%2C58837","4372646%2C944154","4373230%2C877979","4372952%2C26129","4371059%2C767622","4371552%2C04721","4372329%2C915962","4373085%2C209063","4372108%2C267675","4372351%2C26","4372026%2C430752","4372075%2C219696","4371763%2C576003","4372948%2C046848","4374466%2C280192","4374438%2C192976","4374880%2C6","4373997%2C544775","4373850%2C183328","4373917%2C552499","4373183%2C325255","4373396%2C655853","4373328%2C778575","4373213%2C040678","4373218%2C386123","4371635%2C513854","4371663%2C744294","4370979%2C784556","4370278%2C878365","4373048%2C660022","4373685%2C761636","4373559%2C738203","4373225%2C590064","4372922%2C865367","4372652%2C868193","4372941%2C715577","4372501%2C811219","4371989%2C377145","4372010%2C975286","4371789%2C015077","4371634%2C070327","4371319%2C4","4371766%2C02","4371238%2C124991","4370980%2C064898","4370982%2C982994","4371713%2C239789","4371040%2C037524","4372880%2C782677","4370712%2C437094","4374765%2C824729","4372215%2C133316","4370237%2C539428","4374129%2C913956","4373526%2C755223","4373725%2C02283","4372084%2C762093","4372523%2C916444","4371610%2C96099","4371609%2C13","4370896%2C456595","4370923%2C965041","4370985%2C554792","4373249%2C31313","4373716%2C212932","4371825%2C504459","4372342%2C548076","4372537%2C245512","4372213%2C951892","4371624%2C497485","4373267%2C697052","4373649%2C686988","4373362%2C374031","4371639%2C593852","4375101%2C676712","4375224%2C813475","4375438%2C758016","4370645%2C475992","4374616%2C6634","4373832%2C962966","4373743%2C169754","4371522%2C897756","4370961%2C07","4371181%2C456327","4371354%2C432517","4372704%2C15","4372682%2C121226","4372490%2C002923","4372603%2C289729","4373597%2C044334","4374663%2C285078","4375462%2C325352","4375483%2C061738","4373821%2C667979","4373574%2C575975","4370137%2C786248","4369869%2C933849","4369789%2C646181","4374812%2C857705","4374329%2C369791","4369707%2C096161","4369800%2C02128","4374155%2C260959","4374039%2C280598","4374499%2C923437","4371432%2C367011","4375171%2C506601","4375565%2C19419","4375596%2C552059","4370910%2C886982","4371364%2C777553","4371767%2C89","4371806%2C724134","4371432%2C338203","4370627%2C472178","4372822%2C89","4372299%2C69","4372339%2C93","4371870%2C39","4373898%2C38","4374338%2C85","4373775%2C39","4373493%2C67","4372326%2C52","4373466%2C84","4371749%2C65","4371796%2C74","4374350%2C93","4374647%2C4","4371088%2C76","4370408%2C09","4375869%2C45","4376297%2C52","4375442%2C16","4375629%2C11","4375201%2C79","4375776%2C2","4369656%2C41","4372443%2C83","4374848%2C64","4372541%2C17","4373279%2C02","4370781%2C79","4370581%2C48","4373839%2C74","4373661%2C64","4372343%2C48","4372343%2C48","4371585%2C92"],"longitud": ["726045%2C72","726348%2C5","727516%2C848891","727512%2C063188","725878%2C128173","725362%2C194554","725283%2C02","725119%2C555785","725507%2C247155","725793%2C805457","725382%2C446489","726169%2C653464","726310%2C502146","726033%2C660805","725932%2C867344","726359%2C878118","725799%2C237306","725054%2C297205","724655%2C714786","724918%2C240463","724607%2C159861","724766%2C062944","725224%2C740135","724930%2C10782","727143%2C721917","727838%2C93163","724411%2C137495","723300%2C34","723284%2C7345","723221%2C070054","724810%2C700963","724108%2C113063","724597%2C89088","724492%2C027393","725939%2C12","726927%2C628343","726872%2C635602","726769%2C036194","727559%2C139305","727032%2C864566","727007%2C533822","726966%2C881443","727338%2C333375","727000%2C873109","726831%2C24743","725890%2C291062","722903%2C974104","725117%2C439348","725426%2C475013","725188%2C889223","726559%2C37014","726862%2C930513","727689%2C835631","728245%2C648152","728116%2C558934","727970%2C822951","727837%2C190666","728444%2C400583","727869%2C458531","727812%2C27","727401%2C41","727402%2C270737","727589%2C134771","726968%2C753447","724129%2C343259","723594%2C615273","723243%2C362476","727134%2C735195","725547%2C380372","722081%2C372995","726328%2C912354","724036%2C915589","727444%2C340295","727198%2C289588","729350%2C632111","729400%2C224464","729071%2C029601","728791%2C58","724634%2C213686","724845%2C17857","724915%2C596427","729477%2C281264","729557%2C253092","727112%2C199471","726862%2C378127","726745%2C481018","726622%2C826637","722374%2C611994","723164%2C0182","724338%2C451458","723859%2C059833","723301%2C125141","723476%2C240845","723678%2C033025","723278%2C549551","727951%2C917475","723775%2C302898","725271%2C532307","725081%2C751871","727479%2C80845","728319%2C51","728258%2C928913","728764%2C732375","726330%2C84","726474%2C917098","726001%2C399229","726147%2C603969","728441%2C544067","725239%2C131965","724839%2C403176","724998%2C310491","723588%2C527473","723128%2C699816","724277%2C225209","724718%2C57789","725016%2C895905","722993%2C61837","723264%2C955498","725556%2C192915","726520%2C171647","725562%2C462689","724923%2C735472","727752%2C464329","729587%2C250607","727332%2C954599","726218%2C197751","725282%2C299103","729836%2C868294","729588%2C62233","729863%2C73","730248%2C956518","727858%2C998088","729423%2C770459","723873%2C49","723596%2C1","723017%2C18","724802%2C17","724194%2C31","724006%2C16","725296%2C66","725115%2C74","725429%2C32","724778%2C04","725851%2C45","725425%2C98","724400%2C47","725163%2C99","727496%2C07","728179%2C16","721128%2C66","721883%2C48","726602%2C38","726033%2C96","725417%2C17","725273%2C49","726267%2C52","725788%2C36","725670%2C54","725863%2C51","724319%2C74","728803%2C5","728585%2C8","727932%2C73","727852%2C36","729989%2C82","729767%2C17","722939%2C15"],"tipoicono": ["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","2","1","2","1","2","1","1","1","1","1","1","1"]}}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camaras_valencia_es
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-23 00:00:00.000000000 Z
12
+ date: 2012-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
16
- requirement: &70328969763020 !ruby/object:Gem::Requirement
16
+ requirement: &70194219471640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,21 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70328969763020
24
+ version_requirements: *70194219471640
25
25
  - !ruby/object:Gem::Dependency
26
- name: active_support
27
- requirement: &70328969762460 !ruby/object:Gem::Requirement
26
+ name: therubyracer
27
+ requirement: &70194219470840 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70194219470840
36
+ - !ruby/object:Gem::Dependency
37
+ name: proj4rb
38
+ requirement: &70194219470000 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ! '>='
@@ -32,7 +43,18 @@ dependencies:
32
43
  version: '0'
33
44
  type: :runtime
34
45
  prerelease: false
35
- version_requirements: *70328969762460
46
+ version_requirements: *70194219470000
47
+ - !ruby/object:Gem::Dependency
48
+ name: active_support
49
+ requirement: &70194219469420 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70194219469420
36
58
  description: A RESTful wrapper to the RESTful-like API at http://camaras.valencia.es
37
59
  to access traffic CCTV information.
38
60
  email:
@@ -50,7 +72,14 @@ files:
50
72
  - lib/camaras_valencia_es.rb
51
73
  - lib/camaras_valencia_es/surveillance_camera.rb
52
74
  - lib/camaras_valencia_es/surveillance_post.rb
75
+ - lib/camaras_valencia_es/util/lat_lon_converter.rb
76
+ - lib/camaras_valencia_es/util/v8_unescaper.rb
53
77
  - lib/camaras_valencia_es/version.rb
78
+ - spec/fixtures/imagen_1.json
79
+ - spec/fixtures/imagen_2.json
80
+ - spec/fixtures/infocaramas.json
81
+ - spec/fixtures/infogrupo.json
82
+ - spec/fixtures/infogrupos.json
54
83
  homepage: http://github.com/vicentereig/camaras_valencia_es
55
84
  licenses: []
56
85
  post_install_message:
@@ -75,4 +104,9 @@ rubygems_version: 1.8.16
75
104
  signing_key:
76
105
  specification_version: 3
77
106
  summary: A client to access http://camaras.valencia.es traffic CCTV information.
78
- test_files: []
107
+ test_files:
108
+ - spec/fixtures/imagen_1.json
109
+ - spec/fixtures/imagen_2.json
110
+ - spec/fixtures/infocaramas.json
111
+ - spec/fixtures/infogrupo.json
112
+ - spec/fixtures/infogrupos.json