Ma Suhyeon

Implement two more APIs

...@@ -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 }
......
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=
......
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 +}