Skip to content
This repository has been archived by the owner on Feb 16, 2022. It is now read-only.

Commit

Permalink
Restructure (#55)
Browse files Browse the repository at this point in the history
Restructure the whole repo into smaller, testable sub packages.
  • Loading branch information
kochman committed Jul 12, 2017
1 parent bb73954 commit aad60fe
Show file tree
Hide file tree
Showing 32 changed files with 1,497 additions and 1,204 deletions.
5 changes: 5 additions & 0 deletions .codecov.yaml
@@ -0,0 +1,5 @@
comment: false
coverage:
status:
patch: false
project: false
8 changes: 2 additions & 6 deletions .gitignore
@@ -1,9 +1,5 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'

bower_components
conf.json
*.swp
/vendor/*/
/coverage.txt
15 changes: 15 additions & 0 deletions .travis.yml
@@ -0,0 +1,15 @@
language: go

go:
- 1.8.x
- tip

before_install:
- go get -u github.com/kardianos/govendor
- govendor sync

script:
- ./test.sh

after_success:
- bash <(curl -s https://codecov.io/bash)
16 changes: 8 additions & 8 deletions Dockerfile
Expand Up @@ -13,19 +13,19 @@ RUN ln -s /usr/bin/nodejs /usr/bin/node
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH

RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
WORKDIR $GOPATH/src/shuttle_tracking_2
RUN mkdir -p "$GOPATH/src/github.com/wtg/shuttletracker" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
WORKDIR $GOPATH/src/github.com/wtg/shuttletracker
RUN go get -u github.com/kardianos/govendor

# ADD ./package.json /app
RUN npm install -g bower


COPY ./bower.json $GOPATH/src/shuttle_tracking_2
COPY ./bower.json .
RUN bower install --allow-root

COPY . $GOPATH/src/shuttle_tracking_2
COPY . .

RUN go get
RUN go build
RUN govendor sync
RUN go build -o shuttletracker

CMD ["shuttle_tracking_2"]
CMD ["./shuttletracker"]
54 changes: 24 additions & 30 deletions README.md
@@ -1,34 +1,28 @@
Shuttle Tracking v2
===================
Shuttle Tracker [![Build Status](https://travis-ci.org/wtg/shuttletracker.svg?branch=master)](https://travis-ci.org/wtg/shuttletracker)&nbsp;[![codecov](https://codecov.io/gh/wtg/shuttletracker/branch/master/graph/badge.svg)](https://codecov.io/gh/wtg/shuttletracker)&nbsp;[![GoDoc](https://godoc.org/github.com/wtg/shuttletracker?status.svg)](https://godoc.org/github.com/wtg/shuttletracker)&nbsp;[![Go Report Card](https://goreportcard.com/badge/github.com/wtg/shuttletracker)](https://goreportcard.com/report/github.com/wtg/shuttletracker)
===============

Remaking the original [Shuttle Tracker](https://github.com/wtg/shuttle_tracking) using [Go](https://golang.org/), [Polymer Web Components](https://www.polymer-project.org/), and [MongoDB](https://www.mongodb.org/).
Tracking and mapping RPI's shuttles with [Go](https://golang.org/), [Polymer Web Components](https://www.polymer-project.org/), and [MongoDB](https://www.mongodb.org/).

Setting Up
-----------------
1. Clone this repository using `git clone https://github.com/wtg/shuttle_tracking_2`
* Make sure the repository is cloned to a parent directory named `src`
2. Make sure you have npm, bower, golang and mongodb installed
* On Debian-based linux, run `sudo apt-get install nodejs npm golang mongodb` to install npm and go language packages
* On CentOs run `sudo yum install nodejs npm golang mongodb` instead
* Run `sudo npm install -g bower` to install bower
3. Run `bower install` inside shuttle tracking directory to install dependencies listed in bower.json
4. Rename conf.json.sample to conf.json
5. Edit conf.json with the following:
* Data Feed: API with tracking information, this is a unique API info url that we can get data from it. Since it is private, we will only put this on our private group for now (Slacks).
* UpdateInterval: Number of seconds between each request to the data feed
* MongoUrl: Url where MongoDB is located
* MongoPort: Port where MongoDB is bound (default is 27017)
3. Change your gopath to the parent directory or src directory listed on step 1 using `export GOPATH="path-to-directory"`
4. Run `bower install` inside shuttle tracking directory to install dependencies listed in bower.json
5. Run `./goget` (script provided) to install additional dependencies
6. Rename conf.json.sample to conf.json and edit with the following:
* Data Feed: API with tracking information (iTrak in our case), if using the dummy server, http://localhost:8081
* UpdateInterval: Number of seconds between each request to the data feed
* MongoUrl: Url where MongoDB is located
* MongoPort: Port where MongoDB is bound (default is 27017)
7. Run the app using `go run main.go` in the project root directory
8. Visit http://localhost:8080/ to view the tracking application and http://localhost:8080/admin to view the admin panel
Check it out in action at [shuttles.rpi.edu](https://shuttles.rpi.edu).

More Information
Setting Up
-----------------
For more information please visit the [Wiki page](https://github.com/KeyboardNerd/shuttle_tracking_2/wiki).
1. Install Go
2. `go get github.com/wtg/shuttletracker`
3. `govendor sync`
4. Make sure you have npm, bower, golang and mongodb installed
5. Run `bower install` inside shuttle tracking directory to install dependencies listed in bower.json
6. Rename conf.json.sample to conf.json
7. Edit conf.json with the following:
* Data Feed: API with tracking information, this is a unique API info url that we can get data from it. Since it is private, we will only put this on our private group for now (Slacks).
* UpdateInterval: Number of seconds between each request to the data feed
* MongoUrl: Url where MongoDB is located
* MongoPort: Port where MongoDB is bound (default is 27017)
9. Run `bower install` inside shuttle tracking directory to install dependencies listed in bower.json
10. Rename conf.json.sample to conf.json and edit with the following:
* Data Feed: API with tracking information (iTrak in our case), if using the dummy server, http://localhost:8081
* UpdateInterval: Number of seconds between each request to the data feed
* MongoUrl: Url where MongoDB is located
* MongoPort: Port where MongoDB is bound (default is 27017)
11. Run the app using `go run main.go` in the project root directory
12. Visit http://localhost:8080/ to view the tracking application and http://localhost:8080/admin to view the admin panel
176 changes: 176 additions & 0 deletions api/api.go
@@ -0,0 +1,176 @@
package api

import (
"encoding/json"
"net/http"
"net/url"

"github.com/wtg/shuttletracker/database"
"github.com/wtg/shuttletracker/log"

"fmt"
"github.com/gorilla/mux"
"gopkg.in/cas.v1"
"gopkg.in/mgo.v2/bson"
"strings"
)

// Configuration holds the settings for connecting to outside resources.
type Config struct {
GoogleMapAPIKey string
GoogleMapMinDistance int
CasURL string `env:"CAS_URL"`
Authenticate bool `env:"AUTHENTICATE" envDefault:"true"`
ListenURL string
}

// App holds references to Mongo resources.
type API struct {
cfg Config
CasAUTH *cas.Client
CasMEM *cas.MemoryStore
db database.Database
handler http.Handler
}

// InitApp initializes the application given a config and connects to backends.
// It also seeds any needed information to the database.
func New(cfg Config, db database.Database) (*API, error) {
// Set up CAS authentication
url, err := url.Parse(cfg.CasURL)
if err != nil {
return nil, err
}
var tickets *cas.MemoryStore

client := cas.NewClient(&cas.Options{
URL: url,
Store: nil,
})

// Create API instance to store database session and collections
api := API{
cfg: cfg,
CasAUTH: client,
CasMEM: tickets,
db: db,
}

r := mux.NewRouter()

// Public
r.HandleFunc("/vehicles", api.VehiclesHandler).Methods("GET")
r.HandleFunc("/updates", api.UpdatesHandler).Methods("GET")
r.HandleFunc("/updates/message", api.UpdateMessageHandler).Methods("GET")
r.HandleFunc("/routes", api.RoutesHandler).Methods("GET")
r.HandleFunc("/stops", api.StopsHandler).Methods("GET")

// Admin
r.Handle("/admin/", api.CasAUTH.HandleFunc(api.AdminHandler)).Methods("GET")
r.Handle("/admin", api.CasAUTH.HandleFunc(api.AdminHandler)).Methods("GET")
r.Handle("/admin/success/", api.CasAUTH.HandleFunc(api.AdminPageServer)).Methods("GET")
r.Handle("/admin/success", api.CasAUTH.HandleFunc(api.AdminPageServer)).Methods("GET")
r.Handle("/admin/logout/", api.CasAUTH.HandleFunc(api.AdminLogout)).Methods("GET")
r.Handle("/admin/logout", api.CasAUTH.HandleFunc(api.AdminLogout)).Methods("GET")
r.Handle("/vehicles/create", api.CasAUTH.HandleFunc(api.VehiclesCreateHandler)).Methods("POST")
r.Handle("/vehicles/edit", api.CasAUTH.HandleFunc(api.VehiclesEditHandler)).Methods("POST")
r.Handle("/vehicles/{id:[0-9]+}", api.CasAUTH.HandleFunc(api.VehiclesDeleteHandler)).Methods("DELETE")
r.Handle("/routes/create", api.CasAUTH.HandleFunc(api.RoutesCreateHandler)).Methods("POST")
r.Handle("/routes/{id:.+}", api.CasAUTH.HandleFunc(api.RoutesDeleteHandler)).Methods("DELETE")
r.Handle("/stops/create", api.CasAUTH.HandleFunc(api.StopsCreateHandler)).Methods("POST")
r.Handle("/stops/{id:.+}", api.CasAUTH.HandleFunc(api.StopsDeleteHandler)).Methods("DELETE")
//r.HandleFunc("/import", api.ImportHandler).Methods("GET")

// Legacy routes to support the ancient iOS app
r.HandleFunc("/vehicles/current.js", api.LegacyVehiclesHandler).Methods("GET")
r.HandleFunc("/displays/netlink.js", api.LegacyRoutesHandler).Methods("GET")

// Static files
r.HandleFunc("/", IndexHandler).Methods("GET")
r.PathPrefix("/bower_components/").Handler(http.StripPrefix("/bower_components/", http.FileServer(http.Dir("bower_components/"))))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static/"))))

// Serve requests
hand := api.CasAUTH.Handle(r)
api.handler = hand

return &api, nil
}

func NewConfig() *Config {
return &Config{ListenURL: "localhost:8080"}
}

func (api *API) Run() {
if err := http.ListenAndServe(api.cfg.ListenURL, api.handler); err != nil {
log.WithError(err).Error("Unable to serve.")
}
}

// IndexHandler serves the index page.
func IndexHandler(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
}

type User struct {
Name string
}

// AdminHandler serves the admin page.
func (api *API) AdminHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%u", api.cfg.Authenticate)
if api.cfg.Authenticate && !cas.IsAuthenticated(r) {
cas.RedirectToLogin(w, r)
return
} else {
valid := false
var users []User
api.db.Users.Find(bson.M{}).All(&users)
for _, u := range users {
if u.Name == strings.ToLower(cas.Username(r)) {
valid = true
}
}
if api.cfg.Authenticate == false {
valid = true
fmt.Printf("not authenticating")
}
if valid {
http.Redirect(w, r, "/admin/success/", 301)
} else {
http.Redirect(w, r, "/admin/logout/", 301)
}
}

}

func (api *API) AdminPageServer(w http.ResponseWriter, r *http.Request) {

if api.cfg.Authenticate && !cas.IsAuthenticated(r) {
http.Redirect(w, r, "/admin/", 301)
return
} else {
http.ServeFile(w, r, "admin.html")
}

}

func (api *API) AdminLogout(w http.ResponseWriter, r *http.Request) {

if cas.IsAuthenticated(r) {
cas.RedirectToLogout(w, r)
}

}

// WriteJSON writes the data as JSON.
func WriteJSON(w http.ResponseWriter, data interface{}) error {
w.Header().Set("Content-Type", "application/json")
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return err
}
w.Write(b)
return nil
}

0 comments on commit aad60fe

Please sign in to comment.