Skip to content
This repository was archived by the owner on Apr 30, 2023. It is now read-only.
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: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/

test-results/
tmp/
routes/
23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

26 changes: 15 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
FROM node:6
FROM golang:1.13-alpine

RUN apt-get update -y && \
apt-get upgrade -y && \
apt-get install -y git GraphicsMagick
RUN apk add --no-cache git

RUN mkdir -p /app/
WORKDIR /app/
RUN mkdir -p /gopath
ENV GOPATH=/gopath
WORKDIR /gopath

RUN npm install -g node-pg-migrate pg --silent
RUN go get github.com/revel/revel && \
go get github.com/revel/cmd/revel && \
go get github.com/jinzhu/gorm && \
go get github.com/lib/pq && \
go get github.com/revel/modules/static && \
go get github.com/Jeffail/gabs && \
go get github.com/mrjones/oauth

COPY package.json .
RUN npm install
COPY . /gopath/src/github.com/criticalmaps/criticalmaps-api

COPY . .
WORKDIR /gopath/src/github.com/criticalmaps/criticalmaps-api

CMD npm start
CMD ["/gopath/bin/revel", "run"]
57 changes: 31 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
# Critical Maps API
# Welcome to Revel

[![Build Status](https://travis-ci.org/criticalmaps/criticalmaps-api.svg?branch=master)](https://travis-ci.org/criticalmaps/criticalmaps-api)
[![Code Climate](https://codeclimate.com/github/criticalmaps/criticalmaps-api/badges/gpa.svg)](https://codeclimate.com/github/criticalmaps/criticalmaps-api)
[![Test Coverage](https://codeclimate.com/github/criticalmaps/criticalmaps-api/badges/coverage.svg)](https://codeclimate.com/github/criticalmaps/criticalmaps-api/coverage)
[![Dependency Status](https://gemnasium.com/criticalmaps/criticalmaps-api.svg)](https://gemnasium.com/criticalmaps/criticalmaps-api)
A high-productivity web framework for the [Go language](http://www.golang.org/).

## Start development session with:

```docker-compose -f docker-compose.dev.yml up --build```
### Start the web server:

### Api will be available under:
http://localhost:3000
revel run myapp

### Debugger will be available at:
http://localhost:8080/?port=5858
### Go to http://localhost:9000/ and you'll see:

### phpPgAdmin is at:
http://localhost:8082/phppgadmin/
"It works"

## Migrations
## Code Layout

```
docker build -t criticalmaps-db-migrations -f Dockerfile.migrations . && \
docker run \
-v $(pwd)/migrations/:/migrations/ \
-e DATABASE_URL=postgres://bla:bla@db/criticalmaps \
criticalmaps-db-migrations \
up
```
The directory structure of a generated Revel application:

docker exec -ti $(docker ps | grep postgres | awk '{ print $1}') /bin/bash
conf/ Configuration directory
app.conf Main app configuration file
routes Routes definition file

psql -d criticalmaps -U bla
app/ App sources
init.go Interceptor registration
controllers/ App controllers go here
views/ Templates directory

## TODO
cors header??
messages/ Message files

public/ Public static assets
css/ CSS files
js/ Javascript files
images/ Image files

tests/ Test suites


## Help

* The [Getting Started with Revel](http://revel.github.io/tutorial/gettingstarted.html).
* The [Revel guides](http://revel.github.io/manual/index.html).
* The [Revel sample apps](http://revel.github.io/examples/index.html).
* The [API documentation](https://godoc.org/github.com/revel/revel).
54 changes: 0 additions & 54 deletions app.js

This file was deleted.

23 changes: 23 additions & 0 deletions app/controllers/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package controllers

import (
"errors"

"github.com/criticalmaps/criticalmaps-api/app/models"
"github.com/revel/revel"
)

type App struct {
*revel.Controller
}

func (c App) Index() revel.Result {
location := []models.Location{}

result := DB.Find(&location)
if result.Error != nil {
return c.RenderError(errors.New("Record Not Found"))
}

return c.RenderJSON(location)
}
33 changes: 33 additions & 0 deletions app/controllers/gorm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package controllers

import (
"fmt"

"github.com/criticalmaps/criticalmaps-api/app/models"
"github.com/jinzhu/gorm"
"github.com/revel/revel"
)

var DB *gorm.DB

func InitDB() {
db, err := gorm.Open("postgres",

fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
revel.Config.StringDefault("db.host", "127.0.0.1"),
revel.Config.StringDefault("db.port", "5432"),
revel.Config.StringDefault("db.username", "foo"),
revel.Config.StringDefault("db.password", "bar"),
revel.Config.StringDefault("db.database", "criticalmaps"),
))

if err != nil {
revel.AppLog.Fatal(err.Error())
}

db.DB()

db.AutoMigrate(&models.Location{})

DB = db
}
59 changes: 59 additions & 0 deletions app/controllers/locations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package controllers

import (
"errors"
"fmt"
"time"

"regexp"

"github.com/criticalmaps/criticalmaps-api/app/models"
"github.com/revel/revel"
)

type Locations struct {
App
}

func (c Locations) List() revel.Result {
location := []models.Location{}

result := DB.Find(&location)
if result.Error != nil {
return c.RenderError(errors.New("Record Not Found"))
}

return c.RenderJSON(location)
}

func (c Locations) Post() revel.Result {
receivedLocation := models.Location{}
c.Params.BindJSON(&receivedLocation)

if receivedLocation.Device == "" || receivedLocation.Latitude == "" || receivedLocation.Longitude == "" {
return c.RenderError(fmt.Errorf("required parameters were left empty"))
}

if !c.isValidCoordinateFormat(receivedLocation.Latitude, receivedLocation.Longitude) {
return c.RenderError(fmt.Errorf("coordinates are not valid: %q, %q", receivedLocation.Longitude, receivedLocation.Latitude))
}

receivedLocation.Updated = time.Now().UTC()
DB.Where(models.Location{Device: receivedLocation.Device}).Assign(receivedLocation).FirstOrCreate(&receivedLocation)

return c.RenderJSON(receivedLocation)
}

func (c Locations) isValidCoordinateFormat(latitude string, longitude string) bool {
regex := "^[-+]?[0-9]+$"

matched, err := regexp.Match(regex, []byte(latitude))
if !matched || err != nil {
return false
}
matched, err = regexp.Match(regex, []byte(longitude))
if !matched || err != nil {
return false
}
return true
}
57 changes: 57 additions & 0 deletions app/controllers/locationsarchive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package controllers

import (
"time"

"github.com/Jeffail/gabs"
"github.com/revel/revel"
)

type LocationsArchive struct {
App
}

func (c LocationsArchive) List() revel.Result {
// purge old data
DB.Exec(`DELETE FROM locations_archive
WHERE created < (NOW() - INTERVAL '48 HOURS')`)

startEpoch := c.Params.Query.Get("start")
endEpoch := c.Params.Query.Get("end")

// retrieve archived data
rows, err := DB.Raw(`SELECT device, created, longitude, latitude
FROM locations_archive
WHERE
created BETWEEN TO_TIMESTAMP(?) AND TO_TIMESTAMP(?)`, startEpoch, endEpoch).Rows()

if err != nil {
return c.RenderError(err)
}

jsonObj := gabs.New()

defer rows.Close()
for rows.Next() {
var device string
var created time.Time
var longitude string
var latitude string

rows.Scan(&device, &created, &longitude, &latitude)

if !jsonObj.Exists(device) {
jsonObj.Array(device)
}

location := gabs.New()

location.Set(created.Unix(), "created")
location.Set(latitude, "latitude")
location.Set(longitude, "longitude")

jsonObj.ArrayAppend(location.Data(), device)
}

return c.RenderJSON(jsonObj.Data())
}
Loading