| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  | __filename__ = "theme.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2021-01-26 10:07:42 +00:00
										 |  |  | __version__ = "1.2.0" | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@freedombone.net" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-26 11:16:41 +00:00
										 |  |  | __module_group__ = "Web Interface" | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2021-06-25 18:02:05 +00:00
										 |  |  | from utils import isAccountDir | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  | from utils import loadJson | 
					
						
							|  |  |  | from utils import saveJson | 
					
						
							| 
									
										
										
										
											2020-11-21 11:54:29 +00:00
										 |  |  | from utils import getImageExtensions | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  | from utils import copytree | 
					
						
							| 
									
										
										
										
											2021-07-13 21:59:53 +00:00
										 |  |  | from utils import acctDir | 
					
						
							| 
									
										
										
										
											2020-05-28 21:30:40 +00:00
										 |  |  | from shutil import copyfile | 
					
						
							| 
									
										
										
										
											2021-05-28 21:39:34 +00:00
										 |  |  | from shutil import make_archive | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  | from shutil import unpack_archive | 
					
						
							| 
									
										
										
										
											2021-05-30 11:36:20 +00:00
										 |  |  | from shutil import rmtree | 
					
						
							| 
									
										
										
										
											2020-11-15 11:01:05 +00:00
										 |  |  | from content import dangerousCSS | 
					
						
							| 
									
										
										
										
											2020-11-15 10:33:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  | def importTheme(baseDir: str, filename: str) -> bool: | 
					
						
							|  |  |  |     """Imports a theme
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not os.path.isfile(filename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     tempThemeDir = baseDir + '/imports/files' | 
					
						
							| 
									
										
										
										
											2021-05-30 11:39:09 +00:00
										 |  |  |     if os.path.isdir(tempThemeDir): | 
					
						
							|  |  |  |         rmtree(tempThemeDir) | 
					
						
							|  |  |  |     os.mkdir(tempThemeDir) | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  |     unpack_archive(filename, tempThemeDir, 'zip') | 
					
						
							|  |  |  |     essentialThemeFiles = ('name.txt', 'theme.json') | 
					
						
							|  |  |  |     for themeFile in essentialThemeFiles: | 
					
						
							|  |  |  |         if not os.path.isfile(tempThemeDir + '/' + themeFile): | 
					
						
							|  |  |  |             print('WARN: ' + themeFile + | 
					
						
							|  |  |  |                   ' missing from imported theme') | 
					
						
							|  |  |  |             return False | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |     newThemeName = None | 
					
						
							|  |  |  |     with open(tempThemeDir + '/name.txt', 'r') as fp: | 
					
						
							|  |  |  |         newThemeName = fp.read().replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  |         if len(newThemeName) > 20: | 
					
						
							|  |  |  |             print('WARN: Imported theme name is too long') | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         if len(newThemeName) < 2: | 
					
						
							|  |  |  |             print('WARN: Imported theme name is too short') | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         newThemeName = newThemeName.lower() | 
					
						
							|  |  |  |         forbiddenChars = ( | 
					
						
							|  |  |  |             ' ', ';', '/', '\\', '?', '!', '#', '@', | 
					
						
							|  |  |  |             ':', '%', '&', '"', '+', '<', '>', '$' | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         for ch in forbiddenChars: | 
					
						
							|  |  |  |             if ch in newThemeName: | 
					
						
							|  |  |  |                 print('WARN: theme name contains forbidden character') | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  |     if not newThemeName: | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-05-30 11:06:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if the theme name in the default themes list? | 
					
						
							|  |  |  |     defaultThemesFilename = baseDir + '/defaultthemes.txt' | 
					
						
							|  |  |  |     if os.path.isfile(defaultThemesFilename): | 
					
						
							|  |  |  |         if newThemeName.title() + '\n' in open(defaultThemesFilename).read(): | 
					
						
							|  |  |  |             newThemeName = newThemeName + '2' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  |     themeDir = baseDir + '/theme/' + newThemeName | 
					
						
							|  |  |  |     if not os.path.isdir(themeDir): | 
					
						
							|  |  |  |         os.mkdir(themeDir) | 
					
						
							|  |  |  |     copytree(tempThemeDir, themeDir) | 
					
						
							| 
									
										
										
										
											2021-05-30 11:34:30 +00:00
										 |  |  |     if os.path.isdir(tempThemeDir): | 
					
						
							| 
									
										
										
										
											2021-05-30 11:36:20 +00:00
										 |  |  |         rmtree(tempThemeDir) | 
					
						
							| 
									
										
										
										
											2021-05-29 11:04:03 +00:00
										 |  |  |     return os.path.isfile(themeDir + '/theme.json') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-28 21:39:34 +00:00
										 |  |  | def exportTheme(baseDir: str, theme: str) -> bool: | 
					
						
							|  |  |  |     """Exports a theme as a zip file
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     themeDir = baseDir + '/theme/' + theme | 
					
						
							| 
									
										
										
										
											2021-05-28 22:00:46 +00:00
										 |  |  |     if not os.path.isfile(themeDir + '/theme.json'): | 
					
						
							| 
									
										
										
										
											2021-05-28 21:39:34 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  |     if not os.path.isdir(baseDir + '/exports'): | 
					
						
							|  |  |  |         os.mkdir(baseDir + '/exports') | 
					
						
							|  |  |  |     exportFilename = baseDir + '/exports/' + theme + '.zip' | 
					
						
							|  |  |  |     if os.path.isfile(exportFilename): | 
					
						
							|  |  |  |         os.remove(exportFilename) | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2021-05-28 21:52:32 +00:00
										 |  |  |         make_archive(baseDir + '/exports/' + theme, 'zip', themeDir) | 
					
						
							| 
									
										
										
										
											2021-05-28 21:39:34 +00:00
										 |  |  |     except BaseException: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  |     return os.path.isfile(exportFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _getThemeFiles() -> []: | 
					
						
							| 
									
										
										
										
											2021-02-07 15:22:06 +00:00
										 |  |  |     """Gets the list of theme style sheets
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-07-11 09:30:07 +00:00
										 |  |  |     return ('epicyon.css', 'login.css', 'follow.css', | 
					
						
							| 
									
										
										
										
											2020-07-25 22:12:59 +00:00
										 |  |  |             'suspended.css', 'calendar.css', 'blog.css', | 
					
						
							| 
									
										
										
										
											2021-02-25 12:42:05 +00:00
										 |  |  |             'options.css', 'search.css', 'links.css', | 
					
						
							|  |  |  |             'welcome.css') | 
					
						
							| 
									
										
										
										
											2020-07-11 09:30:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-27 11:44:50 +00:00
										 |  |  | def isNewsThemeName(baseDir: str, themeName: str) -> bool: | 
					
						
							|  |  |  |     """Returns true if the given theme is a news instance
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     themeDir = baseDir + '/theme/' + themeName | 
					
						
							|  |  |  |     if os.path.isfile(themeDir + '/is_news_instance'): | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 15:28:29 +00:00
										 |  |  | def getThemesList(baseDir: str) -> []: | 
					
						
							| 
									
										
										
										
											2020-05-28 09:11:21 +00:00
										 |  |  |     """Returns the list of available themes
 | 
					
						
							|  |  |  |     Note that these should be capitalized, since they're | 
					
						
							|  |  |  |     also used to create the web interface dropdown list | 
					
						
							|  |  |  |     and to lookup function names | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-11-14 15:28:29 +00:00
										 |  |  |     themes = [] | 
					
						
							| 
									
										
										
										
											2020-11-14 15:37:20 +00:00
										 |  |  |     for subdir, dirs, files in os.walk(baseDir + '/theme'): | 
					
						
							| 
									
										
										
										
											2020-11-14 15:28:29 +00:00
										 |  |  |         for themeName in dirs: | 
					
						
							| 
									
										
										
										
											2020-11-15 09:55:49 +00:00
										 |  |  |             if '~' not in themeName and \ | 
					
						
							|  |  |  |                themeName != 'icons' and themeName != 'fonts': | 
					
						
							| 
									
										
										
										
											2020-11-14 15:34:13 +00:00
										 |  |  |                 themes.append(themeName.title()) | 
					
						
							| 
									
										
										
										
											2020-11-14 15:37:20 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2020-11-16 15:11:11 +00:00
										 |  |  |     themes.sort() | 
					
						
							| 
									
										
										
										
											2020-11-14 15:28:29 +00:00
										 |  |  |     print('Themes available: ' + str(themes)) | 
					
						
							|  |  |  |     return themes | 
					
						
							| 
									
										
										
										
											2020-05-28 09:11:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-27 12:36:14 +00:00
										 |  |  | def _copyThemeHelpFiles(baseDir: str, themeName: str, | 
					
						
							|  |  |  |                         systemLanguage: str) -> None: | 
					
						
							|  |  |  |     """Copies any theme specific help files from the welcome subdirectory
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-02-27 12:40:14 +00:00
										 |  |  |     if not systemLanguage: | 
					
						
							|  |  |  |         systemLanguage = 'en' | 
					
						
							| 
									
										
										
										
											2021-02-27 12:36:14 +00:00
										 |  |  |     themeDir = baseDir + '/theme/' + themeName + '/welcome' | 
					
						
							|  |  |  |     if not os.path.isdir(themeDir): | 
					
						
							|  |  |  |         themeDir = baseDir + '/defaultwelcome' | 
					
						
							|  |  |  |     for subdir, dirs, files in os.walk(themeDir): | 
					
						
							|  |  |  |         for helpMarkdownFile in files: | 
					
						
							| 
									
										
										
										
											2021-02-27 14:39:35 +00:00
										 |  |  |             if not helpMarkdownFile.endswith('_' + systemLanguage + '.md'): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             destHelpMarkdownFile = \ | 
					
						
							|  |  |  |                 helpMarkdownFile.replace('_' + systemLanguage + '.md', '.md') | 
					
						
							| 
									
										
										
										
											2021-02-27 14:44:47 +00:00
										 |  |  |             if destHelpMarkdownFile == 'profile.md' or \ | 
					
						
							|  |  |  |                destHelpMarkdownFile == 'final.md': | 
					
						
							|  |  |  |                 destHelpMarkdownFile = 'welcome_' + destHelpMarkdownFile | 
					
						
							| 
									
										
										
										
											2021-03-03 13:39:39 +00:00
										 |  |  |             if os.path.isdir(baseDir + '/accounts'): | 
					
						
							|  |  |  |                 copyfile(themeDir + '/' + helpMarkdownFile, | 
					
						
							|  |  |  |                          baseDir + '/accounts/' + destHelpMarkdownFile) | 
					
						
							| 
									
										
										
										
											2021-02-27 12:36:14 +00:00
										 |  |  |         break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setThemeInConfig(baseDir: str, name: str) -> bool: | 
					
						
							| 
									
										
										
										
											2021-02-07 15:22:06 +00:00
										 |  |  |     """Sets the theme with the given name within config.json
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     if not os.path.isfile(configFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |     configJson = loadJson(configFilename, 0) | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     if not configJson: | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |     configJson['theme'] = name | 
					
						
							|  |  |  |     return saveJson(configJson, configFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setNewswirePublishAsIcon(baseDir: str, useIcon: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2020-10-24 16:37:37 +00:00
										 |  |  |     """Shows the newswire publish action as an icon or a button
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							|  |  |  |     if not os.path.isfile(configFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson = loadJson(configFilename, 0) | 
					
						
							|  |  |  |     if not configJson: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson['showPublishAsIcon'] = useIcon | 
					
						
							|  |  |  |     return saveJson(configJson, configFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setIconsAsButtons(baseDir: str, useButtons: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2020-10-25 20:38:01 +00:00
										 |  |  |     """Whether to show icons in the header (inbox, outbox, etc)
 | 
					
						
							|  |  |  |     as buttons | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							|  |  |  |     if not os.path.isfile(configFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson = loadJson(configFilename, 0) | 
					
						
							|  |  |  |     if not configJson: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson['iconsAsButtons'] = useButtons | 
					
						
							|  |  |  |     return saveJson(configJson, configFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setRssIconAtTop(baseDir: str, atTop: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2020-10-26 20:32:01 +00:00
										 |  |  |     """Whether to show RSS icon at the top of the timeline
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							|  |  |  |     if not os.path.isfile(configFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson = loadJson(configFilename, 0) | 
					
						
							|  |  |  |     if not configJson: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson['rssIconAtTop'] = atTop | 
					
						
							|  |  |  |     return saveJson(configJson, configFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 21:33:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setPublishButtonAtTop(baseDir: str, atTop: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2020-10-26 21:33:40 +00:00
										 |  |  |     """Whether to show the publish button above the title image
 | 
					
						
							|  |  |  |     in the newswire column | 
					
						
							| 
									
										
										
										
											2020-10-26 21:32:08 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							|  |  |  |     if not os.path.isfile(configFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson = loadJson(configFilename, 0) | 
					
						
							|  |  |  |     if not configJson: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson['publishButtonAtTop'] = atTop | 
					
						
							|  |  |  |     return saveJson(configJson, configFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 20:32:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setFullWidthTimelineButtonHeader(baseDir: str, fullWidth: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2020-10-24 17:51:00 +00:00
										 |  |  |     """Shows the timeline button header containing inbox, outbox,
 | 
					
						
							|  |  |  |     calendar, etc as full width | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							|  |  |  |     if not os.path.isfile(configFilename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson = loadJson(configFilename, 0) | 
					
						
							|  |  |  |     if not configJson: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     configJson['fullWidthTimelineButtonHeader'] = fullWidth | 
					
						
							|  |  |  |     return saveJson(configJson, configFilename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  | def getTheme(baseDir: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-02-07 15:22:06 +00:00
										 |  |  |     """Gets the current theme name from config.json
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |     configFilename = baseDir + '/config.json' | 
					
						
							| 
									
										
										
										
											2020-05-27 13:05:23 +00:00
										 |  |  |     if os.path.isfile(configFilename): | 
					
						
							|  |  |  |         configJson = loadJson(configFilename, 0) | 
					
						
							|  |  |  |         if configJson: | 
					
						
							|  |  |  |             if configJson.get('theme'): | 
					
						
							|  |  |  |                 return configJson['theme'] | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |     return 'default' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _removeTheme(baseDir: str): | 
					
						
							| 
									
										
										
										
											2021-02-07 15:22:06 +00:00
										 |  |  |     """Removes the current theme style sheets
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     themeFiles = _getThemeFiles() | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     for filename in themeFiles: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |         if os.path.isfile(baseDir + '/' + filename): | 
					
						
							|  |  |  |             os.remove(baseDir + '/' + filename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  | def setCSSparam(css: str, param: str, value: str) -> str: | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     """Sets a CSS parameter to a given value
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # is this just a simple string replacement? | 
					
						
							|  |  |  |     if ';' in param: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |         return css.replace(param, value) | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     # color replacement | 
					
						
							|  |  |  |     if param.startswith('rgba('): | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |         return css.replace(param, value) | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     # if the parameter begins with * then don't prepend -- | 
					
						
							| 
									
										
										
										
											2020-09-14 12:58:24 +00:00
										 |  |  |     onceOnly = False | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     if param.startswith('*'): | 
					
						
							| 
									
										
										
										
											2020-09-14 12:52:22 +00:00
										 |  |  |         if param.startswith('**'): | 
					
						
							| 
									
										
										
										
											2020-09-14 12:58:24 +00:00
										 |  |  |             onceOnly = True | 
					
						
							|  |  |  |             searchStr = param.replace('**', '') + ':' | 
					
						
							| 
									
										
										
										
											2020-09-14 12:52:22 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             searchStr = param.replace('*', '') + ':' | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |         searchStr = '--' + param + ':' | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     if searchStr not in css: | 
					
						
							|  |  |  |         return css | 
					
						
							| 
									
										
										
										
											2020-09-14 13:05:12 +00:00
										 |  |  |     if onceOnly: | 
					
						
							|  |  |  |         s = css.split(searchStr, 1) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         s = css.split(searchStr) | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |     newcss = '' | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     for sectionStr in s: | 
					
						
							| 
									
										
										
										
											2020-11-16 20:13:48 +00:00
										 |  |  |         # handle font-family which is a variable | 
					
						
							|  |  |  |         nextSection = sectionStr | 
					
						
							|  |  |  |         if ';' in nextSection: | 
					
						
							|  |  |  |             nextSection = nextSection.split(';')[0] + ';' | 
					
						
							|  |  |  |         if searchStr == 'font-family:' and "var(--" in nextSection: | 
					
						
							|  |  |  |             newcss += searchStr + ' ' + sectionStr | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |         if not newcss: | 
					
						
							|  |  |  |             if sectionStr: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |                 newcss = sectionStr | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |                 newcss = ' ' | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if ';' in sectionStr: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |                 newcss += \ | 
					
						
							|  |  |  |                     searchStr + ' ' + value + ';' + sectionStr.split(';', 1)[1] | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |                 newcss += searchStr + ' ' + sectionStr | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     return newcss.strip() | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setThemeFromDict(baseDir: str, name: str, | 
					
						
							|  |  |  |                       themeParams: {}, bgParams: {}, | 
					
						
							|  |  |  |                       allowLocalNetworkAccess: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     """Uses a dictionary to set a theme
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-07-10 18:08:45 +00:00
										 |  |  |     if name: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |         _setThemeInConfig(baseDir, name) | 
					
						
							|  |  |  |     themeFiles = _getThemeFiles() | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |     for filename in themeFiles: | 
					
						
							| 
									
										
										
										
											2020-11-14 13:18:11 +00:00
										 |  |  |         # check for custom css within the theme directory | 
					
						
							|  |  |  |         templateFilename = baseDir + '/theme/' + name + '/epicyon-' + filename | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |         if filename == 'epicyon.css': | 
					
						
							| 
									
										
										
										
											2020-11-14 13:18:11 +00:00
										 |  |  |             templateFilename = \ | 
					
						
							|  |  |  |                 baseDir + '/theme/' + name + '/epicyon-profile.css' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 11:07:12 +00:00
										 |  |  |         # Ensure that any custom CSS is mostly harmless. | 
					
						
							|  |  |  |         # If not then just use the defaults | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |         if dangerousCSS(templateFilename, allowLocalNetworkAccess) or \ | 
					
						
							| 
									
										
										
										
											2020-11-15 10:33:11 +00:00
										 |  |  |            not os.path.isfile(templateFilename): | 
					
						
							| 
									
										
										
										
											2020-11-14 13:18:11 +00:00
										 |  |  |             # use default css | 
					
						
							|  |  |  |             templateFilename = baseDir + '/epicyon-' + filename | 
					
						
							|  |  |  |             if filename == 'epicyon.css': | 
					
						
							|  |  |  |                 templateFilename = baseDir + '/epicyon-profile.css' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  |         if not os.path.isfile(templateFilename): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2020-11-14 13:18:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |         with open(templateFilename, 'r') as cssfile: | 
					
						
							|  |  |  |             css = cssfile.read() | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |             for paramName, paramValue in themeParams.items(): | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |                 if paramName == 'newswire-publish-icon': | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     if paramValue.lower() == 'true': | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setNewswirePublishAsIcon(baseDir, True) | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setNewswirePublishAsIcon(baseDir, False) | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 elif paramName == 'full-width-timeline-buttons': | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     if paramValue.lower() == 'true': | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setFullWidthTimelineButtonHeader(baseDir, True) | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setFullWidthTimelineButtonHeader(baseDir, False) | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 elif paramName == 'icons-as-buttons': | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     if paramValue.lower() == 'true': | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setIconsAsButtons(baseDir, True) | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setIconsAsButtons(baseDir, False) | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 elif paramName == 'rss-icon-at-top': | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     if paramValue.lower() == 'true': | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setRssIconAtTop(baseDir, True) | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setRssIconAtTop(baseDir, False) | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 elif paramName == 'publish-button-at-top': | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     if paramValue.lower() == 'true': | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setPublishButtonAtTop(baseDir, True) | 
					
						
							| 
									
										
										
										
											2020-11-14 19:21:11 +00:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                         _setPublishButtonAtTop(baseDir, False) | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  |                 css = setCSSparam(css, paramName, paramValue) | 
					
						
							|  |  |  |             filename = baseDir + '/' + filename | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |             with open(filename, 'w+') as cssfile: | 
					
						
							|  |  |  |                 cssfile.write(css) | 
					
						
							| 
									
										
										
										
											2019-11-23 13:04:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 16:46:32 +00:00
										 |  |  |     screenName = ( | 
					
						
							|  |  |  |         'login', 'follow', 'options', 'search', 'welcome' | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     for s in screenName: | 
					
						
							|  |  |  |         if bgParams.get(s): | 
					
						
							|  |  |  |             _setBackgroundFormat(baseDir, name, s, bgParams[s]) | 
					
						
							| 
									
										
										
										
											2020-04-04 12:03:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 11:59:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setBackgroundFormat(baseDir: str, name: str, | 
					
						
							|  |  |  |                          backgroundType: str, extension: str) -> None: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:25:04 +00:00
										 |  |  |     """Sets the background file extension
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-07-25 19:07:06 +00:00
										 |  |  |     if extension == 'jpg': | 
					
						
							| 
									
										
										
										
											2020-07-25 16:25:04 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-07-26 11:59:48 +00:00
										 |  |  |     cssFilename = baseDir + '/' + backgroundType + '.css' | 
					
						
							|  |  |  |     if not os.path.isfile(cssFilename): | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |     with open(cssFilename, 'r') as cssfile: | 
					
						
							|  |  |  |         css = cssfile.read() | 
					
						
							| 
									
										
										
										
											2020-07-26 11:59:48 +00:00
										 |  |  |         css = css.replace('background.jpg', 'background.' + extension) | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |         with open(cssFilename, 'w+') as cssfile2: | 
					
						
							|  |  |  |             cssfile2.write(css) | 
					
						
							| 
									
										
										
										
											2020-07-25 16:25:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  | def enableGrayscale(baseDir: str) -> None: | 
					
						
							|  |  |  |     """Enables grayscale for the current theme
 | 
					
						
							| 
									
										
										
										
											2020-07-10 18:16:33 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     themeFiles = _getThemeFiles() | 
					
						
							| 
									
										
										
										
											2020-07-10 18:16:33 +00:00
										 |  |  |     for filename in themeFiles: | 
					
						
							|  |  |  |         templateFilename = baseDir + '/' + filename | 
					
						
							|  |  |  |         if not os.path.isfile(templateFilename): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |         with open(templateFilename, 'r') as cssfile: | 
					
						
							|  |  |  |             css = cssfile.read() | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  |             if 'grayscale' not in css: | 
					
						
							|  |  |  |                 css = \ | 
					
						
							|  |  |  |                     css.replace('body, html {', | 
					
						
							|  |  |  |                                 'body, html {\n    filter: grayscale(100%);') | 
					
						
							|  |  |  |                 filename = baseDir + '/' + filename | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |                 with open(filename, 'w+') as cssfile: | 
					
						
							|  |  |  |                     cssfile.write(css) | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  |     grayscaleFilename = baseDir + '/accounts/.grayscale' | 
					
						
							|  |  |  |     if not os.path.isfile(grayscaleFilename): | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |         with open(grayscaleFilename, 'w+') as grayfile: | 
					
						
							|  |  |  |             grayfile.write(' ') | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def disableGrayscale(baseDir: str) -> None: | 
					
						
							|  |  |  |     """Disables grayscale for the current theme
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     themeFiles = _getThemeFiles() | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  |     for filename in themeFiles: | 
					
						
							|  |  |  |         templateFilename = baseDir + '/' + filename | 
					
						
							|  |  |  |         if not os.path.isfile(templateFilename): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |         with open(templateFilename, 'r') as cssfile: | 
					
						
							|  |  |  |             css = cssfile.read() | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  |             if 'grayscale' in css: | 
					
						
							|  |  |  |                 css = \ | 
					
						
							|  |  |  |                     css.replace('\n    filter: grayscale(100%);', '') | 
					
						
							|  |  |  |                 filename = baseDir + '/' + filename | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |                 with open(filename, 'w+') as cssfile: | 
					
						
							|  |  |  |                     cssfile.write(css) | 
					
						
							| 
									
										
										
										
											2020-07-11 09:22:06 +00:00
										 |  |  |     grayscaleFilename = baseDir + '/accounts/.grayscale' | 
					
						
							|  |  |  |     if os.path.isfile(grayscaleFilename): | 
					
						
							|  |  |  |         os.remove(grayscaleFilename) | 
					
						
							| 
									
										
										
										
											2020-07-10 18:16:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setCustomFont(baseDir: str): | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |     """Uses a dictionary to set a theme
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     customFontExt = None | 
					
						
							|  |  |  |     customFontType = None | 
					
						
							|  |  |  |     fontExtension = { | 
					
						
							|  |  |  |         'woff': 'woff', | 
					
						
							|  |  |  |         'woff2': 'woff2', | 
					
						
							|  |  |  |         'otf': 'opentype', | 
					
						
							|  |  |  |         'ttf': 'truetype' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for ext, extType in fontExtension.items(): | 
					
						
							|  |  |  |         filename = baseDir + '/fonts/custom.' + ext | 
					
						
							|  |  |  |         if os.path.isfile(filename): | 
					
						
							|  |  |  |             customFontExt = ext | 
					
						
							|  |  |  |             customFontType = extType | 
					
						
							|  |  |  |     if not customFontExt: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     themeFiles = _getThemeFiles() | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |     for filename in themeFiles: | 
					
						
							| 
									
										
										
										
											2020-05-26 21:35:48 +00:00
										 |  |  |         templateFilename = baseDir + '/' + filename | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |         if not os.path.isfile(templateFilename): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |         with open(templateFilename, 'r') as cssfile: | 
					
						
							|  |  |  |             css = cssfile.read() | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |             css = \ | 
					
						
							|  |  |  |                 setCSSparam(css, "*src", | 
					
						
							|  |  |  |                             "url('./fonts/custom." + | 
					
						
							|  |  |  |                             customFontExt + | 
					
						
							|  |  |  |                             "') format('" + | 
					
						
							|  |  |  |                             customFontType + "')") | 
					
						
							| 
									
										
										
										
											2020-05-26 20:23:38 +00:00
										 |  |  |             css = setCSSparam(css, "*font-family", "'CustomFont'") | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |             filename = baseDir + '/' + filename | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |             with open(filename, 'w+') as cssfile: | 
					
						
							|  |  |  |                 cssfile.write(css) | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _readVariablesFile(baseDir: str, themeName: str, | 
					
						
							|  |  |  |                        variablesFile: str, | 
					
						
							|  |  |  |                        allowLocalNetworkAccess: bool) -> None: | 
					
						
							| 
									
										
										
										
											2020-11-14 17:34:11 +00:00
										 |  |  |     """Reads variables from a file in the theme directory
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     themeParams = loadJson(variablesFile, 0) | 
					
						
							|  |  |  |     if not themeParams: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     bgParams = { | 
					
						
							|  |  |  |         "login": "jpg", | 
					
						
							|  |  |  |         "follow": "jpg", | 
					
						
							|  |  |  |         "options": "jpg", | 
					
						
							|  |  |  |         "search": "jpg" | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     _setThemeFromDict(baseDir, themeName, themeParams, bgParams, | 
					
						
							|  |  |  |                       allowLocalNetworkAccess) | 
					
						
							| 
									
										
										
										
											2020-11-14 17:34:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setThemeDefault(baseDir: str, allowLocalNetworkAccess: bool): | 
					
						
							| 
									
										
										
										
											2020-07-26 11:45:09 +00:00
										 |  |  |     name = 'default' | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     _removeTheme(baseDir) | 
					
						
							|  |  |  |     _setThemeInConfig(baseDir, name) | 
					
						
							| 
									
										
										
										
											2020-07-26 11:59:48 +00:00
										 |  |  |     bgParams = { | 
					
						
							| 
									
										
										
										
											2020-07-27 09:49:54 +00:00
										 |  |  |         "login": "jpg", | 
					
						
							|  |  |  |         "follow": "jpg", | 
					
						
							|  |  |  |         "options": "jpg", | 
					
						
							|  |  |  |         "search": "jpg" | 
					
						
							| 
									
										
										
										
											2020-07-26 11:59:48 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-31 11:51:31 +00:00
										 |  |  |     themeParams = { | 
					
						
							| 
									
										
										
										
											2020-11-14 18:08:46 +00:00
										 |  |  |         "newswire-publish-icon": True, | 
					
						
							|  |  |  |         "full-width-timeline-buttons": False, | 
					
						
							|  |  |  |         "icons-as-buttons": False, | 
					
						
							|  |  |  |         "rss-icon-at-top": True, | 
					
						
							|  |  |  |         "publish-button-at-top": False, | 
					
						
							| 
									
										
										
										
											2020-10-28 22:32:13 +00:00
										 |  |  |         "banner-height": "20vh", | 
					
						
							| 
									
										
										
										
											2020-11-07 20:14:46 +00:00
										 |  |  |         "banner-height-mobile": "10vh", | 
					
						
							|  |  |  |         "search-banner-height-mobile": "15vh" | 
					
						
							| 
									
										
										
										
											2020-08-31 11:51:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     _setThemeFromDict(baseDir, name, themeParams, bgParams, | 
					
						
							|  |  |  |                       allowLocalNetworkAccess) | 
					
						
							| 
									
										
										
										
											2020-05-29 10:00:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  | def _setThemeFonts(baseDir: str, themeName: str) -> None: | 
					
						
							| 
									
										
										
										
											2020-11-15 09:55:49 +00:00
										 |  |  |     """Adds custom theme fonts
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     themeNameLower = themeName.lower() | 
					
						
							|  |  |  |     fontsDir = baseDir + '/fonts' | 
					
						
							|  |  |  |     themeFontsDir = \ | 
					
						
							|  |  |  |         baseDir + '/theme/' + themeNameLower + '/fonts' | 
					
						
							|  |  |  |     if not os.path.isdir(themeFontsDir): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     for subdir, dirs, files in os.walk(themeFontsDir): | 
					
						
							|  |  |  |         for filename in files: | 
					
						
							|  |  |  |             if filename.endswith('.woff2') or \ | 
					
						
							|  |  |  |                filename.endswith('.woff') or \ | 
					
						
							|  |  |  |                filename.endswith('.ttf') or \ | 
					
						
							|  |  |  |                filename.endswith('.otf'): | 
					
						
							|  |  |  |                 destFilename = fontsDir + '/' + filename | 
					
						
							|  |  |  |                 if os.path.isfile(destFilename): | 
					
						
							|  |  |  |                     # font already exists in the destination location | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 copyfile(themeFontsDir + '/' + filename, | 
					
						
							|  |  |  |                          destFilename) | 
					
						
							|  |  |  |         break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-05 19:50:09 +00:00
										 |  |  | def getTextModeBanner(baseDir: str) -> str: | 
					
						
							|  |  |  |     """Returns the banner used for shell browsers, like Lynx
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     textModeBannerFilename = baseDir + '/accounts/banner.txt' | 
					
						
							|  |  |  |     if os.path.isfile(textModeBannerFilename): | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |         with open(textModeBannerFilename, 'r') as fp: | 
					
						
							|  |  |  |             bannerStr = fp.read() | 
					
						
							|  |  |  |             if bannerStr: | 
					
						
							|  |  |  |                 return bannerStr.replace('\n', '<br>') | 
					
						
							| 
									
										
										
										
											2021-02-05 19:50:09 +00:00
										 |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 14:30:18 +00:00
										 |  |  | def getTextModeLogo(baseDir: str) -> str: | 
					
						
							|  |  |  |     """Returns the login screen logo used for shell browsers, like Lynx
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     textModeLogoFilename = baseDir + '/accounts/logo.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(textModeLogoFilename): | 
					
						
							|  |  |  |         textModeLogoFilename = baseDir + '/img/logo.txt' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 22:52:04 +00:00
										 |  |  |     with open(textModeLogoFilename, 'r') as fp: | 
					
						
							|  |  |  |         logoStr = fp.read() | 
					
						
							|  |  |  |         if logoStr: | 
					
						
							|  |  |  |             return logoStr.replace('\n', '<br>') | 
					
						
							| 
									
										
										
										
											2021-02-06 14:30:18 +00:00
										 |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 15:32:15 +00:00
										 |  |  | def _setTextModeTheme(baseDir: str, name: str) -> None: | 
					
						
							|  |  |  |     # set the text mode logo which appears on the login screen | 
					
						
							|  |  |  |     # in browsers such as Lynx | 
					
						
							| 
									
										
										
										
											2021-02-06 18:51:36 +00:00
										 |  |  |     textModeLogoFilename = \ | 
					
						
							| 
									
										
										
										
											2021-02-07 15:32:15 +00:00
										 |  |  |         baseDir + '/theme/' + name + '/logo.txt' | 
					
						
							| 
									
										
										
										
											2021-02-06 18:51:36 +00:00
										 |  |  |     if os.path.isfile(textModeLogoFilename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             copyfile(textModeLogoFilename, | 
					
						
							|  |  |  |                      baseDir + '/accounts/logo.txt') | 
					
						
							|  |  |  |         except BaseException: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             copyfile(baseDir + '/img/logo.txt', | 
					
						
							|  |  |  |                      baseDir + '/accounts/logo.txt') | 
					
						
							|  |  |  |         except BaseException: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 15:32:15 +00:00
										 |  |  |     # set the text mode banner which appears in browsers such as Lynx | 
					
						
							| 
									
										
										
										
											2021-02-05 19:39:21 +00:00
										 |  |  |     textModeBannerFilename = \ | 
					
						
							| 
									
										
										
										
											2021-02-07 15:32:15 +00:00
										 |  |  |         baseDir + '/theme/' + name + '/banner.txt' | 
					
						
							| 
									
										
										
										
											2021-02-05 19:42:51 +00:00
										 |  |  |     if os.path.isfile(baseDir + '/accounts/banner.txt'): | 
					
						
							|  |  |  |         os.remove(baseDir + '/accounts/banner.txt') | 
					
						
							| 
									
										
										
										
											2021-02-05 19:39:21 +00:00
										 |  |  |     if os.path.isfile(textModeBannerFilename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             copyfile(textModeBannerFilename, | 
					
						
							|  |  |  |                      baseDir + '/accounts/banner.txt') | 
					
						
							|  |  |  |         except BaseException: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 15:32:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def _setThemeImages(baseDir: str, name: str) -> None: | 
					
						
							|  |  |  |     """Changes the profile background image
 | 
					
						
							|  |  |  |     and banner to the defaults | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     themeNameLower = name.lower() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     profileImageFilename = \ | 
					
						
							|  |  |  |         baseDir + '/theme/' + themeNameLower + '/image.png' | 
					
						
							|  |  |  |     bannerFilename = \ | 
					
						
							|  |  |  |         baseDir + '/theme/' + themeNameLower + '/banner.png' | 
					
						
							|  |  |  |     searchBannerFilename = \ | 
					
						
							|  |  |  |         baseDir + '/theme/' + themeNameLower + '/search_banner.png' | 
					
						
							|  |  |  |     leftColImageFilename = \ | 
					
						
							|  |  |  |         baseDir + '/theme/' + themeNameLower + '/left_col_image.png' | 
					
						
							|  |  |  |     rightColImageFilename = \ | 
					
						
							|  |  |  |         baseDir + '/theme/' + themeNameLower + '/right_col_image.png' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _setTextModeTheme(baseDir, themeNameLower) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 14:03:09 +00:00
										 |  |  |     backgroundNames = ('login', 'shares', 'delete', 'follow', | 
					
						
							| 
									
										
										
										
											2021-02-25 19:07:45 +00:00
										 |  |  |                        'options', 'block', 'search', 'calendar', | 
					
						
							|  |  |  |                        'welcome') | 
					
						
							| 
									
										
										
										
											2020-11-21 11:54:29 +00:00
										 |  |  |     extensions = getImageExtensions() | 
					
						
							| 
									
										
										
										
											2020-07-25 14:03:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for subdir, dirs, files in os.walk(baseDir + '/accounts'): | 
					
						
							| 
									
										
										
										
											2020-07-25 09:55:11 +00:00
										 |  |  |         for acct in dirs: | 
					
						
							| 
									
										
										
										
											2021-06-25 18:02:05 +00:00
										 |  |  |             if not isAccountDir(acct): | 
					
						
							| 
									
										
										
										
											2020-07-25 09:55:11 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             accountDir = \ | 
					
						
							|  |  |  |                 os.path.join(baseDir + '/accounts', acct) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 10:13:24 +00:00
										 |  |  |             for backgroundType in backgroundNames: | 
					
						
							| 
									
										
										
										
											2020-07-25 16:12:14 +00:00
										 |  |  |                 for ext in extensions: | 
					
						
							|  |  |  |                     if themeNameLower == 'default': | 
					
						
							|  |  |  |                         backgroundImageFilename = \ | 
					
						
							| 
									
										
										
										
											2020-11-14 12:44:24 +00:00
										 |  |  |                             baseDir + '/theme/default/' + \ | 
					
						
							|  |  |  |                             backgroundType + '_background.' + ext | 
					
						
							| 
									
										
										
										
											2020-07-25 16:12:14 +00:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         backgroundImageFilename = \ | 
					
						
							| 
									
										
										
										
											2020-11-14 12:44:24 +00:00
										 |  |  |                             baseDir + '/theme/' + themeNameLower + '/' + \ | 
					
						
							|  |  |  |                             backgroundType + '_background' + '.' + ext | 
					
						
							| 
									
										
										
										
											2020-07-25 16:12:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if os.path.isfile(backgroundImageFilename): | 
					
						
							|  |  |  |                         try: | 
					
						
							|  |  |  |                             copyfile(backgroundImageFilename, | 
					
						
							| 
									
										
										
										
											2020-11-14 12:44:24 +00:00
										 |  |  |                                      baseDir + '/accounts/' + | 
					
						
							|  |  |  |                                      backgroundType + '-background.' + ext) | 
					
						
							| 
									
										
										
										
											2020-07-25 17:56:06 +00:00
										 |  |  |                             continue | 
					
						
							| 
									
										
										
										
											2020-07-25 16:12:14 +00:00
										 |  |  |                         except BaseException: | 
					
						
							|  |  |  |                             pass | 
					
						
							|  |  |  |                     # background image was not found | 
					
						
							|  |  |  |                     # so remove any existing file | 
					
						
							|  |  |  |                     if os.path.isfile(baseDir + '/accounts/' + | 
					
						
							| 
									
										
										
										
											2020-11-14 12:44:24 +00:00
										 |  |  |                                       backgroundType + '-background.' + ext): | 
					
						
							| 
									
										
										
										
											2020-07-25 16:12:14 +00:00
										 |  |  |                         try: | 
					
						
							|  |  |  |                             os.remove(baseDir + '/accounts/' + | 
					
						
							| 
									
										
										
										
											2020-11-14 12:44:24 +00:00
										 |  |  |                                       backgroundType + '-background.' + ext) | 
					
						
							| 
									
										
										
										
											2020-07-25 16:12:14 +00:00
										 |  |  |                         except BaseException: | 
					
						
							|  |  |  |                             pass | 
					
						
							| 
									
										
										
										
											2020-07-25 10:03:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 09:55:11 +00:00
										 |  |  |             if os.path.isfile(profileImageFilename) and \ | 
					
						
							|  |  |  |                os.path.isfile(bannerFilename): | 
					
						
							| 
									
										
										
										
											2020-05-28 21:39:41 +00:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     copyfile(profileImageFilename, | 
					
						
							|  |  |  |                              accountDir + '/image.png') | 
					
						
							| 
									
										
										
										
											2020-06-10 15:09:14 +00:00
										 |  |  |                 except BaseException: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2020-05-28 21:39:41 +00:00
										 |  |  |                     copyfile(bannerFilename, | 
					
						
							|  |  |  |                              accountDir + '/banner.png') | 
					
						
							|  |  |  |                 except BaseException: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 15:09:14 +00:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     if os.path.isfile(searchBannerFilename): | 
					
						
							|  |  |  |                         copyfile(searchBannerFilename, | 
					
						
							|  |  |  |                                  accountDir + '/search_banner.png') | 
					
						
							|  |  |  |                 except BaseException: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-03 10:09:21 +00:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     if os.path.isfile(leftColImageFilename): | 
					
						
							|  |  |  |                         copyfile(leftColImageFilename, | 
					
						
							|  |  |  |                                  accountDir + '/left_col_image.png') | 
					
						
							| 
									
										
										
										
											2020-10-03 10:11:26 +00:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         if os.path.isfile(accountDir + | 
					
						
							|  |  |  |                                           '/left_col_image.png'): | 
					
						
							|  |  |  |                             os.remove(accountDir + '/left_col_image.png') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-03 10:09:21 +00:00
										 |  |  |                 except BaseException: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     if os.path.isfile(rightColImageFilename): | 
					
						
							|  |  |  |                         copyfile(rightColImageFilename, | 
					
						
							|  |  |  |                                  accountDir + '/right_col_image.png') | 
					
						
							| 
									
										
										
										
											2020-10-03 10:11:26 +00:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         if os.path.isfile(accountDir + | 
					
						
							|  |  |  |                                           '/right_col_image.png'): | 
					
						
							|  |  |  |                             os.remove(accountDir + '/right_col_image.png') | 
					
						
							| 
									
										
										
										
											2020-10-03 10:09:21 +00:00
										 |  |  |                 except BaseException: | 
					
						
							|  |  |  |                     pass | 
					
						
							| 
									
										
										
										
											2020-12-13 22:13:45 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2020-10-03 10:09:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-28 21:39:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-13 21:38:19 +00:00
										 |  |  | def setNewsAvatar(baseDir: str, name: str, | 
					
						
							|  |  |  |                   httpPrefix: str, | 
					
						
							|  |  |  |                   domain: str, domainFull: str) -> None: | 
					
						
							|  |  |  |     """Sets the avatar for the news account
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     nickname = 'news' | 
					
						
							| 
									
										
										
										
											2020-11-14 11:49:29 +00:00
										 |  |  |     newFilename = baseDir + '/theme/' + name + '/icons/avatar_news.png' | 
					
						
							| 
									
										
										
										
											2020-10-15 18:21:05 +00:00
										 |  |  |     if not os.path.isfile(newFilename): | 
					
						
							| 
									
										
										
										
											2020-11-14 11:49:29 +00:00
										 |  |  |         newFilename = baseDir + '/theme/default/icons/avatar_news.png' | 
					
						
							| 
									
										
										
										
											2020-10-13 21:38:19 +00:00
										 |  |  |     if not os.path.isfile(newFilename): | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-10-13 21:45:53 +00:00
										 |  |  |     avatarFilename = \ | 
					
						
							|  |  |  |         httpPrefix + '://' + domainFull + '/users/' + nickname + '.png' | 
					
						
							|  |  |  |     avatarFilename = avatarFilename.replace('/', '-') | 
					
						
							| 
									
										
										
										
											2020-10-13 21:51:06 +00:00
										 |  |  |     filename = baseDir + '/cache/avatars/' + avatarFilename | 
					
						
							| 
									
										
										
										
											2020-10-13 21:45:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-13 21:38:19 +00:00
										 |  |  |     if os.path.isfile(filename): | 
					
						
							|  |  |  |         os.remove(filename) | 
					
						
							| 
									
										
										
										
											2020-10-13 21:55:52 +00:00
										 |  |  |     if os.path.isdir(baseDir + '/cache/avatars'): | 
					
						
							| 
									
										
										
										
											2020-10-13 21:38:19 +00:00
										 |  |  |         copyfile(newFilename, filename) | 
					
						
							| 
									
										
										
										
											2021-07-13 21:59:53 +00:00
										 |  |  |     accountDir = acctDir(baseDir, nickname, domain) | 
					
						
							|  |  |  |     copyfile(newFilename, accountDir + '/avatar.png') | 
					
						
							| 
									
										
										
										
											2020-10-13 21:38:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 14:01:22 +00:00
										 |  |  | def _setClearCacheFlag(baseDir: str) -> None: | 
					
						
							|  |  |  |     """Sets a flag which can be used by an external system
 | 
					
						
							|  |  |  |     (eg. a script in a cron job) to clear the browser cache | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-03-03 13:39:39 +00:00
										 |  |  |     if not os.path.isdir(baseDir + '/accounts'): | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-02-23 14:01:22 +00:00
										 |  |  |     flagFilename = baseDir + '/accounts/.clear_cache' | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |     with open(flagFilename, 'w+') as flagFile: | 
					
						
							|  |  |  |         flagFile.write('\n') | 
					
						
							| 
									
										
										
										
											2021-02-23 14:01:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  | def setTheme(baseDir: str, name: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-02-27 12:36:14 +00:00
										 |  |  |              allowLocalNetworkAccess: bool, systemLanguage: str) -> bool: | 
					
						
							| 
									
										
										
										
											2021-02-07 15:22:06 +00:00
										 |  |  |     """Sets the theme with the given name as the current theme
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |     result = False | 
					
						
							| 
									
										
										
										
											2020-05-28 09:11:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-28 21:30:40 +00:00
										 |  |  |     prevThemeName = getTheme(baseDir) | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     _removeTheme(baseDir) | 
					
						
							| 
									
										
										
										
											2020-05-28 21:30:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 15:31:49 +00:00
										 |  |  |     themes = getThemesList(baseDir) | 
					
						
							| 
									
										
										
										
											2020-05-28 09:11:21 +00:00
										 |  |  |     for themeName in themes: | 
					
						
							| 
									
										
										
										
											2020-05-28 21:30:40 +00:00
										 |  |  |         themeNameLower = themeName.lower() | 
					
						
							|  |  |  |         if name == themeNameLower: | 
					
						
							| 
									
										
										
										
											2020-11-14 17:01:25 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2020-11-20 10:58:49 +00:00
										 |  |  |                 globals()['setTheme' + themeName](baseDir, | 
					
						
							|  |  |  |                                                   allowLocalNetworkAccess) | 
					
						
							| 
									
										
										
										
											2020-11-14 17:01:25 +00:00
										 |  |  |             except BaseException: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-28 21:30:40 +00:00
										 |  |  |             if prevThemeName: | 
					
						
							|  |  |  |                 if prevThemeName.lower() != themeNameLower: | 
					
						
							|  |  |  |                     # change the banner and profile image | 
					
						
							|  |  |  |                     # to the default for the theme | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |                     _setThemeImages(baseDir, name) | 
					
						
							|  |  |  |                     _setThemeFonts(baseDir, name) | 
					
						
							| 
									
										
										
										
											2020-05-28 09:11:21 +00:00
										 |  |  |             result = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not result: | 
					
						
							| 
									
										
										
										
											2020-05-27 11:02:51 +00:00
										 |  |  |         # default | 
					
						
							| 
									
										
										
										
											2020-12-22 21:24:46 +00:00
										 |  |  |         _setThemeDefault(baseDir, allowLocalNetworkAccess) | 
					
						
							| 
									
										
										
										
											2020-05-27 11:02:51 +00:00
										 |  |  |         result = True | 
					
						
							| 
									
										
										
										
											2020-05-28 09:11:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 17:40:11 +00:00
										 |  |  |     variablesFile = baseDir + '/theme/' + name + '/theme.json' | 
					
						
							| 
									
										
										
										
											2020-11-14 17:34:11 +00:00
										 |  |  |     if os.path.isfile(variablesFile): | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |         _readVariablesFile(baseDir, name, variablesFile, | 
					
						
							|  |  |  |                            allowLocalNetworkAccess) | 
					
						
							| 
									
										
										
										
											2020-11-14 17:34:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     _setCustomFont(baseDir) | 
					
						
							| 
									
										
										
										
											2020-10-09 19:28:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # set the news avatar | 
					
						
							|  |  |  |     newsAvatarThemeFilename = \ | 
					
						
							| 
									
										
										
										
											2020-11-14 11:49:29 +00:00
										 |  |  |         baseDir + '/theme/' + name + '/icons/avatar_news.png' | 
					
						
							| 
									
										
										
										
											2020-11-20 09:34:31 +00:00
										 |  |  |     if os.path.isdir(baseDir + '/accounts/news@' + domain): | 
					
						
							|  |  |  |         if os.path.isfile(newsAvatarThemeFilename): | 
					
						
							|  |  |  |             newsAvatarFilename = \ | 
					
						
							|  |  |  |                 baseDir + '/accounts/news@' + domain + '/avatar.png' | 
					
						
							|  |  |  |             copyfile(newsAvatarThemeFilename, newsAvatarFilename) | 
					
						
							| 
									
										
										
										
											2020-10-09 19:28:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 18:08:45 +00:00
										 |  |  |     grayscaleFilename = baseDir + '/accounts/.grayscale' | 
					
						
							|  |  |  |     if os.path.isfile(grayscaleFilename): | 
					
						
							|  |  |  |         enableGrayscale(baseDir) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         disableGrayscale(baseDir) | 
					
						
							| 
									
										
										
										
											2020-11-14 18:32:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-27 12:36:14 +00:00
										 |  |  |     _copyThemeHelpFiles(baseDir, name, systemLanguage) | 
					
						
							| 
									
										
										
										
											2020-12-22 18:06:23 +00:00
										 |  |  |     _setThemeInConfig(baseDir, name) | 
					
						
							| 
									
										
										
										
											2021-02-23 14:01:22 +00:00
										 |  |  |     _setClearCacheFlag(baseDir) | 
					
						
							| 
									
										
										
										
											2020-05-26 20:17:16 +00:00
										 |  |  |     return result | 
					
						
							| 
									
										
										
										
											2021-05-30 11:06:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def updateDefaultThemesList(baseDir: str) -> None: | 
					
						
							|  |  |  |     """Recreates the list of default themes
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     themeNames = getThemesList(baseDir) | 
					
						
							|  |  |  |     defaultThemesFilename = baseDir + '/defaultthemes.txt' | 
					
						
							| 
									
										
										
										
											2021-06-22 12:27:10 +00:00
										 |  |  |     with open(defaultThemesFilename, 'w+') as defaultThemesFile: | 
					
						
							|  |  |  |         for name in themeNames: | 
					
						
							|  |  |  |             defaultThemesFile.write(name + '\n') |