-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrunbot.php
executable file
·190 lines (175 loc) · 6.58 KB
/
runbot.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
<?php
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );
ini_set( 'max_execution_time', 600 );
// Exit if not run from command-line
if ( php_sapi_name() !== 'cli' ) {
echo "This script should be run from the command-line.";
die();
}
// Set up configuration and wikipedia class
require_once dirname(__FILE__) . '/config.inc.php';
require_once dirname(__FILE__) . '/botclasses.php';
// Set $verbose to true to see how long each subscription takes to process.
$verbose = false;
function getEditCounts( $link, $source, $days = 3, $limit = 5, $method = 'category' ) {
$pages = array();
if ( $days <= 30 ) {
// Retrieve the ID and timestamp of the first revision within the requested time period.
$result = mysqli_query($link, "select s.rev_id,s.rev_timestamp from revision as s where s.rev_timestamp> DATE_FORMAT(DATE_SUB(NOW(),INTERVAL " . $days . " DAY),'%Y%m%d%H%i%s') order by s.rev_timestamp asc limit 1;");
if ( $result ) {
while ( $row = mysqli_fetch_array( $result ) ) {
$revId = $row['rev_id'];
$revTimestamp = $row['rev_timestamp'];
}
// Retrieve the pages with the most revisions since the threshold revision.
if ( isset( $revId ) && $revId && isset( $revTimestamp ) && $revTimestamp ) {
$source = mysqli_real_escape_string( $link, $source );
if ( $method === 'template' ) {
$subquery = "select a.page_id,a.page_title from templatelinks join page as t on t.page_id=tl_from and t.page_namespace=1 join page as a on a.page_title=t.page_title and a.page_namespace=0 where tl_title='".$source."' and a.page_latest>".$revId;
} else {
$subquery = "select a.page_id,a.page_title from categorylinks join page as t on t.page_id=cl_from and t.page_namespace=1 join page as a on a.page_title=t.page_title and a.page_namespace=0 where cl_to='".$source."' and a.page_latest>".$revId;
}
$query = "select main.page_title as title,count(main.rc_minor) as ctall, sum(main.rc_minor) from (select tt.page_title,rc_minor from recentchanges join (".$subquery.") as tt on rc_cur_id=tt.page_id where rc_timestamp>".$revTimestamp." and rc_type<2) as main group by main.page_title order by ctall desc limit ".$limit.";";
$result = mysqli_query( $link, $query );
if ( $result ) {
while ( $row = mysqli_fetch_array( $result ) ) {
$title = str_replace( '_', ' ', $row['title'] );
$pages[$title] = $row['ctall'];
}
} else {
echo "No pages retrieved. " . mysqli_error( $link ) . "\n";
}
} else {
echo "ID or timestamp of first revision invalid.\n";
}
} else {
echo "Could not retrieve ID and timestamp of first revision.\n";
}
} else {
echo "Days greater than maximum.\n";
}
return $pages;
}
/**
* Fetch all the subscription data for the bot
*
* @param object $wikipedia The interface object for Wikipedia
* @param string $project The name of a specific WikiProject (e.g. "WikiProject
* Spiders"). If no project is specified, config data for all the projects
* will be returned.
* @return array The configuration data
* @throws Exception
*/
function getSubscriptions( $wikipedia, $project = null ) {
$configPage = 'User:HotArticlesBot/Config.json';
$page = $wikipedia->getpage( $configPage );
if ( $page ) {
$res = json_decode( $page, true );
$config = [];
foreach ( $res as $key => $values ) {
// Skip the description of the config page format
if ( $key === 'description' ) {
continue;
}
// If a specific project was requested, skip other projects
if ( $project && $key !== $project ) {
continue;
}
$config[$key] = [
'category' => $values['Category'],
'page' => $values['Page'],
'articles' => $values['Articles'],
'days' => $values['Days'],
'orange' => $values['Orange'],
'red' => $values['Red']
];
}
return $config;
} else {
throw new Exception( 'Could not retrieve config page.' );
}
}
function isSubscriptionSane( $subscription ) {
if ( strpos( $subscription['page'], 'Wikipedia:' ) === 0 &&
$subscription['articles'] >= 5 &&
$subscription['articles'] <= 10 &&
$subscription['days'] >= 1 &&
$subscription['days'] <= 7 &&
$subscription['orange'] > 0 &&
$subscription['red'] > 0
) {
return true;
} else {
return false;
}
}
$wikipedia = new wikipedia();
// Log in to wikipedia
$wikipedia->login( $enwiki['user'], $enwiki['pass'] );
if ( isset( $argv[1] ) ) {
$subscriptions = getSubscriptions( $wikipedia, $argv[1] );
} else {
$subscriptions = getSubscriptions( $wikipedia );
}
$link = mysqli_connect($enwikidb['host'], $enwikidb['user'], $enwikidb['pass'], $enwikidb['dbname']);
// Fetch all the subscriptions and generate a chart for each
foreach ( $subscriptions as $subscriptionName => $row ) {
if ( !isSubscriptionSane( $row ) ) {
echo "Subscription for ".$subscriptionName." is malformed. Skipping.\n";
continue;
}
$time_start = microtime(true);
// Allow up to 5 minutes for each chart to be generated. This resets max_execution_time.
set_time_limit( 300 );
$category = str_replace( ' ', '_', $row['category'] );
$count = $wikipedia->categorypagecount( 'Category:'.$category );
if ( $count < $maxArticles ) {
$editCounts = getEditCounts( $link, $category, $row['days'], $row['articles'] );
} else {
echo "Category ".$row['category']." is too large. Skipping.\n";
continue;
}
$output = "{|\n";
$validUpdate = false;
foreach ( $editCounts as $key => $value ) {
if ( $value != '' && $key != '' ) {
$validUpdate = true;
switch ( true ) {
case ( $value >= $row['red'] ):
$color = '#c60d27';
break;
case ( $value >= $row['orange'] ):
$color = '#f75a0d';
break;
case ( $value > 0 ):
$color = '#ff9900';
break;
}
$output .= <<<WIKITEXT
|-
| style="text-align:center; font-size:130%; color:white; background:$color; padding:0 0.2em; vertical-align:middle;" | '''$value''' <span style="font-size:60%">edits</span>
| style="padding: 0.4em;" | [[$key]]
WIKITEXT;
$output .= "\n";
}
}
$output .= <<<WIKITEXT
|-
| style="padding: 0.1em;" |
|}
WIKITEXT;
$wordarray = array('zero','one','two','three','four','five','six','seven','eight','nine','ten');
$date = date('j F Y', time());
$output .= "\n<small>These are the articles that have been edited the most within the last ".$wordarray[$row['days']]." days. Last updated $date by [[User:HotArticlesBot|HotArticlesBot]].</small>\n";
if ( $validUpdate ) {
$edit = $wikipedia->edit($row['page'],$output,'Updating for '.date('F j, Y'));
}
$time_end = microtime(true);
$execution_time = round( $time_end - $time_start, 2 );
if ($verbose) {
echo $subscriptionName . " (" . $execution_time . " seconds)\n";
}
}
$date = date('j F Y', time());
echo "$date: Bot run\n";