<commit_before>/*
 * Builds up the interface for tirade, needs jquery and more than one jquery plugin
 */

// Auto preview
jQuery.fn.preview = function() {
  var url = $(this).attr('action') + '/preview';
  var form = $(this);
  var fetchPreview = function(data) {
    $.ajax({
      url: url,
      type: 'POST',
      data: data || form.formSerialize()
    });
  };
  Toolbox.scroller().one('prev', function() {
    fetchPreview(form.find('input[@name=authenticity_token],input[@name=_method],input[@name=context_page_id]').serialize()); /* reset old state */
  });

  form.formWatch({callback: fetchPreview});
}

// Apply roles classes from cookie (for body etc.)
jQuery.fn.applyRoles = function() {
  var e = $(this);
  if ($.cookie("roles")) {
    $(e[0].className.split(/ /)).each(function(i,cls) {
      if (cls.match(/role_\S*/))
        e.removeClass(cls)
    });
    $($.cookie("roles").split(/&/)).each(function(i,role) {
      e.addClass('role_' + role);
    });
    e.addClass('cookie_roles');
  }
  return(e);
}

jQuery.fn.surrounds = function(position) {
  me = $(this);
  meoff = me.offset();
  return(
      meoff.top < position.top && meoff.left < position.left &&
      meoff.top + me.height() > position.top &&
      meoff.left + me.width() > position.left
  );
}

jQuery.fn.beBusy = function(message) {
  var e = $(this);
  e.appendDom([
    { tagName: 'div', class: 'busy', childNodes: [
      { tagName: 'span', class: 'message', innerHTML: 'Loading' },
      { tagName: 'img', class: 'status', src: '/images/toolbox/pentagon.gif' }
    ] },
  ]);

  minih = (e.height() > e.width() ? e.width() : e.height()) * 0.7;
  if (e.height() > e.width()) { /* "Bert" */
    $('img.status', e)
      .animate({
        top: (e.height() - minih) * 0.6,
        left: (e.width() - minih) * 0.5,
        height: minih,
        opacity: 1
      },800);
  } else { /* "Ernie" */
    $('img.status', e)
      .animate({
        top: (e.height() - minih) * 0.5,
        left: e.width() - (minih * 1.1),
        height: minih,
        opacity: 1
      },800);
  }

  if (message)
    $('span.message', e).text(message);

    return e.fadeIn(230);
}
jQuery.fn.unBusy = function() {
  return $('div.busy', this).fadeOut(230).remove();
}

ChiliBook.recipeFolder = 'javascripts/syntax/'

$.ajaxSetup({
  dataType: 'script'
});

function pageContextForRequest() {
  return "&context_page_id=" + $('body > div.page').resourceId()
}

$(function() {
  $('div.admin > a').livequery(function() { $(this).useToolbox(); });
  $('a.login').livequery(function() { $(this).useToolbox(); });
  $('a.with_toolbox').livequery(function() { $(this).useToolbox(); });
  $('a.dashboard').livequery('click', function(event) {
    event.preventDefault();
    Toolbox.findOrCreate();
    Toolbox.last().refresh();
  });

  $('code.html').livequery(function() { $(this).chili() });
  $('code.liquid').livequery(function() { $(this).chili() });

  $('div#toolbox > div.body > div.content > div.frame a.show').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.index').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.new').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.edit').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.sidebar a.show').livequery(function() { $(this).useToolbox(); });
  $('body.role_admin div.page div.rendering').livequery(function(i) {
    $(this)
      .appendDom([
        { tagName: 'div', class: 'admin', id: 'admin_' + $(this).attr('id'), childNodes: [
          { tagName: 'a', href: rendering_url({id: $(this).resourceId()}), class: 'edit rendering', innerHTML: 'edit' },
          { tagName: 'span', class: 'handle', innerHTML: 'drag' }
          ] }
      ]);
  });
  $('body.role_admin.disabled div.page div.grid div.rendering.fake').livequery(function(i) {
    $(this)
      .droppable({
        accept: 'li,dd',
        hoverClass: 'hover',
        activeClass: 'active-droppable',
        tolerance: 'pointer',
        drop: function(e,ui) {
          var droppee = ui.draggable.typeAndId();
          ui.element.beBusy("applying " + droppee.type);
          data = 'rendering[grid_id]=' + ui.element.parent().resourceId();
          data += '&rendering[page_id]=' + ui.element.parents('div.page').resourceId();
          switch(droppee.type) {
            case 'Part':
              data += '&rendering[part_id]=' + droppee.id;
              break;
            default:
              data += '&rendering[content_id]=' + droppee.id;
              data += '&rendering[content_type]=' + droppee.type;
          }
          data += pageContextForRequest();
          $.ajax({
            url: renderings_url(),
            data: data, type: 'POST'
          });
        }
      });
  });
  $('div#toolbox ul.list.records > li,div#toolbox dl di dd.record').livequery(function() {
    $(this).draggable({
      helper: 'clone',
      zIndex: 500,
      appendTo: 'body',
      scroll: true,
      cursor: 'crosshair',
      cursorAt: {top: -1, left: -1},
      drag: function(e,ui) {
        if (Toolbox.surrounds(ui.absolutePosition)) {
          Toolbox.beExclusiveDroppable();
          Toolbox.unGhost();
        } else {
          Toolbox.unExclusiveDroppable();
          Toolbox.beGhost();
        };
      },
      stop: function(e,ui) {
        Toolbox.unExclusiveDroppable();
        Toolbox.unGhost();
      }
    });
  });
  $('div#toolbox div.sidebar ul.clipboard').livequery(function() {
    var list = $(this);
    list.droppable({
      accept: function(draggable) {
        return(
          draggable.is('li, dd.record') &&
          draggable.parent()[0] != list[0]
        );
      },
      hoverClass: 'hover',
      activeClass: 'active-droppable',
      greedy: true,
      tolerance: 'touch',
      drop: function(e,ui) {
        $.ajax({
          url: clipboard_url(),
          data: {id: $(ui.draggable).resourceIdentifier()},
          type: 'POST'
        });
      }
    });
  });
  $('div#toolbox div.sidebar ul.clipboard li').livequery(function() {
    var item = $(this);
    item.find('img.association').remove();
    item.appendDom([ { tagName: 'img', src: '/images/icons/small/x.gif', class: 'association remove' } ]);
    item.find('img.remove').click(function(event) {
      item.remove();
      $.ajax({
        url: clipboard_url(),
        data: {id: item.resourceIdentifier()},
        type: 'DELETE'
      });
    });
  });
  $('form.edit_part, form.edit_rendering').livequery(function() {
    $(this).preview();
  });
  $('form.edit.content').livequery(function() {
    $(this).preview();
  });
  $('body').applyRoles();

  /* TODO: move to acts_as_custom_configurable */
  $('form ul.define_options').livequery(function() {
    var list = $(this);
    $('').prependTo(list);
    list.find('img.add').click(function() {
      list.find('li:last').clone().removeClass('dummy').appendTo(list);
      return false;
    });
  });
  $('form ul.define_options li:not(.dummy)').livequery(function() {
    var item = $(this);
    $('').prependTo(item);
    item.find('img.remove').click(function() {
      item.remove();
      return false;
    });
  });

  // Grid leafs
  $('div.grid:not(:has(> div.grid))').livequery(function() {
    $(this).sortable({
      connectWith: ['div.grid:not(:has(> div.grid))'],
      //containment: 'div.page',
      appendTo: 'div.page',
      distance: 5,
      dropOnEmpty: true,
      placeholder: 'placeholder',
      forcePlaceHolderSize: true,
      items: '> div.rendering',
      handle: 'span.handle',
      tolerance: 'pointer',
      scroll: true,
      cursor: 'move',
      zIndex: 1,
      change: function(e,ui) {
        ui.item.width(ui.element.width());
      },
      stop: function(e,ui) {
        $('div.rendering').width('');
        grid = ui.item.parent();
        $.ajax({
          data: grid.sortable("serialize"),
          url: order_renderings_grid_url({id: grid.resourceId()}),
          type: 'POST'
        });
      }
    })
    .droppable({
      accept: 'li',
      activeClass: 'active-droppable',
      hoverClass: 'drop-invite',
      greedy: true,
      tolerance: 'pointer',
      drop: function(e,ui) {
        var droppee = ui.draggable.typeAndId();
        context = "rendering[grid_id]=" + ui.element.resourceId();
        context += "&rendering[page_id]=" + $('body > div.page').resourceId();
        switch(droppee.type) {
          case 'Rendering': /* drop renderings (hints) from toolbox, updates its #grid */
            $.ajax({
              url: rendering_url({id: droppee.id}),
              data: context,
              type: 'PUT'
            });
            break;
          case 'Part': /* Part from Toolbox creates Rendering without a Content */
            $.ajax({
              url: renderings_url(),
              data: context + '&rendering[part_id]=' + droppee.id,
              type: 'POST'
            });
            break;
          default: /* dropping anything else will create a Rendering with this assigned as content */
            $.ajax({
              url: renderings_url(),
              data: context +
                    '&rendering[content_id]=' + droppee.id +
                    '&rendering[content_type]=' + droppee.type,
              type: 'POST'
            });
        }
      }
    });
  });

  $('div.rendering.without_part').livequery(function() {
    $(this).droppable({
      accept: 'li.part',
      activeClass: 'active-droppable',
      hoverClass: 'drop-invite',
      greedy: true,
      tolerance: 'pointer',
      drop: function(e,ui) {
        var droppee = ui.draggable.typeAndId();
        $.ajax({
          url: rendering_url({id: ui.element.resourceId()}),
          data: 'rendering[part_id]=' + droppee.id,
          type: 'PUT'
        });
      }
    });
  });
  $('div.rendering.without_content').livequery(function() {
    $(this).droppable({
      accept: 'li:not(.part)',
      activeClass: 'active-droppable',
      hoverClass: 'drop-invite',
      greedy: true,
      tolerance: 'pointer',
      drop: function(e,ui) {
        var droppee = ui.draggable.typeAndId();
        $.ajax({
          url: rendering_url({id: ui.element.resourceId()}),
          data: 'rendering[content_id]=' + droppee.id +
                '&rendering[content_type]=' + droppee.type,
          type: 'PUT'
        });
      }
    });
  });

  /* empty grid */
  $('body.role_admin div.page div.grid:not(:has(> div.grid, > div.rendering))').livequery(function() {
    $(this).addClass('empty').html('
Empty Grid. Please drop here a Rendering, Part or any Content.
');
  });

  /* lets sort all vertical aligned Grids, if there is more than one child */
  $('div.page div.grid:not(.horizontal):has(> div.grid + div.grid)').livequery(function() {
    $(this).find('> div.grid').append('

').end()
    .sortable("destroy").sortable({
      handle: 'span.handle',
      axis: 'y',
      distance: 10,
      placeholder: 'placeholder',
      forcePlaceHolderSize: true,
      items: '> div.grid',
      tolerance: 'pointer',
      cursor: 'move',
      stop: function(e,ui) {
        grid = ui.item.parent();
        $.ajax({
          data: grid.sortable("serialize") + pageContextForRequest(),
          url: order_children_grid_url({id: grid.resourceId()}),
          type: 'POST'
        });
      }
    })
  });
  // mark hovered divs as hovered. we can get them later by $('div.hovered').last() for positioniing the toolbox
  $('div.rendering > div.admin, div.grid > div.admin').livequery(function() {
    $(this).hover(
      function() {
        $(this).parents('div.grid, div.rendering').addClass('hover')
      },
      function() {
        $('div.page .hover').removeClass('hover');
      }
    );
  });

  /* click grid mockups to browse */
  $('dd > div.grid.preview').livequery(function() {
    $(this)
    .click(function(e) {
      if ( id = $(e.target).resourceId() ) {
        Toolbox.beBusy("Loading Grid");
        $.get(grid_url({id: id}));
      } else if ( id = $(e.target).parent().resourceId() ) {
        Toolbox.beBusy("Loading Grid");
        $.get(grid_url({id: id}));
      }
    })
  });
  $('dd div.grid.preview').livequery(function() {
    $(this).hover(
      function() {
        if ( id = $(this).resourceId() ) {
          $('div.page div.grid.grid_' + id).addClass('hover');
        }
      },
      function() {
        $('div.page div.grid').removeClass('hover');
      }
    );
  });

});
<commit_msg>ajaxify destroy links, too<commit_after>/*
 * Builds up the interface for tirade, needs jquery and more than one jquery plugin
 */

