Lots of little fixes for import, status should be imported mostly OK now.

A dded a migration_steps.txt that outlines the steps to migrate data.

Still todo:
* Extensions/addons, skipped now, will do next week
* Hide some unnecessary transactions
* Figure out policies for tasks and projects
* Test run over all tasks to see that they work
This commit is contained in:
2013-11-02 20:18:13 +01:00
committed by Sergey Sharybin
parent 41a820fdf0
commit 5abc5cf9f8
11 changed files with 974 additions and 800 deletions

View File

@@ -2,10 +2,6 @@
$migrate_dedup_users = array();
// XXX
$migrate_dedup_users["quick_testing_hack"] = "brechtvl";
$migrate_dedup_users["quick_testing_more"] = "brechtvl";
$migrate_dedup_users["midiclub"] = "midclub";
$migrate_dedup_users["trip"] = "car";
$migrate_dedup_users["thunderbolt"] = "thunderbolt16";

View File

@@ -1,10 +0,0 @@
./export_task.php 1 5000
./export_task.php 5000 10000
./export_task.php 10000 15000
./export_task.php 15000 20000
./export_task.php 20000 25000
./export_task.php 25000 30000
./export_task.php 30000 35000
./export_task.php 35000 38000

View File

@@ -29,8 +29,8 @@ require_once 'storage.php';
function lookup_user_name($user_id)
{
$res = db_query_params ('SELECT user_name FROM users WHERE user_id=$1', array($user_id));
return db_result($res, 0, 'user_name');
$res = db_query_params ('SELECT user_name FROM users WHERE user_id=$1', array($user_id));
return db_result($res, 0, 'user_name');
}
for ($aid=intval($argv[1]); $aid<intval($argv[2]); $aid++) {
@@ -40,32 +40,32 @@ $group_id = null;
$atid = null;
if ($aid && (!$group_id && !$atid)) {
$a =& artifact_get_object($aid);
$a =& artifact_get_object($aid);
if (!$a || !is_object($a) || $a->isError()) {
echo "SKIP " . $aid . "\n";
continue;
} else {
echo "GO " . $aid . "\n";
$group_id=$a->ArtifactType->Group->getID();
$atid=$a->ArtifactType->getID();
}
if (!$a || !is_object($a) || $a->isError()) {
echo "SKIP " . $aid . "\n";
continue;
} else {
echo "GO " . $aid . "\n";
$group_id=$a->ArtifactType->Group->getID();
$atid=$a->ArtifactType->getID();
}
}
$group =& group_get_object($group_id);
if (!$group || !is_object($group) || $group->isError())
echo "Group invalid\n";
echo "Group invalid\n";
$ath = new ArtifactTypeHtml($group,$atid);
if (!$ath || !is_object($ath) || $ath->isError())
echo "Artifact type invalid\n";
echo "Artifact type invalid\n";
$ah=new ArtifactHtml($ath,$aid);
if (!$ah || !is_object($ah) || $ah->isError())
echo "Artifact invalid\n";
echo "Artifact invalid\n";
/* create task */
$mtasks = array();
@@ -88,11 +88,11 @@ $result= $ah->getMessages();
$rows=db_numrows($result);
for ($i=0; $i < $rows; $i++) {
$mcomment = new MigrateComment();
$mcomment->user = db_result($result, $i,'user_name');
$mcomment->description = db_result($result, $i, 'body');
$mcomment->date = db_result($result, $i, 'adddate');
$mtask->comments[] = $mcomment;
$mcomment = new MigrateComment();
$mcomment->user = db_result($result, $i,'user_name');
$mcomment->description = db_result($result, $i, 'body');
$mcomment->date = db_result($result, $i, 'adddate');
$mtask->comments[] = $mcomment;
}
/* history */
@@ -103,37 +103,36 @@ $historyrows= db_numrows($history);
$file_list =& $ah->getFiles();
$rows=count($file_list);
// TODO skipping attachments for now
/*for ($i=0; $i<$rows; $i++) {
$af = $file_list[$i];
for ($i=0; $i<$rows; $i++) {
$af = $file_list[$i];
$afd=new ArtifactFile($ah,$af->getID());
$afd=new ArtifactFile($ah,$af->getID());
$fileuser = null;
$fileuser = null;
for ($j=0; $j < $historyrows; $j++) {
$hvalue = db_result($history, $j, 'old_value');
if($hvalue == $af->getID() + ": " + $af->getName())
$fileuser = db_result($history, $j, 'user_name');
}
for ($j=0; $j < $historyrows; $j++) {
$hvalue = db_result($history, $j, 'old_value');
if($hvalue == $af->getID() + ": " + $af->getName())
$fileuser = db_result($history, $j, 'user_name');
}
$mfile = new MigrateFile();
$mfile->user = $fileuser;
$mfile->name = $af->getName();
$mfile->date = $af->getDate();
$mfile->type = $af->getType();
$mfile->contents = $afd->getData();
$mtask->files[] = $mfile;
}*/
$mfile = new MigrateFile();
$mfile->user = $fileuser;
$mfile->name = $af->getName();
$mfile->date = $af->getDate();
$mfile->type = $af->getType();
$mfile->contents = $afd->getData();
$mtask->files[] = $mfile;
}
/* history */
for ($i=0; $i < $historyrows; $i++) {
$mhistory = new MigrateHistory();
$mhistory->user = db_result($history, $i, 'user_name');
$mhistory->date = db_result($history, $i, 'entrydate');
$mhistory->field = db_result($history, $i, 'field_name');
$mhistory->old = db_result($history, $i, 'old_value');
$mtask->history[] = $mhistory;
$mhistory = new MigrateHistory();
$mhistory->user = db_result($history, $i, 'user_name');
$mhistory->date = db_result($history, $i, 'entrydate');
$mhistory->field = db_result($history, $i, 'field_name');
$mhistory->old = db_result($history, $i, 'old_value');
$mtask->history[] = $mhistory;
}
/* subscribers */
@@ -142,19 +141,19 @@ $ccids = util_result_column_to_array($res);
$ccs = array();
foreach($ccids as $ccid)
if($ccid)
$ccs[] = lookup_user_name($ccid);
if($ccid)
$ccs[] = lookup_user_name($ccid);
if($ah->getAssignedTo())
$ccs[] = lookup_user_name($ah->getAssignedTo());
$ccs[] = lookup_user_name($ah->getAssignedTo());
if($ah->getSubmittedBy())
$ccs[] = lookup_user_name($ah->getSubmittedBy());
$ccs[] = lookup_user_name($ah->getSubmittedBy());
$result= $ah->getMessages();
$rows=db_numrows($result);
for ($i=0; $i < $rows; $i++)
$ccs[] = lookup_user_name(db_result($result,$i,'user_id'));
$ccs[] = lookup_user_name(db_result($result,$i,'user_id'));
$mtask->ccs = array_unique($ccs);
$mtask->extra_fields = $ah->getExtraFieldDataText();

View File

