<commit_before>define(['App', 'jquery', 'underscore', 'backbone', 'view/basem-view', 'hbs!template/post-row', 'hbs!template/post-row-small', 'hbs!template/post-row-large', 'view/hover-img-view'],
    function(App, $, _, Backbone, BaseView, PostRowTmpl, PostRowSmallTmpl, PostRowLargeTmpl, HoverImgView) {
        return BaseView.extend({

            events: {
                'click a': "gotoSingle",
                'click .upArrow': 'upvote',
                'click .downArrow': 'downvote',
                'click .save': 'savePost',
                'click .unsave': 'unSavePost',
                'click .hide': 'hidePost',
                'click .report': 'reportShow',
                'click .reportConfirmYes': 'reportYes',
                'click .reportConfirmNo': 'reportShow',
                'click .expando-button': 'toggleExpando',
                'click .share-button': 'toggleShare',
                'drag .dragImg': 'dragImg',
                'mouseover .outBoundLink': 'postLinkHover'
            },
            regions: {
                hoverImgParent: '.md:first'
            },
            ui: {
                'expandoButton': '.expando-button',
                'postRowContent': '.postRowContent',
                upArrow: '.upArrow',
                downArrow: '.downArrow',
                midcol: '.midcol',
                'reportConfirm': '.reportConfirm',
                'reportConfirmYes': '.reportConfirmYes',
                'save': '.save',
                'unsave': '.unsave'
            },
            initialize: function(data) {
                //  _.bindAll(this);
                this.model = data.model;
                this.gridOption = data.gridOption

                this.lastDragPos = {} //keeps track of what direction the user is dragging the image
                this.dragTimeout = null;
                this.dragImgMinWidth = 100

                // this.isSingle = data.isSingle || false
                if (data.isSingle && this.model.get('is_self') === false) {
                    //changes the main post link to be external instead of linking back to itself
                    this.tmpLink = this.model.get('url')
                    this.model.set('url', this.model.get('actualUrl'))
                    this.model.set('external', 'data-bypass')
                } else {
                    //so when the user returns to the subreddit page, we set the model back to non-external link
                    //  this.model.set('url', this.model.get('permalink'))
                    //  this.model.set('external', '')
                }

                if (typeof data.expand !== 'undefined' && (this.model.get('embededImg') === true || this.model.get('selftext_html'))) {
                    console.log('expandhtml=', this.model.get('expandHTML'))
                    this.expand = true;
                }

                if (this.gridOption == "normal" || typeof this.gridOption === 'undefined' || this.gridOption === null) {
                    this.template = PostRowTmpl
                } //else if (this.gridOption == "small") {
                //     this.template = PostRowSmallTmpl
                // } else if (this.gridOption == "large") {
                //     this.template = PostRowLargeTmpl
                // }

            },
            onRender: function() {

                if (this.expand === true) {
                    this.toggleExpando()
                }

            },
            onBeforeClose: function() {
                if (this.tmpLink) {
                    this.model.set('url', this.tmpLink)
                    this.model.set('external', '')
                }
            },

            dragImg: function(e) {
                var self = this

                var target = $(e.currentTarget)
                var targetWidth = target.width()
                var position = target.position();

                if ($.isEmptyObject(this.lastDragPos)) {
                    this.lastDragPos.x = e.originalEvent.pageX
                    this.lastDragPos.y = e.originalEvent.pageY
                    //create img where person clicked mouse to indicate draging direction

                    var posIndicator = $('

').css({
                        top: e.originalEvent.clientY,
                        left: e.originalEvent.clientX
                    })
                    $('body').append(posIndicator)

                }

                if ((this.lastDragPos.x > e.originalEvent.pageX || this.lastDragPos.y > e.originalEvent.pageY) && targetWidth > this.dragImgMinWidth) {
                    target.width(targetWidth - 5)
                } else {
                    target.width(targetWidth + 5)
                }

                clearTimeout(this.dragTimeout);
                this.dragTimeout = setTimeout(function() {
                    self.lastDragPos = {} //resets the direction the user wants to drag the image
                    $('.dragIndicatorImg').remove()
                }, 1000);

            },
            postLinkHover: function(e) {
                //console.log('hovering over a comment')
                e.preventDefault()
                e.stopPropagation()
                if (App.settings.get('cmtLoad') === true) {
                    if (App.Delay !== true) {
                        var target = $(e.currentTarget)

                        var url = $(target).attr("href")

                        var youtubeID = this.youtubeChecker(url);
                        //check if the url is an image we can embed
                        if (youtubeID === false) {
                            url = url.replace(/(\?.*)|(#.*)|(&.*)/g, "")
                        }
                        if (this.checkIsImg(url) === false) {
                            //URL is NOT an image
                            //try and fix an imgur link?
                            url = this.fixImgur(url)

                        }

                        if (url !== false || youtubeID !== false) {

                            var ahrefDescription = $(target).text()
                            if (!ahrefDescription) {
                                ahrefDescription = url
                            }

                            //$(target).css('float', 'left')
                            var originalText = $('.outBoundLink:first').parent().parent().text().trim()
                            var originalHtml = this.$('.outBoundLink:first').parent().parent().html()
                            if (youtubeID) {
                                url = $(target).attr("href") //in case it was a youtube video we should reset the url link to pass into the view
                            }

                            console.log('hello there this is a :' + this);

                            this.hoverImgParent.show(new HoverImgView({
                                url: url,
                                ahrefDescription: ahrefDescription,
                                originalText: originalText,
                                originalHtml: originalHtml,
                                youtubeID: youtubeID

                            }))

                        }
                    }
                }
            },
            toggleExpando: function() {
                //if (this.model.get('embededImg') === false && this.expand === false) {
                // this.ui.expandoButton.hide()
                // return
                //}

                var str;
                if (this.ui.expandoButton.hasClass('expanded')) {
                    this.ui.expandoButton.removeClass('expanded')
                    this.ui.expandoButton.addClass('collapsed')
                    this.ui.postRowContent.html('').hide()
                } else {
                    var model = this.model
                    this.ui.expandoButton.removeClass('collapsed')
                    this.ui.expandoButton.addClass('expanded')

                    if (this.model.get('is_self') === true) {
                        str = '

' + this.model.get('selftext_html') + '

'
                    } else {
                        str = this.model.get('media_embed')
                    }

                    this.ui.postRowContent.html(str).show()

                    this.addOutboundLink()
                }
            }

        });
    });<commit_msg>removed console.log that has no real purpose<commit_after>define(['App', 'jquery', 'underscore', 'backbone', 'view/basem-view', 'hbs!template/post-row', 'hbs!template/post-row-small', 'hbs!template/post-row-large', 'view/hover-img-view'],
    function(App, $, _, Backbone, BaseView, PostRowTmpl, PostRowSmallTmpl, PostRowLargeTmpl, HoverImgView) {
        return BaseView.extend({

            events: {
                'click a': "gotoSingle",
                'click .upArrow': 'upvote',
                'click .downArrow': 'downvote',
                'click .save': 'savePost',
                'click .unsave': 'unSavePost',
                'click .hide': 'hidePost',
                'click .report': 'reportShow',
                'click .reportConfirmYes': 'reportYes',
                'click .reportConfirmNo': 'reportShow',
                'click .expando-button': 'toggleExpando',
                'click .share-button': 'toggleShare',
                'drag .dragImg': 'dragImg',
                'mouseover .outBoundLink': 'postLinkHover'
            },
            regions: {
                hoverImgParent: '.md:first'
            },
            ui: {
                'expandoButton': '.expando-button',
                'postRowContent': '.postRowContent',
                upArrow: '.upArrow',
                downArrow: '.downArrow',
                midcol: '.midcol',
                'reportConfirm': '.reportConfirm',
                'reportConfirmYes': '.reportConfirmYes',
                'save': '.save',
                'unsave': '.unsave'
            },
            initialize: function(data) {
                //  _.bindAll(this);
                this.model = data.model;
                this.gridOption = data.gridOption

                this.lastDragPos = {} //keeps track of what direction the user is dragging the image
                this.dragTimeout = null;
                this.dragImgMinWidth = 100

                // this.isSingle = data.isSingle || false
                if (data.isSingle && this.model.get('is_self') === false) {
                    //changes the main post link to be external instead of linking back to itself
                    this.tmpLink = this.model.get('url')
                    this.model.set('url', this.model.get('actualUrl'))
                    this.model.set('external', 'data-bypass')
                } else {
                    //so when the user returns to the subreddit page, we set the model back to non-external link
                    //  this.model.set('url', this.model.get('permalink'))
                    //  this.model.set('external', '')
                }

                if (typeof data.expand !== 'undefined' && (this.model.get('embededImg') === true || this.model.get('selftext_html'))) {
                    console.log('expandhtml=', this.model.get('expandHTML'))
                    this.expand = true;
                }

                if (this.gridOption == "normal" || typeof this.gridOption === 'undefined' || this.gridOption === null) {
                    this.template = PostRowTmpl
                } //else if (this.gridOption == "small") {
                //     this.template = PostRowSmallTmpl
                // } else if (this.gridOption == "large") {
                //     this.template = PostRowLargeTmpl
                // }

            },
            onRender: function() {

                if (this.expand === true) {
                    this.toggleExpando()
                }

            },
            onBeforeClose: function() {
                if (this.tmpLink) {
                    this.model.set('url', this.tmpLink)
                    this.model.set('external', '')
                }
            },

            dragImg: function(e) {
                var self = this

                var target = $(e.currentTarget)
                var targetWidth = target.width()
                var position = target.position();

                if ($.isEmptyObject(this.lastDragPos)) {
                    this.lastDragPos.x = e.originalEvent.pageX
                    this.lastDragPos.y = e.originalEvent.pageY
                    //create img where person clicked mouse to indicate draging direction

                    var posIndicator = $('

').css({
                        top: e.originalEvent.clientY,
                        left: e.originalEvent.clientX
                    })
                    $('body').append(posIndicator)

                }

                if ((this.lastDragPos.x > e.originalEvent.pageX || this.lastDragPos.y > e.originalEvent.pageY) && targetWidth > this.dragImgMinWidth) {
                    target.width(targetWidth - 5)
                } else {
                    target.width(targetWidth + 5)
                }

                clearTimeout(this.dragTimeout);
                this.dragTimeout = setTimeout(function() {
                    self.lastDragPos = {} //resets the direction the user wants to drag the image
                    $('.dragIndicatorImg').remove()
                }, 1000);

            },
            postLinkHover: function(e) {
                //console.log('hovering over a comment')
                e.preventDefault()
                e.stopPropagation()
                if (App.settings.get('cmtLoad') === true) {
                    if (App.Delay !== true) {
                        var target = $(e.currentTarget)

                        var url = $(target).attr("href")

                        var youtubeID = this.youtubeChecker(url);
                        //check if the url is an image we can embed
                        if (youtubeID === false) {
                            url = url.replace(/(\?.*)|(#.*)|(&.*)/g, "")
                        }
                        if (this.checkIsImg(url) === false) {
                            //URL is NOT an image
                            //try and fix an imgur link?
                            url = this.fixImgur(url)

                        }

                        if (url !== false || youtubeID !== false) {

                            var ahrefDescription = $(target).text()
                            if (!ahrefDescription) {
                                ahrefDescription = url
                            }

                            //$(target).css('float', 'left')
                            var originalText = $('.outBoundLink:first').parent().parent().text().trim()
                            var originalHtml = this.$('.outBoundLink:first').parent().parent().html()
                            if (youtubeID) {
                                url = $(target).attr("href") //in case it was a youtube video we should reset the url link to pass into the view
                            }

                            this.hoverImgParent.show(new HoverImgView({
                                url: url,
                                ahrefDescription: ahrefDescription,
                                originalText: originalText,
                                originalHtml: originalHtml,
                                youtubeID: youtubeID

                            }))

                        }
                    }
                }
            },
            toggleExpando: function() {
                //if (this.model.get('embededImg') === false && this.expand === false) {
                // this.ui.expandoButton.hide()
                // return
                //}

                var str;
                if (this.ui.expandoButton.hasClass('expanded')) {
                    this.ui.expandoButton.removeClass('expanded')
                    this.ui.expandoButton.addClass('collapsed')
                    this.ui.postRowContent.html('').hide()
                } else {
                    var model = this.model
                    this.ui.expandoButton.removeClass('collapsed')
                    this.ui.expandoButton.addClass('expanded')

                    if (this.model.get('is_self') === true) {
                        str = '

' + this.model.get('selftext_html') + '

'
                    } else {
                        str = this.model.get('media_embed')
                    }

                    this.ui.postRowContent.html(str).show()

                    this.addOutboundLink()
                }
            }

        });
    });<|endoftext|>


<commit_before>/*global define*/
define([
	'jQuery-2.1.4.min',
	'underscore_1.3.3',
	'backbone_0.9.2',
	'text!../../../js/app/templates/leftMenu.html'
], function ($, _, Backbone, LeftMenuTemplate) {
	'use strict';

	var LeftMenuView = Backbone.View.extend({

		tagName:  'div',

    el: '#leftMenu',

		template: _.template(LeftMenuTemplate),

		// The DOM events specific to an item.
		events: {
			//'click .toggle':	'toggleCompleted',
			//'dblclick label':	'edit',
			//'click .destroy':	'clear',
			//'keypress .edit':	'updateOnEnter',
			//'keydown .edit':	'revertOnEscape',
			//'blur .edit':		'close'
      'click #dashboardLink': 'showDashboard',
      'click #pagesLink': 'showPages',
      'click #pageList': 'showPages2',
      'click #postsLink': 'showPosts',
      'click #postList': 'showPosts2',
      'click #postAddNew': 'showPostsAddNew',
      'click #pageAddNew': 'showPagesAddNew',
      'click #mediaLink': 'showImageLibrary',
      'click #imageLibraryLink': 'showImageLibrary2',
      'click #imageAddNew': 'showImageAddNew',
      'click .sidebar li a': 'treeMenu',
      'click #fileLibraryLink': 'showFileLibrary',
      'click #categories': 'showCategories',
      'click #sections': 'showSections',
      'click #frontEndWidgetLink': 'showFrontEndWidgets'
		},

		// The TodoView listens for changes to its model, re-rendering. Since there's
		// a one-to-one correspondence between a **Todo** and a **TodoView** in this
		// app, we set a direct reference on the model for convenience.
		initialize: function () {
			//this.listenTo(this.model, 'change', this.render);
			//this.listenTo(this.model, 'destroy', this.remove);
			//this.listenTo(this.model, 'visible', this.toggleVisible);
		},

		// Re-render the titles of the todo item.
		render: function () {
			//this.$el.html(this.template(this.model.toJSON()));
      this.$el.html(this.template);
			//this.$el.toggleClass('completed', this.model.get('completed'));

      //Show the link to the Keystone Admin UI if the current user is a superuser.
      if(superusers.indexOf(userdata._id) > -1)
        this.$el.find('#keystone-link').show();

			//this.toggleVisible();
			//this.$input = this.$('.edit');
			return this;
		},

    showDashboard: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').show();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      else
        this.closeCollapsableLeftMenu();

      //Switch the 'active' class to the selected menu item
      $('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Dashboard');
    },

    //This function shows the down-down menu for Pages in the left menu.
    showPages: function (e) {
      //debugger;

      this.treeMenu(e, "#pagesLink");
    },

    //This function shows the drop-down menu for Posts in the left menu.
    showPosts: function (e) {
      //debugger;

      this.treeMenu(e, "#postsLink");
    },

    //This function shows the postsView and hides all other views.
    showPosts2: function (e) {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#postsView').show();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      //if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
      //  $('.sidebar-menu').find('.active').removeClass('active');
      //else
      //  this.closeCollapsableLeftMenu();
      //Switch the 'active' class to the selected menu item
      //$('#pagesLink').parent().addClass('active');

      $('#app-location').text('Posts');

      //Render the Pages view.
      global.postsView.render();
      //global.pagesAddNewView.render();

      //this.treeMenu(e, "#pagesLink");
    },

    showPages2: function (e) {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').show();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      //if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
      //  $('.sidebar-menu').find('.active').removeClass('active');
      //else
      //  this.closeCollapsableLeftMenu();
      //Switch the 'active' class to the selected menu item
      //$('#pagesLink').parent().addClass('active');

      $('#app-location').text('Pages');

      //Render the Pages view.
      global.pagesView.render();
      //global.pagesAddNewView.render();

      //this.treeMenu(e, "#pagesLink");
    },

    showPostsAddNew: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#pagesAddNewView').hide();
      $('#postsAddNewView').show();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      //else
      //  this.closeCollapsableLeftMenu();
      //Switch the 'active' class to the selected menu item
      //$('#pagesLink').parent().addClass('active');

      $('#app-location').text('Posts : Add New');

      //Signal that a blank, new post should be added.
      global.tinymce.currentModelIndex = null;

      //Render the Pages view.
      global.postsAddNewView.render();
    },

    showPagesAddNew: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#pagesAddNewView').show();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      //else
      //  this.closeCollapsableLeftMenu();
      //Switch the 'active' class to the selected menu item
      //$('#pagesLink').parent().addClass('active');

      $('#app-location').text('Pages : Add New');

      //Signal that a blank, new post should be added.
      global.tinymce.currentModelIndex = null;

      //Render the Pages view.
      global.pagesAddNewView.render();
    },

    showImageLibrary: function(e) {
      //debugger;

      this.treeMenu(e, "#mediaLink");
    },

    showImageLibrary2: function(e) {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').show();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      //if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
      //  $('.sidebar-menu').find('.active').removeClass('active');
      //Switch the 'active' class to the selected menu item
      //$('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Image Library - View Gallery');

      //CT 9/8/16 - Replaced code below with this new functionality. image collection should be loaded on load and refreshed if changed.
      //Not refreshed right before loading of the view.
      if( global.imageUploadCollection == undefined ) {
        global.imageUploadCollection.reset();
      }
      //If the library has already been loaded once, reset the collection before loading the page
      //in case there have been any additions to the library.
      //if( global.imageUploadCollection != undefined ) {
      //  global.imageUploadCollection.reset();
      //}

      //render the image library page.
      global.imageLibraryView.render();

      //this.treeMenu(e, "#mediaLink");
    },

    showImageAddNew: function() {
      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').show();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      //Switch the 'active' class to the selected menu item
      //$('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Image Library - Add New');

      //render the image library page.
      global.imageAddNewView.render();
    },

    //This function copied from adminlte.js. Moved here as it controls the animation of this view
    //and the animation was getting screwed up.
    treeMenu: function(e, linkElem) {
      //debugger;

      //Get the clicked link and the next element
      var $this = $(linkElem);
      var checkElement = $this.next();
      var animationSpeed = $.AdminLTE.options.animationSpeed;
      var _this = $.AdminLTE;

      //Check if the next element is a menu and is visible
      if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) {
        //Close the menu
        checkElement.slideUp(animationSpeed, function () {
          checkElement.removeClass('menu-open');
          //Fix the layout in case the sidebar stretches over the height of the window
          //_this.layout.fix();
        });
        checkElement.parent("li").removeClass("active");
      }
      //If the menu is not visible
      else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) {
        //Get the parent menu
        var parent = $this.parents('ul').first();
        //Close all open menus within the parent
        var ul = parent.find('ul:visible').slideUp(animationSpeed);
        //Remove the menu-open class from the parent
        ul.removeClass('menu-open');
        //Get the parent li
        var parent_li = $this.parent("li");

        //Open the target menu and add the menu-open class
        checkElement.slideDown(animationSpeed, function () {
          //Add the class active to the parent li
          checkElement.addClass('menu-open');
          parent.find('li.active').removeClass('active');
          parent_li.addClass('active');
          //Fix the layout in case the sidebar stretches over the height of the window
          //debugger; //line below this is causing an error: 'Uncaught TypeError: Cannot read property 'fix' of undefined'
          //_this.layout.fix();
        });
      }
      //if this isn't a link, prevent the page from being redirected
      if (checkElement.is('.treeview-menu')) {
        try{
          e.preventDefault();
        } catch(err) {
          if( e == undefined ) {
            log.push('treeMenu() called without event.');
          } else {
            console.error('Unhandled error in treeMenu() in leftMenuView.js. Error:');
            console.error(err.message);

            log.push('Unhandled error in treeMenu() in leftMenuView.js. Error:');
            log.push(err.message);
            sendLog();
          }
        }
      }
    },

    //This function is called to close collapsable menus.
    closeCollapsableLeftMenu: function() {
      //debugger;

      var $this = $('.menu-open').parent().find('a');
      var checkElement = $this.next();
      var animationSpeed = $.AdminLTE.options.animationSpeed;

      //Check if the next element is a menu and is visible
      if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) {
        //Close the menu
        checkElement.slideUp(animationSpeed, function () {
          checkElement.removeClass('menu-open');
          //Fix the layout in case the sidebar stretches over the height of the window
          //_this.layout.fix();
        });
        checkElement.parent("li").removeClass("active");
      }
    },

    showFileLibrary: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').show();
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      //if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
      //  $('.sidebar-menu').find('.active').removeClass('active');
      //Switch the 'active' class to the selected menu item
      //$('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Media Library - Files');

      //If the library has already been loaded once, reset the collection before loading the page
      //in case there have been any additions to the library.
      //if( global.imageUploadCollection != undefined ) {
      //  global.imageUploadCollection.reset();
      //}

      //render the image library page.
      global.fileLibraryView.render();
    },

    showCategories: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide()
      $('#categoriesView').show();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      //if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
      //  $('.sidebar-menu').find('.active').removeClass('active');
      //Switch the 'active' class to the selected menu item
      //$('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Posts : Categories');

      //If the library has already been loaded once, reset the collection before loading the page
      //in case there have been any additions to the library.
      //if( global.imageUploadCollection != undefined ) {
      //  global.imageUploadCollection.reset();
      //}

      //render the image library page.
      global.categoriesView.render();
    },

    showSections: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide()
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').show();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      //if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
      //  $('.sidebar-menu').find('.active').removeClass('active');
      //Switch the 'active' class to the selected menu item
      //$('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Pages : Sections');

      //If the library has already been loaded once, reset the collection before loading the page
      //in case there have been any additions to the library.
      //if( global.imageUploadCollection != undefined ) {
      //  global.imageUploadCollection.reset();
      //}

      //render the image library page.
      global.sectionsView.render();
    },

    showFrontEndWidgets: function() {
      //debugger;

      //Hide old Views and show new one.
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide()
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').show();
      $('#widgetEditor').hide();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      else
        this.closeCollapsableLeftMenu();

      //Switch the 'active' class to the selected menu item
      $('#frontEndWidgetLink').parent().addClass('active');

      $('#app-location').text('Front End Widgets');

      //render the image library page.
      global.frontEndWidgetView.render();
    },

    hideAll: function() {
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide()
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      debugger;

      //Loop through any views associated with loaded plugins and hide those views as well.
      for(var i=0; i < global.pluginView.loadedPlugins.length; i++) {

        //Loop through all the views in this plugin
        for(var j=0; j < global.pluginView.loadedPlugins[i].views.length; j++) {

          //Hide the view
          global.pluginView.loadedPlugins[i].views[j].$el.hide();
        }
      }

    }

	});

  //debugger;
	return LeftMenuView;
});
<commit_msg>Updating and refactoring leftMenuView.js<commit_after>/*global define*/
define([
	'jQuery-2.1.4.min',
	'underscore_1.3.3',
	'backbone_0.9.2',
	'text!../../../js/app/templates/leftMenu.html'
], function ($, _, Backbone, LeftMenuTemplate) {
	'use strict';

	var LeftMenuView = Backbone.View.extend({

		tagName:  'div',

    el: '#leftMenu',

		template: _.template(LeftMenuTemplate),

		// The DOM events specific to an item.
		events: {
			//'click .toggle':	'toggleCompleted',
			//'dblclick label':	'edit',
			//'click .destroy':	'clear',
			//'keypress .edit':	'updateOnEnter',
			//'keydown .edit':	'revertOnEscape',
			//'blur .edit':		'close'
      'click #dashboardLink': 'showDashboard',
      'click #pagesLink': 'showPages',
      'click #pageList': 'showPages2',
      'click #postsLink': 'showPosts',
      'click #postList': 'showPosts2',
      'click #postAddNew': 'showPostsAddNew',
      'click #pageAddNew': 'showPagesAddNew',
      'click #mediaLink': 'showImageLibrary',
      'click #imageLibraryLink': 'showImageLibrary2',
      'click #imageAddNew': 'showImageAddNew',
      'click .sidebar li a': 'treeMenu',
      'click #fileLibraryLink': 'showFileLibrary',
      'click #categories': 'showCategories',
      'click #sections': 'showSections',
      'click #frontEndWidgetLink': 'showFrontEndWidgets'
		},

		// The TodoView listens for changes to its model, re-rendering. Since there's
		// a one-to-one correspondence between a **Todo** and a **TodoView** in this
		// app, we set a direct reference on the model for convenience.
		initialize: function () {
			//this.listenTo(this.model, 'change', this.render);
			//this.listenTo(this.model, 'destroy', this.remove);
			//this.listenTo(this.model, 'visible', this.toggleVisible);
		},

		render: function () {
      this.$el.html(this.template);

      //Show the link to the Keystone Admin UI if the current user is a superuser.
      if(superusers.indexOf(userdata._id) > -1)
        this.$el.find('#keystone-link').show();

			return this;
		},

    showDashboard: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#dashboardView').show();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      else
        this.closeCollapsableLeftMenu();

      //Switch the 'active' class to the selected menu item
      $('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Dashboard');
    },

    //This function shows the down-down menu for Pages in the left menu.
    showPages: function (e) {
      //debugger;

      this.treeMenu(e, "#pagesLink");
    },

    //This function shows the drop-down menu for Posts in the left menu.
    showPosts: function (e) {
      //debugger;

      this.treeMenu(e, "#postsLink");
    },

    //This function shows the postsView and hides all other views.
    showPosts2: function (e) {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#postsView').show();

      $('#app-location').text('Posts');

      //Render the Pages view.
      global.postsView.render();

    },

    showPages2: function (e) {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#pagesView').show();

      $('#app-location').text('Pages');

      //Render the Pages view.
      global.pagesView.render();

    },

    showPostsAddNew: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#postsAddNewView').show();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');

      $('#app-location').text('Posts : Add New');

      //Signal that a blank, new post should be added.
      global.tinymce.currentModelIndex = null;

      //Render the Pages view.
      global.postsAddNewView.render();
    },

    showPagesAddNew: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#pagesAddNewView').show();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');

      $('#app-location').text('Pages : Add New');

      //Signal that a blank, new post should be added.
      global.tinymce.currentModelIndex = null;

      //Render the Pages view.
      global.pagesAddNewView.render();
    },

    showImageLibrary: function(e) {
      //debugger;

      this.treeMenu(e, "#mediaLink");
    },

    showImageLibrary2: function(e) {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#imageLibraryView').show();

      $('#app-location').text('Image Library - View Gallery');

      if( global.imageUploadCollection == undefined ) {
        global.imageUploadCollection.reset();
      }

      //render the image library page.
      global.imageLibraryView.render();

    },

    showImageAddNew: function() {
      //Hide old Views and show new one.
      this.hideAll();
      $('#imageAddNewView').show();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      //Switch the 'active' class to the selected menu item
      //$('#dashboardLink').parent().addClass('active');

      $('#app-location').text('Image Library - Add New');

      //render the image library page.
      global.imageAddNewView.render();
    },

    //This function copied from adminlte.js. Moved here as it controls the animation of this view
    //and the animation was getting screwed up.
    treeMenu: function(e, linkElem) {
      //debugger;

      //Get the clicked link and the next element
      var $this = $(linkElem);
      var checkElement = $this.next();
      var animationSpeed = $.AdminLTE.options.animationSpeed;
      var _this = $.AdminLTE;

      //Check if the next element is a menu and is visible
      if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) {
        //Close the menu
        checkElement.slideUp(animationSpeed, function () {
          checkElement.removeClass('menu-open');
          //Fix the layout in case the sidebar stretches over the height of the window
          //_this.layout.fix();
        });
        checkElement.parent("li").removeClass("active");
      }
      //If the menu is not visible
      else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) {
        //Get the parent menu
        var parent = $this.parents('ul').first();
        //Close all open menus within the parent
        var ul = parent.find('ul:visible').slideUp(animationSpeed);
        //Remove the menu-open class from the parent
        ul.removeClass('menu-open');
        //Get the parent li
        var parent_li = $this.parent("li");

        //Open the target menu and add the menu-open class
        checkElement.slideDown(animationSpeed, function () {
          //Add the class active to the parent li
          checkElement.addClass('menu-open');
          parent.find('li.active').removeClass('active');
          parent_li.addClass('active');
          //Fix the layout in case the sidebar stretches over the height of the window
          //debugger; //line below this is causing an error: 'Uncaught TypeError: Cannot read property 'fix' of undefined'
          //_this.layout.fix();
        });
      }
      //if this isn't a link, prevent the page from being redirected
      if (checkElement.is('.treeview-menu')) {
        try{
          e.preventDefault();
        } catch(err) {
          if( e == undefined ) {
            log.push('treeMenu() called without event.');
          } else {
            console.error('Unhandled error in treeMenu() in leftMenuView.js. Error:');
            console.error(err.message);

            log.push('Unhandled error in treeMenu() in leftMenuView.js. Error:');
            log.push(err.message);
            sendLog();
          }
        }
      }
    },

    //This function is called to close collapsable menus.
    closeCollapsableLeftMenu: function() {
      //debugger;

      var $this = $('.menu-open').parent().find('a');
      var checkElement = $this.next();
      var animationSpeed = $.AdminLTE.options.animationSpeed;

      //Check if the next element is a menu and is visible
      if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) {
        //Close the menu
        checkElement.slideUp(animationSpeed, function () {
          checkElement.removeClass('menu-open');
          //Fix the layout in case the sidebar stretches over the height of the window
          //_this.layout.fix();
        });
        checkElement.parent("li").removeClass("active");
      }
    },

    showFileLibrary: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#fileLibraryView').show();

      $('#app-location').text('Media Library - Files');

      //render the image library page.
      global.fileLibraryView.render();
    },

    showCategories: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#categoriesView').show();

      $('#app-location').text('Posts : Categories');

      //render the image library page.
      global.categoriesView.render();
    },

    showSections: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#sectionsView').show();

      $('#app-location').text('Pages : Sections');

      //render the image library page.
      global.sectionsView.render();
    },

    showFrontEndWidgets: function() {
      //debugger;

      //Hide old Views and show new one.
      this.hideAll();
      $('#frontEndWidgetView').show();

      //Remove the 'active' class from the menu item, unless it's a treeview menu item.
      //(treeview) menu items will remove their active class in their click event.
      if( !$('.sidebar-menu').find('.active').hasClass('treeview') )
        $('.sidebar-menu').find('.active').removeClass('active');
      else
        this.closeCollapsableLeftMenu();

      //Switch the 'active' class to the selected menu item
      $('#frontEndWidgetLink').parent().addClass('active');

      $('#app-location').text('Front End Widgets');

      //render the image library page.
      global.frontEndWidgetView.render();
    },

    hideAll: function() {
      $('#dashboardView').hide();
      $('#pagesView').hide();
      $('#imageLibraryView').hide();
      $('#imageAddNewView').hide();
      $('#pagesAddNewView').hide();
      $('#fileLibraryView').hide()
      $('#categoriesView').hide();
      $('#postsView').hide();
      $('#postsAddNewView').hide();
      $('#sectionsView').hide();
      $('#frontEndWidgetView').hide();
      $('#widgetEditor').hide();

      //Loop through any views associated with loaded plugins and hide those views as well.
      for(var i=0; i < global.pluginView.loadedPlugins.length; i++) {

        //Loop through all the views in this plugin
        for(var j=0; j < global.pluginView.loadedPlugins[i].views.length; j++) {

          //Hide the view
          global.pluginView.loadedPlugins[i].views[j].$el.hide();
        }
      }

    }

	});

  //debugger;
	return LeftMenuView;
});
<|endoftext|>