// Auto preview
jQuery.fn.preview = function() {
  var url = $(this).attr('action') + '/preview';
  var form = $(this);
  var fetchPreview = function(data) {
    $.ajax({
      url: url,
      type: 'POST',
      data: data || form.formSerialize()
    });
  };
  Toolbox.scroller().one('prev', function() {
    fetchPreview(form.find('input[@name=authenticity_token],input[@name=_method],input[@name=context_page_id]').serialize()); /* reset old state */
  });

  form.formWatch({callback: fetchPreview});
}

// Apply roles classes from cookie (for body etc.)
jQuery.fn.applyRoles = function() {
  var e = $(this);
  if ($.cookie("roles")) {
    $(e[0].className.split(/ /)).each(function(i,cls) {
      if (cls.match(/role_\S*/))
        e.removeClass(cls)
    });
    $($.cookie("roles").split(/&/)).each(function(i,role) {
      e.addClass('role_' + role);
    });
    e.addClass('cookie_roles');
  }
  return(e);
}

jQuery.fn.surrounds = function(position) {
  me = $(this);
  meoff = me.offset();
  return(
      meoff.top < position.top && meoff.left < position.left &&
      meoff.top + me.height() > position.top &&
      meoff.left + me.width() > position.left
  );
}

jQuery.fn.beBusy = function(message) {
  var e = $(this);
  e.appendDom([
    { tagName: 'div', class: 'busy', childNodes: [
      { tagName: 'span', class: 'message', innerHTML: 'Loading' },
      { tagName: 'img', class: 'status', src: '/images/toolbox/pentagon.gif' }
    ] },
  ]);

  minih = (e.height() > e.width() ? e.width() : e.height()) * 0.7;
  if (e.height() > e.width()) { /* "Bert" */
    $('img.status', e)
      .animate({
        top: (e.height() - minih) * 0.6,
        left: (e.width() - minih) * 0.5,
        height: minih,
        opacity: 1
      },800);
  } else { /* "Ernie" */
    $('img.status', e)
      .animate({
        top: (e.height() - minih) * 0.5,
        left: e.width() - (minih * 1.1),
        height: minih,
        opacity: 1
      },800);
  }

  if (message)
    $('span.message', e).text(message);

    return e.fadeIn(230);
}
jQuery.fn.unBusy = function() {
  return $('div.busy', this).fadeOut(230).remove();
}

ChiliBook.recipeFolder = 'javascripts/syntax/'

$.ajaxSetup({
  dataType: 'script'
});

function pageContextForRequest() {
  return "&context_page_id=" + $('body > div.page').resourceId()
}

$(function() {
  $('div.admin > a').livequery(function() { $(this).useToolbox(); });
  $('a.login').livequery(function() { $(this).useToolbox(); });
  $('a.with_toolbox').livequery(function() { $(this).useToolbox(); });
  $('a.dashboard').livequery('click', function(event) {
    event.preventDefault();
    Toolbox.findOrCreate();
    Toolbox.last().refresh();
  });

  $('code.html').livequery(function() { $(this).chili() });
  $('code.liquid').livequery(function() { $(this).chili() });

  /* Resourceful Links in Toolbox */
  $('div#toolbox > div.body > div.content > div.frame a.show').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.index').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.new').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.edit').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.body > div.content > div.frame a.destroy').livequery(function() { $(this).useToolbox(); });
  $('div#toolbox > div.sidebar a.show').livequery(function() { $(this).useToolbox(); });
  $('body.role_admin div.page div.rendering').livequery(function(i) {
    $(this)
      .appendDom([
        { tagName: 'div', class: 'admin', id: 'admin_' + $(this).attr('id'), childNodes: [
          { tagName: 'a', href: rendering_url({id: $(this).resourceId()}), class: 'edit rendering', innerHTML: 'edit' },
          { tagName: 'span', class: 'handle', innerHTML: 'drag' }
          ] }
      ]);
  });
  $('body.role_admin.disabled div.page div.grid div.rendering.fake').livequery(function(i) {
    $(this)
      .droppable({
        accept: 'li,dd',
        hoverClass: 'hover',
        activeClass: 'active-droppable',
        tolerance: 'pointer',
        drop: function(e,ui) {
          var droppee = ui.draggable.typeAndId();
          ui.element.beBusy("applying " + droppee.type);
          data = 'rendering[grid_id]=' + ui.element.parent().resourceId();
          data += '&rendering[page_id]=' + ui.element.parents('div.page').resourceId();
          switch(droppee.type) {
            case 'Part':
              data += '&rendering[part_id]=' + droppee.id;
              break;
            default:
              data += '&rendering[content_id]=' + droppee.id;
              data += '&rendering[content_type]=' + droppee.type;
          }
          data += pageContextForRequest();
          $.ajax({
            url: renderings_url(),
            data: data, type: 'POST'
          });
        }
      });
  });
  $('div#toolbox ul.list.records > li,div#toolbox dl di dd.record').livequery(function() {
    $(this).draggable({
      helper: 'clone',
      zIndex: 500,
      appendTo: 'body',
      scroll: true,
      cursor: 'crosshair',
      cursorAt: {top: -1, left: -1},
      drag: function(e,ui) {
        if (Toolbox.surrounds(ui.absolutePosition)) {
          Toolbox.beExclusiveDroppable();
          Toolbox.unGhost();
        } else {
          Toolbox.unExclusiveDroppable();
          Toolbox.beGhost();
        };
      },
      stop: function(e,ui) {
        Toolbox.unExclusiveDroppable();
        Toolbox.unGhost();
      }
    });
  });
  $('div#toolbox div.sidebar ul.clipboard').livequery(function() {
    var list = $(this);
    list.droppable({
      accept: function(draggable) {
        return(
          draggable.is('li, dd.record') &&
          draggable.parent()[0] != list[0]
        );
      },
      hoverClass: 'hover',
      activeClass: 'active-droppable',
      greedy: true,
      tolerance: 'touch',
      drop: function(e,ui) {
        $.ajax({
          url: clipboard_url(),
          data: {id: $(ui.draggable).resourceIdentifier()},
          type: 'POST'
        });
      }
    });
  });
  $('div#toolbox div.sidebar ul.clipboard li').livequery(function() {
    var item = $(this);
    item.find('img.association').remove();
    item.appendDom([ { tagName: 'img', src: '/images/icons/small/x.gif', class: 'association remove' } ]);
    item.find('img.remove').click(function(event) {
      item.remove();
      $.ajax({
        url: clipboard_url(),
        data: {id: item.resourceIdentifier()},
        type: 'DELETE'
      });
    });
  });
  $('form.edit_part, form.edit_rendering').livequery(function() {
    $(this).preview();
  });
  $('form.edit.content').livequery(function() {
    $(this).preview();
  });
  $('body').applyRoles();

  /* TODO: move to acts_as_custom_configurable */
  $('form ul.define_options').livequery(function() {
    var list = $(this);
    $('').prependTo(list);
    list.find('img.add').click(function() {
      list.find('li:last').clone().removeClass('dummy').appendTo(list);
      return false;
    });
  });
  $('form ul.define_options li:not(.dummy)').livequery(function() {
    var item = $(this);
    $('').prependTo(item);
    item.find('img.remove').click(function() {
      item.remove();
      return false;
    });
  });

  // Grid leafs
  $('div.grid:not(:has(> div.grid))').livequery(function() {
    $(this).sortable({
      connectWith: ['div.grid:not(:has(> div.grid))'],
      //containment: 'div.page',
      appendTo: 'div.page',
      distance: 5,
      dropOnEmpty: true,
      placeholder: 'placeholder',
      forcePlaceHolderSize: true,
      items: '> div.rendering',
      handle: 'span.handle',
      tolerance: 'pointer',
      scroll: true,
      cursor: 'move',
      zIndex: 1,
      change: function(e,ui) {
        ui.item.width(ui.element.width());
      },
      stop: function(e,ui) {
        $('div.rendering').width('');
        grid = ui.item.parent();
        $.ajax({
          data: grid.sortable("serialize"),
          url: order_renderings_grid_url({id: grid.resourceId()}),
          type: 'POST'
        });
      }
    })
    .droppable({
      accept: 'li',
      activeClass: 'active-droppable',
      hoverClass: 'drop-invite',
      greedy: true,
      tolerance: 'pointer',
      drop: function(e,ui) {
        var droppee = ui.draggable.typeAndId();
        context = "rendering[grid_id]=" + ui.element.resourceId();
        context += "&rendering[page_id]=" + $('body > div.page').resourceId();
        switch(droppee.type) {
          case 'Rendering': /* drop renderings (hints) from toolbox, updates its #grid */
            $.ajax({
              url: rendering_url({id: droppee.id}),
              data: context,
              type: 'PUT'
            });
            break;
          case 'Part': /* Part from Toolbox creates Rendering without a Content */
            $.ajax({
              url: renderings_url(),
              data: context + '&rendering[part_id]=' + droppee.id,
              type: 'POST'
            });
            break;
          default: /* dropping anything else will create a Rendering with this assigned as content */
            $.ajax({
              url: renderings_url(),
              data: context +
                    '&rendering[content_id]=' + droppee.id +
                    '&rendering[content_type]=' + droppee.type,
              type: 'POST'
            });
        }
      }
    });
  });

  $('div.rendering.without_part').livequery(function() {
    $(this).droppable({
      accept: 'li.part',
      activeClass: 'active-droppable',
      hoverClass: 'drop-invite',
      greedy: true,
      tolerance: 'pointer',
      drop: function(e,ui) {
        var droppee = ui.draggable.typeAndId();
        $.ajax({
          url: rendering_url({id: ui.element.resourceId()}),
          data: 'rendering[part_id]=' + droppee.id,
          type: 'PUT'
        });
      }
    });
  });
  $('div.rendering.without_content').livequery(function() {
    $(this).droppable({
      accept: 'li:not(.part)',
      activeClass: 'active-droppable',
      hoverClass: 'drop-invite',
      greedy: true,
      tolerance: 'pointer',
      drop: function(e,ui) {
        var droppee = ui.draggable.typeAndId();
        $.ajax({
          url: rendering_url({id: ui.element.resourceId()}),
          data: 'rendering[content_id]=' + droppee.id +
                '&rendering[content_type]=' + droppee.type,
          type: 'PUT'
        });
      }
    });
  });

  /* empty grid */
  $('body.role_admin div.page div.grid:not(:has(> div.grid, > div.rendering))').livequery(function() {
    $(this).addClass('empty').html('
Empty Grid. Please drop here a Rendering, Part or any Content.
');
  });

  /* lets sort all vertical aligned Grids, if there is more than one child */
  $('div.page div.grid:not(.horizontal):has(> div.grid + div.grid)').livequery(function() {
    $(this).find('> div.grid').append('

').end()
    .sortable("destroy").sortable({
      handle: 'span.handle',
      axis: 'y',
      distance: 10,
      placeholder: 'placeholder',
      forcePlaceHolderSize: true,
      items: '> div.grid',
      tolerance: 'pointer',
      cursor: 'move',
      stop: function(e,ui) {
        grid = ui.item.parent();
        $.ajax({
          data: grid.sortable("serialize") + pageContextForRequest(),
          url: order_children_grid_url({id: grid.resourceId()}),
          type: 'POST'
        });
      }
    })
  });
  // mark hovered divs as hovered. we can get them later by $('div.hovered').last() for positioniing the toolbox
  $('div.rendering > div.admin, div.grid > div.admin').livequery(function() {
    $(this).hover(
      function() {
        $(this).parents('div.grid, div.rendering').addClass('hover')
      },
      function() {
        $('div.page .hover').removeClass('hover');
      }
    );
  });

  /* click grid mockups to browse */
  $('dd > div.grid.preview').livequery(function() {
    $(this)
    .click(function(e) {
      if ( id = $(e.target).resourceId() ) {
        Toolbox.beBusy("Loading Grid");
        $.get(grid_url({id: id}));
      } else if ( id = $(e.target).parent().resourceId() ) {
        Toolbox.beBusy("Loading Grid");
        $.get(grid_url({id: id}));
      }
    })
  });
  $('dd div.grid.preview').livequery(function() {
    $(this).hover(
      function() {
        if ( id = $(this).resourceId() ) {
          $('div.page div.grid.grid_' + id).addClass('hover');
        }
      },
      function() {
        $('div.page div.grid').removeClass('hover');
      }
    );
  });

});
<|endoftext|>


