Showing
11 changed files
with
175 additions
and
0 deletions
| ... | @@ -33,6 +33,11 @@ func NewApp(config Config) *App { | ... | @@ -33,6 +33,11 @@ func NewApp(config Config) *App { |
| 33 | app.router.HandleFunc("/users", app.PostUsers).Methods("POST") | 33 | app.router.HandleFunc("/users", app.PostUsers).Methods("POST") |
| 34 | app.router.HandleFunc("/users/tokens", app.PostTokens).Methods("POST") | 34 | app.router.HandleFunc("/users/tokens", app.PostTokens).Methods("POST") |
| 35 | app.router.Handle("/extractions", app.WithAuth(app.PostExtractions)).Methods("Post") | 35 | app.router.Handle("/extractions", app.WithAuth(app.PostExtractions)).Methods("Post") |
| 36 | + app.router.HandleFunc("/extractions/{file}/calls", app.GetCalls).Methods("GET") | ||
| 37 | + app.router.HandleFunc("/extractions/{file}/messages", app.GetMessages).Methods("GET") | ||
| 38 | + app.router.HandleFunc("/extractions/{file}/calls/analyses", app.GetCallsAnalyses).Methods("GET") | ||
| 39 | + app.router.HandleFunc("/extractions/{file}/apps/analyses", app.GetAppsAnalyses).Methods("GET") | ||
| 40 | + app.router.HandleFunc("/extractions/{file}/messages/analyses", app.GetMessagesAnalyses).Methods("GET") | ||
| 36 | 41 | ||
| 37 | return app | 42 | return app |
| 38 | } | 43 | } | ... | ... |
source/server/data.go
0 → 100644
| 1 | +package main | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "fmt" | ||
| 5 | + "net/http" | ||
| 6 | + "time" | ||
| 7 | + | ||
| 8 | + "github.com/gorilla/mux" | ||
| 9 | + "github.com/jmoiron/sqlx" | ||
| 10 | + | ||
| 11 | + _ "github.com/mattn/go-sqlite3" | ||
| 12 | +) | ||
| 13 | + | ||
| 14 | +type Call struct { | ||
| 15 | + ID int `json:"id" db:"id"` | ||
| 16 | + Type int `json:"type" db:"type"` | ||
| 17 | + Name *string `json:"name" db:"name"` | ||
| 18 | + Number int `json:"number" db:"number"` | ||
| 19 | + Duration int `json:"duration" db:"duration"` | ||
| 20 | + Date Time `json:"date" db:"date"` | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +func (app *App) GetCalls(w http.ResponseWriter, r *http.Request) { | ||
| 24 | + vars := mux.Vars(r) | ||
| 25 | + | ||
| 26 | + calls := []Call{} | ||
| 27 | + | ||
| 28 | + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"])) | ||
| 29 | + if err != nil { | ||
| 30 | + WriteError(w, http.StatusInternalServerError, "Could not open db file") | ||
| 31 | + return | ||
| 32 | + } | ||
| 33 | + defer db.Close() | ||
| 34 | + | ||
| 35 | + query := `SELECT * FROM calllog` | ||
| 36 | + fmt.Println(db.Select(&calls, query)) | ||
| 37 | + | ||
| 38 | + WriteJson(w, calls) | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +type CallStats struct { | ||
| 42 | + Number string `json:"number" db:"number"` | ||
| 43 | + Name *string `json:"name" db:"name"` | ||
| 44 | + Incoming int `json:"incoming" db:"incoming"` | ||
| 45 | + Outgoing int `json:"outgoing" db:"outgoing"` | ||
| 46 | + Duration int `json:"duration" db:"duration"` | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +func (app *App) GetCallsAnalyses(w http.ResponseWriter, r *http.Request) { | ||
| 50 | + vars := mux.Vars(r) | ||
| 51 | + | ||
| 52 | + calls := []CallStats{} | ||
| 53 | + | ||
| 54 | + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"])) | ||
| 55 | + if err != nil { | ||
| 56 | + WriteError(w, http.StatusInternalServerError, "Could not open db file") | ||
| 57 | + return | ||
| 58 | + } | ||
| 59 | + defer db.Close() | ||
| 60 | + | ||
| 61 | + query := `SELECT number, name, | ||
| 62 | + (SELECT COUNT(1) FROM calllog s WHERE s.number=c.number AND s.type=1) incoming, | ||
| 63 | + (SELECT COUNT(1) FROM calllog s WHERE s.number=c.number AND s.type=2) outgoing, | ||
| 64 | + SUM(duration) duration | ||
| 65 | + FROM calllog c GROUP BY number ORDER BY duration DESC` | ||
| 66 | + db.Select(&calls, query) | ||
| 67 | + | ||
| 68 | + WriteJson(w, calls) | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +type AppInfo struct { | ||
| 72 | + PackageName string `json:"package_name" db:"packagename"` | ||
| 73 | + Name string `json:"name" db:"name"` | ||
| 74 | + Version string `json:"version" db:"version"` | ||
| 75 | + WifiUsage int `json:"wifi_usage" db:"wifiusage"` | ||
| 76 | + CellularUsage int `json:"cellular_usage" db:"cellularusage"` | ||
| 77 | + LastUsed time.Time `json:"last_used" db:"lasttimeused"` | ||
| 78 | + ForegroundTime int `json:"foreground_time" db:"totaltimeforeground"` | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +func (app *App) GetAppsAnalyses(w http.ResponseWriter, r *http.Request) { | ||
| 82 | + vars := mux.Vars(r) | ||
| 83 | + | ||
| 84 | + apps := []AppInfo{} | ||
| 85 | + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"])) | ||
| 86 | + if err != nil { | ||
| 87 | + WriteError(w, http.StatusInternalServerError, "Could not open db file") | ||
| 88 | + return | ||
| 89 | + } | ||
| 90 | + defer db.Close() | ||
| 91 | + | ||
| 92 | + query := `SELECT | ||
| 93 | + a.packagename, a.name, a.version, a.wifiusage, a.cellularusage, | ||
| 94 | + u.lasttimeused, u.totaltimeforeground | ||
| 95 | + FROM AppInfo a JOIN AppUsageYear u | ||
| 96 | + ORDER BY totaltimeforeground DESC` | ||
| 97 | + db.Select(&apps, query) | ||
| 98 | + | ||
| 99 | + WriteJson(w, apps) | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +type Message struct { | ||
| 103 | + ID int `json:"id" db:"mid"` | ||
| 104 | + Type int `json:"type" db:"type"` | ||
| 105 | + Address string `json:"address"` | ||
| 106 | + Body string `json:"body"` | ||
| 107 | + Date Time `json:"date" db:"date"` | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +func (app *App) GetMessages(w http.ResponseWriter, r *http.Request) { | ||
| 111 | + vars := mux.Vars(r) | ||
| 112 | + | ||
| 113 | + messages := []Message{} | ||
| 114 | + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"])) | ||
| 115 | + if err != nil { | ||
| 116 | + WriteError(w, http.StatusInternalServerError, "Could not open db file") | ||
| 117 | + return | ||
| 118 | + } | ||
| 119 | + defer db.Close() | ||
| 120 | + | ||
| 121 | + query := `SELECT mid, type, address, body, date FROM sms` | ||
| 122 | + db.Select(&messages, query) | ||
| 123 | + | ||
| 124 | + WriteJson(w, messages) | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +type MessageStats struct { | ||
| 128 | + Address string `json:"number" db:"number"` | ||
| 129 | + Receive int `json:"incoming" db:"incoming"` | ||
| 130 | + Send int `json:"outgoing" db:"outgoing"` | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +func (app *App) GetMessagesAnalyses(w http.ResponseWriter, r *http.Request) { | ||
| 134 | + vars := mux.Vars(r) | ||
| 135 | + | ||
| 136 | + messages := []MessageStats{} | ||
| 137 | + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"])) | ||
| 138 | + if err != nil { | ||
| 139 | + WriteError(w, http.StatusInternalServerError, "Could not open db file") | ||
| 140 | + return | ||
| 141 | + } | ||
| 142 | + defer db.Close() | ||
| 143 | + | ||
| 144 | + query := `SELECT address, | ||
| 145 | + (SELECT COUNT(1) FROM sms m WHERE m.address=s.address AND m.type=1) receive, | ||
| 146 | + (SELECT COUNT(1) FROM sms m WHERE m.address=s.address AND m.type=2) send | ||
| 147 | + FROM sms s GROUP BY address ORDER BY receive + send DESC` | ||
| 148 | + db.Select(&messages, query) | ||
| 149 | + | ||
| 150 | + WriteJson(w, messages) | ||
| 151 | +} |
| ... | @@ -8,5 +8,6 @@ require ( | ... | @@ -8,5 +8,6 @@ require ( |
| 8 | github.com/google/uuid v1.1.2 | 8 | github.com/google/uuid v1.1.2 |
| 9 | github.com/gorilla/mux v1.8.0 | 9 | github.com/gorilla/mux v1.8.0 |
| 10 | github.com/jmoiron/sqlx v1.2.0 | 10 | github.com/jmoiron/sqlx v1.2.0 |
| 11 | + github.com/mattn/go-sqlite3 v1.9.0 | ||
| 11 | golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 | 12 | golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 |
| 12 | ) | 13 | ) | ... | ... |
| ... | @@ -11,6 +11,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 | ... | @@ -11,6 +11,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 |
| 11 | github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= | 11 | github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= |
| 12 | github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= | 12 | github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= |
| 13 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | 13 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= |
| 14 | +github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= | ||
| 14 | github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | 15 | github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= |
| 15 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | 16 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
| 16 | golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= | 17 | golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= | ... | ... |
source/server/types.go
0 → 100644
| 1 | +package main | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "time" | ||
| 5 | +) | ||
| 6 | + | ||
| 7 | +type Time time.Time | ||
| 8 | + | ||
| 9 | +func (t *Time) Scan(v interface{}) error { | ||
| 10 | + p, err := time.Parse("2006-01-02 15:04:05", string(v.([]byte))) | ||
| 11 | + *t = Time(p) | ||
| 12 | + return err | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +func (t *Time) MarshalJSON() ([]byte, error) { | ||
| 16 | + return time.Time(*t).MarshalJSON() | ||
| 17 | +} |
-
Please register or login to post a comment