You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
15 KiB
355 lines
15 KiB
6 months ago
|
import string
|
||
|
|
||
|
from collections import OrderedDict
|
||
|
from typing import Dict, Literal, Optional, Sequence, Union
|
||
|
|
||
|
from .. import BaseProvider, ElementsType
|
||
|
|
||
|
|
||
|
class Provider(BaseProvider):
|
||
|
"""Implement default file provider for Faker."""
|
||
|
|
||
|
application_mime_types: ElementsType[str] = (
|
||
|
"application/atom+xml", # Atom feeds
|
||
|
"application/ecmascript",
|
||
|
# ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to
|
||
|
# application/javascript but with stricter processing rules)
|
||
|
"application/EDI-X12", # EDI X12 data; Defined in RFC 1767
|
||
|
"application/EDIFACT", # EDI EDIFACT data; Defined in RFC 1767
|
||
|
"application/json", # JavaScript Object Notation JSON; Defined in RFC 4627
|
||
|
# ECMAScript/JavaScript; Defined in RFC 4329 (equivalent to
|
||
|
# application/ecmascript
|
||
|
"application/javascript",
|
||
|
# but with looser processing rules) It is not accepted in IE 8
|
||
|
# or earlier - text/javascript is accepted but it is defined as obsolete in RFC 4329.
|
||
|
# The "type" attribute of the <script> tag in HTML5 is optional and in practice
|
||
|
# omitting the media type of JavaScript programs is the most interoperable
|
||
|
# solution since all browsers have always assumed the correct
|
||
|
# default even before HTML5.
|
||
|
"application/octet-stream",
|
||
|
# Arbitrary binary data.[6] Generally speaking this type identifies files that are not associated with
|
||
|
# a specific application. Contrary to past assumptions by software packages such as Apache this is not
|
||
|
# a type that should be applied to unknown files. In such a case, a server or application should not indicate
|
||
|
# a content type, as it may be incorrect, but rather, should omit the type in order to allow the recipient
|
||
|
# to guess the type.[7]
|
||
|
"application/ogg", # Ogg, a multimedia bitstream container format; Defined in RFC 5334
|
||
|
"application/pdf", # Portable Document Format, PDF has been in use for document exchange
|
||
|
# on the Internet since 1993; Defined in RFC 3778
|
||
|
"application/postscript", # PostScript; Defined in RFC 2046
|
||
|
"application/rdf+xml", # Resource Description Framework; Defined by RFC 3870
|
||
|
"application/rss+xml", # RSS feeds
|
||
|
"application/soap+xml", # SOAP; Defined by RFC 3902
|
||
|
# Web Open Font Format; (candidate recommendation; use application/x-font-woff
|
||
|
"application/font-woff",
|
||
|
# until standard is official)
|
||
|
"application/xhtml+xml", # XHTML; Defined by RFC 3236
|
||
|
"application/xml-dtd", # DTD files; Defined by RFC 3023
|
||
|
"application/xop+xml", # XOP
|
||
|
"application/zip", # ZIP archive files; Registered[8]
|
||
|
"application/gzip", # Gzip, Defined in RFC 6713
|
||
|
)
|
||
|
|
||
|
audio_mime_types: ElementsType[str] = (
|
||
|
"audio/basic", # mulaw audio at 8 kHz, 1 channel; Defined in RFC 2046
|
||
|
"audio/L24", # 24bit Linear PCM audio at 8-48 kHz, 1-N channels; Defined in RFC 3190
|
||
|
"audio/mp4", # MP4 audio
|
||
|
"audio/mpeg", # MP3 or other MPEG audio; Defined in RFC 3003
|
||
|
"audio/ogg", # Ogg Vorbis, Speex, Flac and other audio; Defined in RFC 5334
|
||
|
"audio/vorbis", # Vorbis encoded audio; Defined in RFC 5215
|
||
|
# RealAudio; Documented in RealPlayer Help[9]
|
||
|
"audio/vnd.rn-realaudio",
|
||
|
"audio/vnd.wave", # WAV audio; Defined in RFC 2361
|
||
|
"audio/webm", # WebM open media format
|
||
|
)
|
||
|
|
||
|
image_mime_types: ElementsType[str] = (
|
||
|
"image/gif", # GIF image; Defined in RFC 2045 and RFC 2046
|
||
|
"image/jpeg", # JPEG JFIF image; Defined in RFC 2045 and RFC 2046
|
||
|
"image/pjpeg",
|
||
|
# JPEG JFIF image; Associated with Internet Explorer; Listed in ms775147(v=vs.85) - Progressive JPEG,
|
||
|
# initiated before global browser support for progressive JPEGs (Microsoft and Firefox).
|
||
|
# Portable Network Graphics; Registered,[10] Defined in RFC 2083
|
||
|
"image/png",
|
||
|
"image/svg+xml", # SVG vector image; Defined in SVG Tiny 1.2 Specification Appendix M
|
||
|
# Tag Image File Format (only for Baseline TIFF); Defined in RFC 3302
|
||
|
"image/tiff",
|
||
|
"image/vnd.microsoft.icon", # ICO image; Registered[11]
|
||
|
)
|
||
|
|
||
|
message_mime_types: ElementsType[str] = (
|
||
|
"message/http", # Defined in RFC 2616
|
||
|
"message/imdn+xml", # IMDN Instant Message Disposition Notification; Defined in RFC 5438
|
||
|
"message/partial", # Email; Defined in RFC 2045 and RFC 2046
|
||
|
# Email; EML files, MIME files, MHT files, MHTML files; Defined in RFC
|
||
|
# 2045 and RFC 2046
|
||
|
"message/rfc822",
|
||
|
)
|
||
|
|
||
|
model_mime_types: ElementsType[str] = (
|
||
|
"model/example", # Defined in RFC 4735
|
||
|
"model/iges", # IGS files, IGES files; Defined in RFC 2077
|
||
|
"model/mesh", # MSH files, MESH files; Defined in RFC 2077, SILO files
|
||
|
"model/vrml", # WRL files, VRML files; Defined in RFC 2077
|
||
|
# X3D ISO standard for representing 3D computer graphics, X3DB binary
|
||
|
# files
|
||
|
"model/x3d+binary",
|
||
|
"model/x3d+vrml", # X3D ISO standard for representing 3D computer graphics, X3DV VRML files
|
||
|
"model/x3d+xml", # X3D ISO standard for representing 3D computer graphics, X3D XML files
|
||
|
)
|
||
|
|
||
|
multipart_mime_types: ElementsType[str] = (
|
||
|
"multipart/mixed", # MIME Email; Defined in RFC 2045 and RFC 2046
|
||
|
"multipart/alternative", # MIME Email; Defined in RFC 2045 and RFC 2046
|
||
|
# MIME Email; Defined in RFC 2387 and used by MHTML (HTML mail)
|
||
|
"multipart/related",
|
||
|
"multipart/form-data", # MIME Webform; Defined in RFC 2388
|
||
|
"multipart/signed", # Defined in RFC 1847
|
||
|
"multipart/encrypted", # Defined in RFC 1847
|
||
|
)
|
||
|
|
||
|
text_mime_types: ElementsType[str] = (
|
||
|
"text/cmd", # commands; subtype resident in Gecko browsers like Firefox 3.5
|
||
|
"text/css", # Cascading Style Sheets; Defined in RFC 2318
|
||
|
"text/csv", # Comma-separated values; Defined in RFC 4180
|
||
|
"text/html", # HTML; Defined in RFC 2854
|
||
|
"text/javascript",
|
||
|
# (Obsolete): JavaScript; Defined in and obsoleted by RFC 4329 in order to discourage its usage in favor of
|
||
|
# application/javascript. However, text/javascript is allowed in HTML 4 and 5 and, unlike
|
||
|
# application/javascript, has cross-browser support. The "type" attribute of the <script> tag in HTML5 is
|
||
|
# optional and there is no need to use it at all since all browsers have always assumed the correct default
|
||
|
# (even in HTML 4 where it was required by the specification).
|
||
|
"text/plain", # Textual data; Defined in RFC 2046 and RFC 3676
|
||
|
"text/vcard", # vCard (contact information); Defined in RFC 6350
|
||
|
"text/xml", # Extensible Markup Language; Defined in RFC 3023
|
||
|
)
|
||
|
|
||
|
video_mime_types: ElementsType[str] = (
|
||
|
"video/mpeg", # MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046
|
||
|
"video/mp4", # MP4 video; Defined in RFC 4337
|
||
|
# Ogg Theora or other video (with audio); Defined in RFC 5334
|
||
|
"video/ogg",
|
||
|
"video/quicktime", # QuickTime video; Registered[12]
|
||
|
"video/webm", # WebM Matroska-based open media format
|
||
|
"video/x-matroska", # Matroska open media format
|
||
|
"video/x-ms-wmv", # Windows Media Video; Documented in Microsoft KB 288102
|
||
|
"video/x-flv", # Flash video (FLV files)
|
||
|
)
|
||
|
|
||
|
mime_types: Dict[str, ElementsType[str]] = OrderedDict(
|
||
|
(
|
||
|
("application", application_mime_types),
|
||
|
("audio", audio_mime_types),
|
||
|
("image", image_mime_types),
|
||
|
("message", message_mime_types),
|
||
|
("model", model_mime_types),
|
||
|
("multipart", multipart_mime_types),
|
||
|
("text", text_mime_types),
|
||
|
("video", video_mime_types),
|
||
|
)
|
||
|
)
|
||
|
|
||
|
audio_file_extensions: ElementsType[str] = (
|
||
|
"flac",
|
||
|
"mp3",
|
||
|
"wav",
|
||
|
)
|
||
|
|
||
|
image_file_extensions: ElementsType[str] = (
|
||
|
"bmp",
|
||
|
"gif",
|
||
|
"jpeg",
|
||
|
"jpg",
|
||
|
"png",
|
||
|
"tiff",
|
||
|
)
|
||
|
|
||
|
text_file_extensions: ElementsType[str] = (
|
||
|
"css",
|
||
|
"csv",
|
||
|
"html",
|
||
|
"js",
|
||
|
"json",
|
||
|
"txt",
|
||
|
)
|
||
|
|
||
|
video_file_extensions: ElementsType[str] = (
|
||
|
"mp4",
|
||
|
"avi",
|
||
|
"mov",
|
||
|
"webm",
|
||
|
)
|
||
|
|
||
|
office_file_extensions: ElementsType[str] = (
|
||
|
"doc", # legacy MS Word
|
||
|
"docx", # MS Word
|
||
|
"xls", # legacy MS Excel
|
||
|
"xlsx", # MS Excel
|
||
|
"ppt", # legacy MS PowerPoint
|
||
|
"pptx", # MS PowerPoint
|
||
|
"odt", # LibreOffice document
|
||
|
"ods", # LibreOffice spreadsheet
|
||
|
"odp", # LibreOffice presentation
|
||
|
"pages", # Apple Pages
|
||
|
"numbers", # Apple Numbers
|
||
|
"key", # Apple Keynote
|
||
|
"pdf", # Portable Document Format
|
||
|
)
|
||
|
|
||
|
file_extensions: Dict[str, ElementsType[str]] = OrderedDict(
|
||
|
(
|
||
|
("audio", audio_file_extensions),
|
||
|
("image", image_file_extensions),
|
||
|
("office", office_file_extensions),
|
||
|
("text", text_file_extensions),
|
||
|
("video", video_file_extensions),
|
||
|
)
|
||
|
)
|
||
|
|
||
|
file_systems_path_rules: Dict[str, Dict] = {
|
||
|
"windows": {
|
||
|
"root": "C:\\",
|
||
|
"separator": "\\",
|
||
|
},
|
||
|
"linux": {
|
||
|
"root": "/",
|
||
|
"separator": "/",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
unix_device_prefixes: ElementsType[str] = ("sd", "vd", "xvd")
|
||
|
|
||
|
def mime_type(self, category: Optional[str] = None) -> str:
|
||
|
"""Generate a mime type under the specified ``category``.
|
||
|
|
||
|
If ``category`` is ``None``, a random category will be used. The list of
|
||
|
valid categories include ``'application'``, ``'audio'``, ``'image'``,
|
||
|
``'message'``, ``'model'``, ``'multipart'``, ``'text'``, and
|
||
|
``'video'``.
|
||
|
|
||
|
:sample:
|
||
|
:sample: category='application'
|
||
|
"""
|
||
|
category = category if category else self.random_element(list(self.mime_types.keys()))
|
||
|
return self.random_element(self.mime_types[category])
|
||
|
|
||
|
def file_name(self, category: Optional[str] = None, extension: Optional[str] = None) -> str:
|
||
|
"""Generate a random file name with extension.
|
||
|
|
||
|
If ``extension`` is ``None``, a random extension will be created
|
||
|
under the hood using |file_extension| with the specified
|
||
|
``category``. If a value for ``extension`` is provided, the
|
||
|
value will be used instead, and ``category`` will be ignored.
|
||
|
The actual name part itself is generated using |word|. If
|
||
|
extension is an empty string then no extension will be added,
|
||
|
and file_name will be the same as |word|.
|
||
|
|
||
|
:sample: size=10
|
||
|
:sample: category='audio'
|
||
|
:sample: extension='abcdef'
|
||
|
:sample: category='audio', extension='abcdef'
|
||
|
:sample: extension=''
|
||
|
"""
|
||
|
if extension is None:
|
||
|
extension = self.file_extension(category)
|
||
|
filename: str = self.generator.word()
|
||
|
return f"{filename}.{extension}" if extension else filename
|
||
|
|
||
|
def file_extension(self, category: Optional[str] = None) -> str:
|
||
|
"""Generate a file extension under the specified ``category``.
|
||
|
|
||
|
If ``category`` is ``None``, a random category will be used. The list of
|
||
|
valid categories include: ``'audio'``, ``'image'``, ``'office'``,
|
||
|
``'text'``, and ``'video'``.
|
||
|
|
||
|
:sample:
|
||
|
:sample: category='image'
|
||
|
"""
|
||
|
if category is None:
|
||
|
category = self.random_element(list(self.file_extensions.keys()))
|
||
|
return self.random_element(self.file_extensions[category])
|
||
|
|
||
|
def file_path(
|
||
|
self,
|
||
|
depth: int = 1,
|
||
|
category: Optional[str] = None,
|
||
|
extension: Optional[Union[str, Sequence[str]]] = None,
|
||
|
absolute: Optional[bool] = True,
|
||
|
file_system_rule: Literal["linux", "windows"] = "linux",
|
||
|
) -> str:
|
||
|
"""Generate an pathname to a file.
|
||
|
|
||
|
This method uses |file_name| under the hood to generate the file
|
||
|
name itself, and ``depth`` controls the depth of the directory
|
||
|
path, and |word| is used under the hood to generate the
|
||
|
different directory names.
|
||
|
|
||
|
If ``absolute`` is ``True`` (default), the generated path starts
|
||
|
with ``/`` and is absolute. Otherwise, the generated path is
|
||
|
relative.
|
||
|
|
||
|
If used, ``extension`` can be either a string, forcing that
|
||
|
extension, a sequence of strings (one will be picked at random),
|
||
|
or an empty sequence (the path will have no extension). Default
|
||
|
behaviour is the same as |file_name|
|
||
|
|
||
|
if ``file_system`` is set (default="linux"), the generated path uses
|
||
|
specified file system path standard, the list of valid file systems include:
|
||
|
``'windows'``, ``'linux'``.
|
||
|
|
||
|
:sample: size=10
|
||
|
:sample: depth=3
|
||
|
:sample: depth=5, category='video'
|
||
|
:sample: depth=5, category='video', extension='abcdef'
|
||
|
:sample: extension=[]
|
||
|
:sample: extension=''
|
||
|
:sample: extension=["a", "bc", "def"]
|
||
|
:sample: depth=5, category='video', extension='abcdef', file_system='windows'
|
||
|
"""
|
||
|
|
||
|
if extension is not None and not isinstance(extension, str):
|
||
|
if len(extension):
|
||
|
extension = self.random_element(extension)
|
||
|
else:
|
||
|
extension = ""
|
||
|
|
||
|
fs_rule = self.file_systems_path_rules.get(file_system_rule, None)
|
||
|
if not fs_rule:
|
||
|
raise TypeError("Specified file system is invalid.")
|
||
|
|
||
|
root = fs_rule["root"]
|
||
|
seperator = fs_rule["separator"]
|
||
|
|
||
|
path: str = self.file_name(category, extension)
|
||
|
for _ in range(0, depth):
|
||
|
path = f"{self.generator.word()}{seperator}{path}"
|
||
|
|
||
|
return root + path if absolute else path
|
||
|
|
||
|
def unix_device(self, prefix: Optional[str] = None) -> str:
|
||
|
"""Generate a Unix device file name.
|
||
|
|
||
|
If ``prefix`` is ``None``, a random prefix will be used. The list of
|
||
|
valid prefixes include: ``'sd'``, ``'vd'``, and ``'xvd'``.
|
||
|
|
||
|
:sample:
|
||
|
:sample: prefix='mmcblk'
|
||
|
"""
|
||
|
if prefix is None:
|
||
|
prefix = self.random_element(self.unix_device_prefixes)
|
||
|
suffix: str = self.random_element(string.ascii_lowercase)
|
||
|
path = "/dev/%s%s" % (prefix, suffix)
|
||
|
return path
|
||
|
|
||
|
def unix_partition(self, prefix: Optional[str] = None) -> str:
|
||
|
"""Generate a Unix partition name.
|
||
|
|
||
|
This method uses |unix_device| under the hood to create a device file
|
||
|
name with the specified ``prefix``.
|
||
|
|
||
|
:sample:
|
||
|
:sample: prefix='mmcblk'
|
||
|
"""
|
||
|
path: str = self.unix_device(prefix=prefix)
|
||
|
path += str(self.random_digit())
|
||
|
return path
|