Skip to content

Commit

Permalink
Merge pull request #331 from hackforla/dev
Browse files Browse the repository at this point in the history
Update master with latest dev version
  • Loading branch information
brodly authored Mar 1, 2020
2 parents 8ee3486 + d8b3df1 commit a3fb483
Show file tree
Hide file tree
Showing 49 changed files with 1,246 additions and 171 deletions.
12 changes: 11 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,23 @@ module.exports = {
ecmaVersion: 2018,
sourceType: 'module',
},
settings: {
"import/extensions": [
".js",
".jsx"
],
'import/resolver': {
webpack: "webpack.config.js",
},
},
plugins: [
'react',
'react-hooks'
],
rules: {
'linebreak-style': 'off',
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
"react-hooks/exhaustive-deps": "warn",
"arrow-parens": ["error", "as-needed"]
},
};
1 change: 1 addition & 0 deletions .example.env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
REACT_APP_MAPBOX_TOKEN=REDACTED
DB_URL=REDACTED
14 changes: 14 additions & 0 deletions .github/ISSUE_TEMPLATE/blank-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: Blank Issue
about: Describe this issue's purpose here
title: ''
labels: ''
assignees: ''

---

#Description

## Action Items

## Resources
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Describe a new feature for the project
title: "[FEAT]"
labels: ''
assignees: ''

---

### Overview
REPLACE THIS TEXT -General overview of the feature

### Action Items
REPLACE THIS TEXT -If the issue has already been researched, and the course of action is clear, this will describe the steps. However, if the steps can be divided into tasks for more than one person, we recommend dividing it up into separate issues, or assigning it as a pair programming task.

### Resources/Instructions
REPLACE THIS TEXT -If there is a website which has documentation that helps with this issue provide the link(s) here.
62 changes: 62 additions & 0 deletions .github/ISSUE_TEMPLATE/new-backend-service-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: New Backend Service request
about: Describe the inputs and outputs of a frontend request to the backend
title: "[Service] Enter service name here"
labels: backend
assignees: ''

---

# Description
Describe the new service purpose here

## Endpoint
Check or uncheck the supported methods
Accepted methods
- [ ] GET
- [ ] POST

Path: ```server:port/{ENTER PATH HERE}```

## Inputs
Describe a quick overview of the inputs here
**Use JSON code flags to describe the json payload**
```json
{
"startDate":"2015-01-01",
"endDate":"2015-12-31",
"ncList": ["SUNLAND-TUJUNGA NC"],
"requestTypes":["Homeless Encampment"]
}
```
## Outputs
Describe a quick overview of the expected outputs here
**Use JSON code flags to describe the json payload**
```json
{
"lastPulled": "NOW",
"data": [
{
"ncname": "SUNLAND-TUJUNGA NC",
"requesttype": "Homeless Encampment",
"srnumber": "1-79371671",
"latitude": 34.2500573562,
"longitude": -118.285967224,
"address": "TUJUNGA CANYON BLVD AT PINEWOOD AVE, 91042",
"createddate": 1449835131
},
{
"ncname": "SUNLAND-TUJUNGA NC",
"requesttype": "Homeless Encampment",
"srnumber": "1-75982851",
"latitude": 34.2480072639,
"longitude": -118.285966934,
"address": "PINEWOOD AVE AT FOOTHILL BLVD, 91042",
"createddate": 1449245408
},
]
}
```

**Additional context**
Add any other context about the feature request here.
23 changes: 23 additions & 0 deletions bin/checkEnv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

// verifies that the .env file contains all the keys in .example.env

const fs = require('fs');
const dotenv = require('dotenv');

function getKeys(fileName) {
try {
return Object.keys(dotenv.parse(fs.readFileSync(fileName)));
} catch {
console.log(`Your ${fileName} file does not exist or is incorrectly formatted.\n`);
process.exit(1);
}
}

const envKeys = getKeys('.env'),
exampleKeys = getKeys('.example.env'),
missingKeys = exampleKeys.filter(key => !envKeys.includes(key));

