зеркало из https://github.com/mozilla/workshop.git
Rewrite in JavaScript
This commit is contained in:
Родитель
07827ac81d
Коммит
092580eea3
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"presets": ["env"]
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
# Python
|
||||
env/
|
||||
*.pyc
|
||||
build
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
update: insecure
|
||||
search: False
|
||||
requirements:
|
||||
- requirements.txt
|
1
Procfile
1
Procfile
|
@ -1 +0,0 @@
|
|||
web: PYTHONPATH=$PYTHONPATH:lib gunicorn --reload --log-file - server:api
|
14
README.md
14
README.md
|
@ -8,12 +8,14 @@ default. When that happens, we won't need this project any more.
|
|||
|
||||
### Install
|
||||
|
||||
1. Install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)
|
||||
2. Run `python3 -m venv env`
|
||||
3. Run `source env/bin/activate`
|
||||
4. Run `pip install -r requirements.txt`
|
||||
`npm install`
|
||||
|
||||
### Run
|
||||
|
||||
1. Run `source env/bin/activate`
|
||||
3. Run `heroku local`
|
||||
#### Locally
|
||||
|
||||
`npm run local`
|
||||
|
||||
#### In production
|
||||
|
||||
`npm run start`
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "fhwr-unflattener",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node build/server",
|
||||
"build": "babel src --source-maps --minified --out-dir build",
|
||||
"postinstall": "npm run build",
|
||||
"local": "npm-run-all --parallel local:*",
|
||||
"local:build-and-watch": "babel src --watch --source-maps --out-dir build",
|
||||
"local:start-and-watch": "nodemon build/server"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-cli": "6.26.0",
|
||||
"babel-preset-env": "1.6.1",
|
||||
"decimal": "0.0.2",
|
||||
"request": "2.83.0",
|
||||
"restify": "6.3.4",
|
||||
"restify-cors-middleware": "1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "1.15.1",
|
||||
"npm-run-all": "4.1.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
]
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
falcon==1.4.1
|
||||
falcon-cors==1.1.7
|
||||
gunicorn==19.7.1
|
||||
python-mimeparse==1.6.0
|
||||
six==1.11.0
|
|
@ -1 +0,0 @@
|
|||
python-3.6.2
|
44
server.py
44
server.py
|
@ -1,44 +0,0 @@
|
|||
import falcon
|
||||
import json
|
||||
from falcon_cors import CORS
|
||||
from urllib.request import urlopen
|
||||
|
||||
|
||||
class Unflattened:
|
||||
def on_get(self, req, res):
|
||||
source_url = 'https://analysis-output.telemetry.mozilla.org/game-hardware-survey/data/hwsurvey-weekly.json'
|
||||
source_data = json.loads(urlopen(source_url).read())
|
||||
|
||||
pretransposed_data = []
|
||||
|
||||
for day in source_data:
|
||||
metrics_dict = {}
|
||||
day_dict = {'metrics': metrics_dict}
|
||||
for k, v in day.items():
|
||||
k_split = k.split('_', 1)
|
||||
if len(k_split) == 1:
|
||||
# it's metadata
|
||||
day_dict[k] = v
|
||||
else:
|
||||
# it's a metric
|
||||
metric_name = k_split[0]
|
||||
if metric_name == "cpuCoresSpeed":
|
||||
# these aren't used and are janky
|
||||
continue
|
||||
bucket_name = k_split[1]
|
||||
metric_dict = metrics_dict.get(metric_name, None)
|
||||
if metric_dict is None:
|
||||
metric_dict = dict()
|
||||
metrics_dict[metric_name] = metric_dict
|
||||
metric_dict[bucket_name] = v
|
||||
pretransposed_data.append(day_dict)
|
||||
|
||||
res.media = { "data": pretransposed_data }
|
||||
|
||||
cors = CORS(allow_all_origins=True,
|
||||
allow_all_headers=True,
|
||||
allow_methods_list=['GET'])
|
||||
api = falcon.API(middleware=[cors.middleware])
|
||||
|
||||
# Routes
|
||||
api.add_route('/', Unflattened())
|
|
@ -0,0 +1,29 @@
|
|||
import restify from 'restify';
|
||||
import restifyCORSMiddleware from 'restify-cors-middleware';
|
||||
|
||||
import unflatten from './unflatten';
|
||||
|
||||
|
||||
const server = restify.createServer();
|
||||
const port = process.env.PORT || 8000;
|
||||
|
||||
function respond(req, res, next) {
|
||||
unflatten('https://analysis-output.telemetry.mozilla.org/game-hardware-survey/data/hwsurvey-weekly.json', output => {
|
||||
res.send(output);
|
||||
});
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
const cors = restifyCORSMiddleware({
|
||||
origins: ['*'],
|
||||
});
|
||||
|
||||
server.pre(cors.preflight);
|
||||
server.pre(cors.actual);
|
||||
|
||||
server.get('/', respond);
|
||||
|
||||
server.listen(port, function() {
|
||||
console.log('%s listening at %s', server.name, server.url);
|
||||
});
|
|
@ -0,0 +1,55 @@
|
|||
import request from 'request';
|
||||
import decimal from 'decimal';
|
||||
|
||||
|
||||
export default (sourceURL, callback) => {
|
||||
request(sourceURL, (error, response, body) => {
|
||||
if (error) {
|
||||
return callback({
|
||||
error: 'Cannot fetch ' + source,
|
||||
});
|
||||
}
|
||||
|
||||
const output = {
|
||||
'data': [],
|
||||
};
|
||||
|
||||
const sourceData = JSON.parse(body);
|
||||
|
||||
sourceData.forEach((day, index) => {
|
||||
const metrics = {};
|
||||
const entry = { metrics };
|
||||
|
||||
Object.keys(day).forEach(key => {
|
||||
const value = sourceData[index][key];
|
||||
const split = key.split(/_(.+)/);
|
||||
|
||||
// It's metadata
|
||||
if (split.length === 1) {
|
||||
entry[key] = value;
|
||||
|
||||
// It's a metric
|
||||
} else {
|
||||
const newMetricName = split[0];
|
||||
|
||||
// These aren't used
|
||||
if (newMetricName === 'cpuCoresSpeed') {
|
||||
return;
|
||||
}
|
||||
|
||||
const bucketName = split[1];
|
||||
|
||||
if (metrics[newMetricName] === undefined) {
|
||||
metrics[newMetricName] = {};
|
||||
}
|
||||
|
||||
metrics[newMetricName][bucketName] = value;
|
||||
}
|
||||
});
|
||||
|
||||
output.data.push(entry);
|
||||
});
|
||||
|
||||
callback(output);
|
||||
});
|
||||
}
|
Загрузка…
Ссылка в новой задаче