<commit_before>var xml2js = require("xml2js"),
    deepmerge = require("deepmerge");

var fetch = require("./request.js"),
    parsing = require("./parse.js"),
    responseHandlers = require("./response.js");

module.exports = {

    getDirectoryContents: function getDirectoryContents(url, dirPath, options) {
        dirPath = dirPath || "/";
        options = options || { headers: {} };
        var fetchURL = url + dirPath;
        return fetch(
                fetchURL,
                {
                    method: "PROPFIND",
                    headers: deepmerge(
                        {
                            Depth: 1
                        },
                        options.headers
                    )
                }
            )
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.text();
            })
            .then(function(body) {
                var parser = new xml2js.Parser({
                    ignoreAttrs: true
                });
                return new Promise(function(resolve, reject) {
                    parser.parseString(body, function (err, result) {
                        if (err) {
                            reject(err);
                        } else {
                            resolve(parsing.parseDirectoryLookup(dirPath, result));
                        }
                    });
                });
            });
    },

    getFileContents: function getFileContents(url, filePath, options) {
        options = options || { headers: {} };
        return fetch(url + filePath, {
                method: "GET",
                headers: options.headers
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.buffer();
            });
    },

    getStat: function getStat(url, itemPath, options) {
        options = options || { headers: {} };
        return fetch(url + itemPath, {
                method: "PROPFIND",
                headers: deepmerge(
                    {
                        Depth: 1
                    },
                    options.headers
                )
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.text();
            })
            .then(function(body) {
                var parser = new xml2js.Parser({
                    ignoreAttrs: true
                });
                return new Promise(function(resolve, reject) {
                    parser.parseString(body, function (err, result) {
                        if (err) {
                            reject(err);
                        } else {
                            var targetPath = itemPath.replace(/^\//, "");
                            resolve(parsing.parseDirectoryLookup(targetPath, result, true));
                        }
                    });
                });
            })
            .then(function(stats) {
                return stats.shift();
            });
    },

    getTextContents: function getTextContents(url, filePath, options) {
        options = options || { headers: {} };
        return fetch(url + filePath, {
                headers: options.headers
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.text();
            });
    }

};
<commit_msg>Add get+create read stream<commit_after>var xml2js = require("xml2js"),
    deepmerge = require("deepmerge");

var Stream = require("stream"),
    ReadableStream = Stream.Readable,
    PassThroughStream = Stream.PassThrough;

var fetch = require("./request.js"),
    parsing = require("./parse.js"),
    responseHandlers = require("./response.js");

var adapter = module.exports = {

    createReadStream: function createReadStream(url, filePath, options) {
        var outStream = new PassThroughStream();
        adapter
            .getFileStream(url, filePath, options)
            .then(function __handleStream(stream) {
                stream.pipe(outStream);
            })
            .catch(function __handleReadError(err) {
                outStream.emit("error", err);
            });
        return outStream;
    },

    getDirectoryContents: function getDirectoryContents(url, dirPath, options) {
        dirPath = dirPath || "/";
        options = options || { headers: {} };
        var fetchURL = url + dirPath;
        return fetch(
                fetchURL,
                {
                    method: "PROPFIND",
                    headers: deepmerge(
                        {
                            Depth: 1
                        },
                        options.headers
                    )
                }
            )
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.text();
            })
            .then(function(body) {
                var parser = new xml2js.Parser({
                    ignoreAttrs: true
                });
                return new Promise(function(resolve, reject) {
                    parser.parseString(body, function (err, result) {
                        if (err) {
                            reject(err);
                        } else {
                            resolve(parsing.parseDirectoryLookup(dirPath, result));
                        }
                    });
                });
            });
    },

    getFileContents: function getFileContents(url, filePath, options) {
        options = options || { headers: {} };
        return fetch(url + filePath, {
                method: "GET",
                headers: options.headers
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.buffer();
            });
    },

    getFileStream: function getFileStream(url, filePath, options) {
        options = options || { headers: {} };
        return fetch(url + filePath, {
                method: "GET",
                headers: deepmerge(
                    {
                        // todo range
                    },
                    options.headers
                )
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.body;
            });
    },

    getStat: function getStat(url, itemPath, options) {
        options = options || { headers: {} };
        return fetch(url + itemPath, {
                method: "PROPFIND",
                headers: deepmerge(
                    {
                        Depth: 1
                    },
                    options.headers
                )
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.text();
            })
            .then(function(body) {
                var parser = new xml2js.Parser({
                    ignoreAttrs: true
                });
                return new Promise(function(resolve, reject) {
                    parser.parseString(body, function (err, result) {
                        if (err) {
                            reject(err);
                        } else {
                            var targetPath = itemPath.replace(/^\//, "");
                            resolve(parsing.parseDirectoryLookup(targetPath, result, true));
                        }
                    });
                });
            })
            .then(function(stats) {
                return stats.shift();
            });
    },

    getTextContents: function getTextContents(url, filePath, options) {
        options = options || { headers: {} };
        return fetch(url + filePath, {
                headers: options.headers
            })
            .then(responseHandlers.handleResponseCode)
            .then(function(res) {
                return res.text();
            });
    }

};
<|endoftext|>


<commit_before>/* ========================================================================
 * Bootstrap-Pagy
 * http://getbootstrap.com/javascript/#popovers
 * ========================================================================
 * Copyright 2013 Kai Schlamp
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */

+function ($) { "use strict";

	var PageProxy = function(options, page) {
		this.isCurrent = function() { return page == options.currentPage }
		this.isFirst = function() { return page == 1 }
		this.isLast = function() { return page == options.totalPages }
		this.isPrev = function() { return page == (options.currentPage - 1) }
		this.isNext = function() { return page == (options.currentPage + 1) }
		this.isLeftOuter = function() { return page <= options.outerWindow }
		this.isRightOuter = function() { return (options.totalPages - page) < options.outerWindow }
		this.isInsideWindow = function() { return Math.abs(options.currentPage -page) <= options.innerWindow }
		this.number = function() { return page }
	}

	var View = {
		firstPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.html(options.first)
				.bind('click.bs-pagy', function() {
					pagy.firstPage();
					return false;
				}));

			if (currentPageProxy.isFirst()) {
				li.addClass("disabled");
			}

			return li;
		},

		prevPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.attr("rel", "prev")
				.html(options.prev)
				.bind('click.bs-pagy', function() {
					pagy.prevPage();
					return false;
				}));

			if (currentPageProxy.isFirst()) {
				li.addClass("disabled");
			}

			return li;
		},

		nextPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.attr("rel", "next")
				.html(options.next)
				.bind('click.bs-pagy', function() {
					pagy.nextPage();
					return false;
				}));

			if (currentPageProxy.isLast()) {
				li.addClass("disabled");
			}

			return li;
		},

		lastPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.html(options.last)
				.bind('click.bs-pagy', function() {
					pagy.lastPage();
					return false;
				}));

			if (currentPageProxy.isLast()) {
				li.addClass("disabled");
			}

			return li;
		},

		gap: function(pagy, options) {
			return $('
').addClass("disabled")
				.append($('').html(options.gap));
		},

		page: function(pagy, options, pageProxy) {
			var li = $('
').append(function() {
				var link = $('');
				if (pageProxy.isNext()) { link.attr("rel", "next") }
				if (pageProxy.isPrev()) { link.attr("rel", "prev") }
				link.html(pageProxy.number());
				link.bind('click.bs-pagy', function() {
					pagy.page(pageProxy.number());
					return false;
				});
				return link;
			});

			if (pageProxy.isCurrent()) {
				li.addClass("active");
			}

			return li;
		}
	}

  // PAGY PUBLIC CLASS DEFINITION
  // ===============================

  var Pagy = function (element, options) {
		this.$element = $(element);
		this.options = $.extend({}, Pagy.DEFAULTS, options);

		this.$ul = this.$element.find("ul");

		this.render();
  }

  Pagy.DEFAULTS = {
    currentPage: null
  , totalPages: null
  , innerWindow: 2
  , outerWindow: 0
  , first: '«'
  , prev: '‹'
  , next: '›'
  , last: '»'
  , gap: '...'
	, truncate: true
  , page: function(page) { return true }
  }

	Pagy.prototype.render = function () {
		var options = this.options;

		if (!options.totalPages) return;

		var currentPageProxy = new PageProxy(options, options.currentPage);

		if (!currentPageProxy.isFirst() || !options.truncate) {
			if (options.first) {
				this.$ul.append(View.firstPage(this, options, currentPageProxy));
			}

			if (options.prev) {
				this.$ul.append(View.prevPage(this, options, currentPageProxy));
			}
		}

		var wasTruncated = false;
		for (var i = 1, length = options.totalPages; i <= length; i++) {
			var pageProxy = new PageProxy(options, i);
			if (pageProxy.isLeftOuter() || pageProxy.isRightOuter() || pageProxy.isInsideWindow()) {
				this.$ul.append(View.page(this, options, pageProxy));
				wasTruncated = false;
			}
			else {
				if (!wasTruncated && options.outerWindow > 0) {
					this.$ul.append(View.gap(this, options));
					wasTruncated = true;
				}
			}
		}

		if (!currentPageProxy.isLast() || !options.truncate) {
			if (options.next) {
				this.$ul.append(View.nextPage(this, options, currentPageProxy));
			}

			if (options.last) {
				this.$ul.append(View.lastPage(this, options, currentPageProxy));
			}
		}
	}

	Pagy.prototype.page = function (page, totalPages) {
		var options = this.options;

		if (totalPages === undefined) {
			totalPages = options.totalPages;
		}

		if (page > 0 && page <= totalPages) {
			if (options.page(page)) {
				this.$ul.empty();
				options.currentPage = page;
				options.totalPages = totalPages;
				this.render();
			}
		}

		return false;
	}

	Pagy.prototype.firstPage = function () {
		return this.page(1);
	}

	Pagy.prototype.lastPage = function () {
		return this.page(this.options.totalPages);
	}

	Pagy.prototype.nextPage = function () {
		return this.page(this.options.currentPage + 1);
	}

	Pagy.prototype.prevPage = function () {
		return this.page(this.options.currentPage - 1);
	}

  // PAGY PLUGIN DEFINITION
  // =========================

  var old = $.fn.pagy;

  $.fn.pagy = function (option) {
		var args = arguments;

    return this.each(function () {
      var $this   = $(this);
      var data    = $this.data('bs.pagy');
      var options = typeof option == 'object' && option;

      if (!data) $this.data('bs.pagy', (data = new Pagy(this, options)));
      if (typeof option == 'string') {
				data[option].apply(data, Array.prototype.slice.call(args, 1));
			}
    });
  }

  $.fn.pagy.Constructor = Pagy;

  // PAGY NO CONFLICT
  // ===================

  $.fn.pagy.noConflict = function () {
    $.fn.pagy = old;
    return this;
  }

}(jQuery);
<commit_msg>hide pagination when there a now pages to show<commit_after>/* ========================================================================
 * Bootstrap-Pagy
 * http://getbootstrap.com/javascript/#popovers
 * ========================================================================
 * Copyright 2013 Kai Schlamp
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */

+function ($) { "use strict";

	var PageProxy = function(options, page) {
		this.isCurrent = function() { return page == options.currentPage }
		this.isFirst = function() { return page == 1 }
		this.isLast = function() { return page == options.totalPages }
		this.isPrev = function() { return page == (options.currentPage - 1) }
		this.isNext = function() { return page == (options.currentPage + 1) }
		this.isLeftOuter = function() { return page <= options.outerWindow }
		this.isRightOuter = function() { return (options.totalPages - page) < options.outerWindow }
		this.isInsideWindow = function() { return Math.abs(options.currentPage - page) <= options.innerWindow }
		this.number = function() { return page }
	}

	var View = {
		firstPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.html(options.first)
				.bind('click.bs-pagy', function() {
					pagy.firstPage();
					return false;
				}));

			if (currentPageProxy.isFirst()) {
				li.addClass("disabled");
			}

			return li;
		},

		prevPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.attr("rel", "prev")
				.html(options.prev)
				.bind('click.bs-pagy', function() {
					pagy.prevPage();
					return false;
				}));

			if (currentPageProxy.isFirst()) {
				li.addClass("disabled");
			}

			return li;
		},

		nextPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.attr("rel", "next")
				.html(options.next)
				.bind('click.bs-pagy', function() {
					pagy.nextPage();
					return false;
				}));

			if (currentPageProxy.isLast()) {
				li.addClass("disabled");
			}

			return li;
		},

		lastPage: function(pagy, options, currentPageProxy) {
			var li = $('
').append(
				$('')
				.html(options.last)
				.bind('click.bs-pagy', function() {
					pagy.lastPage();
					return false;
				}));

			if (currentPageProxy.isLast()) {
				li.addClass("disabled");
			}

			return li;
		},

		gap: function(pagy, options) {
			return $('
').addClass("disabled")
				.append($('').html(options.gap));
		},

		page: function(pagy, options, pageProxy) {
			var li = $('
').append(function() {
				var link = $('');
				if (pageProxy.isNext()) { link.attr("rel", "next") }
				if (pageProxy.isPrev()) { link.attr("rel", "prev") }
				link.html(pageProxy.number());
				link.bind('click.bs-pagy', function() {
					pagy.page(pageProxy.number());
					return false;
				});
				return link;
			});

			if (pageProxy.isCurrent()) {
				li.addClass("active");
			}

			return li;
		}
	}

  // PAGY PUBLIC CLASS DEFINITION
  // ===============================

  var Pagy = function (element, options) {
		this.$element = $(element);
		this.options = $.extend({}, Pagy.DEFAULTS, options);

		this.$ul = this.$element.find("ul");

		this.render();
  }

  Pagy.DEFAULTS = {
    currentPage: null
  , totalPages: null
  , innerWindow: 2
  , outerWindow: 0
  , first: '«'
  , prev: '‹'
  , next: '›'
  , last: '»'
  , gap: '...'
	, truncate: true
  , page: function(page) { return true }
  }

	Pagy.prototype.render = function () {
		var options = this.options;

		if (!options.totalPages) {
			this.$element.hide();
			return;
		}
		else {
			this.$element.show();
		}

		var currentPageProxy = new PageProxy(options, options.currentPage);

		if (!currentPageProxy.isFirst() || !options.truncate) {
			if (options.first) {
				this.$ul.append(View.firstPage(this, options, currentPageProxy));
			}

			if (options.prev) {
				this.$ul.append(View.prevPage(this, options, currentPageProxy));
			}
		}

		var wasTruncated = false;
		for (var i = 1, length = options.totalPages; i <= length; i++) {
			var pageProxy = new PageProxy(options, i);
			if (pageProxy.isLeftOuter() || pageProxy.isRightOuter() || pageProxy.isInsideWindow()) {
				this.$ul.append(View.page(this, options, pageProxy));
				wasTruncated = false;
			}
			else {
				if (!wasTruncated && options.outerWindow > 0) {
					this.$ul.append(View.gap(this, options));
					wasTruncated = true;
				}
			}
		}

		if (!currentPageProxy.isLast() || !options.truncate) {
			if (options.next) {
				this.$ul.append(View.nextPage(this, options, currentPageProxy));
			}

			if (options.last) {
				this.$ul.append(View.lastPage(this, options, currentPageProxy));
			}
		}
	}

	Pagy.prototype.page = function (page, totalPages) {
		var options = this.options;

		if (totalPages === undefined) {
			totalPages = options.totalPages;
		}

		if (page > 0 && page <= totalPages) {
			if (options.page(page)) {
				this.$ul.empty();
				options.currentPage = page;
				options.totalPages = totalPages;
				this.render();
			}
		}

		return false;
	}

	Pagy.prototype.firstPage = function () {
		return this.page(1);
	}

	Pagy.prototype.lastPage = function () {
		return this.page(this.options.totalPages);
	}

	Pagy.prototype.nextPage = function () {
		return this.page(this.options.currentPage + 1);
	}

	Pagy.prototype.prevPage = function () {
		return this.page(this.options.currentPage - 1);
	}

  // PAGY PLUGIN DEFINITION
  // =========================

  var old = $.fn.pagy;

  $.fn.pagy = function (option) {
		var args = arguments;

    return this.each(function () {
      var $this   = $(this);
      var data    = $this.data('bs.pagy');
      var options = typeof option == 'object' && option;

      if (!data) $this.data('bs.pagy', (data = new Pagy(this, options)));
      if (typeof option == 'string') {
				data[option].apply(data, Array.prototype.slice.call(args, 1));
			}
    });
  }

  $.fn.pagy.Constructor = Pagy;

  // PAGY NO CONFLICT
  // ===================

  $.fn.pagy.noConflict = function () {
    $.fn.pagy = old;
    return this;
  }

}(jQuery);
<|endoftext|>


<commit_before>/*global SpritzLoginDialog, $ */

enyo.kind({
    name: "SpritzLoginDialog",
    kind: "onyx.Popup",
    style: "text-align: center; width: 80%; z-index: 130",
    scrim: true,
    modal: true,
    autoDismiss: true,
    floating: true,
    centered: true,
    showTransitions: true,
    components: [
        {
            kind: "enyo.Scroller",
            classe: "enyo-fill",
            components: [
                {
                    name: "message",
                    content: "Loging in to spritz. Please log in to spritz in new window and copy result and paste it below."
                },
                {
                    kind: "onyx.InputDecorator",
                    style: "display: block; width: 90%; margin: 10px auto;",
                    components: [
                        {
                            classes: "enyo-fill",
                            name: "resultEntry",
                            kind: "onyx.Input",
                            placeholder: "Paste result here"
                        }
                    ]
                },
                {
                    style: "display: block; margin: 10px auto;",
                    kind: "onyx.Button",
                    content: "Finish Auth",
                    name: "finishBtn",
                    ontap: "doFinish"
                },
                {
                    style: "display: block; margin: 10px auto;",
                    kind: "onyx.Button",
                    content: "Retry",
                    name: "retryBtn",
                    ontap: "doRetry"
                }
            ]
        }
    ],
    published: {
        loginResult: false
    },
    doFinish: function () {
        var auth = this.$.resultEntry.getValue();
        if (auth) {
            this.loginResult = auth;
            SpritzClient.setAuthResponse(auth);
            moboreader.Spritz.init();
            this.hide();
        }
    },
    doRetry: function () {
        SpritzClient.userLogin();
    }
});

enyo.singleton({
    name: "moboreader.Spritz",

    published: {
        wordCompleted: 0,
        totalWords: 0,
        running: false,
        numDownloading: 0,
        available: false
    },
    bindings: [
        { from: "^.moboreader.Prefs.useSpritz", to: ".available" }
    ],
    dlCounter: 0,
    initialized: false,

    availableChanged: function () {
        this.log("Need to activate Spritz: ", moboreader.Prefs.useSpritz);
        if (moboreader.Prefs.useSpritz) {
            if (window.$ === undefined && !this.loadingJQuery) {
                //load jquery
                this.loadScript("jquery-2.1.0.min.js");
                this.loadingJQuery = true;
            }
            if (window.SpritzClient === undefined && !this.loadingSpritz) {
                if (window.$) {
                    //load spritz
                    this.loadScript("spritz.1.2.min.js");
                    this.loadingSpritz = true;
                } else {
                    this.log("Delaying spritz loading until jquery is ready.");
                    setTimeout(this.availableChanged.bind(this), 100);
                }
            }
        }
    },

    login: function (popupWindow) {
        if (popupWindow) {
            SpritzClient.userLogin();
        }
        var dialog = new SpritzLoginDialog();
        dialog.show();
    },

    loadScript: function (name) {
        this.log("Loading ", name);
        var head = document.getElementsByTagName("head")[0],
            script = document.createElement("script");
        script.type = "text/javascript";
        script.charset = "utf-8";
        script.src = "assets/" + name;
        head.appendChild(script);
    },

    init: function () {
        var node = $("#spritzer"),
            options = {
                defaultSpeed: 500,
                speedItems: [250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900,  950, 1000],
                redicleWidth: node.width() - 10
            };

        if (this.initialized) {
            this.spritzController.detach();
            delete this.spritzController;
        }

        this.spritzController = new SPRITZ.spritzinc.SpritzerController(options);
        this.spritzController.attach(node);
        this.spritzController.setProgressReporter(this.bindSafely("receiveProgress"));

        this.initialized = true;

        //if (!SpritzClient.isUserLoggedIn()) {
            //this.login();
        var btn = document.getElementsByClassName("spritzer-login-btn")[0];
        if (btn) {
            btn.addEventListener("click", function () { this.login(false); }.bind(this));
        }
        //}

        setInterval(function () {
            this.setRunning(this.isRunning());
        }.bind(this), 100);
    },

    receiveProgress: function (completed, total) {
        this.setWordCompleted(completed);
        this.setTotalWords(total);
    },

    start: function (articleModel, restart) {
        var spritzModel;

        if (!this.initialized) {
            this.init();
        }

        if (articleModel.spritzOk && articleModel.spritzModel) {
            spritzModel = articleModel.spritzModel;
        } else if (articleModel.spritzModelPersist) {
            articleModel.spritzModel = this.restoreSpritzModel(articleModel.spritzModelPersist);
            articleModel.spritzOk = true;
            spritzModel = articleModel.spritzModel;
            spritzModel.reset();
        } else {
            this.log("Need to download spritz model from ", articleModel.attributes.url);
            if (articleModel.spritzDownloading >= 0) {
                return articleModel.spritzDownloading;
            } else {
                return this.downloadSpritzModel(articleModel);
            }
        }

        if (restart) {
            spritzModel.reset();
        }
        this.spritzController.startSpritzing(spritzModel);
        this.pause();

        return -1;
    },
    stop: function () {
        this.spritzController.stopSpritzing();
    },

    pause: function () {
        this.spritzController.pauseSpritzing();
    },
    resume: function () {
        this.spritzController.resumeSpritzing();
    },

    setWpm: function (wpm) {
        if (!this.spritzController.setSpeed(wpm)) {
            this.spritzController.setSpeed(this.spritzController.maxUnregisteredSpeed);
        }
        return this.spritzController.getSpeed();
    },

    isRunning: function () {
        return this.spritzController.spritzPanel.isRunning();
    },
    isComplete: function () {
        return this.spritzController.spritzPanel.isCompleted();
    },

    downloadSpritzModel: function (articleModel, webContent) {
        if (!webContent) {
            webContent = null;
        }
        this.dlCounter += 1;
        this.setNumDownloading(this.numDownloading + 1);
        articleModel.spritzDownloading = this.dlCounter;

        if (!articleModel.attributes.content) {
            SpritzClient.fetchContents(articleModel.get("url"),
                                       this.bindSafely("fetchSuccess", articleModel, this.dlCounter, webContent),
                                       this.bindSafely("fetchError", articleModel, this.dlCounter, webContent));
        } else {
            var locale = articleModel.attributes.content,
                start = locale.indexOf("lang=\"") + 6,
                end = locale.indexOf("\"", start),
                tmpNode = document.createElement("div"),
                text = "";

            if (start >= 0 && end >= 0 && end > start) {
                locale = locale.substring(start, end);
                this.log("Extracted locale: ", locale);
            } else {
                locale = "en";
                this.error("Could not extract locale.");
            }

            //now get rid of HTML:
            tmpNode.innerHTML = articleModel.attributes.content;
            text = tmpNode.innerText;

            SpritzClient.spritzify(text, locale,
                                   this.bindSafely("fetchSuccess", articleModel, this.dlCounter, webContent),
                                   this.bindSafely("fetchError", articleModel, this.dlCounter, webContent));
        }

        return this.dlCounter;
    },
    fetchSuccess: function (articleModel, dlId, webContent, result) {
        this.log("Got spritzData: ", result);
        if (!articleModel.attributes || !articleModel.previous) {
            this.log("Article was already destroyed.");
        } else {
            articleModel.spritzModel = result;
            articleModel.spritzOk = true;
        }
        delete articleModel.spritzDownloading;

        var spritzPersist = this.storeSpritzModel(result);

        enyo.Signals.send("onArticleDownloaded", {
            id: articleModel.get(articleModel.primaryKey),
            content: {
                web: webContent,
                spritz: spritzPersist
            },
            model: articleModel
        });

        enyo.Signals.send("onSpritzDL", {id: dlId, success: true});
        this.setNumDownloading(this.numDownloading - 1);
    },
    fetchError: function (articleModel, dlId) {
        this.log("Error fetching: ", articleModel.get("url"));
        enyo.Signals.send("onSpritzDL", {id: dlId, success: false});
        this.setNumDownloading(this.numDownloading - 1);
        delete articleModel.spritzDownloading;

        enyo.Signals.send("onArticleDownloaded", {
            id: articleModel.get(articleModel.primaryKey),
            content: {},
            model: articleModel
        });
    },

    storeSpritzModel: function (spritzModel) {
        var obj = {
            contentVersion: spritzModel.getContentVersionId(),
            words: spritzModel.getWords(),
            duration: spritzModel.getDuration(),
            locale: spritzModel.getLocale(),
            version: spritzModel.getVersion(),
            wordCount: spritzModel.getWordCount()
        };

        this.log("Created object: ", obj, " from ", spritzModel);

        return obj;
    },
    restoreSpritzModel: function (obj) {
        var words = [];
        obj.words.forEach(function (word, index) {
            words[index] = new SPRITZ.model.TimedWord(word.word, word.orp, word.multiplier, word.position, word.flags);
        });

        return new SPRITZ.model.SpritzText(obj.contentVersion, words, obj.duration, obj.locale, obj.version, obj.wordCount);
    }
});
<commit_msg>fixed: Spritzify text, not webpage<commit_after>/*global SpritzLoginDialog, $ */

enyo.kind({
    name: "SpritzLoginDialog",
    kind: "onyx.Popup",
    style: "text-align: center; width: 80%; z-index: 130",
    scrim: true,
    modal: true,
    autoDismiss: true,
    floating: true,
    centered: true,
    showTransitions: true,
    components: [
        {
            kind: "enyo.Scroller",
            classe: "enyo-fill",
            components: [
                {
                    name: "message",
                    content: "Loging in to spritz. Please log in to spritz in new window and copy result and paste it below."
                },
                {
                    kind: "onyx.InputDecorator",
                    style: "display: block; width: 90%; margin: 10px auto;",
                    components: [
                        {
                            classes: "enyo-fill",
                            name: "resultEntry",
                            kind: "onyx.Input",
                            placeholder: "Paste result here"
                        }
                    ]
                },
                {
                    style: "display: block; margin: 10px auto;",
                    kind: "onyx.Button",
                    content: "Finish Auth",
                    name: "finishBtn",
                    ontap: "doFinish"
                },
                {
                    style: "display: block; margin: 10px auto;",
                    kind: "onyx.Button",
                    content: "Retry",
                    name: "retryBtn",
                    ontap: "doRetry"
                }
            ]
        }
    ],
    published: {
        loginResult: false
    },
    doFinish: function () {
        var auth = this.$.resultEntry.getValue();
        if (auth) {
            this.loginResult = auth;
            SpritzClient.setAuthResponse(auth);
            moboreader.Spritz.init();
            this.hide();
        }
    },
    doRetry: function () {
        SpritzClient.userLogin();
    }
});

enyo.singleton({
    name: "moboreader.Spritz",

    published: {
        wordCompleted: 0,
        totalWords: 0,
        running: false,
        numDownloading: 0,
        available: false
    },
    bindings: [
        { from: "^.moboreader.Prefs.useSpritz", to: ".available" }
    ],
    dlCounter: 0,
    initialized: false,

    availableChanged: function () {
        this.log("Need to activate Spritz: ", moboreader.Prefs.useSpritz);
        if (moboreader.Prefs.useSpritz) {
            if (window.$ === undefined && !this.loadingJQuery) {
                //load jquery
                this.loadScript("jquery-2.1.0.min.js");
                this.loadingJQuery = true;
            }
            if (window.SpritzClient === undefined && !this.loadingSpritz) {
                if (window.$) {
                    //load spritz
                    this.loadScript("spritz.1.2.min.js");
                    this.loadingSpritz = true;
                } else {
                    this.log("Delaying spritz loading until jquery is ready.");
                    setTimeout(this.availableChanged.bind(this), 100);
                }
            }
        }
    },

    login: function (popupWindow) {
        if (popupWindow) {
            SpritzClient.userLogin();
        }
        var dialog = new SpritzLoginDialog();
        dialog.show();
    },

    loadScript: function (name) {
        this.log("Loading ", name);
        var head = document.getElementsByTagName("head")[0],
            script = document.createElement("script");
        script.type = "text/javascript";
        script.charset = "utf-8";
        script.src = "assets/" + name;
        head.appendChild(script);
    },

    init: function () {
        var node = $("#spritzer"),
            options = {
                defaultSpeed: 500,
                speedItems: [250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900,  950, 1000],
                redicleWidth: node.width() - 10
            };

        if (this.initialized) {
            this.spritzController.detach();
            delete this.spritzController;
        }

        this.spritzController = new SPRITZ.spritzinc.SpritzerController(options);
        this.spritzController.attach(node);
        this.spritzController.setProgressReporter(this.bindSafely("receiveProgress"));

        this.initialized = true;

        //if (!SpritzClient.isUserLoggedIn()) {
            //this.login();
        var btn = document.getElementsByClassName("spritzer-login-btn")[0];
        if (btn) {
            btn.addEventListener("click", function () { this.login(false); }.bind(this));
        }
        //}

        setInterval(function () {
            this.setRunning(this.isRunning());
        }.bind(this), 100);
    },

    receiveProgress: function (completed, total) {
        this.setWordCompleted(completed);
        this.setTotalWords(total);
    },

    start: function (articleModel, restart) {
        var spritzModel;

        if (!this.initialized) {
            this.init();
        }

        if (articleModel.spritzOk && articleModel.spritzModel) {
            spritzModel = articleModel.spritzModel;
        } else if (articleModel.spritzModelPersist) {
            articleModel.spritzModel = this.restoreSpritzModel(articleModel.spritzModelPersist);
            articleModel.spritzOk = true;
            spritzModel = articleModel.spritzModel;
            spritzModel.reset();
        } else {
            this.log("Need to download spritz model from ", articleModel.attributes.url);
            if (articleModel.spritzDownloading >= 0) {
                return articleModel.spritzDownloading;
            } else {
                return this.downloadSpritzModel(articleModel);
            }
        }

        if (restart) {
            spritzModel.reset();
        }
        this.spritzController.startSpritzing(spritzModel);
        this.pause();

        return -1;
    },
    stop: function () {
        this.spritzController.stopSpritzing();
    },

    pause: function () {
        this.spritzController.pauseSpritzing();
    },
    resume: function () {
        this.spritzController.resumeSpritzing();
    },

    setWpm: function (wpm) {
        if (!this.spritzController.setSpeed(wpm)) {
            this.spritzController.setSpeed(this.spritzController.maxUnregisteredSpeed);
        }
        return this.spritzController.getSpeed();
    },

    isRunning: function () {
        return this.spritzController.spritzPanel.isRunning();
    },
    isComplete: function () {
        return this.spritzController.spritzPanel.isCompleted();
    },

    downloadSpritzModel: function (articleModel, webContent) {
        if (!webContent) {
            webContent = null;
        }
        this.dlCounter += 1;
        this.setNumDownloading(this.numDownloading + 1);
        articleModel.spritzDownloading = this.dlCounter;

        if (!webContent) {
            SpritzClient.fetchContents(articleModel.get("url"),
                                       this.bindSafely("fetchSuccess", articleModel, this.dlCounter, webContent),
                                       this.bindSafely("fetchError", articleModel, this.dlCounter, webContent));
        } else {
            var locale = webContent,
                start = locale.indexOf("lang=\"") + 6,
                end = locale.indexOf("\"", start),
                tmpNode = document.createElement("div"),
                text = "";

            if (start >= 0 && end >= 0 && end > start) {
                locale = locale.substring(start, end);
                this.log("Extracted locale: ", locale);
            } else {
                locale = "en";
                this.error("Could not extract locale.");
            }

            //now get rid of HTML:
            tmpNode.innerHTML = webContent;
            text = tmpNode.innerText;

            SpritzClient.spritzify(text, locale,
                                   this.bindSafely("fetchSuccess", articleModel, this.dlCounter, webContent),
                                   this.bindSafely("fetchError", articleModel, this.dlCounter, webContent));
        }

        return this.dlCounter;
    },
    fetchSuccess: function (articleModel, dlId, webContent, result) {
        this.log("Got spritzData: ", result);
        if (!articleModel.attributes || !articleModel.previous) {
            this.log("Article was already destroyed.");
        } else {
            articleModel.spritzModel = result;
            articleModel.spritzOk = true;
        }
        delete articleModel.spritzDownloading;

        var spritzPersist = this.storeSpritzModel(result);

        enyo.Signals.send("onArticleDownloaded", {
            id: articleModel.get(articleModel.primaryKey),
            content: {
                web: webContent,
                spritz: spritzPersist
            },
            model: articleModel
        });

        enyo.Signals.send("onSpritzDL", {id: dlId, success: true});
        this.setNumDownloading(this.numDownloading - 1);
    },
    fetchError: function (articleModel, dlId) {
        this.log("Error fetching: ", articleModel.get("url"));
        enyo.Signals.send("onSpritzDL", {id: dlId, success: false});
        this.setNumDownloading(this.numDownloading - 1);
        delete articleModel.spritzDownloading;

        enyo.Signals.send("onArticleDownloaded", {
            id: articleModel.get(articleModel.primaryKey),
            content: {},
            model: articleModel
        });
    },

    storeSpritzModel: function (spritzModel) {
        var obj = {
            contentVersion: spritzModel.getContentVersionId(),
            words: spritzModel.getWords(),
            duration: spritzModel.getDuration(),
            locale: spritzModel.getLocale(),
            version: spritzModel.getVersion(),
            wordCount: spritzModel.getWordCount()
        };

        this.log("Created object: ", obj, " from ", spritzModel);

        return obj;
    },
    restoreSpritzModel: function (obj) {
        var words = [];
        obj.words.forEach(function (word, index) {
            words[index] = new SPRITZ.model.TimedWord(word.word, word.orp, word.multiplier, word.position, word.flags);
        });

        return new SPRITZ.model.SpritzText(obj.contentVersion, words, obj.duration, obj.locale, obj.version, obj.wordCount);
    }
});
<|endoftext|>