@@ -38,16 +38,16 @@ $musers = array();
for ($i = 0; $i < count ($user_names); $i++)
{
$muser = new MigrateUser();
$muser->id = $user_ids[$i];
$muser->password = $user_pws[$i];
$muser->name = $user_names[$i];
$muser->realname = trim($user_realnames[$i]);
$muser->email = $user_emails[$i];
$muser->date = $user_dates[$i];
$muser->timezone = $user_timezones[$i];
$muser = new MigrateUser();
$muser->id = $user_ids[$i];
$muser->password = $user_pws[$i];
$muser->name = $user_names[$i];
$muser->realname = trim($user_realnames[$i]);
$muser->email = $user_emails[$i];
$muser->date = $user_dates[$i];
$muser->timezone = $user_timezones[$i];
$musers[] = $muser;
$musers[] = $muser;
}
file_put_contents('dump/users', serialize($musers));

View File

@@ -1,10 +0,0 @@
./import_task.php 1 5000
./import_task.php 5000 10000
./import_task.php 10000 15000
./import_task.php 15000 20000
./import_task.php 20000 25000
./import_task.php 25000 30000
./import_task.php 30000 35000
./import_task.php 35000 38000

View File

@@ -7,11 +7,9 @@ require_once 'storage.php';
require_once 'adapt.php';
require_once 'phab.php';
// TODO: add all necessary projects
/* projects */
create_project("BF Blender", "None", true, $bf_developers, "Blender Foundation official release.");
create_project("Extensions", "None", true, $addon_developers, "Addon scripts and plugins for Blender.");
create_project("Addons", "None", true, $addon_developers, "Addon scripts and plugins for Blender.");
create_project("Translations", "None", true, $translation_developers, "Localization of Blender in different languages.");
/* modules */

View File

