Created
December 28, 2019 21:31
-
-
Save palevell/3264ab36209c149d15e63fc8816fcdd6 to your computer and use it in GitHub Desktop.
This is a utily script to update the settings.py file in Django projects, based on the contents of the .env file. It also adds code for dotenv support.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# update_settings - Monday, December 23, 2019 | |
__version__ = '1.1.10' | |
import os, re | |
from glob import glob | |
from os.path import basename, dirname, exists, getmtime, join | |
def main(): | |
""" Update settings.py with my preferences """ | |
# Read settings.py | |
contents_modified = False | |
with open(SETTINGS, 'rt') as infile: | |
contents = [x.rstrip() for x in infile.readlines()] | |
# Search & Insert | |
search_inserts = [ | |
( "import os", "from dotenv import load_dotenv" ), | |
( "BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))", | |
"load_dotenv(os.path.join(BASE_DIR, '.env'))" ), | |
( "", "" ), | |
] | |
for search, insert in search_inserts: | |
if not search: | |
continue | |
s = contents.index(search) | |
if s and contents[s + 1] != insert: | |
# print(insert) | |
contents.insert(s + 1, insert) | |
contents_modified = True | |
# Search & Replace | |
search_replaces = [ | |
("SECRET_KEY = ", "SECRET_KEY = os.getenv('SECRET_KEY') or "), | |
("TIME_ZONE = 'UTC'", "TIME_ZONE = os.getenv('TZ') or 'UTC'"), | |
("DEBUG = True", "DEBUG = os.getenv('DEBUG') or False"), | |
("", ""), | |
] | |
for search, replace in search_replaces: | |
if not search: | |
continue | |
for i in range(len(contents)): | |
# ToDo: SECRET_KEY, DEBUG = os.getenv() | |
if contents[i].startswith(search) and replace not in contents[i]: | |
contents[i] = contents[i].replace(search, replace) | |
contents_modified = True | |
# ToDo: TEMPLATES.DIRS = [ os.path.join(BASE_DIR, 'templates'), ] | |
# ToDo: TIME_ZONE = 'UTC' ==> TIME_ZONE = os.getenv('TZ') or 'America/Toronto' | |
# ToDo: LOGIN URLs, etc. | |
# Section Processing - TEMPLATES | |
section = 'TEMPLATES = ' | |
inside_templates = False | |
for i in range(len(contents)): | |
if contents[i].startswith(section): | |
# print('Found TEMPLATES') | |
inside_templates = True | |
if inside_templates: | |
search = "'DIRS': []," | |
replace = "'DIRS': [ os.path.join(BASE_DIR, 'templates'), ]," | |
if contents[i].strip() == search and replace not in contents[i]: | |
contents[i] = contents[i].replace(search, replace) | |
contents_modified = True | |
if contents[i] == ']': | |
inside_templates = False | |
# Process .env file | |
with open('.env', 'rt') as envfile: | |
# Only load non-blank lines that aren't comments and strip newline characters | |
envlines = [x.rstrip() for x in envfile.readlines() if x != '\n' and not x.startswith('#')] | |
# print(envlines) | |
varnames = [] | |
for line in envlines: | |
varnames.append(line.split('=')[0]) | |
# print(varnames) | |
vars_regex = re.compile(r'(%s)\s*=' % '|'.join(varnames)) | |
# print("RegEx:", vars_regex) | |
found = [] | |
for i in range(len(contents)): | |
line = contents[i] | |
match = vars_regex.search(line) | |
if match: | |
word = match[0].split('=')[0].strip() | |
found.append(word) | |
not_found = [] | |
for v in varnames: | |
if v not in found: | |
not_found.append(v) | |
if not_found: | |
addlines = [x + " = os.getenv('%s')" % x for x in not_found] | |
addlines.insert(0, "\n\n# Additional environment variables in .env added by 'update_settings'") | |
contents += addlines + ['\n\n\n',] | |
contents_modified = True | |
# Process any changes | |
if contents_modified: | |
# Remove duplicate lines from file | |
newlines = [] | |
lastline = '' | |
for c in contents: | |
if c != lastline: | |
newlines.append(c) | |
if c.strip() != '': | |
lastline = c | |
contents = newlines | |
# Write updated file to disk | |
with open(WORKFILE, 'wt') as outfile: | |
outfile.writelines([ x + os.linesep for x in contents ]) | |
os.renames(SETTINGS, SETTINGS + '~') | |
os.renames(WORKFILE, SETTINGS) | |
else: | |
print("No modifications detected.") | |
return | |
def init(): | |
""" Prepare for main() processing """ | |
global SETTINGS, WORKFILE | |
settings_py = glob('**/%s' % SETTINGS, recursive=True) | |
if not settings_py: | |
raise FileNotFoundError(SETTINGS) | |
SETTINGS = settings_py[0] | |
parts = SETTINGS.split(os.sep) | |
parts[-1] = '.' + parts[-1] | |
if not exists(SETTINGS): | |
raise FileNotFoundError(SETTINGS) | |
WORKFILE = os.sep.join(parts) | |
return | |
def eoj(): | |
if exists(BACKUP_FILE): | |
os.system('meld %s %s' % (BACKUP_FILE, SETTINGS)) | |
return | |
def debug_breakpoint(): | |
pass | |
return | |
if __name__ == '__main__': | |
SETTINGS = 'settings.py' | |
WORKFILE = '.' + SETTINGS | |
BACKUP_FILE = SETTINGS + '~' | |
init() | |
main() | |
eoj() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment