Coverage for slidge/core/config.py: 100%

111 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-11-26 19:34 +0000

1from pathlib import Path 

2from typing import Optional 

3 

4from slixmpp import JID as JIDType 

5 

6# REQUIRED, so not default value 

7 

8 

9class _Categories: 

10 MANDATORY = (0, "Mandatory settings") 

11 BASE = (10, "Basic configuration") 

12 ATTACHMENTS = (20, "Attachments") 

13 LOG = (30, "Logging") 

14 ADVANCED = (40, "Advanced settings") 

15 

16 

17LEGACY_MODULE: str 

18LEGACY_MODULE__DOC = ( 

19 "Importable python module containing (at least) a BaseGateway and a LegacySession subclass. " 

20 "NB: this is not needed if you use a gateway-specific entrypoint, e.g., `slidgram` or " 

21 "`python -m slidgram`." 

22) 

23LEGACY_MODULE__CATEGORY = _Categories.BASE 

24 

25SERVER: str = "localhost" 

26SERVER__DOC = ( 

27 "The XMPP server's host name. Defaults to localhost, which is the " 

28 "standard way of running slidge, on the same host as the XMPP server. " 

29 "The 'Jabber Component Protocol' (XEP-0114) does not mention encryption, " 

30 "so you *should* provide encryption another way, eg via port forwarding, if " 

31 "you change this." 

32) 

33SERVER__SHORT = "s" 

34SERVER__CATEGORY = _Categories.BASE 

35 

36SECRET: str 

37SECRET__DOC = "The gateway component's secret (required to connect to the XMPP server)" 

38SECRET__CATEGORY = _Categories.MANDATORY 

39 

40JID: JIDType 

41JID__DOC = "The gateway component's JID" 

42JID__SHORT = "j" 

43JID__CATEGORY = _Categories.MANDATORY 

44 

45PORT: str = "5347" 

46PORT__DOC = "The XMPP server's port for incoming component connections" 

47PORT__SHORT = "p" 

48PORT__CATEGORY = _Categories.BASE 

49 

50# Dynamic default (depends on other values) 

51 

52HOME_DIR: Path 

53HOME_DIR__DOC = ( 

54 "Directory where slidge will writes it persistent data and cache. " 

55 "Defaults to /var/lib/slidge/${SLIDGE_JID}. " 

56) 

57HOME_DIR__DYNAMIC_DEFAULT = True 

58HOME_DIR__CATEGORY = _Categories.BASE 

59 

60DB_URL: str 

61DB_URL__DOC = ( 

62 "Database URL, see <https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls>. " 

63 "Defaults to sqlite:///${HOME_DIR}/slidge.sqlite" 

64) 

65DB_URL__DYNAMIC_DEFAULT = True 

66DB_URL__CATEGORY = _Categories.ADVANCED 

67 

68USER_JID_VALIDATOR: str 

69USER_JID_VALIDATOR__DOC = ( 

70 "Regular expression to restrict users that can register to the gateway, by JID. " 

71 "Defaults to .*@${INFERRED_SERVER}. INFERRED_SERVER is derived for the gateway JID, " 

72 "by removing whatever is before the first encountered dot in it. Example: if " 

73 "slidge's JID=slidge.example.org, INFERRED_SERVER=example.org." 

74) 

75USER_JID_VALIDATOR__DYNAMIC_DEFAULT = True 

76USER_JID_VALIDATOR__CATEGORY = _Categories.BASE 

77 

78# Optional, so default value + type hint if default is None 

79 

80ADMINS: tuple[JIDType, ...] = () 

81ADMINS__DOC = "JIDs of the gateway admins" 

82ADMINS__CATEGORY = _Categories.BASE 

83 

84UPLOAD_SERVICE: Optional[str] = None 

85UPLOAD_SERVICE__DOC = ( 

86 "JID of an HTTP upload service the gateway can use. " 

87 "This is optional, as it should be automatically determined via service" 

88 "discovery." 

89) 