@@ -8,423 +8,487 @@ require_once 'adapt.php';
require_once 'phab.php';
for($id = intval($argv[1]); $id < intval($argv[2]); $id+=1) {
/* unserialize */
$fname = "dump/task_" . $id;
if(!file_exists($fname))
continue;
//echo "IMPORT " . $id . "\n";
/* unserialize */
$fname = "dump/task_" . $id;
if(!file_exists($fname))
continue;
//echo "IMPORT " . $id . "\n";
$fcontents = file_get_contents($fname);
$mtask = unserialize($fcontents);
$fcontents = file_get_contents($fname);
$mtask = unserialize($fcontents);
/* extract basic data */
$author = lookup_user(dedup_user($mtask->author));
$assign = lookup_user(dedup_user($mtask->assign));
$projects = array();
// 100 Unbreak Now!, 90 Needs Triage, 80 High, 50 Normal, 25 Low, 0, Wishlist
$status = ManiphestTaskStatus::STATUS_OPEN;
$description = '%%%' . html_entity_decode($mtask->description) . '%%%'; // TODO replace urls
$title = html_entity_decode($mtask->title);
/* extract basic data */
$author = lookup_user(dedup_user($mtask->author));
$assign = lookup_user(dedup_user($mtask->assign));
$projects = array();
$status = ManiphestTaskStatus::STATUS_OPEN;
$description = '%%%' . html_entity_decode($mtask->description) . '%%%';
$title = html_entity_decode($mtask->title);
/* spam detection */
if(($author == "None" || $author == null) && startsWith($description, "%%%<a href= http://") && strpos($title, " ") == false)
continue;
/* spam detection */
if(($author == "None" || $author == null) && startsWith($description, "%%%<a href= http://") && strpos($title, " ") == false)
continue;
/* missing author */
if($author == null)
$author = lookup_user("None");
if($assign && $assign->getUsername() == "None")
$assign = null;
/* extra fields */
$extra = "";
$extension_type = "None";
$task_type = "Bug";
/* missing author */
if($author == null)
$author = lookup_user("None");
if($assign && $assign->getUsername() == "None")
$assign = null;
/* extra fields */
$extra = "";
$task_type = "Bug";
$remove_subscribers = false;
/* BF Blender tasks */
if($mtask->project == "Blender 2.x BF release") {
$projects[] = lookup_project("BF Blender")->getPHID();
$category = null;
$category_key = null;
$mstatus = null;
$mstatus_key = null;
$resolution = null;
$resolution_key = null;
$old_resolution = null;
$old_resolution_key = null;
$data_type = null;
$date_type_key = null;
/* BF Blender tasks */
if($mtask->project == "Blender 2.x BF release") {
$category = null;
$category_key = null;
$mstatus = null;
$mstatus_key = null;
$resolution = null;
$resolution_key = null;
$old_resolution = null;
$old_resolution_key = null;
$data_type = null;
$date_type_key = null;
foreach($mtask->extra_fields as $key => $field) {
if($field['name'] == "Category") {
$category = $field['value'];
$category_key = $key;
}
else if($field['name'] == "Status") {
$mstatus = $field['value'];
$mstatus_key = $key;
}
else if($field['name'] == "Resolution") {
$resolution = $field['value'];
$resolution_key = $key;
}
else if($field['name'] == "Resolution(Old, use status)") {
$old_resolution = $field['value'];
$old_resolution_key = $key;
}
else if($field['name'] == "Data Type") {
$data_type = $field['value'];
$data_type_key = $key;
}
}
foreach($mtask->extra_fields as $key => $field) {
if($field['name'] == "Category") {
$category = $field['value'];
$category_key = $key;
}
else if($field['name'] == "Status") {
$mstatus = $field['value'];
$mstatus_key = $key;
}
else if($field['name'] == "Resolution") {
$resolution = $field['value'];
$resolution_key = $key;
}
else if($field['name'] == "Resolution(Old, use status)") {
$old_resolution = $field['value'];
$old_resolution_key = $key;
}
else if($field['name'] == "Data Type") {
$data_type = $field['value'];
$data_type_key = $key;
}
}
if($mtask->tracker == "Blender 2.6 Bug Tracker") {
$close_as_archived = false;
$task_type = "Bug";
$priority = 50;
if($mtask->tracker == "Blender 2.6 Bug Tracker") {
$projects[] = lookup_project("BF Blender")->getPHID();
$close_as_archived = false;
$task_type = "Bug";
$priority = 40;
if($category) {
if($bf_blender_categories[$category])
$projects[] = lookup_project($bf_blender_categories[$category])->getPHID();
unset($mtask->extra_fields[$category_key]);
}
if($category) {
if($bf_blender_categories[$category])
$projects[] = lookup_project($bf_blender_categories[$category])->getPHID();
unset($mtask->extra_fields[$category_key]);
}
// TODO: add more statuses or fields
switch($mstatus) {
case "New":
$priority = 90;
break;
case "Reopened":
break;
case "Investigate":
break;
case "Confirmed":
break;
case "Incomplete":
break;
case "Fixed / Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Rejected / Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
break;
case "Todo / Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Out of scope / Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Ready":
break;
case "*RELEASE BLOCKER*":
$priority = 80;
break;
default:
echo "ERROR: unkown status \"" . $mstatus . "\" (" . $id . ")\n";
break;
}
switch($mstatus) {
case "New":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Reopened":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Investigate":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Confirmed":
$priority = 50;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Incomplete":
$priority = 30;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Fixed / Closed":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Rejected / Closed":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Closed":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Todo / Closed":
$task_type = "To Do";
$priority = 40;
$assign = null;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
break;
case "Out of scope / Closed":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Ready":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "*RELEASE BLOCKER*":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
default:
echo "ERROR: unkown status \"" . $mstatus . "\" (" . $id . ")\n";
break;
}
unset($mtask->extra_fields[$mstatus_key]);
}
else if($mtask->tracker == "Blender 2.4x Bug Tracker") {
// TODO: handle status
$task_type = "Bug";
$priority = 50;
$close_as_archived = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
else if($mtask->tracker == "Game Engine") {
// TODO: add more statuses or fields
switch($mstatus) {
case "None":
case "New":
case "Reopened":
case "Investigate":
case "Ready":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Fixed":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Duplicate":
$status = ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE;
break;
case "Rejected":
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
default:
echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n";
break;
}
unset($mtask->extra_fields[$mstatus_key]);
}
else if($mtask->tracker == "Blender 2.4x Bug Tracker") {
$projects[] = lookup_project("BF Blender")->getPHID();
$task_type = "Bug";
$priority = 20;
$close_as_archived = true;
$remove_subscribers = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
else if($mtask->tracker == "Game Engine") {
$projects[] = lookup_project("BF Blender")->getPHID();
$projects[] = lookup_project("Game Engine")->getPHID();
$task_type = "Bug";
$priority = 40;
$close_as_archived = false;
$status = ManiphestTaskStatus::STATUS_OPEN;
unset($mtask->extra_fields[$mstatus_key]);
switch($mstatus) {
case "New":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "None":
case "Reopened":
case "Investigate":
case "Ready":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Fixed":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Duplicate":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE;
break;
case "Rejected":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Closed":
$priority = 40;
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
default:
echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n";
break;
}
$projects[] = lookup_project("Game Engine")->getPHID();
$task_type = "Bug";
$priority = 50;
$close_as_archived = false;
$status = ManiphestTaskStatus::STATUS_OPEN;
}
else if($mtask->tracker == "Todo") {
$task_type = "To Do";
$priority = 0;
$close_as_archived = false;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
else if($mtask->tracker == "OpenGL errors") {
$task_type = "OpenGL Error";
$priority = 25;
$close_as_archived = false;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
else if($mtask->tracker == "Patches") {
$task_type = "Patch";
$priority = 50;
$close_as_archived = false;
unset($mtask->extra_fields[$mstatus_key]);
}
else if($mtask->tracker == "Todo") {
$projects[] = lookup_project("BF Blender")->getPHID();
$task_type = "To Do";
$assign = null;
$priority = 20;
$close_as_archived = false;
$remove_subscribers = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
else if($mtask->tracker == "OpenGL errors") {
$projects[] = lookup_project("BF Blender")->getPHID();
$task_type = "OpenGL Error";
$priority = 20;
$close_as_archived = false;
$remove_subscribers = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
else if($mtask->tracker == "Patches") {
$projects[] = lookup_project("BF Blender")->getPHID();
$task_type = "Patch";
$priority = 40;
$close_as_archived = false;
if($category) {
if($bf_blender_categories[$category])
$projects[] = lookup_project($bf_blender_categories[$category])->getPHID();
unset($mtask->extra_fields[$category_key]);
}
if($category) {
if($bf_blender_categories[$category])
$projects[] = lookup_project($bf_blender_categories[$category])->getPHID();
unset($mtask->extra_fields[$category_key]);
}
// TODO: add more statuses or fields
switch($resolution) {
case "None":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Open":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Investigate":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Need updates":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Applied":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
default:
echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n";
break;
}
switch($resolution) {
case "None":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Open":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Investigate":
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Need updates":
$priority = 30;
$status = ManiphestTaskStatus::STATUS_OPEN;
break;
case "Applied":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Closed":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
default:
echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n";
break;
}
unset($mtask->extra_fields[$resolution_key]);
if($old_resolution)
unset($mtask->extra_fields[$old_resolution_key]);
}
else {
echo "ERROR: unknown BF Blender tracker " . $mtask->tracker . " (" . $id . ")\n";
$priority = 50;
$close_as_archived = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
}
else if($mtask->project == "Blender Extensions") {
switch($mtask->tracker) {
case "Py Scripts Extern":
$extension_type = "Python Script Extern";
break;
case "dev-tools":
break;
case "test-tracker":
break;
case "Plugins Release":
$extension_type = "Plugin Release";
break;
case "Plugins Contrib":
$extension_type = "Plugin Contrib";
break;
case "Plugins Upload":
$extension_type = "Plugin Upload";
break;
case "Py Scripts Release":
$extension_type = "Pythin Script Release";
break;
case "Py Scripts Contrib":
$extension_type = "Python Script Contrib";
break;
case "Py Scripts Upload":
$extension_type = "Python Script Upload";
break;
case "Bugs":
break;
default:
echo "ERROR: unkown extension tracker \"" . $mtask->tracker . "\" (" . $id . ")\n";
break;
}
if($status == ManiphestTaskStatus::STATUS_OPEN) {
switch($old_resolution) {
case "Approved":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
case "Rejected":
$status = ManiphestTaskStatus::STATUS_CLOSED_INVALID;
break;
case "Postponed":
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
break;
case "Fixed":
$status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
break;
}
// TODO: status!
/* weird stuff goes on here, seems there are closed patches
* that do no show any closed resolution, so force it */
if($mtask->state == "Closed")
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
$projects[] = lookup_project("Extensions")->getPHID();
$task_type = "Extension";
$priority = 50;
$status = ManiphestTaskStatus::STATUS_OPEN;
$close_as_archived = false;
}
else {
$extra .= "**Project**: " . $mtask->project . "\n";
$extra .= "**Tracker**: " . $mtask->tracker . "\n";
unset($mtask->extra_fields[$resolution_key]);
if($old_resolution)
unset($mtask->extra_fields[$old_resolution_key]);
}
else {
$projects[] = lookup_project("BF Blender")->getPHID();
echo "ERROR: unknown BF Blender tracker " . $mtask->tracker . " (" . $id . ")\n";
$priority = 20;
$close_as_archived = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
$remove_subscribers = true;
}
}
else if($mtask->project == "Blender Extensions") {
// TODO: import extensions as addons
// split bugs and leave out extensions
$task_type = "Other";
$priority = 50;
$close_as_archived = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
}
/* switch($mtask->tracker) {
case "Py Scripts Extern":
$extension_type = "Python Script Extern";
break;
case "dev-tools":
break;
case "test-tracker":
break;
case "Plugins Release":
$extension_type = "Plugin Release";
break;
case "Plugins Contrib":
$extension_type = "Plugin Contrib";
break;
case "Plugins Upload":
$extension_type = "Plugin Upload";
break;
case "Py Scripts Release":
$extension_type = "Python Script Release";
break;
case "Py Scripts Contrib":
$extension_type = "Python Script Contrib";
break;
case "Py Scripts Upload":
$extension_type = "Python Script Upload";
break;
case "Bugs":
break;
default:
echo "ERROR: unkown extension tracker \"" . $mtask->tracker . "\" (" . $id . ")\n";
break;
}
/* add remaining extra fields to description */
foreach($mtask->extra_fields as $field) {
if($field['value'] == "" || $field['value'] == 'None')
continue;
$projects[] = lookup_project("Addons")->getPHID();
$task_type = "Extension";
$priority = 50;
$status = ManiphestTaskStatus::STATUS_OPEN;
$close_as_archived = false;*/
if($field['name'] == 'Relates to') {
$extra .= "**Relates to**: ";
}
else if($field['name'] == 'Related to') {
$extra .= "**Related to**: ";
}
else if($field['name'] == 'Duplicate') {
$extra .= "**Duplicate**: ";
}
else if($field['name'] == 'Duplicates') {
$extra .= "**Duplicates**: ";
}
else if($field['name'] == 'Patches') {
$extra .= "**Patches**: ";
}
else if($field['name'] == 'Patch for') {
$extra .= "**Patch for**: ";
}
else {
$extra .= "**" . $field['name'] . "**: " . $field['value'] . "\n";
continue;
}
continue;
}
else {
$extra .= "**Project**: " . $mtask->project . "\n";
$extra .= "**Tracker**: " . $mtask->tracker . "\n";
$value = explode(" ", str_replace("#", "", $field['value']));
$first = true;
foreach($value as $subvalue) {
if($first)
$first = false;
else
$extra .= " ";
$task_type = "Other";
$priority = 20;
$close_as_archived = true;
$status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED;
$remove_subscribers = true;
}
$extra .= "T" . $subvalue;
}
/* add remaining extra fields to description */
foreach($mtask->extra_fields as $field) {
if($field['value'] == "" || $field['value'] == 'None')
continue;
$extra .= "\n";
}
if($field['name'] == 'Relates to') {
$extra .= "**Relates to**: ";
}
else if($field['name'] == 'Related to') {
$extra .= "**Related to**: ";
}
else if($field['name'] == 'Duplicate') {
$extra .= "**Duplicate**: ";
}
else if($field['name'] == 'Duplicates') {
$extra .= "**Duplicates**: ";
}
else if($field['name'] == 'Patches') {
$extra .= "**Patches**: ";
}
else if($field['name'] == 'Patch for') {
$extra .= "**Patch for**: ";
}
else {
$extra .= "**" . $field['name'] . "**: " . $field['value'] . "\n";
continue;
}
if($extra != "")
$description = $extra . "\n" . $description;
/* subscribers */
$ccs = array();
foreach ($mtask->ccs as $mcc) {
if($mcc && $mcc != "" && $mcc != "None") {
$ccuser = lookup_user(dedup_user($mcc));
if($ccuser)
$ccs[] = $ccuser->getPHID();
}
}
$value = explode(" ", str_replace("#", "", $field['value']));
$first = true;
foreach($value as $subvalue) {
if($first)
$first = false;
else
$extra .= " ";
/* we don't check these */
$projects = array_unique($projects);
$extra .= "T" . $subvalue;
}
/* create task */
$task = create_task($author, $mtask->id, $title, $projects,
$description, $assign, $mtask->date, $ccs, $priority, $task_type, $extension_type);
/* create array with all operations */
$sorted_dates = array();
$sorted_actions = array();
$extra .= "\n";
}
/* files */
foreach ($mtask->files as $mfile) {
$sorted_dates[] = $mfile->date;
$sorted_actions[] = $mfile;
}
if($extra != "")
$description = $extra . "\n" . $description;
/* subscribers */
$ccs = array();
/* comments */
foreach ($mtask->comments as $mcomment) {
$sorted_dates[] = $mcomment->date + 1; // couldn't find stable sort, so hack
$sorted_actions[] = $mcomment;
}
if(!$remove_subscribers) {
if(!$close_as_archived) { /* don't notify for dead issues */
foreach ($mtask->ccs as $mcc) {
if($mcc && $mcc != "" && $mcc != "None") {
$ccuser = lookup_user(dedup_user($mcc));
if($ccuser)
$ccs[] = $ccuser->getPHID();
}
}
}
}
/* history */
$old_status = $status;
$found_last_status = false;
/* we don't check these */
$projects = array_unique($projects);
foreach ($mtask->history as $mhistory) {
// TODO: different types of status fields exist
if($mhistory->field == "Status" || $mhistory->field == "status_id" || $mhistory->field == "Resolution") {
$sorted_dates[] = $mhistory->date + 2; // couldn't find stable sort, so hack
$sorted_actions[] = array($mhistory->user, $mhistory->date, $old_status);
$old_status = $mhistory->old;
$found_last_status = true;
break; // only does last status, too messy to figure out from history
}
}
/* create task */
$task = create_task($author, $mtask->id, $title, $projects,
$description, $assign, $mtask->date, $ccs, $priority, $task_type);
/* create array with all operations */
$sorted_dates = array();
$sorted_actions = array();
if(!$found_last_status) {
$sorted_dates[] = $mtask->date;
$sorted_actions[] = array("None", $mtask->date, $old_status);
}
/* files */
foreach ($mtask->files as $mfile) {
$sorted_dates[] = $mfile->date;
$sorted_actions[] = $mfile;
}
/* sort and apply in order */
array_multisort($sorted_dates, $sorted_actions);
/* comments */
foreach ($mtask->comments as $mcomment) {
$sorted_dates[] = $mcomment->date + 1; // couldn't find stable sort, so hack
$sorted_actions[] = $mcomment;
}
foreach($sorted_actions as $action) {
if(is_object($action) && get_class($action) == "MigrateFile") {
/* create file */
$mfile = $action;
$user = lookup_user(dedup_user($mfile->user));
/* history */
$old_status = $status;
$found_last_status = false;
// TODO skip low file IDS to avoid F1..F12 becoming shortcut key links
// TODO mysql file size limit
if($user)
create_file($task, $user, $mfile->name, $mfile->contents, $mfile->date);
//create_comment($task, $user, "Attach file: " . $mfile->name, $mfile->date);
}
else if(is_object($action) && get_class($action) == "MigrateComment") {
/* create comment */
$mcomment = $action;
$user = lookup_user(dedup_user($mcomment->user));
if($user) {
$description = '%%%' . html_entity_decode($mcomment->description) . '%%%';
create_comment($task, $user, $description, $mcomment->date);
}
}
else {
/* change status */
$muser = $action[0];
$mdate = $action[1];
$mstatus = $action[2];
foreach ($mtask->history as $mhistory) {
if($mhistory->field == "Status" || $mhistory->field == "status_id" || $mhistory->field == "Resolution") {
$sorted_dates[] = $mhistory->date + 2; // couldn't find stable sort, so hack
$sorted_actions[] = array($mhistory->user, $mhistory->date, $old_status);
$old_status = $mhistory->old;
$found_last_status = true;
break; // only does last status, too messy to figure out from history
}
}
$user = lookup_user(dedup_user($muser));
if(!$user)
$user = lookup_user("None");
if(!$found_last_status) {
$sorted_dates[] = $mtask->date;
$sorted_actions[] = array("None", $mtask->date, $old_status);
}
set_status($task, $user, $mstatus, $mdate);
}
}
/* sort and apply in order */
array_multisort($sorted_dates, $sorted_actions);
/* final status check */
if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $close_as_archived)
set_status($task, lookup_user("None"), ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED, $mtask->date);
foreach($sorted_actions as $action) {
if(is_object($action) && get_class($action) == "MigrateFile") {
/* create file */
$mfile = $action;
$user = lookup_user(dedup_user($mfile->user));
if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $mtask->state == "Closed")
echo "ERROR: status out of sync, task should have been closed (" . $id . ")\n";
if($user)
create_file($task, $user, $mfile->name, $mfile->contents, $mfile->date);
//create_comment($task, $user, "Attach file: " . $mfile->name, $mfile->date);
}
else if(is_object($action) && get_class($action) == "MigrateComment") {
/* create comment */
$mcomment = $action;
$user = lookup_user(dedup_user($mcomment->user));
if($user) {
$description = '%%%' . html_entity_decode($mcomment->description) . '%%%';
create_comment($task, $user, $description, $mcomment->date);
}
}
else {
/* change status */
$muser = $action[0];
$mdate = $action[1];
$mstatus = $action[2];
$user = lookup_user(dedup_user($muser));
if(!$user)
$user = lookup_user("None");
set_status($task, $user, $mstatus, $mdate);
}
}
/* final status check */
if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $close_as_archived)
set_status($task, lookup_user("None"), ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED, $mtask->date);
if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $mtask->state == "Closed")
echo "ERROR: status out of sync, task should have been closed (" . $id . ")\n";
}
// TODO: test importing the whole range of tasks locally

View File

@@ -11,8 +11,8 @@ require_once 'phab.php';
function isValidTimezoneId($timezoneId)
{
@$tz=timezone_open($timezoneId);
return $tz!==FALSE;
@$tz=timezone_open($timezoneId);
return $tz!==FALSE;
}
$musers = unserialize(file_get_contents("dump/users"));
@@ -21,117 +21,116 @@ $usedemails = array();
foreach ($musers as $muser)
{
$username = $muser->name;
$userid = $muser->id;
$realname = trim($muser->realname);
$email = $muser->email;
$date = $muser->date;
$timezone = $muser->timezone;
$username = $muser->name;
$userid = $muser->id;
$realname = trim($muser->realname);
$email = $muser->email;
$date = $muser->date;
$timezone = $muser->timezone;
// TODO broken intentionally to avoid sending emails during tests
$email = "brokenemail___" . $email . "___brokenemail";
$email = "_tmpdisabledemail_" . $email . "_tmpdisabledemail_";
/* skip duplicate users */
if(array_key_exists($username, $migrate_dedup_users))
continue;
/* skip duplicate users */
if(array_key_exists($username, $migrate_dedup_users))
continue;
/* log imported users */
$importeduser = new MigrateImportedUser();
$importeduser->name = $username;
$importeduser->email = $email;
/* log imported users */
$importeduser = new MigrateImportedUser();
$importeduser->name = $username;
$importeduser->email = $email;
/* detect spam */
$isspam = false;
/* detect spam */
$isspam = false;
foreach($spammails as $spam)
if(endsWith($email, $spam))
$isspam = true;
if(!$isspam && strlen($realname) > 4) {
if(substr($realname, 0, strlen($realname)-2) == $username . " " . $username) {
if(ctype_upper(substr($realname, strlen($realname)-2, 2))) {
$isspam = true;
}
}
}
if ($isspam) {
$importeduser->isspam = true;
$importedusers[$username] = $importeduser;
continue;
}
foreach($spammails as $spam)
if(endsWith($email, $spam))
$isspam = true;
if(!$isspam && strlen($realname) > 4) {
if(substr($realname, 0, strlen($realname)-2) == $username . " " . $username) {
if(ctype_upper(substr($realname, strlen($realname)-2, 2))) {
$isspam = true;
}
}
}
if ($isspam) {
$importeduser->isspam = true;
$importedusers[$username] = $importeduser;
continue;
}
/* fix timezones */
if (!isValidTimezoneId($timezone)) {
switch($timezone) {
case "China/Beijing": $timezone = "Asia/Shanghai"; break;
case "China/Shanghai": $timezone = "Asia/Shanghai"; break;
case "-1": $timezone = "GMT"; break;
case "-2": $timezone = "GMT"; break;
case "-3": $timezone = "GMT"; break;
case "0": $timezone = "GMT"; break;
case "1": $timezone = "GMT"; break;
case "2": $timezone = "GMT"; break;
case "3": $timezone = "GMT"; break;
case "Asia/Beijing": $timezone = "Asia/Shanghai"; break;
case "Asia/Riyadh87": $timezone = "Asia/Riyadh"; break;
case "Asia/Riyadh88": $timezone = "Asia/Riyadh"; break;
case "Asia/Riyadh89": $timezone = "Asia/Riyadh"; break;
case "Mideast/Riyadh87": $timezone = "Asia/Riyadh"; break;
case "Mideast/Riyadh88": $timezone = "Asia/Riyadh"; break;
case "Mideast/Riyadh89": $timezone = "Asia/Riyadh"; break;
}
}
/* fix timezones */
if (!isValidTimezoneId($timezone)) {
switch($timezone) {
case "China/Beijing": $timezone = "Asia/Shanghai"; break;
case "China/Shanghai": $timezone = "Asia/Shanghai"; break;
case "-1": $timezone = "GMT"; break;
case "-2": $timezone = "GMT"; break;
case "-3": $timezone = "GMT"; break;
case "0": $timezone = "GMT"; break;
case "1": $timezone = "GMT"; break;
case "2": $timezone = "GMT"; break;
case "3": $timezone = "GMT"; break;
case "Asia/Beijing": $timezone = "Asia/Shanghai"; break;
case "Asia/Riyadh87": $timezone = "Asia/Riyadh"; break;
case "Asia/Riyadh88": $timezone = "Asia/Riyadh"; break;
case "Asia/Riyadh89": $timezone = "Asia/Riyadh"; break;
case "Mideast/Riyadh87": $timezone = "Asia/Riyadh"; break;
case "Mideast/Riyadh88": $timezone = "Asia/Riyadh"; break;
case "Mideast/Riyadh89": $timezone = "Asia/Riyadh"; break;
}
}
if (!isValidTimezoneId($timezone)) {
echo "ERROR: invalid timezone " . $timezone . ", changed to GMT\n";
$timezone = "GMT";
}
/* check existing user and email */
$existing_user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username);
if ($existing_user) {
echo 'ERROR: ' . $username . " already exists.\n";
}
if (!isValidTimezoneId($timezone)) {
echo "ERROR: invalid timezone " . $timezone . ", changed to GMT\n";
$timezone = "GMT";
}
/* check existing user and email */
$existing_user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username);
if ($existing_user) {
echo 'ERROR: ' . $username . " already exists.\n";
}
$existing_email = id(new PhabricatorUserEmail())->loadOneWhere('address = %s', $email);
if ($existing_email) {
echo 'ERROR: ' . $email . " already exists for user " . $username . ".\n";
}
$existing_email = id(new PhabricatorUserEmail())->loadOneWhere('address = %s', $email);
if ($existing_email) {
echo 'ERROR: ' . $email . " already exists for user " . $username . ".\n";
}
if ($existing_email || $existing_user) {
$importedusers[$username] = $importeduser;
continue;
}
if ($existing_email || $existing_user) {
$importedusers[$username] = $importeduser;
continue;
}
/* create user */
$user = new PhabricatorUser();
$user->setUsername($username);
$user->setRealname($realname);
$user->setOverrideDate($date);
$user->setOverrideID($userid);
$user->setTimezoneIdentifier($timezone);
/* create user */
$user = new PhabricatorUser();
$user->setUsername($username);
$user->setRealname($realname);
$user->setOverrideDate($date);
$user->setOverrideID($userid);
$user->setTimezoneIdentifier($timezone);
if(in_array($username, $admins))
$user->setIsAdmin(true);
if(in_array($username, $admins))
$user->setIsAdmin(true);
$email_object = id(new PhabricatorUserEmail())
->setAddress($email)
->setIsVerified(1);
$email_object = id(new PhabricatorUserEmail())
->setAddress($email)
->setIsVerified(1);
id(new PhabricatorUserEditor())
->setActor($user)
->createNewUser($user, $email_object);
id(new PhabricatorUserEditor())
->setActor($user)
->createNewUser($user, $email_object);
/* set password */
$envelope = new PhutilOpaqueEnvelope($muser->password);
id(new PhabricatorUserEditor())
->setActor($user)
->changePassword($user, $envelope, true);
/* set password */
$envelope = new PhutilOpaqueEnvelope($muser->password);
id(new PhabricatorUserEditor())
->setActor($user)
->changePassword($user, $envelope, true);
/* log imported user */
$importedusers[$username] = $importeduser;
$usedemails[strtolower($email)] = $username;
/* log imported user */
$importedusers[$username] = $importeduser;
$usedemails[strtolower($email)] = $username;
}
file_put_contents('dump/importedusers', serialize($importedusers));

View File

@@ -0,0 +1,142 @@
A) CONFIGURE PHABRICATOR
========================
./bin/config set policy.allow-public true
./bin/config set feed.public true
./bin/config set welcome.file rsrc/custom/static/welcome.html
set maniphest.custom-field-definitions
{
"blender:task-type": {
"name": "Type",
"type": "select",
"search": true,
"options": {
"Bug": "Bug",
"Patch": "Patch",
"Design": "Design",
"To Do": "To Do",
"Feature Request": "Feature Request",
"OpenGL Error": "OpenGL Error"
}
}
}
set maniphest.priorities
{
"100" : {
"name" : "Unbreak Now!",
"short" : "Unbreak!",
"color" : "indigo"
},
"90" : {
"name" : "Needs Triage",
"short" : "Triage",
"color" : "violet"
},
"50" : {
"name" : "Confirmed",
"short" : "Confirmed",
"color" : "orange"
},
"40" : {
"name" : "Normal",
"short" : "Normal",
"color" : "yellow"
},
"30" : {
"name" : "Incomplete",
"short" : "Incomplete",
"color" : "red"
},
"20" : {
"name" : "Low",
"short" : "Low",
"color" : "yellow"
}
}
Disable irrelevant applications and set policies (TODO figure out policies!)
B) FILE STORAGE
===============
Set some file storage upload limit (I think projects.blender.org is 5MB, but make it bigger for import to be sure, can lower again later):
./bin/config set storage.upload-size-limit 10M
Decide to store files in MySQL DB or in files on disk. So either:
./bin/config set storage.local-disk.path /some/path/to/files
Or increase MySQL storage limit to match storage.upload-size-limit
C) MYSQL TABLE TWEAKS
=====================
Avoid F1, F2 shortcut keys being considered as file links:
ALTER TABLE phabricator_file.file AUTO_INCREMENT = 1000;
Avoid conflicts with existing report numbers or users while testing:
ALTER TABLE phabricator_maniphest.maniphest_task AUTO_INCREMENT = 50000;
ALTER TABLE phabricator_user.user AUTO_INCREMENT = 50000;
D) ACCIDENTAL EMAIL SENDING
===========================
All email addresses have been modified to avoid sending emails while users and tasks are being created.
Either disable email sending code in phab, or disable postfix, or figure out what happens when you try to send a ton of emails to invalid addresses.
E) IMPORT USERS AND PROJECTS
============================
./export_users.php on projects.blender.org
copy over dump/ folder
./import_users.php on developer.blender.org
./import_projects.php
F) IMPORT TASKS
===============
This is going to be slow and lots of data, best to do it in steps, perhaps starting with the newest reports.
./export_task.php 37000 38000
copy over dump/ folder
./import_task.php 37000 38000
And so on for all task ranges ..
G) TESTS
========
* Check if number of developers with commit rights match
* Check if number of open bugs and patches roughly match
* Check for report status, attached files, missing comments, etc
* Add email address to you user settings to test (it's set to an invalid one for testing)
* Test if emails, password reset, etc works
H) FOR FINAL
============
* Search and remove _tmpdisabledemail_ on all email addresses in DB
* Preserve user and project data from testing period somehow, or dump it all?
* Replace projects.blender.org link in comments (either in DB or beforehand)
* Perhaps clear feeds in DB, may take up unnecessary space?
* Make redirects from projects.blender.org

