Automatically exported from code.google.com/p/planningalerts
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.
 
 
 
 
 
 

109 line
3.5 KiB

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use CGI qw(:cgi);
  5. use HTML::TreeBuilder;
  6. use LWP::UserAgent;
  7. use XML::Writer;
  8. # The master URLs for the Dacorum planning search
  9. our $SearchURL = "http://www.dacorum.gov.uk/default.aspx?page=1495";
  10. our $InfoURL = "http://www.dacorum.gov.uk/Default.aspx?page=1497&ID=";
  11. our $CommentURL = "http://www.dacorum.gov.uk/Default.aspx?page=2847&ID=";
  12. # We're a CGI script...
  13. my $query = CGI->new();
  14. # Construct an LWP user agent
  15. our $UA = LWP::UserAgent->new(env_proxy => 1,
  16. cookie_jar => {},
  17. requests_redirectable => [ 'GET', 'HEAD', 'POST' ]);
  18. # Post the URL to get an initial blank form
  19. my $state = get_state(do_post());
  20. # Do the search
  21. my $page = do_post({"__VIEWSTATE" => $state,
  22. "Template:_ctl12:_ctl0:btnSearch" => "Search",
  23. "Template:_ctl12:_ctl0:tbRegistrationFromDay" => $query->param("day"),
  24. "Template:_ctl12:_ctl0:tbRegistrationFromMon" => $query->param("month"),
  25. "Template:_ctl12:_ctl0:tbRegistrationFromYear" => $query->param("year"),
  26. "Template:_ctl12:_ctl0:tbRegistrationToDay" => $query->param("day"),
  27. "Template:_ctl12:_ctl0:tbRegistrationToMon" => $query->param("month"),
  28. "Template:_ctl12:_ctl0:tbRegistrationToYear" => $query->param("year")});
  29. # Output an HTTP response header
  30. print $query->header(-type => "text/xml");
  31. # Create an XML output stream
  32. my $Writer = XML::Writer->new(DATA_MODE => 1);
  33. # Output the XML header data
  34. $Writer->xmlDecl("UTF-8");
  35. $Writer->startTag("planning");
  36. $Writer->dataElement("authority_name", "Dacorum Borough Council");
  37. $Writer->dataElement("authority_short_name", "Dacorum");
  38. $Writer->startTag("applications");
  39. # Find the result table
  40. my $table = $page->look_down("_tag" => "table", "class" => "FormDataGrid");
  41. # Process each row of the results
  42. foreach my $row ($table->look_down("_tag" => "tr"))
  43. {
  44. my @cells = $row->look_down("_tag" => "td");
  45. if ($cells[0]->attr("class") eq "FormGridDataItem" ||
  46. $cells[0]->attr("class") eq "FormGridAlternatingDataItem")
  47. {
  48. my $reference = $cells[0]->as_trimmed_text;
  49. my $address = $cells[1]->as_trimmed_text;
  50. my $description = $cells[2]->as_trimmed_text;
  51. my $date = $cells[3]->as_trimmed_text;
  52. my $postcode;
  53. if ($address =~ /\s+([A-Z]+\d+\s+\d+[A-Z]+)$/)
  54. {
  55. $postcode = $1;
  56. }
  57. $Writer->startTag("application");
  58. $Writer->dataElement("council_reference", $reference);
  59. $Writer->dataElement("address", $address);
  60. $Writer->dataElement("postcode", $postcode);
  61. $Writer->dataElement("description", $description);
  62. $Writer->dataElement("info_url", $InfoURL . $reference);
  63. $Writer->dataElement("comment_url", $CommentURL . $reference);
  64. $Writer->dataElement("date_received", $date);
  65. $Writer->endTag("application");
  66. }
  67. }
  68. # Finish off XML output
  69. $Writer->endTag("applications");
  70. $Writer->endTag("planning");
  71. $Writer->end();
  72. exit 0;
  73. # Extract the state from a page so we can repost it
  74. sub get_state
  75. {
  76. my $page = shift;
  77. my $viewstate = $page->look_down("_tag" => "input", "name" => "__VIEWSTATE");
  78. return $viewstate->attr("value");
  79. }
  80. # Post to the planning search page
  81. sub do_post
  82. {
  83. my $response = $UA->post($SearchURL, @_);
  84. die $response->status_line unless $response->is_success;
  85. return HTML::TreeBuilder->new_from_content($response->content);
  86. }