<commit_before>/*global db, sleep, print, ObjectId, printjson, mapReduce, run, shouldRun, runAction, clearOut */
/*jslint nomen: true, sloppy: true */

// TODO: clean up
// TODO: document
// TODO: move settings to db (providing sane default settings)
// TODO: perhaps provide string interpolation so debugging statements don't look as ugly
// TODO: perhaps provide convenience debug(), info(), warning(), error() functions?
// TODO: error handling
// TODO: make polling loop a function, and the body an argument
// TODO: provide convenience functions for doing a check, autostarting, starting in a parallel shell

var pid     = new ObjectId(),   // the "pid" of this runner
    running = true,             // when false, we exit
    interval = 1000,            // how many ms we should sleep in between runs
    counter = 0,                // how many mapReduce actions were executed this run
    totalcount = 0;             // how many mapReduce actions were executed by this instance

var loglevels = {
    DEBUG: 0,       // things that are really quite redundant to see all the time,
                    // but are useful when debugging
    INFO: 1,        // quite useful when you're wondering what's going on
    WARNING: 2,     // generally used for recoverable things or when exiting
    ERROR: 3        // when we're broken and need fixing
};

var loglevel = {
    db: loglevels.DEBUG,
    console: loglevels.INFO
};

db.mapreduce.run.save(
    {"_id": "unique", "pid": pid}
);

log(loglevels.INFO, "Starting");

var runningPid = {},
    start = 0,
    end = 0;

while (running) {
    runningPid = db.mapreduce.run.findOne({"_id": "unique"});

    if (runningPid === null || !runningPid.hasOwnProperty("pid")) {
        running = false;
        log(loglevels.WARNING, "Exiting, canceled");
    } else if (pid.toString() !== runningPid.pid.toString()) {
        running = false;
        log(loglevels.WARNING, "Exiting, new instance started");
    } else {
        db.mapreduce.run.update({"_id": "unique"}, {"$set": {"status": "running"}});

        doMapReduce();

        log(loglevels.DEBUG, "Going to sleep for " + interval + "ms");
        sleep(interval);
    }
}

function doMapReduce() {
    start = new Date().getTime();
    executeMapReduceActions();
    end = new Date().getTime();

    totalcount += counter;

    db.mapreduce.run.update({"_id": "unique"}, {"$set":
        {
            "status":   "sleeping",
            "time":     end - start,
            "actions":  counter,
            "totalactions": totalcount,
            "ping":     end
        }});
    counter = 0;
}

function executeMapReduceActions() {
    var actions = db.mapreduce.find();

    log(loglevels.DEBUG, "Found " + actions.count() + " actions");

    actions.forEach(function(action) {
        log(loglevels.DEBUG, "Checking if " + action.name + " should be executed");
        if (shouldRun(action)) {
            log(loglevels.DEBUG, "Executing " + action.name);
            runAction(action);
        }
    });
}

/**
 * Determine whether or not a given action should run - this time.
 *
 * There are 2 conditions in which an action will (automatically) execute:
 * - force was set to `true`
 * - lastrun + interval <= now
 *
 * If either or both of the lastrun and interval fields are missing, this action
 * will not execute. Keep this in mind when adding a new action - the lastrun field
 * must be set to an integer value, as well as the interval field.
 */
function shouldRun(action) {
    var timestamp = new Date().getTime();

    var execute = false;

    if (action.hasOwnProperty("force") && action.force === true) {
        execute = true;
        log(loglevels.DEBUG, "Force set to true");
    } else if (action.hasOwnProperty("lastrun") && action.hasOwnProperty("interval")
                && action.lastrun + action.interval < timestamp) {
        execute = true;
        log(loglevels.DEBUG, "lastrun + interval = " + action.lastrun + " + " + action.interval + " = " + (action.lastrun + action.interval));
    }

    return execute;
}

/**
 * Convenience function to easily allow to manually run an action - simply specify the name
 */
function run(actionName) {
    log(loglevels.INFO, "Trying to run action manually", actionName);

    var action = db.mapreduce.findOne({"name": actionName});
    if (action !== null) {
        log(loglevels.INFO, "Action found, running", actionName);
        printjson(runAction(action, "manual"));
    } else {
        log(loglevels.WARNING, "Action not found", actionName);
    }
}

/**
 * For internal use.
 *
 * Tries to generate the needed options for running the actual mapReduce command.
 *
 * Some options are always passed through as is:
 * - finalize
 * - sort
 * - limit
 *
 * The "out" and "query" options are generally also passed through, but conditions apply.
 *
 * The "query" option does not need to be a document; it can also be a function that returns a document
 * which can be used by the map-reduce functionality to filter the results that will have mapping
 * applied to.
 *
 * // TODO: finish this documentation
 */
function extractOptions(action) {
    var options = {},
        possibleOptions = ["finalize", "sort", "limit"],
        i,
        c,
        option,
        previous = {},
        setCustomOut = false;

    if (
            action.hasOwnProperty("incremental") &&
            typeof (action.incremental) === "string" &&
            action.hasOwnProperty("previous") &&
            typeof (action.previous) !== undefined &&
            action.previous !== {} &&
            action.hasOwnProperty("lastrun") &&
            action.lastrun > 0
        ) {

        log(loglevels.DEBUG, "Setting default incremental options");

        if (action.hasOwnProperty("out") && typeof (action.out) === "string" && typeof (action.out) !== "object") {
            options.out = {reduce: action.out};
            setCustomOut = true;
        }

        options.query = {};
        options.query[action.incremental] = {"$gt": action.lastrun};
    }

    for (i = 0, c = possibleOptions.length; i < c; i += 1) {
        option = possibleOptions[i];
        if (action.hasOwnProperty(option)) {
            options[option] = action[option];
        }
    }

    if (action.hasOwnProperty("out") && !setCustomOut) {
        options.out = action.out;
    }

    if (!options.hasOwnProperty("out")) {
        log(loglevels.WARNING, "No output collection/action specified, writing to results." + action.name, action);
        options.out = {reduce: "results." + action.name};
    }

    log(loglevels.DEBUG, "Applying options");

    if (action.hasOwnProperty("previous") && action.previous !== null) {
        previous = action.previous;
    } else {
        log(loglevels.DEBUG, "Resetting output collection - previous is empty");
        clearOut(action);
    }

    var q = extractQuery(action);
    if (q !== null) {
        options.query = q;
    }

    return options;
}

function extractQuery(action) {
    var query = null;

    if (action.hasOwnProperty("query") && typeof (action.query) === "string") {
        eval("query = " + action.query);
    }

    if (action.hasOwnProperty("queryf") && typeof (action.queryf) === "function") {
        if (query !== null) {
            log(loglevels.WARNING, "Both 'query' and 'queryf' are defined, using 'queryf'", action);
        }

        query = action.queryf.apply(action);
    }

    return query;
}

function clearOut(action) {
    var out = action.out;

    if (typeof out === "object") {
        if (out.hasOwnProperty("merge")) {
            out = out.merge;
        } else if (out.hasOwnProperty("reduce")) {
            out = out.reduce;
        }
    }

    log(loglevels.INFO, "Clearing " + out + " - reset", action);
    if (typeof out === "string") {
        db[out].remove();
    }
}

function runAction(action, type) {
    var options,
        result,
        timestamp,
        cleanResult,
        previous = {},
        update,
        logObj;

    counter += 1;

    if (type === undefined) {
        type = "auto";
    }

    if (action.hasOwnProperty("pre") && typeof (action.pre) === "function") {
        log(loglevels.DEBUG, "Applying pre-processing function");
        action.pre.apply(action);
    }

    options = extractOptions(action);

    log(loglevels.DEBUG, "Applying mapReduce");
    result = db[action.collection].mapReduce(
        action.map,
        action.reduce,
        options
    );

    timestamp = new Date().getTime();

    cleanResult = {
        "out":          result.result,
        "timeMillis":   result.timeMillis,
        "ok":           result.ok,
        "counts":       result.counts
    };

    if (action.hasOwnProperty("previous")) {
        previous = action.previous;
    }
    previous.timestamp  = timestamp;
    previous.result     = cleanResult;

    log(loglevels.DEBUG, "Updating action-information");

    update = {
        "force":    false,
        "lastrun":  timestamp,
        "type":     type,
        "previous": previous
    };

    db.mapreduce.update(
        {"_id":     action._id},
        {"$set":    update}
    );

    logObj = {
        "timestamp":    timestamp,
        "action":       action,
        "result":       cleanResult
        // TODO: because the query field might contain fields that start with "$", signifying an operator,
        // and fields starting with "$" are not allowed in mongo, we can't log the options object as-is.
        // so, we'll need to find a solution for that.
    };

    log(loglevels.INFO, "Finished running " + action.name, logObj);

    if (action.hasOwnProperty("post") && typeof (action.post) === "function") {
        log(loglevels.DEBUG, "Applying post-processing information");
        action.post.apply(action);
    }

    return log;
}