90UPLOAD_SERVICE__CATEGORY = _Categories.ATTACHMENTS 

91 

92AVATAR_SIZE = 200 

93AVATAR_SIZE__DOC = ( 

94 "Maximum image size (width and height), image ratio will be preserved" 

95) 

96AVATAR_SIZE__CATEGORY = _Categories.ADVANCED 

97 

98USE_ATTACHMENT_ORIGINAL_URLS = False 

99USE_ATTACHMENT_ORIGINAL_URLS__DOC = ( 

100 "For legacy plugins in which attachments are publicly downloadable URLs, " 

101 "let XMPP clients directly download them from this URL. Note that this will " 

102 "probably leak your client IP to the legacy network." 

103) 

104USE_ATTACHMENT_ORIGINAL_URLS__CATEGORY = _Categories.ATTACHMENTS 

105 

106UPLOAD_REQUESTER: Optional[str] = None 

107UPLOAD_REQUESTER__DOC = ( 

108 "Set which JID should request the upload slots. Defaults to the user's JID if " 

109 "IQ/get privileges granted for the 'urn:xmpp:http:upload:0' namespace; the component " 

110 "JID otherwise." 

111) 

112UPLOAD_REQUESTER__CATEGORY = _Categories.ATTACHMENTS 

113 

114UPLOAD_URL_PREFIX: Optional[str] = None 

115UPLOAD_URL_PREFIX__DOC = ( 

116 "This is an optional setting to make sure the URL of your upload service is never leaked " 

117 "to the legacy network in bodies of messages. This can happen under rare circumstances and/or bugs," 

118 "when replying to an attachment. Set this to the common prefix of the public URL your attachments get, " 

119 "eg https://upload.example.org:5281/" 

120) 

121UPLOAD_URL_PREFIX__CATEGORY = _Categories.ATTACHMENTS 

122 

123NO_UPLOAD_PATH: Optional[str] = None 

124NO_UPLOAD_PATH__DOC = ( 

125 "Instead of using the XMPP server's HTTP upload component, copy files to this dir. " 

126 "You need to set NO_UPLOAD_URL_PREFIX too if you use this option, and configure " 

127 "an web server to serve files in this dir." 

128) 

129NO_UPLOAD_PATH__CATEGORY = _Categories.ATTACHMENTS 

130 

131NO_UPLOAD_URL_PREFIX: Optional[str] = None 

132NO_UPLOAD_URL_PREFIX__DOC = ( 

133 "Base URL that servers files in the dir set in the no-upload-path option, " 

134 "eg https://example.com:666/slidge-attachments/" 

135) 

136NO_UPLOAD_URL_PREFIX__CATEGORY = _Categories.ATTACHMENTS 

137 

138NO_UPLOAD_METHOD: str = "copy" 

139NO_UPLOAD_METHOD__DOC = ( 

140 "Whether to 'copy', 'move', 'hardlink' or 'symlink' the files in no-upload-path." 

141) 

142NO_UPLOAD_METHOD__CATEGORY = _Categories.ATTACHMENTS 

143 

144NO_UPLOAD_FILE_READ_OTHERS = False 

145NO_UPLOAD_FILE_READ_OTHERS__DOC = ( 

146 "After writing a file in NO_UPLOAD_PATH, change its permission so that 'others' can" 

147 " read it." 

148) 

149NO_UPLOAD_FILE_READ_OTHERS__CATEGORY = _Categories.ATTACHMENTS 

150 

151IGNORE_DELAY_THRESHOLD = 300 

152IGNORE_DELAY_THRESHOLD__DOC = ( 

153 "Threshold, in seconds, below which the <delay> information is stripped " 

154 "out of emitted stanzas." 

155) 

156IGNORE_DELAY_THRESHOLD__CATEGORY = _Categories.ADVANCED 

157 

158PARTIAL_REGISTRATION_TIMEOUT = 3600 

159PARTIAL_REGISTRATION_TIMEOUT__DOC = ( 

160 "Timeout before registration and login. Only useful for legacy networks where " 

161 "a single step registration process is not enough." 

162) 