<commit_before>function SettingReplyCtrl($scope) {

    $scope.todos = [
        {text: 'Mathew is kewl', done: true}
      , {text: 'He loves Irene.', done: true}
    ];

    $scope.get_total_todos = function() {
        return $scope.todos.length;
    };

    $scope.add_todo = function($event) {
        if(!$scope.form_todo_text) {
            alert("cannot be blank!");
        } else {
            $scope.todos.push({text: $scope.form_todo_text, done: false});
            $scope.form_todo_text = null;
        }
        $event.preventDefault();
    };

    $scope.clear_completed = function($event) {
        console.log($scope.todos);

        jQuery.each($scope.todos, function(index, value) {
            console.log(index);
            console.log(value);
        })

        $event.preventDefault();
    }
}
<commit_msg>The power of functional programming<commit_after>function SettingReplyCtrl($scope) {

    $scope.todos = [
        {text: 'Mathew is kewl', done: true}
      , {text: 'He loves Irene.', done: true}
    ];

    $scope.get_total_todos = function() {
        return $scope.todos.length;
    };

    $scope.add_todo = function($event) {
        if(!$scope.form_todo_text) {
            alert("cannot be blank!");
        } else {
            $scope.todos.push({text: $scope.form_todo_text, done: false});
            $scope.form_todo_text = null;
        }
        $event.preventDefault();
    };

    $scope.clear_completed = function($event) {
        console.log($scope.todos);

        var todos = jQuery.grep($scope.todos, function(index, value) {
            return !value.todos;
        })

        console.log(todos);

        $event.preventDefault();
    }
}
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare","dijit/_WidgetBase","dojo/on",
	"dojo/dom-class",
	"dojo/text!./templates/Assembly.html","./AppBase","dojo/dom-construct",
        "dojo/_base/Deferred","dojo/aspect","dojo/_base/lang","dojo/domReady!","dijit/form/NumberTextBox",
	"dojo/query"
], function(
	declare, WidgetBase, on,
	domClass,
	Template,AppBase,domConstr,
        Deferred,aspect,lang,domReady,NumberTextBox,query
){
	return declare([AppBase], {
		"baseClass": "App Assembly",
		templateString: Template,
		applicationName: "GenomeAssembly",
		libraryData: null,
		startingRows: 14,

		constructor: function(){

			this.addedLibs=0;
			this.addedPairs=0;
			this.pairToAttachPt={
				read1:"read1pair1",
				read2:"read2pair1",
				interleaved:"interleaved",
				insert_size_mean:"avgpair1",
				insert_size_stdev:"stdpair1"};
			this.singleToAttachPt={
				single_end_libs:"read1"};
		},

                startup: function(){
                        if (this._started) { return; }
                        this.inherited(arguments);
			for (i = 0; i < this.startingRows; i++) {
				var tr =  this.libsTable.insertRow(0);//domConstr.create("tr",{},this.libsTableBody);
				var td = domConstr.create('td', {innerHTML: "

"},tr);
				var td2 = domConstr.create("td", {innerHTML: "

"},tr);
			}
			this.numlibs.startup();
			//this.read1pair1.set('value',"/" +  window.App.user.id +"/home/");
			//this.read2pair1.set('value',"/" +  window.App.user.id +"/home/");
			//this.read1.set('value',"/" +  window.App.user.id +"/home/");
			//this.output_path.set('value',"/" +  window.App.user.id +"/home/");
/*
			this.libraryGrid = new Grid({
				columns: {'first': 'Libraries in assembly'}
			}, this.gridNode);

			this.libraryGrid.startup();
			this.libraryGrid.renderArray(this.libraryData);
*/
			this._started=true;
		},
		getValues:function(){
			if (typeof String.prototype.startsWith != 'function') {
				String.prototype.startsWith = function (str){
    					return this.slice(0, str.length) == str;
  				};
			}
			var assembly_values={};
			var values = this.inherited(arguments);
			var pairedList = query(".pairdata");
			var singleList = query(".singledata");
			var pairedLibs =[];
			var singleLibs=[];
			for (var k in values) {
				if(!k.startsWith("libdat_")){
					assembly_values[k]=values[k];
				}
			}
			pairedList.forEach(function(item){
				pairedLibs.push(item.libRecord)});
			if(pairedLibs.length){
				assembly_values["paired_end_libs"]=pairedLibs;
			}
			singleList.forEach(function(item){
				singleLibs.push(item.libRecord["single_end_libs"]) });
			if(singleLibs.length){
				assembly_values["single_end_libs"]=singleLibs;
			}
			return assembly_values;

		},
		ingestLibrary: function(input_pts, target){
			var success=1;
			for (var key in input_pts) {
				var cur_value=this[input_pts[key]].value;
				if(typeof(cur_value) == "string"){
					target[key]=cur_value.trim();
				}
				else{
					target[key]=cur_value;
				}
				if(!target[key]){
					this[input_pts[key]]._set("state","Error");
					success=0;
				}
				else{
					this[input_pts[key]]._set("state","");
				}
			}
			return(success);
		},
		makePairName:function(libRecord){
			var fn =libRecord["read1"].replace(/^.*[\\\/]/, '');
			var fn2 =libRecord["read2"].replace(/^.*[\\\/]/, '');
			if(fn.length > 10){
				fn=fn.substr(0,3)+".."+fn.substr(7,9);
			}
			if(fn2.length > 10){
				fn2=fn2.substr(0,3)+".."+fn2.substr(7,9);
			}
			return "("+fn+", "+fn2+")";
		},

		makeSingleName:function(libRecord){
			var fn =libRecord["single_end_libs"].replace(/^.*[\\\/]/, '');
			if(fn.length > 10){
				fn=fn.substr(0,3)+".."+fn.substr(7,9);
			}
			return fn;
		},

		increaseLib: function(){
			this.addedLibs= this.addedLibs+1;
			this.numlibs.set('value',Number(this.addedLibs));

		},
		decreaseLib: function(){
			this.addedLibs = this.addedLibs-1;
			this.numlibs.set('value',Number(this.addedLibs));
		},
		onAddSingle: function(){
			console.log("Create New Row", domConstr);
			var lrec={};
			var chkPassed=this.ingestLibrary(this.singleToAttachPt, lrec);
			if (chkPassed){
				var tr = this.libsTable.insertRow(0);
				var td = domConstr.create('td', {"class":"singledata", innerHTML:""},tr);
				td.libRecord=lrec;
				td.innerHTML=this.makeSingleName(td.libRecord);
				var td2 = domConstr.create("td", {innerHTML: ""},tr);
				if(this.addedLibs < this.startingRows){
					this.libsTable.deleteRow(-1);
				}
				var handle = on(td2, "click", lang.hitch(this,function(evt){
					console.log("Delete Row");
					domConstr.destroy(tr);
					this.decreaseLib();
					if (this.addedLibs < this.startingRows){
						var ntr = this.libsTable.insertRow(-1);
						var ntd = domConstr.create('td', {innerHTML: "

"},ntr);
						var ntd2 = domConstr.create("td", {innerHTML: "

"},ntr);
					}
					handle.remove();
				}));
				this.increaseLib();
			}
		},

		onAddPair: function(){
			console.log("Create New Row", domConstr);
//			var tr =  domConstr.create("tr",{});
//			domConstr.place(tr,this.libsTableBody,"first");
			var lrec={};
			var chkPassed=this.ingestLibrary(this.pairToAttachPt, lrec);
			if (chkPassed){
				var tr = this.libsTable.insertRow(0);
				var td = domConstr.create('td', {"class":"pairdata", innerHTML:""},tr);
				td.libRecord=lrec;
				td.innerHTML=this.makePairName(td.libRecord);
				var td2 = domConstr.create("td", {innerHTML: ""},tr);
				if(this.addedLibs < this.startingRows){
					this.libsTable.deleteRow(-1);
				}
				var handle = on(td2, "click", lang.hitch(this,function(evt){
					console.log("Delete Row");
					domConstr.destroy(tr);
					this.decreaseLib();
					if (this.addedLibs < this.startingRows){
	//					var ntr =  domConstr.create("tr",{});
	//					domConstr.place("ntr",this.libsTableBody,"last");
						var ntr = this.libsTable.insertRow(-1);
						var ntd = domConstr.create('td', {innerHTML: "

"},ntr);
						var ntd2 = domConstr.create("td", {innerHTML: "

"},ntr);
					}
					handle.remove();
				}));
				this.increaseLib();
			}
		}

	});
});

<commit_msg>updating Assembly form to get values correctly for ObjectSelector<commit_after>define([
	"dojo/_base/declare","dijit/_WidgetBase","dojo/on",
	"dojo/dom-class",
	"dojo/text!./templates/Assembly.html","./AppBase","dojo/dom-construct",
        "dojo/_base/Deferred","dojo/aspect","dojo/_base/lang","dojo/domReady!","dijit/form/NumberTextBox",
	"dojo/query"
], function(
	declare, WidgetBase, on,
	domClass,
	Template,AppBase,domConstr,
        Deferred,aspect,lang,domReady,NumberTextBox,query
){
	return declare([AppBase], {
		"baseClass": "App Assembly",
		templateString: Template,
		applicationName: "GenomeAssembly",
		libraryData: null,
		startingRows: 14,

		constructor: function(){

			this.addedLibs=0;
			this.addedPairs=0;
			this.pairToAttachPt=["read1", "read2", "interleaved", "insert_size_mean", "insert_size_stdev"];
			this.paramToAttachPt=["recipe","output_path","output_file","reference_assembly"];
			this.singleToAttachPt=["single_end_libs"];
		},

                startup: function(){
                        if (this._started) { return; }
                        this.inherited(arguments);
			for (i = 0; i < this.startingRows; i++) {
				var tr =  this.libsTable.insertRow(0);//domConstr.create("tr",{},this.libsTableBody);
				var td = domConstr.create('td', {innerHTML: "

"},tr);
				var td2 = domConstr.create("td", {innerHTML: "

"},tr);
			}
			this.numlibs.startup();
			this.read1.set('value',"/" +  window.App.user.id +"/home/");
			this.read2.set('value',"/" +  window.App.user.id +"/home/");
			this.single_end_libs.set('value',"/" +  window.App.user.id +"/home/");
			this.output_path.set('value',"/" +  window.App.user.id +"/home/");
/*
			this.libraryGrid = new Grid({
				columns: {'first': 'Libraries in assembly'}
			}, this.gridNode);

			this.libraryGrid.startup();
			this.libraryGrid.renderArray(this.libraryData);
*/
			this._started=true;
		},
		getValues:function(){
			if (typeof String.prototype.startsWith != 'function') {
				String.prototype.startsWith = function (str){
    					return this.slice(0, str.length) == str;
  				};
			}
			var assembly_values={};
			var values = this.inherited(arguments);
			var pairedList = query(".pairdata");
			var singleList = query(".singledata");
			var pairedLibs =[];
			var singleLibs=[];
			this.ingestAttachPoints(this.paramToAttachPt, assembly_values);
			//for (var k in values) {
			//	if(!k.startsWith("libdat_")){
			//		assembly_values[k]=values[k];
			//	}
			//}
			pairedList.forEach(function(item){
				pairedLibs.push(item.libRecord)});
			if(pairedLibs.length){
				assembly_values["paired_end_libs"]=pairedLibs;
			}
			singleList.forEach(function(item){
				singleLibs.push(item.libRecord["single_end_libs"]) });
			if(singleLibs.length){
				assembly_values["single_end_libs"]=singleLibs;
			}
			return assembly_values;

		},
		ingestAttachPoints: function(input_pts, target){
			var success=1;
			input_pts.forEach(function(attachname){
				var cur_value=null;
				var incomplete =0;
				if(attachname == "read1" || attachname == "read2" || attachname == "single_end_libs"){
					cur_value=this[attachname].searchBox.get('value');
					incomplete=((cur_value.replace(/^.*[\\\/]/, '')).length==0);
				}
				else if(attachname == "output_path"){
					cur_value=this[attachname].searchBox.get('value');
				}
				else {
					cur_value=this[attachname].value;
				}

				if(typeof(cur_value) == "string"){
					target[attachname]=cur_value.trim();
				}
				else{
					target[attachname]=cur_value;
				}
				if(!target[attachname] || incomplete){
					this[attachname]._set("state","Error");
					success=0;
				}
				else{
					this[attachname]._set("state","");
				}
			}, this);
			return(success);
		},
		makePairName:function(libRecord){
			var fn =libRecord["read1"].replace(/^.*[\\\/]/, '');
			var fn2 =libRecord["read2"].replace(/^.*[\\\/]/, '');
			if(fn.length > 10){
				fn=fn.substr(0,3)+".."+fn.substr(7,9);
			}
			if(fn2.length > 10){
				fn2=fn2.substr(0,3)+".."+fn2.substr(7,9);
			}
			return "("+fn+", "+fn2+")";
		},

		makeSingleName:function(libRecord){
			var fn =libRecord["single_end_libs"].replace(/^.*[\\\/]/, '');
			if(fn.length > 10){
				fn=fn.substr(0,3)+".."+fn.substr(7,9);
			}
			return fn;
		},

		increaseLib: function(){
			this.addedLibs= this.addedLibs+1;
			this.numlibs.set('value',Number(this.addedLibs));

		},
		decreaseLib: function(){
			this.addedLibs = this.addedLibs-1;
			this.numlibs.set('value',Number(this.addedLibs));
		},
		onAddSingle: function(){
			console.log("Create New Row", domConstr);
			var lrec={};
			var chkPassed=this.ingestAttachPoints(this.singleToAttachPt, lrec);
			if (chkPassed){
				var tr = this.libsTable.insertRow(0);
				var td = domConstr.create('td', {"class":"singledata", innerHTML:""},tr);
				td.libRecord=lrec;
				td.innerHTML=this.makeSingleName(td.libRecord);
				var td2 = domConstr.create("td", {innerHTML: ""},tr);
				if(this.addedLibs < this.startingRows){
					this.libsTable.deleteRow(-1);
				}
				var handle = on(td2, "click", lang.hitch(this,function(evt){
					console.log("Delete Row");
					domConstr.destroy(tr);
					this.decreaseLib();
					if (this.addedLibs < this.startingRows){
						var ntr = this.libsTable.insertRow(-1);
						var ntd = domConstr.create('td', {innerHTML: "

"},ntr);
						var ntd2 = domConstr.create("td", {innerHTML: "

"},ntr);
					}
					handle.remove();
				}));
				this.increaseLib();
			}
		},

		onAddPair: function(){
			console.log("Create New Row", domConstr);
//			var tr =  domConstr.create("tr",{});
//			domConstr.place(tr,this.libsTableBody,"first");
			var lrec={};
			var chkPassed=this.ingestAttachPoints(this.pairToAttachPt, lrec);
			if (chkPassed){
				var tr = this.libsTable.insertRow(0);
				var td = domConstr.create('td', {"class":"pairdata", innerHTML:""},tr);
				td.libRecord=lrec;
				td.innerHTML=this.makePairName(td.libRecord);
				var td2 = domConstr.create("td", {innerHTML: ""},tr);
				if(this.addedLibs < this.startingRows){
					this.libsTable.deleteRow(-1);
				}
				var handle = on(td2, "click", lang.hitch(this,function(evt){
					console.log("Delete Row");
					domConstr.destroy(tr);
					this.decreaseLib();
					if (this.addedLibs < this.startingRows){
	//					var ntr =  domConstr.create("tr",{});
	//					domConstr.place("ntr",this.libsTableBody,"last");
						var ntr = this.libsTable.insertRow(-1);
						var ntd = domConstr.create('td', {innerHTML: "

"},ntr);
						var ntd2 = domConstr.create("td", {innerHTML: "

"},ntr);
					}
					handle.remove();
				}));
				this.increaseLib();
			}
		}

	});
});

<|endoftext|>


<commit_before>var http = require('http');
http.globalAgent.maxSockets = 30;

function errorHandler(err, message) {
    if (err) {
        if (err.socket) {
            console.log("Host %s responded to %s request on endpoint %s with an error".red,
                err.socket._httpMessage._headers.host, err.socket._httpMessage.method, err.socket._httpMessage.path);
        }
        if (err.message) {
            console.log(err.message.red);
        }
        if (message) {
            console.log(message.red);
        }
    }
}

/**
 * Resets all stored states of this driver and allows to start over from the beginning without restarting.
 */
exports.reset = function() {
    exports.scrollId = null;
};

/**
 * Fetches general statistical in informational data from the target database.
 * @param opts
 * @param callback Callback function without a parameter. The stats result will be attached to the opts object.
 */
exports.getTargetStats = function(opts, callback) {
    var tmpOpts = {
        sourceHost: opts.targetHost,
        sourcePort: opts.targetPort,
        sourceAuth: opts.targetAuth
    };
    exports.getSourceStats(tmpOpts, function() {
        opts.targetStats = tmpOpts.sourceStats;
        callback();
    });
};

/**
 * Fetches general statistical in informational data from the source database.
 * @param opts
 * @param callback Callback function without a parameter. The stats result will be attached to the opts object.
 */
exports.getSourceStats = function(opts, callback) {
    if (opts.logEnabled) {
        console.log('Reading source statistics from ElasticSearch');
    }

    opts.sourceStats = {
        version: false,
        cluster_status: false,
        docs: false
    };
    function done() {
        for (var prop in opts.sourceStats) {
            if (!opts.sourceStats[prop]) {
                return;
            }
        }
        callback();
    }

    var serverStatusOptions = { host: opts.sourceHost, port: opts.sourcePort, path: '/', auth: opts.sourceAuth };
    http.get(serverStatusOptions, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            opts.sourceStats.version = data.version.number;
            done();
        });
    }).on('error', errorHandler);

    var clusterHealthOptions = { host: opts.sourceHost, port: opts.sourcePort, path: '/_cluster/health', auth: opts.sourceAuth };
    http.get(clusterHealthOptions, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            opts.sourceStats.cluster_status = data.status;
            done();
        });
    }).on('error', errorHandler);

    var statusOptions = { host: opts.sourceHost, port: opts.sourcePort, path: '/_status', auth: opts.sourceAuth };
    http.get(statusOptions, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            var indices = {};
            var total = 0;
            for (var index in data.indices) {
                indices[index] = data.indices[index].docs.num_docs;
                total += indices[index];
            }
            opts.sourceStats.docs = {
                indices: indices,
                total: total
            };
            done();
        });
    }).on('error', errorHandler);
};

/**
 * Returns both settings and mappings depending on which scope is set in opts.
 * The resulting object is as close to the format that is sent to ES as possible.
 * For the all scope the returned object holds the proper requests stored under the name of each index.
 * @param opts
 * @param callback Callback function that receives the meta data object as first parameter
 */
exports.getMeta = function(opts, callback) {
    if (opts.logEnabled) {
        console.log('Reading mapping from ElasticSearch');
    }
    var source = '/';
    if (opts.sourceIndex) {
        source += opts.sourceIndex + '/';
    }
    if (opts.sourceType) {
        source += opts.sourceType + '/';
    }
    var options = { host: opts.sourceHost, port: opts.sourcePort, path: source + '_mapping', auth: opts.sourceAuth };
    http.get(options, function(res) {
        var data = '';
        res.on('data', function(chunk) {
            data += chunk;
        });
        res.on('end', function() {
            data = JSON.parse(data);
            if (opts.sourceType) {
                getSettings(opts, data, callback);
            } else if (opts.sourceIndex) {
                getSettings(opts, { mappings: data[opts.sourceIndex] }, callback);
            } else {
                var metadata = {};
                for (var index in data) {
                    metadata[index] = {
                        mappings: data[index]
                    };
                }
                getSettings(opts, metadata, callback);
            }
        });
    }).on('error', errorHandler);
};

/**
 * Does the settings request after the mapping has been fetched. Settings are not fetched for a type request,
 * as the index that is created when a type does not exists is only there to ensure that data can be copied.
 * To ensure the full copy including mappings, at least an index export should be done.
 *
 * @param opts
 * @param metadata
 * @param callback Callback function that receives the meta data object as first parameter
 */
function getSettings(opts, metadata, callback) {
    var source = '/';
    if (opts.sourceIndex) {
        source += opts.sourceIndex + '/';
    }
    if (opts.sourceType) {
        callback(metadata);
        return;
    }
    // Get settings for either 'index' or 'all' scope
    var options = { host: opts.sourceHost, port: opts.sourcePort, path: source + '_settings', auth: opts.sourceAuth };
    http.get(options,function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            if (opts.sourceIndex) {
                metadata.settings = data[opts.sourceIndex].settings;
            } else {
                for (var index in data) {
                    metadata[index].settings = data[index].settings;
                }
            }
            callback(metadata);
        });
    }).on('error', errorHandler);
}

/**
 * Stores the meta data according to the scope that is set through the opts.
 *
 * @param opts
 * @param metadata
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
exports.storeMeta = function(opts, metadata, callback) {
    if (opts.sourceType) {
        storeTypeMeta(opts, metadata, callback);
    } else if (opts.sourceIndex) {
        storeIndexMeta(opts, metadata, callback);
    } else {
        storeAllMeta(opts, metadata, callback);
    }
};

/**
 * Does the actual store operation for a type metadata. When storing types, only mapping data is stored.
 * This is different then the index or all scope, as it uses the put mapping request.
 *
 * @param opts
 * @param metadata
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
function storeTypeMeta(opts, metadata, callback) {
    if (opts.logEnabled) {
        console.log('Creating type mapping in target ElasticSearch instance');
    }
    var createIndexReq = http.request({
		host : opts.targetHost,
		port : opts.targetPort,
		path : '/' + opts.targetIndex,
		method : 'PUT',
        auth: opts.targetAuth
	}, function() {
        var path;
        if (opts.targetStats.version.substring(0,4) == '0.9.') {
            path = '/' + opts.targetIndex + '/' + opts.targetType + '/_mapping';
        } else {
            path = '/' + opts.targetIndex + '/_mapping/' + opts.targetType + '/';
        }
		var typeMapReq = http.request({
			host : opts.targetHost,
			port : opts.targetPort,
			path : path,
			method : 'PUT',
            auth: opts.targetAuth
		}, function(err) {
            errorHandler(err);
            callback();
        });
		typeMapReq.on('error', errorHandler);
		typeMapReq.end(JSON.stringify(metadata));
	});
	createIndexReq.on('error', errorHandler);
	createIndexReq.end();
}

/**
 * Stores the index mappings and settings data via a create index call.
 *
 * @param opts
 * @param metadata
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
function storeIndexMeta(opts, metadata, callback) {
    if (opts.logEnabled) {
        console.log('Creating index mapping in target ElasticSearch instance');
    }
	var createIndexReq = http.request({
		host : opts.targetHost,
		port : opts.targetPort,
		path : '/' + opts.targetIndex,
		method : 'PUT',
        auth: opts.targetAuth
	}, function (err) {
        errorHandler(err);
        callback();
    });
	createIndexReq.on('error', errorHandler);
	createIndexReq.end(JSON.stringify(metadata));
}

/**
 * Stores the mappings and settings of all passed in indices via several create index calls.
 *
 * @param opts
 * @param metadata The meta data object, how it was retrieved from the #getMeta() function.
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
function storeAllMeta(opts, metadata, callback) {
    if (opts.logEnabled) {
        console.log('Creating entire mapping in target ElasticSearch instance');
    }
	var numIndices = 0;
	var indicesDone = 0;
    function done(response) {
        indicesDone++;
        if (numIndices == indicesDone) {
            callback();
        }
        response.resume();
    }
	for (var index in metadata) {
		numIndices++;
		var createIndexReq = http.request({
			host : opts.targetHost,
			port : opts.targetPort,
			path : '/' + index,
			method : 'PUT',
			auth: opts.targetAuth
		}, done);
		createIndexReq.on('error', errorHandler);
		createIndexReq.end(JSON.stringify(metadata[index]));
	}
}

/**
 * Fetches data from ElasticSearch via a scroll/scan request.
 *
 * @param opts
 * @param callback Callback which is called when data has been received with the first argument as an array of hits,
 *        and the second the number of total hits.
 * @param retries Should not be set from the calling method, as this is increase through recursion whenever a call fails
 */
exports.getData = function(opts, callback, retries) {
    if (!retries) {
        retries = 0;
    } else {
        if (retries == opts.errorsAllowed) {
            console.log('Maximum number of retries for fetching data reached. Aborting!');
            process.exit(1);
        }
        retries++;
    }

    var query = {
        fields : [
            '_source', '_timestamp', '_version', '_routing', '_percolate', '_parent', '_ttl'
        ],
        size : opts.sourceSize,
        query : opts.sourceQuery
    };
    if (opts.sourceIndex) {
        query = {
            fields : [
                '_source', '_timestamp', '_version', '_routing', '_percolate', '_parent', '_ttl'
            ],
            size : opts.sourceSize,
            query : {
                indices : {
                    indices : [
                        opts.sourceIndex
                    ],
                    query : opts.sourceQuery,
                    no_match_query : 'none'
                }
            }
        };
    }
    if (opts.sourceType) {
        query = {
            fields : [
                '_source', '_timestamp', '_version', '_routing', '_percolate', '_parent', '_ttl'
            ],
            size : opts.sourceSize,
            query : {
                indices : {
                    indices : [
                        opts.sourceIndex
                    ],
                    query : opts.sourceQuery,
                    no_match_query : 'none'
                }
            },
            filter : {
                type : {
                    value : opts.sourceType
                }
            }
        };
    }

    function handleResult(result) {
        if (result.statusCode < 200 && result.statusCode > 299) {
            setTimeout(function () {
                exports.getData(opts, callback, retries);
            }, 1000);
        }
        var data = '';
        result.on('data', function(chunk) {
            data += chunk;
        });
        result.on('end', function() {
            try {
                data = JSON.parse(data);
            } catch (e) {}
            exports.scrollId = data._scroll_id;
            callback(data.hits.hits, data.hits.total);
        });
    }

    if (exports.scrollId !== null) {
        var scrollReq = http.request({
            host : opts.sourceHost,
            port : opts.sourcePort,
            path : '/_search/scroll?scroll=5m',
            method : 'POST'
        }, handleResult);
        scrollReq.on('error', function(err) {
            errorHandler(err);
            setTimeout(function() {
                exports.getData(opts, callback, retries);
            }, 1000);
        });
        scrollReq.end(exports.scrollId);
    } else {
        var firstReq = http.request({
            host : opts.sourceHost,
            port : opts.sourcePort,
            path : '/_search?search_type=scan&scroll=5m',
            method : 'POST'
        }, handleResult);
        firstReq.on('error', function (err) {
            errorHandler(err);
            setTimeout(function () {
                exports.getData(opts, callback, retries);
            }, 1000);
        });
        firstReq.end(JSON.stringify(query));
    }
};

/**
 * Stores data using a bulk request.
 *
 * @param opts
 * @param data The data to transmit in ready to use bulk format.
 * @param callback Callback function that is called without any arguments when the data has been stored.
 * @param retries Should not be set from the calling method, as this is increase through recursion whenever a call fails
 */
exports.storeData = function(opts, data, callback, retries) {
    if (!retries) {
        retries = 0;
    } else {
        if (retries == opts.errorsAllowed) {
            console.log('Maximum number of retries for writing data reached. Aborting!');
            process.exit(1);
        }
        retries++;
    }

    var putReq = http.request({
		host : opts.targetHost,
		port : opts.targetPort,
		path : '_bulk',
		method : 'POST',
        auth: opts.targetAuth
	}, function(res) {
		//Data must be fetched, otherwise socket won't be set to free
		res.on('data', function () {});
		callback();
	});
    putReq.on('error', function (err) {
        errorHandler(err);
        setTimeout(function () {
            exports.storeData(opts, data, callback, retries);
        }, 1000);
    });
	putReq.end(data);
};
<commit_msg>Add Content-Length to POST and PUT requests<commit_after>var http = require('http');
http.globalAgent.maxSockets = 30;

function errorHandler(err, message) {
    if (err) {
        if (err.socket) {
            console.log("Host %s responded to %s request on endpoint %s with an error".red,
                err.socket._httpMessage._headers.host, err.socket._httpMessage.method, err.socket._httpMessage.path);
        }
        if (err.message) {
            console.log(err.message.red);
        }
        if (message) {
            console.log(message.red);
        }
    }
}

/**
 * Resets all stored states of this driver and allows to start over from the beginning without restarting.
 */
exports.reset = function() {
    exports.scrollId = null;
};

/**
 * Fetches general statistical in informational data from the target database.
 * @param opts
 * @param callback Callback function without a parameter. The stats result will be attached to the opts object.
 */
exports.getTargetStats = function(opts, callback) {
    var tmpOpts = {
        sourceHost: opts.targetHost,
        sourcePort: opts.targetPort,
        sourceAuth: opts.targetAuth
    };
    exports.getSourceStats(tmpOpts, function() {
        opts.targetStats = tmpOpts.sourceStats;
        callback();
    });
};

/**
 * Fetches general statistical in informational data from the source database.
 * @param opts
 * @param callback Callback function without a parameter. The stats result will be attached to the opts object.
 */
exports.getSourceStats = function(opts, callback) {
    if (opts.logEnabled) {
        console.log('Reading source statistics from ElasticSearch');
    }

    opts.sourceStats = {
        version: false,
        cluster_status: false,
        docs: false
    };
    function done() {
        for (var prop in opts.sourceStats) {
            if (!opts.sourceStats[prop]) {
                return;
            }
        }
        callback();
    }

    var serverStatusOptions = { host: opts.sourceHost, port: opts.sourcePort, path: '/', auth: opts.sourceAuth };
    http.get(serverStatusOptions, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            opts.sourceStats.version = data.version.number;
            done();
        });
    }).on('error', errorHandler);

    var clusterHealthOptions = { host: opts.sourceHost, port: opts.sourcePort, path: '/_cluster/health', auth: opts.sourceAuth };
    http.get(clusterHealthOptions, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            opts.sourceStats.cluster_status = data.status;
            done();
        });
    }).on('error', errorHandler);

    var statusOptions = { host: opts.sourceHost, port: opts.sourcePort, path: '/_status', auth: opts.sourceAuth };
    http.get(statusOptions, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            var indices = {};
            var total = 0;
            for (var index in data.indices) {
                indices[index] = data.indices[index].docs.num_docs;
                total += indices[index];
            }
            opts.sourceStats.docs = {
                indices: indices,
                total: total
            };
            done();
        });
    }).on('error', errorHandler);
};

/**
 * Returns both settings and mappings depending on which scope is set in opts.
 * The resulting object is as close to the format that is sent to ES as possible.
 * For the all scope the returned object holds the proper requests stored under the name of each index.
 * @param opts
 * @param callback Callback function that receives the meta data object as first parameter
 */
exports.getMeta = function(opts, callback) {
    if (opts.logEnabled) {
        console.log('Reading mapping from ElasticSearch');
    }
    var source = '/';
    if (opts.sourceIndex) {
        source += opts.sourceIndex + '/';
    }
    if (opts.sourceType) {
        source += opts.sourceType + '/';
    }
    var options = { host: opts.sourceHost, port: opts.sourcePort, path: source + '_mapping', auth: opts.sourceAuth };
    http.get(options, function(res) {
        var data = '';
        res.on('data', function(chunk) {
            data += chunk;
        });
        res.on('end', function() {
            data = JSON.parse(data);
            if (opts.sourceType) {
                getSettings(opts, data, callback);
            } else if (opts.sourceIndex) {
                getSettings(opts, { mappings: data[opts.sourceIndex] }, callback);
            } else {
                var metadata = {};
                for (var index in data) {
                    metadata[index] = {
                        mappings: data[index]
                    };
                }
                getSettings(opts, metadata, callback);
            }
        });
    }).on('error', errorHandler);
};

/**
 * Does the settings request after the mapping has been fetched. Settings are not fetched for a type request,
 * as the index that is created when a type does not exists is only there to ensure that data can be copied.
 * To ensure the full copy including mappings, at least an index export should be done.
 *
 * @param opts
 * @param metadata
 * @param callback Callback function that receives the meta data object as first parameter
 */
function getSettings(opts, metadata, callback) {
    var source = '/';
    if (opts.sourceIndex) {
        source += opts.sourceIndex + '/';
    }
    if (opts.sourceType) {
        callback(metadata);
        return;
    }
    // Get settings for either 'index' or 'all' scope
    var options = { host: opts.sourceHost, port: opts.sourcePort, path: source + '_settings', auth: opts.sourceAuth };
    http.get(options,function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk;
        });
        res.on('end', function () {
            data = JSON.parse(data);
            if (opts.sourceIndex) {
                metadata.settings = data[opts.sourceIndex].settings;
            } else {
                for (var index in data) {
                    metadata[index].settings = data[index].settings;
                }
            }
            callback(metadata);
        });
    }).on('error', errorHandler);
}