function log(level, message, data) {
    if (level >= loglevel.db || level >= loglevel.console) {
        var ts = new Date().getTime();

        var logObj = {
            timestamp: ts,
            pid: pid,
            level: level,
            message: message,
            data: data
        };

        if (level >= loglevel.db) {
            db.mapreduce.log.insert(logObj);
        }

        if (level >= loglevel.console) {
            print(ts + "\t" + pid.toString() + "\t" + message);
        }
    }
}
<commit_msg>log options after making the query object a string<commit_after>/*global db, sleep, print, ObjectId, printjson, mapReduce, run, shouldRun, runAction, clearOut */
/*jslint nomen: true, sloppy: true */

// TODO: clean up
// TODO: document
// TODO: move settings to db (providing sane default settings)
// TODO: perhaps provide string interpolation so debugging statements don't look as ugly
// TODO: perhaps provide convenience debug(), info(), warning(), error() functions?
// TODO: error handling
// TODO: make polling loop a function, and the body an argument
// TODO: provide convenience functions for doing a check, autostarting, starting in a parallel shell

var pid     = new ObjectId(),   // the "pid" of this runner
    running = true,             // when false, we exit
    interval = 1000,            // how many ms we should sleep in between runs
    counter = 0,                // how many mapReduce actions were executed this run
    totalcount = 0;             // how many mapReduce actions were executed by this instance

var loglevels = {
    DEBUG: 0,       // things that are really quite redundant to see all the time,
                    // but are useful when debugging
    INFO: 1,        // quite useful when you're wondering what's going on
    WARNING: 2,     // generally used for recoverable things or when exiting
    ERROR: 3        // when we're broken and need fixing
};

var loglevel = {
    db: loglevels.DEBUG,
    console: loglevels.INFO
};

db.mapreduce.run.save(
    {"_id": "unique", "pid": pid}
);

log(loglevels.INFO, "Starting");

var runningPid = {},
    start = 0,
    end = 0;

while (running) {
    runningPid = db.mapreduce.run.findOne({"_id": "unique"});

    if (runningPid === null || !runningPid.hasOwnProperty("pid")) {
        running = false;
        log(loglevels.WARNING, "Exiting, canceled");
    } else if (pid.toString() !== runningPid.pid.toString()) {
        running = false;
        log(loglevels.WARNING, "Exiting, new instance started");
    } else {
        db.mapreduce.run.update({"_id": "unique"}, {"$set": {"status": "running"}});

        doMapReduce();

        log(loglevels.DEBUG, "Going to sleep for " + interval + "ms");
        sleep(interval);
    }
}

function doMapReduce() {
    start = new Date().getTime();
    executeMapReduceActions();
    end = new Date().getTime();

    totalcount += counter;

    db.mapreduce.run.update({"_id": "unique"}, {"$set":
        {
            "status":   "sleeping",
            "time":     end - start,
            "actions":  counter,
            "totalactions": totalcount,
            "ping":     end
        }});
    counter = 0;
}

function executeMapReduceActions() {
    var actions = db.mapreduce.find();

    log(loglevels.DEBUG, "Found " + actions.count() + " actions");

    actions.forEach(function(action) {
        log(loglevels.DEBUG, "Checking if " + action.name + " should be executed");
        if (shouldRun(action)) {
            log(loglevels.DEBUG, "Executing " + action.name);
            runAction(action);
        }
    });
}

/**
 * Determine whether or not a given action should run - this time.
 *
 * There are 2 conditions in which an action will (automatically) execute:
 * - force was set to `true`
 * - lastrun + interval <= now
 *
 * If either or both of the lastrun and interval fields are missing, this action
 * will not execute. Keep this in mind when adding a new action - the lastrun field
 * must be set to an integer value, as well as the interval field.
 */
function shouldRun(action) {
    var timestamp = new Date().getTime();

    var execute = false;

    if (action.hasOwnProperty("force") && action.force === true) {
        execute = true;
        log(loglevels.DEBUG, "Force set to true");
    } else if (action.hasOwnProperty("lastrun") && action.hasOwnProperty("interval")
                && action.lastrun + action.interval < timestamp) {
        execute = true;
        log(loglevels.DEBUG, "lastrun + interval = " + action.lastrun + " + " + action.interval + " = " + (action.lastrun + action.interval));
    }

    return execute;
}

/**
 * Convenience function to easily allow to manually run an action - simply specify the name
 */
function run(actionName) {
    log(loglevels.INFO, "Trying to run action manually", actionName);

    var action = db.mapreduce.findOne({"name": actionName});
    if (action !== null) {
        log(loglevels.INFO, "Action found, running", actionName);
        printjson(runAction(action, "manual"));
    } else {
        log(loglevels.WARNING, "Action not found", actionName);
    }
}

/**
 * For internal use.
 *
 * Tries to generate the needed options for running the actual mapReduce command.
 *
 * Some options are always passed through as is:
 * - finalize
 * - sort
 * - limit
 *
 * The "out" and "query" options are generally also passed through, but conditions apply.
 *
 * The "query" option does not need to be a document; it can also be a function that returns a document
 * which can be used by the map-reduce functionality to filter the results that will have mapping
 * applied to.
 *
 * // TODO: finish this documentation
 */
function extractOptions(action) {
    var options = {},
        possibleOptions = ["finalize", "sort", "limit"],
        i,
        c,
        option,
        previous = {},
        setCustomOut = false;

    if (
            action.hasOwnProperty("incremental") &&
            typeof (action.incremental) === "string" &&
            action.hasOwnProperty("previous") &&
            typeof (action.previous) !== undefined &&
            action.previous !== {} &&
            action.hasOwnProperty("lastrun") &&
            action.lastrun > 0
        ) {

        log(loglevels.DEBUG, "Setting default incremental options");

        if (action.hasOwnProperty("out") && typeof (action.out) === "string" && typeof (action.out) !== "object") {
            options.out = {reduce: action.out};
            setCustomOut = true;
        }

        options.query = {};
        options.query[action.incremental] = {"$gt": action.lastrun};
    }

    for (i = 0, c = possibleOptions.length; i < c; i += 1) {
        option = possibleOptions[i];
        if (action.hasOwnProperty(option)) {
            options[option] = action[option];
        }
    }

    if (action.hasOwnProperty("out") && !setCustomOut) {
        options.out = action.out;
    }

    if (!options.hasOwnProperty("out")) {
        log(loglevels.WARNING, "No output collection/action specified, writing to results." + action.name, action);
        options.out = {reduce: "results." + action.name};
    }

    log(loglevels.DEBUG, "Applying options");

    if (action.hasOwnProperty("previous") && action.previous !== null) {
        previous = action.previous;
    } else {
        log(loglevels.DEBUG, "Resetting output collection - previous is empty");
        clearOut(action);
    }

    var q = extractQuery(action);
    if (q !== null) {
        options.query = q;
    }

    return options;
}

function extractQuery(action) {
    var query = null;

    if (action.hasOwnProperty("query") && typeof (action.query) === "string") {
        eval("query = " + action.query);
    }

    if (action.hasOwnProperty("queryf") && typeof (action.queryf) === "function") {
        if (query !== null) {
            log(loglevels.WARNING, "Both 'query' and 'queryf' are defined, using 'queryf'", action);
        }

        query = action.queryf.apply(action);
    }

    return query;
}

function clearOut(action) {
    var out = action.out;

    if (typeof out === "object") {
        if (out.hasOwnProperty("merge")) {
            out = out.merge;
        } else if (out.hasOwnProperty("reduce")) {
            out = out.reduce;
        }
    }

    log(loglevels.INFO, "Clearing " + out + " - reset", action);
    if (typeof out === "string") {
        db[out].remove();
    }
}

function runAction(action, type) {
    var options,
        result,
        timestamp,
        cleanResult,
        previous = {},
        update,
        logObj;

    counter += 1;

    if (type === undefined) {
        type = "auto";
    }

    if (action.hasOwnProperty("pre") && typeof (action.pre) === "function") {
        log(loglevels.DEBUG, "Applying pre-processing function");
        action.pre.apply(action);
    }

    options = extractOptions(action);

    log(loglevels.DEBUG, "Applying mapReduce");
    result = db[action.collection].mapReduce(
        action.map,
        action.reduce,
        options
    );

    timestamp = new Date().getTime();

    cleanResult = {
        "out":          result.result,
        "timeMillis":   result.timeMillis,
        "ok":           result.ok,
        "counts":       result.counts
    };

    if (action.hasOwnProperty("previous")) {
        previous = action.previous;
    }
    previous.timestamp  = timestamp;
    previous.result     = cleanResult;

    log(loglevels.DEBUG, "Updating action-information");

    update = {
        "force":    false,
        "lastrun":  timestamp,
        "type":     type,
        "previous": previous
    };

    db.mapreduce.update(
        {"_id":     action._id},
        {"$set":    update}
    );

    if (options.hasOwnProperty("query") && typeof (options.query) === "object") {
        options.query = tojsononeline(options.query);
    }

    logObj = {
        "timestamp":    timestamp,
        "action":       action,
        "result":       cleanResult,
        "options":      options
    };

    log(loglevels.INFO, "Finished running " + action.name, logObj);

    if (action.hasOwnProperty("post") && typeof (action.post) === "function") {
        log(loglevels.DEBUG, "Applying post-processing information");
        action.post.apply(action);
    }

    return log;
}

function log(level, message, data) {
    if (level >= loglevel.db || level >= loglevel.console) {
        var ts = new Date().getTime();

        var logObj = {
            timestamp: ts,
            pid: pid,
            level: level,
            message: message,
            data: data
        };

        if (level >= loglevel.db) {
            db.mapreduce.log.insert(logObj);
        }

        if (level >= loglevel.console) {
            print(ts + "\t" + pid.toString() + "\t" + message);
        }
    }
}
<|endoftext|>


<commit_before>window.Kamerleed = window.Kamerleed || {
    app: {
        title: 'Kamerleed'
    },
};
window.Kamerleed.interval = 5000;
window.Kamerleed.loopingEnabled = false;

