Skip to content

Commit 9e5410e

Browse files
author
epriestley
committed
Rename bin/files metadata to bin/files rebuild and let it rebuild MIME information
Summary: See <https://github.com/facebook/phabricator/issues/320>. Files can end up with a bad MIME type, and we don't update it when uploading another copy of the file since obviously the new copy has the same data and thus the same MIME type. - Rename `bin/files metadata` to `bin/files rebuild` to make it a more consistent verb. - Let it rebuild MIME types so users who hit issues like this can run `bin/files rebuild --all --rebuild-mime` to straighten things out. Test Plan: Ran `bin/files` in various modes, examined output. Reviewers: btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D5951
1 parent 1dd91bd commit 9e5410e

File tree

4 files changed

+177
-133
lines changed

4 files changed

+177
-133
lines changed

scripts/files/manage_files.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
new PhabricatorFilesManagementEnginesWorkflow(),
1919
new PhabricatorFilesManagementMigrateWorkflow(),
2020
new PhutilHelpArgumentWorkflow(),
21-
new PhabricatorFilesManagementMetadataWorkflow(),
21+
new PhabricatorFilesManagementRebuildWorkflow(),
2222
);
2323

2424
$args->parseWorkflows($workflows);

src/__phutil_library_map__.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -998,8 +998,8 @@
998998
'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php',
999999
'PhabricatorFilesConfigOptions' => 'applications/files/config/PhabricatorFilesConfigOptions.php',
10001000
'PhabricatorFilesManagementEnginesWorkflow' => 'applications/files/management/PhabricatorFilesManagementEnginesWorkflow.php',
1001-
'PhabricatorFilesManagementMetadataWorkflow' => 'applications/files/management/PhabricatorFilesManagementMetadataWorkflow.php',
10021001
'PhabricatorFilesManagementMigrateWorkflow' => 'applications/files/management/PhabricatorFilesManagementMigrateWorkflow.php',
1002+
'PhabricatorFilesManagementRebuildWorkflow' => 'applications/files/management/PhabricatorFilesManagementRebuildWorkflow.php',
10031003
'PhabricatorFilesManagementWorkflow' => 'applications/files/management/PhabricatorFilesManagementWorkflow.php',
10041004
'PhabricatorFlag' => 'applications/flag/storage/PhabricatorFlag.php',
10051005
'PhabricatorFlagColor' => 'applications/flag/constants/PhabricatorFlagColor.php',
@@ -2761,8 +2761,8 @@
27612761
'PhabricatorFileUploadException' => 'Exception',
27622762
'PhabricatorFilesConfigOptions' => 'PhabricatorApplicationConfigOptions',
27632763
'PhabricatorFilesManagementEnginesWorkflow' => 'PhabricatorFilesManagementWorkflow',
2764-
'PhabricatorFilesManagementMetadataWorkflow' => 'PhabricatorFilesManagementWorkflow',
27652764
'PhabricatorFilesManagementMigrateWorkflow' => 'PhabricatorFilesManagementWorkflow',
2765+
'PhabricatorFilesManagementRebuildWorkflow' => 'PhabricatorFilesManagementWorkflow',
27662766
'PhabricatorFilesManagementWorkflow' => 'PhutilArgumentWorkflow',
27672767
'PhabricatorFlag' => 'PhabricatorFlagDAO',
27682768
'PhabricatorFlagColor' => 'PhabricatorFlagConstants',

src/applications/files/management/PhabricatorFilesManagementMetadataWorkflow.php

