add: adding ports from the symfony mime component
This commit is contained in:
parent
9b53df9b0d
commit
830fcdf0da
12 changed files with 4138 additions and 0 deletions
16
packages/mime/lib/mime.dart
Normal file
16
packages/mime/lib/mime.dart
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Protevus Platform.
|
||||||
|
*
|
||||||
|
* (C) Protevus <developers@protevus.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
library;
|
||||||
|
|
||||||
|
export 'src/mime_type_guesser_interface.dart';
|
||||||
|
export 'src/file_binary_mime_type_guesser.dart';
|
||||||
|
export 'src/file_info_mime_type_guesser.dart';
|
||||||
|
export 'src/mime_types_interface.dart';
|
||||||
|
export 'src/mime_types.dart';
|
14
packages/mime/lib/mime_exception.dart
Normal file
14
packages/mime/lib/mime_exception.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Protevus Platform.
|
||||||
|
*
|
||||||
|
* (C) Protevus <developers@protevus.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
library;
|
||||||
|
|
||||||
|
export 'src/exception/exception_interface.dart';
|
||||||
|
export 'src/exception/invalid_argument_exception.dart';
|
||||||
|
export 'src/exception/logic_exception.dart';
|
24
packages/mime/lib/src/exception/exception_interface.dart
Normal file
24
packages/mime/lib/src/exception/exception_interface.dart
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// This file is part of the Symfony package.
|
||||||
|
//
|
||||||
|
// (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
// In Dart, we don't have a direct equivalent of PHP's namespace.
|
||||||
|
// Instead, we use library or part directives to organize code.
|
||||||
|
// For this example, we'll assume this is part of a library called 'symfony_mime'.
|
||||||
|
|
||||||
|
// Dart doesn't have a direct equivalent to PHP's Throwable interface.
|
||||||
|
// Instead, we'll use the Exception class as the base for our interface.
|
||||||
|
|
||||||
|
/// Exception interface for the Symfony MIME component.
|
||||||
|
///
|
||||||
|
/// This interface is used to mark exceptions specific to the MIME component.
|
||||||
|
/// It doesn't add any additional methods but serves as a marker interface.
|
||||||
|
///
|
||||||
|
/// @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
abstract class ExceptionInterface implements Exception {
|
||||||
|
// This interface doesn't declare any methods.
|
||||||
|
// It's used as a marker interface in Dart, similar to its use in PHP.
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'dart:core';
|
||||||
|
import 'exception_interface.dart';
|
||||||
|
|
||||||
|
/// @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
class InvalidArgumentException implements Exception, ExceptionInterface {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
// Constructor in Dart
|
||||||
|
InvalidArgumentException([this.message = '']);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'InvalidArgumentException: $message';
|
||||||
|
}
|
5
packages/mime/lib/src/exception/logic_exception.dart
Normal file
5
packages/mime/lib/src/exception/logic_exception.dart
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import 'package:protevus_mime/src/exception/exception_interface.dart';
|
||||||
|
|
||||||
|
class LogicException extends StateError implements ExceptionInterface {
|
||||||
|
LogicException(super.message);
|
||||||
|
}
|
95
packages/mime/lib/src/file_binary_mime_type_guesser.dart
Normal file
95
packages/mime/lib/src/file_binary_mime_type_guesser.dart
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:protevus_mime/mime_exception.dart';
|
||||||
|
import 'package:protevus_mime/mime.dart';
|
||||||
|
|
||||||
|
/// This file is part of the Symfony package.
|
||||||
|
///
|
||||||
|
/// (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
///
|
||||||
|
/// For the full copyright and license information, please view the LICENSE
|
||||||
|
/// file that was distributed with this source code.
|
||||||
|
|
||||||
|
/// Guesses the MIME type with the binary "file" (only available on *nix).
|
||||||
|
///
|
||||||
|
/// @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface {
|
||||||
|
/// The command to run to get the MIME type of a file.
|
||||||
|
///
|
||||||
|
/// The $cmd pattern must contain a "%s" string that will be replaced
|
||||||
|
/// with the file name to guess.
|
||||||
|
///
|
||||||
|
/// The command output must start with the MIME type of the file.
|
||||||
|
final String _cmd;
|
||||||
|
|
||||||
|
/// Creates a new [FileBinaryMimeTypeGuesser] instance.
|
||||||
|
///
|
||||||
|
/// [cmd] The command to run to get the MIME type of a file.
|
||||||
|
FileBinaryMimeTypeGuesser([this._cmd = 'file -b --mime -- %s 2>/dev/null']);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isGuesserSupported() {
|
||||||
|
// Dart doesn't have a direct equivalent to PHP's static variables inside methods,
|
||||||
|
// so we'll use a top-level variable instead.
|
||||||
|
return isGuesserSupportedCached();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> guessMimeType(String filePath) async {
|
||||||
|
if (!File(filePath).existsSync() ||
|
||||||
|
!File(filePath).statSync().modeString().contains('r')) {
|
||||||
|
throw InvalidArgumentException(
|
||||||
|
'The "$filePath" file does not exist or is not readable.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isGuesserSupported()) {
|
||||||
|
throw LogicException(
|
||||||
|
'The "${runtimeType.toString()}" guesser is not supported.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final result = await Process.run(
|
||||||
|
'sh', ['-c', _cmd.replaceFirst('%s', _escapeShellArg(filePath))]);
|
||||||
|
|
||||||
|
if (result.exitCode > 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final type = result.stdout.toString().trim();
|
||||||
|
final match =
|
||||||
|
RegExp(r'^([a-z0-9\-]+/[a-z0-9\-\+\.]+)', caseSensitive: false)
|
||||||
|
.firstMatch(type);
|
||||||
|
|
||||||
|
if (match == null) {
|
||||||
|
// it's not a type, but an error message
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match.group(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _escapeShellArg(String arg) {
|
||||||
|
return "'${arg.replaceAll("'", "'\\''")}'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? _supportedCache;
|
||||||
|
|
||||||
|
bool isGuesserSupportedCached() {
|
||||||
|
if (_supportedCache != null) {
|
||||||
|
return _supportedCache!;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Platform.isWindows || !_hasCommand('file')) {
|
||||||
|
return _supportedCache = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _supportedCache = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _hasCommand(String command) {
|
||||||
|
try {
|
||||||
|
final result = Process.runSync('which', [command]);
|
||||||
|
return result.exitCode == 0 && result.stdout.toString().trim().isNotEmpty;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
55
packages/mime/lib/src/file_info_mime_type_guesser.dart
Normal file
55
packages/mime/lib/src/file_info_mime_type_guesser.dart
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:mime/mime.dart' as mime;
|
||||||
|
|
||||||
|
import 'package:protevus_mime/mime_exception.dart';
|
||||||
|
import 'package:protevus_mime/mime.dart';
|
||||||
|
|
||||||
|
/// Guesses the MIME type using the MIME package, which is similar to PHP's FileInfo.
|
||||||
|
///
|
||||||
|
/// @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
/// Ported to Dart by [Your Name]
|
||||||
|
class FileInfoMimeTypeGuesser implements MimeTypeGuesserInterface {
|
||||||
|
/// Constructs a new FileinfoMimeTypeGuesser.
|
||||||
|
FileInfoMimeTypeGuesser();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isGuesserSupported() {
|
||||||
|
// In Dart, we're using the mime package which is always available if imported
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> guessMimeType(String path) async {
|
||||||
|
final file = File(path);
|
||||||
|
|
||||||
|
if (!await file.exists() ||
|
||||||
|
!(await file.stat()).type.toString().contains('file')) {
|
||||||
|
throw InvalidArgumentException(
|
||||||
|
'The "$path" file does not exist or is not readable.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isGuesserSupported()) {
|
||||||
|
throw LogicException(
|
||||||
|
'The "${runtimeType.toString()}" guesser is not supported.');
|
||||||
|
}
|
||||||
|
|
||||||
|
String? mimeType;
|
||||||
|
try {
|
||||||
|
// Using the mime package to guess the MIME type
|
||||||
|
final bytes = await file.openRead(0, 12).first;
|
||||||
|
mimeType = mime.lookupMimeType(path, headerBytes: bytes);
|
||||||
|
} catch (e) {
|
||||||
|
print('Error guessing MIME type: $e');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeType != null && mimeType.length % 2 == 0) {
|
||||||
|
final mimeStart = mimeType.substring(0, mimeType.length ~/ 2);
|
||||||
|
if (mimeStart + mimeStart == mimeType) {
|
||||||
|
mimeType = mimeStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
}
|
22
packages/mime/lib/src/mime_type_guesser_interface.dart
Normal file
22
packages/mime/lib/src/mime_type_guesser_interface.dart
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// This file is part of the Symfony package.
|
||||||
|
//
|
||||||
|
// (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
/// Guesses the MIME type of a file.
|
||||||
|
///
|
||||||
|
/// @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
abstract class MimeTypeGuesserInterface {
|
||||||
|
/// Returns true if this guesser is supported.
|
||||||
|
bool isGuesserSupported();
|
||||||
|
|
||||||
|
/// Guesses the MIME type of the file with the given path.
|
||||||
|
///
|
||||||
|
/// Throws [UnsupportedError] if the guesser is not supported
|
||||||
|
/// Throws [FileSystemException] if the file does not exist or is not readable
|
||||||
|
Future<String?> guessMimeType(String path);
|
||||||
|
}
|
3872
packages/mime/lib/src/mime_types.dart
Normal file
3872
packages/mime/lib/src/mime_types.dart
Normal file
File diff suppressed because it is too large
Load diff
21
packages/mime/lib/src/mime_types_interface.dart
Normal file
21
packages/mime/lib/src/mime_types_interface.dart
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// This file is part of the Symfony package.
|
||||||
|
//
|
||||||
|
// (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
import 'package:protevus_mime/mime.dart';
|
||||||
|
|
||||||
|
/// @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
abstract class MimeTypesInterface implements MimeTypeGuesserInterface {
|
||||||
|
/// Gets the extensions for the given MIME type in decreasing order of preference.
|
||||||
|
///
|
||||||
|
/// Returns a list of strings representing file extensions.
|
||||||
|
List<String> getExtensions(String mimeType);
|
||||||
|
|
||||||
|
/// Gets the MIME types for the given extension in decreasing order of preference.
|
||||||
|
///
|
||||||
|
/// Returns a list of strings representing MIME types.
|
||||||
|
List<String> getMimeTypes(String ext);
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ environment:
|
||||||
|
|
||||||
# Add regular dependencies here.
|
# Add regular dependencies here.
|
||||||
dependencies:
|
dependencies:
|
||||||
|
mime: ^1.0.5
|
||||||
# path: ^1.8.0
|
# path: ^1.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
Loading…
Reference in a new issue