window.Kamerleed.tidbits = [
    {
        title: 'seniority',
        enabled: function() { return (window.Kamerleed.person.profile.start_date != null); },
        sentence: function() {
            var d = Date.parse(window.Kamerleed.person.profile.start_date);
            var s = Math.floor((Date.now() - d) / 86400000) - 1;
            return sprintf("%s zit al %s dagen in de tweede kamer!", window.Kamerleed.person.profile.name, s);
        }
    },
    // FIXME: better to parse age for this?
    {
        title: 'age',
        enabled: function() { return (window.Kamerleed.person.profile.age != null); },
        sentence: function() {
            return sprintf(
                "Wist je dat %s alweer %s jaar oud is?",
                window.Kamerleed.person.profile.name,
                window.Kamerleed.person.profile.age
            )
        }
    },
    {
        title: 'birthplace',
        enabled: function() { return (window.Kamerleed.person.profile.birth_place != null); },
        sentence: function() {
            return sprintf(
                "Blijkbaar is %s geboren in %s!",
                window.Kamerleed.person.profile.name,
                window.Kamerleed.person.profile.birth_place
            );
        }
    },
    {
        title: 'hometown',
        enabled: function() { return (window.Kamerleed.person.profile.home_town != null); },
        sentence: function() {
            return sprintf(
                "Blijkbaar woont %s in %s!",
                window.Kamerleed.person.profile.name,
                window.Kamerleed.person.profile.home_town
            );
        }
    },
];

window.Kamerleed.init = function() {
    // detemine what to load
    if (window.location.pathname == '/') {
        // get random member
        console.log('homepage, should get a random member now ...');
        window.Kamerleed.update();
    } else if (person_match = window.location.pathname.match(/^\/persons\/([a-zA-z\-]+)\/?/)) {
        var slug = person_match[1];
        console.log('Politician page, should fetch data for ' + slug + ' now ...');
        window.Kamerleed.load_person(slug);
    } else {
        console.log('At a totally random path ...');
    }
};

window.Kamerleed.load_person = function(slug) {
    $.get('/persons/' + slug + '/json', function (data) {
        window.Kamerleed.person = data;
        window.Kamerleed.refresh_full_interface();
        // loop the interface
        window.Kamerleed.looper();
    });
};

window.Kamerleed.select_tidbit = function() {
    var enabled_tidbits = $.grep(window.Kamerleed.tidbits, function(item, idx) {
        return item.enabled();
    });
    var random_index = Math.floor((Math.random()*enabled_tidbits.length));
    return enabled_tidbits[random_index];
};

window.Kamerleed.refresh_full_interface = function() {
    // do interface refresh here
    document.title = sprintf("%s - %s", window.Kamerleed.app.title, window.Kamerleed.person.profile.name);
    window.Kamerleed.refresh_marker();
    window.Kamerleed.create_twitter_widget();
    console.log('Interface refreshed!');
};

window.Kamerleed.create_twitter_widget = function() {
    if (window.Kamerleed.person.profile.twitter.accounts.length > 0) {
        var username = window.Kamerleed.person.profile.twitter.accounts[0];
        console.log('creating twitter qidget for ' + username);
        $('#twitter-widget-marker').html('Tweets by @' + username + '');
        twttr.widgets.load();
    } else {
        $('#twitter-widget-marker').empty();
    }
};

window.Kamerleed.refresh_marker = function() {
    $('#marker').fadeOut(500, function() {
        var tidbit = window.Kamerleed.select_tidbit();
        $('#marker').removeClass('block1 block2 block3 block4 block5 block6 block7 blockundefined').addClass('block' + window.Kamerleed.person.profile.block);
        $('#marker div.avatar').attr('style', 'background: url(' + window.Kamerleed.person.profile.photo + ');');
        $('#marker div.avatar img').attr('src', 'http://www.tweedekamer.nl/images/' + window.Kamerleed.person.profile.party.slug + '.jpg');
        $('#marker p.sentence').text(tidbit.sentence());
        $('#marker').fadeIn();
    });
};

window.Kamerleed.update = function() {
    $.get('/persons/random/json', function (data) {
        var slug = data['slug'];
        console.log('Should fetch data for ' + slug + ' now ...');
        window.Kamerleed.load_person(slug);
    }, 'json');
};

window.Kamerleed.looper = function() {
    if (window.Kamerleed.loopingEnabled) {
        setTimeout(function() {
            window.Kamerleed.update();
        }, window.Kamerleed.interval);
    }
};

$(document).ready(function() {
    console.log('kamerleed');
    window.Kamerleed.init();

    setTimeout(function() {
        window.Kamerleed.looper();
    }, window.Kamerleed.interval);
});<commit_msg>Better referencing ...<commit_after>var Kamerleed = window.Kamerleed || {
    app: {
        title: 'Kamerleed'
    },
    interval: 5000,
    loopingEnabled: false,
};

Kamerleed.tidbits = [
    {
        title: 'seniority',
        enabled: function() { return (Kamerleed.person.profile.start_date != null); },
        sentence: function() {
            var d = Date.parse(Kamerleed.person.profile.start_date);
            var s = Math.floor((Date.now() - d) / 86400000) - 1;
            return sprintf("%s zit al %s dagen in de tweede kamer!", Kamerleed.person.profile.name, s);
        }
    },
    // FIXME: better to parse age for this?
    {
        title: 'age',
        enabled: function() { return (Kamerleed.person.profile.age != null); },
        sentence: function() {
            return sprintf(
                "Wist je dat %s alweer %s jaar oud is?",
                Kamerleed.person.profile.name,
                Kamerleed.person.profile.age
            )
        }
    },
    {
        title: 'birthplace',
        enabled: function() { return (Kamerleed.person.profile.birth_place != null); },
        sentence: function() {
            return sprintf(
                "Blijkbaar is %s geboren in %s!",
                Kamerleed.person.profile.name,
                Kamerleed.person.profile.birth_place
            );
        }
    },
    {
        title: 'hometown',
        enabled: function() { return (Kamerleed.person.profile.home_town != null); },
        sentence: function() {
            return sprintf(
                "Blijkbaar woont %s in %s!",
                Kamerleed.person.profile.name,
                Kamerleed.person.profile.home_town
            );
        }
    },
];

Kamerleed.init = function() {
    // detemine what to load
    if (window.location.pathname == '/') {
        // get random member
        console.log('homepage, should get a random member now ...');
        Kamerleed.update();
    } else if (person_match = window.location.pathname.match(/^\/persons\/([a-zA-z\-]+)\/?/)) {
        var slug = person_match[1];
        console.log('Politician page, should fetch data for ' + slug + ' now ...');
        Kamerleed.load_person(slug);
    } else {
        console.log('At a totally random path ...');
    }
};

Kamerleed.load_person = function(slug) {
    $.get('/persons/' + slug + '/json', function (data) {
        Kamerleed.person = data;
        Kamerleed.refresh_full_interface();
        // loop the interface
        Kamerleed.looper();
    });
};

Kamerleed.select_tidbit = function() {
    var enabled_tidbits = $.grep(Kamerleed.tidbits, function(item, idx) {
        return item.enabled();
    });
    var random_index = Math.floor((Math.random()*enabled_tidbits.length));
    return enabled_tidbits[random_index];
};

Kamerleed.refresh_full_interface = function() {
    // do interface refresh here
    document.title = sprintf("%s - %s", Kamerleed.app.title, Kamerleed.person.profile.name);
    Kamerleed.refresh_marker();
    Kamerleed.create_twitter_widget();
    console.log('Interface refreshed!');
};

Kamerleed.create_twitter_widget = function() {
    if (Kamerleed.person.profile.twitter.accounts.length > 0) {
        var username = Kamerleed.person.profile.twitter.accounts[0];
        console.log('creating twitter qidget for ' + username);
        $('#twitter-widget-marker').html('Tweets by @' + username + '');
        twttr.widgets.load();
    } else {
        $('#twitter-widget-marker').empty();
    }
};

Kamerleed.refresh_marker = function() {
    $('#marker').fadeOut(500, function() {
        var tidbit = Kamerleed.select_tidbit();
        $('#marker').removeClass('block1 block2 block3 block4 block5 block6 block7 blockundefined').addClass('block' + Kamerleed.person.profile.block);
        $('#marker div.avatar').attr('style', 'background: url(' + Kamerleed.person.profile.photo + ');');
        $('#marker div.avatar img').attr('src', 'http://www.tweedekamer.nl/images/' + Kamerleed.person.profile.party.slug + '.jpg');
        $('#marker p.sentence').text(tidbit.sentence());
        $('#marker').fadeIn();
    });
};

Kamerleed.update = function() {
    $.get('/persons/random/json', function (data) {
        var slug = data['slug'];
        console.log('Should fetch data for ' + slug + ' now ...');
        Kamerleed.load_person(slug);
    }, 'json');
};

Kamerleed.looper = function() {
    if (Kamerleed.loopingEnabled) {
        setTimeout(function() {
            Kamerleed.update();
        }, Kamerleed.interval);
    }
};

$(document).ready(function() {
    console.log('kamerleed');
    Kamerleed.init();

    setTimeout(function() {
        Kamerleed.looper();
    }, Kamerleed.interval);
});<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
//var globalTunnel = require('global-tunnel');
//globalTunnel.initialize();

var session = require('express-session');
var partials = require('express-partials');

////////////////////////////////////////////////////////////////
// MongoDB初期化
var model = require('./model');
var User = model.User;
var Score = model.Score;

// ページ遷移
var routes = require('./routes/index');
var dashboard = require('./routes/dashboard');
var answer = require('./routes/answer');
var login = require('./routes/login');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(partials());
app.use(session({
  secret: 'the quick brown fox',
  resave: false,
  saveUninitialized: false,
  cookie: {
    maxAge: 30*60*1000
  }
}));

////////////////////////////////////////////////////////////////
// セッションチェック
var sessionCheck = function(req, res, next) {
  if (req.session.user) {
    next();
  } else {
    res.redirect('/');
  }
};

////////////////////////////////////////////////////////////////
// 認証処理
var authconfig = require('./auth.js');
var passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(user, done) {
  done(null, user);
});

////////////////////////////////////////////////////////////////
// GitHubアカウントによるOAuth処理
var GitHubStrategy = require('passport-github').Strategy;
passport.use(new GitHubStrategy({
    clientID: authconfig.github.clientID,
    clientSecret: authconfig.github.clientSecret,
    callbackURL: authconfig.github.callbackURL,
  },
  function(token, tokenSecret, profile, done) {
    User.find({provider: profile.provider, provider_id: profile.id}, function(err, docs){
      if (docs.length == 0) {
        var user = new User({ provider: profile.provider, provider_id: profile.id, nickname: profile.username });
        user.save(function(err) {
          if (err) { console.log(err); }
        });
      }
      if (err) {
        return done(err);
      }
      return done(null, profile);
    });
  })
);

app.get('/auth/github', passport.authenticate('github'));
app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/' }),
  function (req, res) {
    req.session.user = {name: req.body.username};
    res.redirect('/dashboard');
  }
);

////////////////////////////////////////////////////////////////
// TwitterアカウントによるOAuth処理
var TwitterStrategy = require('passport-twitter').Strategy;
passport.use(new TwitterStrategy({
    clientID: authconfig.twitter.clientID,
    clientSecret: authconfig.twitter.clientSecret,
    callbackURL: authconfig.twitter.callbackURL,
  },
  function(token, tokenSecret, profile, done) {
    User.find({provider: profile.provider, provider_id: profile.id}, function(err, docs){
      if (docs.length == 0) {
        var user = new User({ provider: profile.provider, provider_id: profile.id, nickname: profile.username });
        user.save(function(err) {
          if (err) { console.log(err); }
        });
      }
      if (err) {
        return done(err);
      }
      return done(null, profile);
    });
  })
);
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/' }),
  function (req, res) {
    req.session.user = {name: req.body.username};
    res.redirect('/dashboard');
  }
);