View File

@@ -2,140 +2,136 @@
function create_custom_field_transaction($task, $user, $name, $value, $template, $date)
{
// TODO: hide transactions for irrelevant fields
$field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_EDIT);
foreach ($field_list->getFields() as $field) {
$field->setObject($task);
$field->setViewer($user);
}
$field->setObject($task);
$field->setViewer($user);
}
$field_list->readFieldsFromStorage($task);
$aux_fields = $field_list->getFields();
$old_values = array();
foreach ($aux_fields as $aux_arr_key => $aux_field) {
if($aux_arr_key == "std:maniphest:" . $name) {
$aux_old_value = $aux_field->getOldValueForApplicationTransactions();
$aux_field->setValueFromStorage($value);
$aux_new_value = $aux_field->getNewValueForApplicationTransactions();
$old_values = array();
foreach ($aux_fields as $aux_arr_key => $aux_field) {
if($aux_arr_key == "std:maniphest:" . $name) {
$aux_old_value = $aux_field->getOldValueForApplicationTransactions();
$aux_field->setValueFromStorage($value);
$aux_new_value = $aux_field->getNewValueForApplicationTransactions();
$placeholder_editor = new PhabricatorUserProfileEditor();
$placeholder_editor = new PhabricatorUserProfileEditor();
$field_errors = $aux_field->validateApplicationTransactions(
$placeholder_editor,
PhabricatorTransactions::TYPE_CUSTOMFIELD,
array(
id(new ManiphestTransaction())
->setOldValue($aux_old_value)
->setNewValue($aux_new_value),
));
$field_errors = $aux_field->validateApplicationTransactions(
$placeholder_editor,
PhabricatorTransactions::TYPE_CUSTOMFIELD,
array(
id(new ManiphestTransaction())
->setOldValue($aux_old_value)
->setNewValue($aux_new_value),
));
foreach ($field_errors as $error) {
$errors[] = $error->getMessage();
}
foreach ($field_errors as $error) {
$errors[] = $error->getMessage();
}
$old_values[$aux_field->getFieldKey()] = $aux_old_value;
}
}
$old_values[$aux_field->getFieldKey()] = $aux_old_value;
}
}
$transactions = array();
$transactions = array();
foreach ($aux_fields as $aux_arr_key => $aux_field) {
if($aux_arr_key == "std:maniphest:" . $name) {
$transaction = clone $template;
$transaction->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD);
$aux_key = $aux_field->getFieldKey();
$transaction->setMetadataValue('customfield:key', $aux_key);
$old = idx($old_values, $aux_key);
$new = $aux_field->getNewValueForApplicationTransactions();
foreach ($aux_fields as $aux_arr_key => $aux_field) {
if($aux_arr_key == "std:maniphest:" . $name) {
$transaction = clone $template;
$transaction->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD);
$aux_key = $aux_field->getFieldKey();
$transaction->setMetadataValue('customfield:key', $aux_key);
$old = idx($old_values, $aux_key);
$new = $aux_field->getNewValueForApplicationTransactions();
$transaction->setOldValue($old);
$transaction->setNewValue($new);
$transaction->setOverrideDate($date);
$transaction->setOldValue($old);
$transaction->setNewValue($new);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
// TODO: hide transactions for irrelevant fields
$transactions[] = $transaction;
}
}
// XXX not working!
//$aux_field->applyApplicationTransactionExternalEffects($transaction);
}
}
return $transactions;
return $transactions;
}
function create_task($user, $id, $title, $projects, $description, $assign_user, $date, $ccs, $priority, $type_field, $extension_field)
function create_task($user, $id, $title, $projects, $description, $assign_user, $date, $ccs, $priority, $type_field)
{
/* create task */
$task = ManiphestTask::initializeNewTask($user);
$task->setTitle($title);
$task->setProjectPHIDs($projects);
$task->setCCPHIDs($ccs);
$task->setDescription($description);
$task->setPriority($priority);
$task->setOverrideDate($date);
$task->setOverrideID($id);
/* create task */
$task = ManiphestTask::initializeNewTask($user);
$task->setTitle($title);
$task->setProjectPHIDs($projects);
$task->setCCPHIDs($ccs);
// TODO when editing a task, it shows the description as edited even though it didn't really happen, why?
$task->setDescription($description);
$task->setPriority($priority);
$task->setOverrideDate($date);
$task->setOverrideID($id);
if ($assign_user)
$task->setOwnerPHID($assign_user->getPHID());
if ($assign_user)
$task->setOwnerPHID($assign_user->getPHID());
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* transactions */
$changes = array();
$changes[ManiphestTransaction::TYPE_STATUS] = ManiphestTaskStatus::STATUS_OPEN;
$changes[PhabricatorTransactions::TYPE_VIEW_POLICY] = 'public';
$changes[PhabricatorTransactions::TYPE_EDIT_POLICY] = 'admin'; // TODO which permission?
/* transactions */
$changes = array();
$changes[ManiphestTransaction::TYPE_STATUS] = ManiphestTaskStatus::STATUS_OPEN;
$changes[PhabricatorTransactions::TYPE_VIEW_POLICY] = 'public';
$changes[PhabricatorTransactions::TYPE_EDIT_POLICY] = 'admin'; // TODO which permission?
$template = new ManiphestTransaction();
$template = new ManiphestTransaction();
$transactions = array();
$transactions = array();
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
}
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
}
/* type */
$transactions = array_merge($transactions, create_custom_field_transaction($task, $user, "blender:task-type", $type_field, $template, $date));
if($extension_field != "None")
$transactions = array_merge($transactions, create_custom_field_transaction($task, $user, "blender:extension-type", $extension_field, $template, $date));
/* type */
$transactions = array_merge($transactions, create_custom_field_transaction($task, $user, "blender:task-type", $type_field, $template, $date));
$editor = id(new ManiphestTransactionEditor())
->setActor($user)
->setContentSource($content_source)
->setContinueOnNoEffect(true)
->applyTransactions($task, $transactions);
$editor = id(new ManiphestTransactionEditor())
->setActor($user)
->setContentSource($content_source)
->setContinueOnNoEffect(true)
->applyTransactions($task, $transactions);
return $task;
return $task;
}
function create_comment($task, $user, $description, $date)
{
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* transactions */
$comment = id(new ManiphestTransactionComment());
$comment->setContent($description);
/* transactions */
$comment = id(new ManiphestTransactionComment());
$comment->setContent($description);
$transaction = id(new ManiphestTransaction());
$transaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT);
$transaction->setOverrideDate($date);
$transaction->attachComment($comment);
$transaction = id(new ManiphestTransaction());
$transaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT);
$transaction->setOverrideDate($date);
$transaction->attachComment($comment);
$transactions = array();
$transactions[] = $transaction;
$transactions = array();
$transactions[] = $transaction;
/* apply */
/* apply */
$editor = id(new ManiphestTransactionEditor())
->setActor($user)
->setContentSource($content_source)
@@ -145,40 +141,40 @@ function create_comment($task, $user, $description, $date)
function create_file($task, $user, $name, $contents, $date)
{
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* files */
$files = array();
/* files */
$files = array();
$file = PhabricatorFile::newFromFileData(
$contents,
array(
'authorPHID' => $user->getPHID(),
'name' => $name,
));
$files[] = $file;
$file = PhabricatorFile::newFromFileData(
$contents,
array(
'authorPHID' => $user->getPHID(),
'name' => $name,
));
$files[] = $file;
$files = mpull($files, 'getPHID', 'getPHID');
$new = $task->getAttached();
foreach ($files as $phid) {
if (empty($new[PhabricatorFilePHIDTypeFile::TYPECONST])) {
$new[PhabricatorFilePHIDTypeFile::TYPECONST] = array();
}
$files = mpull($files, 'getPHID', 'getPHID');
$new = $task->getAttached();
foreach ($files as $phid) {
if (empty($new[PhabricatorFilePHIDTypeFile::TYPECONST])) {
$new[PhabricatorFilePHIDTypeFile::TYPECONST] = array();
}
$new[PhabricatorFilePHIDTypeFile::TYPECONST][$phid] = array();
}
$new[PhabricatorFilePHIDTypeFile::TYPECONST][$phid] = array();
}
/* transaction */
$transaction = new ManiphestTransaction();
$transaction->setTransactionType(ManiphestTransaction::TYPE_ATTACH);
$transaction->setNewValue($new);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
/* transaction */
$transaction = new ManiphestTransaction();
$transaction->setTransactionType(ManiphestTransaction::TYPE_ATTACH);
$transaction->setNewValue($new);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
/* apply */
/* apply */
$editor = id(new ManiphestTransactionEditor())
->setActor($user)
->setContentSource($content_source)
@@ -188,83 +184,83 @@ function create_file($task, $user, $name, $contents, $date)
function set_status($task, $user, $status, $date)
{
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* content source */
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_UNKNOWN,
array());
/* transactions */
$changes = array();
$changes[ManiphestTransaction::TYPE_STATUS] = $status;
/* transactions */
$changes = array();
$changes[ManiphestTransaction::TYPE_STATUS] = $status;
$template = new ManiphestTransaction();
$template = new ManiphestTransaction();
$transactions = array();
$transactions = array();
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
}
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transaction->setOverrideDate($date);
$transactions[] = $transaction;
}
$editor = id(new ManiphestTransactionEditor())
->setActor($user)
->setContentSource($content_source)
->setContinueOnNoEffect(true)
->applyTransactions($task, $transactions);
$editor = id(new ManiphestTransactionEditor())
->setActor($user)
->setContentSource($content_source)
->setContinueOnNoEffect(true)
->applyTransactions($task, $transactions);
}
function create_project($name, $username, $active, $membernames, $blurb = '')
{
$user = lookup_user($username);
$user = lookup_user($username);
/* create project */
$project = new PhabricatorProject();
$project->setAuthorPHID($user->getPHID());
$project->attachMemberPHIDs(array());
$profile = new PhabricatorProjectProfile();
/* create project */
$project = new PhabricatorProject();
$project->setAuthorPHID($user->getPHID());
$project->attachMemberPHIDs(array());
$profile = new PhabricatorProjectProfile();
$xactions = array();
$xactions = array();
/* policy */
$project->setViewPolicy("public");
$project->setEditPolicy("admin");
$project->setJoinPolicy("admin");
/* policy */
$project->setViewPolicy("public");
$project->setEditPolicy("admin");
$project->setJoinPolicy("admin");
/* archived */
if(!$active)
$project->setStatus(PhabricatorProjectStatus::STATUS_ARCHIVED);
/* name transaction */
$xaction = new PhabricatorProjectTransaction();
$xaction->setTransactionType(
PhabricatorProjectTransactionType::TYPE_NAME);
$xaction->setNewValue($name);
$xactions[] = $xaction;
/* archived */
if(!$active)
$project->setStatus(PhabricatorProjectStatus::STATUS_ARCHIVED);
/* name transaction */
$xaction = new PhabricatorProjectTransaction();
$xaction->setTransactionType(
PhabricatorProjectTransaction::TYPE_NAME);
$xaction->setNewValue($name);
$xactions[] = $xaction;
/* members transaction */
$member_phids = array();
foreach($membernames as $membername) {
$member_phids[] = lookup_user($membername)->getPHID();
}
/* members transaction */
$member_phids = array();
foreach($membernames as $membername) {
$member_phids[] = lookup_user($membername)->getPHID();
}
$xaction = new PhabricatorProjectTransaction();
$xaction->setTransactionType(
PhabricatorProjectTransactionType::TYPE_MEMBERS);
$xaction->setNewValue($member_phids);
$xactions[] = $xaction;
$xaction = new PhabricatorProjectTransaction();
$xaction->setTransactionType(
PhabricatorProjectTransaction::TYPE_MEMBERS);
$xaction->setNewValue($member_phids);
$xactions[] = $xaction;
/* apply transaction */
$editor = new PhabricatorProjectEditor($project);
$editor->setActor($user);
$editor->applyTransactions($xactions);
/* apply transaction */
$editor = new PhabricatorProjectEditor($project);
$editor->setActor($user);
$editor->applyTransactions($xactions);
/* set blurb */
$profile->setBlurb($blurb);
/* set blurb */
$profile->setBlurb($blurb);
$project->save();
$profile->setProjectPHID($project->getPHID());
$profile->save();
$project->save();
$profile->setProjectPHID($project->getPHID());
$profile->save();
}

