syncing with upstream
This commit is contained in:
193
helix/main.py
193
helix/main.py
@@ -4,7 +4,7 @@ from urllib.parse import urlparse
|
||||
import rollbar
|
||||
import rollbar.contrib.flask
|
||||
from flask import Flask, request, make_response, session, render_template, \
|
||||
redirect, url_for, jsonify
|
||||
redirect, url_for, jsonify, flash
|
||||
from flask import got_request_exception
|
||||
from flask.ext import assets
|
||||
from flask_oauthlib.client import OAuth
|
||||
@@ -29,17 +29,32 @@ from helix.forms.input_form import InputForm, ArrayForm, TestDXFForm
|
||||
from helix.models.dxf.dxf_error import DXFError, OldDxfFormatException
|
||||
from helix.presenters.image_presenter import ImagePresenter
|
||||
from helix.presenters.panel_presenter import ProjectPresenter
|
||||
from helix.qa_helper import QAScenario
|
||||
from helix.session_manager import SessionManager
|
||||
from helix.validators.file_validator import FileValidator, FileType
|
||||
from helix.validators.subarray_validator import SubarrayValidator
|
||||
from flask_featureflags import FeatureFlag
|
||||
import flask_featureflags as feature
|
||||
import pprint
|
||||
|
||||
app = Flask(__name__)
|
||||
app.register_blueprint(api, url_prefix='/api')
|
||||
app.secret_key = os.getenv('SECRET_KEY', 'verysecretkey')
|
||||
app.config['PROFILE'] = True
|
||||
|
||||
app.config['FEATURE_FLAGS'] = {
|
||||
'ff_dummy_feature': True,
|
||||
'ff_cpp': True
|
||||
}
|
||||
|
||||
# Sales Force integrations
|
||||
FeatureFlag(app) # initializes feature flags
|
||||
|
||||
if feature.is_active('ff_dummy_feature'):
|
||||
app.logger.info('Feature flags working!')
|
||||
app.logger.info('Current state: ')
|
||||
app.logger.info(pprint.PrettyPrinter(width=41, compact=True).pformat(app.config['FEATURE_FLAGS']))
|
||||
|
||||
# Salesforce integrations
|
||||
oauth = OAuth()
|
||||
SFDC_BASE_URL = os.getenv('SFDC_BASE_URL', 'https://test.salesforce.com')
|
||||
try:
|
||||
@@ -53,7 +68,7 @@ try:
|
||||
authorize_url=SFDC_BASE_URL + '/services/oauth2/authorize',
|
||||
)
|
||||
except TypeError:
|
||||
print('Sales Force integration disabled')
|
||||
print('Salesforce integration disabled')
|
||||
sales_force = None
|
||||
|
||||
|
||||
@@ -90,8 +105,8 @@ def init_rollbar():
|
||||
got_request_exception.connect(rollbar.contrib.flask.report_exception, app)
|
||||
|
||||
|
||||
def is_sfdc_session():
|
||||
return 'SFID' in session
|
||||
def is_sales_force_session():
|
||||
return 'sf_session' in session
|
||||
|
||||
|
||||
@app.route("/")
|
||||
@@ -136,7 +151,7 @@ def test_dxf():
|
||||
# wizard steps
|
||||
@app.route("/site_characterization/", methods=['GET', 'POST'])
|
||||
def site_characterization():
|
||||
if is_sfdc_session():
|
||||
if is_sales_force_session():
|
||||
return redirect('/summary/')
|
||||
|
||||
db_session = sql_constant.sql_session_maker()
|
||||
@@ -184,14 +199,14 @@ def summary():
|
||||
else:
|
||||
context['no_proceed'] = True
|
||||
|
||||
if is_sfdc_session():
|
||||
if is_sales_force_session():
|
||||
context['hide_back'] = True
|
||||
|
||||
db_session.close()
|
||||
return render_template('site_summary.html.jinja', context=context)
|
||||
|
||||
|
||||
def handle_dxf_file(session_manager, file_contents, filename=None, save_file=True):
|
||||
def handle_dxf_file(session_manager, file_contents, filename=None):
|
||||
errors = []
|
||||
user_values = session_manager.user_values()
|
||||
validator = FileValidator(user_values)
|
||||
@@ -215,8 +230,7 @@ def handle_dxf_file(session_manager, file_contents, filename=None, save_file=Tru
|
||||
DXFHelper(),
|
||||
SubarrayValidator())
|
||||
csv = CsvBuilder().build_cad_output(dxf_data['panels'])
|
||||
if save_file:
|
||||
session_manager.save_uploaded_file(csv, dxf_file_name=filename)
|
||||
session_manager.save_uploaded_file(csv, dxf_file_name=filename)
|
||||
|
||||
buildings = dxf_data['buildings']
|
||||
session_manager.save_buildings_polygons(buildings)
|
||||
@@ -264,6 +278,8 @@ def array_summary():
|
||||
file_contents = validator.obtain_stream(file)
|
||||
success, errors = handle_dxf_file(session_manager, file_contents, filename=file.filename)
|
||||
if success:
|
||||
if is_sales_force_session():
|
||||
session['sf_session']['new_dxf_file'] = True
|
||||
return redirect(url_for('array_summary'))
|
||||
else:
|
||||
array_form.dxf_upload.errors.extend(errors)
|
||||
@@ -317,7 +333,10 @@ def array_summary():
|
||||
elif not context['site_data_available']:
|
||||
context['no_proceed'] = True
|
||||
|
||||
if is_sfdc_session() and 'dxf_link_loaded' not in session:
|
||||
if is_sales_force_session() and \
|
||||
session['sf_session'].get('dxf_link', None) and \
|
||||
not session['sf_session'].get('dxf_link_loaded', None):
|
||||
|
||||
context['javascripts'].append('auto_dxf_load')
|
||||
|
||||
db_session.close()
|
||||
@@ -326,14 +345,21 @@ def array_summary():
|
||||
|
||||
@app.route("/load_dxf/", methods=['GET', 'POST'])
|
||||
def load_dxf_file():
|
||||
if 'dxf_link' not in session:
|
||||
if (not is_sales_force_session()) or session['sf_session'].get('dxf_link', None) is None:
|
||||
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)
|
||||
dxf_link = session['sf_session'].get('dxf_link', None)
|
||||
if not dxf_link:
|
||||
session['sf_session']['dxf_link_loaded'] = True
|
||||
response = jsonify({'status': 'success', 'messages': ['No DXF file to load from Salesforce.']})
|
||||
response.status_code = 202
|
||||
return response
|
||||
|
||||
print('Loading DXF file from {}'.format(dxf_link))
|
||||
response = requests.get(dxf_link, timeout=30)
|
||||
if response.status_code == 200:
|
||||
file_contents = response.content.decode('utf-8')
|
||||
filename = urlparse(dxf_link).path.strip('/')
|
||||
@@ -341,12 +367,12 @@ def load_dxf_file():
|
||||
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, save_file=False)
|
||||
session['dxf_link_loaded'] = True
|
||||
success, errors = handle_dxf_file(session_manager, file_contents, filename=filename)
|
||||
session['sf_session']['dxf_link_loaded'] = True
|
||||
if success:
|
||||
return jsonify({'status': 'success'})
|
||||
return jsonify({'status': 'success', 'messages': ['DXF from Salesforce loaded successfully.']})
|
||||
else:
|
||||
errors = ['Unable to download DXF file from Sales Force ({})'.format(response.status_code)]
|
||||
errors = ['Unable to download DXF file from Salesforce ({})'.format(response.status_code)]
|
||||
|
||||
response = jsonify({'errors': errors})
|
||||
response.status_code = 400
|
||||
@@ -431,10 +457,11 @@ def download():
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
context = session_manager.context()
|
||||
context['current_step'] = 5
|
||||
error, data = session.pop('sfdc_export_urls', (None, None))
|
||||
if data is not None:
|
||||
context['sfdc_export_error'] = error
|
||||
context['sfdc_export_urls'] = data
|
||||
if is_sales_force_session():
|
||||
error, data = session['sf_session'].pop('export_urls', (None, None))
|
||||
if data is not None:
|
||||
context['sfdc_export_error'] = error
|
||||
context['sfdc_export_urls'] = data
|
||||
db_session.close()
|
||||
return render_template('download.html.jinja', context=context)
|
||||
|
||||
@@ -524,55 +551,83 @@ def helix_documentation():
|
||||
return render_template('helix_documentation.jinja', context=context)
|
||||
|
||||
|
||||
# Sales Force Integration
|
||||
# Salesforce Integration
|
||||
@app.route('/sales_force_login')
|
||||
def sales_force_login():
|
||||
# To test it locally: https://localhost:8443/sales_force_login?SFID=a3cL00000004QsQIAU
|
||||
sfid = request.args.get('SFID')
|
||||
# To test it locally: https://localhost:8443/sales_force_login?sfid=a3cL00000004QsQIAU
|
||||
sfid = request.args.get('sfid')
|
||||
if sfid:
|
||||
session.clear()
|
||||
session['SFID'] = sfid
|
||||
return sales_force.authorize(callback=url_for('sales_force_authorized', _external=True, SFID=sfid), SFID=sfid)
|
||||
session['sf_session'] = {}
|
||||
session['sf_session']['sfid'] = sfid
|
||||
return sales_force.authorize(callback=url_for('sales_force_authorized', _external=True, sfid=sfid), sfid=sfid)
|
||||
else:
|
||||
flash('Missing sfid')
|
||||
return redirect('/')
|
||||
|
||||
|
||||
@app.route('/sales_force_authorized')
|
||||
def sales_force_authorized():
|
||||
if not is_sales_force_session():
|
||||
flash('This is not a Salesforce session')
|
||||
return redirect('/')
|
||||
|
||||
next_url = url_for('summary')
|
||||
|
||||
resp = sales_force.authorized_response()
|
||||
try:
|
||||
resp = sales_force.authorized_response()
|
||||
except Exception as e:
|
||||
flash('Error on authenticating to Salesforce.')
|
||||
print('Error on authenticating to Salesforce.')
|
||||
print(str(e))
|
||||
return sales_force_logout()
|
||||
|
||||
if resp is None:
|
||||
print('Unable to authenticate to SFDC.')
|
||||
flash('Unknown response from Salesforce.')
|
||||
print('Unknown response from Salesforce.')
|
||||
return redirect(next_url)
|
||||
|
||||
print('New Sales Force - OAuth2 login')
|
||||
print('New Salesforce - OAuth2 login')
|
||||
db_session = sql_constant.sql_session_maker()
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
session['sales_force_token'] = resp['access_token']
|
||||
session['sf_session']['access_token'] = resp['access_token']
|
||||
|
||||
data = sf_tasks.get_site_characterization_from_sales_force(session)
|
||||
if data:
|
||||
session['dxf_link'] = data['dxf_link']
|
||||
session_manager.save_form_submission(data)
|
||||
return redirect(next_url)
|
||||
else:
|
||||
helix_session_id = session['id']
|
||||
access_token = session['sf_session']['access_token']
|
||||
sfid = session['sf_session']['sfid']
|
||||
try:
|
||||
data, status_code = sf_tasks.get_site_characterization_from_sales_force(helix_session_id, access_token, sfid)
|
||||
if data and status_code == 200:
|
||||
session['sf_session']['dxf_link'] = data['dxf_link']
|
||||
session_manager.save_form_submission(data)
|
||||
flash('Connected to Salesforce.')
|
||||
return redirect(next_url)
|
||||
else:
|
||||
flash('Unable to get site characterization from Salesforce. ({})'.format(status_code))
|
||||
return sales_force_logout()
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
flash('Unable to get site characterization from Salesforce.')
|
||||
return sales_force_logout()
|
||||
|
||||
|
||||
@app.route("/export-sfdc")
|
||||
def export_sfdc():
|
||||
if not is_sfdc_session():
|
||||
if not is_sales_force_session():
|
||||
flash('This is not a Salesforce session')
|
||||
return redirect('/')
|
||||
|
||||
db_session = sql_constant.sql_session_maker()
|
||||
session_manager = SessionManager(session, redis_constant.redis_store, db_session)
|
||||
helix_session_id = session_manager.session['id']
|
||||
access_token = session['sales_force_token']
|
||||
sfid = session['SFID']
|
||||
error, data = sf_tasks.export_to_sfdc(helix_session_id, access_token, sfid)
|
||||
sf_session = session['sf_session']
|
||||
access_token = sf_session['access_token']
|
||||
sfid = sf_session['sfid']
|
||||
new_dxf_file = sf_session.get('new_dxf_file', False)
|
||||
error, data = sf_tasks.export_to_sfdc(helix_session_id, access_token, sfid, new_dxf_file=new_dxf_file, qa_test=session.get('qa_test', None))
|
||||
data.pop('bom', None)
|
||||
data['dxfUrlFromSF'] = session['dxf_link']
|
||||
session['sfdc_export_urls'] = (error, data)
|
||||
data['dxfUrlFromSF'] = sf_session['dxf_link']
|
||||
sf_session['export_urls'] = (error, data)
|
||||
db_session.close()
|
||||
return redirect('/download')
|
||||
|
||||
@@ -580,19 +635,55 @@ def export_sfdc():
|
||||
if sales_force:
|
||||
@sales_force.tokengetter
|
||||
def get_sales_force_token(token=None):
|
||||
return session.get('sales_force_token')
|
||||
return session.get('sf_session', {}).get('access_token', None)
|
||||
|
||||
|
||||
@app.route('/sales_force_logout')
|
||||
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.pop('sfdc_export_urls', None)
|
||||
session.clear()
|
||||
session.pop('sf_session', None)
|
||||
return redirect('/')
|
||||
# End of Sales Force Integration
|
||||
# End of Salesforce Integration
|
||||
|
||||
|
||||
# QA scenario simulations
|
||||
|
||||
@app.route('/qa')
|
||||
def qa_simulations():
|
||||
test = request.args.get('test', None)
|
||||
bad_request = None
|
||||
if not test:
|
||||
bad_request = 'Missing `test` parameter.'
|
||||
elif test not in QAScenario.all():
|
||||
bad_request = 'Unknown test scenario: <b>' + test + '</b>.'
|
||||
if bad_request:
|
||||
tests = ''.join(['<li><a href="/qa?test=' + s + '">' + s + '</a></li>' for s in QAScenario.all()])
|
||||
tests = '<ul>' + tests + '</ul>'
|
||||
return bad_request + tests, 400
|
||||
|
||||
if test.startswith('sf_') and 'sf_session' not in session:
|
||||
return 'Please, connect to Salesforce first.', 400
|
||||
|
||||
url = None
|
||||
if test == QAScenario.SF_RESET_ALL.value:
|
||||
session['sf_session']['dxf_link_loaded'] = False
|
||||
session['qa_test'] = None
|
||||
url = request.url_root
|
||||
elif test == QAScenario.SF_NO_DXF.value:
|
||||
session['sf_session']['dxf_link'] = None
|
||||
session['sf_session']['dxf_link_loaded'] = False
|
||||
url = request.url_root + 'array_summary/'
|
||||
elif test == QAScenario.SF_VALID_DXF.value:
|
||||
session['sf_session']['dxf_link'] = 'https://sunpower-test-dgplatform-spectrum.s3.amazonaws.com/a5FL00000008gKcMAI-DXF.dxf'
|
||||
session['sf_session']['dxf_link_loaded'] = False
|
||||
url = request.url_root + 'array_summary/'
|
||||
elif test in (QAScenario.SF_ERROR_UPLOAD_S3.value, QAScenario.SF_ERROR_NOTIFY_SF.value):
|
||||
session['qa_test'] = test
|
||||
url = request.url_root + 'export-sfdc'
|
||||
|
||||
msg = '<b>' + test + '</b> test enabled.'
|
||||
if url:
|
||||
msg += ' Access: <a href="' + url + '">' + url + '</a> to check.'
|
||||
return msg, 200
|
||||
|
||||
|
||||
@app.template_filter('format_number')
|
||||
|
||||
Reference in New Issue
Block a user