mirror of https://github.com/status-im/fathom.git
split-up in multiple file & basic app structure
This commit is contained in:
parent
bdcdd95d93
commit
677cb2ca63
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
static/assets/js
|
||||
static/assets/css
|
|
@ -0,0 +1,20 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/dannyvankooten/ana/core"
|
||||
"github.com/dannyvankooten/ana/api"
|
||||
)
|
||||
|
||||
|
||||
func main() {
|
||||
db := core.SetupDatabaseConnection()
|
||||
defer db.Close()
|
||||
|
||||
http.HandleFunc("/collect", api.CollectHandler)
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "./static/" + r.URL.Path[1:])
|
||||
})
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
|
@ -1,22 +1,26 @@
|
|||
package ana
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"log"
|
||||
"time"
|
||||
"github.com/mssola/user_agent"
|
||||
"github.com/dannyvankooten/ana/models"
|
||||
"github.com/dannyvankooten/ana/core"
|
||||
)
|
||||
|
||||
func collectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func CollectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("[%s] %s %s (%s)\n", time.Now(), r.Method, r.RequestURI, r.UserAgent())
|
||||
|
||||
ua := user_agent.New(r.UserAgent())
|
||||
|
||||
// abort if this is a bot.
|
||||
if ua.Bot() {
|
||||
return
|
||||
}
|
||||
|
||||
// prepare statement for inserting data
|
||||
stmt, err := db.Prepare(`INSERT INTO visits(
|
||||
stmt, err := core.DB.Prepare(`INSERT INTO visits(
|
||||
path,
|
||||
ip_address,
|
||||
referrer_url,
|
||||
|
@ -35,7 +39,7 @@ func collectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// TODO: Query DB to determine whether visitor is returning
|
||||
|
||||
q := r.URL.Query()
|
||||
visit := Visit{
|
||||
visit := models.Visit{
|
||||
Path: q.Get("p"),
|
||||
IpAddress: r.RemoteAddr,
|
||||
ReferrerUrl: q.Get("r"),
|
||||
|
@ -72,13 +76,3 @@ func collectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("Status", "200")
|
||||
}
|
||||
|
||||
func main() {
|
||||
db = connectToDatabase()
|
||||
|
||||
http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, r.URL.Path[1:])
|
||||
})
|
||||
http.HandleFunc("/collect", collectHandler)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
ReactDOM.render(
|
||||
React.createElement(
|
||||
'h1',
|
||||
null,
|
||||
'Hello, world!'
|
||||
), document.getElementById('root')
|
||||
);
|
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
(function() {
|
||||
function jsonToQueryString(json) {
|
||||
var keys = Object.keys(json);
|
||||
|
||||
// omit empty
|
||||
keys = keys.filter(function(k) {
|
||||
return json[k].length > 0;
|
||||
});
|
||||
|
||||
return '?' +
|
||||
keys.map(function(k) {
|
||||
return encodeURIComponent(k) + '=' +
|
||||
encodeURIComponent(json[k]);
|
||||
}).join('&');
|
||||
}
|
||||
|
||||
// abort hit if Do Not Track is enabled.
|
||||
// if( navigator.DonotTrack == 1 ) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
var i = document.createElement('img');
|
||||
var d = {
|
||||
l: navigator.language,
|
||||
p: location.pathname + location.search,
|
||||
sr: screen.width + "x" + screen.height,
|
||||
t: document.title,
|
||||
r: document.referrer
|
||||
};
|
||||
|
||||
|
||||
i.src = 'http://localhost:8080/collect' + jsonToQueryString(d);
|
||||
|
||||
document.body.appendChild(i);
|
||||
})();
|
|
@ -1,27 +1,26 @@
|
|||
package ana
|
||||
package core
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
_"github.com/go-sql-driver/mysql"
|
||||
"log"
|
||||
)
|
||||
|
||||
var db *sql.DB
|
||||
var DB *sql.DB
|
||||
|
||||
func connectToDatabase() *sql.DB {
|
||||
func SetupDatabaseConnection() *sql.DB {
|
||||
// setup db connection
|
||||
var err error
|
||||
db, err = sql.Open("mysql", "root:root@/ana")
|
||||
DB, err = sql.Open("mysql", "root:root@/ana")
|
||||
if err != nil {
|
||||
log.Fatal(err.Error()) // Just for example purpose. You should use proper error handling instead of panic
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Open doesn't open a connection. Validate DSN data:
|
||||
err = db.Ping()
|
||||
err = DB.Ping()
|
||||
if err != nil {
|
||||
log.Fatal(err.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
|
||||
return db
|
||||
|
||||
return DB
|
||||
}
|
35
gulpfile.js
35
gulpfile.js
|
@ -0,0 +1,35 @@
|
|||
'use strict';
|
||||
|
||||
// TODO: Minify JS
|
||||
|
||||
const babelify = require("babelify");
|
||||
const browserify = require('browserify');
|
||||
const gulp = require('gulp');
|
||||
const source = require('vinyl-source-stream');
|
||||
const buffer = require('vinyl-buffer');
|
||||
const rename = require('gulp-rename');
|
||||
const gutil = require('gulp-util');
|
||||
const sass = require('gulp-sass');
|
||||
|
||||
gulp.task('default', [ 'browserify', 'sass' ] );
|
||||
|
||||
gulp.task('browserify', function () {
|
||||
return browserify({
|
||||
entries: './assets/js/script.js',
|
||||
debug: true
|
||||
})
|
||||
.transform("babelify", {presets: ["es2015", "react"]})
|
||||
.on('error', gutil.log)
|
||||
.bundle()
|
||||
.pipe(source('script.js'))
|
||||
.pipe(buffer())
|
||||
.pipe(gulp.dest('./static/assets/js/'))
|
||||
});
|
||||
|
||||
gulp.task('sass', function () {
|
||||
var files = './assets/sass/[^_]*.scss';
|
||||
return gulp.src(files)
|
||||
.pipe(sass())
|
||||
.pipe(rename({ extname: '.css' }))
|
||||
.pipe(gulp.dest('./static/assets/css'))
|
||||
});
|
7
makefile
7
makefile
|
@ -1,4 +1,3 @@
|
|||
.PHONY: debug
|
||||
debug: tracker.go models.go
|
||||
go build
|
||||
$(GOPATH)/bin/ana
|
||||
.PHONY: bin
|
||||
bin: ana.go models/visit.go
|
||||
go install
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package ana
|
||||
package models
|
||||
|
||||
type Visit struct {
|
||||
ID int
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"browserify": "^13.1.1",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sass": "^2.3.2",
|
||||
"react": "^15.4.0",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"babelify": "^7.3.0",
|
||||
"gulp-util": "^3.0.7",
|
||||
"react-dom": "^15.4.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="no-js">
|
||||
<head>
|
||||
<script>
|
||||
document.documentElement.className = document.documentElement.className.replace('no-js', '');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="/assets/js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||
function jsonToQueryString(json) {
|
||||
var keys = Object.keys(json);
|
||||
|
||||
// omit empty
|
||||
keys = keys.filter(function(k) {
|
||||
return json[k].length > 0;
|
||||
});
|
||||
|
||||
return '?' +
|
||||
keys.map(function(k) {
|
||||
return encodeURIComponent(k) + '=' +
|
||||
encodeURIComponent(json[k]);
|
||||
}).join('&');
|
||||
}
|
||||
|
||||
// abort hit if Do Not Track is enabled.
|
||||
// if( navigator.DonotTrack == 1 ) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
var i = document.createElement('img');
|
||||
var d = {
|
||||
l: navigator.language,
|
||||
p: location.pathname + location.search,
|
||||
sr: screen.width + "x" + screen.height,
|
||||
t: document.title,
|
||||
r: document.referrer
|
||||
};
|
||||
|
||||
|
||||
i.src = 'http://localhost:8080/collect' + jsonToQueryString(d);
|
||||
|
||||
document.body.appendChild(i);
|
Loading…
Reference in New Issue