Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mikf
GitHub Repository: mikf/gallery-dl
Path: blob/master/gallery_dl/exception.py
5457 views
1
# -*- coding: utf-8 -*-
2
3
# Copyright 2015-2023 Mike Fährmann
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License version 2 as
7
# published by the Free Software Foundation.
8
9
"""Exception classes used by gallery-dl
10
11
Class Hierarchy:
12
13
Exception
14
└── GalleryDLException
15
├── ExtractionError
16
│ ├── HttpError
17
│ │ └── ChallengeError
18
│ ├── AuthorizationError
19
│ │ └── AuthRequired
20
│ ├── AuthenticationError
21
│ └── NotFoundError
22
├── InputError
23
│ ├── FormatError
24
│ │ ├── FilenameFormatError
25
│ │ └── DirectoryFormatError
26
│ ├── FilterError
27
│ ├── InputFileError
28
│ └── NoExtractorError
29
└── ControlException
30
├── StopExtraction
31
├── AbortExtraction
32
├── TerminateExtraction
33
└── RestartExtraction
34
"""
35
36
37
class GalleryDLException(Exception):
38
"""Base class for GalleryDL exceptions"""
39
default = None
40
msgfmt = None
41
code = 1
42
43
def __init__(self, message=None, fmt=True):
44
if not message:
45
message = self.default
46
elif isinstance(message, Exception):
47
message = f"{message.__class__.__name__}: {message}"
48
if fmt and self.msgfmt is not None:
49
message = self.msgfmt.replace("{}", message)
50
self.message = message
51
Exception.__init__(self, message)
52
53
54
###############################################################################
55
# Extractor Errors ############################################################
56
57
class ExtractionError(GalleryDLException):
58
"""Base class for exceptions during information extraction"""
59
code = 4
60
61
62
class HttpError(ExtractionError):
63
"""HTTP request during data extraction failed"""
64
default = "HTTP request failed"
65
66
def __init__(self, message="", response=None):
67
self.response = response
68
if response is None:
69
self.status = 0
70
else:
71
self.status = response.status_code
72
if not message:
73
message = (f"'{response.status_code} {response.reason}' "
74
f"for '{response.url}'")
75
ExtractionError.__init__(self, message)
76
77
78
class ChallengeError(HttpError):
79
code = 8
80
81
def __init__(self, challenge, response):
82
message = (
83
f"{challenge} ({response.status_code} {response.reason}) "
84
f"for '{response.url}'")
85
HttpError.__init__(self, message, response)
86
87
88
class AuthenticationError(ExtractionError):
89
"""Invalid or missing login credentials"""
90
default = "Invalid login credentials"
91
code = 16
92
93
94
class AuthorizationError(ExtractionError):
95
"""Insufficient privileges to access a resource"""
96
default = "Insufficient privileges to access this resource"
97
code = 16
98
99
100
class AuthRequired(AuthorizationError):
101
default = "Account credentials required"
102
103
def __init__(self, auth=None, resource="resource", message=None):
104
if auth:
105
if not isinstance(auth, str):
106
auth = " or ".join(auth)
107
if " " not in resource:
108
resource = "this " + resource
109
if message is None:
110
message = (f"{auth} needed to access {resource}")
111
else:
112
message = (f"{auth} needed to access {resource} "
113
f"('{message}')")
114
AuthorizationError.__init__(self, message)
115
116
117
class NotFoundError(ExtractionError):
118
"""Requested resource (gallery/image) could not be found"""
119
msgfmt = "Requested {} could not be found"
120
default = "resource (gallery/image)"
121
122
123
###############################################################################
124
# User Input ##################################################################
125
126
class InputError(GalleryDLException):
127
"""Error caused by user input and config options"""
128
code = 32
129
130
131
class FormatError(InputError):
132
"""Error while building output paths"""
133
134
135
class FilenameFormatError(FormatError):
136
"""Error while building output filenames"""
137
msgfmt = "Applying filename format string failed ({})"
138
139
140
class DirectoryFormatError(FormatError):
141
"""Error while building output directory paths"""
142
msgfmt = "Applying directory format string failed ({})"
143
144
145
class FilterError(InputError):
146
"""Error while evaluating a filter expression"""
147
msgfmt = "Evaluating filter expression failed ({})"
148
149
150
class InputFileError(InputError):
151
"""Error when parsing an input file"""
152
153
154
class NoExtractorError(InputError):
155
"""No extractor can handle the given URL"""
156
157
158
###############################################################################
159
# Control Flow ################################################################
160
161
class ControlException(GalleryDLException):
162
code = 0
163
164
165
class StopExtraction(ControlException):
166
"""Stop data extraction"""
167
168
def __init__(self, target=None):
169
ControlException.__init__(self)
170
171
if target is None:
172
self.target = None
173
self.depth = 1
174
elif isinstance(target, int):
175
self.target = None
176
self.depth = target
177
elif target.isdecimal():
178
self.target = None
179
self.depth = int(target)
180
else:
181
self.target = target
182
self.depth = 128
183
184
185
class AbortExtraction(ExtractionError, ControlException):
186
"""Abort data extraction due to an error"""
187
188
189
class TerminateExtraction(ControlException):
190
"""Terminate data extraction"""
191
192
193
class RestartExtraction(ControlException):
194
"""Restart data extraction"""
195
196