diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/go-location-logger.iml b/.idea/go-location-logger.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/go-location-logger.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..703fe63
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..aff40c1
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,22 @@
+# Use an official Golang runtime as a parent image
+FROM golang:1.21.4
+
+# Set the working directory in the container
+WORKDIR /go/src/app
+
+# Copy the local package files to the container's workspace
+COPY ../../Downloads .
+
+# Download and install any required third-party dependencies into the container.
+#RUN go get -u github.com/gorilla/mux
+RUN go get -u github.com/go-sql-driver/mysql
+RUN go get -u github.com/sirupsen/logrus
+
+# Build the Go application
+RUN go build -o main .
+
+# Expose port 8080 to the outside world
+EXPOSE 8080
+
+# Command to run the application with environment variables
+CMD ["./main"]
diff --git a/README.md b/README.md
index c8e1416..58a30ad 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,98 @@
-# go-location-logger
+# Go Location Logger
+A simple Go program that handles location data sent via HTTP POST requests and inserts it into a MySQL database.
+
+## Features
+
+- Handles JSON payloads containing location data.
+- Inserts location data into a MySQL database.
+- Supports parameters `device` and `user` in HTTP requests.
+
+## Prerequisites
+
+Before running the program, ensure you have the following:
+
+- Go installed: [https://golang.org/doc/install](https://golang.org/doc/install)
+- Docker and Docker Compose installed: [https://docs.docker.com/get-docker/](https://docs.docker.com/get-docker/)
+
+## Installation
+
+1. Clone the repository:
+
+ ```bash
+ git clone https://github.com/yourusername/go-location-logger.git
+ ```
+
+2. Navigate to the project directory:
+
+ ```bash
+ cd go-location-logger
+ ```
+
+3. Install dependencies:
+
+ ```bash
+ go get -u github.com/sirupsen/logrus
+ ```
+
+4. Create an `.env` file in the project root with your environment variables:
+
+ ```plaintext
+ # .env
+
+ DB_USER=your_db_user
+ DB_PASSWORD=your_db_password
+ DB_HOST=your_db_host
+ DB_PORT=your_db_port
+ DB_NAME=your_db_name
+ ```
+
+## Usage
+
+### Running with Docker Compose
+
+1. Create a Docker network:
+
+ ```bash
+ docker network create app-network
+ ```
+
+2. Use Docker Compose to start the services:
+
+ ```bash
+ docker-compose up -d
+ ```
+
+3. Access your Go application at `http://localhost:8080`. Make HTTP POST requests as described in the README.md.
+
+4. To stop the services, run:
+
+ ```bash
+ docker-compose down
+ ```
+
+### Running without Docker
+
+If you prefer not to use Docker, you can run the Go application directly using:
+
+```bash
+go run main.go
+```
+
+The server will start on `http://localhost:8080`.
+
+Make a POST request with a JSON payload to `http://localhost:8080/?device=your_device&user=your_user`. The JSON payload should include location data.
+
+Example:
+
+```bash
+curl -X POST -d '{"_type": "location", "tst": 1637650367, "lat": 37.7749, "lon": -122.4194, "tid": "123", "batt": 90, "vac": 220}' http://localhost:8080/?device=your_device&user=your_user
+```
+
+## Contributing
+
+Feel free to open issues or submit pull requests.
+
+## License
+
+This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..74892dc
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,34 @@
+version: "3.9"
+
+services:
+
+# Go application service
+ go-app:
+ build:
+ context: go/.
+ args:
+ - GO111MODULE=on
+ ports:
+ - "8080:8080"
+ depends_on:
+ - db
+ environment:
+ - DB_HOST=db
+ - DB_PORT=3306
+ - DB_USER=root
+ - DB_PASSWORD=owntracks
+ - DB_NAME=owntracks
+
+ restart: always
+ networks:
+ default:
+
+ db:
+ image: mariadb
+ volumes:
+ - ./mysql-data:/var/lib/mysql
+ environment:
+ MYSQL_ROOT_PASSWORD: owntracks
+ MYSQL_DATABASE: owntracks
+ networks:
+ default:
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..119d48a
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,10 @@
+module go-app
+
+go 1.21.4
+
+require (
+ github.com/go-sql-driver/mysql v1.7.1
+ github.com/sirupsen/logrus v1.9.3
+)
+
+require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..05471c9
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,17 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
+github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..50fa232
--- /dev/null
+++ b/main.go
@@ -0,0 +1,110 @@
+package main
+
+import (
+ "database/sql"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "os"
+ "time"
+
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/sirupsen/logrus"
+)
+
+var log = logrus.New()
+
+// Location represents the JSON payload structure
+type Location struct {
+ Type string `json:"_type"`
+ Tst int64 `json:"tst"`
+ Lat float64 `json:"lat"`
+ Lon float64 `json:"lon"`
+ Tid string `json:"tid"`
+ Batt int `json:"batt"`
+ Vac int `json:"vac"`
+}
+
+func init() {
+ // Log as JSON instead of the default ASCII formatter.
+ log.SetFormatter(&logrus.JSONFormatter{})
+
+ // Output to stdout instead of the default stderr
+ // Can be any io.Writer, see below for File example
+ log.SetOutput(os.Stdout)
+
+ // Only log the warning severity or above.
+ log.SetLevel(logrus.InfoLevel)
+}
+
+func main() {
+ log.Info("Server started. Listening on :8080")
+
+ http.HandleFunc("/", handleRequest)
+ http.ListenAndServe(":8080", nil)
+}
+
+func handleRequest(w http.ResponseWriter, r *http.Request) {
+ log.Info("Handling request")
+
+ if r.Method != http.MethodPost {
+ log.Warn("Method not allowed")
+ http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+ return
+ }
+
+ // Parse query parameters
+ device := r.URL.Query().Get("d")
+ user := r.URL.Query().Get("u")
+
+ log.Infof("Received request with device=%s and user=%s", device, user)
+
+ var loc Location
+ decoder := json.NewDecoder(r.Body)
+ err := decoder.Decode(&loc)
+ if err != nil {
+ log.Error("Invalid JSON payload: ", err)
+ http.Error(w, "Invalid JSON payload", http.StatusBadRequest)
+ return
+ }
+
+ log.Infof("Received JSON payload: %+v", loc)
+
+ if loc.Type == "location" {
+ db, err := sql.Open("mysql", getDBConnectionString())
+ if err != nil {
+ log.Error("Database connection error: ", err)
+ http.Error(w, fmt.Sprintf("Database connection error: %v", err), http.StatusInternalServerError)
+ return
+ }
+ defer db.Close()
+
+ dt := time.Unix(loc.Tst, 0).Format("2006-01-02 15:04:05")
+
+ _, err = db.Exec("INSERT INTO locations (dt, tid, lat, lon, batt, vac, device, user) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
+ dt, loc.Tid, loc.Lat, loc.Lon, loc.Batt, loc.Vac, device, user)
+ if err != nil {
+ log.Error("Database insertion error: ", err)
+ http.Error(w, fmt.Sprintf("Database insertion error: %v", err), http.StatusInternalServerError)
+ return
+ }
+
+ log.Info("Location data inserted into the database")
+ }
+
+ response := make(map[string]interface{})
+ // Optionally add objects to return to the app (e.g., friends or cards)
+ json.NewEncoder(w).Encode(response)
+
+ log.Info("Request handled successfully")
+}
+
+func getDBConnectionString() string {
+ user := os.Getenv("DB_USER")
+ password := os.Getenv("DB_PASSWORD")
+ host := os.Getenv("DB_HOST")
+ port := os.Getenv("DB_PORT")
+ dbName := os.Getenv("DB_NAME")
+
+ return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", user, password, host, port, dbName)
+}