Guest User

Untitled

a guest
May 10th, 2012
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.02 KB | None | 0 0
  1. #!/usr/bin/env perl
  2. # We want to know if stuff is going to explode in our face
  3. use warnings;
  4. use strict;
  5.  
  6. # Awesome logging
  7. use Log::Log4perl;
  8.  
  9. # LWP is an awesome HTTP client
  10. use LWP::UserAgent;
  11. use HTTP::Request;
  12.  
  13. # For interacting with the API
  14. use XML::Simple;
  15.  
  16. # Mediawiki is too awesome to use unix time
  17. use Date::Parse;
  18. use Time::Local;
  19.  
  20. # Good for debugging
  21. use Data::Dumper;
  22.  
  23. =head1 NAME
  24. check_cluebotng.pl - A script to check cluebotng is running
  25.  
  26. =head1 OVERVIEW
  27. This script checks the last edit time against a threashold.
  28.  
  29. =head1 AUTHOR
  30. Damian Zaremba <[email protected]>
  31.  
  32. =head1 LICENSE
  33. This program is free software: you can redistribute it and/or modify
  34. it under the terms of the GNU General Public License as published by
  35. the Free Software Foundation, either version 3 of the License, or
  36. (at your option) any later version.
  37.  
  38. This program is distributed in the hope that it will be useful,
  39. but WITHOUT ANY WARRANTY; without even the implied warranty of
  40. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  41. GNU General Public License for more details.
  42.  
  43. You should have received a copy of the GNU General Public License
  44. along with this program. If not, see <http://www.gnu.org/licenses/>.
  45.  
  46. =head1 CONFIG
  47.  
  48. Hash of our config values
  49.  
  50. =head2 Required options
  51.  
  52. wiki_url - URL to the wiki api.php script
  53. threashold - Time threashold
  54. admins - Array of people to notify
  55.  
  56. =cut
  57.  
  58. # Config stuff
  59. my $config = {
  60. wiki_url => "http://en.wikipedia.org/w/api.php",
  61. threashold => 1800, # 30min
  62. admins => [
  63. ],
  64. };
  65.  
  66. my $VERSION = "0.1";
  67.  
  68. # Stuff we need everywhere
  69. our($logger);
  70.  
  71. =head1 METHODS
  72.  
  73. =head2 run
  74. Sets up everything and kicks off the process.
  75.  
  76. =head3 Arguments
  77. Takes no arguments.
  78.  
  79. =head3 Returns
  80. Returns nothing.
  81.  
  82. =cut
  83.  
  84. sub run {
  85. # Setup the logger object
  86. Log::Log4perl->easy_init();
  87. $logger = Log::Log4perl->get_logger();
  88.  
  89. # Error if we couldn't initialize the logger oject
  90. if( ! defined( $logger ) ) {
  91. print "!!! Could not init logger !!!\n";
  92. exit(1);
  93. }
  94.  
  95. $logger->info("Getting edit info");
  96. my $edit = get_last_edit();
  97.  
  98. if( get_last_edit() ) {
  99. $logger->info("Got edit info");
  100. my $editUNIXTime = str2time($edit->{'timestamp'});
  101. my $time = time();
  102. my $difference = $time-$editUNIXTime;
  103.  
  104. $logger->info("Checking edit time");
  105. if( $difference > $config->{'threashold'} ) {
  106. $logger->info("Bot not running!");
  107. notify_admins("Not running - last edit was " . $edit->{'title'} . " " . $difference . "s ago");
  108. notify_wiki("Not running - last edit was " . $edit->{'title'} . " " . $difference . "s ago");
  109. } else {
  110. $logger->info("Bot running!");
  111. notify_wiki("Running - last edit was " . $edit->{'title'} . " " . $difference . "s ago");
  112. }
  113. }
  114. }
  115.  
  116. =head2 get_last_edit
  117. Gets the lsat bot edit
  118.  
  119. =head3 Arguments
  120. Takes no arguments
  121.  
  122. =head3 Returns
  123. Hash of edit data.
  124.  
  125. =cut
  126.  
  127. sub get_last_edit {
  128. # user_agent to make the request with
  129. my $user_agent = LWP::UserAgent->new(
  130. timeout => 5,
  131. agent => "ClueBotNGChecker/v" . $VERSION,
  132. );
  133.  
  134. # URL to request
  135. my $url = $config->{"wiki_url"} . "?format=xml&action=query&list=usercontribs&ucuser=ClueBot_NG&uclimit=1";
  136.  
  137. # Request object
  138. my $request_object = HTTP::Request->new(
  139. GET => $url,
  140. );
  141.  
  142. # Make the request and store the response object
  143. my $response = $user_agent->request($request_object);
  144.  
  145. # Check if we didn't get a 200OK back
  146. if ( ! $response->is_success ) {
  147. $logger->error("Could not get " . $url . ", server returned: " . $response->status_line);
  148. return 0;
  149. } else {
  150. # Everything was good, get the content
  151. my $raw_data = $response->decoded_content;
  152.  
  153. # Data is where we will stick the config
  154. my $data;
  155.  
  156. # Try and load the returned XML
  157. eval {
  158. my $xml = new XML::Simple;
  159. $data = $xml->XMLin($raw_data);
  160. };
  161.  
  162. # If the XML was bad then error
  163. if( $@ ) {
  164. $logger->error("Could not process the api data: " . $@);
  165. return 0;
  166. } else {
  167. my $contributions = $data->{'query'}->{'usercontribs'};
  168. if(
  169. $contributions->{'item'} &&
  170. $contributions->{'item'}->{'timestamp'} &&
  171. $contributions->{'item'}->{'title'}
  172. ) {
  173. return $contributions->{'item'};
  174. }
  175. }
  176. }
  177. }
  178.  
  179. =head2 notify_wiki
  180. Updates the wiki check page
  181.  
  182. =head3 Arguments
  183. message - Message to update with
  184.  
  185. =head3 Returns
  186. Returns nothing.
  187.  
  188. =cut
  189.  
  190. sub notify_wiki {
  191. my $message = shift;
  192.  
  193. # user_agent to make the request with
  194. my $user_agent = LWP::UserAgent->new(
  195. timeout => 5,
  196. agent => "ClueBotNGChecker/v" . $VERSION,
  197. );
  198.  
  199. # URL to request
  200. my $url = $config->{"wiki_url"} . "?format=xml&action=edit&title=User:ClueBot_NG/running";
  201. $url .= "&summary=Uploading running status&token=%2B%5C" . "&text=" . $message;
  202.  
  203. # Request object
  204. my $request_object = HTTP::Request->new(
  205. POST => $url,
  206. );
  207.  
  208. # Make the request and store the response object
  209. my $response = $user_agent->request($request_object);
  210.  
  211. # Check if we didn't get a 200OK back
  212. if ( ! $response->is_success ) {
  213. $logger->error("Could not get " . $url . ", server returned: " . $response->status_line);
  214. return 0;
  215. } else {
  216. # Everything was good, get the content
  217. my $raw_data = $response->decoded_content;
  218.  
  219. # Data is where we will stick the config
  220. my $data;
  221.  
  222. # Try and load the returned XML
  223. eval {
  224. my $xml = new XML::Simple;
  225. $data = $xml->XMLin($raw_data);
  226. };
  227.  
  228. # If the XML was bad then error
  229. if( $@ ) {
  230. $logger->error("Could not process the api data: " . $@);
  231. return 0;
  232. } else {
  233. if( $data->{'edit'} && $data->{'edit'}->{'result'} eq "Success" ) {
  234. $logger->info("Wiki updted");
  235. } else {
  236. $logger->error("Could not update wiki");
  237. }
  238. }
  239. }
  240.  
  241. }
  242.  
  243. =head2 notify_admins
  244. Emails the cluebotng admins if it doesn't appear to be editing
  245.  
  246. =head3 Arguments
  247. message - Message to send
  248.  
  249. =head3 Returns
  250. Returns nothing
  251.  
  252. =cut
  253.  
  254. sub notify_admins {
  255. my $message = shift;
  256. my $admins = join(", ", @{ $config->{"admins"} });
  257.  
  258. $logger->info("Notifying admins: " . $admins);
  259. my $MAIL;
  260. open($MAIL, "|/usr/lib/sendmail -oi -t");
  261. print $MAIL "From: watcher\@cluebotng\n";
  262. print $MAIL "To: " . $admins . "\n";
  263. print $MAIL "Subject: Bot not running\n\n";
  264. print $MAIL "$message\n";
  265. close($MAIL)
  266. }
  267.  
  268. run();
Advertisement
Add Comment
Please, Sign In to add comment