merge with upstream

This commit is contained in:
Senad Uka
2017-12-20 20:27:55 +01:00
parent 8beef5faea
commit 2ea9e2e702
12 changed files with 237 additions and 81 deletions

View File

@@ -1,9 +1,10 @@
import os
import requests
from urllib.parse import urlparse
import rollbar
import rollbar.contrib.flask
from flask import Flask, request, make_response, session, render_template, \
redirect, url_for
redirect, url_for, jsonify
from flask import got_request_exception
from flask.ext import assets
from flask_oauthlib.client import OAuth
@@ -16,6 +17,7 @@ from helix.Services.dxf_service import DXFService
from helix.api.api import api
from helix.calculators.calculator import Calculator
from helix.constants import redis_constant, sql_constant
from helix.constants.file_validation_error import FileValidationError, FileValidationException
from helix.constants.inverter_type import InverterType
from helix.constants.system_type import SystemType
from helix.csv_builder import CsvBuilder
@@ -184,6 +186,44 @@ def summary():
return render_template('site_summary.html.jinja', context=context)
def handle_dxf_file(session_manager, file_contents, filename=None):
errors = []
user_values = session_manager.user_values()
validator = FileValidator(user_values)
calculator = Calculator(user_values, calculate_panel_data=False)
extension = os.path.splitext(filename)[1] or 'dxf'
extension = extension.split('.')[-1]
validation_error = validator.validate(file_contents, FileType.AuroraDxf, extension=extension)
if validation_error:
error_msg = validation_error.format_error_message()
errors.append(error_msg)
else:
try:
module_constants = user_values.module_system_constants()
# FIXME: parsing a file with many entities is very slow
dxf_data = DXFService().parse(file_contents,
module_constants,
user_values.system_type(),
calculator.L_B() * 12,
DXFHelper(),
SubarrayValidator())
csv = CsvBuilder().build_cad_output(dxf_data['panels'])
session_manager.save_uploaded_file(csv, dxf_file_name=filename)
buildings = dxf_data['buildings']
session_manager.save_buildings_polygons(buildings)
session_manager.save_is_drawing_inaccurate(dxf_data['is_panel_drawing_inaccurate'])
return True, errors
except DXFError as error:
errors.append(error.message)
except OldDxfFormatException as error:
errors.append(error.message)
return False, errors
@app.route("/array_summary/", methods=['GET', 'POST'])
def array_summary():
"""This endpoint allows you to upload a file.
@@ -202,8 +242,7 @@ def array_summary():
validator = FileValidator(session_manager.user_values())
file = request.files['file_upload']
file_contents = validator.obtain_stream(file)
validation_error = validator.validate(file_contents, file,
FileType.Csv)
validation_error = validator.validate(file_contents, FileType.Csv, file)
if not validation_error:
session_manager.save_uploaded_file(file_contents,
cad_file_name=file.filename)
@@ -215,36 +254,13 @@ def array_summary():
elif 'dxf_upload' in request.files and request.files['dxf_upload'].filename:
file = request.files['dxf_upload']
user_values = session_manager.user_values()
calculator = Calculator(user_values, calculate_panel_data=False)
validator = FileValidator(user_values)
file_contents = validator.obtain_stream(file)
validation_error = validator.validate(file_contents, file,
FileType.AuroraDxf)
if validation_error:
error_msg = validation_error.format_error_message()
array_form.dxf_upload.errors.append(error_msg)
success, errors = handle_dxf_file(session_manager, file_contents, filename=file.filename)
if success:
return redirect(url_for('array_summary'))
else:
try:
module_constants = user_values.module_system_constants()
# FIXME: parsing a file with many entities is very slow
dxf_data = DXFService().parse(file_contents,
module_constants,
user_values.system_type(),
calculator.L_B() * 12,
DXFHelper(),
SubarrayValidator())
csv = CsvBuilder().build_cad_output(dxf_data['panels'])
session_manager.save_uploaded_file(csv, dxf_file_name=file.filename)
buildings = dxf_data['buildings']
session_manager.save_buildings_polygons(buildings)
session_manager.save_is_drawing_inaccurate(dxf_data['is_panel_drawing_inaccurate'])
return redirect(url_for('array_summary'))
except DXFError as error:
array_form.dxf_upload.errors.append(error.message)
except OldDxfFormatException as error:
array_form.dxf_upload.errors.append(error.message)
array_form.dxf_upload.errors.extend(errors)
elif context['csv_available']:
return redirect(url_for('power_station_configuration'))
else:
@@ -256,39 +272,81 @@ def array_summary():
context['dxf_file_name'] = ''
if context['site_data_available'] and context['csv_available']:
user_values = session_manager.user_values()
calculator = Calculator(user_values)
system_type = user_values.system_type()
module_type = user_values.module_type()
project_presenter = ProjectPresenter(system_type, module_type)
try:
calculator = Calculator(user_values)
system_type = user_values.system_type()
module_type = user_values.module_type()
project_presenter = ProjectPresenter(system_type, module_type)
context['wind_zones'] = system_type.system_constants().wind_zones
context['summary_table'] = calculator.summary_table()
context['minimum_array_sizes'] = calculator.minimum_array_sizes()
context['seismic_anchors'] = calculator.subarray_summary()
context['summary_values'] = calculator.summary_values()
context['wind_zones'] = system_type.system_constants().wind_zones
context['summary_table'] = calculator.summary_table()
context['minimum_array_sizes'] = calculator.minimum_array_sizes()
context['seismic_anchors'] = calculator.subarray_summary()
context['summary_values'] = calculator.summary_values()
panels = calculator.get_computed_csv_columns()
context['panel_array'] = project_presenter.get_panel_data(panels,
calculator.subarrays,
project_presenter.get_max_y(
calculator.buildings_for_drawing,
panels))
context['buildings'] = project_presenter.get_buildings(calculator.buildings_for_drawing)
context['override_form'] = True
context['cad_file_name'] = session_manager.site.cad_file_name or 'Upload System Text Data'
context['dxf_file_name'] = session_manager.site.dxf_file_name or 'Upload System DXF'
context['is_drawing_inaccurate'] = session_manager.user_values().is_panel_drawing_inaccurate()
context['inaccurate_drawing_warning'] = 'The subarrays in this design are not parallel to each other, \
panels = calculator.get_computed_csv_columns()
context['panel_array'] = project_presenter.get_panel_data(panels,
calculator.subarrays,
project_presenter.get_max_y(
calculator.buildings_for_drawing,
panels))
context['buildings'] = project_presenter.get_buildings(calculator.buildings_for_drawing)
context['override_form'] = True
context['cad_file_name'] = session_manager.site.cad_file_name or 'Upload System Text Data'
context['dxf_file_name'] = session_manager.site.dxf_file_name or 'Upload System DXF'
context['is_drawing_inaccurate'] = session_manager.user_values().is_panel_drawing_inaccurate()
context['inaccurate_drawing_warning'] = 'The subarrays in this design are not parallel to each other, \
and the graphical representation on this page may not be accurate.'
except FileValidationException as error:
# when calculator is about to enter infinte loop
# it throws an exception - it is supplied wrong data
context['site_data_available'] = False
context['csv_available'] = False
context['no_proceed'] = True
context['cad_file_name'] = ''
context['dxf_file_name'] = ''
context['infinite_loop_detection_message'] = error.message
elif not context['site_data_available']:
context['no_proceed'] = True
if is_sfdc_session() and 'dxf_link_loaded' not in session:
context['javascripts'].append('auto_dxf_load')
db_session.close()
return render_template('array_summary.html.jinja', context=context, form=array_form)
@app.route("/load_dxf/", methods=['GET', 'POST'])
def load_dxf_file():
if 'dxf_link' not in session:
errors = ['DXF link not found']
response = jsonify({'errors': errors})
response.status_code = 404
return response
dxf_link = session['dxf_link']
response = requests.get(dxf_link)
if response.status_code == 200:
file_contents = response.content.decode('utf-8')
filename = urlparse(dxf_link).path.strip('/')
db_session = sql_constant.sql_session_maker()
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
success, errors = handle_dxf_file(session_manager, file_contents, filename=filename)
session['dxf_link_loaded'] = True
if success:
return jsonify({'status': 'success'})
else:
errors = ['Unable to download DXF file from Sales Force ({})'.format(response.status_code)]
response = jsonify({'errors': errors})
response.status_code = 400
return response
@app.route("/power_station_configuration/", methods=['GET', 'POST'])
def power_station_configuration():
db_session = sql_constant.sql_session_maker()
@@ -485,6 +543,7 @@ def sales_force_authorized():
data = sf_tasks.get_site_characterization_from_sales_force(session, resp['instance_url'])
if data:
session['dxf_link'] = data['dxf_link']
session_manager.save_form_submission(data)
return redirect(next_url)
else:
@@ -492,7 +551,6 @@ def sales_force_authorized():
# FIXME
from flask import jsonify
@app.route("/export-sfdc")
def export_sfdc():
if not is_sfdc_session():
@@ -515,6 +573,8 @@ def get_sales_force_token(token=None):
def sales_force_logout():
session.pop('SFID', None)
session.pop('sales_force_token', None)
session.pop('dxf_link', None)
session.pop('dxf_link_loaded', None)
session.clear()
return redirect('/')
# End of Sales Force Integration