MeUtils 2025.3.3.18.41.24__py3-none-any.whl → 2025.3.5.19.55.22__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {MeUtils-2025.3.3.18.41.24.dist-info → MeUtils-2025.3.5.19.55.22.dist-info}/METADATA +264 -264
- {MeUtils-2025.3.3.18.41.24.dist-info → MeUtils-2025.3.5.19.55.22.dist-info}/RECORD +61 -33
- examples/_openaisdk/open_router.py +2 -1
- examples/_openaisdk/openai_files.py +16 -5
- examples/_openaisdk/openai_images.py +1 -0
- examples/_openaisdk/openai_moon.py +22 -19
- examples/sh/__init__.py +11 -0
- meutils/apis/baidu/bdaitpzs.py +9 -17
- meutils/apis/chatglm/glm_video_api.py +2 -2
- meutils/apis/images/edits.py +7 -2
- meutils/apis/jimeng/common.py +1 -1
- meutils/apis/oneapi/common.py +4 -4
- meutils/apis/proxy/ips.py +2 -0
- meutils/caches/common.py +4 -0
- meutils/data/VERSION +1 -1
- meutils/data/oneapi/NOTICE.html +12 -0
- meutils/data/oneapi/__init__.py +1 -1
- meutils/data/oneapi/index.html +275 -0
- meutils/io/_openai_files.py +31 -0
- meutils/io/openai_files.py +138 -0
- meutils/io/parsers/__init__.py +10 -0
- meutils/io/parsers/fileparser/PDF/346/212/275/345/217/226.py +58 -0
- meutils/io/parsers/fileparser/__init__.py +11 -0
- meutils/io/parsers/fileparser/common.py +91 -0
- meutils/io/parsers/fileparser/demo.py +41 -0
- meutils/io/parsers/fileparser/filetype/__init__.py +10 -0
- meutils/io/parsers/fileparser/filetype/__main__.py +37 -0
- meutils/io/parsers/fileparser/filetype/filetype.py +98 -0
- meutils/io/parsers/fileparser/filetype/helpers.py +140 -0
- meutils/io/parsers/fileparser/filetype/match.py +155 -0
- meutils/io/parsers/fileparser/filetype/types/__init__.py +118 -0
- meutils/io/parsers/fileparser/filetype/types/application.py +22 -0
- meutils/io/parsers/fileparser/filetype/types/archive.py +687 -0
- meutils/io/parsers/fileparser/filetype/types/audio.py +212 -0
- meutils/io/parsers/fileparser/filetype/types/base.py +29 -0
- meutils/io/parsers/fileparser/filetype/types/document.py +256 -0
- meutils/io/parsers/fileparser/filetype/types/font.py +115 -0
- meutils/io/parsers/fileparser/filetype/types/image.py +383 -0
- meutils/io/parsers/fileparser/filetype/types/isobmff.py +33 -0
- meutils/io/parsers/fileparser/filetype/types/video.py +223 -0
- meutils/io/parsers/fileparser/filetype/utils.py +84 -0
- meutils/io/parsers/fileparser/filetype.py +41 -0
- meutils/io/parsers/fileparser/mineru.py +48 -0
- meutils/io/parsers/fileparser/pdf.py +30 -0
- meutils/io/parsers/fileparser//350/241/250/346/240/274/346/212/275/345/217/226.py +118 -0
- meutils/llm/check_utils.py +33 -2
- meutils/llm/clients.py +1 -0
- meutils/llm/completions/chat_gemini.py +72 -0
- meutils/llm/completions/chat_plus.py +78 -0
- meutils/llm/completions/{agents/file.py → chat_spark.py} +46 -26
- meutils/llm/completions/qwenllm.py +57 -16
- meutils/llm/completions/yuanbao.py +29 -3
- meutils/llm/openai_utils/common.py +2 -2
- meutils/schemas/oneapi/common.py +22 -19
- meutils/schemas/openai_types.py +65 -29
- meutils/schemas/yuanbao_types.py +6 -7
- meutils/types.py +2 -0
- meutils/data/oneapi/NOTICE.md +0 -1
- meutils/data/oneapi/_NOTICE.md +0 -140
- meutils/llm/completions/gemini.py +0 -69
- {MeUtils-2025.3.3.18.41.24.dist-info → MeUtils-2025.3.5.19.55.22.dist-info}/LICENSE +0 -0
- {MeUtils-2025.3.3.18.41.24.dist-info → MeUtils-2025.3.5.19.55.22.dist-info}/WHEEL +0 -0
- {MeUtils-2025.3.3.18.41.24.dist-info → MeUtils-2025.3.5.19.55.22.dist-info}/entry_points.txt +0 -0
- {MeUtils-2025.3.3.18.41.24.dist-info → MeUtils-2025.3.5.19.55.22.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
from __future__ import absolute_import
|
4
|
+
|
5
|
+
from .base import Type
|
6
|
+
|
7
|
+
|
8
|
+
class Midi(Type):
|
9
|
+
"""
|
10
|
+
Implements the Midi audio type matcher.
|
11
|
+
"""
|
12
|
+
MIME = 'audio/midi'
|
13
|
+
EXTENSION = 'midi'
|
14
|
+
|
15
|
+
def __init__(self):
|
16
|
+
super(Midi, self).__init__(
|
17
|
+
mime=Midi.MIME,
|
18
|
+
extension=Midi.EXTENSION
|
19
|
+
)
|
20
|
+
|
21
|
+
def match(self, buf):
|
22
|
+
return (len(buf) > 3 and
|
23
|
+
buf[0] == 0x4D and
|
24
|
+
buf[1] == 0x54 and
|
25
|
+
buf[2] == 0x68 and
|
26
|
+
buf[3] == 0x64)
|
27
|
+
|
28
|
+
|
29
|
+
class Mp3(Type):
|
30
|
+
"""
|
31
|
+
Implements the MP3 audio type matcher.
|
32
|
+
"""
|
33
|
+
MIME = 'audio/mpeg'
|
34
|
+
EXTENSION = 'mp3'
|
35
|
+
|
36
|
+
def __init__(self):
|
37
|
+
super(Mp3, self).__init__(
|
38
|
+
mime=Mp3.MIME,
|
39
|
+
extension=Mp3.EXTENSION
|
40
|
+
)
|
41
|
+
|
42
|
+
def match(self, buf):
|
43
|
+
return (len(buf) > 2 and
|
44
|
+
((buf[0] == 0x49 and
|
45
|
+
buf[1] == 0x44 and
|
46
|
+
buf[2] == 0x33) or
|
47
|
+
(buf[0] == 0xFF and
|
48
|
+
buf[1] == 0xF2) or
|
49
|
+
(buf[0] == 0xFF and
|
50
|
+
buf[1] == 0xF3) or
|
51
|
+
(buf[0] == 0xFF and
|
52
|
+
buf[1] == 0xFB)))
|
53
|
+
|
54
|
+
|
55
|
+
class M4a(Type):
|
56
|
+
"""
|
57
|
+
Implements the M4A audio type matcher.
|
58
|
+
"""
|
59
|
+
MIME = 'audio/mp4'
|
60
|
+
EXTENSION = 'm4a'
|
61
|
+
|
62
|
+
def __init__(self):
|
63
|
+
super(M4a, self).__init__(
|
64
|
+
mime=M4a.MIME,
|
65
|
+
extension=M4a.EXTENSION
|
66
|
+
)
|
67
|
+
|
68
|
+
def match(self, buf):
|
69
|
+
return (len(buf) > 10 and
|
70
|
+
((buf[4] == 0x66 and
|
71
|
+
buf[5] == 0x74 and
|
72
|
+
buf[6] == 0x79 and
|
73
|
+
buf[7] == 0x70 and
|
74
|
+
buf[8] == 0x4D and
|
75
|
+
buf[9] == 0x34 and
|
76
|
+
buf[10] == 0x41) or
|
77
|
+
(buf[0] == 0x4D and
|
78
|
+
buf[1] == 0x34 and
|
79
|
+
buf[2] == 0x41 and
|
80
|
+
buf[3] == 0x20)))
|
81
|
+
|
82
|
+
|
83
|
+
class Ogg(Type):
|
84
|
+
"""
|
85
|
+
Implements the OGG audio type matcher.
|
86
|
+
"""
|
87
|
+
MIME = 'audio/ogg'
|
88
|
+
EXTENSION = 'ogg'
|
89
|
+
|
90
|
+
def __init__(self):
|
91
|
+
super(Ogg, self).__init__(
|
92
|
+
mime=Ogg.MIME,
|
93
|
+
extension=Ogg.EXTENSION
|
94
|
+
)
|
95
|
+
|
96
|
+
def match(self, buf):
|
97
|
+
return (len(buf) > 3 and
|
98
|
+
buf[0] == 0x4F and
|
99
|
+
buf[1] == 0x67 and
|
100
|
+
buf[2] == 0x67 and
|
101
|
+
buf[3] == 0x53)
|
102
|
+
|
103
|
+
|
104
|
+
class Flac(Type):
|
105
|
+
"""
|
106
|
+
Implements the FLAC audio type matcher.
|
107
|
+
"""
|
108
|
+
MIME = 'audio/x-flac'
|
109
|
+
EXTENSION = 'flac'
|
110
|
+
|
111
|
+
def __init__(self):
|
112
|
+
super(Flac, self).__init__(
|
113
|
+
mime=Flac.MIME,
|
114
|
+
extension=Flac.EXTENSION
|
115
|
+
)
|
116
|
+
|
117
|
+
def match(self, buf):
|
118
|
+
return (len(buf) > 3 and
|
119
|
+
buf[0] == 0x66 and
|
120
|
+
buf[1] == 0x4C and
|
121
|
+
buf[2] == 0x61 and
|
122
|
+
buf[3] == 0x43)
|
123
|
+
|
124
|
+
|
125
|
+
class Wav(Type):
|
126
|
+
"""
|
127
|
+
Implements the WAV audio type matcher.
|
128
|
+
"""
|
129
|
+
MIME = 'audio/x-wav'
|
130
|
+
EXTENSION = 'wav'
|
131
|
+
|
132
|
+
def __init__(self):
|
133
|
+
super(Wav, self).__init__(
|
134
|
+
mime=Wav.MIME,
|
135
|
+
extension=Wav.EXTENSION
|
136
|
+
)
|
137
|
+
|
138
|
+
def match(self, buf):
|
139
|
+
return (len(buf) > 11 and
|
140
|
+
buf[0] == 0x52 and
|
141
|
+
buf[1] == 0x49 and
|
142
|
+
buf[2] == 0x46 and
|
143
|
+
buf[3] == 0x46 and
|
144
|
+
buf[8] == 0x57 and
|
145
|
+
buf[9] == 0x41 and
|
146
|
+
buf[10] == 0x56 and
|
147
|
+
buf[11] == 0x45)
|
148
|
+
|
149
|
+
|
150
|
+
class Amr(Type):
|
151
|
+
"""
|
152
|
+
Implements the AMR audio type matcher.
|
153
|
+
"""
|
154
|
+
MIME = 'audio/amr'
|
155
|
+
EXTENSION = 'amr'
|
156
|
+
|
157
|
+
def __init__(self):
|
158
|
+
super(Amr, self).__init__(
|
159
|
+
mime=Amr.MIME,
|
160
|
+
extension=Amr.EXTENSION
|
161
|
+
)
|
162
|
+
|
163
|
+
def match(self, buf):
|
164
|
+
return (len(buf) > 11 and
|
165
|
+
buf[0] == 0x23 and
|
166
|
+
buf[1] == 0x21 and
|
167
|
+
buf[2] == 0x41 and
|
168
|
+
buf[3] == 0x4D and
|
169
|
+
buf[4] == 0x52 and
|
170
|
+
buf[5] == 0x0A)
|
171
|
+
|
172
|
+
|
173
|
+
class Aac(Type):
|
174
|
+
"""Implements the Aac audio type matcher."""
|
175
|
+
|
176
|
+
MIME = 'audio/aac'
|
177
|
+
EXTENSION = 'aac'
|
178
|
+
|
179
|
+
def __init__(self):
|
180
|
+
super(Aac, self).__init__(
|
181
|
+
mime=Aac.MIME,
|
182
|
+
extension=Aac.EXTENSION
|
183
|
+
)
|
184
|
+
|
185
|
+
def match(self, buf):
|
186
|
+
return (buf[:2] == bytearray([0xff, 0xf1]) or
|
187
|
+
buf[:2] == bytearray([0xff, 0xf9]))
|
188
|
+
|
189
|
+
|
190
|
+
class Aiff(Type):
|
191
|
+
"""
|
192
|
+
Implements the AIFF audio type matcher.
|
193
|
+
"""
|
194
|
+
MIME = 'audio/x-aiff'
|
195
|
+
EXTENSION = 'aiff'
|
196
|
+
|
197
|
+
def __init__(self):
|
198
|
+
super(Aiff, self).__init__(
|
199
|
+
mime=Aiff.MIME,
|
200
|
+
extension=Aiff.EXTENSION
|
201
|
+
)
|
202
|
+
|
203
|
+
def match(self, buf):
|
204
|
+
return (len(buf) > 11 and
|
205
|
+
buf[0] == 0x46 and
|
206
|
+
buf[1] == 0x4F and
|
207
|
+
buf[2] == 0x52 and
|
208
|
+
buf[3] == 0x4D and
|
209
|
+
buf[8] == 0x41 and
|
210
|
+
buf[9] == 0x49 and
|
211
|
+
buf[10] == 0x46 and
|
212
|
+
buf[11] == 0x46)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
class Type(object):
|
5
|
+
"""
|
6
|
+
Represents the file type object inherited by
|
7
|
+
specific file type matchers.
|
8
|
+
Provides convenient accessor and helper methods.
|
9
|
+
"""
|
10
|
+
def __init__(self, mime, extension):
|
11
|
+
self.__mime = mime
|
12
|
+
self.__extension = extension
|
13
|
+
|
14
|
+
@property
|
15
|
+
def mime(self):
|
16
|
+
return self.__mime
|
17
|
+
|
18
|
+
@property
|
19
|
+
def extension(self):
|
20
|
+
return self.__extension
|
21
|
+
|
22
|
+
def is_extension(self, extension):
|
23
|
+
return self.__extension is extension
|
24
|
+
|
25
|
+
def is_mime(self, mime):
|
26
|
+
return self.__mime is mime
|
27
|
+
|
28
|
+
def match(self, buf):
|
29
|
+
raise NotImplementedError
|
@@ -0,0 +1,256 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
from __future__ import absolute_import
|
4
|
+
|
5
|
+
from .base import Type
|
6
|
+
|
7
|
+
|
8
|
+
class ZippedDocumentBase(Type):
|
9
|
+
def match(self, buf):
|
10
|
+
# start by checking for ZIP local file header signature
|
11
|
+
idx = self.search_signature(buf, 0, 6000)
|
12
|
+
if idx != 0:
|
13
|
+
return
|
14
|
+
|
15
|
+
return self.match_document(buf)
|
16
|
+
|
17
|
+
def match_document(self, buf):
|
18
|
+
raise NotImplementedError
|
19
|
+
|
20
|
+
def compare_bytes(self, buf, subslice, start_offset):
|
21
|
+
sl = len(subslice)
|
22
|
+
|
23
|
+
if start_offset + sl > len(buf):
|
24
|
+
return False
|
25
|
+
|
26
|
+
return buf[start_offset:start_offset + sl] == subslice
|
27
|
+
|
28
|
+
def search_signature(self, buf, start, rangeNum):
|
29
|
+
signature = b"PK\x03\x04"
|
30
|
+
length = len(buf)
|
31
|
+
|
32
|
+
end = start + rangeNum
|
33
|
+
end = length if end > length else end
|
34
|
+
|
35
|
+
if start >= end:
|
36
|
+
return -1
|
37
|
+
|
38
|
+
try:
|
39
|
+
return buf.index(signature, start, end)
|
40
|
+
except ValueError:
|
41
|
+
return -1
|
42
|
+
|
43
|
+
|
44
|
+
class OpenDocument(ZippedDocumentBase):
|
45
|
+
def match_document(self, buf):
|
46
|
+
# Check if first file in archive is the identifying file
|
47
|
+
if not self.compare_bytes(buf, b"mimetype", 0x1E):
|
48
|
+
return
|
49
|
+
|
50
|
+
# Check content of mimetype file if it matches current mime
|
51
|
+
return self.compare_bytes(buf, bytes(self.mime, "ASCII"), 0x26)
|
52
|
+
|
53
|
+
|
54
|
+
class OfficeOpenXml(ZippedDocumentBase):
|
55
|
+
def match_document(self, buf):
|
56
|
+
# Check if first file in archive is the identifying file
|
57
|
+
ft = self.match_filename(buf, 0x1E)
|
58
|
+
if ft:
|
59
|
+
return ft
|
60
|
+
|
61
|
+
# Otherwise check that the fist file is one of these
|
62
|
+
if (
|
63
|
+
not self.compare_bytes(buf, b"[Content_Types].xml", 0x1E)
|
64
|
+
and not self.compare_bytes(buf, b"_rels/.rels", 0x1E)
|
65
|
+
and not self.compare_bytes(buf, b"docProps", 0x1E)
|
66
|
+
):
|
67
|
+
return
|
68
|
+
|
69
|
+
# Loop through next 3 files and check if they match
|
70
|
+
# NOTE: OpenOffice/Libreoffice orders ZIP entry differently, so check the 4th file
|
71
|
+
# https://github.com/h2non/filetype/blob/d730d98ad5c990883148485b6fd5adbdd378364a/matchers/document.go#L134
|
72
|
+
idx = 0
|
73
|
+
for i in range(4):
|
74
|
+
# Search for next file header
|
75
|
+
idx = self.search_signature(buf, idx + 4, 6000)
|
76
|
+
if idx == -1:
|
77
|
+
return
|
78
|
+
|
79
|
+
# Filename is at file header + 30
|
80
|
+
ft = self.match_filename(buf, idx + 30)
|
81
|
+
if ft:
|
82
|
+
return ft
|
83
|
+
|
84
|
+
def match_filename(self, buf, offset):
|
85
|
+
if self.compare_bytes(buf, b"word/", offset):
|
86
|
+
return (
|
87
|
+
self.mime
|
88
|
+
== "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
89
|
+
)
|
90
|
+
if self.compare_bytes(buf, b"ppt/", offset):
|
91
|
+
return (
|
92
|
+
self.mime
|
93
|
+
== "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
94
|
+
)
|
95
|
+
if self.compare_bytes(buf, b"xl/", offset):
|
96
|
+
return (
|
97
|
+
self.mime
|
98
|
+
== "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
99
|
+
)
|
100
|
+
|
101
|
+
|
102
|
+
class Doc(Type):
|
103
|
+
"""
|
104
|
+
Implements the Microsoft Word (Office 97-2003) document type matcher.
|
105
|
+
"""
|
106
|
+
|
107
|
+
MIME = "application/msword"
|
108
|
+
EXTENSION = "doc"
|
109
|
+
|
110
|
+
def __init__(self):
|
111
|
+
super(Doc, self).__init__(mime=Doc.MIME, extension=Doc.EXTENSION)
|
112
|
+
|
113
|
+
def match(self, buf):
|
114
|
+
if len(buf) > 515 and buf[0:8] == b"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1":
|
115
|
+
if buf[512:516] == b"\xEC\xA5\xC1\x00":
|
116
|
+
return True
|
117
|
+
if (
|
118
|
+
len(buf) > 2142
|
119
|
+
and b"\x00\x0A\x00\x00\x00MSWordDoc\x00\x10\x00\x00\x00Word.Document.8\x00\xF49\xB2q"
|
120
|
+
in buf[2075:2142]
|
121
|
+
):
|
122
|
+
return True
|
123
|
+
|
124
|
+
return False
|
125
|
+
|
126
|
+
|
127
|
+
class Docx(OfficeOpenXml):
|
128
|
+
"""
|
129
|
+
Implements the Microsoft Word OOXML (Office 2007+) document type matcher.
|
130
|
+
"""
|
131
|
+
|
132
|
+
MIME = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
133
|
+
EXTENSION = "docx"
|
134
|
+
|
135
|
+
def __init__(self):
|
136
|
+
super(Docx, self).__init__(mime=Docx.MIME, extension=Docx.EXTENSION)
|
137
|
+
|
138
|
+
|
139
|
+
class Odt(OpenDocument):
|
140
|
+
"""
|
141
|
+
Implements the OpenDocument Text document type matcher.
|
142
|
+
"""
|
143
|
+
|
144
|
+
MIME = "application/vnd.oasis.opendocument.text"
|
145
|
+
EXTENSION = "odt"
|
146
|
+
|
147
|
+
def __init__(self):
|
148
|
+
super(Odt, self).__init__(mime=Odt.MIME, extension=Odt.EXTENSION)
|
149
|
+
|
150
|
+
|
151
|
+
class Xls(Type):
|
152
|
+
"""
|
153
|
+
Implements the Microsoft Excel (Office 97-2003) document type matcher.
|
154
|
+
"""
|
155
|
+
|
156
|
+
MIME = "application/vnd.ms-excel"
|
157
|
+
EXTENSION = "xls"
|
158
|
+
|
159
|
+
def __init__(self):
|
160
|
+
super(Xls, self).__init__(mime=Xls.MIME, extension=Xls.EXTENSION)
|
161
|
+
|
162
|
+
def match(self, buf):
|
163
|
+
if len(buf) > 520 and buf[0:8] == b"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1":
|
164
|
+
if buf[512:516] == b"\xFD\xFF\xFF\xFF" and (
|
165
|
+
buf[518] == 0x00 or buf[518] == 0x02
|
166
|
+
):
|
167
|
+
return True
|
168
|
+
if buf[512:520] == b"\x09\x08\x10\x00\x00\x06\x05\x00":
|
169
|
+
return True
|
170
|
+
if (
|
171
|
+
len(buf) > 2095
|
172
|
+
and b"\xE2\x00\x00\x00\x5C\x00\x70\x00\x04\x00\x00Calc"
|
173
|
+
in buf[1568:2095]
|
174
|
+
):
|
175
|
+
return True
|
176
|
+
|
177
|
+
return False
|
178
|
+
|
179
|
+
|
180
|
+
class Xlsx(OfficeOpenXml):
|
181
|
+
"""
|
182
|
+
Implements the Microsoft Excel OOXML (Office 2007+) document type matcher.
|
183
|
+
"""
|
184
|
+
|
185
|
+
MIME = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
186
|
+
EXTENSION = "xlsx"
|
187
|
+
|
188
|
+
def __init__(self):
|
189
|
+
super(Xlsx, self).__init__(mime=Xlsx.MIME, extension=Xlsx.EXTENSION)
|
190
|
+
|
191
|
+
|
192
|
+
class Ods(OpenDocument):
|
193
|
+
"""
|
194
|
+
Implements the OpenDocument Spreadsheet document type matcher.
|
195
|
+
"""
|
196
|
+
|
197
|
+
MIME = "application/vnd.oasis.opendocument.spreadsheet"
|
198
|
+
EXTENSION = "ods"
|
199
|
+
|
200
|
+
def __init__(self):
|
201
|
+
super(Ods, self).__init__(mime=Ods.MIME, extension=Ods.EXTENSION)
|
202
|
+
|
203
|
+
|
204
|
+
class Ppt(Type):
|
205
|
+
"""
|
206
|
+
Implements the Microsoft PowerPoint (Office 97-2003) document type matcher.
|
207
|
+
"""
|
208
|
+
|
209
|
+
MIME = "application/vnd.ms-powerpoint"
|
210
|
+
EXTENSION = "ppt"
|
211
|
+
|
212
|
+
def __init__(self):
|
213
|
+
super(Ppt, self).__init__(mime=Ppt.MIME, extension=Ppt.EXTENSION)
|
214
|
+
|
215
|
+
def match(self, buf):
|
216
|
+
if len(buf) > 524 and buf[0:8] == b"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1":
|
217
|
+
if buf[512:516] == b"\xA0\x46\x1D\xF0":
|
218
|
+
return True
|
219
|
+
if buf[512:516] == b"\x00\x6E\x1E\xF0":
|
220
|
+
return True
|
221
|
+
if buf[512:516] == b"\x0F\x00\xE8\x03":
|
222
|
+
return True
|
223
|
+
if buf[512:516] == b"\xFD\xFF\xFF\xFF" and buf[522:524] == b"\x00\x00":
|
224
|
+
return True
|
225
|
+
if (
|
226
|
+
len(buf) > 2096
|
227
|
+
and buf[2072:2096]
|
228
|
+
== b"\x00\xB9\x29\xE8\x11\x00\x00\x00MS PowerPoint 97"
|
229
|
+
):
|
230
|
+
return True
|
231
|
+
|
232
|
+
return False
|
233
|
+
|
234
|
+
|
235
|
+
class Pptx(OfficeOpenXml):
|
236
|
+
"""
|
237
|
+
Implements the Microsoft PowerPoint OOXML (Office 2007+) document type matcher.
|
238
|
+
"""
|
239
|
+
|
240
|
+
MIME = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
241
|
+
EXTENSION = "pptx"
|
242
|
+
|
243
|
+
def __init__(self):
|
244
|
+
super(Pptx, self).__init__(mime=Pptx.MIME, extension=Pptx.EXTENSION)
|
245
|
+
|
246
|
+
|
247
|
+
class Odp(OpenDocument):
|
248
|
+
"""
|
249
|
+
Implements the OpenDocument Presentation document type matcher.
|
250
|
+
"""
|
251
|
+
|
252
|
+
MIME = "application/vnd.oasis.opendocument.presentation"
|
253
|
+
EXTENSION = "odp"
|
254
|
+
|
255
|
+
def __init__(self):
|
256
|
+
super(Odp, self).__init__(mime=Odp.MIME, extension=Odp.EXTENSION)
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
from __future__ import absolute_import
|
4
|
+
|
5
|
+
from .base import Type
|
6
|
+
|
7
|
+
|
8
|
+
class Woff(Type):
|
9
|
+
"""
|
10
|
+
Implements the WOFF font type matcher.
|
11
|
+
"""
|
12
|
+
MIME = 'application/font-woff'
|
13
|
+
EXTENSION = 'woff'
|
14
|
+
|
15
|
+
def __init__(self):
|
16
|
+
super(Woff, self).__init__(
|
17
|
+
mime=Woff.MIME,
|
18
|
+
extension=Woff.EXTENSION
|
19
|
+
)
|
20
|
+
|
21
|
+
def match(self, buf):
|
22
|
+
return (len(buf) > 7 and
|
23
|
+
buf[0] == 0x77 and
|
24
|
+
buf[1] == 0x4F and
|
25
|
+
buf[2] == 0x46 and
|
26
|
+
buf[3] == 0x46 and
|
27
|
+
((buf[4] == 0x00 and
|
28
|
+
buf[5] == 0x01 and
|
29
|
+
buf[6] == 0x00 and
|
30
|
+
buf[7] == 0x00) or
|
31
|
+
(buf[4] == 0x4F and
|
32
|
+
buf[5] == 0x54 and
|
33
|
+
buf[6] == 0x54 and
|
34
|
+
buf[7] == 0x4F) or
|
35
|
+
(buf[4] == 0x74 and
|
36
|
+
buf[5] == 0x72 and
|
37
|
+
buf[6] == 0x75 and
|
38
|
+
buf[7] == 0x65)))
|
39
|
+
|
40
|
+
|
41
|
+
class Woff2(Type):
|
42
|
+
"""
|
43
|
+
Implements the WOFF2 font type matcher.
|
44
|
+
"""
|
45
|
+
MIME = 'application/font-woff'
|
46
|
+
EXTENSION = 'woff2'
|
47
|
+
|
48
|
+
def __init__(self):
|
49
|
+
super(Woff2, self).__init__(
|
50
|
+
mime=Woff2.MIME,
|
51
|
+
extension=Woff2.EXTENSION
|
52
|
+
)
|
53
|
+
|
54
|
+
def match(self, buf):
|
55
|
+
return (len(buf) > 7 and
|
56
|
+
buf[0] == 0x77 and
|
57
|
+
buf[1] == 0x4F and
|
58
|
+
buf[2] == 0x46 and
|
59
|
+
buf[3] == 0x32 and
|
60
|
+
((buf[4] == 0x00 and
|
61
|
+
buf[5] == 0x01 and
|
62
|
+
buf[6] == 0x00 and
|
63
|
+
buf[7] == 0x00) or
|
64
|
+
(buf[4] == 0x4F and
|
65
|
+
buf[5] == 0x54 and
|
66
|
+
buf[6] == 0x54 and
|
67
|
+
buf[7] == 0x4F) or
|
68
|
+
(buf[4] == 0x74 and
|
69
|
+
buf[5] == 0x72 and
|
70
|
+
buf[6] == 0x75 and
|
71
|
+
buf[7] == 0x65)))
|
72
|
+
|
73
|
+
|
74
|
+
class Ttf(Type):
|
75
|
+
"""
|
76
|
+
Implements the TTF font type matcher.
|
77
|
+
"""
|
78
|
+
MIME = 'application/font-sfnt'
|
79
|
+
EXTENSION = 'ttf'
|
80
|
+
|
81
|
+
def __init__(self):
|
82
|
+
super(Ttf, self).__init__(
|
83
|
+
mime=Ttf.MIME,
|
84
|
+
extension=Ttf.EXTENSION
|
85
|
+
)
|
86
|
+
|
87
|
+
def match(self, buf):
|
88
|
+
return (len(buf) > 4 and
|
89
|
+
buf[0] == 0x00 and
|
90
|
+
buf[1] == 0x01 and
|
91
|
+
buf[2] == 0x00 and
|
92
|
+
buf[3] == 0x00 and
|
93
|
+
buf[4] == 0x00)
|
94
|
+
|
95
|
+
|
96
|
+
class Otf(Type):
|
97
|
+
"""
|
98
|
+
Implements the OTF font type matcher.
|
99
|
+
"""
|
100
|
+
MIME = 'application/font-sfnt'
|
101
|
+
EXTENSION = 'otf'
|
102
|
+
|
103
|
+
def __init__(self):
|
104
|
+
super(Otf, self).__init__(
|
105
|
+
mime=Otf.MIME,
|
106
|
+
extension=Otf.EXTENSION
|
107
|
+
)
|
108
|
+
|
109
|
+
def match(self, buf):
|
110
|
+
return (len(buf) > 4 and
|
111
|
+
buf[0] == 0x4F and
|
112
|
+
buf[1] == 0x54 and
|
113
|
+
buf[2] == 0x54 and
|
114
|
+
buf[3] == 0x4F and
|
115
|
+
buf[4] == 0x00)
|