/**
 * Stores the meta data according to the scope that is set through the opts.
 *
 * @param opts
 * @param metadata
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
exports.storeMeta = function(opts, metadata, callback) {
    if (opts.sourceType) {
        storeTypeMeta(opts, metadata, callback);
    } else if (opts.sourceIndex) {
        storeIndexMeta(opts, metadata, callback);
    } else {
        storeAllMeta(opts, metadata, callback);
    }
};

/**
 * Does the actual store operation for a type metadata. When storing types, only mapping data is stored.
 * This is different then the index or all scope, as it uses the put mapping request.
 *
 * @param opts
 * @param metadata
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
function storeTypeMeta(opts, metadata, callback) {
    if (opts.logEnabled) {
        console.log('Creating type mapping in target ElasticSearch instance');
    }

    var createIndexReq = http.request({
        host : opts.targetHost,
        port : opts.targetPort,
        path : '/' + opts.targetIndex,
        method : 'PUT',
        auth: opts.targetAuth,
        headers: {
            "Content-Length": 0
        }
    }, function() {
        var path,
            buffer = new Buffer(JSON.stringify(metadata), 'utf8');

        if (opts.targetStats.version.substring(0,4) == '0.9.') {
            path = '/' + opts.targetIndex + '/' + opts.targetType + '/_mapping';
        } else {
            path = '/' + opts.targetIndex + '/_mapping/' + opts.targetType + '/';
        }
        var typeMapReq = http.request({
            host : opts.targetHost,
            port : opts.targetPort,
            path : path,
            method : 'PUT',
            auth: opts.targetAuth,
            headers: {
                "Content-Length": buffer.length
            }
        }, function(err) {
            errorHandler(err);
            callback();
        });
        typeMapReq.on('error', errorHandler);
        typeMapReq.end(buffer);
    });
    createIndexReq.on('error', errorHandler);
    createIndexReq.end();
}

/**
 * Stores the index mappings and settings data via a create index call.
 *
 * @param opts
 * @param metadata
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
function storeIndexMeta(opts, metadata, callback) {
    if (opts.logEnabled) {
        console.log('Creating index mapping in target ElasticSearch instance');
    }

    var buffer = new Buffer(JSON.stringify(metadata), 'utf8');

    var createIndexReq = http.request({
        host : opts.targetHost,
        port : opts.targetPort,
        path : '/' + opts.targetIndex,
        method : 'PUT',
        auth: opts.targetAuth,
        headers: {
            "Content-Length": buffer.length
        }
    }, function (err) {
        errorHandler(err);
        callback();
    });
    createIndexReq.on('error', errorHandler);
    createIndexReq.end(buffer);
}

/**
 * Stores the mappings and settings of all passed in indices via several create index calls.
 *
 * @param opts
 * @param metadata The meta data object, how it was retrieved from the #getMeta() function.
 * @param callback Callback method that will called once the meta data has been stored. No significant data is passed via arguments.
 */