<commit_before>'use strict'

const utilities = require('../brain/utilities');

// unit testable
function isHandlerForRequest(context) {
  var responseUrl = context.userRequest.response_url || '';
  return (responseUrl && responseUrl.includes('hooks.slack.com')) ? true : false;
}

// not needed?
// will delete this if won't cause problems when missing
function verify() {
  console.log("Nothing to see here.")
}

// what needs to be known before processing?
// should this extract more from the context rather than keep passing it around?
function translateRequestToGenericFormats(context) {
  var genericRequests = [{
    context: context
  }];
  var text = context.userRequest.text
  if (text) {
    genericRequests[0].userInput = text;
  }
  return genericRequests;
}

function generateResponsePayloads(genericResponse) {
  var payloads =  [];
  console.log("About to begin generating payloads from genericResponse.");
// Case: no user input
  if (!genericResponse.data) {
    console.log("No data detected in genericResponse.");
    // is this the right way to load the payload?
    payloads.push([{
        username: 'GetHuman',
        text: "Tell me the company you would like to contact.",
        response_type: 'ephemeral',
        icon_emoji: ':gethuman:'
    }]);
    return botSpecificResponse;
  }
// Case: nothing returned from Companies search
// How to tell?
  else if (genericResponse.data.posts === {}) {
    console.log("No posts detected in data of genericResponse.");
    var textInput = genericResponse.context.userRequest.text;
    payloads.push([{
        username: 'GetHuman',
        text: "I couldn't tell what you meant by \"" + textInput + "\". Please tell me company you are looking for. (ex: \"/gethuman Verizon Wireless\")",
        icon_emoji: ':gethuman:',
        response_type: 'ephemeral'
    }]);
    return payloads;
  }

  console.log("Passed first two checks in generateResponsePayloads function.")

  var name = genericResponse.data.name;
  var posts = genericResponse.data.posts;
  var otherCompanies = genericResponse.data.otherCompanies;
  var colors = utilities.colors;

  console.log("About to extract contact info from genericResponse.");

// *** breaks here ***
  var contactInfo = utilities.extractContactInfo(genericResponse.data);
  var topContacts = utilities.formatTextFieldSlack(contactInfo);

  console.log("About to start pushing info into payloads.");

  payloads.push([{
    // may not need to set these
      username: 'GetHuman',
      icon_emoji: ':gethuman:',
      // set response_type to 'in_channel' if we want all to see it
      // doesn't work like that though!
      response_type: 'ephemeral',
      attachments: []
  }]);

// get payload-loaders into sub-functions for testing
  if (posts && posts.length) {
      payloads[0].text = "Top issues for " + name + ":";
      for (let i = 0; i < posts.length; i++) {
          let title = posts[i].title || '';
          let urlId = posts[i].urlId || ''
          let color = colors[i];
          let singleAttachment = {
              "fallback": "Issue for " + name,
              "title": title,
              "color": color,
              "fields": [
                  {
                      "value": "<https://gethuman.com?company=" + encodeURIComponent(name) + "|Solve this for me - $20>",
                      "short": true
                  },
                  {
                      "value": "<https://answers.gethuman.co/_" + encodeURIComponent(urlId) + "|More info ...>",
                      "short": true
                  }
              ]
          };
          payloads[0].attachments.push(singleAttachment);
      };
  }

  // attach Company contact info:
  payloads[0].attachments.push({
      "fallback": "Contact info for " + name,
      "title": "Best ways to contact " + name + ":",
      "color": '#999999',
      "text": topContacts,
  });

  // attach Other Companies info if they exist
  if (otherCompanies && otherCompanies.length) {
      var otherCompaniesList = utilities.convertArrayToBoldList(otherCompanies);
      payloads[0].attachments.push({
          "fallback": "Other solutions",
          "title": "Were you talking about " + name + "?",
          "color": '#BBBBBB',
          "text": "Or maybe you meant " + otherCompaniesList + "?",
          "mrkdwn_in": ["text"]
      });
  }

  if (!payloads[0].attachments.length) {
      payloads[0].text = "I couldn't find anything for \"" + name + "\". Please tell me which company you are looking for. (ex: \"/gethuman Verizon Wireless\")"
  }

  console.log("Payloads processed from genericResponse: " + JSON.stringify(payloads));
  return payloads;
}

function sendResponseToPlatform(payload, context) {
  if (context.isTest) {
    console.log("Test flag detected in payload context.");
    context.sendResponse(payload);
    return Q.when();
  }
  // if this part needed?
  else if (!payload || (payload === [])) {
    console.log("No payload data detected.");
    return Q.when();
  }
  else {
    return sendRequestAsReply(payload, context);
  }
}

// unique function
function sendRequestAsReply(payload, context) {
  console.log("Last step before sending this payload: " + JSON.stringify(payload));
  var deferred = Q.defer();
  var path = config.slackAccessToken;
  var uri = 'https://hooks.slack.com/services/' + path;

// should this be extracted elsewhere? Any other reason to keep context this far?
  payload.channel = context.userRequest.channel_id;

// eventually want to send this as the response to original request
  request({
    uri: uri,
    method: 'POST',
    body: JSON.stringify(payload)
  }, function (error, response, body) {
    if (error) {
      deferred.reject(error);
    }
    else {
      deferred.resolve();
    }
  });
  return deferred.promise;
}

function sendErrorResponse(error, context) {
  console.log("Ran into an error, sending from Bot Handler: " + error);
  var payload = {
        username: 'GetHuman',
        text: error,
        icon_emoji: ':gethuman:'
  };
  sendRequestsAsReply(payload, context);
}

module.exports = {
  isHandlerForRequest: isHandlerForRequest,
  sendResponseToPlatform: sendResponseToPlatform,
  sendErrorResponse: sendErrorResponse,
  verify: verify,
  translateRequestToGenericFormats: translateRequestToGenericFormats,
  generateResponsePayloads: generateResponsePayloads
};
<commit_msg>debug<commit_after>'use strict'

const utilities = require('../brain/utilities');

// unit testable
function isHandlerForRequest(context) {
  var responseUrl = context.userRequest.response_url || '';
  return (responseUrl && responseUrl.includes('hooks.slack.com')) ? true : false;
}

// not needed?
// will delete this if won't cause problems when missing
function verify() {
  console.log("Nothing to see here.")
}

// what needs to be known before processing?
// should this extract more from the context rather than keep passing it around?
function translateRequestToGenericFormats(context) {
  var genericRequests = [{
    context: context
  }];
  var text = context.userRequest.text
  if (text) {
    genericRequests[0].userInput = text;
  }
  return genericRequests;
}

function generateResponsePayloads(genericResponse) {
  var payloads =  [];
  console.log("About to begin generating payloads from genericResponse.");
// Case: no user input
  if (!genericResponse.data) {
    console.log("No data detected in genericResponse.");
    // is this the right way to load the payload?
    payloads.push([{
        username: 'GetHuman',
        text: "Tell me the company you would like to contact.",
        response_type: 'ephemeral',
        icon_emoji: ':gethuman:'
    }]);
    return botSpecificResponse;
  }
// Case: nothing returned from Companies search
// How to tell?
  else if (genericResponse.data.posts === {}) {
    console.log("No posts detected in data of genericResponse.");
    var textInput = genericResponse.context.userRequest.text;
    payloads.push([{
        username: 'GetHuman',
        text: "I couldn't tell what you meant by \"" + textInput + "\". Please tell me company you are looking for. (ex: \"/gethuman Verizon Wireless\")",
        icon_emoji: ':gethuman:',
        response_type: 'ephemeral'
    }]);
    return payloads;
  }

  console.log("Passed first two checks in generateResponsePayloads function.")

  var name = genericResponse.data.name;
  var posts = genericResponse.data.posts;
  var otherCompanies = genericResponse.data.otherCompanies;
  var colors = utilities.colors;

  console.log("About to extract contact info from genericResponse.");

  var contactInfo = utilities.extractContactInfo(genericResponse.data);
  var topContacts = utilities.formatTextFieldSlack(contactInfo);

  console.log("About to start pushing info into payloads.");

// *** breaks here ***
  payloads.push([{
    // may not need to set these
      username: 'GetHuman',
      icon_emoji: ':gethuman:',
      // set response_type to 'in_channel' if we want all to see it
      // doesn't work like that though!
      response_type: 'ephemeral',
      attachments: []
  }]);

  console.log("Basic info pushed into Payloads:" + JSON.stringify(payloads));

// get payload-loaders into sub-functions for testing
  if (posts && posts.length) {
      payloads[0].text = "Top issues for " + name + ":";
      for (let i = 0; i < posts.length; i++) {
          let title = posts[i].title || '';
          let urlId = posts[i].urlId || ''
          let color = colors[i];
          let singleAttachment = {
              "fallback": "Issue for " + name,
              "title": title,
              "color": color,
              "fields": [
                  {
                      "value": "<https://gethuman.com?company=" + encodeURIComponent(name) + "|Solve this for me - $20>",
                      "short": true
                  },
                  {
                      "value": "<https://answers.gethuman.co/_" + encodeURIComponent(urlId) + "|More info ...>",
                      "short": true
                  }
              ]
          };
          payloads[0].attachments.push(singleAttachment);
      };
  }

  // attach Company contact info:
  payloads[0].attachments.push({
      "fallback": "Contact info for " + name,
      "title": "Best ways to contact " + name + ":",
      "color": '#999999',
      "text": topContacts,
  });

  // attach Other Companies info if they exist
  if (otherCompanies && otherCompanies.length) {
      var otherCompaniesList = utilities.convertArrayToBoldList(otherCompanies);
      payloads[0].attachments.push({
          "fallback": "Other solutions",
          "title": "Were you talking about " + name + "?",
          "color": '#BBBBBB',
          "text": "Or maybe you meant " + otherCompaniesList + "?",
          "mrkdwn_in": ["text"]
      });
  }

  if (!payloads[0].attachments.length) {
      payloads[0].text = "I couldn't find anything for \"" + name + "\". Please tell me which company you are looking for. (ex: \"/gethuman Verizon Wireless\")"
  }

  console.log("Payloads processed from genericResponse: " + JSON.stringify(payloads));
  return payloads;
}

