mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
Resolve #7.
This commit is contained in:
parent
0664861f74
commit
0e61870568
1482
data/colors.json
Normal file
1482
data/colors.json
Normal file
File diff suppressed because it is too large
Load Diff
31
main.go
31
main.go
@ -3,10 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/codegangsta/negroni"
|
"github.com/codegangsta/negroni"
|
||||||
@ -26,6 +29,8 @@ import (
|
|||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: Refactor entire project to be structured after business domains
|
||||||
|
|
||||||
func readConfig() *models.Config {
|
func readConfig() *models.Config {
|
||||||
if err := godotenv.Load(); err != nil {
|
if err := godotenv.Load(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -64,6 +69,27 @@ func readConfig() *models.Config {
|
|||||||
customLangs[k.Name()] = k.MustString("unknown")
|
customLangs[k.Name()] = k.MustString("unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read language colors
|
||||||
|
// Source: https://raw.githubusercontent.com/ozh/github-colors/master/colors.json
|
||||||
|
var colors = make(map[string]string)
|
||||||
|
var rawColors map[string]struct {
|
||||||
|
Color string `json:"color"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile("data/colors.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(data, &rawColors); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range rawColors {
|
||||||
|
colors[strings.ToLower(k)] = v.Color
|
||||||
|
}
|
||||||
|
|
||||||
return &models.Config{
|
return &models.Config{
|
||||||
Env: env,
|
Env: env,
|
||||||
Port: port,
|
Port: port,
|
||||||
@ -77,6 +103,7 @@ func readConfig() *models.Config {
|
|||||||
DbMaxConn: dbMaxConn,
|
DbMaxConn: dbMaxConn,
|
||||||
CleanUp: cleanUp,
|
CleanUp: cleanUp,
|
||||||
CustomLanguages: customLangs,
|
CustomLanguages: customLangs,
|
||||||
|
LanguageColors: colors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,8 +174,8 @@ func main() {
|
|||||||
mainRouter.Path("/").Methods(http.MethodGet).HandlerFunc(summaryHandler.Index)
|
mainRouter.Path("/").Methods(http.MethodGet).HandlerFunc(summaryHandler.Index)
|
||||||
|
|
||||||
// API Routes
|
// API Routes
|
||||||
apiRouter.Path("/heartbeat").Methods(http.MethodPost).HandlerFunc(heartbeatHandler.Post)
|
apiRouter.Path("/heartbeat").Methods(http.MethodPost).HandlerFunc(heartbeatHandler.ApiPost)
|
||||||
apiRouter.Path("/summary").Methods(http.MethodGet).HandlerFunc(summaryHandler.Get)
|
apiRouter.Path("/summary").Methods(http.MethodGet).HandlerFunc(summaryHandler.ApiGet)
|
||||||
|
|
||||||
// Static Routes
|
// Static Routes
|
||||||
router.PathPrefix("/assets").Handler(negroni.Classic().With(negroni.Wrap(http.FileServer(http.Dir("./static")))))
|
router.PathPrefix("/assets").Handler(negroni.Classic().With(negroni.Wrap(http.FileServer(http.Dir("./static")))))
|
||||||
|
@ -13,6 +13,7 @@ type Config struct {
|
|||||||
DbMaxConn uint
|
DbMaxConn uint
|
||||||
CleanUp bool
|
CleanUp bool
|
||||||
CustomLanguages map[string]string
|
CustomLanguages map[string]string
|
||||||
|
LanguageColors map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) IsDev() bool {
|
func (c *Config) IsDev() bool {
|
||||||
|
@ -35,3 +35,8 @@ type SummaryItemContainer struct {
|
|||||||
Type uint8
|
Type uint8
|
||||||
Items []*SummaryItem
|
Items []*SummaryItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SummaryViewModel struct {
|
||||||
|
*Summary
|
||||||
|
LanguageColors map[string]string
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ type HeartbeatHandler struct {
|
|||||||
HeartbeatSrvc *services.HeartbeatService
|
HeartbeatSrvc *services.HeartbeatService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HeartbeatHandler) Post(w http.ResponseWriter, r *http.Request) {
|
func (h *HeartbeatHandler) ApiPost(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
|
@ -44,7 +44,7 @@ func (m *SummaryHandler) loadTemplates() {
|
|||||||
m.indexTemplate = indexTpl
|
m.indexTemplate = indexTpl
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *SummaryHandler) Get(w http.ResponseWriter, r *http.Request) {
|
func (h *SummaryHandler) ApiGet(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodGet {
|
if r.Method != http.MethodGet {
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
@ -91,7 +91,12 @@ func (h *SummaryHandler) Index(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h.indexTemplate.Execute(w, summary)
|
vm := models.SummaryViewModel{
|
||||||
|
Summary: summary,
|
||||||
|
LanguageColors: utils.FilterLanguageColors(h.SummarySrvc.Config.LanguageColors, summary),
|
||||||
|
}
|
||||||
|
|
||||||
|
h.indexTemplate.Execute(w, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadUserSummary(r *http.Request, summaryService *services.SummaryService) (*models.Summary, error, int) {
|
func loadUserSummary(r *http.Request, summaryService *services.SummaryService) (*models.Summary, error, int) {
|
||||||
|
@ -121,7 +121,7 @@ function draw() {
|
|||||||
data: wakapiData.languages
|
data: wakapiData.languages
|
||||||
.slice(0, Math.min(SHOW_TOP_N, wakapiData.languages.length))
|
.slice(0, Math.min(SHOW_TOP_N, wakapiData.languages.length))
|
||||||
.map(p => parseInt(p.total)),
|
.map(p => parseInt(p.total)),
|
||||||
backgroundColor: wakapiData.languages.map(p => getRandomColor(p.key))
|
backgroundColor: wakapiData.languages.map(p => languageColors[p.key.toLowerCase()] || getRandomColor(p.key))
|
||||||
}],
|
}],
|
||||||
labels: wakapiData.languages
|
labels: wakapiData.languages
|
||||||
.slice(0, Math.min(SHOW_TOP_N, wakapiData.languages.length))
|
.slice(0, Math.min(SHOW_TOP_N, wakapiData.languages.length))
|
||||||
|
16
utils/color.go
Normal file
16
utils/color.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/n1try/wakapi/models"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FilterLanguageColors(all map[string]string, summary *models.Summary) map[string]string {
|
||||||
|
subset := make(map[string]string)
|
||||||
|
for _, item := range summary.Languages {
|
||||||
|
if c, ok := all[strings.ToLower(item.Key)]; ok {
|
||||||
|
subset[strings.ToLower(item.Key)] = c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return subset
|
||||||
|
}
|
@ -64,7 +64,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
let wakapiData = {}
|
let wakapiData = {}
|
||||||
wakapiData.projects = {{ json .Projects }}
|
let languageColors = {{ .LanguageColors | json }}
|
||||||
|
wakapiData.projects = {{ .Projects | json }}
|
||||||
wakapiData.operatingSystems = {{ .OperatingSystems | json }}
|
wakapiData.operatingSystems = {{ .OperatingSystems | json }}
|
||||||
wakapiData.editors = {{ .Editors | json }}
|
wakapiData.editors = {{ .Editors | json }}
|
||||||
wakapiData.languages = {{ .Languages | json }}
|
wakapiData.languages = {{ .Languages | json }}
|
||||||
|
Loading…
Reference in New Issue
Block a user