Add a downloads collumn to the statistics

This commit is contained in:
Las Zenow 2013-09-24 14:22:53 +02:00
parent 173ee04592
commit a23264ec8d
5 changed files with 251 additions and 35 deletions

View file

@ -3,21 +3,24 @@ package main
const (
PORT = "8080"
DB_IP = "127.0.0.1"
DB_NAME = "trantor"
META_COLL = "meta"
BOOKS_COLL = "books"
TAGS_COLL = "tags"
VISITED_COLL = "visited"
DOWNLOADED_COLL = "downloaded"
HOURLY_VISITS_COLL = "visits.hourly"
DAILY_VISITS_COLL = "visits.daily"
MONTHLY_VISITS_COLL = "visits.monthly"
USERS_COLL = "users"
NEWS_COLL = "news"
STATS_COLL = "statistics"
FS_BOOKS = "fs_books"
FS_IMGS = "fs_imgs"
DB_IP = "127.0.0.1"
DB_NAME = "trantor"
META_COLL = "meta"
BOOKS_COLL = "books"
TAGS_COLL = "tags"
VISITED_COLL = "visited"
DOWNLOADED_COLL = "downloaded"
HOURLY_VISITS_COLL = "visits.hourly"
DAILY_VISITS_COLL = "visits.daily"
MONTHLY_VISITS_COLL = "visits.monthly"
HOURLY_DOWNLOADS_COLL = "downloads.hourly"
DAILY_DOWNLOADS_COLL = "downloads.daily"
MONTHLY_DOWNLOADS_COLL = "downloads.monthly"
USERS_COLL = "users"
NEWS_COLL = "news"
STATS_COLL = "statistics"
FS_BOOKS = "fs_books"
FS_IMGS = "fs_imgs"
PASS_SALT = "ImperialLibSalt"
MINUTES_UPDATE_TAGS = 11

View file

@ -258,3 +258,21 @@ func (d *DB) GetMonthVisits(start time.Time) ([]Visits, error) {
mr := NewMR(d.session.DB(DB_NAME))
return mr.GetMonthVisits(start, statsColl)
}
func (d *DB) GetHourDownloads(start time.Time) ([]Visits, error) {
statsColl := d.session.DB(DB_NAME).C(STATS_COLL)
mr := NewMR(d.session.DB(DB_NAME))
return mr.GetHourDownloads(start, statsColl)
}
func (d *DB) GetDayDownloads(start time.Time) ([]Visits, error) {
statsColl := d.session.DB(DB_NAME).C(STATS_COLL)
mr := NewMR(d.session.DB(DB_NAME))
return mr.GetDayDowloads(start, statsColl)
}
func (d *DB) GetMonthDownloads(start time.Time) ([]Visits, error) {
statsColl := d.session.DB(DB_NAME).C(STATS_COLL)
mr := NewMR(d.session.DB(DB_NAME))
return mr.GetMonthDowloads(start, statsColl)
}

View file

@ -129,7 +129,7 @@ func (m *MR) GetHourVisits(start time.Time, statsColl *mgo.Collection) ([]Visits
var date = Date.UTC(this.date.getUTCFullYear(),
this.date.getUTCMonth(),
this.date.getUTCDate(),
this.date.getUTCHours());
this.date.getUTCHours());
emit({date: date, session: this.session}, 1);
}`
mr.Reduce = reduce
@ -228,6 +228,123 @@ func (m *MR) GetMonthVisits(start time.Time, statsColl *mgo.Collection) ([]Visit
return result, err
}
func (m *MR) GetHourDownloads(start time.Time, statsColl *mgo.Collection) ([]Visits, error) {
if m.isOutdated(HOURLY_DOWNLOADS_COLL, MINUTES_UPDATE_HOURLY) {
const reduce = `function(date, vals) {
var count = 0;
vals.forEach(function(v) { count += v; });
return count;
}`
var mr mgo.MapReduce
mr.Map = `function() {
if (this.section == "download") {
var date = Date.UTC(this.date.getUTCFullYear(),
this.date.getUTCMonth(),
this.date.getUTCDate(),
this.date.getUTCHours());
emit({date: date}, 1);
}
}`
mr.Reduce = reduce
err := m.update(&mr, bson.M{"date": bson.M{"$gte": start}}, statsColl, HOURLY_DOWNLOADS_COLL+"_raw")
if err != nil {
return nil, err
}
var mr2 mgo.MapReduce
mr2.Map = `function() {
emit(this['_id']['date'], 1);
}`
mr2.Reduce = reduce
hourly_raw := m.database.C(HOURLY_DOWNLOADS_COLL + "_raw")
err = m.update(&mr2, bson.M{}, hourly_raw, HOURLY_DOWNLOADS_COLL)
if err != nil {
return nil, err
}
}
var result []Visits
hourlyColl := m.database.C(HOURLY_DOWNLOADS_COLL)
err := hourlyColl.Find(nil).All(&result)
return result, err
}
func (m *MR) GetDayDowloads(start time.Time, statsColl *mgo.Collection) ([]Visits, error) {
if m.isOutdated(DAILY_DOWNLOADS_COLL, MINUTES_UPDATE_DAILY) {
const reduce = `function(date, vals) {
var count = 0;
vals.forEach(function(v) { count += v; });
return count;
}`
var mr mgo.MapReduce
mr.Map = `function() {
if (this.section == "download") {
var date = Date.UTC(this.date.getUTCFullYear(),
this.date.getUTCMonth(),
this.date.getUTCDate());
emit({date: date, session: this.session}, 1);
}
}`
mr.Reduce = reduce
err := m.update(&mr, bson.M{"date": bson.M{"$gte": start}}, statsColl, DAILY_DOWNLOADS_COLL+"_raw")
if err != nil {
return nil, err
}
var mr2 mgo.MapReduce
mr2.Map = `function() {
emit(this['_id']['date'], 1);
}`
mr2.Reduce = reduce
daily_raw := m.database.C(DAILY_DOWNLOADS_COLL + "_raw")
err = m.update(&mr2, bson.M{}, daily_raw, DAILY_DOWNLOADS_COLL)
if err != nil {
return nil, err
}
}
var result []Visits
dailyColl := m.database.C(DAILY_DOWNLOADS_COLL)
err := dailyColl.Find(nil).All(&result)
return result, err
}
func (m *MR) GetMonthDowloads(start time.Time, statsColl *mgo.Collection) ([]Visits, error) {
if m.isOutdated(MONTHLY_DOWNLOADS_COLL, MINUTES_UPDATE_MONTHLY) {
const reduce = `function(date, vals) {
var count = 0;
vals.forEach(function(v) { count += v; });
return count;
}`
var mr mgo.MapReduce
mr.Map = `function() {
if (this.section == "download") {
var date = Date.UTC(this.date.getUTCFullYear(),
this.date.getUTCMonth());
emit({date: date, session: this.session}, 1);
}
}`
mr.Reduce = reduce
err := m.update(&mr, bson.M{"date": bson.M{"$gte": start}}, statsColl, MONTHLY_DOWNLOADS_COLL+"_raw")
if err != nil {
return nil, err
}
var mr2 mgo.MapReduce
mr2.Map = `function() {
emit(this['_id']['date'], 1);
}`
mr2.Reduce = reduce
monthly_raw := m.database.C(MONTHLY_DOWNLOADS_COLL + "_raw")
err = m.update(&mr2, bson.M{}, monthly_raw, MONTHLY_DOWNLOADS_COLL)
if err != nil {
return nil, err
}
}
var result []Visits
monthlyColl := m.database.C(MONTHLY_DOWNLOADS_COLL)
err := monthlyColl.Find(nil).All(&result)
return result, err
}
func (m *MR) update(mr *mgo.MapReduce, query bson.M, queryColl *mgo.Collection, storeColl string) error {
metaColl := m.database.C(META_COLL)
_, err := metaColl.RemoveAll(bson.M{"type": storeColl})

View file

@ -65,18 +65,24 @@ func statsHandler(h handler) {
var data statsData
data.S = GetStatus(h)
data.S.Stats = true
data.Hourly = getHourlyVisits(h.db)
data.Daily = getDailyVisits(h.db)
data.Monthly = getMonthlyVisits(h.db)
data.HVisits = getHourlyVisits(h.db)
data.DVisits = getDailyVisits(h.db)
data.MVisits = getMonthlyVisits(h.db)
data.HDownloads = getHourlyDownloads(h.db)
data.DDownloads = getDailyDownloads(h.db)
data.MDownloads = getMonthlyDownloads(h.db)
loadTemplate(h.w, "stats", data)
}
type statsData struct {
S Status
Hourly []visitData
Daily []visitData
Monthly []visitData
S Status
HVisits []visitData
DVisits []visitData
MVisits []visitData
HDownloads []visitData
DDownloads []visitData
MDownloads []visitData
}
type visitData struct {
@ -135,6 +141,57 @@ func getMonthlyVisits(db *DB) []visitData {
return visits
}
func getHourlyDownloads(db *DB) []visitData {
const numDays = 2
var visits []visitData
start := time.Now().UTC().Add(-numDays * 24 * time.Hour)
visit, _ := db.GetHourDownloads(start)
for _, v := range visit {
var elem visitData
hour := time.Unix(v.Date/1000, 0).UTC().Hour()
elem.Label = strconv.Itoa(hour + 1)
elem.Count = v.Count
visits = append(visits, elem)
}
return visits
}
func getDailyDownloads(db *DB) []visitData {
const numDays = 30
var visits []visitData
start := time.Now().UTC().Add(-numDays * 24 * time.Hour).Truncate(24 * time.Hour)
visit, _ := db.GetDayDownloads(start)
for _, v := range visit {
var elem visitData
day := time.Unix(v.Date/1000, 0).UTC().Day()
elem.Label = strconv.Itoa(day)
elem.Count = v.Count
visits = append(visits, elem)
}
return visits
}
func getMonthlyDownloads(db *DB) []visitData {
const numDays = 365
var visits []visitData
start := time.Now().UTC().Add(-numDays * 24 * time.Hour).Truncate(24 * time.Hour)
visit, _ := db.GetMonthDownloads(start)
for _, v := range visit {
var elem visitData
month := time.Unix(v.Date/1000, 0).UTC().Month()
elem.Label = month.String()
elem.Count = v.Count
visits = append(visits, elem)
}
return visits
}
func appendFiles(r *http.Request, stats map[string]interface{}) {
if r.Method == "POST" && r.MultipartForm != nil {
files := r.MultipartForm.File

View file

@ -3,12 +3,24 @@
<script src="/js/Chart.min.js"></script>
<div class="row">
<h4>Hourly visits:</h4>
<canvas id="hourly" height="400" width="800"></canvas>
<h4>Daily visits:</h4>
<canvas id="daily" height="400" width="800"></canvas>
<h4>Monthly visits:</h4>
<canvas id="monthly" height="400" width="800"></canvas>
<div id="visits" class="span6">
<h2>Visits</h2>
<h4>Hourly:</h4>
<canvas id="hvisits" height="400" width="500"></canvas>
<h4>Daily:</h4>
<canvas id="dvisits" height="400" width="500"></canvas>
<h4>Monthly:</h4>
<canvas id="mvisits" height="400" width="500"></canvas>
</div>
<div id="downloads" class="span6">
<h2>Downloads</h2>
<h4>Hourly:</h4>
<canvas id="hdownloads" height="400" width="500"></canvas>
<h4>Daily:</h4>
<canvas id="ddownloads" height="400" width="500"></canvas>
<h4>Monthly:</h4>
<canvas id="mdownlodas" height="400" width="500"></canvas>
</div>
</div>
<script type="text/javascript">
@ -30,12 +42,21 @@
new Chart(ctx).Line(data);
}
chart("#hourly", [{{range .Hourly}}"{{.Label}}",{{end}}],
[{{range .Hourly}}{{.Count}},{{end}}])
chart("#daily", [{{range .Daily}}"{{.Label}}",{{end}}],
[{{range .Daily}}{{.Count}},{{end}}])
chart("#monthly", [{{range .Monthly}}"{{.Label}}",{{end}}],
[{{range .Monthly}}{{.Count}},{{end}}])
$(document).ready(function() {
chart("#hvisits", [{{range .HVisits}}"{{.Label}}",{{end}}],
[{{range .HVisits}}{{.Count}},{{end}}])
chart("#dvisits", [{{range .DVisits}}"{{.Label}}",{{end}}],
[{{range .DVisits}}{{.Count}},{{end}}])
chart("#mvisits", [{{range .MVisits}}"{{.Label}}",{{end}}],
[{{range .MVisits}}{{.Count}},{{end}}])
chart("#hdownloads", [{{range .HDownloads}}"{{.Label}}",{{end}}],
[{{range .HDownloads}}{{.Count}},{{end}}])
chart("#ddownloads", [{{range .DDownloads}}"{{.Label}}",{{end}}],
[{{range .DDownloads}}{{.Count}},{{end}}])
chart("#mdownlodas", [{{range .MDownloads}}"{{.Label}}",{{end}}],
[{{range .MDownloads}}{{.Count}},{{end}}])
})
</script>
{{template "footer.html"}}