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.
|
||||
dependencies:
|
||||
mime: ^1.0.5
|
||||
# path: ^1.8.0
|
||||
|
||||
dev_dependencies:
|
||||
|
|
Loading…
Reference in a new issue