function sendResponseToPlatform(payload, context) {
  if (context.isTest) {
    console.log("Test flag detected in payload context.");
    context.sendResponse(payload);
    return Q.when();
  }
  // if this part needed?
  else if (!payload || (payload === [])) {
    console.log("No payload data detected.");
    return Q.when();
  }
  else {
    return sendRequestAsReply(payload, context);
  }
}

// unique function
function sendRequestAsReply(payload, context) {
  console.log("Last step before sending this payload: " + JSON.stringify(payload));
  var deferred = Q.defer();
  var path = config.slackAccessToken;
  var uri = 'https://hooks.slack.com/services/' + path;

// should this be extracted elsewhere? Any other reason to keep context this far?
  payload.channel = context.userRequest.channel_id;

// eventually want to send this as the response to original request
  request({
    uri: uri,
    method: 'POST',
    body: JSON.stringify(payload)
  }, function (error, response, body) {
    if (error) {
      deferred.reject(error);
    }
    else {
      deferred.resolve();
    }
  });
  return deferred.promise;
}

function sendErrorResponse(error, context) {
  console.log("Ran into an error, sending from Bot Handler: " + error);
  var payload = {
        username: 'GetHuman',
        text: error,
        icon_emoji: ':gethuman:'
  };
  sendRequestsAsReply(payload, context);
}

module.exports = {
  isHandlerForRequest: isHandlerForRequest,
  sendResponseToPlatform: sendResponseToPlatform,
  sendErrorResponse: sendErrorResponse,
  verify: verify,
  translateRequestToGenericFormats: translateRequestToGenericFormats,
  generateResponsePayloads: generateResponsePayloads
};
<|endoftext|>


<commit_before>import logger from 'kolibri.lib.logging';
import filter from 'lodash/filter';
import { TaskResource } from 'kolibri.resources';
import client from 'kolibri.client';
import urls from 'kolibri.urls';
import { TaskStatuses, TaskTypes } from '../../constants';

const logging = logger.getLogger(__filename);

function startSummaryCSVExport(store) {
  const params = {
    logtype: 'summary',
  };
  if (!store.getters.inSummaryCSVCreation) {
    let promise = TaskResource.startexportlogcsv(params);

    return promise.then(task => {
      store.commit('START_SUMMARY_CSV_EXPORT', task.entity.id);
      return task.entity.id;
    });
  }
}

function getExportedLogsInfo(store) {
  return client({
    path: urls['kolibri:core:exportedlogsinfo'](),
  }).then(response => {
    const data = response.entity;
    let sessionTimeStamp = null;
    if (data.session != null) {
      sessionTimeStamp = new Date(data.session * 1000);
      store.commit('SET_FINISHED_SESSION_CSV_CREATION', sessionTimeStamp);
    }
    let summaryTimeStamp = null;
    if (data.summary != null) {
      summaryTimeStamp = new Date(data.summary * 1000);
      store.commit('SET_FINISHED_SUMMARY_CSV_CREATION', summaryTimeStamp);
    }
  });
}

function startSessionCSVExport(store) {
  const params = {
    logtype: 'session',
  };
  if (!store.getters.inSessionCSVCreation) {
    let promise = TaskResource.startexportlogcsv(params);

    return promise.then(task => {
      store.commit('START_SESSION_CSV_EXPORT', task.entity.id);
      return task.entity.id;
    });
  }
}

function refreshTaskList(store) {
  return TaskResource.fetchCollection({
    force: true,
  })
    .then(newTasks => {
      // Identify if some of the generation scripts are running:
      if (!store.getters.sessionTaskId) {
        const sessionRunning = filter(newTasks, function(task) {
          return (
            task.type === TaskTypes.EXPORTSESSIONLOGCSV &&
            task.status !== TaskStatuses.COMPLETED &&
            task.status !== TaskStatuses.FAILED
          );
        });
        if (sessionRunning.length > 0)
          store.commit('START_SESSION_CSV_EXPORT', sessionRunning[0].id);
      } else {
        const sessionCompleted = filter(newTasks, {
          id: store.getters.sessionTaskId,
        });
        if (sessionCompleted.length > 0) {
          const task = sessionCompleted[0];
          if (task.status === TaskStatuses.COMPLETED)
            store.commit('SET_FINISHED_SESSION_CSV_CREATION', new Date());
        }
      }

      if (!store.getters.summaryTaskId) {
        const summaryRunning = filter(newTasks, function(task) {
          return (
            task.type === TaskTypes.EXPORTSUMMARYLOGCSV &&
            task.status !== TaskStatuses.COMPLETED &&
            task.status !== TaskStatuses.FAILED
          );
        });
        if (summaryRunning.length > 0)
          store.commit('START_SUMMARY_CSV_EXPORT', summaryRunning[0].id);
      } else {
        const summaryCompleted = filter(newTasks, {
          id: store.getters.summaryTaskId,
        });
        if (summaryCompleted.length > 0) {
          const task = summaryCompleted[0];
          if (task.status === TaskStatuses.COMPLETED)
            store.commit('SET_FINISHED_SUMMARY_CSV_CREATION', new Date());
        }
      }
    })
    .catch(error => {
      logging.error('There was an error while fetching the task list: ', error);
    });
}

export default {
  refreshTaskList,
  startSummaryCSVExport,
  startSessionCSVExport,
  getExportedLogsInfo,
};
<commit_msg>Small refactoring for the actions<commit_after>import logger from 'kolibri.lib.logging';
import filter from 'lodash/filter';
import { TaskResource } from 'kolibri.resources';
import client from 'kolibri.client';
import urls from 'kolibri.urls';
import { TaskStatuses, TaskTypes } from '../../constants';

const logging = logger.getLogger(__filename);

function startSummaryCSVExport(store) {
  const params = {
    logtype: 'summary',
  };
  if (!store.getters.inSummaryCSVCreation) {
    let promise = TaskResource.startexportlogcsv(params);

    return promise.then(task => {
      store.commit('START_SUMMARY_CSV_EXPORT', task.entity.id);
      return task.entity.id;
    });
  }
}

function getExportedLogsInfo(store) {
  return client({
    path: urls['kolibri:core:exportedlogsinfo'](),
  }).then(response => {
    const data = response.entity;
    let sessionTimeStamp = null;
    if (data.session != null) {
      sessionTimeStamp = new Date(data.session * 1000);
      store.commit('SET_FINISHED_SESSION_CSV_CREATION', sessionTimeStamp);
    }
    let summaryTimeStamp = null;
    if (data.summary != null) {
      summaryTimeStamp = new Date(data.summary * 1000);
      store.commit('SET_FINISHED_SUMMARY_CSV_CREATION', summaryTimeStamp);
    }
  });
}

function startSessionCSVExport(store) {
  const params = {
    logtype: 'session',
  };
  if (!store.getters.inSessionCSVCreation) {
    let promise = TaskResource.startexportlogcsv(params);

    return promise.then(task => {
      store.commit('START_SESSION_CSV_EXPORT', task.entity.id);
      return task.entity.id;
    });
  }
}

function checkTaskStatus(store, newTasks, taskType, taskId, commitStart, commitFinish) {
  if (taskId) {
    const completed = filter(newTasks, {
      id: taskId,
    });
    if (completed.length > 0) {
      const task = completed[0];
      if (task.status === TaskStatuses.COMPLETED) store.commit(commitFinish, new Date());
    }
  } else {
    const running = filter(newTasks, function(task) {
      return (
        task.type === taskType &&
        task.status !== TaskStatuses.COMPLETED &&
        task.status !== TaskStatuses.FAILED
      );
    });
    if (running.length > 0) store.commit(commitStart, running[0].id);
  }
}

function refreshTaskList(store) {
  return TaskResource.fetchCollection({
    force: true,
  })
    .then(newTasks => {
      checkTaskStatus(
        store,
        newTasks,
        TaskTypes.EXPORTSESSIONLOGCSV,
        store.getters.sessionTaskId,
        'START_SESSION_CSV_EXPORT',
        'SET_FINISHED_SESSION_CSV_CREATION'
      );
      checkTaskStatus(
        store,
        newTasks,
        TaskTypes.EXPORTSUMMARYLOGCSV,
        store.getters.summaryTaskId,
        'START_SUMMARY_CSV_EXPORT',
        'SET_FINISHED_SUMMARY_CSV_CREATION'
      );
    })
    .catch(error => {
      logging.error('There was an error while fetching the task list: ', error);
    });
}

export default {
  refreshTaskList,
  startSummaryCSVExport,
  startSessionCSVExport,
  getExportedLogsInfo,
};
<|endoftext|>


<commit_before>import fs from 'fs';
import crypto from 'crypto';
import _ from 'lodash';
import path from 'path';
import ncp from 'ncp';
import shellJs from 'shelljs';

const copy = ncp.ncp;

/**
 * Only picks certain app args to pass to nativefier.json
 * @param options
 */
function selectAppArgs(options) {
  return {
    name: options.name,
    companyName: options.companyName,
    targetUrl: options.targetUrl,
    counter: options.counter,
    width: options.width,
    height: options.height,
    minWidth: options.minWidth,
    minHeight: options.minHeight,
    maxWidth: options.maxWidth,
    maxHeight: options.maxHeight,
    showMenuBar: options.showMenuBar,
    fastQuit: options.fastQuit,
    userAgent: options.userAgent,
    nativefierVersion: options.nativefierVersion,
    ignoreCertificate: options.ignoreCertificate,
    ignoreGpuBlacklist: options.ignoreGpuBlacklist,
    enableEs3Apis: options.enableEs3Apis,
    insecure: options.insecure,
    flashPluginDir: options.flashPluginDir,
    diskCacheSize: options.diskCacheSize,
    fullScreen: options.fullScreen,
    hideWindowFrame: options.hideWindowFrame,
    maximize: options.maximize,
    disableContextMenu: options.disableContextMenu,
    disableDevTools: options.disableDevTools,
    zoom: options.zoom,
    internalUrls: options.internalUrls,
    crashReporter: options.crashReporter,
    singleInstance: options.singleInstance,
    dependencies: options.dependencies,
    processEnvs: options.processEnvs,
  };
}

function maybeCopyScripts(srcs, dest) {
  if (!srcs) {
    return new Promise((resolve) => {
      resolve();
    });
  }
  const promises = srcs.map(src => new Promise((resolve, reject) => {
    if (!fs.existsSync(src)) {
      reject('Error copying injection files: file not found');
      return;
    }

    let destFileName;
    if (path.extname(src) === '.js') {
      destFileName = 'inject.js';
    } else if (path.extname(src) === '.css') {
      destFileName = 'inject.css';
    } else {
      resolve();
      return;
    }

    copy(src, path.join(dest, 'inject', destFileName), (error) => {
      if (error) {
        reject(`Error Copying injection files: ${error}`);
        return;
      }
      resolve();
    });
  }));

  return new Promise((resolve, reject) => {
    Promise.all(promises)
      .then(() => {
        resolve();
      })
      .catch((error) => {
        reject(error);
      });
  });
}

