Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
"""
Running the file process
In the brandsite virtual env run following command for bpm zips
python manage.py update_bonita_dir <dir>/<subdir>
python manage.py update_bonita_dir ops/cancer-care-proposal-form
By default this command concatenates and minifies js and css file, use a command in this format to disallow this
python manage.py update_bonita_dir <dir>/<subdir> --nooptimize
"""
from django.core.management.base import BaseCommand
from subprocess import call
from bs4 import BeautifulSoup
import os
import zipfile
import fileinput
CODEBASE_ROOT = 'webapp/static/bpm/'
JS_EXTENSION = '.js'
CSS_EXTENSION = '.css'
REPLACE_WORD_DICT = {
'<head>': '',
'</head>': '',
'<body': '<div',
'</body>': '</div>'
}
JS_FILES_NOT_TO_BE_MINIFIED = ['vendor.min.js', 'runtime.min.js']
CSS_FILES_NOT_TO_BE_MINIFIED = ['bootstrap.min.css']
PREFIXES_FOR_EXTERNAL_LINK = ['http', 'https', 'www']
class Command(BaseCommand):
help = 'To add fixtures into the site models'
optimize = True
def read_entirely(self, file):
"""
:param file(file object): file whose content needs to read
returns content of file
"""
if not os.path.isfile(file):
return ''
with open(file, 'r') as handle:
return handle.read()
def is_external_file(self, src):
"""
:param src(string): source to js file which will be parsed
:returns status whether a given file is an external or internal
"""
for prefix in PREFIXES_FOR_EXTERNAL_LINK:
if prefix in src:
return True
def to_be_minified_js_files(self, src):
"""
:param src(string): source to js file which will be parsed
:returns status whether a given needs to be minified or not
"""
for script_name in JS_FILES_NOT_TO_BE_MINIFIED:
if script_name in src:
return False
if JS_EXTENSION not in src or self.is_external_file(src):
return False
return True
def to_be_minified_css_files(self, src):
"""
:param src(string): link to css file which will be parsed
:returns status whether a given needs to be minified or not
"""
for css_file in CSS_FILES_NOT_TO_BE_MINIFIED:
if css_file in src:
return False
if CSS_EXTENSION not in src or self.is_external_file(src):
return False
return True
def concatenate_files(self, directory, folder_name, dest_file_name):
"""
:param directory(string): name of main directory to bonita form
:param folder_name(list): an array of sources to different file
:param dest_file_name(string): final destination to file where content of concatenated files need to written
utiliy function to concatenate files
"""
# over here custom widget related js content is being concatenated and written to a new file
result = '\n'.join(self.read_entirely(file) for file in folder_name)
file = 'webapp/static/bpm/' + directory + '/resources/' + dest_file_name
with open(file, 'w+') as handle:
handle.write(result)
def handle(self, *args, **options):
"""Does following operations:
Unzips the code
Parses html and add relevant static file paths
Removes unnecessary html tags
"""
# setting the optimize flag if user has passed it as argument
if not options['optimize']:
self.optimize = options['optimize']
# Extract the zip file
os.makedirs(CODEBASE_ROOT + options['dir'])
zip_ref = zipfile.ZipFile(CODEBASE_ROOT + options['dir'] + '.zip', 'r')
zip_ref.extractall(CODEBASE_ROOT + options['dir'])
zip_ref.close()
# Reads the html file to correct static paths
file_path = CODEBASE_ROOT + options['dir'] + '/resources/index.html'
BeautifulSoup(open(file_path), "html5lib")
try:
soup = BeautifulSoup(open(CODEBASE_ROOT + options['dir'] + '/resources/index.html'), "html5lib")
pass
except Exception as e:
print("file not found, please check if the location exist:%s%s/resources/index.html " %
(CODEBASE_ROOT, options['dir']))
return None
# performing links related actions
links = soup.find_all('link')
links_to_be_minified = []
for index, link in enumerate(links):
if link.get('href') and self.optimize and self.to_be_minified_css_files(link.get('href')):
link['href'] = 'webapp/static/bpm/' + options['dir'] + '/resources/' + link.get('href')
links_to_be_minified.append(link['href'])
link.extract()
elif link.get('href') and not self.is_external_file(link.get('href')):
link['href'] = '/static/bpm/' + options['dir'] + '/resources/' + link.get('href')
if self.optimize:
try:
self.concatenate_files(options['dir'], links_to_be_minified, 'assets/css/custom_widget_css.css')
# over here concatenated file is being minified
call(["grunt", "minifyBonitaCss", "--fileName=" + options['dir']])
# appending newly created minified custom widget css file
file = '/static/bpm/' + options['dir'] + '/resources/assets/css/custom_widget_css.min.css'
link_tag = soup.new_tag("link", href=file, rel="stylesheet")
soup.head.append(link_tag)
except Exception as e:
print("Error while concatenating and minifying custom widget css" + str(e))
# performing script related actions
scripts = soup.find_all('script')
scripts_to_be_minified = []
for index, script in enumerate(scripts):
if script.get('src') and '/static/bpm/' in script.get('src'):
print('Already updated page, please check')
return
# find custom widget related js file which have not been minified
if script.get('src') and self.to_be_minified_js_files(script['src']) and self.optimize:
script['src'] = 'webapp/static/bpm/' + options['dir'] + '/resources/' + script['src']
scripts_to_be_minified.append(script['src'])
script.extract()
elif script.get('src') and not self.is_external_file(script.get('src')):
script['src'] = '/static/bpm/' + options['dir'] + '/resources/' + script.get('src')
if self.optimize:
try:
self.concatenate_files(options['dir'], scripts_to_be_minified, 'widgets/custom_widget.js')
# over here concatenated file is being minified
call(["grunt", "minifyBonita", "--fileName=" + options['dir']])
# appending newly created minified custom widget js file
file = '/static/bpm/' + options['dir'] + '/resources/widgets/custom_widget.min.js'
script_tag = soup.new_tag("script", src=file)
soup.head.append(script_tag)
except Exception as e:
print("Error while concatenating and minifying custom widget js" + str(e))
soup.title.decompose()
soup.meta.decompose()
soup.meta.decompose()
# removing empty line added in index.html
modified_soup = '\n'.join([line for line in str(soup).split("\n") if line.strip() != ''])
soup = BeautifulSoup(modified_soup, "html5lib")
head = soup.head.extract()
body = soup.body.extract()
f = open(file_path, 'w+')
f.write('%s%s' % (head, body))
f.close()
for k, v in REPLACE_WORD_DICT.items():
with fileinput.FileInput(file_path, inplace=True, backup='.bak') as file:
for line in file:
print(line.replace(k, v), end='')
print("%s BPM file extracted successfully " % (options['dir']))
def add_arguments(self, parser):
parser.add_argument('dir', type=str)
parser.add_argument(
'--nooptimize',
action='store_false',
dest='optimize',
default=True,
help='Flag maintained to decide when to optimize',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment