Skip to content

Commit cac44fd

Browse files
authored
Merge pull request #52822 from nextcloud/feat/mime-names
2 parents c62fa55 + ed8ebac commit cac44fd

15 files changed

Lines changed: 9797 additions & 11 deletions

File tree

LICENSES/GPL-2.0-only.txt

Lines changed: 117 additions & 0 deletions
Large diffs are not rendered by default.

core/Command/Maintenance/Mimetype/GenerateMimetypeFileBuilder.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class GenerateMimetypeFileBuilder {
1515
* @param array<string,string> $aliases
1616
* @return string
1717
*/
18-
public function generateFile(array $aliases): string {
18+
public function generateFile(array $aliases, array $names): string {
1919
// Remove comments
2020
$aliases = array_filter($aliases, static function ($key) {
2121
// Single digit extensions will be treated as integers
@@ -71,6 +71,15 @@ public function generateFile(array $aliases): string {
7171
sort($themes[$theme]);
7272
}
7373

74+
$namesOutput = '';
75+
foreach ($names as $key => $name) {
76+
if (str_starts_with($key, '_')) {
77+
// Skip internal names
78+
continue;
79+
}
80+
$namesOutput .= "'$key': t('core', " . json_encode($name) . "),\n";
81+
}
82+
7483
//Generate the JS
7584
return '/**
7685
* This file is automatically generated
@@ -83,7 +92,8 @@ public function generateFile(array $aliases): string {
8392
OC.MimeTypeList={
8493
aliases: ' . json_encode($aliases, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . ',
8594
files: ' . json_encode($files, JSON_PRETTY_PRINT) . ',
86-
themes: ' . json_encode($themes, JSON_PRETTY_PRINT) . '
95+
themes: ' . json_encode($themes, JSON_PRETTY_PRINT) . ',
96+
names: {' . $namesOutput . '},
8797
};
8898
';
8999
}

core/Command/Maintenance/Mimetype/UpdateJS.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
3232

3333
// Output the JS
3434
$generatedMimetypeFile = new GenerateMimetypeFileBuilder();
35-
file_put_contents(\OC::$SERVERROOT . '/core/js/mimetypelist.js', $generatedMimetypeFile->generateFile($aliases));
35+
$namings = $this->mimetypeDetector->getAllNamings();
36+
file_put_contents(\OC::$SERVERROOT . '/core/js/mimetypelist.js', $generatedMimetypeFile->generateFile($aliases, $namings));
3637

3738
$output->writeln('<info>mimetypelist.js is updated');
3839
return 0;

core/js/mimetypelist.js

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ OC.MimeTypeList={
8181
"application/x-7z-compressed": "package/x-generic",
8282
"application/x-bzip2": "package/x-generic",
8383
"application/x-cbr": "text",
84-
"application/x-compressed": "package/x-generic",
8584
"application/x-dcraw": "image",
8685
"application/x-deb": "package/x-generic",
8786
"application/x-fictionbook+xml": "text",
@@ -115,6 +114,7 @@ OC.MimeTypeList={
115114
"text/x-h": "text/code",
116115
"text/x-java-source": "text/code",
117116
"text/x-ldif": "text/code",
117+
"text/x-nfo": "text/code",
118118
"text/x-python": "text/code",
119119
"text/x-rst": "text",
120120
"text/x-shellscript": "text/code",
@@ -151,5 +151,110 @@ OC.MimeTypeList={
151151
"x-office-presentation",
152152
"x-office-spreadsheet"
153153
],
154-
themes: []
154+
themes: [],
155+
names: {'application/epub+zip': t('core', "Electronic book document"),
156+
'application/gpx+xml': t('core', "GPX geographic data"),
157+
'application/gzip': t('core', "Gzip archive"),
158+
'application/illustrator': t('core', "Adobe Illustrator document"),
159+
'application/json': t('core', "JSON document"),
160+
'application/msword': t('core', "Word document"),
161+
'application/octet-stream': t('core', "Unknown"),
162+
'application/pdf': t('core', "PDF document"),
163+
'application/postscript': t('core', "PostScript document"),
164+
'application/rss+xml': t('core', "RSS summary"),
165+
'application/vnd.android.package-archive': t('core', "Android package"),
166+
'application/vnd.google-earth.kml+xml': t('core', "KML geographic data"),
167+
'application/vnd.google-earth.kmz': t('core', "KML geographic compressed data"),
168+
'application/vnd.lotus-wordpro': t('core', "Lotus Word Pro document"),
169+
'application/vnd.ms-excel': t('core', "Excel spreadsheet"),
170+
'application/vnd.ms-excel.addin.macroEnabled.12': t('core', "Excel add-in"),
171+
'application/vnd.ms-excel.sheet.binary.macroEnabled.12': t('core', "Excel 2007 binary spreadsheet"),
172+
'application/vnd.ms-excel.sheet.macroEnabled.12': t('core', "Excel spreadsheet"),
173+
'application/vnd.ms-excel.template.macroEnabled.12': t('core', "Excel spreadsheet template"),
174+
'application/vnd.ms-powerpoint': t('core', "PowerPoint presentation"),
175+
'application/vnd.ms-powerpoint.addin.macroEnabled.12': t('core', "PowerPoint add-in"),
176+
'application/vnd.ms-powerpoint.presentation.macroEnabled.12': t('core', "PowerPoint presentation"),
177+
'application/vnd.ms-powerpoint.slideshow.macroEnabled.12': t('core', "PowerPoint presentation"),
178+
'application/vnd.ms-powerpoint.template.macroEnabled.12': t('core', "PowerPoint presentation template"),
179+
'application/vnd.ms-word.document.macroEnabled.12': t('core', "Word document"),
180+
'application/vnd.oasis.opendocument.formula': t('core', "ODF formula"),
181+
'application/vnd.oasis.opendocument.graphics': t('core', "ODG drawing"),
182+
'application/vnd.oasis.opendocument.graphics-flat-xml': t('core', "ODG drawing (Flat XML)"),
183+
'application/vnd.oasis.opendocument.graphics-template': t('core', "ODG template"),
184+
'application/vnd.oasis.opendocument.presentation': t('core', "ODP presentation"),
185+
'application/vnd.oasis.opendocument.presentation-flat-xml': t('core', "ODP presentation (Flat XML)"),
186+
'application/vnd.oasis.opendocument.presentation-template': t('core', "ODP template"),
187+
'application/vnd.oasis.opendocument.spreadsheet': t('core', "ODS spreadsheet"),
188+
'application/vnd.oasis.opendocument.spreadsheet-flat-xml': t('core', "ODS spreadsheet (Flat XML)"),
189+
'application/vnd.oasis.opendocument.spreadsheet-template': t('core', "ODS template"),
190+
'application/vnd.oasis.opendocument.text': t('core', "ODT document"),
191+
'application/vnd.oasis.opendocument.text-flat-xml': t('core', "ODT document (Flat XML)"),
192+
'application/vnd.oasis.opendocument.text-template': t('core', "ODT template"),
193+
'application/vnd.openxmlformats-officedocument.presentationml.presentation': t('core', "PowerPoint 2007 presentation"),
194+
'application/vnd.openxmlformats-officedocument.presentationml.slideshow': t('core', "PowerPoint 2007 show"),
195+
'application/vnd.openxmlformats-officedocument.presentationml.template': t('core', "PowerPoint 2007 presentation template"),
196+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': t('core', "Excel 2007 spreadsheet"),
197+
'application/vnd.openxmlformats-officedocument.spreadsheetml.template': t('core', "Excel 2007 spreadsheet template"),
198+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': t('core', "Word 2007 document"),
199+
'application/vnd.openxmlformats-officedocument.wordprocessingml.template': t('core', "Word 2007 document template"),
200+
'application/vnd.visio': t('core', "Microsoft Visio document"),
201+
'application/vnd.wordperfect': t('core', "WordPerfect document"),
202+
'application/x-7z-compressed': t('core', "7-zip archive"),
203+
'application/x-blender': t('core', "Blender scene"),
204+
'application/x-bzip2': t('core', "Bzip2 archive"),
205+
'application/x-fictionbook+xml': t('core', "FictionBook document"),
206+
'application/x-krita': t('core', "Krita document"),
207+
'application/x-mobipocket-ebook': t('core', "Mobipocket e-book"),
208+
'application/x-msi': t('core', "Windows Installer package"),
209+
'application/x-perl': t('core', "Perl script"),
210+
'application/x-php': t('core', "PHP script"),
211+
'application/x-tar': t('core', "Tar archive"),
212+
'application/xml': t('core', "XML document"),
213+
'application/yaml': t('core', "YAML document"),
214+
'application/zip': t('core', "Zip archive"),
215+
'application/zstd': t('core', "Zstandard archive"),
216+
'audio/aac': t('core', "AAC audio"),
217+
'audio/flac': t('core', "FLAC audio"),
218+
'audio/mp4': t('core', "MPEG-4 audio"),
219+
'audio/mpeg': t('core', "MP3 audio"),
220+
'audio/ogg': t('core', "Ogg audio"),
221+
'audio/webm': t('core', "WebM audio"),
222+
'audio/x-scpls': t('core', "MP3 ShoutCast playlist"),
223+
'image/bmp': t('core', "Windows BMP image"),
224+
'image/emf': t('core', "EMF image"),
225+
'image/gif': t('core', "GIF image"),
226+
'image/heif': t('core', "HEIF image"),
227+
'image/jp2': t('core', "JPEG-2000 JP2 image"),
228+
'image/jpeg': t('core', "JPEG image"),
229+
'image/png': t('core', "PNG image"),
230+
'image/svg+xml': t('core', "SVG image"),
231+
'image/tiff': t('core', "TIFF image"),
232+
'image/webp': t('core', "WebP image"),
233+
'image/x-dcraw': t('core', "Digital raw image"),
234+
'message/rfc822': t('core', "Email message"),
235+
'text/calendar': t('core', "VCS\/ICS calendar"),
236+
'text/css': t('core', "CSS stylesheet"),
237+
'text/csv': t('core', "CSV document"),
238+
'text/html': t('core', "HTML document"),
239+
'text/markdown': t('core', "Markdown document"),
240+
'text/org': t('core', "Org-mode file"),
241+
'text/plain': t('core', "Plain text document"),
242+
'text/vcard': t('core', "Electronic business card"),
243+
'text/x-c++src': t('core', "C++ source code"),
244+
'text/x-ldif': t('core', "LDIF address book"),
245+
'text/x-nfo': t('core', "NFO document"),
246+
'text/x-python': t('core', "Python script"),
247+
'text/x-rst': t('core', "ReStructuredText document"),
248+
'video/3gpp': t('core', "3GPP multimedia file"),
249+
'video/dv': t('core', "DV video"),
250+
'video/mp2t': t('core', "MPEG-2 transport stream"),
251+
'video/mp4': t('core', "MPEG-4 video"),
252+
'video/mpeg': t('core', "MPEG video"),
253+
'video/ogg': t('core', "Ogg video"),
254+
'video/quicktime': t('core', "QuickTime video"),
255+
'video/webm': t('core', "WebM video"),
256+
'video/x-flv': t('core', "Flash video"),
257+
'video/x-matroska': t('core', "Matroska video"),
258+
'video/x-ms-wmv': t('core', "Windows Media video"),
259+
},
155260
};

lib/private/Files/Type/Detection.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
class Detection implements IMimeTypeDetector {
2525
private const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json';
2626
private const CUSTOM_MIMETYPEALIASES = 'mimetypealiases.json';
27+
private const CUSTOM_MIMETYPENAMES = 'mimetypenames.json';
2728

2829
/** @var array<list{string, string|null}> */
2930
protected array $mimeTypes = [];
@@ -32,6 +33,8 @@ class Detection implements IMimeTypeDetector {
3233
protected array $mimeTypeIcons = [];
3334
/** @var array<string,string> */
3435
protected array $mimeTypeAlias = [];
36+
/** @var array<string,string> */
37+
protected array $mimeTypesNames = [];
3538

3639
public function __construct(
3740
private IURLGenerator $urlGenerator,
@@ -149,6 +152,25 @@ public function getAllMappings(): array {
149152
return $this->mimeTypes;
150153
}
151154

155+
private function loadNamings(): void {
156+
if (!empty($this->mimeTypesNames)) {
157+
return;
158+
}
159+
160+
$mimeTypeMapping = json_decode(file_get_contents($this->defaultConfigDir . '/mimetypenames.dist.json'), true);
161+
$mimeTypeMapping = $this->loadCustomDefinitions(self::CUSTOM_MIMETYPENAMES, $mimeTypeMapping);
162+
163+
$this->mimeTypesNames = $mimeTypeMapping;
164+
}
165+
166+
/**
167+
* @return array<string,string>
168+
*/
169+
public function getAllNamings(): array {
170+
$this->loadNamings();
171+
return $this->mimeTypesNames;
172+
}
173+
152174
/**
153175
* detect MIME type only based on filename, content of file is not used
154176
*

lib/private/IntegrityCheck/Checker.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ private function generateHashes(\RecursiveIteratorIterator $iterator,
148148
}
149149
if ($filename === $this->environmentHelper->getServerRoot() . '/core/js/mimetypelist.js') {
150150
$oldMimetypeList = new GenerateMimetypeFileBuilder();
151-
$newFile = $oldMimetypeList->generateFile($this->mimeTypeDetector->getAllAliases());
151+
$newFile = $oldMimetypeList->generateFile($this->mimeTypeDetector->getAllAliases(), $this->mimeTypeDetector->getAllNamings());
152152
$oldFile = $this->fileAccessHelper->file_get_contents($filename);
153153
if ($newFile === $oldFile) {
154-
$hashes[$relativeFileName] = hash('sha512', $oldMimetypeList->generateFile($this->mimeTypeDetector->getOnlyDefaultAliases()));
154+
$hashes[$relativeFileName] = hash('sha512', $oldMimetypeList->generateFile($this->mimeTypeDetector->getOnlyDefaultAliases(), $this->mimeTypeDetector->getAllNamings()));
155155
continue;
156156
}
157157
}

lib/public/Files/IMimeTypeDetector.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,12 @@ public function getAllAliases(): array;
8787
* @since 32.0.0
8888
*/
8989
public function getAllMappings(): array;
90+
91+
/**
92+
* Get all human readable mime names
93+
*
94+
* @return array<string,string>
95+
* @since 32.0.0
96+
*/
97+
public function getAllNamings(): array;
9098
}

0 commit comments

Comments
 (0)