Lines changed: 0 additions & 130 deletions
This file was deleted.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
<?php
2+
3+
final class PhabricatorFilesManagementRebuildWorkflow
4+
extends PhabricatorFilesManagementWorkflow {
5+
6+
public function didConstruct() {
7+
$this
8+
->setName('rebuild')
9+
->setSynopsis('Rebuild metadata of old files.')
10+
->setArguments(
11+
array(
12+
array(
13+
'name' => 'all',
14+
'help' => 'Update all files.',
15+
),
16+
array(
17+
'name' => 'id',
18+
'wildcard' => true,
19+
'help' => 'Update the given file. You can specify this flag '.
20+
'multiple times.',
21+
),
22+
array(
23+
'name' => 'dry-run',
24+
'help' => 'Show what would be updated.',
25+
),
26+
array(
27+
'name' => 'rebuild-mime',
28+
'help' => 'Rebuild MIME information.',
29+
),
30+
array(
31+
'name' => 'rebuild-dimensions',
32+
'help' => 'Rebuild image dimension information.',
33+
),
34+
));
35+
}
36+
37+
public function execute(PhutilArgumentParser $args) {
38+
$console = PhutilConsole::getConsole();
39+
40+
if ($args->getArg('all')) {
41+
if ($args->getArg('id')) {
42+
throw new PhutilArgumentUsageException(
43+
"Specify either a list of files or `--all`, but not both.");
44+
}
45+
$iterator = new LiskMigrationIterator(new PhabricatorFile());
46+
} else if ($args->getArg('id')) {
47+
$iterator = array();
48+
49+
foreach ($args->getArg('id') as $id) {
50+
$id = trim($id);
51+
52+
$id = preg_replace('/^F/i', '', $id);
53+
if (ctype_digit($id)) {
54+
$file = id(new PhabricatorFile())->loadOneWhere(
55+
'id = %d',
56+
$id);
57+
if (!$file) {
58+
throw new PhutilArgumentUsageException(
59+
"No file exists with ID '{$id}'.");
60+
}
61+
}
62+
$iterator[] = $file;
63+
}
64+
} else {
65+
throw new PhutilArgumentUsageException(
66+
"Either specify a list of files to update, or use `--all` ".
67+
"to update all files.");
68+
}
69+
70+
$update = array(
71+
'mime' => $args->getArg('rebuild-mime'),
72+
'dimensions' => $args->getArg('rebuild-dimensions'),
73+
);
74+
75+
// If the user didn't select anything, rebuild everything.
76+
if (!array_filter($update)) {
77+
foreach ($update as $key => $ignored) {
78+
$update[$key] = true;
79+
}
80+
}
81+
82+
$is_dry_run = $args->getArg('dry-run');
83+
84+
$failed = array();
85+
86+
foreach ($iterator as $file) {
87+
$fid = 'F'.$file->getID();
88+
89+
if ($update['mime']) {
90+
$tmp = new TempFile();
91+
Filesystem::writeFile($tmp, $file->loadFileData());
92+
$new_type = Filesystem::getMimeType($tmp);
93+
94+
if ($new_type == $file->getMimeType()) {
95+
$console->writeOut(
96+
"%s: Mime type not changed (%s).\n",
97+
$fid,
98+
$new_type);
99+
} else {
100+
if ($is_dry_run) {
101+
$console->writeOut(
102+
"%s: Would update Mime type: '%s' -> '%s'.\n",
103+
$fid,
104+
$file->getMimeType(),
105+
$new_type);
106+
} else {
107+
$console->writeOut(
108+
"%s: Updating Mime type: '%s' -> '%s'.\n",
109+
$fid,
110+
$file->getMimeType(),
111+
$new_type);
112+
$file->setMimeType($new_type);
113+
$file->save();
114+
}
115+
}
116+
}
117+
118+
if ($update['dimensions']) {
119+
if (!$file->isViewableImage()) {
120+
$console->writeOut(
121+
"%s: Not an image file.\n",
122+
$fid);
123+
continue;
124+
}
125+
126+
$metadata = $file->getMetadata();
127+
$image_width = idx($metadata, PhabricatorFile::METADATA_IMAGE_WIDTH);
128+
$image_height = idx($metadata, PhabricatorFile::METADATA_IMAGE_HEIGHT);
129+
if ($image_width && $image_height) {
130+
$console->writeOut(
131+
"%s: Image dimensions already exist.\n",
132+
$fid);
133+
continue;
134+
}
135+
136+
if ($is_dry_run) {
137+
$console->writeOut(
138+
"%s: Would update file dimensions (dry run)\n",
139+
$fid);
140+
continue;
141+
}
142+
143+
$console->writeOut(
144+
"%s: Updating metadata... ",
145+
$fid);
146+
147+
try {
148+
$file->updateDimensions();
149+
$console->writeOut("done.\n");
150+
} catch (Exception $ex) {
151+
$console->writeOut("failed!\n");
152+
$console->writeErr("%s\n", (string)$ex);
153+
$failed[] = $file;
154+
}
155+
}
156+
}
157+
158+
if ($failed) {
159+
$console->writeOut("**Failures!**\n");
160+
$ids = array();
161+
foreach ($failed as $file) {
162+
$ids[] = 'F'.$file->getID();
163+
}
164+
$console->writeOut("%s\n", implode(', ', $ids));
165+
166+
return 1;
167+
} else {
168+
$console->writeOut("**Success!**\n");
169+
return 0;
170+
}
171+
172+
return 0;
173+
}
174+
}

0 commit comments

Comments
 (0)