function storeAllMeta(opts, metadata, callback) {
    if (opts.logEnabled) {
        console.log('Creating entire mapping in target ElasticSearch instance');
    }
    var numIndices = 0;
    var indicesDone = 0;

    function done(response) {
        indicesDone++;
        if (numIndices == indicesDone) {
            callback();
        }
        response.resume();
    }
    for (var index in metadata) {
        numIndices++;
        var buffer = new Buffer(JSON.stringify(metadata[index]), 'utf8')

        var createIndexReq = http.request({
            host : opts.targetHost,
            port : opts.targetPort,
            path : '/' + index,
            method : 'PUT',
            auth: opts.targetAuth,
            headers: {
                "Content-Length": buffer.length
            }
        }, done);
        createIndexReq.on('error', errorHandler);
        createIndexReq.end(buffer);
    }
}

/**
 * Fetches data from ElasticSearch via a scroll/scan request.
 *
 * @param opts
 * @param callback Callback which is called when data has been received with the first argument as an array of hits,
 *        and the second the number of total hits.
 * @param retries Should not be set from the calling method, as this is increase through recursion whenever a call fails
 */
exports.getData = function(opts, callback, retries) {
    if (!retries) {
        retries = 0;
    } else {
        if (retries == opts.errorsAllowed) {
            console.log('Maximum number of retries for fetching data reached. Aborting!');
            process.exit(1);
        }
        retries++;
    }

    var query = {
        fields : [
            '_source', '_timestamp', '_version', '_routing', '_percolate', '_parent', '_ttl'
        ],
        size : opts.sourceSize,
        query : opts.sourceQuery
    };
    if (opts.sourceIndex) {
        query = {
            fields : [
                '_source', '_timestamp', '_version', '_routing', '_percolate', '_parent', '_ttl'
            ],
            size : opts.sourceSize,
            query : {
                indices : {
                    indices : [
                        opts.sourceIndex
                    ],
                    query : opts.sourceQuery,
                    no_match_query : 'none'
                }
            }
        };
    }
    if (opts.sourceType) {
        query = {
            fields : [
                '_source', '_timestamp', '_version', '_routing', '_percolate', '_parent', '_ttl'
            ],
            size : opts.sourceSize,
            query : {
                indices : {
                    indices : [
                        opts.sourceIndex
                    ],
                    query : opts.sourceQuery,
                    no_match_query : 'none'
                }
            },
            filter : {
                type : {
                    value : opts.sourceType
                }
            }
        };
    }

    function handleResult(result) {
        if (result.statusCode < 200 && result.statusCode > 299) {
            setTimeout(function () {
                exports.getData(opts, callback, retries);
            }, 1000);
        }
        var data = '';
        result.on('data', function(chunk) {
            data += chunk;
        });
        result.on('end', function() {
            try {
                data = JSON.parse(data);
            } catch (e) {}
            exports.scrollId = data._scroll_id;
            callback(data.hits.hits, data.hits.total);
        });
    }

    if (exports.scrollId !== null) {
        var buffer = new Buffer(exports.scrollId, 'utf8');
        var scrollReq = http.request({
            host : opts.sourceHost,
            port : opts.sourcePort,
            path : '/_search/scroll?scroll=5m',
            method : 'POST',
            headers: {
                "Content-Length": buffer.length
            }
        }, handleResult);
        scrollReq.on('error', function(err) {
            errorHandler(err);
            setTimeout(function() {
                exports.getData(opts, callback, retries);
            }, 1000);
        });
        scrollReq.end(buffer);
    } else {
        var buffer = new Buffer(JSON.stringify(query), 'utf8');
        var firstReq = http.request({
            host : opts.sourceHost,
            port : opts.sourcePort,
            path : '/_search?search_type=scan&scroll=5m',
            method : 'POST',
            headers: {
                "Content-Length": buffer.length
            }
        }, handleResult);
        firstReq.on('error', function (err) {
            errorHandler(err);
            setTimeout(function () {
                exports.getData(opts, callback, retries);
            }, 1000);
        });
        firstReq.end(buffer);
    }
};

