Source code for door43_tools.project_deployer

from __future__ import print_function, unicode_literals
import os
import sys
import tempfile
from glob import glob
from shutil import copyfile
from aws_tools.s3_handler import S3Handler
from general_tools.file_utils import write_file
from door43_tools import templaters


[docs]class ProjectDeployer(object): """ Deploys a project's revision to the door43.org bucket Read from the project's user dir in the cdn.door43.org bucket by applying the door43.org template to the raw html files """ def __init__(self, cdn_bucket, door43_bucket, s3_handler_class=S3Handler): """ :param string cdn_bucket: :param string door43_bucket: :param class s3_handler_class """ self.cdn_bucket = cdn_bucket self.door43_bucket = door43_bucket self.s3_handler_class = s3_handler_class
[docs] def deploy_revision_to_door43(self, build_log_key): cdn_handler = S3Handler(self.cdn_bucket) door43_handler = S3Handler(self.door43_bucket) build_log = None try: build_log = cdn_handler.get_json(build_log_key) except: pass print(build_log) if not build_log or 'commit_id' not in build_log or 'repo_owner' not in build_log or 'repo_name' not in build_log: return False user = build_log['repo_owner'] repo_name = build_log['repo_name'] commit_id = build_log['commit_id'][:10] s3_commit_key = 'u/{0}/{1}/{2}'.format(user, repo_name, commit_id) s3_repo_key = 'u/{0}/{1}'.format(user, repo_name) source_dir = tempfile.mkdtemp(prefix='source_') output_dir = tempfile.mkdtemp(prefix='output_') template_dir = tempfile.mkdtemp(prefix='template_') cdn_handler.download_dir(s3_commit_key, source_dir) source_dir = os.path.join(source_dir, s3_commit_key) # determining the template and templater from the resource_type, use general if not found try: templater_class = self.str_to_class('templaters.{0}Templater'.format(build_log['resource_type'].capitalize())) if build_log['resource_type']: template_key = 'templates/{0}.html'.format(build_log['resource_type']) else: template_key = 'templates/obs.html' # Use a generic template here except AttributeError: templater_class = templaters.Templater template_key = 'templates/obs.html' # Use a generic template here template_file = os.path.join(template_dir, 'template.html') print("Downloading {0} to {1}...".format(template_key, template_file)) door43_handler.download_file(template_key, template_file) html_files = sorted(glob(os.path.join(source_dir, '*.html'))) if len(html_files) < 1: content = '' if len(build_log['errors']) > 0: content += """ <div style="text-align:center;margin-bottom:20px"> <i class="fa fa-times-circle-o" style="font-size: 250px;font-weight: 300;color: red"></i> <br/> <h2>Critical!</h2> <h3>Here is what went wrong with this build:</h3> </div> """ content += '<div><ul><li>' + '</li><li>'.join(build_log['errors']) + '</li></ul></div>' elif len(build_log['warnings']) > 0: content += """ <div style="text-align:center;margin-bottom:20px"> <i class="fa fa-exclamation-circle" style="font-size: 250px;font-weight: 300;color: yellow"></i> <br/> <h2>Warning!</h2> <h3>Here are some problems with this build:</h3> </div> """ content += '<ul><li>' + '</li><li>'.join(build_log['warnings']) + '</li></ul>' else: content += '<h1>{0}</h1>'.format(build_log['message']) content += '<p><i>No content is available to show for {0} yet.</i></p>'.format(repo_name) html = """ <html lang="en"> <head> <title>{0}</title>' </head> <body> <div id="content">{1}</div> </body> </html>""".format(repo_name, content) repo_index_file = os.path.join(source_dir, 'index.html') write_file(repo_index_file, html) # merge the source files with the template templater = templater_class(source_dir, output_dir, template_file) templater.run() # Copy first HTML file to index.html if index.html doesn't exist html_files = sorted(glob(os.path.join(output_dir, '*.html'))) if len(html_files) > 0: index_file = os.path.join(output_dir, 'index.html') if not os.path.isfile(index_file): copyfile(os.path.join(output_dir, html_files[0]), index_file) # Copy all other files over that don't already exist in output_dir, like css files for filename in sorted(glob(os.path.join(source_dir, '*'))): output_file = os.path.join(output_dir, os.path.basename(filename)) if not os.path.exists(output_file) and not os.path.isdir(filename): copyfile(filename, output_file) # Upload all files to the door43.org bucket for root, dirs, files in os.walk(output_dir): for f in sorted(files): path = os.path.join(root, f) key = s3_commit_key + path.replace(output_dir, '') print("Uploading {0} to {1}".format(path, key)) door43_handler.upload_file(path, key, 0) # Now we place json files and make an index.html file for the whole repo try: door43_handler.copy(from_key='{0}/project.json'.format(s3_repo_key), from_bucket=self.cdn_bucket) door43_handler.copy(from_key='{0}/manifest.json'.format(s3_commit_key), to_key='{0}/manifest.json'.format(s3_repo_key)) door43_handler.redirect(s3_repo_key, '/' + s3_commit_key) door43_handler.redirect(s3_repo_key + '/index.html', '/' + s3_commit_key) except Exception: pass return True
[docs] def redeploy_all_commits(self): cdn_handler = S3Handler(self.cdn_bucket) success = True for obj in cdn_handler.get_objects(prefix='u/', suffix='build_log.json'): success = (success and self.deploy_revision_to_door43(obj.key)) return success
@staticmethod
[docs] def str_to_class(str): """ Gets a class from a string. :param str|unicode str: The string of the class name """ return reduce(getattr, str.split("."), sys.modules[__name__])