View File

@@ -3,97 +3,97 @@
/* serialization */
class MigrateFile {
public $name;
public $contents;
public $user;
public $date;
public $type;
public $name;
public $contents;
public $user;
public $date;
public $type;
}
class MigrateComment {
public $user;
public $description;
public $date;
public $user;
public $description;
public $date;
}
class MigrateHistory {
public $user;
public $date;
public $field;
public $old;
public $user;
public $date;
public $field;
public $old;
}
class MigrateTask {
public $id;
public $author;
public $title;
public $description;
public $date;
public $assign;
public $state;
public $priority;
public $id;
public $author;
public $title;
public $description;
public $date;
public $assign;
public $state;
public $priority;
public $project;
public $tracker;
public $project;
public $tracker;
public $comments = array();
public $files = array();
public $ccs = array();
public $history = array();
public $comments = array();
public $files = array();
public $ccs = array();
public $history = array();
public $extra_fields = array();
public $extra_fields = array();
}
class MigrateUser {
public $name;
public $id;
public $realname;
public $email;
public $date;
public $timezone;
public $password;
public $name;
public $id;
public $realname;
public $email;
public $date;
public $timezone;
public $password;
}
class MigrateImportedUser {
public $name;
public $email;
public $isspam = false;
public $duplicateof = null;
public $name;
public $email;
public $isspam = false;
public $duplicateof = null;
}
/* utilities */
function startsWith($haystack, $needle)
{
return $needle === "" || strpos($haystack, $needle) === 0;
return $needle === "" || strpos($haystack, $needle) === 0;
}
function endsWith($haystack, $needle)
{
return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
}
function lookup_user($name)
{
if($name == null)
return null;
if($name == null)
return null;
$user = id(new PhabricatorUser())->loadOneWhere('username = %s', $name);
if (!$user)
echo "ERROR: lookup of user " . $name . " failed\n";
$user = id(new PhabricatorUser())->loadOneWhere('username = %s', $name);
if (!$user)
echo "ERROR: lookup of user " . $name . " failed\n";
return $user;
return $user;
}
function lookup_project($name)
{
if($name == null)
return null;
if($name == null)
return null;
$project = id(new PhabricatorProject())->loadOneWhere('name = %s', $name);
if (!$project)
echo "ERROR: lookup of project " . $name . " failed\n";
$project = id(new PhabricatorProject())->loadOneWhere('name = %s', $name);
if (!$project)
echo "ERROR: lookup of project " . $name . " failed\n";
return $project;
return $project;
}