////////////////////////////////////////////////////////////////
// GoogleアカウントによるOAuth処理
var GoogleStrategy = require('passport-google-oauth').Strategy;
passport.use(new GoogleStrategy({
    clientID: authconfig.google.clientID,
    clientSecret: authconfig.google.clientSecret,
    callbackURL: authconfig.google.callbackURL,
  },
  function(token, tokenSecret, profile, done) {
    User.find({provider: profile.provider, provider_id: profile.id}, function(err, docs){
      if (docs.length == 0) {
        var user = new User({ provider: profile.provider, provider_id: profile.id, nickname: profile.username });
        user.save(function(err) {
          if (err) { console.log(err); }
        });
      }
      if (err) {
        return done(err);
      }
      return done(null, profile);
    });
  })
);
app.get('/auth/google', passport.authenticate('google'));
app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/' }),
  function (req, res) {
    req.session.user = {name: req.body.username};
    res.redirect('/dashboard');
  }
);

///////////////////////////////////////
app.use('/', routes);
app.use('/login', login);
app.use('/dashboard', sessionCheck, dashboard);
app.use('/answer', sessionCheck, answer);

var problem = require('./routes/problem/problem_public');
app.use('/problem', sessionCheck, problem);

app.get('/logout', function(req, res) {
  delete req.session.user;
  res.redirect('/');
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;
<commit_msg>seiri<commit_after>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
//var globalTunnel = require('global-tunnel');
//globalTunnel.initialize();

var session = require('express-session');
var partials = require('express-partials');

////////////////////////////////////////////////////////////////
// MongoDB初期化
var model = require('./model');
var User = model.User;
var Score = model.Score;

// ページ遷移
var routes = require('./routes/index');
var dashboard = require('./routes/dashboard');
var answer = require('./routes/answer');
var login = require('./routes/login');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(partials());
app.use(session({
  secret: 'the quick brown fox',
  resave: false,
  saveUninitialized: false,
  cookie: {
    maxAge: 30*60*1000
  }
}));

////////////////////////////////////////////////////////////////
// セッションチェック
var sessionCheck = function(req, res, next) {
  if (req.session.user) {
    next();
  } else {
    res.redirect('/');
  }
};

////////////////////////////////////////////////////////////////
// 認証処理
var authconfig = require('./auth.js');
var passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(user, done) {
  done(null, user);
});

////////////////////////////////////////////////////////////////
// GitHubアカウントによるOAuth処理
var GitHubStrategy = require('passport-github').Strategy;
passport.use(new GitHubStrategy({
    clientID: authconfig.github.clientID,
    clientSecret: authconfig.github.clientSecret,
    callbackURL: authconfig.github.callbackURL,
  },
  function(token, tokenSecret, profile, done) {
    User.find({provider: profile.provider, provider_id: profile.id}, function(err, docs){
      if (docs.length == 0) {
        var user = new User({ provider: profile.provider, provider_id: profile.id, nickname: profile.username });
        user.save(function(err) {
          if (err) { console.log(err); }
        });
      }
      if (err) {
        return done(err);
      }
      return done(null, profile);
    });
  })
);

app.get('/auth/github', passport.authenticate('github'));
app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/' }),
  function (req, res) {
    req.session.user = {name: req.body.username};
    res.redirect('/dashboard');
  }
);

/*
////////////////////////////////////////////////////////////////
// TwitterアカウントによるOAuth処理
var TwitterStrategy = require('passport-twitter').Strategy;
passport.use(new TwitterStrategy({
    clientID: authconfig.twitter.clientID,
    clientSecret: authconfig.twitter.clientSecret,
    callbackURL: authconfig.twitter.callbackURL,
  },
  function(token, tokenSecret, profile, done) {
    User.find({provider: profile.provider, provider_id: profile.id}, function(err, docs){
      if (docs.length == 0) {
        var user = new User({ provider: profile.provider, provider_id: profile.id, nickname: profile.username });
        user.save(function(err) {
          if (err) { console.log(err); }
        });
      }
      if (err) {
        return done(err);
      }
      return done(null, profile);
    });
  })
);
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/' }),
  function (req, res) {
    req.session.user = {name: req.body.username};
    res.redirect('/dashboard');
  }
);
*/

////////////////////////////////////////////////////////////////
// GoogleアカウントによるOAuth処理
var GoogleStrategy = require('passport-google-oauth').Strategy;
passport.use(new GoogleStrategy({
    clientID: authconfig.google.clientID,
    clientSecret: authconfig.google.clientSecret,
    callbackURL: authconfig.google.callbackURL,
  },
  function(token, tokenSecret, profile, done) {
    User.find({provider: profile.provider, provider_id: profile.id}, function(err, docs){
      if (docs.length == 0) {
        var user = new User({ provider: profile.provider, provider_id: profile.id, nickname: profile.username });
        user.save(function(err) {
          if (err) { console.log(err); }
        });
      }
      if (err) {
        return done(err);
      }
      return done(null, profile);
    });
  })
);
app.get('/auth/google', passport.authenticate('google'));
app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/' }),
  function (req, res) {
    req.session.user = {name: req.body.username};
    res.redirect('/dashboard');
  }
);

///////////////////////////////////////
app.use('/', routes);
app.use('/login', login);
app.use('/dashboard', sessionCheck, dashboard);
app.use('/answer', sessionCheck, answer);

var problem = require('./routes/problem/problem_public');
app.use('/problem', sessionCheck, problem);

