Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli client [DO NOT MERGE] #65

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
node_modules/
public/bower_components/
.vscode/
.vscode/
client/~
client/build
*.pyc
9 changes: 9 additions & 0 deletions client/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.5.2-alpine

ENV AppDir=/app
ENV AppName=


mkdir $AppDir

ENTRYPOINT ["$AppDir", ""]
7 changes: 7 additions & 0 deletions client/MANIFEST
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# file GENERATED by distutils, do NOT edit
setup.py
client\__init__.py
client\__main__.py
client\connection.py
client\dealerships.py
client\vehicles.py
3 changes: 3 additions & 0 deletions client/client/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Copyright ClusterHQ Inc. See LICENSE file for details.
__all__ = [ "client" ]

23 changes: 23 additions & 0 deletions client/client/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright ClusterHQ Inc. See LICENSE file for details.
"""
Executed with 'python -m <packageName>'.
Cannot be imported as a regular module.
"""
if __name__ != '__main__':
raise ImportError('This module cannot be imported in a Python script.')

baseurl = 'http://localhost:8000/'

import argparse #noqa
import sys #noqa

from client import connection, dealerships, vehicles

PARSER = argparse.ArgumentParser(description='Primary argument parser', prog='Specify the desired sub-command.')
SUBPARSERS = PARSER.add_subparsers()
connection.make_parser(SUBPARSERS)
dealerships.make_parser(SUBPARSERS)
vehicles.make_parser(SUBPARSERS)

args = PARSER.parse_args()
args.func(args)
49 changes: 49 additions & 0 deletions client/client/connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright ClusterHQ Inc. See LICENSE file for details.

import json
import os

### Specify the fully qualified path to the configuration file
configpath = '{}\.inventory_app.config.json'.format(os.path.expanduser('~'))
connectionVar = 'INVAPPENDPOINT'

def SetEndpoint(endpoint):
"""
Sets an environment variable to define the URI of the inventory app API
and writes the endpoint to a JSON file.
"""
file = GetConfigHandle()
file.write(json.dumps({
'endpoint': endpoint
}))
os.environ[connectionVar] = endpoint
file.close()

def GetEndpoint():
"""
Get the connection endpoint.
"""
endpoint = os.environ.get(connectionVar)
if endpoint == None:
raise "Please specify a connection endpoint."
else:
return endpoint

def GetConfigHandle():
home = os.path.expanduser('~')
return open('{0}\.inventory_app.json'.format(home), mode='w')

def make_parser(parent):
"""
Create command line parser for this module.
"""
subparser = parent.add_parser('connection')
setup_parser(subparser)
subparser.set_defaults(func=main)

def setup_parser(parser):
parser.add_argument('--endpoint', help='The prefix of the endpoint (eg. https://localhost:8000)')

def main(args):
print("Called main in connection")
SetEndpoint(args.endpoint)
34 changes: 34 additions & 0 deletions client/client/dealerships.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright ClusterHQ Inc. See LICENSE file for details.

import requests
import argparse
from . import connection

def AddDealership(name, phone, address):
print("Creating a new dealership, name: {name}, phone: {phone}, address: {address}".format(name=name, phone=phone, address=address))
method = '{}/dealerships'.format(connection.GetEndpoint())
requests.post(method, data={
'name': name,
'phone': phone,
'addr': address
})

def make_parser(parent):
"""
Create command line parser for this module.
"""
subparser = parent.add_parser('dealerships', aliases=['dealer'])
setup_parser(subparser)
subparser.set_defaults(func=main)

def setup_parser(parser):
"""
Sets up the parameters for this module.
"""
parser.add_argument('--name', required=True, help='The name of the dealership', metavar='DealerName')
parser.add_argument('--phone', required=True, help='The phone number for the dealership', metavar='DealerPhone')
parser.add_argument('--address', required=True, help='The address of the dealership', metavar='DealerAddress')

def main(args):
print("Called main in dealerships")
AddDealership(args.name, args.phone, args.address)
21 changes: 21 additions & 0 deletions client/client/vehicles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright ClusterHQ Inc. See LICENSE file for details.

import json
import requests

def AddVehicle(manufacturer, model, year):
print("Adding a new vehicle")

def make_parser(parent):
"""
Create command line parser for this module.
"""
subparser = parent.add_parser('vehicles')
setup_parser(subparser)
subparser.set_defaults(func=main)

def setup_parser(parser):
parser.add_argument('--manufacturer', required=True)

def main():
print("Called main in vehicles")
5 changes: 5 additions & 0 deletions client/launch.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Create Python Virtual Environment and change context into it
$VirtualEnvPath = "$env:USERPROFILE\pyclient"
virtualenv "$VirtualEnvPath"
& $VirtualEnvPath\scripts\activate.ps1

15 changes: 15 additions & 0 deletions client/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python

### Documentation for setup.py can be found here: https://docs.python.org/3.5/distutils/setupscript.html

from distutils.core import setup

setup(name='InventoryAppClient',
version='1.0',
description='A command line client companion for the ClusterHQ Inventory Application sample app.',
author='Trevor Sullivan, Ryan Wallner',
author_email='[email protected], [email protected]',
url='https://github.com/clusterhq/inventory-app',
packages=['client'],
)

36 changes: 36 additions & 0 deletions docker-compose.localdev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This Docker Compose file is used for local development work.
# It contains static port mappings, to make the services easily accessible to developers.

version: '2'

