Compare commits
3 Commits
master
...
feature/ol
Author | SHA1 | Date |
---|---|---|
![]() |
3a04b629b8 | |
![]() |
e46a4d4c32 | |
![]() |
8339ca0add |
|
@ -23,3 +23,4 @@
|
||||||
./idea
|
./idea
|
||||||
|
|
||||||
config.yml
|
config.yml
|
||||||
|
/.idea/
|
||||||
|
|
|
@ -41,4 +41,5 @@ func SetupDatabase() {
|
||||||
func syncModels() {
|
func syncModels() {
|
||||||
_ = x.Sync2(new(Issue))
|
_ = x.Sync2(new(Issue))
|
||||||
_ = x.Sync2(new(Repository))
|
_ = x.Sync2(new(Repository))
|
||||||
|
_ = x.Sync2(new(User))
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,11 @@
|
||||||
|
|
||||||
package models
|
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
|
// Repository represents a Gitea repository indexed at the local database
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
|
@ -25,7 +29,7 @@ type Repository struct {
|
||||||
Owner string `xorm:"unique(owner_name)"`
|
Owner string `xorm:"unique(owner_name)"`
|
||||||
Name string `xorm:"unique(owner_name)"`
|
Name string `xorm:"unique(owner_name)"`
|
||||||
|
|
||||||
Activated bool
|
Activated bool `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindRepositoriesByUserID returns all repos of an user
|
// 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) {
|
func findRepositoriesByUserID(e *xorm.Engine, userID int64) ([]*Repository, error) {
|
||||||
repos := make([]*Repository, 0)
|
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"
|
"context"
|
||||||
"gitea.com/jonasfranz/staletea/auth"
|
"gitea.com/jonasfranz/staletea/auth"
|
||||||
"gitea.com/jonasfranz/staletea/config"
|
"gitea.com/jonasfranz/staletea/config"
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// User represents a signed in oauth2 gitea user saved in a session
|
// User represents a signed in oauth2 gitea user saved in a session
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int64
|
ID int64 `xorm:"pk"`
|
||||||
Username string
|
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
|
// GiteaClient will return a gitea client with authentication of the user
|
||||||
|
|
|
@ -74,6 +74,10 @@ func handleCallback(ctx *gin.Context) {
|
||||||
Username: user.UserName,
|
Username: user.UserName,
|
||||||
Token: token,
|
Token: token,
|
||||||
}
|
}
|
||||||
|
if err := models.InsertOrUpdateUser(storedUser); err != nil {
|
||||||
|
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
session.Set("user", storedUser)
|
session.Set("user", storedUser)
|
||||||
if err := session.Save(); err != nil {
|
if err := session.Save(); err != nil {
|
||||||
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
_ = ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func showDashboard(ctx *gin.Context) {
|
func showDashboard(ctx *gin.Context) {
|
||||||
|
@ -42,11 +43,7 @@ func showDashboard(ctx *gin.Context) {
|
||||||
_ = ctx.AbortWithError(500, err)
|
_ = ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
combinedRepos := make(map[int64]*models.Repository, len(activatedRepos))
|
combinedRepos := make(map[int64]*models.Repository, len(remoteRepos))
|
||||||
|
|
||||||
for _, repo := range activatedRepos {
|
|
||||||
combinedRepos[repo.ID] = repo
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, repo := range remoteRepos {
|
for _, repo := range remoteRepos {
|
||||||
combinedRepos[repo.ID] = &models.Repository{
|
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{}{
|
data := map[string]interface{}{
|
||||||
"repos": combinedRepos,
|
"repos": combinedRepos,
|
||||||
"user": user,
|
"user": user,
|
||||||
}
|
}
|
||||||
|
session.Set("repos", combinedRepos)
|
||||||
|
if err := session.Save(); err != nil {
|
||||||
|
ctx.AbortWithError(500, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
ctx.HTML(200, "dashboard.tmpl", data)
|
ctx.HTML(200, "dashboard.tmpl", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleActivate(ctx *gin.Context) {
|
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 {
|
func StartServer(addr ...string) error {
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
gob.Register(new(models.User))
|
gob.Register(new(models.User))
|
||||||
|
gob.Register(new(models.Repository))
|
||||||
|
gob.Register(map[int64]*models.Repository{})
|
||||||
store := cookie.NewStore([]byte(config.SessionSecret.Get().(string)))
|
store := cookie.NewStore([]byte(config.SessionSecret.Get().(string)))
|
||||||
r.Use(sessions.Sessions("sessions", store))
|
r.Use(sessions.Sessions("sessions", store))
|
||||||
r.LoadHTMLFiles("templates/dashboard.tmpl")
|
r.LoadHTMLFiles("templates/dashboard.tmpl")
|
||||||
|
|
Loading…
Reference in New Issue