function maybeCopyAssets(srcs, dest) {
  if (!srcs) {
    return new Promise((resolve) => {
      resolve();
    });
  }

  const promises = srcs.map(src => new Promise((resolve, reject) => {
    if (!fs.existsSync(src)) {
      reject('Error copying assets directories or files: not found');
      return;
    }

    const destPath = path.join(dest, 'assets/');
    if (!fs.existsSync(destPath)) {
      fs.mkdir(destPath);
    }

    copy(src, path.join(destPath, path.basename(src)), (error) => {
      if (error) {
        reject(`Error Copying assets directories or files: ${error}`);
        return;
      }
      resolve();
    });
  }));

  return new Promise((resolve, reject) => {
    Promise.all(promises)
      .then(() => {
        resolve();
      })
      .catch((error) => {
        reject(error);
      });
  });
}

function normalizeAppName(appName, url) {
    // use a simple 3 byte random string to prevent collision
  const hash = crypto.createHash('md5');
  hash.update(url);
  const postFixHash = hash.digest('hex').substring(0, 6);
  const normalized = _.kebabCase(appName.toLowerCase());
  return `${normalized}-nativefier-${postFixHash}`;
}

function changeAppPackageJsonName(appPath, name, url) {
  const packageJsonPath = path.join(appPath, '/package.json');
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
  packageJson.name = normalizeAppName(name, url);
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson));
}

function addAdditionalDependencies(appPath, options) {
  if (options.dependencies) {
    const packageJsonPath = path.join(appPath, '/package.json');
    const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
    packageJson.dependencies = Object.assign(packageJson.dependencies, options.dependencies);
    fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson));
  }
}

/**
 * Allow to start a shell command
 *
 * @param {string} cmd
 * @param {boolean} silent
 * @param {function} callback
 */
function shellExec(cmd, silent, callback) {
  shellJs.exec(cmd, { silent }, (code, stdout, stderr) => {
    if (code) {
      callback(JSON.stringify({ code, stdout, stderr }));
      return;
    }
    callback();
  });
}

/**
 * Creates a temporary directory and copies the './app folder' inside,
 * and adds a text file with the configuration for the single page app.
 *
 * @param {string} src
 * @param {string} dest
 * @param {{}} options
 * @param callback
 */
function buildApp(src, dest, options, callback) {
  const appArgs = selectAppArgs(options);
  copy(src, dest, (error) => {
    if (error) {
      callback(`Error Copying temporary directory: ${error}`);
      return;
    }

    fs.writeFileSync(path.join(dest, '/nativefier.json'), JSON.stringify(appArgs));

    maybeCopyScripts(options.inject, dest)
      .then(() => maybeCopyAssets(options.assets, dest))
      .then(() => {
        changeAppPackageJsonName(dest, appArgs.name, appArgs.targetUrl);
        addAdditionalDependencies(dest, options);
        shellExec(`cd ${dest} && npm install`, true, () => {});
        callback();
      })
      .catch(() => {

      });
  });
}

export default buildApp;
<commit_msg>Fix hount<commit_after>import fs from 'fs';
import crypto from 'crypto';
import _ from 'lodash';
import path from 'path';
import ncp from 'ncp';
import shellJs from 'shelljs';

const copy = ncp.ncp;

/**
 * Only picks certain app args to pass to nativefier.json
 * @param options
 */
function selectAppArgs(options) {
  return {
    name: options.name,
    companyName: options.companyName,
    targetUrl: options.targetUrl,
    counter: options.counter,
    width: options.width,
    height: options.height,
    minWidth: options.minWidth,
    minHeight: options.minHeight,
    maxWidth: options.maxWidth,
    maxHeight: options.maxHeight,
    showMenuBar: options.showMenuBar,
    fastQuit: options.fastQuit,
    userAgent: options.userAgent,
    nativefierVersion: options.nativefierVersion,
    ignoreCertificate: options.ignoreCertificate,
    ignoreGpuBlacklist: options.ignoreGpuBlacklist,
    enableEs3Apis: options.enableEs3Apis,
    insecure: options.insecure,
    flashPluginDir: options.flashPluginDir,
    diskCacheSize: options.diskCacheSize,
    fullScreen: options.fullScreen,
    hideWindowFrame: options.hideWindowFrame,
    maximize: options.maximize,
    disableContextMenu: options.disableContextMenu,
    disableDevTools: options.disableDevTools,
    zoom: options.zoom,
    internalUrls: options.internalUrls,
    crashReporter: options.crashReporter,
    singleInstance: options.singleInstance,
    dependencies: options.dependencies,
    processEnvs: options.processEnvs,
  };
}

function maybeCopyScripts(srcs, dest) {
  if (!srcs) {
    return new Promise((resolve) => {
      resolve();
    });
  }
  const promises = srcs.map(src => new Promise((resolve, reject) => {
    if (!fs.existsSync(src)) {
      reject('Error copying injection files: file not found');
      return;
    }

    let destFileName;
    if (path.extname(src) === '.js') {
      destFileName = 'inject.js';
    } else if (path.extname(src) === '.css') {
      destFileName = 'inject.css';
    } else {
      resolve();
      return;
    }

    copy(src, path.join(dest, 'inject', destFileName), (error) => {
      if (error) {
        reject(`Error Copying injection files: ${error}`);
        return;
      }
      resolve();
    });
  }));

  return new Promise((_resolve, _reject) => {
    Promise.all(promises)
      .then(() => {
        _resolve();
      })
      .catch((error) => {
        _reject(error);
      });
  });
}

function maybeCopyAssets(srcs, dest) {
  if (!srcs) {
    return new Promise((resolve) => {
      resolve();
    });
  }

  const promises = srcs.map(src => new Promise((resolve, reject) => {
    if (!fs.existsSync(src)) {
      reject('Error copying assets directories or files: not found');
      return;
    }

    const destPath = path.join(dest, 'assets/');
    if (!fs.existsSync(destPath)) {
      fs.mkdir(destPath);
    }

    copy(src, path.join(destPath, path.basename(src)), (error) => {
      if (error) {
        reject(`Error Copying assets directories or files: ${error}`);
        return;
      }
      resolve();
    });
  }));

  return new Promise((resolve, reject) => {
    Promise.all(promises)
      .then(() => {
        resolve();
      })
      .catch((error) => {
        reject(error);
      });
  });
}

function normalizeAppName(appName, url) {
    // use a simple 3 byte random string to prevent collision
  const hash = crypto.createHash('md5');
  hash.update(url);
  const postFixHash = hash.digest('hex').substring(0, 6);
  const normalized = _.kebabCase(appName.toLowerCase());
  return `${normalized}-nativefier-${postFixHash}`;
}

function changeAppPackageJsonName(appPath, name, url) {
  const packageJsonPath = path.join(appPath, '/package.json');
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
  packageJson.name = normalizeAppName(name, url);
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson));
}

function addAdditionalDependencies(appPath, options) {
  if (options.dependencies) {
    const packageJsonPath = path.join(appPath, '/package.json');
    const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
    packageJson.dependencies = Object.assign(packageJson.dependencies, options.dependencies);
    fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson));
  }
}

/**
 * Allow to start a shell command
 *
 * @param {string} cmd
 * @param {boolean} silent
 * @param {function} callback
 */
function shellExec(cmd, silent, callback) {
  shellJs.exec(cmd, { silent }, (code, stdout, stderr) => {
    if (code) {
      callback(JSON.stringify({ code, stdout, stderr }));
      return;
    }
    callback();
  });
}

/**
 * Creates a temporary directory and copies the './app folder' inside,
 * and adds a text file with the configuration for the single page app.
 *
 * @param {string} src
 * @param {string} dest
 * @param {{}} options
 * @param callback
 */
function buildApp(src, dest, options, callback) {
  const appArgs = selectAppArgs(options);
  copy(src, dest, (error) => {
    if (error) {
      callback(`Error Copying temporary directory: ${error}`);
      return;
    }

    fs.writeFileSync(path.join(dest, '/nativefier.json'), JSON.stringify(appArgs));

    maybeCopyScripts(options.inject, dest)
      .then(() => maybeCopyAssets(options.assets, dest))
      .then(() => {
        changeAppPackageJsonName(dest, appArgs.name, appArgs.targetUrl);
        addAdditionalDependencies(dest, options);
        shellExec(`cd ${dest} && npm install`, true, () => {});
        callback();
      })
      .catch(() => {
      });
  });
}

export default buildApp;
<|endoftext|>


<commit_before>(function () {
    "use strict";

    angular
     .module("common.services")
     .factory("AchievementService",
             achievementService);

    achievementService.$inject = ["config", '$http', '$q'];

    function achievementService(config, $http, $q)
    {
        return {
            GetAchievements : getAchievements
        }

        function getAchievements() {
            var deferred = $q.defer();

            $http.get(config.apiUrl + 'achivements')
                .success(function (data, status, headers, config) {
                    deferred.resolve(data);
                })
                .error(function (data, status, headers, config) {
                    deferred.reject(status);
                });

            return deferred.promise;
        }
    }
}());<commit_msg>add getPlayerAchievements method to angular service for achievements<commit_after>(function () {
    "use strict";

    angular
     .module("common.services")
     .factory("AchievementService",
             achievementService);

    achievementService.$inject = ["config", '$http', '$q'];

    function achievementService(config, $http, $q)
    {
        return {
            GetAchievements: getAchievements,
            GetPlayerAchievements: getPlayerAchievements
        }

        function getAchievements() {
            var deferred = $q.defer();

            $http.get(config.apiUrl + 'achievements')
                .success(function (data, status, headers, config) {
                    deferred.resolve(data);
                })
                .error(function (data, status, headers, config) {
                    deferred.reject(status);
                });

            return deferred.promise;
        }

        function getPlayerAchievements(playerName) {
            var deferred = $q.defer();

            $http.get(config.apiUrl + 'achievements/player/'+ playerName)
                .success(function (data, status, headers, config) {
                    deferred.resolve(data);
                })
                .error(function (data, status, headers, config) {
                    deferred.reject(status);
                });

            return deferred.promise;
        }
    }
}());<|endoftext|>


<commit_before>;(function() {
    'use strict';
    console.log("%cWelcome to the guts of our website. Want to see or contribute to the code? https://github.com/mdn/viewsourceconf", "color: #fff;background-color: #313131;padding: 5px;display: block;");
})();
<commit_msg>Refine consoler<commit_after>;(function() {
    'use strict';
    console.log("%cWelcome to the guts of our website. We're glad you're here! Want to see or contribute to the code? https://github.com/mdn/viewsourceconf", "color: #fff;background-color: #4D4E53;padding: 5px;display: block;line-height: 1.75em;");
})();
<|endoftext|>