volumes:
rethink-data:
driver: local

services:
db:
networks:
- net
image: rethinkdb
volumes:
- rethink-data:/data
ports:
- 28015
- 29015
- '8080:8080'
frontend:
networks:
- net
build: ./frontend
image: frontend
depends_on:
- db
ports:
- '8000:8000'
environment:
- DATABASE_HOST=db
- DATABASE_PORT=28015

networks:
net:
driver: bridge
30 changes: 30 additions & 0 deletions frontend/controllers/dealership.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
db = require('../db/dbutils')
rdb = require('rethinkdb')

module.exports.addDealership = function (req, res) {
console.log('Creating a new dealership');
console.log(req.body);
console.log('Dealership name is ' + req.body.name);
dbconn = db.connect();
dbconn.then(function (conn) {
rdb.table('Dealership').insert(req.body).run(conn, function(err, results){
console.log(results);
conn.close();
});
});
res.send(201, { status: 'Successful' })
}

module.exports.getDealerships = function (req, res) {
console.log('Received GET /dealerships request')
dbconn.then(function(conn) {
rdb.table('Dealership').run(conn, function(err, cursor) {
if (err) throw err;
cursor.toArray(function(err, result) {
if (err) throw err;
console.log("Sending back Dealership results");
res.send(JSON.stringify(result, null, 2));
});
});
})
}
16 changes: 16 additions & 0 deletions frontend/controllers/vehicles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
db = require('../db/dbutils')
rdb = require('rethinkdb')

module.exports.getVehicles = function (req, res) {
console.log('recieved vehicles request')
dbconn.then(function(conn) {
rdb.table('Vehicle').run(conn, function(err, cursor) {
if (err) throw err;
cursor.toArray(function(err, result) {
if (err) throw err;
console.log("Sending back Vehicle results");
res.send(JSON.stringify(result, null, 2));
});
});
})
}
1 change: 1 addition & 0 deletions frontend/test/dbutils.js → frontend/db/dbutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var port = process.env.DATABASE_PORT || 28015;

// Setup the connection
exports.connect = function connect() {
console.log('Connecting to RethinkDB')
return r.connect({host: host, port: port})
}

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"rethinkdb": "2.3.3",
"request": "2.74.0",
"assert": "1.4.1",
"body-parser": "1.15.2",
"util": "0.10.3"
},
"keywords": [
Expand Down
49 changes: 9 additions & 40 deletions frontend/sc_modules/http-handler.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
r = require('rethinkdb');
db = require('../db/dbutils')
rdb = require('rethinkdb')

module.exports.attach = function (expressApp) {
// Setup HTTP/REST API for Server Side.

// Should these vars be centralized?
var host = process.env.DATABASE_HOST || '127.0.0.1';
var port = process.env.DATABASE_PORT || 28015;

// Should move this into each API request?
// using a function like `connect()` to wrap
// it made API response flaky.
// See test/dbutils.js for better version.
// TODO
var conn = null;
r.connect({host: host, port: port}, function(err, connection) {
if (err) throw err;
console.log("Connected to RethinkDB");
conn = connection;
})

// Connect to RethinkDB
dbconn = db.connect();

// Simple GET /ping for testing HTTP
expressApp.get('/ping',(req,res) => {
Expand All @@ -28,34 +15,16 @@ module.exports.attach = function (expressApp) {
})

// GET /dealerships (All Dealerships)
expressApp.get('/dealerships',(req, res) => {
console.log('recieved dealerships request')
r.table('Dealership').run(conn, function(err, cursor) {
if (err) throw err;
cursor.toArray(function(err, result) {
if (err) throw err;
console.log("Sending back Dealership results");
res.send(JSON.stringify(result, null, 2));
});
});
})
expressApp.get('/dealerships', require('../controllers/dealership.js').getDealerships)

// POST /dealerships
expressApp.post('/dealerships', require('../controllers/dealership.js').addDealership)

// GET /vehicles (All Vehicles)
expressApp.get('/vehicles',(req, res) => {
console.log('recieved vehicles request')
r.table('Vehicle').run(conn, function(err, cursor) {
if (err) throw err;
cursor.toArray(function(err, result) {
if (err) throw err;
console.log("Sending back Vehicle results");
res.send(JSON.stringify(result, null, 2));
});
});
})
expressApp.get('/vehicles', require('../controllers/vehicles.js').getVehicles)

/* TODO, remove from list when complete */

//(POST) Dealership(s)
//(POST) vehicles to Dealership(s)
//(DELETE) Remove vehicles from Dealership(s)
//(GET) A Dealership (by ID)
Expand Down
20 changes: 19 additions & 1 deletion frontend/test/test_http_dealers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
r = require('rethinkdb');
var assert = require('assert');
var request = require('request');
var db = require('./dbutils');
var db = require('../db/dbutils');
var dbConnect = db.connect();

var apihost = process.env.FRONTEND_HOST || 'localhost'
Expand Down Expand Up @@ -45,6 +45,24 @@ describe('HTTPTests for Dealerships', function() {
});
});

it('/dealerships POST should return HTTP 201 Created', function () {
request({
url: util.format('http://%s:%s/dealerships', apihost, apiport),
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
json: {
name: 'New dealer',
phone: '555-999-1122',
addr: '123 Street, City, State, ######-####'
}
}, function (err, res, body) {
if (err) throw (err);
assert.strictEqual(res.statusCode, 201)
})
})

});
/*end tests*/
});
Loading