A Ruby gem to get planning applications data from UK council websites.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

152 rivejä
4.0 KiB

  1. require 'date'
  2. module UKPlanningScraper
  3. class Authority
  4. # Parameter methods for Authority#scrape
  5. # Desgined to be method chained, eg:
  6. #
  7. # applications = UKPlanningScraper::Authority.named("Barnet"). \
  8. # development_type("Q22").keywords("illuminat"). \
  9. # validated_days(30).scrape
  10. def validated_days(n)
  11. # Validated within the last n days
  12. # Assumes that every scraper/system can do a date range search
  13. check_class(n, Integer)
  14. unless n > 0
  15. raise ArgumentError.new("validated_days must be greater than 0")
  16. end
  17. validated_from(Date.today - (n - 1))
  18. validated_to(Date.today)
  19. self
  20. end
  21. def received_days(n)
  22. # received within the last n days
  23. # Assumes that every scraper/system can do a date range search
  24. check_class(n, Integer)
  25. unless n > 0
  26. raise ArgumentError.new("received_days must be greater than 0")
  27. end
  28. received_from(Date.today - (n - 1))
  29. received_to(Date.today)
  30. self
  31. end
  32. def decided_days(n)
  33. # decided within the last n days
  34. # Assumes that every scraper/system can do a date range search
  35. check_class(n, Integer)
  36. unless n > 0
  37. raise ArgumentError.new("decided_days must be greater than 0")
  38. end
  39. decided_from(Date.today - (n - 1))
  40. decided_to(Date.today)
  41. self
  42. end
  43. def applicant_name(s)
  44. unless system == 'idox'
  45. raise NoMethodError.new("applicant_name is only implemented for Idox. \
  46. This authority (#{@name}) is #{system.capitalize}.")
  47. end
  48. check_class(s, String)
  49. @scrape_params[:applicant_name] = s.strip
  50. self
  51. end
  52. def case_officer_code(s)
  53. unless system == 'northgate'
  54. raise NoMethodError.new("case_officer_code is only implemented for Northgate. \
  55. This authority (#{@name}) is #{system.capitalize}.")
  56. end
  57. check_class(s, String)
  58. @scrape_params[:case_officer_code] = s.strip
  59. self
  60. end
  61. def application_type(s)
  62. unless system == 'idox'
  63. raise NoMethodError.new("application_type is only implemented for \
  64. Idox. This authority (#{@name}) is #{system.capitalize}.")
  65. end
  66. check_class(s, String)
  67. @scrape_params[:application_type] = s.strip
  68. self
  69. end
  70. def development_type(s)
  71. unless system == 'idox'
  72. raise NoMethodError.new("development_type is only implemented for \
  73. Idox. This authority (#{@name}) is #{system.capitalize}.")
  74. end
  75. check_class(s, String)
  76. @scrape_params[:development_type] = s.strip
  77. self
  78. end
  79. def status(s)
  80. check_class(s, String)
  81. @scrape_params[:status] = s.strip
  82. self
  83. end
  84. private
  85. # Handle the simple params with this
  86. def method_missing(method_name, *args)
  87. sc_params = {
  88. validated_from: Date,
  89. validated_to: Date,
  90. received_from: Date,
  91. received_to: Date,
  92. decided_from: Date,
  93. decided_to: Date,
  94. keywords: String
  95. }
  96. value = args[0]
  97. if sc_params[method_name]
  98. check_class(value, sc_params[method_name], method_name.to_s)
  99. value.strip! if value.class == String
  100. if value.class == Date && value > Date.today
  101. raise ArgumentError.new("#{method_name} can't be a date in the " + \
  102. "future (#{value.to_s})")
  103. end
  104. @scrape_params[method_name] = value
  105. self
  106. else
  107. raise NoMethodError.new(method_name.to_s)
  108. end
  109. end
  110. def clear_scrape_params
  111. @scrape_params = {}
  112. end
  113. # https://stackoverflow.com/questions/5100299/how-to-get-the-name-of-the-calling-method
  114. def check_class(
  115. param_value,
  116. expected_class,
  117. param_name = caller_locations(1, 1)[0].label) # name of calling method
  118. unless param_value.class == expected_class
  119. raise TypeError.new("#{param_name} must be a " \
  120. "#{expected_class} not a #{param_value.class.to_s}")
  121. end
  122. end
  123. end
  124. end