<commit_before>(function (window) {
  'use strict';

  function Even(config) {
    this.config = config;
  }

  Even.prototype.setup = function() {
    var leancloud = this.config.leancloud;

    this.navbar();
    this.responsiveTable();

    if (this.config.toc) {
      this.scrollToc();
      this.tocFollow();
    }
    if (this.config.fancybox) {
      this.fancybox();
    }
    if (leancloud.app_id && leancloud.app_key) {
      this.recordReadings();
    }
    if (this.config.pjax) {
      this.pjax();
    }
    if(this.config.latex) {
      this.renderLaTeX();
    }
    this.backToTop();
  };

  Even.prototype.navbar = function () {
    var $nav = $('#mobile-navbar');
    var $navIcon = $('.mobile-navbar-icon');

    var slideout = new Slideout({
      'panel': document.getElementById('mobile-panel'),
      'menu': document.getElementById('mobile-menu'),
      'padding': 180,
      'tolerance': 70
    });
    slideout.disableTouch();

    $navIcon.click(function () {
      slideout.toggle();
    });

    slideout.on('beforeopen', function () {
      $nav.addClass('fixed-open');
      $navIcon.addClass('icon-click').removeClass('icon-out');
    });

    slideout.on('beforeclose', function () {
      $nav.removeClass('fixed-open');
      $navIcon.addClass('icon-out').removeClass('icon-click');
    });

    $('#mobile-panel').on('touchend', function () {
      slideout.isOpen() && $navIcon.click();
    });
  };

  Even.prototype.responsiveTable = function () {
    var tables = $('.post-content > table')
    tables.wrap('
')
  };

  Even.prototype.scrollToc = function () {
    var SPACING = 20;
    var $toc = $('.post-toc');
    var $footer = $('.post-footer');

    if ($toc.length) {
      var minScrollTop = $toc.offset().top - SPACING;
      var maxScrollTop = $footer.offset().top - $toc.height() - SPACING;

      var tocState = {
        start: {
          'position': 'absolute',
          'top': minScrollTop
        },
        process: {
          'position': 'fixed',
          'top': SPACING
        },
        end: {
          'position': 'absolute',
          'top': maxScrollTop
        }
      }

      $(window).scroll(function () {
        var scrollTop = $(window).scrollTop();

        if (scrollTop < minScrollTop) {
          $toc.css(tocState.start);
        } else if (scrollTop > maxScrollTop) {
          $toc.css(tocState.end);
        } else {
          $toc.css(tocState.process);
        }
      })
    }
  };

  Even.prototype.tocFollow = function () {
    var HEADERFIX = 30;
    var isFirefox = /firefox/i.test(navigator.userAgent);
    var isEdge = /edge/i.test(navigator.userAgent);
    var $toclink = $('.toc-link'),
      $headerlink = $('.headerlink');

    $(window).scroll(function () {
      var scrollTop = $(window).scrollTop();
      var headerlinkTop = $.map($headerlink, function (link) {
        if(isFirefox || isEdge) {
          return $(link).offset().top;
        }
        return scrollTop + $(link).offset().top;
      });

      for (var i = 0; i < $toclink.length; i++) {
        var isLastOne = i + 1 === $toclink.length,
          currentTop = headerlinkTop[i] - HEADERFIX,
          nextTop = isLastOne ? Infinity : headerlinkTop[i + 1] - HEADERFIX;

        if (currentTop < scrollTop && scrollTop <= nextTop) {
          $($toclink[i]).addClass('active');
        } else {
          $($toclink[i]).removeClass('active');
        }
      }
    });
  };

  Even.prototype.fancybox = function () {
    if ($.fancybox) {
      $('.post').each(function () {
        $(this).find('img').each(function () {
          var href = 'href="' + this.src + '"';
          var title = 'title="' + this.alt + '"';
          $(this).wrap('');
        });
      });

      $('.fancybox').fancybox({
        openEffect: 'elastic',
        closeEffect: 'elastic'
      });
    }
  };

  Even.prototype.recordReadings = function () {
    if (typeof AV !== 'object') return;

    var $visits = $('.post-visits');
    var Counter = AV.Object.extend('Counter');
    if ($visits.length === 1) {
      addCounter(Counter);
    } else {
      showTime(Counter);
    }

    function updateVisits(dom, time) {
      var readText = dom.text().replace(/(\d+)/i, time)
      dom.text(readText);
    }

    function addCounter(Counter) {
      var query = new AV.Query(Counter);

      var url = $visits.data('url').trim();
      var title = $visits.data('title').trim();

      query.equalTo('url', url);
      query.find().then(function (results) {
        if (results.length > 0) {
          var counter = results[0];
          counter.save(null, {
            fetchWhenSave: true
          }).then(function (counter) {
            counter.increment('time', 1);
            return counter.save();
          }).then(function (counter) {
            updateVisits($visits, counter.get('time'));
          });
        } else {
          var newcounter = new Counter();
          newcounter.set('title', title);
          newcounter.set('url', url);
          newcounter.set('time', 1);

          var acl = new AV.ACL();
          acl.setWriteAccess('*', true)
          acl.setReadAccess('*', true)
          newcounter.setACL(acl)

          newcounter.save().then(function () {
            updateVisits($visits, newcounter.get('time'));
          });
        }
      }, function (error) {
        // eslint-disable-next-line
        console.log('Error:' + error.code + ' ' + error.message);
      });
    }

    function showTime(Counter) {
      $visits.each(function () {
        var $this = $(this);
        var query = new AV.Query(Counter);
        var url = $this.data('url').trim();

        query.equalTo('url', url);
        query.find().then(function (results) {
          if (results.length === 0) {
            updateVisits($this, 0);
          } else {
            var counter = results[0];
            updateVisits($this, counter.get('time'));
          }
        }, function (error) {
          // eslint-disable-next-line
          console.log('Error:' + error.code + ' ' + error.message);
        });
      })
    }
  };

  Even.prototype.pjax = function () {
    if (location.hostname === 'localhost' || this.hasPjax) return;
    this.hasPjax = true;
    this._fancybox = $.fancybox;
    this._fancyboxProto = $.prototype.fancybox;

    var that = this;
    $(document).pjax('a', 'body', { fragment: 'body' });
    $(document).on('pjax:send', function () {
      NProgress.start();
      $('body').addClass('hide-top');
    });
    $(document).on('pjax:complete', function () {
      NProgress.done();
      $('body').removeClass('hide-top');
      $.fancybox = that._fancybox;
      $.prototype.fancybox = that._fancyboxProto;
      that.setup();
    });
  };

  Even.prototype.backToTop = function () {
    var $backToTop = $('#back-to-top');

    $(window).scroll(function () {
      if ($(window).scrollTop() > 100) {
        $backToTop.fadeIn(1000);
      } else {
        $backToTop.fadeOut(1000);
      }
    });

    $backToTop.click(function () {
      $('body,html').animate({ scrollTop: 0 });
    });
  };

  Even.prototype.renderLaTeX = function () {
    var loopID = setInterval(function () {
      if(window.MathJax) {
        var jax = window.MathJax;
        jax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'], ['\\(', '\\)']] }});
        jax.Hub.Queue(['Typeset', jax.Hub, $(document.body)[0]]);
        clearInterval(loopID);
      }
    }, 500);
  }

  var config = window.config;
  var even = new Even(config);
  even.setup();
}(window))
<commit_msg>update: change logic from manually patch other browsers to patch webkit<commit_after>(function (window) {
  'use strict';

  function Even(config) {
    this.config = config;
  }

  Even.prototype.setup = function() {
    var leancloud = this.config.leancloud;

    this.navbar();
    this.responsiveTable();

    if (this.config.toc) {
      this.scrollToc();
      this.tocFollow();
    }
    if (this.config.fancybox) {
      this.fancybox();
    }
    if (leancloud.app_id && leancloud.app_key) {
      this.recordReadings();
    }
    if (this.config.pjax) {
      this.pjax();
    }
    if(this.config.latex) {
      this.renderLaTeX();
    }
    this.backToTop();
  };

  Even.prototype.navbar = function () {
    var $nav = $('#mobile-navbar');
    var $navIcon = $('.mobile-navbar-icon');

    var slideout = new Slideout({
      'panel': document.getElementById('mobile-panel'),
      'menu': document.getElementById('mobile-menu'),
      'padding': 180,
      'tolerance': 70
    });
    slideout.disableTouch();

    $navIcon.click(function () {
      slideout.toggle();
    });

    slideout.on('beforeopen', function () {
      $nav.addClass('fixed-open');
      $navIcon.addClass('icon-click').removeClass('icon-out');
    });

    slideout.on('beforeclose', function () {
      $nav.removeClass('fixed-open');
      $navIcon.addClass('icon-out').removeClass('icon-click');
    });

    $('#mobile-panel').on('touchend', function () {
      slideout.isOpen() && $navIcon.click();
    });
  };

  Even.prototype.responsiveTable = function () {
    var tables = $('.post-content > table')
    tables.wrap('
')
  };

  Even.prototype.scrollToc = function () {
    var SPACING = 20;
    var $toc = $('.post-toc');
    var $footer = $('.post-footer');

    if ($toc.length) {
      var minScrollTop = $toc.offset().top - SPACING;
      var maxScrollTop = $footer.offset().top - $toc.height() - SPACING;

      var tocState = {
        start: {
          'position': 'absolute',
          'top': minScrollTop
        },
        process: {
          'position': 'fixed',
          'top': SPACING
        },
        end: {
          'position': 'absolute',
          'top': maxScrollTop
        }
      }

      $(window).scroll(function () {
        var scrollTop = $(window).scrollTop();

        if (scrollTop < minScrollTop) {
          $toc.css(tocState.start);
        } else if (scrollTop > maxScrollTop) {
          $toc.css(tocState.end);
        } else {
          $toc.css(tocState.process);
        }
      })
    }
  };

  Even.prototype.tocFollow = function () {
    var HEADERFIX = 30;
    var isWebKit = /AppleWebKit/i.test(navigator.userAgent);
    var $toclink = $('.toc-link'),
      $headerlink = $('.headerlink');

    $(window).scroll(function () {
      var scrollTop = $(window).scrollTop();
      var headerlinkTop = $.map($headerlink, function (link) {
        if(isWebKit) {
          return scrollTop + $(link).offset().top;
        }
        return $(link).offset().top;
      });

      for (var i = 0; i < $toclink.length; i++) {
        var isLastOne = i + 1 === $toclink.length,
          currentTop = headerlinkTop[i] - HEADERFIX,
          nextTop = isLastOne ? Infinity : headerlinkTop[i + 1] - HEADERFIX;

        if (currentTop < scrollTop && scrollTop <= nextTop) {
          $($toclink[i]).addClass('active');
        } else {
          $($toclink[i]).removeClass('active');
        }
      }
    });
  };

  Even.prototype.fancybox = function () {
    if ($.fancybox) {
      $('.post').each(function () {
        $(this).find('img').each(function () {
          var href = 'href="' + this.src + '"';
          var title = 'title="' + this.alt + '"';
          $(this).wrap('');
        });
      });

      $('.fancybox').fancybox({
        openEffect: 'elastic',
        closeEffect: 'elastic'
      });
    }
  };

  Even.prototype.recordReadings = function () {
    if (typeof AV !== 'object') return;

    var $visits = $('.post-visits');
    var Counter = AV.Object.extend('Counter');
    if ($visits.length === 1) {
      addCounter(Counter);
    } else {
      showTime(Counter);
    }

    function updateVisits(dom, time) {
      var readText = dom.text().replace(/(\d+)/i, time)
      dom.text(readText);
    }

    function addCounter(Counter) {
      var query = new AV.Query(Counter);

      var url = $visits.data('url').trim();
      var title = $visits.data('title').trim();

      query.equalTo('url', url);
      query.find().then(function (results) {
        if (results.length > 0) {
          var counter = results[0];
          counter.save(null, {
            fetchWhenSave: true
          }).then(function (counter) {
            counter.increment('time', 1);
            return counter.save();
          }).then(function (counter) {
            updateVisits($visits, counter.get('time'));
          });
        } else {
          var newcounter = new Counter();
          newcounter.set('title', title);
          newcounter.set('url', url);
          newcounter.set('time', 1);

          var acl = new AV.ACL();
          acl.setWriteAccess('*', true)
          acl.setReadAccess('*', true)
          newcounter.setACL(acl)

          newcounter.save().then(function () {
            updateVisits($visits, newcounter.get('time'));
          });
        }
      }, function (error) {
        // eslint-disable-next-line
        console.log('Error:' + error.code + ' ' + error.message);
      });
    }

    function showTime(Counter) {
      $visits.each(function () {
        var $this = $(this);
        var query = new AV.Query(Counter);
        var url = $this.data('url').trim();

        query.equalTo('url', url);
        query.find().then(function (results) {
          if (results.length === 0) {
            updateVisits($this, 0);
          } else {
            var counter = results[0];
            updateVisits($this, counter.get('time'));
          }
        }, function (error) {
          // eslint-disable-next-line
          console.log('Error:' + error.code + ' ' + error.message);
        });
      })
    }
  };

  Even.prototype.pjax = function () {
    if (location.hostname === 'localhost' || this.hasPjax) return;
    this.hasPjax = true;
    this._fancybox = $.fancybox;
    this._fancyboxProto = $.prototype.fancybox;

    var that = this;
    $(document).pjax('a', 'body', { fragment: 'body' });
    $(document).on('pjax:send', function () {
      NProgress.start();
      $('body').addClass('hide-top');
    });
    $(document).on('pjax:complete', function () {
      NProgress.done();
      $('body').removeClass('hide-top');
      $.fancybox = that._fancybox;
      $.prototype.fancybox = that._fancyboxProto;
      that.setup();
    });
  };

  Even.prototype.backToTop = function () {
    var $backToTop = $('#back-to-top');

    $(window).scroll(function () {
      if ($(window).scrollTop() > 100) {
        $backToTop.fadeIn(1000);
      } else {
        $backToTop.fadeOut(1000);
      }
    });

    $backToTop.click(function () {
      $('body,html').animate({ scrollTop: 0 });
    });
  };

  Even.prototype.renderLaTeX = function () {
    var loopID = setInterval(function () {
      if(window.MathJax) {
        var jax = window.MathJax;
        jax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'], ['\\(', '\\)']] }});
        jax.Hub.Queue(['Typeset', jax.Hub, $(document.body)[0]]);
        clearInterval(loopID);
      }
    }, 500);
  }

  var config = window.config;
  var even = new Even(config);
  even.setup();
}(window))
<|endoftext|>


<commit_before>'use strict';

/* globals patchRequire,casper,phantom */

// override the phantom.casperScriptBaseDir temporarily
const origCasperScriptBaseDir = phantom.casperScriptBaseDir;
phantom.casperScriptBaseDir = origCasperScriptBaseDir + '/..';

var require = patchRequire(require), // jshint ignore:line
    _ = require('lodash'),
    fs = require('fs'),
    path = require('path'),
    options = _.merge({ // Merge default options and cli options
        'file': null,
        'selectors': null,
        'phantomcssPath': null
    }, casper.cli.options, (a, b) => {
        if (b === 'undefined') {
            return null;
        }
    }),
    phantomcssPath = options.phantomcssPath,
    phantomcss = phantomcssPath ? require(path.join(phantomcssPath, 'phantomcss')) : null,
    screenshotDir = '/screenshots',
    failedDir = screenshotDir + '/failed',
    resultsDir = screenshotDir + '/results';

// Reset phantom.casperScriptBaseDir
phantom.casperScriptBaseDir = origCasperScriptBaseDir;

function exit(msg, code = 0) {
    if (msg) {
        if (code === 0) {
            console.log(msg);
        } else {
            console.error(msg);
        }
    }
    return casper.exit(code);
}

function initPhantomCSS(dirPath) {
    let screenshotRoot = dirPath + screenshotDir,
        failedComparisonsRoot = dirPath + failedDir;

    // Remove failed directory if any
    fs.removeTree(failedComparisonsRoot);

    // Initialize phantomCSS
    phantomcss.init({
        casper: casper,
        cleanupComparisonImages: true,
        comparisonResultRoot: dirPath + resultsDir,
        libraryRoot: phantomcssPath,
        screenshotRoot: screenshotRoot,
        failedComparisonsRoot: failedComparisonsRoot,
        addLabelToFailedImage: false,
        mismatchTolerance: 1
    });
}

function takeFullScreenshot(screenshotName) {
    phantomcss.screenshot('*', screenshotName);
}

function getClassNamesToCapture(selectors) {
    // convert the selectors to an array
    selectors = selectors.split(',');

    let classNames = [];

    selectors.forEach(selector => {
        let domNodes = Array.prototype.map.call(document.querySelectorAll(selector), node => node);
        // populate the class names
        domNodes.forEach((element, index) => {
            let className =  'modshot-' + index;
            element.setAttribute('class', element.getAttribute('class') + ' ' + className);
            classNames.push(className);
        });
    });

    return classNames;
}

function takeSelectorScreenshot(screenshotName, classNames) {
    // Take screenshot for all the class names
    classNames.forEach((className, index) => {
        phantomcss.screenshot('.' + className, screenshotName + '-' + index);
    });
}

function compareScreenshot() {
    phantomcss.compareSession();
}

function run() {

    // Check if phantomcss is present
    if (!phantomcss) {
        exit('PhantomCSS not found', 1);
        return;
    }

    let file = options.file;
    if (!file) {
        exit('Please provide a html file path to continue', 1);
        return;
    }
    let fileDir = path.dirname(file);

    // Initialize PhantomCSS
    initPhantomCSS(fileDir);

    casper.test.begin('Visual testing - ' + options.file, test => {
        casper.start(file);

        // Set the viewport
        casper.viewport(1024, 768);

        // Take screenshot
        let screenshotName = path.basename(file, '.html');
        if (options.selectors) {
            casper.then(() => {
                let classNames = casper.evaluate(getClassNamesToCapture, options.selectors);
                takeSelectorScreenshot(screenshotName, classNames);
            });
        } else {
            casper.then(takeFullScreenshot.bind(undefined, screenshotName));
        }

        // Compare screenshot
        casper.then(compareScreenshot);

        // Run & wrap up the test
        casper.run(() => {
            // Clean up the results dir
            fs.removeTree(fileDir + resultsDir);

            console.log('Finished visual testing for - ' + file);
            test.done();
            // Calling exit to prevent unsafe JavaScript error https://github.com/n1k0/casperjs/issues/1068
            casper.exit();
        });
    });
}

// Start the run
run();
<commit_msg>Testing<commit_after>'use strict';

/* globals patchRequire,casper,phantom */

// override the phantom.casperScriptBaseDir temporarily
const origCasperScriptBaseDir = phantom.casperScriptBaseDir;
phantom.casperScriptBaseDir = origCasperScriptBaseDir + '/..';

var require = patchRequire(require), // jshint ignore:line
    _ = require('lodash'),
    fs = require('fs'),
    path = require('path'),
    options = _.merge({ // Merge default options and cli options
        'file': null,
        'selectors': null,
        'phantomcssPath': null
    }, casper.cli.options, (a, b) => {
        if (b === 'undefined') {
            return null;
        }
    }),
    phantomcssPath = options.phantomcssPath,
    phantomcss = phantomcssPath ? require(path.join(phantomcssPath, 'phantomcss')) : null,
    screenshotDir = '/screenshots',
    failedDir = screenshotDir + '/failed',
    resultsDir = screenshotDir + '/results';

// Reset phantom.casperScriptBaseDir
phantom.casperScriptBaseDir = origCasperScriptBaseDir;

function exit(msg, code = 0) {
    if (msg) {
        if (code === 0) {
            console.log(msg);
        } else {
            console.error(msg);
        }
    }
    return casper.exit(code);
}

function initPhantomCSS(dirPath) {
    let screenshotRoot = dirPath + screenshotDir,
        failedComparisonsRoot = dirPath + failedDir;

    // Remove failed directory if any
    fs.removeTree(failedComparisonsRoot);

    // Initialize phantomCSS
    phantomcss.init({
        casper: casper,
        cleanupComparisonImages: true,
        comparisonResultRoot: dirPath + resultsDir,
        libraryRoot: phantomcssPath,
        screenshotRoot: screenshotRoot,
        failedComparisonsRoot: failedComparisonsRoot,
        addLabelToFailedImage: false,
        mismatchTolerance: 0.95
    });
}

function takeFullScreenshot(screenshotName) {
    phantomcss.screenshot('*', screenshotName);
}

function getClassNamesToCapture(selectors) {
    // convert the selectors to an array
    selectors = selectors.split(',');

    let classNames = [];

    selectors.forEach(selector => {
        let domNodes = Array.prototype.map.call(document.querySelectorAll(selector), node => node);
        // populate the class names
        domNodes.forEach((element, index) => {
            let className =  'modshot-' + index;
            element.setAttribute('class', element.getAttribute('class') + ' ' + className);
            classNames.push(className);
        });
    });

    return classNames;
}

function takeSelectorScreenshot(screenshotName, classNames) {
    // Take screenshot for all the class names
    classNames.forEach((className, index) => {
        phantomcss.screenshot('.' + className, screenshotName + '-' + index);
    });
}

function compareScreenshot() {
    phantomcss.compareSession();
}

function run() {

    // Check if phantomcss is present
    if (!phantomcss) {
        exit('PhantomCSS not found', 1);
        return;
    }

    let file = options.file;
    if (!file) {
        exit('Please provide a html file path to continue', 1);
        return;
    }
    let fileDir = path.dirname(file);

    // Initialize PhantomCSS
    initPhantomCSS(fileDir);

    casper.test.begin('Visual testing - ' + options.file, test => {
        casper.start(file);

        // Set the viewport
        casper.viewport(1024, 768);

        // Take screenshot
        let screenshotName = path.basename(file, '.html');
        if (options.selectors) {
            casper.then(() => {
                let classNames = casper.evaluate(getClassNamesToCapture, options.selectors);
                takeSelectorScreenshot(screenshotName, classNames);
            });
        } else {
            casper.then(takeFullScreenshot.bind(undefined, screenshotName));
        }

        // Compare screenshot
        casper.then(compareScreenshot);

        // Run & wrap up the test
        casper.run(() => {
            // Clean up the results dir
            fs.removeTree(fileDir + resultsDir);

            console.log('Finished visual testing for - ' + file);
            test.done();
            // Calling exit to prevent unsafe JavaScript error https://github.com/n1k0/casperjs/issues/1068
            casper.exit();
        });
    });
}

// Start the run
run();
<|endoftext|>