Skip to content

Commit 0de8b4d

Browse files
author
SidneyNiccolson
committed
v0.01
1 parent 6a420d2 commit 0de8b4d

File tree

170 files changed

+15509
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

170 files changed

+15509
-2
lines changed

README.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,41 @@
22
---
33
RaMa-Scene is a django 2.0 based web-application that allows for analyzing Environmentally Extended Input-Output (EEIO) tables. EXIOBASE v3.3 is used in this project.
44

5-
**Getting started**
5+
**Documentation**
66
---
77
TODO
88

9+
**Getting started**
10+
---
11+
Clone the data repository: git clone https://SidneyNiccolson@bitbucket.org/CML-IE/rama-scene_data.git
12+
13+
Clone the project: git clone https://SidneyNiccolson@bitbucket.org/CML-IE/rama-scene.git
14+
15+
Point in settings.py to the data repository files: PATH_TO_L, PATH_TO_B, PATH_TO_Y
16+
17+
Create a virtual environment and install the app requirements : $pip3 install -r requirements.txt
18+
19+
Install node.js: $sudo apt-get update
20+
$sudo apt-get install nodejs
21+
22+
On debian install nodejslegacy: $sudo apt-get install nodejs-legacy
23+
24+
Install redis: $sudo apt install redis-server
25+
26+
[Perform next steps while in virtualenv and in the rootfolder of the project]
27+
28+
Prepare the database by running: $python3 manage.py makemigrations and $python3 manage.py migrate
29+
30+
Populate the database by running: $python3 manage.py populateHierarchies
31+
32+
Prepare static resources (node version: 3.10.10 or higher): $npm install
33+
34+
Built React bundle: $./node_modules/.bin/webpack --config webpack.config.js
35+
36+
Start Celery: $celery -A ramasceneMasterProject worker -l info --concurrency=2
37+
38+
Start the development server: $python3 manage.py runserver
39+
940
**Core dependencies**
1041
---
11-
The app uses Celery (4.1.0) and Django channels (2.0.2).
42+
The app uses Celery [4.1.0] (http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html), Django channels [2.0.2] (https://channels.readthedocs.io/en/latest/) and React [16.2.0] (https://reactjs.org/)

assets/js/client/analysisJob.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// @flow
2+
import React, {Component} from 'react';
3+
import { Glyphicon } from 'react-bootstrap';
4+
// import {csrftoken} from './csrfToken';
5+
import $ from 'jquery';
6+
7+
class AnalysisJob extends Component {
8+
9+
constructor(props) {
10+
super(props);
11+
12+
this.STATUS_STARTED = 'started';
13+
this.STATUS_COMPLETED = 'completed';
14+
15+
this.state = {key: props.id, query: props.query, selected: props.selected, detailLevel: props.detailLevel, resultHandler: props.resultHandler, deleteHandler: props.deleteHandler, job_status: null, job_id: null, job_name: null, job_label: ""};
16+
}
17+
18+
componentWillReceiveProps(nextProps) {
19+
this.setState({key: this.state.key, query: this.state.query, selected: nextProps.selected, detailLevel: this.state.detailLevel, resultHandler: this.state.resultHandler, deleteHandler: this.state.deleteHandler, job_status: this.state.job_status, job_id: this.state.job_id, job_name: this.state.job_name, job_label: this.state.job_label});
20+
}
21+
22+
componentDidMount() {
23+
const ws = new WebSocket(WEBSOCKET_URL);
24+
25+
ws.onopen = function() {
26+
ws.send(JSON.stringify({'querySelection': this.state.query, 'action': 'start_calc'}));
27+
}.bind(this);
28+
29+
ws.onmessage = this.handleWebSocketResponse.bind(this);
30+
}
31+
32+
handleWebSocketResponse(message) {
33+
const job = JSON.parse(message.data);
34+
if(job.job_status == this.STATUS_STARTED) {
35+
console.log('received: %s', JSON.stringify(job));
36+
37+
// construct job label
38+
var label_parts = [job.job_name.dimType.substr(0, 4), job.job_name.vizType.substr(0, job.job_name.vizType.length - 3), job.job_name.nodesSec.toString().substr(0, 10), job.job_name.nodesReg.toString().substr(0, 10), job.job_name.extn.toString().substr(0, 10)];
39+
40+
this.setState({key: this.state.key, query: this.state.query, resultHandler: this.state.resultHandler, deleteHandler: this.state.deleteHandler, job_status: job.job_status, job_id: job.job_id, job_name: job.job_name, job_label: label_parts.join('>')});
41+
} else if(job.job_status == this.STATUS_COMPLETED) {
42+
console.log('received: %s', JSON.stringify(job));
43+
this.setState({key: this.state.key, query: this.state.query, resultHandler: this.state.resultHandler, deleteHandler: this.state.deleteHandler, job_status: job.job_status, job_id: job.job_id, job_name: job.job_name, job_label: this.state.job_label});
44+
}
45+
}
46+
47+
retrieveRawResult() {
48+
// I can't get this to work
49+
// fetch(AJAX_URL, {
50+
// body: JSON.stringify({TaskID: + job.job_id}),
51+
// cache: 'no-cache',
52+
// method: 'POST',
53+
// mode: 'cors',
54+
// })
55+
// .then(response => {
56+
// if(response.ok)
57+
// return response.json();
58+
// throw new Error('Network response was not ok.');
59+
// })
60+
// .then(function(response) {
61+
// console.log('received: %s', JSON.stringify(response));
62+
// this.state.dataCallback(response);
63+
// }.bind(this), function(error) {
64+
// console.log(error);
65+
// }).finally(function() {
66+
// this.setState({busy: false, startCallback: this.state.startCallback, completedCallback: this.state.completedCallback, dataCallback: this.state.dataCallback});
67+
// this.state.completedCallback();
68+
// }.bind(this));
69+
70+
$.ajax({
71+
cache: false,
72+
complete: function(jqXHR, textStatus) {
73+
74+
},
75+
data: {'TaskID': this.state.job_id},
76+
dataType: 'json',
77+
error: function(jqXHR, textStatus, errorThrown) {
78+
console.log(errorThrown);
79+
},
80+
headers: {
81+
// 'X-CSRFToken': csrftoken
82+
},
83+
method: 'POST',
84+
success: function(data, textStatus, jqXHR) {
85+
const result = JSON.parse(data.rawResultData)['rawResultData'];
86+
console.log('received: %s', JSON.stringify(result));
87+
this.state.resultHandler(result, this.state.key);
88+
}.bind(this),
89+
url: AJAX_URL
90+
});
91+
}
92+
93+
destroy() {
94+
this.state.deleteHandler(this.state.selected, this.state.key);
95+
}
96+
97+
render() {
98+
return (
99+
<tr className={this.state.job_status == this.STATUS_STARTED ? 'primary' : (this.state.job_status == this.STATUS_COMPLETED ? 'success' : 'default')} key={this.state.key}>
100+
<td onClick={this.state.job_status == this.STATUS_COMPLETED ? this.retrieveRawResult.bind(this) : function() {}} style={this.state.job_status == this.STATUS_COMPLETED ? {cursor: 'pointer'} : {cursor: 'default'}}>
101+
{this.state.selected && <Glyphicon glyph="chevron-left"/>} {this.state.job_label}
102+
</td>
103+
<td>{this.state.job_status == this.STATUS_COMPLETED && <Glyphicon glyph="trash" style={{cursor: 'pointer'}} onClick={this.destroy.bind(this)}/>}</td>
104+
</tr>
105+
);
106+
}
107+
}
108+
109+
export default AnalysisJob;

assets/js/client/csrfToken.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var getCookie = function(name) {
2+
var cookieValue = null;
3+
if (document.cookie && document.cookie != '') {
4+
var cookies = document.cookie.split(';');
5+
for (var i = 0; i < cookies.length; i++) {
6+
var cookie = cookies[i].trim();
7+
// Does this cookie string begin with the name we want?
8+
if (cookie.substring(0, name.length + 1) == (name + '=')) {
9+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
10+
break;
11+
}
12+
}
13+
}
14+
return cookieValue;
15+
}
16+
17+
var csrftoken = getCookie('csrftoken');
18+
19+
export {csrftoken}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// @flow
2+
import React, {Component} from 'react';
3+
import TreeSelect from 'rc-tree-select';
4+
import 'rc-tree-select/assets/index.css';
5+
6+
class FilterableMultiSelectDropdownTree extends Component {
7+
8+
constructor(props) {
9+
super(props);
10+
11+
this.state = {disabled: props.disabled, strategy: props.strategy, data: props.data, value: props.value, placeholder: props.placeholder, callback: props.onChange};
12+
}
13+
14+
componentWillReceiveProps(nextProps) {
15+
this.setState({disabled: nextProps.disabled, strategy: nextProps.strategy, data: this.state.data, value: nextProps.value, placeholder: this.state.placeholder, callback: this.state.callback });
16+
}
17+
18+
render() {
19+
//https://github.com/react-component/tree-select
20+
return (
21+
<TreeSelect
22+
allowClear={true}
23+
disabled={this.state.disabled}
24+
dropdownStyle={{ maxHeight: 200, overflow: 'auto' }}
25+
maxTagTextLength={15}
26+
multiple={true}
27+
notFoundContent={<i>Not found</i>}
28+
onChange={this.state.callback}
29+
placeholder={<i>{this.state.placeholder}</i>}
30+
showCheckedStrategy={this.state.strategy}
31+
showSearch={true}
32+
style={{ width: '100%'}}
33+
// treeCheckable cannot be true if you want to dynamically change it
34+
// treeCheckable must be true if you want to be able to select all childs by selecting the parent
35+
treeCheckable={true}
36+
treeCheckStrictly={false}
37+
treeData={this.state.data}
38+
treeDataSimpleMode={{id: 'id', pId: 'pId', rootPId: 0}}
39+
treeDefaultExpandAll={false}
40+
treeIcon={false}
41+
treeLine={true}
42+
treeNodeFilterProp={'label'}
43+
value={this.state.value}
44+
/>
45+
);
46+
}
47+
}
48+
49+
export default FilterableMultiSelectDropdownTree;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// @flow
2+
import React, {Component} from 'react';
3+
import TreeSelect from 'rc-tree-select';
4+
import 'rc-tree-select/assets/index.css';
5+
6+
class FilterableSingleSelectDropdownTree extends Component {
7+
8+
constructor(props) {
9+
super(props);
10+
11+
this.state = {disabled: props.disabled, data: props.data, value: props.value, placeholder: props.placeholder, callback: props.onChange};
12+
}
13+
14+
componentWillReceiveProps(nextProps) {
15+
this.setState({disabled: nextProps.disabled, data: this.state.data, value: nextProps.value, placeholder: this.state.placeholder, callback: this.state.callback });
16+
}
17+
18+
render() {
19+
//https://github.com/react-component/tree-select
20+
return (
21+
<TreeSelect
22+
allowClear={true}
23+
disabled={this.state.disabled}
24+
dropdownStyle={{ maxHeight: 200, overflow: 'auto' }}
25+
maxTagTextLength={15}
26+
multiple={false}
27+
notFoundContent={<i>Not found</i>}
28+
onChange={this.state.callback}
29+
placeholder={<i>{this.state.placeholder}</i>}
30+
showCheckedStrategy={TreeSelect.SHOW_PARENT}
31+
showSearch={true}
32+
style={{ width: '100%'}}
33+
// treeCheckable cannot be true if you want to dynamically change it
34+
// treeCheckable must be true if you want to be able to select all childs by selecting the parent
35+
treeCheckable={false}
36+
treeCheckStrictly={false}
37+
treeData={this.state.data}
38+
treeDataSimpleMode={{id: 'id', pId: 'pId', rootPId: 0}}
39+
treeDefaultExpandAll={false}
40+
treeIcon={false}
41+
treeLine={true}
42+
treeNodeFilterProp={'label'}
43+
value={this.state.value}
44+
/>
45+
);
46+
}
47+
}
48+
49+
export default FilterableSingleSelectDropdownTree;
Binary file not shown.

0 commit comments

Comments
 (0)