PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/boinc/boinc/html/ops/team_import.php

http://decs.googlecode.com/
PHP | 247 lines | 193 code | 17 blank | 37 comment | 57 complexity | a5280743c9eb8f511975bef8eee71d24 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. #!/usr/bin/env php
  2. <?php
  3. // fetch a list of "BOINC-wide teams" and create or update them
  4. require_once("../inc/util.inc");
  5. require_once("../inc/user.inc");
  6. require_once("../inc/team.inc");
  7. require_once("../inc/email.inc");
  8. // set the following to 1 to print queries but not do anything
  9. $dry_run = 0;
  10. function lookup_team_seti_id($id) {
  11. $result = mysql_query("select * from team where seti_id=$id");
  12. if ($result) {
  13. $team = mysql_fetch_object($result);
  14. mysql_free_result($result);
  15. return $team;
  16. }
  17. return null;
  18. }
  19. function parse_team($f) {
  20. while ($s = fgets($f)) {
  21. if (strstr($s, '</team>')) {
  22. $t->name = htmlspecialchars_decode($t->name);
  23. $t->url = htmlspecialchars_decode($t->url);
  24. $t->name_html = htmlspecialchars_decode($t->name_html);
  25. $t->description = htmlspecialchars_decode($t->description);
  26. $t->user_name = htmlspecialchars_decode($t->user_name);
  27. $t->user_country = htmlspecialchars_decode($t->user_country);
  28. $t->user_postal_code = htmlspecialchars_decode($t->user_postal_code);
  29. $t->user_url = htmlspecialchars_decode($t->user_url);
  30. return $t;
  31. }
  32. else if (strstr($s, '<name>')) $t->name = parse_element($s, '<name>');
  33. else if (strstr($s, '<url>')) $t->url = parse_element($s, '<url>');
  34. else if (strstr($s, '<type>')) $t->type = parse_element($s, '<type>');
  35. else if (strstr($s, '<name_html>')) $t->name_html = parse_element($s, '<name_html>');
  36. else if (strstr($s, '<description>')) {
  37. while ($s = fgets($f)) {
  38. if (strstr($s, '</description>')) break;
  39. $t->description .= $s;
  40. }
  41. }
  42. else if (strstr($s, '<country>')) $t->country = parse_element($s, '<country>');
  43. else if (strstr($s, '<id>')) $t->id = parse_element($s, '<id>');
  44. else if (strstr($s, '<user_email_munged>')) {
  45. $user_email_munged = parse_element($s, '<user_email_munged>');
  46. $t->user_email = str_rot13($user_email_munged);
  47. }
  48. else if (strstr($s, '<user_name>')) $t->user_name = parse_element($s, '<user_name>');
  49. else if (strstr($s, '<user_country>')) $t->user_country = parse_element($s, '<user_country>');
  50. else if (strstr($s, '<user_postal_code>')) $t->user_postal_code = parse_element($s, '<user_postal_code>');
  51. else if (strstr($s, '<user_url>')) $t->user_url = parse_element($s, '<user_url>');
  52. }
  53. return null;
  54. }
  55. function valid_team($t) {
  56. if (!$t->id) return false;
  57. if (!$t->name) return false;
  58. if (!$t->user_email) return false;
  59. if (!$t->user_name) return false;
  60. return true;
  61. }
  62. function update_team($t, $team, $user) {
  63. global $dry_run;
  64. if (
  65. trim($t->url) == $team->url
  66. && $t->type == $team->type
  67. && trim($t->name_html) == $team->name_html
  68. && trim($t->description) == $team->description
  69. && $t->country == $team->country
  70. && $t->id == $team->seti_id
  71. ) {
  72. echo " no changes\n";
  73. return;
  74. }
  75. echo " updating\n";
  76. $url = process_user_text($t->url);
  77. $name_html = process_user_text($t->name_html);
  78. $description = process_user_text($t->description);
  79. $country = process_user_text($t->country);
  80. $query = "update team set url='$url', type=$t->type, name_html='$name_html', description='$description', country='$country', seti_id=$t->id where id=$team->id";
  81. if ($dry_run) {
  82. echo " $query\n";
  83. return;
  84. }
  85. $retval = mysql_query($query);
  86. if (!$retval) {
  87. echo " update failed: $query\n";
  88. exit;
  89. }
  90. }
  91. function insert_case($t, $user) {
  92. global $master_url;
  93. global $dry_run;
  94. if ($dry_run) {
  95. if (!$user) echo " making user $t->user_email\n";
  96. echo " making team $t->name\n";
  97. return;
  98. }
  99. if (!$user) {
  100. echo " making user $t->user_email\n";
  101. $user = make_user(mysql_real_escape_string($t->user_email), mysql_real_escape_string($t->user_name), random_string());
  102. if (!$user) {
  103. echo " Can't make user $t->user_email\n";
  104. echo mysql_error();
  105. exit;
  106. }
  107. }
  108. echo " making team $t->name\n";
  109. $team = make_team(
  110. $user->id, $t->name, $t->url, $t->type, $t->name_html,
  111. $t->description, $t->country
  112. );
  113. if (!$team) {
  114. echo " Can't make team $t->id\n";
  115. echo mysql_error();
  116. echo "\n";
  117. exit;
  118. }
  119. mysql_query("update team set seti_id=$t->id where id=$team->id");
  120. mysql_query("update user set teamid=$team->id where id=$user->id");
  121. send_email($user, "Team created on ".PROJECT,
  122. "An instance of the BOINC-wide team '$t->name'
  123. has been created on the project:
  124. name: ".PROJECT."
  125. URL: $master_url
  126. "
  127. );
  128. }
  129. // There are several cases for a given record:
  130. // (note: "ID" means the ID coming from BOINC, stored locally in seti_id)
  131. // insert case:
  132. // There's no team with given name; create one,
  133. // and create the user if needed
  134. // update1 case:
  135. // There's a team with the given name and the given ID
  136. // and its founder has the right email address.
  137. // Update its parameters if any are different.
  138. // update2 case:
  139. // There's a team with the given name and seti_id=0,
  140. // and its founder has the right email address.
  141. // Update its parameters if any are different,
  142. // and set its seti_id.
  143. // This handles the case where the team founder created the team
  144. // before this new system was run.
  145. // conflict case:
  146. // There's a team with the given name,
  147. // and either it has the wrong ID
  148. // or its founder has a different email address.
  149. // Don't change anything.
  150. // These semantics mean that:
  151. // - A BOINC team can't change its name via this mechanism.
  152. // This avoids pathological cases, e.g. if two teams swapped names,
  153. // the updates would always fail.
  154. // If a BOINC team wants to change its name,
  155. // it must do it manually everywhere.
  156. // - If a BOINC team changes its founder (or the founder changes email)
  157. // they'll have to make this change manually on all projects.
  158. // (this is better than a security vulnerability)
  159. // - This mechanism can't be used to update the founder's
  160. // account parameters on all projects
  161. function handle_team($f) {
  162. $t = parse_team($f);
  163. if (!$t) {
  164. echo "Failed to parse team\n";
  165. return;
  166. }
  167. //print_r($t);
  168. //return;
  169. if (!valid_team($t)) {
  170. echo "Invalid team\n";
  171. return;
  172. }
  173. echo "Processing $t->name $t->user_email\n";
  174. $user = lookup_user_email_addr($t->user_email);
  175. $team = lookup_team_name($t->name);
  176. if ($team) {
  177. if (!$user) {
  178. echo " team exists but user $t->user_email doesn't\n";
  179. return;
  180. }
  181. if ($user->id != $team->userid) {
  182. echo " team exists but is owned by a different user\n";
  183. return;
  184. }
  185. if ($team->seti_id) {
  186. if ($team->seti_id == $t->id) {
  187. echo " case 1\n";
  188. update_team($t, $team, $user); // update1 case
  189. } else {
  190. echo " team exists but has wrong seti_id\n";
  191. }
  192. } else {
  193. $team2 = lookup_team_seti_id($t->id);
  194. if ($team2) {
  195. // update1 case
  196. echo " case 2\n";
  197. update_team($t, $team2, $user);
  198. } else {
  199. // update2 case
  200. echo " case 3\n";
  201. update_team($t, $team, $user);
  202. }
  203. }
  204. } else {
  205. $team = lookup_team_seti_id($t->id);
  206. if ($team) {
  207. echo " A team with same ID but different name exists;\n";
  208. echo " Please report this to $t->user_email;\n";
  209. } else {
  210. echo " Adding team\n";
  211. insert_case($t, $user);
  212. }
  213. }
  214. }
  215. function main() {
  216. $f = fopen("http://boinc.berkeley.edu/boinc_teams.xml", "r");
  217. if (!$f) {
  218. echo "Can't get times file\n";
  219. exit;
  220. }
  221. while ($s = fgets($f)) {
  222. if (strstr($s, '<team>')) {
  223. handle_team($f);
  224. }
  225. }
  226. }
  227. db_init();
  228. main();
  229. ?>