app.get('/logout', function(req, res) {
  delete req.session.user;
  res.redirect('/');
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "./PageGrid", "dojo/store/JsonRest", "dgrid/extensions/DijitRegistry",
	"dgrid/Keyboard", "dgrid/Selection", "./formatter", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnHider",
	"dgrid/extensions/DnD", "dojo/dnd/Source", "dojo/_base/Deferred", "dojo/aspect", "dojo/_base/lang",
	"dojo/topic", "dgrid/editor", "dijit/Menu", "dijit/MenuItem", "../WorkspaceManager", "dijit/Dialog",
	"../JobManager", "dojo/on"

],
function(declare, Grid, Store, DijitRegistry,
		 Keyboard, Selection, formatter, ColumnResizer,
		 ColumnHider, DnD, DnDSource,
		 Deferred, aspect, lang, Topic, editor, Menu, MenuItem, WorkspaceManager, Dialog,
		 JobManager, on){

	var store = JobManager.getStore();

	return declare([Grid, ColumnHider, Selection, Keyboard, ColumnResizer, DijitRegistry], {
		store: store,
		columns: {
			"status_indicator": {
				label: "",
				field: "status",
				formatter: formatter.status_indicator
			},
			"status": {
				label: "Status",
				field: "status",
				formatter: formatter.status_alias
			},

			submit_time: {
				label: "Submit",
				field: "submit_time",
				formatter: formatter.date
			},

			"id": {
				label: "ID",
				field: "id",
				hidden: true
			},
			"app": {
				label: "App",
				field: "app",
				formatter: formatter.appLabel
			},
			parameters: {
				label: "Output Name",
				field: "parameters",
				formatter: function(val){
					return val.output_file || "";
				}
			},

			start_time: {
				label: "Start",
				field: "start_time",
				formatter: formatter.date
			},
			completed_time: {
				label: "Completed",
				field: "completed_time",
				formatter: formatter.date
			}
		},
		constructor: function(){

			this.queryOptions = {
				sort: [{attribute: "submit_time", descending: true}]

//				sort: [{attribute: "genome_name", descending: false},
//					{attribute: "accession", descending: false},
//					{attribute: "start", descending: false}]
			};

			this.dndParams.creator = lang.hitch(this, function(item, hint){
				//console.log("item: ", item, " hint:", hint, "dataType: ", this.dndDataType);
				var avatar = dojo.create("div", {
					innerHTML: item.organism_name || item.ncbi_taxon_id || item.id
				});
				avatar.data = item;
				if(hint == 'avatar'){
					// create your avatar if you want
				}

				return {
					node: avatar,
					data: item,
					type: this.dndDataType
				}
			})

		},
		selectionMode: "single",
		allowTextSelection: false,
		deselectOnRefresh: false,
		minRowsPerPage: 50,
		bufferRows: 100,
		maxRowsPerPage: 1000,
		pagingDelay: 250,
		//		pagingMethod: "throttleDelayed",
		farOffRemoval: 2000,
		keepScrollPosition: true,
		rowHeight: 24,
		loadingMessage: "Loading...",
		dndDataType: "genome",
		dndParams: {
			accept: "none",
			selfAccept: false,
			copyOnly: true
		},
		queryOptions: {
			sort: [
				{attribute: "submit_time", descending: true}
			]
		},

		sort: [
			{attribute: "submit_time", descending: true}
		],

		/*
			_setApiServer: function(server){
					//console.log("_setapiServerAttr: ", server);
					this.apiServer = server;
					this.set('store', this.createStore(this.dataModel), this.buildQuery());
			},
	*/

		_setTotalRows: function(rows){
			this.totalRows = rows;
			//console.log("Total Rows: ", rows);
			if(this.controlButton){
				//console.log("this.controlButton: ", this.controlButton);
				if(!this._originalTitle){
					this._originalTitle = this.controlButton.get('label');
				}
				this.controlButton.set('label', this._originalTitle + " (" + rows + ")");

				//console.log(this.controlButton);
			}
		},

		showErrorDialog: function(data){
			//console.log("Show Error Dialog: ", data);
			if(!this.errorDialog){
				this.errorDialog = new Dialog({title: "Task Output", content: "Loading Task Detail..."});
			}else{
				this.errorDialog.set("content", "Loading Task Detail...");
			}

			var _self = this;
			var timer = setTimeout(function(){
				_self.errorDialog.set("content", "Unable to retreive additional details about this task at this task. The operation timed out.");
			}, 30000);
			JobManager.queryTaskDetail(data.id, true, true).then(function(detail){
				//console.log("JOB DETAIL: ", detail);
				clearTimeout(timer);
				if(detail.stderr){
					_self.errorDialog.set("content", "

" + (detail.stdout || "None.") + "

" + (detail.stderr || "None.") + "

");
				}else{
					_self.errorDialog.set("content", "Unable to retreive additional details about this task at this task.

" + JSON.stringify(detail, null, 4) + "
");
				}
			}, function(err){
				_self.errorDialog.set("content", "Unable to retreive additional details about this task at this task.
" + err + "

");
			});

			this.errorDialog.show();
		},

		startup: function(){
			if(this._started){
				return;
			}
			var _self = this;
			aspect.before(_self, 'renderArray', function(results){
				Deferred.when(results.total, function(x){
					_self.set("totalRows", x);
				});
			});

			// this.on(".dgrid-content .dgrid-row:dblclick", function(evt) {
			// 	var row = _self.row(evt);
			// 	//console.log("dblclick row:", row)
			// 	if (row.data && row.data.status && row.data.status=="completed"){
			// 		//console.log("row.data: ", row.data);
			// 		Topic.publish("/navigate", {href: "/workspace" + row.data.parameters.output_path+ "/" + row.data.parameters.output_file});
			// 	}else{
			// 		_self.showErrorDialog(row.data);
			// 	}

			// });

			_selection = {};
			Topic.publish("/select", []);

			this.on("dgrid-select", function(evt){
				console.log('dgrid-select: ', evt);
				var newEvt = {
					rows: evt.rows,
					selected: evt.grid.selection,
					grid: _self,
					bubbles: true,
					cancelable: true
				};
				on.emit(_self.domNode, "select", newEvt);
			});
			this.on("dgrid-deselect", function(evt){
				console.log("dgrid-select");
				var newEvt = {
					rows: evt.rows,
					selected: evt.grid.selection,
					grid: _self,
					bubbles: true,
					cancelable: true
				};
				on.emit(_self.domNode, "deselect", newEvt);
			});

			console.log("STARTUP REFRESH");
			this.refresh();

		},
		_setActiveFilter: function(filter){
			//console.log("Set Active Filter: ", filter, "started:", this._started);
			this.activeFilter = filter;
			this.set("query", this.buildQuery());
		},

		buildQuery: function(table, extra){
			var q = "?" + (this.activeFilter ? ("in(gid,query(genomesummary,and(" + this.activeFilter + ",limit(Infinity),values(genome_info_id))))") : "") + (this.extra || "");
			//console.log("Feature Grid Query:", q);
			return q;
		},
		createStore: function(dataModel){
			//console.log("Create Store for ", dataModel, " at ", this.apiServer);
			var store = new Store({
				target: (this.apiServer ? (this.apiServer) : "") + "/" + dataModel + "/",
				idProperty: "rownum",
				headers: {
					"accept": "application/json",
					"content-type": "application/json",
					"Authorization": (window.App.authorizationToken || ""),
					'X-Requested-With': null
				}
			});
			//console.log("store: ", store);
			return store;
		},

		getFilterPanel: function(){
			//console.log("getFilterPanel()");
			return FilterPanel;
		}

	});

});
<commit_msg>resolves PATRIC3/patric3_website#542<commit_after>define([
	"dojo/_base/declare", "./PageGrid", "dojo/store/JsonRest", "dgrid/extensions/DijitRegistry",
	"dgrid/Keyboard", "dgrid/Selection", "./formatter", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnHider",
	"dgrid/extensions/DnD", "dojo/dnd/Source", "dojo/_base/Deferred", "dojo/aspect", "dojo/_base/lang",
	"dojo/topic", "dgrid/editor", "dijit/Menu", "dijit/MenuItem", "../WorkspaceManager", "dijit/Dialog",
	"../JobManager", "dojo/on"

],
function(declare, Grid, Store, DijitRegistry,
		 Keyboard, Selection, formatter, ColumnResizer,
		 ColumnHider, DnD, DnDSource,
		 Deferred, aspect, lang, Topic, editor, Menu, MenuItem, WorkspaceManager, Dialog,
		 JobManager, on){

	var store = JobManager.getStore();

	return declare([Grid, ColumnHider, Selection, Keyboard, ColumnResizer, DijitRegistry], {
		store: store,
		columns: {
			"status_indicator": {
				label: "",
				field: "status",
				unhidable: true,
				formatter: formatter.status_indicator
			},
			"status": {
				label: "Status",
				field: "status",
				formatter: formatter.status_alias
			},

			submit_time: {
				label: "Submit",
				field: "submit_time",
				formatter: formatter.date
			},

			"id": {
				label: "ID",
				field: "id",
				hidden: true
			},
			"app": {
				label: "App",
				field: "app",
				formatter: formatter.appLabel
			},
			parameters: {
				label: "Output Name",
				field: "parameters",
				formatter: function(val){
					return val.output_file || "";
				}
			},

			start_time: {
				label: "Start",
				field: "start_time",
				formatter: formatter.date
			},
			completed_time: {
				label: "Completed",
				field: "completed_time",
				formatter: formatter.date
			}
		},
		constructor: function(){

			this.queryOptions = {
				sort: [{attribute: "submit_time", descending: true}]

//				sort: [{attribute: "genome_name", descending: false},
//					{attribute: "accession", descending: false},
//					{attribute: "start", descending: false}]
			};

			this.dndParams.creator = lang.hitch(this, function(item, hint){
				//console.log("item: ", item, " hint:", hint, "dataType: ", this.dndDataType);
				var avatar = dojo.create("div", {
					innerHTML: item.organism_name || item.ncbi_taxon_id || item.id
				});
				avatar.data = item;
				if(hint == 'avatar'){
					// create your avatar if you want
				}

				return {
					node: avatar,
					data: item,
					type: this.dndDataType
				}
			})

		},
		selectionMode: "single",
		allowTextSelection: false,
		deselectOnRefresh: false,
		minRowsPerPage: 50,
		bufferRows: 100,
		maxRowsPerPage: 1000,
		pagingDelay: 250,
		//		pagingMethod: "throttleDelayed",
		farOffRemoval: 2000,
		keepScrollPosition: true,
		rowHeight: 24,
		loadingMessage: "Loading...",
		dndDataType: "genome",
		dndParams: {
			accept: "none",
			selfAccept: false,
			copyOnly: true
		},
		queryOptions: {
			sort: [
				{attribute: "submit_time", descending: true}
			]
		},

		sort: [
			{attribute: "submit_time", descending: true}
		],

		/*
			_setApiServer: function(server){
					//console.log("_setapiServerAttr: ", server);
					this.apiServer = server;
					this.set('store', this.createStore(this.dataModel), this.buildQuery());
			},
	*/

		_setTotalRows: function(rows){
			this.totalRows = rows;
			//console.log("Total Rows: ", rows);
			if(this.controlButton){
				//console.log("this.controlButton: ", this.controlButton);
				if(!this._originalTitle){
					this._originalTitle = this.controlButton.get('label');
				}
				this.controlButton.set('label', this._originalTitle + " (" + rows + ")");

				//console.log(this.controlButton);
			}
		},

		showErrorDialog: function(data){
			//console.log("Show Error Dialog: ", data);
			if(!this.errorDialog){
				this.errorDialog = new Dialog({title: "Task Output", content: "Loading Task Detail..."});
			}else{
				this.errorDialog.set("content", "Loading Task Detail...");
			}

			var _self = this;
			var timer = setTimeout(function(){
				_self.errorDialog.set("content", "Unable to retreive additional details about this task at this task. The operation timed out.");
			}, 30000);
			JobManager.queryTaskDetail(data.id, true, true).then(function(detail){
				//console.log("JOB DETAIL: ", detail);
				clearTimeout(timer);
				if(detail.stderr){
					_self.errorDialog.set("content", "

" + (detail.stdout || "None.") + "

" + (detail.stderr || "None.") + "

");
				}else{
					_self.errorDialog.set("content", "Unable to retreive additional details about this task at this task.

" + JSON.stringify(detail, null, 4) + "
");
				}
			}, function(err){
				_self.errorDialog.set("content", "Unable to retreive additional details about this task at this task.
" + err + "

");
			});

			this.errorDialog.show();
		},

		startup: function(){
			if(this._started){
				return;
			}
			var _self = this;
			aspect.before(_self, 'renderArray', function(results){
				Deferred.when(results.total, function(x){
					_self.set("totalRows", x);
				});
			});

			// this.on(".dgrid-content .dgrid-row:dblclick", function(evt) {
			// 	var row = _self.row(evt);
			// 	//console.log("dblclick row:", row)
			// 	if (row.data && row.data.status && row.data.status=="completed"){
			// 		//console.log("row.data: ", row.data);
			// 		Topic.publish("/navigate", {href: "/workspace" + row.data.parameters.output_path+ "/" + row.data.parameters.output_file});
			// 	}else{
			// 		_self.showErrorDialog(row.data);
			// 	}

			// });

			_selection = {};
			Topic.publish("/select", []);

			this.on("dgrid-select", function(evt){
				console.log('dgrid-select: ', evt);
				var newEvt = {
					rows: evt.rows,
					selected: evt.grid.selection,
					grid: _self,
					bubbles: true,
					cancelable: true
				};
				on.emit(_self.domNode, "select", newEvt);
			});
			this.on("dgrid-deselect", function(evt){
				console.log("dgrid-select");
				var newEvt = {
					rows: evt.rows,
					selected: evt.grid.selection,
					grid: _self,
					bubbles: true,
					cancelable: true
				};
				on.emit(_self.domNode, "deselect", newEvt);
			});

			console.log("STARTUP REFRESH");
			this.refresh();

		},
		_setActiveFilter: function(filter){
			//console.log("Set Active Filter: ", filter, "started:", this._started);
			this.activeFilter = filter;
			this.set("query", this.buildQuery());
		},

		buildQuery: function(table, extra){
			var q = "?" + (this.activeFilter ? ("in(gid,query(genomesummary,and(" + this.activeFilter + ",limit(Infinity),values(genome_info_id))))") : "") + (this.extra || "");
			//console.log("Feature Grid Query:", q);
			return q;
		},
		createStore: function(dataModel){
			//console.log("Create Store for ", dataModel, " at ", this.apiServer);
			var store = new Store({
				target: (this.apiServer ? (this.apiServer) : "") + "/" + dataModel + "/",
				idProperty: "rownum",
				headers: {
					"accept": "application/json",
					"content-type": "application/json",
					"Authorization": (window.App.authorizationToken || ""),
					'X-Requested-With': null
				}
			});
			//console.log("store: ", store);
			return store;
		},

		getFilterPanel: function(){
			//console.log("getFilterPanel()");
			return FilterPanel;
		}

	});

});
<|endoftext|>


<commit_before>var MongoClient = require('mongodb').MongoClient;

/**
 * The Authentication controller.
 */
var StressJS = function() {
};

/**
 * Create random string.
 * @param size, the lenght of the string
 */
StressJS.randomString = function(size) {
	var s = "";
	var keys = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*=!#$%&";
	for (var i = 0; i < size; i++) {
		s += keys.charAt(Math.floor(Math.random() * keys.length));
	}
	return s;
};

/**
 * Opens and close the db.
 * Save a post and save the user email
 */
StressJS.save = function() {
	MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {

		//Selecting the post collection
		var posts = db.collection("posts");

		var title = StressJS.randomString(20) + new Date() + '_' + Math.floor((Math.random() * 100));
		var permalink = title;
		var user = {
			fname : StressJS.randomString(8),
			lname : StressJS.randomString(8),
			domain : '@' + StressJS.randomString(10) + '.' + StressJS.randomString(5) + '.' + StressJS.randomString(5)
		};

		user.email = user.fname + "." + user.lname + user.domain;

		// Build a new post
		var post = {
			"title" : "MNA || " + title,
			"author" : user.email,
			"body" : 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
			"permalink" : permalink,
			"tags" : [StressJS.randomString(5), StressJS.randomString(2), StressJS.randomString(6)],
			"comments" : [StressJS.randomString(4) + '2' + StressJS.randomString(4)],
			"date" : new Date().getDate()
		};

		posts.insert(post, function(err, result) {
			if (err) {
				console.log("Post ERROR ");
				db.close();
			} else {
				console.log("Post OK ");
				//Selecting the post collection
				var users = db.collection("users");
				users.insert(user, function(err, result) {
					if (err) {
						console.log("Post ERROR ");
						db.close();
					} else {
						console.log("User OK ");
						db.close();
					}
				});
			}
		});

	});
};

/**
 * Here we go!.
 */
StressJS.run = function() {
	setInterval(function() {
			StressJS.save();
		}, 100);
};

//Exports the object
exports.StressJS = StressJS;
<commit_msg>Eval in db object<commit_after>var MongoClient = require('mongodb').MongoClient;

/**
 * The Authentication controller.
 */
var StressJS = function() {
};

/**
 * Create random string.
 * @param size, the lenght of the string
 */
StressJS.randomString = function(size) {
	var s = "";
	var keys = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*=!#$%&";
	for (var i = 0; i < size; i++) {
		s += keys.charAt(Math.floor(Math.random() * keys.length));
	}
	return s;
};

/**
 * Opens and close the db.
 * Save a post and save the user email
 */
StressJS.save = function() {
	MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
		if (err) {
			console.log("Mongo connecting: " + err);
			if (db) {
				db.close();
			}
		} else {
			if (db) {
				//Selecting the post collection
				var posts = db.collection("posts");

				var title = StressJS.randomString(20) + new Date() + '_' + Math.floor((Math.random() * 100));
				var permalink = title;
				var user = {
					fname : StressJS.randomString(8),
					lname : StressJS.randomString(8),
					domain : '@' + StressJS.randomString(10) + '.' + StressJS.randomString(5) + '.' + StressJS.randomString(5)
				};

				user.email = user.fname + "." + user.lname + user.domain;

				// Build a new post
				var post = {
					"title" : "MNA || " + title,
					"author" : user.email,
					"body" : 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
					"permalink" : permalink,
					"tags" : [StressJS.randomString(5), StressJS.randomString(2), StressJS.randomString(6)],
					"comments" : [StressJS.randomString(4) + '2' + StressJS.randomString(4)],
					"date" : new Date().getDate()
				};

				posts.insert(post, function(err, result) {
					if (err) {
						console.log("Post ERROR ");
						db.close();
					} else {
						console.log("Post OK ");
						//Selecting the post collection
						var users = db.collection("users");
						users.insert(user, function(err, result) {
							if (err) {
								console.log("Post ERROR ");
								db.close();
							} else {
								console.log("User OK ");
								db.close();
							}
						});
					}
				});
			} else {
				console.log("ERR: No db object found.");
			}
		}
	});
};

/**
 * Here we go!.
 */
StressJS.run = function() {
	setInterval(function() {
		StressJS.save();
	}, 100);
};

//Exports the object
exports.StressJS = StressJS;
<|endoftext|>


<commit_before>/*
 * IFrameStorage
 *
 * Persist data from any domain.
 * Targets modern browsers, IE8+
*/

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['domready'], factory);
  } else {
    root.IFS = factory(root.domready);
  }
}(this, function() {

  // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
  function has(object, property){
    var t = typeof object[property];
    return t == 'function' || (!!(t == 'object' && object[property])) || t == 'unknown';
  }

  var support = {
    storageEventTarget: ('onstorage' in document) ? document : window
  };

  if (has(window, 'addEventListener')) {
    support.on = function(target, name, callback) {
      target.addEventListener(name, callback, false);
    }
    support.off = function(target, name, callback) {
      target.removeEventListener(name, callback, false);
    }
  } else if (has(window, 'attachEvent')) {
    support.on = function(object, name, callback) {
      object.attachEvent('on' + name, callback);
    }
    support.off = function(object, name, callback) {
      object.detachEvent('on' + name, callback);
    }
  }

  var IFS = {};

  IFS.Parent = function(childOrigin, path, name, callback) {
    this.childOrigin = childOrigin;
    this.childUri = childOrigin + path;
    this.name = name;
    this.iframe = this._createIframe(this.childUri, this.name, callback);

    this._counter = 0;
    this._queue = {};

    this._listen();
  };

  IFS.Parent.prototype = {

    get: function(key, callback) {
      this._callMethod('get', [key], callback);
    },

    set: function(key, value, options, callback) {
      if (typeof options === 'function') {
        callback = options;
        options = {}
      }

      this._callMethod('set', [key, value, options], callback);
    },

    unset: function(key, callback) {
      this._callMethod('unset', [key], callback);
    },

    _listen: function() {
      var self = this;
      support.on(window, 'message', function(evt) {
        if (evt.origin == self.childOrigin) {
          self._receiveMessage(JSON.parse(evt.data));
        }
      });
    },

    _addCall: function(callback) {
      this._queue[++this._counter] = callback;
      return this._counter;
    },

    _callMethod: function(method, args, callback) {
      var params = {
        method: method,
        args: args
      };
      if (typeof callback === 'function') {
        params.id = this._addCall(callback);
      }

      var message = JSON.stringify(params);
      this.iframe.contentWindow.postMessage(message, this.childOrigin);
    },

    _receiveMessage: function(message) {
      switch (message.type) {
        case 'callback':
          this._queue[message.id].apply(this, message.args);
          this._queue[message.id] = null;
          break;
      }
    },

    _createIframe: function(uri, name, callback) {
      var iframe = document.createElement('iframe');
      iframe.id = 'ifs_' + name;
      iframe.name = 'ifs_' + name;
      iframe.style.position = 'absolute';
      iframe.style.top = '-2000px';
      iframe.style.left = '0px';
      iframe.src = uri;
      iframe.border = iframe.frameBorder = 0;
      iframe.allowTransparency = true;

      support.on(iframe, 'load', callback);

      document.body.appendChild(iframe);

      return iframe;
    }

  };

  IFS.Child = function(parentOrigin) {
    this.parent = window.parent;
    this.parentOrigin = parentOrigin;

    this._listen();
  };

  IFS.Child.prototype = {

    get: function(key) {
      return localStorage.getItem(key);
    },

    set: function(key, value, options) {
      return localStorage.setItem(key, value);
    },

    unset: function(key) {
      return localStorage.removeItem(key);
    },

    _listen: function() {
      var self = this;
      support.on(window, 'message', function(evt) {
        if (evt.origin == self.parentOrigin) {
          self._receiveMessage(JSON.parse(evt.data));
        }
      });

      var target = support.storageEventTarget;
      support.on(target, 'storage', function(evt) {
        console.log('storage evt', evt);
      });
    },

    _fireCallback: function(id, result) {
      var params = {
        type: 'callback',
        id: id,
        args: [result]
      };

      var message = JSON.stringify(params);
      this.parent.postMessage(message, this.parentOrigin);
    },

    _receiveMessage: function(message) {
      var id = message.id,
          method = message.method,
          args = message.args || [];

      if (!method || !this[method])
        return;

      var result = this[method].apply(this, args);

      if (id !== undefined && id !== null) this._fireCallback(id, result);
    }

  };

  return IFS;

}));
<commit_msg>Style pts<commit_after>/*
 * IFrameStorage
 *
 * Persist data from any domain.
 * Targets modern browsers, IE8+
*/

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['domready'], factory);
  } else {
    root.IFS = factory(root.domready);
  }
}(this, function() {

  // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
  function has(object, property){
    var t = typeof object[property];
    return t == 'function' || (!!(t == 'object' && object[property])) || t == 'unknown';
  }

  var support = {
    storageEventTarget: ('onstorage' in document ? document : window)
  };

  if (has(window, 'addEventListener')) {
    support.on = function(target, name, callback) {
      target.addEventListener(name, callback, false);
    }
    support.off = function(target, name, callback) {
      target.removeEventListener(name, callback, false);
    }
  } else if (has(window, 'attachEvent')) {
    support.on = function(object, name, callback) {
      object.attachEvent('on' + name, callback);
    }
    support.off = function(object, name, callback) {
      object.detachEvent('on' + name, callback);
    }
  }

  var IFS = {};

  IFS.Parent = function(childOrigin, path, name, callback) {
    this.childOrigin = childOrigin;
    this.childUri = childOrigin + path;
    this.name = name;
    this.iframe = this._createIframe(this.childUri, this.name, callback);

    this._counter = 0;
    this._queue = {};

    this._listen();
  };

  IFS.Parent.prototype = {

    get: function(key, callback) {
      this._callMethod('get', [key], callback);
    },

    set: function(key, value, options, callback) {
      if (typeof options === 'function') {
        callback = options;
        options = {};
      }

      this._callMethod('set', [key, value, options], callback);
    },

    unset: function(key, callback) {
      this._callMethod('unset', [key], callback);
    },

    _listen: function() {
      var self = this;
      support.on(window, 'message', function(evt) {
        if (evt.origin == self.childOrigin) {
          self._receiveMessage(JSON.parse(evt.data));
        }
      });
    },

    _addCall: function(callback) {
      this._queue[++this._counter] = callback;
      return this._counter;
    },

    _callMethod: function(method, args, callback) {
      var params = {
        method: method,
        args: args
      };
      if (typeof callback === 'function') {
        params.id = this._addCall(callback);
      }

      var message = JSON.stringify(params);
      this.iframe.contentWindow.postMessage(message, this.childOrigin);
    },

    _receiveMessage: function(message) {
      switch (message.type) {
        case 'callback':
          this._queue[message.id].apply(this, message.args);
          this._queue[message.id] = null;
          break;
      }
    },

    _createIframe: function(uri, name, callback) {
      var iframe = document.createElement('iframe');
      iframe.id = 'ifs_' + name;
      iframe.name = 'ifs_' + name;
      iframe.style.position = 'absolute';
      iframe.style.top = '-2000px';
      iframe.style.left = '0px';
      iframe.src = uri;
      iframe.border = iframe.frameBorder = 0;
      iframe.allowTransparency = true;

      support.on(iframe, 'load', callback);

      document.body.appendChild(iframe);

      return iframe;
    }

  };

  IFS.Child = function(parentOrigin) {
    this.parent = window.parent;
    this.parentOrigin = parentOrigin;

    this._listen();
  };

  IFS.Child.prototype = {

    get: function(key) {
      return localStorage.getItem(key);
    },

    set: function(key, value, options) {
      return localStorage.setItem(key, value);
    },

    unset: function(key) {
      return localStorage.removeItem(key);
    },

    _listen: function() {
      var self = this;
      support.on(window, 'message', function(evt) {
        if (evt.origin == self.parentOrigin) {
          self._receiveMessage(JSON.parse(evt.data));
        }
      });

      var target = support.storageEventTarget;
      support.on(target, 'storage', function(evt) {
        console.log('storage evt', evt);
      });
    },

    _fireCallback: function(id, result) {
      var params = {
        type: 'callback',
        id: id,
        args: [result]
      };

      var message = JSON.stringify(params);
      this.parent.postMessage(message, this.parentOrigin);
    },

    _receiveMessage: function(message) {
      var id = message.id,
          method = message.method,
          args = message.args || [];

      if (!method || !this[method])
        return;

      var result = this[method].apply(this, args);

      if (id !== undefined && id !== null) this._fireCallback(id, result);
    }

  };

  return IFS;

}));
<|endoftext|>