if (missingKeys.length > 0) {
console.error('You are missing these keys in your .env file:', missingKeys, '\n');
process.exit(1);
}
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
"bulma": "^0.8.0",
"bulma-checkradio": "^1.1.1",
"bulma-switch": "^2.0.0",
"chart.js": "^2.9.3",
"chartjs-chart-box-and-violin-plot": "^2.2.0",
"classnames": "^2.2.6",
"dataframe-js": "^1.4.3",
"dotenv": "^8.2.0",
"dotenv-webpack": "^1.7.0",
"eslint-import-resolver-webpack": "^0.12.1",
"gh-pages": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"jest": "^24.9.0",
Expand All @@ -30,16 +34,19 @@
"redux": "^4.0.4",
"redux-devtools-extension": "^2.13.8",
"redux-logger": "^3.0.6",
"redux-saga": "^1.1.3",
"regenerator-runtime": "^0.13.3",
"webpack-merge": "^4.2.2"
},
"scripts": {
"start": "npm run dev",
"start": "npm run check-env && npm run dev",
"dev": "webpack-dev-server --config webpack.dev.js --host 0.0.0.0",
"build": "webpack --config webpack.prod.js",
"lint": "eslint src/**/*.js*",
"lint": "eslint 'src/**/*.js*'",
"test": "jest --passWithNoTests",
"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
"deploy": "gh-pages -d dist",
"check-env": "node ./bin/checkEnv"
},
"devDependencies": {
"@babel/core": "^7.8.4",
Expand Down
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" style="overflow: hidden;">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand Down
5 changes: 3 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
const express = require('express');
const path = require('path');

const port = process.env.PORT || 3000;
const app = express();

// the __dirname is the current directory from where the script is running
app.use(express.static(__dirname + '/dist'));
app.use(express.static(path.join(__dirname, '/dist')));

// send the user to index html page inspite of the url
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'public/index.html'));
});

console.log(`Listening on port ${port}`)
console.log(`Listening on port ${port}`);
app.listen(port);
1 change: 1 addition & 0 deletions server/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ requests-async==0.5.0
rfc3986==1.3.2
sanic==19.9.0
Sanic-Cors==0.10.0.post3
sanic-gzip==0.3.0
Sanic-Plugins-Framework==0.9.2
six==1.14.0
sodapy==2.0.0
Expand Down
20 changes: 20 additions & 0 deletions server/src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from sanic import Sanic
from sanic.response import json
from sanic_cors import CORS
from sanic_gzip import Compress
from configparser import ConfigParser
from threading import Timer
from datetime import datetime
Expand All @@ -10,11 +11,13 @@
from services.time_to_close import time_to_close
from services.frequency import frequency
from services.pinService import PinService
from services.requestDetailService import RequestDetailService
from services.ingress_service import ingress_service
from services.sqlIngest import DataHandler

app = Sanic(__name__)
CORS(app)
compress = Compress()


def configure_app():
Expand All @@ -31,11 +34,13 @@ def configure_app():


@app.route('/')
@compress.compress()
async def index(request):
return json('You hit the index')


@app.route('/timetoclose')
@compress.compress()
async def timetoclose(request):
ttc_worker = time_to_close(app.config['Settings'])

Expand All @@ -50,6 +55,7 @@ async def timetoclose(request):


@app.route('/requestfrequency')
@compress.compress()
async def requestfrequency(request):
freq_worker = frequency(app.config['Settings'])

Expand All @@ -61,13 +67,15 @@ async def requestfrequency(request):


@app.route('/sample-data')
@compress.compress()
async def sample_route(request):
sample_dataset = {'cool_key': ['value1', 'value2'],
app.config['REDACTED']: app.config['REDACTED']}
return json(sample_dataset)


@app.route('/ingest', methods=["POST"])
@compress.compress()
async def ingest(request):
"""Accept POST requests with a list of years to import.
Query parameter name is 'years', and parameter value is
Expand All @@ -89,20 +97,23 @@ async def ingest(request):


@app.route('/update')
@compress.compress()
async def update(request):
ingress_worker = ingress_service()
return_data = ingress_worker.update()
return json(return_data)


@app.route('/delete')
@compress.compress()
async def delete(request):
ingress_worker = ingress_service()
return_data = ingress_worker.delete()
return json(return_data)


@app.route('/pins', methods=["POST"])
@compress.compress()
async def pinMap(request):
pin_worker = PinService(app.config['Settings'])
postArgs = request.json
Expand All @@ -118,7 +129,16 @@ async def pinMap(request):
return json(return_data)


@app.route('/servicerequest/<srnumber>', methods=["GET"])
async def requestDetails(request, srnumber):
detail_worker = RequestDetailService(app.config['Settings'])

return_data = await detail_worker.get_request_detail(srnumber)
return json(return_data)


@app.route('/test_multiple_workers')
@compress.compress()
async def test_multiple_workers(request):
Timer(10.0, print, ["Timer Test."]).start()
return json("Done")
Expand Down
12 changes: 8 additions & 4 deletions server/src/services/dataService.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import sqlalchemy as db
import datetime
import pandas as pd
import sqlalchemy as db


class DataService(object):
def includeMeta(func):
def inner1(*args, **kwargs):
def innerFunc(*args, **kwargs):
dataResponse = func(*args, **kwargs)
if 'Error' in dataResponse:
return dataResponse

withMeta = {'lastPulled': 'NOW', 'data': dataResponse}
# Will represent last time the ingest pipeline ran
lastPulledTimestamp = datetime.datetime.utcnow()
withMeta = {'lastPulled': lastPulledTimestamp,
'data': dataResponse}
return withMeta

return inner1
return innerFunc

def __init__(self, config=None, tableName="ingest_staging_table"):
self.config = config
Expand Down
Loading

0 comments on commit a3fb483

Please sign in to comment.