mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-24 08:02:18 +02:00
got websockets working. added stubs for html5 notifications api
This commit is contained in:
parent
77daa5743f
commit
e8abb11c19
@ -6,6 +6,8 @@ env:
|
||||
- PATH=$PATH:$GOROOT/bin:$GOPATH/bin
|
||||
script:
|
||||
- sudo apt-get -y install libsqlite3-dev sqlite3 1> /dev/null 2> /dev/null
|
||||
- sudo npm install -g uglify-js
|
||||
- sudo npm install -g less
|
||||
- make deps
|
||||
- make build
|
||||
- make test
|
||||
|
@ -37,7 +37,9 @@
|
||||
<script src="/scripts/services/conf.js"></script>
|
||||
<script src="/scripts/services/repo.js"></script>
|
||||
<script src="/scripts/services/user.js"></script>
|
||||
<script src="/scripts/services/ws.js"></script>
|
||||
<script src="/scripts/services/feed.js"></script>
|
||||
<script src="/scripts/services/notify.js"></script>
|
||||
<script src="/scripts/services/stdout.js"></script>
|
||||
<script src="/scripts/filters/filters.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -280,14 +280,6 @@ app.controller("RepoController", function($scope, $http, $routeParams, user, rep
|
||||
});
|
||||
};
|
||||
|
||||
$scope.options={
|
||||
barColor:"#40C598",
|
||||
trackColor:'#EEEEEE',
|
||||
scaleColor:false,
|
||||
lineWidth:10,
|
||||
lineCap:'butt',
|
||||
size:130
|
||||
};
|
||||
});
|
||||
|
||||
app.controller("BranchController", function($scope, $http, $routeParams, user) {
|
||||
@ -327,15 +319,21 @@ app.controller("BranchController", function($scope, $http, $routeParams, user) {
|
||||
});
|
||||
});
|
||||
|
||||
app.controller("CommitController", function($scope, $http, $routeParams, user) {
|
||||
app.controller("CommitController", function($scope, $http, $routeParams, stdout, feed) {
|
||||
|
||||
$scope.user = user;
|
||||
var remote = $routeParams.remote;
|
||||
var owner = $routeParams.owner;
|
||||
var name = $routeParams.name;
|
||||
var branch = $routeParams.branch;
|
||||
var commit = $routeParams.commit;
|
||||
|
||||
feed.subscribe(function(event) {
|
||||
if (event.commit.sha == commit
|
||||
&& event.commit.branch == branch) {
|
||||
$scope.commit = event.commit;
|
||||
}
|
||||
});
|
||||
|
||||
// load the repo meta-data
|
||||
$http({method: 'GET', url: '/v1/repos/'+remote+'/'+owner+"/"+name}).
|
||||
success(function(data, status, headers, config) {
|
||||
@ -351,6 +349,14 @@ app.controller("CommitController", function($scope, $http, $routeParams, user) {
|
||||
$scope.commit = data;
|
||||
$scope.coverage=45;
|
||||
$scope.passing=100;
|
||||
|
||||
if (data.status!='Started' && data.status!='Pending') {
|
||||
return;
|
||||
}
|
||||
|
||||
stdout.subscribe(data.id, function(out){
|
||||
console.log(out);
|
||||
});
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log(data);
|
||||
@ -375,21 +381,6 @@ app.controller("CommitController", function($scope, $http, $routeParams, user) {
|
||||
});
|
||||
|
||||
|
||||
$scope.options={
|
||||
barColor:"#40C598",
|
||||
trackColor:'#EEEEEE',
|
||||
scaleColor:false,
|
||||
lineWidth:10,
|
||||
lineCap:'butt',
|
||||
size:130
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
function barColor(percent) {
|
||||
switch(true) {
|
||||
case percent > 80: return "#40C598";
|
||||
case percent < 50: return "rgba(189, 54, 47, 0.8)";
|
||||
default: return "#f0ad4e";
|
||||
}
|
||||
}
|
||||
});
|
@ -1,11 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app').controller("HomeController", function($scope, $http, user, websocket) {
|
||||
angular.module('app').controller("HomeController", function($scope, $http, feed, notify) {
|
||||
|
||||
$scope.user = user;
|
||||
|
||||
websocket.subscribeRepos(function(repos) {
|
||||
console.log(repos);
|
||||
feed.subscribe(function(message) {
|
||||
notify.send(message.repo.name);
|
||||
});
|
||||
|
||||
$http({method: 'GET', url: '/v1/user/feed'}).
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app').controller("UserController", function($scope, $http, user) {
|
||||
angular.module('app').controller("UserController", function($scope, $http, user, notify) {
|
||||
|
||||
$scope.user = user;
|
||||
|
||||
@ -17,6 +17,10 @@ angular.module('app').controller("UserController", function($scope, $http, user)
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
$scope.notifications = {}
|
||||
$scope.notifications.supported = notify.supported();
|
||||
$scope.notifications.granted = notify.granted();
|
||||
|
||||
$scope.save = function() {
|
||||
// request to create a new repository
|
||||
$http({method: 'PUT', url: '/v1/user', data: $scope.userTemp }).
|
||||
@ -35,4 +39,7 @@ angular.module('app').controller("UserController", function($scope, $http, user)
|
||||
name : $scope.user.name
|
||||
};
|
||||
};
|
||||
$scope.enableNotifications = function() {
|
||||
notify.requestPermission();
|
||||
};
|
||||
});
|
24
server/app/scripts/services/feed.js
Normal file
24
server/app/scripts/services/feed.js
Normal file
@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app').service('feed', ['$http', '$window', function($http, $window) {
|
||||
|
||||
var proto = ($window.location.protocol == 'https:' ? 'wss' : 'ws');
|
||||
var route = [proto, "://", $window.location.host, '/ws/user'].join('');
|
||||
|
||||
var wsCallback = undefined;
|
||||
var ws = new WebSocket(route);
|
||||
ws.onmessage = function(event) {
|
||||
var data = angular.fromJson(event.data);
|
||||
if (wsCallback != undefined) {
|
||||
wsCallback(data);
|
||||
}
|
||||
};
|
||||
|
||||
this.subscribe = function(callback) {
|
||||
wsCallback = callback;
|
||||
};
|
||||
|
||||
this.unsubscribe = function() {
|
||||
ws.close();
|
||||
};
|
||||
}]);
|
23
server/app/scripts/services/notify.js
Normal file
23
server/app/scripts/services/notify.js
Normal file
@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app').service('notify', ['$window', '$timeout', function($window, $timeout) {
|
||||
|
||||
this.supported = function() {
|
||||
return ("Notification" in $window)
|
||||
}
|
||||
|
||||
this.granted = function() {
|
||||
return ("Notification" in $window) && Notification.permission === "granted";
|
||||
}
|
||||
|
||||
this.requestPermission = function() {
|
||||
Notification.requestPermission();
|
||||
}
|
||||
|
||||
this.send = function(title, opts) {
|
||||
if ("Notification" in $window) {
|
||||
var n = new Notification(title, opts);
|
||||
$timeout(function() { n.close(); }, 10000);
|
||||
}
|
||||
};
|
||||
}]);
|
27
server/app/scripts/services/stdout.js
Normal file
27
server/app/scripts/services/stdout.js
Normal file
@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app').service('stdout', ['$window', function($window) {
|
||||
var callback = undefined;
|
||||
var websocket = undefined;
|
||||
|
||||
this.subscribe = function(path, _callback) {
|
||||
callback = _callback;
|
||||
|
||||
var proto = ($window.location.protocol == 'https:' ? 'wss' : 'ws');
|
||||
var route = [proto, "://", $window.location.host, '/ws/stdout/', path].join('');
|
||||
|
||||
websocket = new WebSocket(route);
|
||||
websocket.onmessage = function(event) {
|
||||
if (callback != undefined) {
|
||||
callback(event.data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.unsubscribe = function() {
|
||||
callback = undefined;
|
||||
if (webscoket != undefined) {
|
||||
websocket.close();
|
||||
}
|
||||
};
|
||||
}]);
|
@ -1,18 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app').service('websocket', function($q, $http, $window) {
|
||||
var wsCallback = undefined;
|
||||
var ws = new WebSocket('ws://localhost:8080/ws/user');
|
||||
ws.onmessage = function(event) {
|
||||
var data = angular.fromJson(event.data);
|
||||
if (wsCallback != undefined) {
|
||||
wsCallback(data);
|
||||
}
|
||||
};
|
||||
return {
|
||||
subscribeRepos: function(callback) {
|
||||
wsCallback = callback;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -54,6 +54,10 @@
|
||||
{{failure}}
|
||||
</div>
|
||||
|
||||
<div ng-if="notifications.supported && !notifications.granted">
|
||||
<button ng-click="enableNotifications()">Enable Notifications</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button ng-click="save()">Save</button>
|
||||
<button ng-click="cancel()">Cancel</button>
|
||||
|
@ -27,6 +27,10 @@ type PermManager interface {
|
||||
// Admin returns true if the specified user is an
|
||||
// administrator of the repository.
|
||||
Admin(u *model.User, r *model.Repo) (bool, error)
|
||||
|
||||
// Member returns true if the specified user is a
|
||||
// collaborator on the repository.
|
||||
Member(u *model.User, r *model.Repo) (bool, error)
|
||||
}
|
||||
|
||||
// permManager manages user permissions to access repositories.
|
||||
@ -147,6 +151,20 @@ func (db *permManager) Admin(u *model.User, r *model.Repo) (bool, error) {
|
||||
return perm.Admin, err
|
||||
}
|
||||
|
||||
func (db *permManager) Member(u *model.User, r *model.Repo) (bool, error) {
|
||||
switch {
|
||||
// if the user is nil, deny access
|
||||
case u == nil:
|
||||
return false, nil
|
||||
case u.ID == r.UserID:
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// get the permissions from the database
|
||||
perm, err := db.find(u, r)
|
||||
return perm.Read, err
|
||||
}
|
||||
|
||||
func (db *permManager) find(u *model.User, r *model.Repo) (*perm, error) {
|
||||
var dst = perm{}
|
||||
var err = meddler.QueryRow(db, &dst, findPermQuery, u.ID, r.ID)
|
||||
|
@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/drone/drone/server/database"
|
||||
@ -77,7 +78,7 @@ func (h *WsHandler) WsUser(w http.ResponseWriter, r *http.Request) error {
|
||||
|
||||
// user must have read access to the repository
|
||||
// in order to pass this message along
|
||||
if ok, _ := h.perms.Read(user, work.Repo); !ok {
|
||||
if ok, _ := h.perms.Member(user, work.Repo); !ok {
|
||||
break
|
||||
}
|
||||
|
||||
@ -109,15 +110,13 @@ func (h *WsHandler) WsUser(w http.ResponseWriter, r *http.Request) error {
|
||||
// WsConsole will upgrade the connection to a Websocket and will stream
|
||||
// the build output to the browser.
|
||||
func (h *WsHandler) WsConsole(w http.ResponseWriter, r *http.Request) error {
|
||||
var host, owner, name = parseRepo(r)
|
||||
var branch = r.FormValue(":branch")
|
||||
var sha = r.FormValue(":commit")
|
||||
var commitID, _ = strconv.Atoi(r.FormValue(":id"))
|
||||
|
||||
repo, err := h.repos.FindName(host, owner, name)
|
||||
commit, err := h.commits.Find(int64(commitID))
|
||||
if err != nil {
|
||||
return notFound{err}
|
||||
}
|
||||
commit, err := h.commits.FindSha(repo.ID, branch, sha)
|
||||
repo, err := h.repos.Find(commit.RepoID)
|
||||
if err != nil {
|
||||
return notFound{err}
|
||||
}
|
||||
@ -212,5 +211,5 @@ func (h *WsHandler) Ping(w http.ResponseWriter, r *http.Request) error {
|
||||
func (h *WsHandler) Register(r *pat.Router) {
|
||||
r.Post("/ws/ping", errorHandler(h.Ping))
|
||||
r.Get("/ws/user", errorHandler(h.WsUser))
|
||||
r.Get("/ws/{host}/{owner}/{name}/branches/{branch}/commits/{commit}", errorHandler(h.WsConsole))
|
||||
r.Get("/ws/stdout/{id}", errorHandler(h.WsConsole))
|
||||
}
|
||||
|
@ -19,3 +19,8 @@ var DefaultOpts = &Opts{
|
||||
Timeout: 0,
|
||||
Record: false,
|
||||
}
|
||||
|
||||
var ConsoleOpts = &Opts{
|
||||
Timeout: time.Minute * 60,
|
||||
Record: true,
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
User *model.User
|
||||
Repo *model.Repo
|
||||
Commit *model.Commit
|
||||
User *model.User `json:"-"`
|
||||
Repo *model.Repo `json:"repo"`
|
||||
Commit *model.Commit `json:"commit"`
|
||||
server *model.Server
|
||||
}
|
||||
|
@ -84,9 +84,9 @@ func (w *worker) Execute(r *Request) {
|
||||
w.commits.Update(r.Commit)
|
||||
|
||||
// notify all listeners that the build is started
|
||||
commitc := w.pubsub.Register("_")
|
||||
commitc := w.pubsub.Register("_global")
|
||||
commitc.Publish(r)
|
||||
stdoutc := w.pubsub.Register(r.Commit.ID)
|
||||
stdoutc := w.pubsub.RegisterOpts(r.Commit.ID, pubsub.ConsoleOpts)
|
||||
defer stdoutc.Close()
|
||||
|
||||
// create a special buffer that will also
|
||||
|
Loading…
Reference in New Issue
Block a user