mirror of
https://github.com/ddworken/hishtory.git
synced 2025-02-02 11:39:24 +01:00
Add backend code to delete entries that have already been read + start collecitng data on usage data so we can eventually prune data from users that are no longer using hishtory
This commit is contained in:
parent
f80c39f6f0
commit
a436edbd16
@ -28,6 +28,22 @@ var (
|
|||||||
ReleaseVersion string = "UNKNOWN"
|
ReleaseVersion string = "UNKNOWN"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UsageData struct {
|
||||||
|
UserId string `json:"user_id" gorm:"not null; uniqueIndex:usageDataUniqueIndex"`
|
||||||
|
DeviceId string `json:"device_id" gorm:"not null; uniqueIndex:usageDataUniqueIndex"`
|
||||||
|
LastUsed time.Time `json:"last_used"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUsageData(userId, deviceId string) {
|
||||||
|
var usageData []UsageData
|
||||||
|
GLOBAL_DB.Where("user_id = ? AND device_id = ?", userId, deviceId).Find(&usageData)
|
||||||
|
if len(usageData) == 0 {
|
||||||
|
GLOBAL_DB.Create(&UsageData{UserId: userId, DeviceId: deviceId, LastUsed: time.Now()})
|
||||||
|
} else {
|
||||||
|
GLOBAL_DB.Model(&UsageData{}).Where("user_id = ? AND device_id = ?", userId, deviceId).Update("last_used", time.Now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func apiESubmitHandler(w http.ResponseWriter, r *http.Request) {
|
func apiESubmitHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
data, err := ioutil.ReadAll(r.Body)
|
data, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -40,6 +56,7 @@ func apiESubmitHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
fmt.Printf("apiESubmitHandler: received request containg %d EncHistoryEntry\n", len(entries))
|
fmt.Printf("apiESubmitHandler: received request containg %d EncHistoryEntry\n", len(entries))
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
|
updateUsageData(entry.UserId, entry.DeviceId)
|
||||||
tx := GLOBAL_DB.Where("user_id = ?", entry.UserId)
|
tx := GLOBAL_DB.Where("user_id = ?", entry.UserId)
|
||||||
var devices []*shared.Device
|
var devices []*shared.Device
|
||||||
result := tx.Find(&devices)
|
result := tx.Find(&devices)
|
||||||
@ -61,7 +78,9 @@ func apiESubmitHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func apiEQueryHandler(w http.ResponseWriter, r *http.Request) {
|
func apiEQueryHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
userId := r.URL.Query().Get("user_id")
|
||||||
deviceId := r.URL.Query().Get("device_id")
|
deviceId := r.URL.Query().Get("device_id")
|
||||||
|
updateUsageData(userId, deviceId)
|
||||||
// Increment the count
|
// Increment the count
|
||||||
GLOBAL_DB.Exec("UPDATE enc_history_entries SET read_count = read_count + 1 WHERE device_id = ?", deviceId)
|
GLOBAL_DB.Exec("UPDATE enc_history_entries SET read_count = read_count + 1 WHERE device_id = ?", deviceId)
|
||||||
|
|
||||||
@ -83,6 +102,8 @@ func apiEQueryHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
// TODO: bootstrap is a janky solution for the initial version of this. Long term, need to support deleting entries from the DB which means replacing bootstrap with a queued message sent to any live instances.
|
// TODO: bootstrap is a janky solution for the initial version of this. Long term, need to support deleting entries from the DB which means replacing bootstrap with a queued message sent to any live instances.
|
||||||
func apiEBootstrapHandler(w http.ResponseWriter, r *http.Request) {
|
func apiEBootstrapHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
userId := r.URL.Query().Get("user_id")
|
userId := r.URL.Query().Get("user_id")
|
||||||
|
deviceId := r.URL.Query().Get("device_id")
|
||||||
|
updateUsageData(userId, deviceId)
|
||||||
tx := GLOBAL_DB.Where("user_id = ?", userId)
|
tx := GLOBAL_DB.Where("user_id = ?", userId)
|
||||||
var historyEntries []*shared.EncHistoryEntry
|
var historyEntries []*shared.EncHistoryEntry
|
||||||
result := tx.Find(&historyEntries)
|
result := tx.Find(&historyEntries)
|
||||||
@ -100,6 +121,7 @@ func apiERegisterHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
userId := r.URL.Query().Get("user_id")
|
userId := r.URL.Query().Get("user_id")
|
||||||
deviceId := r.URL.Query().Get("device_id")
|
deviceId := r.URL.Query().Get("device_id")
|
||||||
GLOBAL_DB.Create(&shared.Device{UserId: userId, DeviceId: deviceId, RegistrationIp: r.RemoteAddr, RegistrationDate: time.Now()})
|
GLOBAL_DB.Create(&shared.Device{UserId: userId, DeviceId: deviceId, RegistrationIp: r.RemoteAddr, RegistrationDate: time.Now()})
|
||||||
|
updateUsageData(userId, deviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiBannerHandler(w http.ResponseWriter, r *http.Request) {
|
func apiBannerHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -122,6 +144,7 @@ func OpenDB() (*gorm.DB, error) {
|
|||||||
}
|
}
|
||||||
db.AutoMigrate(&shared.EncHistoryEntry{})
|
db.AutoMigrate(&shared.EncHistoryEntry{})
|
||||||
db.AutoMigrate(&shared.Device{})
|
db.AutoMigrate(&shared.Device{})
|
||||||
|
db.AutoMigrate(&UsageData{})
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +154,7 @@ func OpenDB() (*gorm.DB, error) {
|
|||||||
}
|
}
|
||||||
db.AutoMigrate(&shared.EncHistoryEntry{})
|
db.AutoMigrate(&shared.EncHistoryEntry{})
|
||||||
db.AutoMigrate(&shared.Device{})
|
db.AutoMigrate(&shared.Device{})
|
||||||
|
db.AutoMigrate(&UsageData{})
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,16 +162,20 @@ func init() {
|
|||||||
if ReleaseVersion == "UNKNOWN" && !isTestEnvironment() {
|
if ReleaseVersion == "UNKNOWN" && !isTestEnvironment() {
|
||||||
panic("server.go was built without a ReleaseVersion!")
|
panic("server.go was built without a ReleaseVersion!")
|
||||||
}
|
}
|
||||||
go keepReleaseVersionUpToDate()
|
|
||||||
InitDB()
|
InitDB()
|
||||||
|
go runBackgroundJobs()
|
||||||
}
|
}
|
||||||
|
|
||||||
func keepReleaseVersionUpToDate() {
|
func runBackgroundJobs() {
|
||||||
for {
|
for {
|
||||||
err := updateReleaseVersion()
|
err := updateReleaseVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
err = cleanDatabase()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
time.Sleep(10 * time.Minute)
|
time.Sleep(10 * time.Minute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,6 +281,14 @@ func byteCountToString(b int) string {
|
|||||||
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "kMG"[exp])
|
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "kMG"[exp])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanDatabase() error {
|
||||||
|
result := GLOBAL_DB.Exec("DELETE FROM enc_history_entries WHERE read_count > 10")
|
||||||
|
if result.Error != nil {
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("Listening on localhost:8080")
|
fmt.Println("Listening on localhost:8080")
|
||||||
http.Handle("/api/v1/esubmit", withLogging(apiESubmitHandler))
|
http.Handle("/api/v1/esubmit", withLogging(apiESubmitHandler))
|
||||||
|
@ -43,6 +43,7 @@ func TestESubmitThenQuery(t *testing.T) {
|
|||||||
|
|
||||||
// Query for device id 1
|
// Query for device id 1
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
// TODO: update this to include the user ID
|
||||||
searchReq := httptest.NewRequest(http.MethodGet, "/?device_id="+devId1, nil)
|
searchReq := httptest.NewRequest(http.MethodGet, "/?device_id="+devId1, nil)
|
||||||
apiEQueryHandler(w, searchReq)
|
apiEQueryHandler(w, searchReq)
|
||||||
res := w.Result()
|
res := w.Result()
|
||||||
@ -72,6 +73,7 @@ func TestESubmitThenQuery(t *testing.T) {
|
|||||||
|
|
||||||
// Same for device id 2
|
// Same for device id 2
|
||||||
w = httptest.NewRecorder()
|
w = httptest.NewRecorder()
|
||||||
|
// TODO: update this to include the user ID
|
||||||
searchReq = httptest.NewRequest(http.MethodGet, "/?device_id="+devId2, nil)
|
searchReq = httptest.NewRequest(http.MethodGet, "/?device_id="+devId2, nil)
|
||||||
apiEQueryHandler(w, searchReq)
|
apiEQueryHandler(w, searchReq)
|
||||||
res = w.Result()
|
res = w.Result()
|
||||||
@ -101,6 +103,7 @@ func TestESubmitThenQuery(t *testing.T) {
|
|||||||
// Bootstrap handler should return 2 entries, one for each device
|
// Bootstrap handler should return 2 entries, one for each device
|
||||||
w = httptest.NewRecorder()
|
w = httptest.NewRecorder()
|
||||||
searchReq = httptest.NewRequest(http.MethodGet, "/?user_id="+data.UserId("key"), nil)
|
searchReq = httptest.NewRequest(http.MethodGet, "/?user_id="+data.UserId("key"), nil)
|
||||||
|
// TODO: update to include device_id
|
||||||
apiEBootstrapHandler(w, searchReq)
|
apiEBootstrapHandler(w, searchReq)
|
||||||
res = w.Result()
|
res = w.Result()
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
@ -63,7 +63,7 @@ func retrieveAdditionalEntriesFromRemote(db *gorm.DB) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
respBody, err := lib.ApiGet("/api/v1/equery?device_id=" + config.DeviceId)
|
respBody, err := lib.ApiGet("/api/v1/equery?device_id=" + config.DeviceId + "&user_id=" + data.UserId(config.UserSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -131,6 +131,7 @@ func saveHistoryEntry() {
|
|||||||
// Persist it remotely
|
// Persist it remotely
|
||||||
encEntry, err := data.EncryptHistoryEntry(config.UserSecret, *entry)
|
encEntry, err := data.EncryptHistoryEntry(config.UserSecret, *entry)
|
||||||
lib.CheckFatalError(err)
|
lib.CheckFatalError(err)
|
||||||
|
encEntry.DeviceId = config.DeviceId
|
||||||
jsonValue, err := json.Marshal([]shared.EncHistoryEntry{encEntry})
|
jsonValue, err := json.Marshal([]shared.EncHistoryEntry{encEntry})
|
||||||
lib.CheckFatalError(err)
|
lib.CheckFatalError(err)
|
||||||
_, err = lib.ApiPost("/api/v1/esubmit", "application/json", jsonValue)
|
_, err = lib.ApiPost("/api/v1/esubmit", "application/json", jsonValue)
|
||||||
|
@ -99,6 +99,9 @@ func RunTestServer() func() {
|
|||||||
if strings.Contains(stderr.String()+stdout.String(), "failed to") {
|
if strings.Contains(stderr.String()+stdout.String(), "failed to") {
|
||||||
panic(fmt.Sprintf("server failed to do something: stderr=%#v, stdout=%#v", stderr.String(), stdout.String()))
|
panic(fmt.Sprintf("server failed to do something: stderr=%#v, stdout=%#v", stderr.String(), stdout.String()))
|
||||||
}
|
}
|
||||||
|
if strings.Contains(stderr.String()+stdout.String(), "ERROR:") {
|
||||||
|
panic(fmt.Sprintf("server experienced an error: stderr=%#v, stdout=%#v", stderr.String(), stdout.String()))
|
||||||
|
}
|
||||||
// fmt.Printf("stderr=%#v, stdout=%#v\n", stderr.String(), stdout.String())
|
// fmt.Printf("stderr=%#v, stdout=%#v\n", stderr.String(), stdout.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user