Compare commits
3 Commits
master
...
feature/ol
Author | SHA1 | Date |
---|---|---|
![]() |
3a04b629b8 | |
![]() |
e46a4d4c32 | |
![]() |
8339ca0add |
|
@ -23,3 +23,4 @@
|
|||
./idea
|
||||
|
||||
config.yml
|
||||
/.idea/
|
||||
|
|
|
@ -41,4 +41,5 @@ func SetupDatabase() {
|
|||
func syncModels() {
|
||||
_ = x.Sync2(new(Issue))
|
||||
_ = x.Sync2(new(Repository))
|
||||
_ = x.Sync2(new(User))
|
||||
}
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
package models
|
||||
|
||||
import "github.com/go-xorm/xorm"
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"github.com/go-xorm/xorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Repository represents a Gitea repository indexed at the local database
|
||||
type Repository struct {
|
||||
|
@ -25,7 +29,7 @@ type Repository struct {
|
|||
Owner string `xorm:"unique(owner_name)"`
|
||||
Name string `xorm:"unique(owner_name)"`
|
||||
|
||||
Activated bool
|
||||
Activated bool `xorm:"-"`
|
||||
}
|
||||
|
||||
// FindRepositoriesByUserID returns all repos of an user
|
||||
|
@ -35,5 +39,96 @@ func FindRepositoriesByUserID(userID int64) ([]*Repository, error) {
|
|||
|
||||
func findRepositoriesByUserID(e *xorm.Engine, userID int64) ([]*Repository, error) {
|
||||
repos := make([]*Repository, 0)
|
||||
return repos, e.Where("user_id = ?", userID).Find(&repos)
|
||||
if err := e.Where("user_id = ?", userID).Find(&repos); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, repo := range repos {
|
||||
repo.Activated = true
|
||||
}
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
// SetActivatedRepositories sets the given repositories as active for the owner. It will sync all issues in addition.
|
||||
func SetActivatedRepositories(repos []*Repository, owner *User) error {
|
||||
return setActivatedRepositories(x, repos, owner)
|
||||
}
|
||||
|
||||
func setActivatedRepositories(e *xorm.Engine, repos []*Repository, owner *User) error {
|
||||
if err := deleteAllReposByUserID(e, owner.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := insertRepos(e, repos); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, repo := range repos {
|
||||
go repo.SyncIssues(owner)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAllReposByUserID deletes all repositories owned by userID
|
||||
func DeleteAllReposByUserID(userID int64) error {
|
||||
return deleteAllReposByUserID(x, userID)
|
||||
}
|
||||
|
||||
func deleteAllReposByUserID(e *xorm.Engine, userID int64) error {
|
||||
if _, err := e.Where("user_id = ?", userID).Delete(new(Repository)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertRepos inserts repos into database
|
||||
func InsertRepos(repos []*Repository) error {
|
||||
return insertRepos(x, repos)
|
||||
}
|
||||
|
||||
func insertRepos(e *xorm.Engine, repos []*Repository) error {
|
||||
_, err := e.Insert(repos)
|
||||
return err
|
||||
}
|
||||
|
||||
// SyncIssues ...
|
||||
func (r *Repository) SyncIssues(user *User) error {
|
||||
return r.syncIssues(x, user)
|
||||
}
|
||||
|
||||
func (r *Repository) syncIssues(e *xorm.Engine, user *User) error {
|
||||
page := 0
|
||||
issues, err := user.GiteaClient().ListRepoIssues(r.Owner, r.Name, structs.ListIssueOption{
|
||||
Page: page,
|
||||
State: "open",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentIssues := issues
|
||||
for len(currentIssues) != 0 {
|
||||
page++
|
||||
currentIssues, err = user.GiteaClient().ListRepoIssues(r.Owner, r.Name, structs.ListIssueOption{
|
||||
Page: page,
|
||||
State: "open",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
issues = append(issues, currentIssues...)
|
||||
}
|
||||
parsedIssues := make([]*Issue, len(issues))
|
||||
now := time.Now()
|
||||
for index, issue := range issues {
|
||||
parsedIssues[index] = &Issue{
|
||||
ID: issue.ID,
|
||||
Closed: issue.State == "closed",
|
||||
Excluded: false, // TODO check labels,
|
||||
IndexedAt: &now,
|
||||
MarkedAt: nil,
|
||||
Stale: false,
|
||||
UpdatedAt: &issue.Updated,
|
||||
RepoID: r.ID,
|
||||
}
|
||||
}
|
||||
e.In("id")
|
||||
_, err = e.Insert(parsedIssues)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -21,14 +21,31 @@ import (
|
|||
"context"
|
||||
"gitea.com/jonasfranz/staletea/auth"
|
||||
"gitea.com/jonasfranz/staletea/config"
|
||||
"github.com/go-xorm/xorm"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// User represents a signed in oauth2 gitea user saved in a session
|
||||
type User struct {
|
||||
ID int64
|
||||
ID int64 `xorm:"pk"`
|
||||
Username string
|
||||
Token *oauth2.Token
|
||||
Token *oauth2.Token `xorm:"json"`
|
||||
}
|
||||
|
||||
// InsertOrUpdateUser inserts or updates an user
|
||||
func InsertOrUpdateUser(user *User) error {
|
||||
return insertOrUpdateUser(x, user)
|
||||
}
|
||||
|
||||
func insertOrUpdateUser(e *xorm.Engine, user *User) error {
|
||||
if ok, err := e.ID(user.ID).Exist(new(User)); err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
_, err := e.InsertOne(user)
|
||||
return err
|
||||
}
|
||||
_, err := e.Update(user)
|
||||
return err
|
||||
}
|
||||
|
||||
// GiteaClient will return a gitea client with authentication of the user
|
||||
|
|
|
@ -74,6 +74,10 @@ func handleCallback(ctx *gin.Context) {
|
|||
Username: user.UserName,
|
||||
Token: token,
|
||||
}
|
||||
if err := models.InsertOrUpdateUser(storedUser); err != nil {
|
||||
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
session.Set("user", storedUser)
|
||||
if err := session.Save(); err != nil {
|
||||
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func showDashboard(ctx *gin.Context) {
|
||||
|
@ -42,11 +43,7 @@ func showDashboard(ctx *gin.Context) {
|
|||
_ = ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
combinedRepos := make(map[int64]*models.Repository, len(activatedRepos))
|
||||
|
||||
for _, repo := range activatedRepos {
|
||||
combinedRepos[repo.ID] = repo
|
||||
}
|
||||
combinedRepos := make(map[int64]*models.Repository, len(remoteRepos))
|
||||
|
||||
for _, repo := range remoteRepos {
|
||||
combinedRepos[repo.ID] = &models.Repository{
|
||||
|
@ -58,14 +55,48 @@ func showDashboard(ctx *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
for _, repo := range activatedRepos {
|
||||
combinedRepos[repo.ID] = repo
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"repos": combinedRepos,
|
||||
"user": user,
|
||||
}
|
||||
|
||||
session.Set("repos", combinedRepos)
|
||||
if err := session.Save(); err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
ctx.HTML(200, "dashboard.tmpl", data)
|
||||
}
|
||||
|
||||
func handleActivate(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
user, ok := session.Get("user").(*models.User)
|
||||
if !ok || user == nil {
|
||||
ctx.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("%s/login", config.BaseURL.Get().(string)))
|
||||
return
|
||||
}
|
||||
|
||||
repos, ok := session.Get("repos").(map[int64]*models.Repository)
|
||||
if !ok {
|
||||
ctx.Status(500)
|
||||
return
|
||||
}
|
||||
|
||||
activatedRepos := make([]*models.Repository, 0, len(repos))
|
||||
for _, repo := range repos {
|
||||
repoID := strconv.FormatInt(repo.ID, 10)
|
||||
if ctx.PostForm(repoID) != "on" {
|
||||
continue
|
||||
}
|
||||
repo.Activated = true
|
||||
activatedRepos = append(activatedRepos, repo)
|
||||
}
|
||||
|
||||
if err := models.SetActivatedRepositories(activatedRepos, user); err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import (
|
|||
func StartServer(addr ...string) error {
|
||||
r := gin.Default()
|
||||
gob.Register(new(models.User))
|
||||
gob.Register(new(models.Repository))
|
||||
gob.Register(map[int64]*models.Repository{})
|
||||
store := cookie.NewStore([]byte(config.SessionSecret.Get().(string)))
|
||||
r.Use(sessions.Sessions("sessions", store))
|
||||
r.LoadHTMLFiles("templates/dashboard.tmpl")
|
||||
|
|
Loading…
Reference in New Issue