163PARTIAL_REGISTRATION_TIMEOUT__CATEGORY = _Categories.ADVANCED 

164 

165QR_TIMEOUT = 60 

166QR_TIMEOUT__DOC = "Timeout for QR code flashing confirmation." 

167QR_TIMEOUT__CATEGORY = _Categories.ADVANCED 

168 

169FIX_FILENAME_SUFFIX_MIME_TYPE = False 

170FIX_FILENAME_SUFFIX_MIME_TYPE__DOC = ( 

171 "Fix the Filename suffix based on the Mime Type of the file. Some clients (eg" 

172 " Conversations) may not inline files that have a wrong suffix for the MIME Type." 

173 " Therefore the MIME Type of the file is checked, if the suffix is not valid for" 

174 " that MIME Type, a valid one will be picked." 

175) 

176FIX_FILENAME_SUFFIX_MIME_TYPE__CATEGORY = _Categories.ATTACHMENTS 

177 

178LOG_FILE: Optional[Path] = None 

179LOG_FILE__DOC = "Log to a file instead of stdout/err" 

180LOG_FILE__CATEGORY = _Categories.LOG 

181 

182LOG_FORMAT: str = "%(levelname)s:%(name)s:%(message)s" 

183LOG_FORMAT__DOC = ( 

184 "Optionally, a format string for logging messages. Refer to " 

185 "https://docs.python.org/3/library/logging.html#logrecord-attributes " 

186 "for available options." 

187) 

188LOG_FORMAT__CATEGORY = _Categories.LOG 

189 

190MAM_MAX_DAYS = 7 

191MAM_MAX_DAYS__DOC = "Maximum number of days for group archive retention." 

192MAM_MAX_DAYS__CATEGORY = _Categories.BASE 

193 

194ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH = 200 

195ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH__DOC = ( 

196 "Some legacy network provide ridiculously long filenames, strip above this limit, " 

197 "preserving suffix." 

198) 

199ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH__CATEGORY = _Categories.ATTACHMENTS 

200 

201CONVERT_STICKERS = False 

202CONVERT_STICKERS__DOC = ( 

203 "Convert lottie vector stickers (from the legacy side) to webp animations." 

204) 

205CONVERT_STICKERS__CATEGORY = _Categories.ATTACHMENTS 

206 

207AVATAR_RESAMPLING_THREADS = 2 

208AVATAR_RESAMPLING_THREADS__DOC = ( 

209 "Number of additional threads to use for avatar resampling. Even in a single-core " 

210 "context, this makes avatar resampling non-blocking." 

211) 

212AVATAR_RESAMPLING_THREADS__CATEGORY = _Categories.ADVANCED 

213 

214DEV_MODE = False 

215DEV_MODE__DOC = ( 

216 "Enables an interactive python shell via chat commands, for admins." 

217 "Not safe to use in prod, but great during dev." 

218) 

219DEV_MODE__CATEGORY = _Categories.ADVANCED 

220 

221 

222STRIP_LEADING_EMOJI_ADHOC = False 

223STRIP_LEADING_EMOJI_ADHOC__DOC = ( 

224 "Strip the leading emoji in ad-hoc command names, if present, in case you " 

225 "are a emoji-hater." 

226) 

227STRIP_LEADING_EMOJI_ADHOC__CATEGORY = _Categories.ADVANCED 

228 

229COMPONENT_NAME: Optional[str] = None 

230COMPONENT_NAME__DOC = ( 

231 "Overrides the default component name with a custom one. This is seen in service discovery and as the nickname " 

232 "of the component in chat windows." 

233) 

234COMPONENT_NAME__CATEGORY = _Categories.ADVANCED 

235 

236WELCOME_MESSAGE: Optional[str] = None 

237WELCOME_MESSAGE__DOC = ( 

238 "Overrides the default welcome message received by newly registered users." 

239) 

240WELCOME_MESSAGE__CATEGORY = _Categories.ADVANCED