mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
0af7d2f8ef | |||
11d1d5bc99 | |||
ada0863f7c | |||
7818f6b094 | |||
f86eb7668d | |||
24469e4922 |
@ -9,7 +9,7 @@ RUN cd /src && go build -o wakapi
|
||||
|
||||
# When running the application using `docker run`, you can pass environment variables
|
||||
# to override config values from .env using `-e` syntax.
|
||||
# Available options are:
|
||||
# Available options are:
|
||||
# – WAKAPI_DB_TYPE
|
||||
# – WAKAPI_DB_USER
|
||||
# – WAKAPI_DB_PASSWORD
|
||||
@ -17,8 +17,7 @@ RUN cd /src && go build -o wakapi
|
||||
# – WAKAPI_DB_PORT
|
||||
# – WAKAPI_DB_NAME
|
||||
# – WAKAPI_PASSWORD_SALT
|
||||
# – WAKAPI_DEFAULT_USER_NAME
|
||||
# – WAKAPI_DEFAULT_USER_PASSWORD
|
||||
# – WAKAPI_BASE_PATH
|
||||
|
||||
FROM debian
|
||||
WORKDIR /app
|
||||
@ -30,8 +29,6 @@ ENV WAKAPI_DB_PASSWORD ''
|
||||
ENV WAKAPI_DB_HOST ''
|
||||
ENV WAKAPI_DB_NAME=/data/wakapi.db
|
||||
ENV WAKAPI_PASSWORD_SALT ''
|
||||
ENV WAKAPI_DEFAULT_USER_NAME admin
|
||||
ENV WAKAPI_DEFAULT_USER_PASSWORD admin
|
||||
|
||||
COPY --from=build-env /src/wakapi /app/
|
||||
COPY --from=build-env /src/config.ini /app/
|
||||
|
13
main.go
13
main.go
@ -43,6 +43,11 @@ func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
|
||||
// Show data loss warning
|
||||
if config.CleanUp {
|
||||
promptAbort("`CLEANUP` is set to `true`, which may cause data loss. Are you sure to continue?", 5)
|
||||
}
|
||||
|
||||
// Connect to database
|
||||
var err error
|
||||
db, err = gorm.Open(config.DbDialect, utils.MakeConnectionString(config))
|
||||
@ -172,3 +177,11 @@ func migrateLanguages() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func promptAbort(message string, timeoutSec int) {
|
||||
log.Printf("[WARNING] %s.\nTo abort server startup, press Ctrl+C.\n", message)
|
||||
for i := timeoutSec; i > 0; i-- {
|
||||
log.Printf("Starting in %d seconds ...\n", i)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,11 @@ func readConfig() *Config {
|
||||
port = cfg.Section("server").Key("port").MustInt()
|
||||
}
|
||||
|
||||
basePathEnv, basePathEnvExists := os.LookupEnv("WAKAPI_BASE_PATH")
|
||||
basePath := cfg.Section("server").Key("base_path").MustString("/")
|
||||
if basePathEnvExists {
|
||||
basePath = basePathEnv
|
||||
}
|
||||
if strings.HasSuffix(basePath, "/") {
|
||||
basePath = basePath[:len(basePath)-1]
|
||||
}
|
||||
|
@ -55,5 +55,5 @@ func (h *HeartbeatHandler) ApiPost(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
@ -96,10 +96,25 @@ func (srv *SummaryService) Construct(from, to time.Time, user *models.User, reco
|
||||
}
|
||||
close(c)
|
||||
|
||||
realFrom, realTo := from, to
|
||||
if len(existingSummaries) > 0 {
|
||||
realFrom = existingSummaries[0].FromTime
|
||||
realTo = existingSummaries[len(existingSummaries)-1].ToTime
|
||||
}
|
||||
if len(heartbeats) > 0 {
|
||||
t1, t2 := time.Time(heartbeats[0].Time), time.Time(heartbeats[len(heartbeats)-1].Time)
|
||||
if t1.After(realFrom) && t1.Before(time.Date(realFrom.Year(), realFrom.Month(), realFrom.Day()+1, 0, 0, 0, 0, realFrom.Location())) {
|
||||
realFrom = t1
|
||||
}
|
||||
if t2.Before(realTo) && t2.After(time.Date(realTo.Year(), realTo.Month(), realTo.Day()-1, 0, 0, 0, 0, realTo.Location())) {
|
||||
realTo = t2
|
||||
}
|
||||
}
|
||||
|
||||
aggregatedSummary := &models.Summary{
|
||||
UserID: user.ID,
|
||||
FromTime: from,
|
||||
ToTime: to,
|
||||
FromTime: realFrom,
|
||||
ToTime: realTo,
|
||||
Projects: projectItems,
|
||||
Languages: languageItems,
|
||||
Editors: editorItems,
|
||||
@ -134,6 +149,7 @@ func (srv *SummaryService) GetByUserWithin(user *models.User, from, to time.Time
|
||||
Where(&models.Summary{UserID: user.ID}).
|
||||
Where("from_time >= ?", from).
|
||||
Where("to_time <= ?", to).
|
||||
Order("from_time asc").
|
||||
Preload("Projects", "type = ?", models.SummaryProject).
|
||||
Preload("Languages", "type = ?", models.SummaryLanguage).
|
||||
Preload("Editors", "type = ?", models.SummaryEditor).
|
||||
@ -224,7 +240,16 @@ func getMissingIntervals(from, to time.Time, existingSummaries []*models.Summary
|
||||
|
||||
// Between
|
||||
for i := 0; i < len(existingSummaries)-1; i++ {
|
||||
if existingSummaries[i].ToTime.Before(existingSummaries[i+1].FromTime) {
|
||||
t1, t2 := existingSummaries[i].ToTime, existingSummaries[i+1].FromTime
|
||||
if t1.Equal(t2) {
|
||||
continue
|
||||
}
|
||||
|
||||
// round to end of day / start of day, assuming that summaries are always generated on a per-day basis
|
||||
td1 := time.Date(t1.Year(), t1.Month(), t1.Day()+1, 0, 0, 0, 0, t1.Location())
|
||||
td2 := time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, t2.Location())
|
||||
// one or more day missing in between?
|
||||
if td1.Before(td2) {
|
||||
intervals = append(intervals, &Interval{existingSummaries[i].ToTime, existingSummaries[i+1].FromTime})
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,12 @@ func StartOfWeek() time.Time {
|
||||
|
||||
func StartOfMonth() time.Time {
|
||||
ref := time.Now()
|
||||
return time.Date(ref.Year(), ref.Month(), 0, 0, 0, 0, 0, ref.Location())
|
||||
return time.Date(ref.Year(), ref.Month(), 1, 0, 0, 0, 0, ref.Location())
|
||||
}
|
||||
|
||||
func StartOfYear() time.Time {
|
||||
ref := time.Now()
|
||||
return time.Date(ref.Year(), time.January, 0, 0, 0, 0, 0, ref.Location())
|
||||
return time.Date(ref.Year(), time.January, 1, 0, 0, 0, 0, ref.Location())
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/18632496
|
||||
|
@ -1 +1 @@
|
||||
1.7.1
|
||||
1.7.4
|
Reference in New Issue
Block a user