Commit 7ef9e631f17e55dbcf91b3a35eba946d3f88ccf3

Authored by Andrew Buss
1 parent 6b261ad25f

allow static dir

Showing 7 changed files with 522 additions and 40 deletions Side-by-side Diff

1 1 *~
2 2 venv*
3   -static*
4 3 *.pyc
5 4 .idea*
6 5 .*.swp
1 1 all: styles/materialize.css styles/flashier.css fixjsstyle
2 2  
3   -JS_SOURCES = config.js $(wildcard scripts/*{Controller,Service,Directive}.js)
  3 +JS_SOURCES = config.js $(wildcard scripts/*Controller.js) $(wildcard scripts/*Directive.js) $(wildcard scripts/*Service.js)
4 4  
  5 +print-%:
  6 + @echo '$*=$($*)'
  7 +
5 8 styles/materialize.css: .PHONY
6 9 sassc sass/materialize.scss styles/materialize.css
7 10  
... ... @@ -9,7 +12,7 @@
9 12 sassc sass/flashier.scss styles/flashier.css
10 13  
11 14 fixjsstyle: .PHONY
12   - $(foreach sourcefile,$(JS_SOURCES),expand $(sourcefile) | sponge > $(sourcefile);)
  15 + $(foreach sourcefile,$(JS_SOURCES),expand $(sourcefile) | sponge $(sourcefile);)
13 16 fixjsstyle --flagfile gjslint.conf config.js scripts/*{Controller,Directive,Service}.js
14 17  
15 18 .PHONY:
scripts/ResetPasswordController.js View file @ 7ef9e63
... ... @@ -15,38 +15,38 @@
15 15 }*/
16 16 console.log('RESETTING');
17 17 $scope.confirmResetPass = function() {
18   - if ($scope.newPassword.length < 8) {
19   - $scope.unacceptable = true;
20   - return;
21   - }
22   - if ($scope.newPassword != $scope.confirmPassword) {
23   - $scope.mismatch = true;
24   - $scope.confirmPassword.$setPristine();
25   - console.log('mismatch');
26   - return;
27   - }
28   - /*password passes local tests*/
29   - $http.post('/api/reset_password/', JSON.stringify({
30   - 'uid': uid,
31   - 'token': token,
32   - 'new_password': $scope.newPassword
33   - }))
34   - .success(function(data) {
35   - $scope.error = false;
36   - $scope.success = true;
37   - //$state.go('resetpasssuccess');
38   - $timeout(function($state) {
39   - $state.go('login');
40   - }, 1000);
41   - console.log(data);
42   - })
43   - .error(function(data, status, header, config) {
44   - $scope.error = true;
45   - $scope.success = false;
46   - $scope.mismatch = false;
47   - $scope.unacceptable = false;
48   - console.log(data);
49   - });
  18 + if ($scope.newPassword.length < 8) {
  19 + $scope.unacceptable = true;
  20 + return;
  21 + }
  22 + if ($scope.newPassword != $scope.confirmPassword) {
  23 + $scope.mismatch = true;
  24 + $scope.confirmPassword.$setPristine();
  25 + console.log('mismatch');
  26 + return;
  27 + }
  28 + /*password passes local tests*/
  29 + $http.post('/api/reset_password/', JSON.stringify({
  30 + 'uid': uid,
  31 + 'token': token,
  32 + 'new_password': $scope.newPassword
  33 + }))
  34 + .success(function(data) {
  35 + $scope.error = false;
  36 + $scope.success = true;
  37 + //$state.go('resetpasssuccess');
  38 + $timeout(function($state) {
  39 + $state.go('login');
  40 + }, 1000);
  41 + console.log(data);
  42 + })
  43 + .error(function(data, status, header, config) {
  44 + $scope.error = true;
  45 + $scope.success = false;
  46 + $scope.mismatch = false;
  47 + $scope.unacceptable = false;
  48 + console.log(data);
  49 + });
50 50 };
51 51 $scope.cancelReset = function() {
52 52 $state.go('login');
scripts/SettingsController.js View file @ 7ef9e63
1 1 angular.module('flashy.SettingsController', ['ui.router']).
2 2  
3   - controller('SettingsController', function($scope) {
  3 + controller('SettingsController', function($scope) {
4 4  
5 5  
6   - $scope.changePassword = function(oldPassword, newPassword, confirmedNewPassword) {
  6 + $scope.changePassword = function(oldPassword, newPassword, confirmedNewPassword) {
7 7  
8 8  
9 9  
10 10  
11   - };
  11 + };
12 12  
13   - });
  13 + });
scripts/StudyController.js View file @ 7ef9e63
... ... @@ -4,7 +4,7 @@
4 4 function($scope, $stateParams, $state, $http, UserService) {
5 5 console.log('Flashy study controller content in this file. also hell0');
6 6 sectionId = $stateParams.sectionId;
7   - $scope.isParamOpen = true;
  7 + $scope.isParamOpen = true;
8 8  
9 9 $(document).ready(function() {
10 10 $('.datepicker').pickadate({
static/js/angular-contenteditable.js View file @ 7ef9e63
  1 +/**
  2 + * @see http://docs.angularjs.org/guide/concepts
  3 + * @see http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController
  4 + * @see https://github.com/angular/angular.js/issues/528#issuecomment-7573166
  5 + */
  6 +
  7 +angular.module('contenteditable', [])
  8 + .directive('contenteditable', ['$timeout', function($timeout) { return {
  9 + restrict: 'A',
  10 + require: '?ngModel',
  11 + link: function(scope, element, attrs, ngModel) {
  12 + // don't do anything unless this is actually bound to a model
  13 + if (!ngModel) {
  14 + return
  15 + }
  16 +
  17 + // options
  18 + var opts = {}
  19 + angular.forEach([
  20 + 'stripBr',
  21 + 'noLineBreaks',
  22 + 'selectNonEditable',
  23 + 'moveCaretToEndOnChange',
  24 + ], function(opt) {
  25 + var o = attrs[opt]
  26 + opts[opt] = o && o !== 'false'
  27 + })
  28 +
  29 + // view -> model
  30 + element.bind('input', function(e) {
  31 + scope.$apply(function() {
  32 + var html, html2, rerender
  33 + html = element.html()
  34 + rerender = false
  35 + if (opts.stripBr) {
  36 + html = html.replace(/<br>$/, '')
  37 + }
  38 + if (opts.noLineBreaks) {
  39 + html2 = html.replace(/<div>/g, '').replace(/<br>/g, '').replace(/<\/div>/g, '')
  40 + if (html2 !== html) {
  41 + rerender = true
  42 + html = html2
  43 + }
  44 + }
  45 + ngModel.$setViewValue(html)
  46 + if (rerender) {
  47 + ngModel.$render()
  48 + }
  49 + if (html === '') {
  50 + // the cursor disappears if the contents is empty
  51 + // so we need to refocus
  52 + $timeout(function(){
  53 + element[0].blur()
  54 + element[0].focus()
  55 + })
  56 + }
  57 + })
  58 + })
  59 +
  60 + // model -> view
  61 + var oldRender = ngModel.$render
  62 + ngModel.$render = function() {
  63 + var el, el2, range, sel
  64 + if (!!oldRender) {
  65 + oldRender()
  66 + }
  67 + element.html(ngModel.$viewValue || '')
  68 + if (opts.moveCaretToEndOnChange) {
  69 + el = element[0]
  70 + range = document.createRange()
  71 + sel = window.getSelection()
  72 + if (el.childNodes.length > 0) {
  73 + el2 = el.childNodes[el.childNodes.length - 1]
  74 + range.setStartAfter(el2)
  75 + } else {
  76 + range.setStartAfter(el)
  77 + }
  78 + range.collapse(true)
  79 + sel.removeAllRanges()
  80 + sel.addRange(range)
  81 + }
  82 + }
  83 + if (opts.selectNonEditable) {
  84 + element.bind('click', function(e) {
  85 + var range, sel, target
  86 + target = e.toElement
  87 + if (target !== this && angular.element(target).attr('contenteditable') === 'false') {
  88 + range = document.createRange()
  89 + sel = window.getSelection()
  90 + range.setStartBefore(target)
  91 + range.setEndAfter(target)
  92 + sel.removeAllRanges()
  93 + sel.addRange(range)
  94 + }
  95 + })
  96 + }
  97 + }
  98 + }}]);
static/js/angular-websocket.js View file @ 7ef9e63
  1 +(function() {
  2 + 'use strict';
  3 +
  4 + var noop = angular.noop;
  5 + var objectFreeze = (Object.freeze) ? Object.freeze : noop;
  6 + var objectDefineProperty = Object.defineProperty;
  7 + var isString = angular.isString;
  8 + var isFunction = angular.isFunction;
  9 + var isDefined = angular.isDefined;
  10 + var isObject = angular.isObject;
  11 + var isArray = angular.isArray;
  12 + var forEach = angular.forEach;
  13 + var arraySlice = Array.prototype.slice;
  14 + // ie8 wat
  15 + if (!Array.prototype.indexOf) {
  16 + Array.prototype.indexOf = function(elt /*, from*/) {
  17 + var len = this.length >>> 0;
  18 + var from = Number(arguments[1]) || 0;
  19 + from = (from < 0) ? Math.ceil(from) : Math.floor(from);
  20 + if (from < 0) {
  21 + from += len;
  22 + }
  23 +
  24 + for (; from < len; from++) {
  25 + if (from in this && this[from] === elt) { return from; }
  26 + }
  27 + return -1;
  28 + };
  29 + }
  30 +
  31 + // $WebSocketProvider.$inject = ['$rootScope', '$q', '$timeout', '$websocketBackend'];
  32 + function $WebSocketProvider($rootScope, $q, $timeout, $websocketBackend) {
  33 +
  34 + function $WebSocket(url, protocols, options) {
  35 + if (!options && isObject(protocols) && !isArray(protocols)) {
  36 + options = protocols;
  37 + protocols = undefined;
  38 + }
  39 +
  40 + this.protocols = protocols;
  41 + this.url = url || 'Missing URL';
  42 + this.ssl = /(wss)/i.test(this.url);
  43 +
  44 + // this.binaryType = '';
  45 + // this.extensions = '';
  46 + // this.bufferedAmount = 0;
  47 + // this.trasnmitting = false;
  48 + // this.buffer = [];
  49 +
  50 + // TODO: refactor options to use isDefined
  51 + this.scope = options && options.scope || $rootScope;
  52 + this.rootScopeFailover = options && options.rootScopeFailover && true;
  53 + this.useApplyAsync = options && options.useApplyAsync || false;
  54 + this.initialTimeout = options && options.initialTimeout || 500; // 500ms
  55 + this.maxTimeout = options && options.maxTimeout || 5 * 60 * 1000; // 5 minutes
  56 + this.reconnectIfNotNormalClose = options && options.reconnectIfNotNormalClose || false;
  57 +
  58 + this._reconnectAttempts = 0;
  59 + this.sendQueue = [];
  60 + this.onOpenCallbacks = [];
  61 + this.onMessageCallbacks = [];
  62 + this.onErrorCallbacks = [];
  63 + this.onCloseCallbacks = [];
  64 +
  65 + objectFreeze(this._readyStateConstants);
  66 +
  67 + if (url) {
  68 + this._connect();
  69 + } else {
  70 + this._setInternalState(0);
  71 + }
  72 +
  73 + }
  74 +
  75 +
  76 + $WebSocket.prototype._readyStateConstants = {
  77 + 'CONNECTING': 0,
  78 + 'OPEN': 1,
  79 + 'CLOSING': 2,
  80 + 'CLOSED': 3,
  81 + 'RECONNECT_ABORTED': 4
  82 + };
  83 +
  84 + $WebSocket.prototype._normalCloseCode = 1000;
  85 +
  86 + $WebSocket.prototype._reconnectableStatusCodes = [
  87 + 4000
  88 + ];
  89 +
  90 + $WebSocket.prototype.safeDigest = function safeDigest(autoApply) {
  91 + if (autoApply && !this.scope.$$phase) {
  92 + this.scope.$digest();
  93 + }
  94 + };
  95 +
  96 + $WebSocket.prototype.bindToScope = function bindToScope(scope) {
  97 + var self = this;
  98 + if (scope) {
  99 + this.scope = scope;
  100 + if (this.rootScopeFailover) {
  101 + this.scope.$on('$destroy', function() {
  102 + self.scope = $rootScope;
  103 + });
  104 + }
  105 + }
  106 + return self;
  107 + };
  108 +
  109 + $WebSocket.prototype._connect = function _connect(force) {
  110 + if (force || !this.socket || this.socket.readyState !== this._readyStateConstants.OPEN) {
  111 + this.socket = $websocketBackend.create(this.url, this.protocols);
  112 + this.socket.onmessage = angular.bind(this, this._onMessageHandler);
  113 + this.socket.onopen = angular.bind(this, this._onOpenHandler);
  114 + this.socket.onerror = angular.bind(this, this._onErrorHandler);
  115 + this.socket.onclose = angular.bind(this, this._onCloseHandler);
  116 + }
  117 + };
  118 +
  119 + $WebSocket.prototype.fireQueue = function fireQueue() {
  120 + while (this.sendQueue.length && this.socket.readyState === this._readyStateConstants.OPEN) {
  121 + var data = this.sendQueue.shift();
  122 +
  123 + this.socket.send(
  124 + isString(data.message) ? data.message : JSON.stringify(data.message)
  125 + );
  126 + data.deferred.resolve();
  127 + }
  128 + };
  129 +
  130 + $WebSocket.prototype.notifyOpenCallbacks = function notifyOpenCallbacks(event) {
  131 + for (var i = 0; i < this.onOpenCallbacks.length; i++) {
  132 + this.onOpenCallbacks[i].call(this, event);
  133 + }
  134 + };
  135 +
  136 + $WebSocket.prototype.notifyCloseCallbacks = function notifyCloseCallbacks(event) {
  137 + for (var i = 0; i < this.onCloseCallbacks.length; i++) {
  138 + this.onCloseCallbacks[i].call(this, event);
  139 + }
  140 + };
  141 +
  142 + $WebSocket.prototype.notifyErrorCallbacks = function notifyErrorCallbacks(event) {
  143 + for (var i = 0; i < this.onErrorCallbacks.length; i++) {
  144 + this.onErrorCallbacks[i].call(this, event);
  145 + }
  146 + };
  147 +
  148 + $WebSocket.prototype.onOpen = function onOpen(cb) {
  149 + this.onOpenCallbacks.push(cb);
  150 + return this;
  151 + };
  152 +
  153 + $WebSocket.prototype.onClose = function onClose(cb) {
  154 + this.onCloseCallbacks.push(cb);
  155 + return this;
  156 + };
  157 +
  158 + $WebSocket.prototype.onError = function onError(cb) {
  159 + this.onErrorCallbacks.push(cb);
  160 + return this;
  161 + };
  162 +
  163 +
  164 + $WebSocket.prototype.onMessage = function onMessage(callback, options) {
  165 + if (!isFunction(callback)) {
  166 + throw new Error('Callback must be a function');
  167 + }
  168 +
  169 + if (options && isDefined(options.filter) && !isString(options.filter) && !(options.filter instanceof RegExp)) {
  170 + throw new Error('Pattern must be a string or regular expression');
  171 + }
  172 +
  173 + this.onMessageCallbacks.push({
  174 + fn: callback,
  175 + pattern: options ? options.filter : undefined,
  176 + autoApply: options ? options.autoApply : true
  177 + });
  178 + return this;
  179 + };
  180 +
  181 + $WebSocket.prototype._onOpenHandler = function _onOpenHandler(event) {
  182 + this._reconnectAttempts = 0;
  183 + this.notifyOpenCallbacks(event);
  184 + this.fireQueue();
  185 + };
  186 +
  187 + $WebSocket.prototype._onCloseHandler = function _onCloseHandler(event) {
  188 + this.notifyCloseCallbacks(event);
  189 + if ((this.reconnectIfNotNormalClose && event.code !== this._normalCloseCode) || this._reconnectableStatusCodes.indexOf(event.code) > -1) {
  190 + this.reconnect();
  191 + }
  192 + };
  193 +
  194 + $WebSocket.prototype._onErrorHandler = function _onErrorHandler(event) {
  195 + this.notifyErrorCallbacks(event);
  196 + };
  197 +
  198 + $WebSocket.prototype._onMessageHandler = function _onMessageHandler(message) {
  199 + var pattern;
  200 + var self = this;
  201 + var currentCallback;
  202 + for (var i = 0; i < self.onMessageCallbacks.length; i++) {
  203 + currentCallback = self.onMessageCallbacks[i];
  204 + pattern = currentCallback.pattern;
  205 + if (pattern) {
  206 + if (isString(pattern) && message.data === pattern) {
  207 + applyAsyncOrDigest(currentCallback.fn, currentCallback.autoApply, message);
  208 + }
  209 + else if (pattern instanceof RegExp && pattern.exec(message.data)) {
  210 + applyAsyncOrDigest(currentCallback.fn, currentCallback.autoApply, message);
  211 + }
  212 + }
  213 + else {
  214 + applyAsyncOrDigest(currentCallback.fn, currentCallback.autoApply, message);
  215 + }
  216 + }
  217 +
  218 + function applyAsyncOrDigest(callback, autoApply, args) {
  219 + args = arraySlice.call(arguments, 2);
  220 + if (self.useApplyAsync) {
  221 + self.scope.$applyAsync(function() {
  222 + callback.apply(self, args);
  223 + });
  224 + } else {
  225 + callback.apply(self, args);
  226 + self.safeDigest(autoApply);
  227 + }
  228 + }
  229 +
  230 + };
  231 +
  232 + $WebSocket.prototype.close = function close(force) {
  233 + if (force || !this.socket.bufferedAmount) {
  234 + this.socket.close();
  235 + }
  236 + return this;
  237 + };
  238 +
  239 + $WebSocket.prototype.send = function send(data) {
  240 + var deferred = $q.defer();
  241 + var self = this;
  242 + var promise = cancelableify(deferred.promise);
  243 +
  244 + if (self.readyState === self._readyStateConstants.RECONNECT_ABORTED) {
  245 + deferred.reject('Socket connection has been closed');
  246 + }
  247 + else {
  248 + self.sendQueue.push({
  249 + message: data,
  250 + deferred: deferred
  251 + });
  252 + self.fireQueue();
  253 + }
  254 +
  255 + // Credit goes to @btford
  256 + function cancelableify(promise) {
  257 + promise.cancel = cancel;
  258 + var then = promise.then;
  259 + promise.then = function() {
  260 + var newPromise = then.apply(this, arguments);
  261 + return cancelableify(newPromise);
  262 + };
  263 + return promise;
  264 + }
  265 +
  266 + function cancel(reason) {
  267 + self.sendQueue.splice(self.sendQueue.indexOf(data), 1);
  268 + deferred.reject(reason);
  269 + return self;
  270 + }
  271 +
  272 + if ($websocketBackend.isMocked && $websocketBackend.isMocked() &&
  273 + $websocketBackend.isConnected(this.url)) {
  274 + this._onMessageHandler($websocketBackend.mockSend());
  275 + }
  276 +
  277 + return promise;
  278 + };
  279 +
  280 + $WebSocket.prototype.reconnect = function reconnect() {
  281 + this.close();
  282 +
  283 + var backoffDelay = this._getBackoffDelay(++this._reconnectAttempts);
  284 +
  285 + var backoffDelaySeconds = backoffDelay / 1000;
  286 + console.log('Reconnecting in ' + backoffDelaySeconds + ' seconds');
  287 +
  288 + $timeout(angular.bind(this, this._connect), backoffDelay);
  289 +
  290 + return this;
  291 + };
  292 + // Exponential Backoff Formula by Prof. Douglas Thain
  293 + // http://dthain.blogspot.co.uk/2009/02/exponential-backoff-in-distributed.html
  294 + $WebSocket.prototype._getBackoffDelay = function _getBackoffDelay(attempt) {
  295 + var R = Math.random() + 1;
  296 + var T = this.initialTimeout;
  297 + var F = 2;
  298 + var N = attempt;
  299 + var M = this.maxTimeout;
  300 +
  301 + return Math.floor(Math.min(R * T * Math.pow(F, N), M));
  302 + };
  303 +
  304 + $WebSocket.prototype._setInternalState = function _setInternalState(state) {
  305 + if (Math.floor(state) !== state || state < 0 || state > 4) {
  306 + throw new Error('state must be an integer between 0 and 4, got: ' + state);
  307 + }
  308 +
  309 + // ie8 wat
  310 + if (!objectDefineProperty) {
  311 + this.readyState = state || this.socket.readyState;
  312 + }
  313 + this._internalConnectionState = state;
  314 +
  315 +
  316 + forEach(this.sendQueue, function(pending) {
  317 + pending.deferred.reject('Message cancelled due to closed socket connection');
  318 + });
  319 + };
  320 +
  321 + // Read only .readyState
  322 + if (objectDefineProperty) {
  323 + objectDefineProperty($WebSocket.prototype, 'readyState', {
  324 + get: function() {
  325 + return this._internalConnectionState || this.socket.readyState;
  326 + },
  327 + set: function() {
  328 + throw new Error('The readyState property is read-only');
  329 + }
  330 + });
  331 + }
  332 +
  333 + return function(url, protocols) {
  334 + return new $WebSocket(url, protocols);
  335 + };
  336 + }
  337 +
  338 + // $WebSocketBackendProvider.$inject = ['$window', '$log'];
  339 + function $WebSocketBackendProvider($window, $log) {
  340 + this.create = function create(url, protocols) {
  341 + var match = /wss?:\/\//.exec(url);
  342 + var Socket, ws;
  343 + if (!match) {
  344 + throw new Error('Invalid url provided');
  345 + }
  346 +
  347 + // CommonJS
  348 + if (typeof exports === 'object' && require) {
  349 + try {
  350 + ws = require('ws');
  351 + Socket = (ws.Client || ws.client || ws);
  352 + } catch(e) {}
  353 + }
  354 +
  355 + // Browser
  356 + Socket = Socket || $window.WebSocket || $window.MozWebSocket;
  357 +
  358 + if (protocols) {
  359 + return new Socket(url, protocols);
  360 + }
  361 +
  362 + return new Socket(url);
  363 + };
  364 + this.createWebSocketBackend = function createWebSocketBackend(url, protocols) {
  365 + $log.warn('Deprecated: Please use .create(url, protocols)');
  366 + return this.create(url, protocols);
  367 + };
  368 + }
  369 +
  370 + angular.module('ngWebSocket', [])
  371 + .factory('$websocket', ['$rootScope', '$q', '$timeout', '$websocketBackend', $WebSocketProvider])
  372 + .factory('WebSocket', ['$rootScope', '$q', '$timeout', 'WebsocketBackend', $WebSocketProvider])
  373 + .service('$websocketBackend', ['$window', '$log', $WebSocketBackendProvider])
  374 + .service('WebSocketBackend', ['$window', '$log', $WebSocketBackendProvider]);
  375 +
  376 +
  377 + angular.module('angular-websocket', ['ngWebSocket']);
  378 +
  379 + if (typeof module === 'object' && typeof define !== 'function') {
  380 + module.exports = angular.module('ngWebSocket');
  381 + }
  382 +}());