/**
 * Stores data using a bulk request.
 *
 * @param opts
 * @param data The data to transmit in ready to use bulk format.
 * @param callback Callback function that is called without any arguments when the data has been stored.
 * @param retries Should not be set from the calling method, as this is increase through recursion whenever a call fails
 */
exports.storeData = function(opts, data, callback, retries) {
    if (!retries) {
        retries = 0;
    } else {
        if (retries == opts.errorsAllowed) {
            console.log('Maximum number of retries for writing data reached. Aborting!');
            process.exit(1);
        }
        retries++;
    }

    var buffer = new Buffer(data, 'utf8');

    var putReq = http.request({
        host : opts.targetHost,
        port : opts.targetPort,
        path : '/_bulk',
        method : 'POST',
        auth: opts.targetAuth,
        headers: {
            "Content-Length": buffer.length
        }
    }, function(res) {
        //Data must be fetched, otherwise socket won't be set to free
        res.on('data', function () {});
        res.on('end', callback);
    });
    putReq.on('error', function (err) {
        errorHandler(err);
        setTimeout(function () {
            exports.storeData(opts, data, callback, retries);
        }, 1000);
    });
    putReq.end(buffer);
};
<|endoftext|>


<commit_before>define([
    "use!backbone",
    "use!handlebars",
    "preference/Preference",
    "text!preference/preference.handlebars",
    "hotkey/HotKeyConfigView"
], function(Backbone, Handlebars, Preference, preferenceTemplate, HotKeyConfigView) {
    var PreferenceView = Backbone.View.extend(
    /** @lends PreferenceView.prototype */
    {
        /**
         * @class PreferenceView
         *
         * @extends Backbone.View
         * @constructs
         */
        initialize : function() {
        },

        model : Preference,
     //make model name: JS/CSS class name
     //   hotkeyview: HotKeyConfigView,

//        classname : "preference",

        //el : $(".preference"),

        template: Handlebars.compile(preferenceTemplate),

        events:{
          "click .skin": "randomSkin"

        },

        render : function() {

        	//Handlebars.registerPartial("hot_key_config", this.hotkeyview.template(this.hotkeyview.model.toJSON()) );

            $(this.el).html(this.template(this.model.toJSON()));
            $(this.el).appendTo("#preference");
            return this;
        },

        randomSkin : function(){
          console.log("Change me!!");
          return true;
        }

    });

    return PreferenceView;
}); <commit_msg>Fixed up PreferenceView to match the other working views.<commit_after>define([
    "use!backbone",
    "use!handlebars",
    "preference/Preference",
    "text!preference/preference.handlebars",
    "hotkey/HotKeyConfigView",
    "libs/Utils"
], function(
  Backbone,
  Handlebars,
  Preference,
  preferenceTemplate,
  HotKeyConfigView
) {
  var PreferenceView = Backbone.View.extend(
  /** @lends PreferenceView.prototype */
  {
    // TODO comment this class
    /**
     * @class PreferenceView
     *
     * @extends Backbone.View
     * @constructs
     */
    initialize : function() {
    },

    /**
     * The underlying model of the PreferenceView is a Preference.
     */
    model : Preference,

    /**
     * Events that the PreferenceView is listening to and their handlers.
     */
    events:{
      "click .skin": "randomSkin"
    },

    /**
     * The Handlebars template rendered as the PreferenceView.
     */
    template: Handlebars.compile(preferenceTemplate),

    render : function() {
      Utils.debug("PREFERENCE render: " + this.el);
      if (this.model != undefined) {
        // Display the PreferenceView
        this.setElement($("#preference"));
        $(this.el).html(this.template(this.model.toJSON()));
      }

      return this;
    },

    // TODO Comment and implement this function
    randomSkin : function(){
      console.log("Change me!!");
      return true;
    }
  });

  return PreferenceView;
}); <|endoftext|>