diff --git a/server/app/scripts/app.js b/server/app/scripts/app.js index 263821c2..a8dbf30a 100644 --- a/server/app/scripts/app.js +++ b/server/app/scripts/app.js @@ -198,10 +198,23 @@ app.run(['$location', '$rootScope', '$routeParams', 'feed', 'stdout', function($ -app.controller("AccountReposController", function($scope, $http, user) { +app.controller("AccountReposController", function($scope, $http, $location, user) { $scope.user = user; + $scope.syncUser = function() { + $http({method: 'POST', url: '/api/user/sync' }).success(function(data){ + $location.search('return_to', $location.$$path).path('/sync') + }).error(function(data, status){ + if (status == 409) { + $scope.msg = 'already' + } else { + $scope.msg = 'bad' + } + $scope.$apply(); + }); + } + // get the user details $http({method: 'GET', url: '/api/user/repos'}). success(function(data, status, headers, config) { diff --git a/server/app/scripts/controllers/home.js b/server/app/scripts/controllers/home.js index 18d612ac..953fd970 100644 --- a/server/app/scripts/controllers/home.js +++ b/server/app/scripts/controllers/home.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('app').controller("HomeController", function($scope, $http, feed) { +angular.module('app').controller("HomeController", function($scope, $http, $location, feed) { feed.subscribe(function(item) { // todo toast notification @@ -14,6 +14,19 @@ angular.module('app').controller("HomeController", function($scope, $http, feed) console.log(data); }); + $scope.syncUser = function() { + $http({method: 'POST', url: '/api/user/sync' }).success(function(data){ + $location.search('return_to', $location.$$path).path('/sync') + }).error(function(data, status){ + if (status == 409) { + $scope.msg = 'already' + } else { + $scope.msg = 'bad' + } + $scope.$apply(); + }); + } + $http({method: 'GET', url: '/api/user/repos'}). success(function(data, status, headers, config) { $scope.repos = (typeof data==='string')?[]:data; diff --git a/server/app/scripts/controllers/sync.js b/server/app/scripts/controllers/sync.js index 909f79ae..9d3521f7 100644 --- a/server/app/scripts/controllers/sync.js +++ b/server/app/scripts/controllers/sync.js @@ -1,10 +1,16 @@ 'use strict'; -angular.module('app').controller("SyncController", function($scope, $http, $interval, $location, users) { +angular.module('app').controller("SyncController", function($scope, $http, $interval, $location, $routeParams, users) { + var return_to = $routeParams.return_to var stop = $interval(function() { // todo(bradrydzewski) We should poll the user to see if the // sync process is complete, using the user.syncing variable. $interval.cancel(stop); - $location.path("/"); + if (return_to != undefined) { + $location.$$search = {} + $location.path(return_to); + } else { + $location.path("/"); + } }, 5000); }); diff --git a/server/app/views/home.html b/server/app/views/home.html index 5e294017..68c45265 100644 --- a/server/app/views/home.html +++ b/server/app/views/home.html @@ -1,7 +1,18 @@ +
+ sync already runned + bad response +
+
diff --git a/server/app/views/repo_list.html b/server/app/views/repo_list.html index 3a486b6b..4fda16c8 100644 --- a/server/app/views/repo_list.html +++ b/server/app/views/repo_list.html @@ -1,7 +1,19 @@ +
+ sync already runned + bad response +
+
diff --git a/server/handler/login.go b/server/handler/login.go index fdae48a5..285702d0 100644 --- a/server/handler/login.go +++ b/server/handler/login.go @@ -4,12 +4,12 @@ import ( "encoding/json" "log" "net/http" - "time" "github.com/drone/drone/plugin/remote" "github.com/drone/drone/server/capability" "github.com/drone/drone/server/datastore" "github.com/drone/drone/server/session" + "github.com/drone/drone/server/sync" "github.com/drone/drone/shared/model" "github.com/goji/context" "github.com/zenazn/goji/web" @@ -83,7 +83,8 @@ func GetLogin(c web.C, w http.ResponseWriter, r *http.Request) { u.Secret = login.Secret u.Name = login.Name u.SetEmail(login.Email) - u.Syncing = true //u.IsStale() // todo (badrydzewski) should not always sync + u.Syncing = u.IsStale() + if err := datastore.PutUser(ctx, u); err != nil { log.Println(err) w.WriteHeader(http.StatusBadRequest) @@ -102,51 +103,8 @@ func GetLogin(c web.C, w http.ResponseWriter, r *http.Request) { redirect = "/sync" log.Println("sync user account.", u.Login) - // sync inside a goroutine. This should eventually be moved to - // its own package / sync utility. - go func() { - repos, err := remote.GetRepos(u) - if err != nil { - log.Println("Error syncing user account, listing repositories", u.Login, err) - return - } - - // insert all repositories - for _, repo := range repos { - var role = repo.Role - if err := datastore.PostRepo(ctx, repo); err != nil { - // typically we see a failure because the repository already exists - // in which case, we can retrieve the existing record to get the ID. - repo, err = datastore.GetRepoName(ctx, repo.Host, repo.Owner, repo.Name) - if err != nil { - log.Println("Error adding repo.", u.Login, repo.Name, err) - continue - } - } - - // add user permissions - perm := model.Perm{ - UserID: u.ID, - RepoID: repo.ID, - Read: role.Read, - Write: role.Write, - Admin: role.Admin, - } - if err := datastore.PostPerm(ctx, &perm); err != nil { - log.Println("Error adding permissions.", u.Login, repo.Name, err) - continue - } - - log.Println("Successfully syced repo.", u.Login+"/"+repo.Name) - } - - u.Synced = time.Now().UTC().Unix() - u.Syncing = false - if err := datastore.PutUser(ctx, u); err != nil { - log.Println("Error syncing user account, updating sync date", u.Login, err) - return - } - }() + // sync inside a goroutine + go sync.SyncUser(ctx, u, remote) } token, err := session.GenerateToken(ctx, r, u) diff --git a/server/handler/user.go b/server/handler/user.go index 3b0b64da..e5e8a734 100644 --- a/server/handler/user.go +++ b/server/handler/user.go @@ -4,7 +4,9 @@ import ( "encoding/json" "net/http" + "github.com/drone/drone/plugin/remote" "github.com/drone/drone/server/datastore" + "github.com/drone/drone/server/sync" "github.com/drone/drone/shared/model" "github.com/goji/context" "github.com/zenazn/goji/web" @@ -111,3 +113,37 @@ func GetUserFeed(c web.C, w http.ResponseWriter, r *http.Request) { } json.NewEncoder(w).Encode(&repos) } + +// PostUserSync accepts a request to post user sync +// +// POST /api/user/sync +// +func PostUserSync(c web.C, w http.ResponseWriter, r *http.Request) { + var ctx = context.FromC(c) + var user = ToUser(c) + if user == nil { + w.WriteHeader(http.StatusUnauthorized) + return + } + + var remote = remote.Lookup(user.Remote) + if remote == nil { + w.WriteHeader(http.StatusNotFound) + return + } + + if user.Syncing { + w.WriteHeader(http.StatusConflict) + return + } + + user.Syncing = true + if err := datastore.PutUser(ctx, user); err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + + go sync.SyncUser(ctx, user, remote) + w.WriteHeader(http.StatusNoContent) + return +} diff --git a/server/router/router.go b/server/router/router.go index 418256d1..651a0146 100644 --- a/server/router/router.go +++ b/server/router/router.go @@ -58,6 +58,7 @@ func New() *web.Mux { user.Use(middleware.RequireUser) user.Get("/api/user/feed", handler.GetUserFeed) user.Get("/api/user/repos", handler.GetUserRepos) + user.Post("/api/user/sync", handler.PostUserSync) user.Get("/api/user", handler.GetUserCurrent) user.Put("/api/user", handler.PutUser) mux.Handle("/api/user*", user) diff --git a/server/sync/sync.go b/server/sync/sync.go new file mode 100644 index 00000000..b926dc23 --- /dev/null +++ b/server/sync/sync.go @@ -0,0 +1,55 @@ +package sync + +import ( + "log" + "time" + + "code.google.com/p/go.net/context" + "github.com/drone/drone/plugin/remote" + "github.com/drone/drone/server/datastore" + "github.com/drone/drone/shared/model" +) + +func SyncUser(ctx context.Context, user *model.User, remote remote.Remote) { + repos, err := remote.GetRepos(user) + if err != nil { + log.Println("Error syncing user account, listing repositories", user.Login, err) + return + } + + // insert all repositories + for _, repo := range repos { + var role = repo.Role + if err := datastore.PostRepo(ctx, repo); err != nil { + // typically we see a failure because the repository already exists + // in which case, we can retrieve the existing record to get the ID. + repo, err = datastore.GetRepoName(ctx, repo.Host, repo.Owner, repo.Name) + if err != nil { + log.Println("Error adding repo.", user.Login, repo.Name, err) + continue + } + } + + // add user permissions + perm := model.Perm{ + UserID: user.ID, + RepoID: repo.ID, + Read: role.Read, + Write: role.Write, + Admin: role.Admin, + } + if err := datastore.PostPerm(ctx, &perm); err != nil { + log.Println("Error adding permissions.", user.Login, repo.Name, err) + continue + } + + log.Println("Successfully syced repo.", user.Login+"/"+repo.Name) + } + + user.Synced = time.Now().UTC().Unix() + user.Syncing = false + if err := datastore.PutUser(ctx, user); err != nil { + log.Println("Error syncing user account, updating sync date", user.Login, err) + return + } +}