<commit_before>'use strict';

var http = require('http');
var fs = require('fs');

var hiscoresUrl = 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=';

var playerName = 'Max Deviant';

http.get(hiscoresUrl + playerName, function (res) {
    var data = [];

    res.on('data', function (chunk) {
        data.push(chunk);
    });

    res.on('end', function () {
        var stats = extractStats(data.join().split('\n'));

        fs.readFile('quests.json', 'utf8', function (err, data) {
            if (err) {
                console.log(err);

                return;
            }

            var questList = JSON.parse(data);

            var tracker = new Quests(questList, stats);

            tracker.completeQuests(['black-knights-fortress', 'cooks-assistant', 'creature-of-fenkenstrain', 'demon-slayer', 'druidic-ritual', 'dorics-quest', 'the-digsite', 'dragon-slayer', 'elemental-workshop-1', 'elemental-workshop-2', 'fishing-contest', 'goblin-diplomacy', 'imp-catcher', 'the-knights-sword', 'pirates-treasure', 'priest-in-peril', 'prince-ali-rescue', 'the-restless-ghost', 'romeo-and-juliet', 'rune-mysteries', 'sheep-shearer', 'a-souls-bane', 'tears-of-guthix', 'vampire-slayer', 'waterfall-quest', 'witchs-potion', 'nature-spirit']);

            console.log(tracker.recommendNext());

            var xp = new XP();

            console.log(xp.getLevel(stats.woodcutting.xp, 10000000));
        });
    });
}).end();

function extractStats(raw) {
    var stats = {};

    var skills = ['overall', 'attack', 'defence', 'strength', 'constitution', 'ranged', 'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing', 'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility', 'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'];

    for (var i in skills) {
        var row = raw[i].split(',');

        stats[skills[i]] = {
            rank: row[0],
            level: row[1],
            xp: row[2]
        };
    }

    return stats;
}

function grep(array, key, value) {
    for (var i in array) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
}

var XP = function () {
    this.chart = {};

    this.init = function () {
        var xp, sum, last, diff;

        for (var level = 1; level < 100; level++) {
            last = xp;
            sum = 0;

            for (var x = 1; x <= level - 1; x++) {
                sum += Math.floor(x + 300 * Math.pow(2, x / 7));
            }

            xp = Math.floor(sum / 4);

            diff = xp - last;

            this.chart[level] = {
                xp: xp,
                diff: diff
            };
        }
    };

    this.atLevel = function (level) {
        return this.chart[level].xp;
    };

    this.forLevel = function (level, currExp) {
        return this.chart[level].xp - currExp;
    };

    this.getLevel = function (currExp, gainedExp) {
        var newExp = parseInt(currExp) + parseInt(gainedExp);

        for (var i = 1; i < 100; i++) {
            if (newExp >= this.chart[i].xp) {
                continue;
            }

            return i;
        }

        return 99;
    };

    this.init();
};

var Quests = function (questList, stats) {
    this.list = questList;
    this.stats = stats;
    this.completed = {
        count: 0,
        percent: 0,
        list: {}
    };

    this.findQuest = function (questName) {
        return grep(this.list, 'slug', questName) || grep(this.list, 'name', questName);
    };

    this.findAvailable = function () {
        var available = [];

        for (var i in this.list) {
            var canDo = true;
            var skillReqs = this.list[i].requirements.skills;
            var questReqs = this.list[i].requirements.quests;

            if (this.completed.list[this.list[i].slug]) {
                continue;
            }

            if (this.hasRequirements(this.list[i].slug)) {
                available.push(this.list[i].slug);
            }
        }

        return available;
    };

    this.listRequirements = function (questName) {
        var quest = this.findQuest(questName);

        return quest.requirements;
    };

    this.hasSkillRequirements = function (questName) {
        var hasStats = true;
        var quest = this.findQuest(questName);
        var skillReqs = quest.requirements.skills;

        for (var i in skillReqs) {
            if (this.stats[i].level < skillReqs[i]) {
                hasStats = false;
            }
        }

        return hasStats;
    };

    this.hasQuestRequirements = function (questName) {
        var hasQuests = true;
        var quest = this.findQuest(questName);
        var questReqs = quest.requirements.quests;

        for (var i in questReqs) {
            if (!this.completed.list[questReqs[i]]) {
                hasQuests = false;
            }
        }

        return hasQuests;
    };

    this.hasRequirements = function (questName) {
        return this.hasSkillRequirements(questName) && this.hasQuestRequirements(questName);
    };

    this.completeQuest = function (quest) {
        this.completeQuests([quest]);
    };

    this.completeQuests = function (quests) {
        for (var i in quests) {
            this.completed.list[quests[i]] = true;
            this.completed.count++;
        }
    };

    this.getCompleted = function () {
        return {
            count: this.completed.count,
            percent: Math.round((this.completed.count / this.list.length) * 100),
            quests: Object.keys(this.completed.list)
        };
    };

    this.computeTotalRequirements = function (questName) {
        var quest = this.findQuest(questName);

        var skillReqs = quest.requirements.skills;
        var questReqs = quest.requirements.quests;

        var totalSkills = {};
        var totalQuests = [];

        for (var i in skillReqs) {
            totalSkills[i] = skillReqs[i];
        }

        for (var i in questReqs) {
            var priorReqs = this.computeTotalRequirements(questReqs[i]);

            for (var j in priorReqs) {
                if (typeof totalSkills[j] === 'undefined') {
                    totalSkills[j] = priorReqs[j];
                } else if (priorReqs[j] > totalSkills[j]) {
                    totalSkills[j] = priorReqs[j];
                }
            }
        }

        return totalSkills;
    };

    this.recommendNext = function () {
        var xp = new XP();
        var recommended = [];

        var neededExp = {};

        for (var i in this.list) {
            if (this.completed.list[this.list[i].slug]) {
                continue;
            }

            var skillReqs = this.list[i].requirements.skills;
            var total = 0;

            neededExp[this.list[i].slug] = 0;

            for (var j in skillReqs) {

                if (skillReqs[j] > this.stats[j].level) {
                    neededExp[this.list[i].slug] += xp.forLevel(skillReqs[j], this.stats[j].xp);
                }
            }
        }

        var lowest = {};

        for (var i in neededExp) {
            if (typeof lowest.xp === 'undefined' || neededExp[i] < lowest.xp) {
                lowest.quest = i;
                lowest.xp = neededExp[i];

                if (this.hasQuestRequirements(i)) {
                    recommended.push(i);
                }
            } else if (lowest.xp === neededExp[i]) {
                if (this.hasQuestRequirements(i)) {
                    recommended.push(i);
                }
            }
        }

        return recommended;
    };
};<commit_msg>Remove redundant variable<commit_after>'use strict';

var http = require('http');
var fs = require('fs');

var hiscoresUrl = 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=';

var playerName = 'Max Deviant';

http.get(hiscoresUrl + playerName, function (res) {
    var data = [];

    res.on('data', function (chunk) {
        data.push(chunk);
    });

    res.on('end', function () {
        var stats = extractStats(data.join().split('\n'));

        fs.readFile('quests.json', 'utf8', function (err, data) {
            if (err) {
                console.log(err);

                return;
            }

            var tracker = new Quests(JSON.parse(data), stats);

            tracker.completeQuests(['black-knights-fortress', 'cooks-assistant', 'creature-of-fenkenstrain', 'demon-slayer', 'druidic-ritual', 'dorics-quest', 'the-digsite', 'dragon-slayer', 'elemental-workshop-1', 'elemental-workshop-2', 'fishing-contest', 'goblin-diplomacy', 'imp-catcher', 'the-knights-sword', 'pirates-treasure', 'priest-in-peril', 'prince-ali-rescue', 'the-restless-ghost', 'romeo-and-juliet', 'rune-mysteries', 'sheep-shearer', 'a-souls-bane', 'tears-of-guthix', 'vampire-slayer', 'waterfall-quest', 'witchs-potion', 'nature-spirit']);

            console.log(tracker.recommendNext());

            var xp = new XP();

            console.log(xp.getLevel(stats.woodcutting.xp, 10000000));
        });
    });
}).end();

function extractStats(raw) {
    var stats = {};

    var skills = ['overall', 'attack', 'defence', 'strength', 'constitution', 'ranged', 'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing', 'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility', 'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'];

    for (var i in skills) {
        var row = raw[i].split(',');

        stats[skills[i]] = {
            rank: row[0],
            level: row[1],
            xp: row[2]
        };
    }

    return stats;
}

function grep(array, key, value) {
    for (var i in array) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
}

var XP = function () {
    this.chart = {};

    this.init = function () {
        var xp, sum, last, diff;

        for (var level = 1; level < 100; level++) {
            last = xp;
            sum = 0;

            for (var x = 1; x <= level - 1; x++) {
                sum += Math.floor(x + 300 * Math.pow(2, x / 7));
            }

            xp = Math.floor(sum / 4);

            diff = xp - last;

            this.chart[level] = {
                xp: xp,
                diff: diff
            };
        }
    };

    this.atLevel = function (level) {
        return this.chart[level].xp;
    };

    this.forLevel = function (level, currExp) {
        return this.chart[level].xp - currExp;
    };

    this.getLevel = function (currExp, gainedExp) {
        var newExp = parseInt(currExp) + parseInt(gainedExp);

        for (var i = 1; i < 100; i++) {
            if (newExp >= this.chart[i].xp) {
                continue;
            }

            return i;
        }

        return 99;
    };

    this.init();
};

var Quests = function (questList, stats) {
    this.list = questList;
    this.stats = stats;
    this.completed = {
        count: 0,
        percent: 0,
        list: {}
    };

    this.findQuest = function (questName) {
        return grep(this.list, 'slug', questName) || grep(this.list, 'name', questName);
    };

    this.findAvailable = function () {
        var available = [];

        for (var i in this.list) {
            var canDo = true;
            var skillReqs = this.list[i].requirements.skills;
            var questReqs = this.list[i].requirements.quests;

            if (this.completed.list[this.list[i].slug]) {
                continue;
            }

            if (this.hasRequirements(this.list[i].slug)) {
                available.push(this.list[i].slug);
            }
        }

        return available;
    };

    this.listRequirements = function (questName) {
        var quest = this.findQuest(questName);

        return quest.requirements;
    };

    this.hasSkillRequirements = function (questName) {
        var hasStats = true;
        var quest = this.findQuest(questName);
        var skillReqs = quest.requirements.skills;

        for (var i in skillReqs) {
            if (this.stats[i].level < skillReqs[i]) {
                hasStats = false;
            }
        }

        return hasStats;
    };

    this.hasQuestRequirements = function (questName) {
        var hasQuests = true;
        var quest = this.findQuest(questName);
        var questReqs = quest.requirements.quests;

        for (var i in questReqs) {
            if (!this.completed.list[questReqs[i]]) {
                hasQuests = false;
            }
        }

        return hasQuests;
    };

    this.hasRequirements = function (questName) {
        return this.hasSkillRequirements(questName) && this.hasQuestRequirements(questName);
    };

    this.completeQuest = function (quest) {
        this.completeQuests([quest]);
    };

    this.completeQuests = function (quests) {
        for (var i in quests) {
            this.completed.list[quests[i]] = true;
            this.completed.count++;
        }
    };

    this.getCompleted = function () {
        return {
            count: this.completed.count,
            percent: Math.round((this.completed.count / this.list.length) * 100),
            quests: Object.keys(this.completed.list)
        };
    };

    this.computeTotalRequirements = function (questName) {
        var quest = this.findQuest(questName);

        var skillReqs = quest.requirements.skills;
        var questReqs = quest.requirements.quests;

        var totalSkills = {};
        var totalQuests = [];

        for (var i in skillReqs) {
            totalSkills[i] = skillReqs[i];
        }

        for (var i in questReqs) {
            var priorReqs = this.computeTotalRequirements(questReqs[i]);

            for (var j in priorReqs) {
                if (typeof totalSkills[j] === 'undefined') {
                    totalSkills[j] = priorReqs[j];
                } else if (priorReqs[j] > totalSkills[j]) {
                    totalSkills[j] = priorReqs[j];
                }
            }
        }

        return totalSkills;
    };

    this.recommendNext = function () {
        var xp = new XP();
        var recommended = [];

        var neededExp = {};

        for (var i in this.list) {
            if (this.completed.list[this.list[i].slug]) {
                continue;
            }

            var skillReqs = this.list[i].requirements.skills;
            var total = 0;

            neededExp[this.list[i].slug] = 0;

            for (var j in skillReqs) {

                if (skillReqs[j] > this.stats[j].level) {
                    neededExp[this.list[i].slug] += xp.forLevel(skillReqs[j], this.stats[j].xp);
                }
            }
        }

        var lowest = {};

        for (var i in neededExp) {
            if (typeof lowest.xp === 'undefined' || neededExp[i] < lowest.xp) {
                lowest.quest = i;
                lowest.xp = neededExp[i];

                if (this.hasQuestRequirements(i)) {
                    recommended.push(i);
                }
            } else if (lowest.xp === neededExp[i]) {
                if (this.hasQuestRequirements(i)) {
                    recommended.push(i);
                }
            }
        }

        return recommended;
    };
};<|endoftext|>


<commit_before>'use strict';
$(document).ready(function() {

  var message = {

    /**
     * message template.
     */
    $template: $('#message-template'),

    /**
     * config.
     */
    config: {

      /**
       * hearbeat timer.
       */
      timer: null,

      /**
       * interval (second).
       */
      interval: 5,

      /**
       * heartbeat function.
       */
      heartbeatTarget: null
    },

    /**
     * initialize.
     */
    initialize: function() {
      // common.
      $('.message-created-at').timeago();

      // for message/smtChain page.
      if ($('body').is('#page_message_smtChain')) {
        // message date line. - show or hide.
        this.updateTimeInfo();

        this.config.heartbeatTarget = this.addNewMessages.bind(false);

        this.addNewMessages(true).always(function() {
          // set timer.
          message.startHeartbeatTimer();
        });

        $('#do-submit').click(function() {
          message.clickDoSubmitButton();
        });

        $('#more').click(function() {
          message.clickMoreButton();
        });

        $('#message_image').change(function() {
          message.imageChangeValidator.call(this);
        });
      }

      // for message/receiveList page.
      if ($('body').is('#page_message_smtList')) {
        this.config.heartbeatTarget = this.updateNewRecentList.bind(false);

        this.updateNewRecentList(true).always(function() {
          // set timer.
          message.startHeartbeatTimer();
        });
      }
    },

    /**
     * hide and show submit fields.
     */
    submitFilter: function() {
      $('#loading').toggle();
      $('#submit-message').toggle();
      $('#do-submit').toggle();
      $('#message_image').toggle();
    },

    /**
     * hide and show more info fields.
     */
    moreFilter: function() {
      $('#loading-more').toggle();
      $('#more').toggle();
    },

    /**
     * hide more info fields.
     */
    hideMore: function() {
      $('#loading-more').hide();
      $('#more').hide();
    },

    /**
     * show more button.
     */
    showMore: function() {
      $('#loading-more').hide();
      $('#more').show();
    },

    /**
     * click #do-submit id button.
     */
    clickDoSubmitButton: function() {

      var body = $('#submit-message').val();
      if (1 > jQuery.trim(body)) {
        return;
      }

      var
        form = $('form#send-message-form'),
        formData = this.getFormData(form);

      this.submitFilter();
      this.stopHeartbeatTimer();

      $.ajax({
        url: openpne.apiBase + "message/post.json",
        type: 'POST',
        processData: false,
        contentType: false,
        data: formData,
        dataType: 'json',
      }).always(function() {

        message.addNewMessages(true).always(function() {
          message.updateTimeInfo();
          $('#no-message').hide();
          $('#submit-message').val('');
          $('#message_image').val('');
          message.submitFilter();
          message.startHeartbeatTimer();
        });
      });
    },

    /**
     * click #more id button.
     */
    clickMoreButton: function() {

      var
        firstMessageWrapper = $('.message-wrapper:first'),
        maxId = Number(firstMessageWrapper.attr('data-message-id'));

      if (isNaN(maxId))
      {
        return false;
      }

      this.moreFilter();

      this.getMessages(maxId, false).done(function(response) {

        message.insertMessages(response.data, false);

        message.moreFilter();

        if (!response.has_more)
        {
          message.hideMore();
        }

      }).fail(function() {
        // TODO error design.
      });
    },

    /**
     * check image file name if change image data.
     */
    imageChangeValidator: function() {

      var a = $(this).prop('files');
      if(0 < a.length)
      {
        var fileType = a[0].type;
        if (null === fileType.match(/(jpeg|gif|png)/))
        {
          alert('ファイル形式が間違っています。');
          $(this).val('');
        }
      }
    },

    /**
     * get FromData Object. openpne apyKey and form value.
     */
    getFormData: function(form)
    {
      var
        formData = new FormData(form[0]);

      formData.append('apiKey', openpne.apiKey);
      formData.append('toMember', this.getMemberId());

      $(form.serializeArray()).each(function(i, v) {
        formData.append(v.name, v.value);
      });

      return formData;
    },

    /**
     * partner member id.
     */
    getMemberId: function() {
      var toMemberObj = $('#messageToMember');
      if (toMemberObj)
      {
        return toMemberObj.val();
      }

      return null;
    },

    /**
     * insert Message template by datas.
     * @param datas
     * @param isAddLow
     */
    insertMessages: function(datas, isAddLow) {

      if (!datas.length)
      {
        return false;
      }

      for (var i = 0; i < datas.length; i++)
      {
        this.insertMessageTemplate(datas[i], isAddLow);
      }

      this.updateTimeInfo();
    },

    /**
     * insert Message template by data.
     * @param data
     * @param isAddRow
     */
    insertMessageTemplate: function(data, isAddRow) {
      var
        template = this.$template.children().clone(),
        $photo = template.find('.photo'),
        position = data.member.id == this.getMemberId() ? 'right' : 'left';

      template
        .attr('data-message-id', data.id)
        .addClass(position)
        .addClass('show')
          .find('.time-info')
          .append(data.formatted_date)
            .parent('.time-info-wrapper')
            .attr('data-created-at-date', data.formatted_date)
          .end()
        .end()
          .find('.popover-title')
          .append(data.member.name)
        .end()
          .find('.message-body')
          .append(data.body)
        .end()
          .find('.message-created-at')
          .addClass(position)
          .attr('title', data.created_at)
          .timeago()
        .end();

      // has one image data from api. this opMessagePlugin version.
      if (data.image_path && data.image_tag) {
        $photo.append('
' + data.image_tag + '
');
      } else {
        $photo.remove();
      }

      if (isAddRow) {
        $('#message-wrapper-parent').append(template);
      } else {
        $('#message-wrapper-parent').prepend(template);
      }
    },

    /**
     * update recent list message data.
     * @param datas
     */
    updateRecentListMessageTemplate: function(datas) {
      var maxId = Number($('#messageKeyId').val());

      if (isNaN(maxId))
      {
        maxId = 0;
      }

      $(datas).each(function(i, data) {
        var
          template = message.$template.children().clone(),
          $oldHtml = $('div[data-member-id="' + data.member.id + '"]');

        if ($oldHtml.is('.message-wrapper')) {
          $oldHtml.remove();
        }

        if (maxId < data.id)
        {
          maxId = data.id;
        }

        template
          .attr('data-member-id', data.member.id)
          .addClass('show')
            .find('.memberIcon')
            .append('')
          .end()
            .find('.memberProfile')
            .append('' + data.member.name + '')
          .end()
            .find('.lastMessage')
            .append('' + data.summary + '')
          .end()
            .find('.message-created-at')
            .attr('title', data.created_at)
          .end();

        if (typeof data.is_read == 'boolean' && !data.is_read)
        {
          template.addClass('message-unread');
        }

         $('#message-wrapper-parent').prepend(template);
      });

      $('.message-created-at').timeago();
      $('#messageKeyId').val(maxId);
    },

    /**
     * update Time info line.
     */
    updateTimeInfo: function() {
      var
        timeInfoWrapper = $('#message-wrapper-parent').find('.time-info-wrapper'),
        currentDate,
        baseDate;

      for (var i = 0; i < timeInfoWrapper.length; i++) {
        currentDate = timeInfoWrapper.eq(i).attr('data-created-at-date');
        if (currentDate) {
          if (currentDate === baseDate) {
            timeInfoWrapper.eq(i).hide();
          } else {
            timeInfoWrapper.eq(i).show();
          }

          baseDate = currentDate;
        }
      }
    },

    /**
     * start heartbeat timer.
     */
    startHeartbeatTimer: function() {
      this.config.timer = setTimeout(this.config.heartbeatTarget, this.config.interval * 1000);
    },

    /**
     * stop heartbeat timer.
     */
    stopHeartbeatTimer: function() {
      clearTimeout(this.config.timer);
    },

    /**
     * insert Message template by data.
     * @param keyId
     * @param isAddLow
     */
    getMessages: function(keyId, isAddLow) {

      var dfd = $.Deferred();

      $.ajax({
        url: openpne.apiBase + "message/search.json",
        type: 'POST',
        data: {
          apiKey: openpne.apiKey,
          memberId: Number(this.getMemberId()),
          maxId: Number(keyId),
          isAddLow: Number(isAddLow)
        },
        dataType: 'json',
        success: function(response) {
          dfd.resolve(response);
        },
        error: function(e) {
          dfd.reject();
        }
      });

      return dfd.promise();
    },

    /**
     * insert Message template by data.
     * @param keyId
     */
    getRecentList: function(keyId) {

      var dfd = $.Deferred();

      $.ajax({
        url: openpne.apiBase + "message/recentList.json",
        type: 'POST',
        data: {
          apiKey: openpne.apiKey,
          keyId: Number(keyId),
        },
        dataType: 'json',
        success: function(response) {
          dfd.resolve(response);
        },
        error: function(e) {
          dfd.reject();
        }
      });

      return dfd.promise();
    },

    /**
     * add new messages.
     */
    addNewMessages: function(notUseHeartbeat) {

      var
        lastMessageWrapper = $('#message-wrapper-parent').find('.message-wrapper:last'),
        minId = Number(lastMessageWrapper.attr('data-message-id')),
        dfd = $.Deferred();

      if (isNaN(minId))
      {
        minId = -1;
      }

      message.getMessages(minId, true).done(function(response) {

        $('#first-loading').hide();
        message.insertMessages(response.data, true);
        dfd.resolve();

        if (!$('#message-wrapper-parent').find('.message-wrapper').length) {
          message.hideMore();
          $('#no-message').show();

          return false;
        }

        $('#no-message').hide();

        if (minId == -1 && response.has_more) {
          message.showMore();
        }

      }).always(function() {

        if (!notUseHeartbeat)
        {
          message.startHeartbeatTimer();
        }

      }).fail(function() {
        dfd.reject();
        // TODO error design.
      });

      return dfd.promise();
    },

    /**
     * update new recent list.
     */
    updateNewRecentList: function(notUseHeartbeat) {

      var
        keyId = Number($('#messageKeyId').val()),
        dfd = $.Deferred();

      if (isNaN(keyId))
      {
        keyId = 0;
      }

      message.getRecentList(keyId).done(function(response) {

        $('#first-loading').hide();
        message.updateRecentListMessageTemplate(response.data);
        dfd.resolve();

        if (!$('#message-wrapper-parent').find('.message-wrapper').length) {
          $('#no-message').show();

          return false;
        }

        $('#no-message').hide();

      }).always(function() {

        if (!notUseHeartbeat)
        {
          message.startHeartbeatTimer();
        }

      }).fail(function() {
        dfd.reject();
        // TODO error design.
      });

      return dfd.promise();
    }
  };

  message.initialize();
});
<commit_msg>(refs #3541) add pager Javascript to smtList page.<commit_after>'use strict';
$(document).ready(function() {

  var message = {

    /**
     * message template.
     */
    $template: $('#message-template'),

    /**
     * config.
     */
    config: {

      /**
       * hearbeat timer.
       */
      timer: null,

      /**
       * interval (second).
       */
      interval: 5,

      /**
       * heartbeat function.
       */
      heartbeatTarget: null
    },

    /**
     * initialize.
     */
    initialize: function() {
      // common.
      $('.message-created-at').timeago();

      // for message/smtChain page.
      if ($('body').is('#page_message_smtChain')) {
        // message date line. - show or hide.
        this.updateTimeInfo();

        this.config.heartbeatTarget = this.addNewMessages.bind(false);

        this.addNewMessages(true).always(function() {
          // set timer.
          message.startHeartbeatTimer();
        });

        $('#do-submit').click(function() {
          message.clickDoSubmitButton();
        });

        $('#more').click(function() {
          message.clickMoreButton();
        });

        $('#message_image').change(function() {
          message.imageChangeValidator.call(this);
        });
      }

      // for message/receiveList page.
      if ($('body').is('#page_message_smtList')) {
        this.config.heartbeatTarget = this.updateNewRecentList.bind(false);

        this.updateNewRecentList(true).always(function() {
          // set timer.
          message.startHeartbeatTimer();
        });

        $('#messagePrevLink').click(function() {
          message.clickPrevButton();
        });

        $('#messageNextLink').click(function() {
          message.clickNextButton();
        });
      }
    },

    /**
     * hide and show submit fields.
     */
    submitFilter: function() {
      $('#loading').toggle();
      $('#submit-message').toggle();
      $('#do-submit').toggle();
      $('#message_image').toggle();
    },

    /**
     * hide and show more info fields.
     */
    moreFilter: function() {
      $('#loading-more').toggle();
      $('#more').toggle();
    },

    /**
     * hide more info fields.
     */
    hideMore: function() {
      $('#loading-more').hide();
      $('#more').hide();
    },

    /**
     * show more button.
     */
    showMore: function() {
      $('#loading-more').hide();
      $('#more').show();
    },

    /**
     * click #do-submit id button.
     */
    clickDoSubmitButton: function() {

      var body = $('#submit-message').val();
      if (1 > jQuery.trim(body)) {
        return;
      }

      var
        form = $('form#send-message-form'),
        formData = this.getFormData(form);

      this.submitFilter();
      this.stopHeartbeatTimer();

      $.ajax({
        url: openpne.apiBase + "message/post.json",
        type: 'POST',
        processData: false,
        contentType: false,
        data: formData,
        dataType: 'json',
      }).always(function() {

        message.addNewMessages(true).always(function() {
          message.updateTimeInfo();
          $('#no-message').hide();
          $('#submit-message').val('');
          $('#message_image').val('');
          message.submitFilter();
          message.startHeartbeatTimer();
        });
      });
    },

    /**
     * click #more id button.
     */
    clickMoreButton: function() {

      var
        firstMessageWrapper = $('.message-wrapper:first'),
        maxId = Number(firstMessageWrapper.attr('data-message-id'));

      if (isNaN(maxId))
      {
        return false;
      }

      this.moreFilter();

      this.getMessages(maxId, false).done(function(response) {

        message.insertMessages(response.data, false);

        message.moreFilter();

        if (!response.has_more)
        {
          message.hideMore();
        }

      }).fail(function() {
        // TODO error design.
      });
    },

    /**
     * click #messagePrevLink id button.
     */
    clickPrevButton: function() {
      var prevPage = Number($('#prevPage').val());

      this.clickPagerLink(prevPage);
    },

    /**
     * click #messageNextLink id button.
     */
    clickNextButton: function() {
      var nextPage = Number($('#nextPage').val());

      this.clickPagerLink(nextPage);
    },

    clickPagerLink: function(page) {

      if (isNaN(page) || page === 0)
      {
        return;
      }

      this.hidePager();
      $('#message-wrapper-parent').find('.message-wrapper').remove();
      $('#messageKeyId').val(0);
      $('#memberIds').val('');

      $('#first-loading').show();
      this.stopHeartbeatTimer();

      $('#page').val(page);

      this.updateNewRecentList(true).always(function() {
        // set timer.
        message.startHeartbeatTimer();
      });
    },

    /**
     * check image file name if change image data.
     */
    imageChangeValidator: function() {

      var a = $(this).prop('files');
      if(0 < a.length)
      {
        var fileType = a[0].type;
        if (null === fileType.match(/(jpeg|gif|png)/))
        {
          alert('ファイル形式が間違っています。');
          $(this).val('');
        }
      }
    },

    /**
     * get FromData Object. openpne apyKey and form value.
     */
    getFormData: function(form)
    {
      var
        formData = new FormData(form[0]);

      formData.append('apiKey', openpne.apiKey);
      formData.append('toMember', this.getMemberId());

      $(form.serializeArray()).each(function(i, v) {
        formData.append(v.name, v.value);
      });

      return formData;
    },

    /**
     * partner member id.
     */
    getMemberId: function() {
      var toMemberObj = $('#messageToMember');
      if (toMemberObj)
      {
        return toMemberObj.val();
      }

      return null;
    },

    /**
     * insert Message template by datas.
     * @param datas
     * @param isAddLow
     */
    insertMessages: function(datas, isAddLow) {

      if (!datas.length)
      {
        return false;
      }

      for (var i = 0; i < datas.length; i++)
      {
        this.insertMessageTemplate(datas[i], isAddLow);
      }

      this.updateTimeInfo();
    },

    /**
     * insert Message template by data.
     * @param data
     * @param isAddRow
     */
    insertMessageTemplate: function(data, isAddRow) {
      var
        template = this.$template.children().clone(),
        $photo = template.find('.photo'),
        position = data.member.id == this.getMemberId() ? 'right' : 'left';

      template
        .attr('data-message-id', data.id)
        .addClass(position)
        .addClass('show')
          .find('.time-info')
          .append(data.formatted_date)
            .parent('.time-info-wrapper')
            .attr('data-created-at-date', data.formatted_date)
          .end()
        .end()
          .find('.popover-title')
          .append(data.member.name)
        .end()
          .find('.message-body')
          .append(data.body)
        .end()
          .find('.message-created-at')
          .addClass(position)
          .attr('title', data.created_at)
          .timeago()
        .end();

      // has one image data from api. this opMessagePlugin version.
      if (data.image_path && data.image_tag) {
        $photo.append('
' + data.image_tag + '
');
      } else {
        $photo.remove();
      }

      if (isAddRow) {
        $('#message-wrapper-parent').append(template);
      } else {
        $('#message-wrapper-parent').prepend(template);
      }
    },

    /**
     * update recent list message data.
     * @param datas
     */
    updateRecentListMessageTemplate: function(datas) {
      var maxId = Number($('#messageKeyId').val());

      if (isNaN(maxId))
      {
        maxId = 0;
      }

      $(datas).each(function(i, data) {
        var
          template = message.$template.children().clone(),
          $oldHtml = $('div[data-member-id="' + data.member.id + '"]');

        if ($oldHtml.is('.message-wrapper')) {
          $oldHtml.remove();
        }

        if (maxId < data.id)
        {
          maxId = data.id;
        }

        template
          .attr('data-member-id', data.member.id)
          .addClass('show')
            .find('.memberIcon')
            .append('')
          .end()
            .find('.memberProfile')
            .append('' + data.member.name + '')
          .end()
            .find('.lastMessage')
            .append('' + data.summary + '')
          .end()
            .find('.message-created-at')
            .attr('title', data.created_at)
          .end();

        if (typeof data.is_read == 'boolean' && !data.is_read)
        {
          template.addClass('message-unread');
        }

         $('#message-wrapper-parent').prepend(template);
      });

      $('.message-created-at').timeago();
      $('#messageKeyId').val(maxId);
    },

    /**
     * update recent list pagenation.
     */
    updatePager: function(response) {

      $('#page').val(response.page);

      if (response.previousPage)
      {
        $('#prevPage').val(response.previousPage);
        $('#messagePrevLink').show();
      }

      if (response.nextPage)
      {
        $('#nextPage').val(response.nextPage);
        $('#messageNextLink').show();
      }

      if (response.previousPage || response.nextPage)
      {
        $('.pager').show();
      }
    },

    /**
     * hide pagenation.
     */
    hidePager: function()
    {
      $('#messagePrevLink').hide();
      $('#messageNextLink').hide();
      $('.pager').hide();

      $('#nextPage').val('');
      $('#prevPage').val('');
      $('#page').val('');
    },

    /**
     * update Time info line.
     */
    updateTimeInfo: function() {
      var
        timeInfoWrapper = $('#message-wrapper-parent').find('.time-info-wrapper'),
        currentDate,
        baseDate;

      for (var i = 0; i < timeInfoWrapper.length; i++) {
        currentDate = timeInfoWrapper.eq(i).attr('data-created-at-date');
        if (currentDate) {
          if (currentDate === baseDate) {
            timeInfoWrapper.eq(i).hide();
          } else {
            timeInfoWrapper.eq(i).show();
          }

          baseDate = currentDate;
        }
      }
    },

    /**
     * start heartbeat timer.
     */
    startHeartbeatTimer: function() {
      this.config.timer = setTimeout(this.config.heartbeatTarget, this.config.interval * 1000);
    },

    /**
     * stop heartbeat timer.
     */
    stopHeartbeatTimer: function() {
      clearTimeout(this.config.timer);
    },

    /**
     * insert Message template by data.
     * @param keyId
     * @param isAddLow
     */
    getMessages: function(keyId, isAddLow) {

      var dfd = $.Deferred();

      $.ajax({
        url: openpne.apiBase + "message/search.json",
        type: 'POST',
        data: {
          apiKey: openpne.apiKey,
          memberId: Number(this.getMemberId()),
          maxId: Number(keyId),
          isAddLow: Number(isAddLow)
        },
        dataType: 'json',
        success: function(response) {
          dfd.resolve(response);
        },
        error: function(e) {
          dfd.reject();
        }
      });

      return dfd.promise();
    },

    /**
     * insert Message template by data.
     * @param keyId
     */
    getRecentList: function(keyId, page, memberIds) {

      var dfd = $.Deferred();

      $.ajax({
        url: openpne.apiBase + "message/recentList.json",
        type: 'POST',
        data: {
          apiKey: openpne.apiKey,
          keyId: Number(keyId),
          page: Number(page),
          memberIds: memberIds,
        },
        dataType: 'json',
        success: function(response) {
          dfd.resolve(response);
        },
        error: function(e) {
          dfd.reject();
        }
      });

      return dfd.promise();
    },

    /**
     * add new messages.
     */
    addNewMessages: function(notUseHeartbeat) {

      var
        lastMessageWrapper = $('#message-wrapper-parent').find('.message-wrapper:last'),
        minId = Number(lastMessageWrapper.attr('data-message-id')),
        dfd = $.Deferred();

      if (isNaN(minId))
      {
        minId = -1;
      }

      message.getMessages(minId, true).done(function(response) {

        $('#first-loading').hide();
        message.insertMessages(response.data, true);
        dfd.resolve();

        if (!$('#message-wrapper-parent').find('.message-wrapper').length) {
          message.hideMore();
          $('#no-message').show();

          return false;
        }

        $('#no-message').hide();

        if (minId == -1 && response.has_more) {
          message.showMore();
        }

      }).always(function() {

        if (!notUseHeartbeat)
        {
          message.startHeartbeatTimer();
        }

      }).fail(function() {
        dfd.reject();
        // TODO error design.
      });

      return dfd.promise();
    },

    /**
     * update new recent list.
     */
    updateNewRecentList: function(notUseHeartbeat) {

      var
        keyId = Number($('#messageKeyId').val()),
        page = Number($('#page').val()),
        memberIds = $('#memberIds').val(),
        dfd = $.Deferred();

      if (isNaN(keyId))
      {
        keyId = 0;
      }

      if (isNaN(page))
      {
        page = 1;
      }

      message.getRecentList(keyId, page, memberIds).done(function(response) {

        $('#first-loading').hide();

        if (response.memberIds.length) {
          $('#memberIds').val(response.memberIds);
        }

        message.updatePager(response);
        message.updateRecentListMessageTemplate(response.data);
        dfd.resolve();

        if (!$('#message-wrapper-parent').find('.message-wrapper').length) {
          $('#no-message').show();

          return false;
        }

        $('#no-message').hide();

      }).always(function() {

        if (!notUseHeartbeat)
        {
          message.startHeartbeatTimer();
        }

      }).fail(function() {
        dfd.reject();
        // TODO error design.
      });

      return dfd.promise();
    }
  };

  message.initialize();
});
<|endoftext|>


<commit_before>"use strict";
var Benchmark = require('benchmark');
var util = require("./benchmarkutil.js");

function logme(x) {
    console.log(x);
}

var sumup = function(array) {
  var answer = 0;
  for (var i = 0; i < array.length; i++) {
    answer = answer + array[i];
  }
  return answer;
}
var typedsumup = function(array) {
  var answer = 0|0;
  var c = array.length |0;
  for (var i = 0|0; i < c; i++) {
    answer += array[i]|0;
  }
  return answer;
}

var sumupof = function(array) {
  var answer = 0;
  for (var i of array) {
    answer += i;
  }
  return answer;
}

var sumupnol = function(array) {
  var answer = 0;
  var ml = array.length
  for (var i = 0; i < ml; i++) {
    answer = answer + array[i];
  }
  return answer;
}

var backsumup = function(array) {
  var answer = 0;
  if(array.length == 0) return answer;
  for(var i = array.length - 1; i !=0 ; i--) {
      answer = answer + array[i];
  }
  return answer;
}

function Bench() {
    logme("starting benchmark");
    var suite = new Benchmark.Suite();
    var length = 128;

    var a1 = new Uint32Array(length);
    var a2 = new Array(length);

    // add tests
    var ms = suite.add('sum over Uint32Array (typed)',function() {return typedsumup(a1);} )
    .add('sum over Uint32Array',function() {return sumup(a1);} )
    .add('reduce over Uint32Array (required recent v8)', function() {return a1.reduce( function(total, num){ return total + num }, 0);})
    .add('sum over Uint32Array using of ',function() {return sumupof(a1);} )
    .add('sum over Array',function() {return sumup(a2);} )
    .add('reduce over Array', function() {return a2.reduce( function(total, num){ return total + num }, 0);})
    .add('sum over Uint32Array (no length)',function() {return sumupnol(a1);} )
    .add('sum over Array (no length)',function() {return sumupnol(a2);} )
    .add('backward sum over Uint32Array',function() {return backsumup(a1);} )
    .add('backward sum over Array',function() {return backsumup(a2);} )
    .on('setup', function() {
        for(var i = 0; i < length; i++) {
            a1[i] = i;
            a2[i] = i;
        }
    })
    // add listeners
    .on('cycle', function(event) {
        logme(String(event.target));
    })
    .on('complete', function() {
       var tps = this.filter('fastest').pluck('hz')[0];
       var intpers = tps * length / 1000000000.0 ;
       logme('Fastest is ' + this.filter('fastest').pluck('name')+' at '+intpers.toFixed(3)+' billions int. per s');
    })
    // run async
    .run({ 'async': false });
}

var main = function() {
    Bench();
}

if (require.main === module) {
    util.describeme();
    main();
}
<commit_msg>Saving...<commit_after>"use strict";
var Benchmark = require('benchmark');
var util = require("./benchmarkutil.js");

function logme(x) {
    console.log(x);
}

var sumup = function(array) {
  var answer = 0;
  for (var i = 0; i < array.length; i++) {
    answer = answer + array[i];
  }
  return answer;
}
var typedsumup = function(array) {
  var answer = 0|0;
  var c = array.length |0;
  for (var i = 0|0; i < c; i++) {
    answer += array[i]|0;
  }
  return answer;
}

var typedsumup2 = function(array) {
  var answer = 0|0;
  var c = array.length |0;
  for (var i = 0|0; i < c; i+=2) {
    answer += array[i]|0;
    answer += array[i+1]|0;

  }
  for (; i < c; i++) {
    answer += array[i]|0;
  }
  return answer;
}

var typedsumup4 = function(array) {
  var answer = 0|0;
  var c = array.length |0;
  for (var i = 0|0; i < c; i+=4) {
    answer += array[i]|0;
    answer += array[i+1]|0;
    answer += array[i+2]|0;
    answer += array[i+3]|0;

  }
  for (; i < c; i++) {
    answer += array[i]|0;
  }
  return answer;
}

var typedsumup8 = function(array) {
  var answer = 0|0;
  var c = array.length |0;
  for (var i = 0|0; i < c; i+=8) {
    answer += array[i]|0;
    answer += array[i+1]|0;
    answer += array[i+2]|0;
    answer += array[i+3]|0;
    answer += array[i+4]|0;
    answer += array[i+5]|0;
    answer += array[i+6]|0;
    answer += array[i+7]|0;

  }
  for (; i < c; i++) {
    answer += array[i]|0;
  }
  return answer;
}

var typedsumup16 = function(array) {
  var answer = 0|0;
  var c = array.length |0;
  for (var i = 0|0; i < c; i+=16) {
    answer += array[i]|0;
    answer += array[i+1]|0;
    answer += array[i+2]|0;
    answer += array[i+3]|0;
    answer += array[i+4]|0;
    answer += array[i+5]|0;
    answer += array[i+6]|0;
    answer += array[i+7]|0;
    answer += array[i+8]|0;
    answer += array[i+9]|0;
    answer += array[i+10]|0;
    answer += array[i+11]|0;
    answer += array[i+12]|0;
    answer += array[i+13]|0;
    answer += array[i+14]|0;
    answer += array[i+15]|0;

  }
  for (; i < c; i++) {
    answer += array[i]|0;
  }
  return answer;
}

var sumupof = function(array) {
  var answer = 0;
  for (var i of array) {
    answer += i;
  }
  return answer;
}

var sumupnol = function(array) {
  var answer = 0;
  var ml = array.length
  for (var i = 0; i < ml; i++) {
    answer = answer + array[i];
  }
  return answer;
}

var backsumup = function(array) {
  var answer = 0;
  if(array.length == 0) return answer;
  for(var i = array.length - 1; i !=0 ; i--) {
      answer = answer + array[i];
  }
  return answer;
}

function Bench() {
    logme("starting benchmark");
    var suite = new Benchmark.Suite();
    var length = 128;

    var a1 = new Uint32Array(length);
    var a2 = new Array(length);

    // add tests
    var ms = suite.add('sum over Uint32Array (typed)',function() {return typedsumup(a1);} )
    .add('sum over Uint32Array (typed,unrolled 2)',function() {return typedsumup8(a1);} )
    .add('sum over Uint32Array (typed,unrolled 4)',function() {return typedsumup8(a1);} )
    .add('sum over Uint32Array (typed,unrolled 8)',function() {return typedsumup8(a1);} )
    .add('sum over Uint32Array (typed,unrolled 16)',function() {return typedsumup16(a1);} )
    .add('sum over Uint32Array',function() {return sumup(a1);} )
    .add('reduce over Uint32Array (required recent v8)', function() {return a1.reduce( function(total, num){ return total + num }, 0);})
    .add('sum over Uint32Array using of ',function() {return sumupof(a1);} )
    .add('sum over Array',function() {return sumup(a2);} )
    .add('reduce over Array', function() {return a2.reduce( function(total, num){ return total + num }, 0);})
    .add('sum over Uint32Array (no length)',function() {return sumupnol(a1);} )
    .add('sum over Array (no length)',function() {return sumupnol(a2);} )
    .add('backward sum over Uint32Array',function() {return backsumup(a1);} )
    .add('backward sum over Array',function() {return backsumup(a2);} )
    .on('setup', function() {
        for(var i = 0; i < length; i++) {
            a1[i] = i;
            a2[i] = i;
        }
    })
    // add listeners
    .on('cycle', function(event) {
        logme(String(event.target));
    })
    .on('complete', function() {
       var tps = this.filter('fastest').pluck('hz')[0];
       var intpers = tps * length / 1000000000.0 ;
       logme('Fastest is ' + this.filter('fastest').pluck('name')+' at '+intpers.toFixed(3)+' billions int. per s');
    })
    // run async
    .run({ 'async': false });
}

var main = function() {
    Bench();
}

if (require.main === module) {
    util.describeme();
    main();
}
<|endoftext|>


<commit_before>const removeComments = (postId, knex) => {
  return knex('comments').where('post_id', postId).pluck('id')
  .then(ids => {
    if (ids.length === 0) return
    return knex('comments_tags').where('comment_id', 'in', ids).del()
    .then(() => knex('comments').where('id', 'in', ids).del())
  })
}

export const removePost = postId => {
  return bookshelf.transaction(trx => {
    const remove = table =>
      trx(table).where('post_id', postId).del()

    const unset = (table, col = 'post_id') =>
      trx(table).where(col, postId).update({[col]: null})

    return Promise.all([
      removeComments(postId, trx),
      remove('follows'),
      remove('user_post_relevance'),
      remove('posts_tags'),
      remove('communities_posts'),
      unset('posts', 'parent_post_id')
    ])
    .then(() => trx('posts').where('id', postId).del())
  })
}
<commit_msg>clean up posts_users when deleting a user<commit_after>const removeComments = (postId, knex) => {
  return knex('comments').where('post_id', postId).pluck('id')
  .then(ids => {
    if (ids.length === 0) return
    return knex('comments_tags').where('comment_id', 'in', ids).del()
    .then(() => knex('comments').where('id', 'in', ids).del())
  })
}

export const removePost = postId => {
  return bookshelf.transaction(trx => {
    const remove = table =>
      trx(table).where('post_id', postId).del()

    const unset = (table, col = 'post_id') =>
      trx(table).where(col, postId).update({[col]: null})

    return Promise.all([
      removeComments(postId, trx),
      remove('follows'),
      remove('user_post_relevance'),
      remove('posts_tags'),
      remove('posts_users'),
      remove('communities_posts'),
      unset('posts', 'parent_post_id')
    ])
    .then(() => trx('posts').where('id', postId).del())
  })
}
<|endoftext|>


<commit_before>/**
 * User: mbrunot
 * Date: 21/10/11
 * Time: 10:01
 * jQuery plugin
 */

(function($){
  $.linecom = function(el, options){
    var base = this;

    base.$el          = $(el);
    base.el           = el;
    base.visibled     = false;
    base.commented    = false;
    base.formVisibled = false;
    base.bloc         = null;

    base.$el.data("linecom", base);

    base.init = function(){
      base.options = $.extend({},$.linecom.defaultOptions, options);

      // initialize visibility
      base.visibled = base.$el.hasClass('disabled');

      // initialize commented status
      base.commented = base.$el.hasClass('commented');

      // initialize bloc
      if (base.visibled) {
        base.bloc = base.$el
          .parent('td')
          .parent('tr')
          .next()
        ;

        base.bindingBloc();
      }

      base.$el.bind('click', function(event) {
        base.displayLineCommentForm();
      });
    };

    base.bindingBloc = function() {

      $('.close', base.bloc).bind('click', function() {
        base.closeForm();
      });

      $('form', base.bloc).bind('submit', function(e) {
        e.preventDefault();
        base.submitForm(this);
      });

      $('.add_comment', base.bloc).bind('click', function(event) {
        event.preventDefault();
        $('.comment_add', base.bloc).hide();
        $('.comment_form', base.bloc).show();
      });

      $('.delete', base.bloc).bind('click', function(event) {
        event.preventDefault();
        base.deleteComment(this);
      });
    };

    base.displayLineCommentForm = function() {
      $.ajax({
        type: "GET",
        url: base.$el.attr('data'),
        success: function(json) {
          // in cases where the element is visible
          if (base.visibled) {
            var tmpBaseBloc = base.bloc;
            base.bloc = $(json.html);
            tmpBaseBloc.after(base.bloc);
            tmpBaseBloc.remove();
          }
          // in cases where the element is invisible
          else {
            base.bloc = base.$el
              .parent('td')
              .parent('tr')
              .after($(json.html))
              .next()
            ;

            base.visibled = !base.visibled;
            base.formVisibled = true;
            base.$el
              .addClass('disabled')
              .removeClass('enabled')
            ;
          }

          base.bindingBloc();
        }
      });
    };

    base.submitForm = function(form) {
      if (form.comment_value.value == '')
      {
        $(form.comment_value).css({'background-color': '#FDD', 'border': '1px solid #FAA'});
        $(form.comment_value).bind('click', function() {
          $(this).css({'background-color': '#FFF', 'border': '1px solid #DEDEDE'});
        });
      }
      else
      {
        $.ajax({
          type: "POST",
          url: $(form).attr('action'),
          data: $(form).serialize(),
          success: function(json) {
            var tmpBaseBloc = base.bloc;
            base.bloc = $(json.html);
            tmpBaseBloc.after(base.bloc);
            tmpBaseBloc.remove();
            base.commented = true;

            base.bindingBloc();
          }
        });
      }

      return false;
    };

    base.deleteComment = function(element) {
      if (confirm('Are you sure you want to delete this comment ?'))
      {
        $.ajax({
          type: "POST",
          url: $(element).attr('data'),
          success: function(json) {
            var tmpBaseBloc = base.bloc;
            base.bloc = $(json.html);
            tmpBaseBloc.after(base.bloc);
            tmpBaseBloc.remove();
            base.commented = true;

            base.bindingBloc();
          }
        });
      }
    };

    base.closeForm = function() {
      var commentForm = $('.comment_form', base.bloc);
      var commentContent = commentForm.find('#comment_value').val();

      if(commentContent == '' || (commentContent != '' && confirm('Are you sure you want to close this comment form ?\nYou will loose all your modification if you do.')))
      {
        if (base.commented) {
          commentForm.hide();
          $('.comment_add', base.bloc).show();
        }
        else {
          base.bloc.remove();
          base.bloc = null;
          base.visibled = false;
        }
      }
    };

    base.init();
  };

  $.linecom.defaultOptions = {
  };

  $.fn.linecom = function(options){

    $('#window').delegate('.clipboard', 'click', function(e) {
      window.prompt("Copy to clipboard: Ctrl+C, Enter", this.href);
      return false;
    });

    return this.each(function(){
      (new $.linecom(this, options));
    });
  };
})(jQuery);

$(document).ready(function() {
  $('.add_bubble').linecom();
});
<commit_msg>Auto focus on textarea when adding a comment<commit_after>/**
 * User: mbrunot
 * Date: 21/10/11
 * Time: 10:01
 * jQuery plugin
 */

(function($){
  $.linecom = function(el, options){
    var base = this;

    base.$el          = $(el);
    base.el           = el;
    base.visibled     = false;
    base.commented    = false;
    base.formVisibled = false;
    base.bloc         = null;

    base.$el.data("linecom", base);

    base.init = function(){
      base.options = $.extend({},$.linecom.defaultOptions, options);

      // initialize visibility
      base.visibled = base.$el.hasClass('disabled');

      // initialize commented status
      base.commented = base.$el.hasClass('commented');

      // initialize bloc
      if (base.visibled) {
        base.bloc = base.$el
          .parent('td')
          .parent('tr')
          .next()
        ;

        base.bindingBloc();
      }

      base.$el.bind('click', function(event) {
        base.displayLineCommentForm();
      });
    };

    base.bindingBloc = function() {

      $('.close', base.bloc).bind('click', function() {
        base.closeForm();
      });

      $('form', base.bloc).bind('submit', function(e) {
        e.preventDefault();
        base.submitForm(this);
      });

      $('.add_comment', base.bloc).bind('click', function(event) {
        event.preventDefault();
        $('.comment_add', base.bloc).hide();
        $('.comment_form', base.bloc).show();
        base.bloc.find('textarea').focus();
      });

      $('.delete', base.bloc).bind('click', function(event) {
        event.preventDefault();
        base.deleteComment(this);
      });
    };

    base.displayLineCommentForm = function() {
      $.ajax({
        type: "GET",
        url: base.$el.attr('data'),
        success: function(json) {
          // in cases where the element is visible
          if (base.visibled) {
            var tmpBaseBloc = base.bloc;
            base.bloc = $(json.html);
            tmpBaseBloc.after(base.bloc);
            tmpBaseBloc.remove();
          }
          // in cases where the element is invisible
          else {
            base.bloc = base.$el
              .parent('td')
              .parent('tr')
              .after($(json.html))
              .next()
            ;

            base.visibled = !base.visibled;
            base.formVisibled = true;
            base.$el
              .addClass('disabled')
              .removeClass('enabled')
            ;
          }

          base.bloc.find('textarea').focus();
          base.bindingBloc();
        }
      });
    };

    base.submitForm = function(form) {
      if (form.comment_value.value == '')
      {
        $(form.comment_value).css({'background-color': '#FDD', 'border': '1px solid #FAA'});
        $(form.comment_value).bind('click', function() {
          $(this).css({'background-color': '#FFF', 'border': '1px solid #DEDEDE'});
        });
      }
      else
      {
        $.ajax({
          type: "POST",
          url: $(form).attr('action'),
          data: $(form).serialize(),
          success: function(json) {
            var tmpBaseBloc = base.bloc;
            base.bloc = $(json.html);
            tmpBaseBloc.after(base.bloc);
            tmpBaseBloc.remove();
            base.commented = true;

            base.bindingBloc();
          }
        });
      }

      return false;
    };

    base.deleteComment = function(element) {
      if (confirm('Are you sure you want to delete this comment ?'))
      {
        $.ajax({
          type: "POST",
          url: $(element).attr('data'),
          success: function(json) {
            var tmpBaseBloc = base.bloc;
            base.bloc = $(json.html);
            tmpBaseBloc.after(base.bloc);
            tmpBaseBloc.remove();
            base.commented = true;

            base.bindingBloc();
          }
        });
      }
    };

    base.closeForm = function() {
      var commentForm = $('.comment_form', base.bloc);
      var commentContent = commentForm.find('#comment_value').val();

      if(commentContent == '' || (commentContent != '' && confirm('Are you sure you want to close this comment form ?\nYou will loose all your modification if you do.')))
      {
        if (base.commented) {
          commentForm.hide();
          $('.comment_add', base.bloc).show();
        }
        else {
          base.bloc.remove();
          base.bloc = null;
          base.visibled = false;
        }
      }
    };

    base.init();
  };

  $.linecom.defaultOptions = {
  };

  $.fn.linecom = function(options){

    $('#window').delegate('.clipboard', 'click', function(e) {
      window.prompt("Copy to clipboard: Ctrl+C, Enter", this.href);
      return false;
    });

    return this.each(function(){
      (new $.linecom(this, options));
    });
  };
})(jQuery);

$(document).ready(function() {
  $('.add_bubble').linecom();
});
<|endoftext|>


<commit_before>app.factory('QueryService', ['$resource', '$injector', '$q', '$filter', 'PollingService', 'DownloadService', 'TableService', 'BrowserService', function($resource, $injector, $q, $filter, PollingService, DownloadService, TableService, BrowserService) {

    /* get the base url */

    var baseurl = angular.element('meta[name="baseurl"]').attr('content');

    /* configure resources */

    var resources = {
        status: $resource(baseurl + 'query/api/status/'),
        forms: $resource(baseurl + 'query/api/forms/'),
        dropdowns: $resource(baseurl + 'query/api/dropdowns/'),
        jobs: $resource(baseurl + 'query/api/jobs/:id/:detail_route/'),
        examples: $resource(baseurl + 'query/api/examples/'),
        databases: $resource(baseurl + 'query/api/databases/:list_route/'),
        functions: $resource(baseurl + 'query/api/functions/'),
        queues: $resource(baseurl + 'query/api/queues/'),
        querylanguages: $resource(baseurl + 'query/api/querylanguages/'),
    };

    /* configure private functions */

    function getJobIndex(job) {
        return service.jobs.indexOf($filter('filter')(service.jobs, {'id': job.id})[0])
    }

    /* initialise the browser service */

    BrowserService.init('databases', ['databases', 'tables', 'columns'])
    BrowserService.init('columns', ['columns'], true)
    BrowserService.init('functions', ['functions'])
    BrowserService.init('examples', ['examples'])

    /* create the query service */

    var service = {
        forms: {},
        dropdowns: {},
        values: {},
        errors: {}
    };

    service.init = function() {
        // fetch queues,  query languages and then load forms
        service.queues = resources.queues.query();
        service.query_languages = resources.querylanguages.query();

        $q.all([service.queues.$promise, service.query_languages.$promise]).then(function(){
            service.active_queue = service.queues[0].id;

            resources.forms.query(function(response) {
                angular.forEach(response, function(form) {
                    service.forms[form.key] = $injector.get(form.form_service);
                });

                // activate first form
                service.forms[response[0].key].activate();
            });
        });

        // load dropdowns
        resources.dropdowns.query(function(response) {
            angular.forEach(response, function(dropdown) {
                service.dropdowns[dropdown.key] = $injector.get(dropdown.dropdown_service);
                service.dropdowns[dropdown.key].options = dropdown.options;
            });
        });

        // fetch status
        service.fetchStatus();

        // fetch functions
        resources.functions.query(function(response) {
            BrowserService.render('functions', response);
        });

        // fetch examples
        resources.examples.query(function(response) {
            BrowserService.render('examples', response);
        });

        // fetch databases
        resources.databases.query(function(response) {
            service.databases = response;

            service.columns = []
            angular.forEach(service.databases, function(database) {
                angular.forEach(database.tables, function(table) {
                    angular.forEach(table.columns, function(column) {
                        var column_copy = angular.copy(column);
                        column_copy.name = database.name + '.' + table.name + '.' + column.name;
                        service.columns.push(column_copy);
                    });
                });
            });

            // load user database when databases have been fetched
            service.fetchUserDatabase();
        });

        // fetch joblist
        service.fetchJobs();

        // activate overview tab
        service.tab = 'overview';

        // start the polling service
        PollingService.init();
        PollingService.register('status', service.fetchStatus);
        PollingService.register('jobs', service.fetchJobs);
        PollingService.register('database', service.fetchUserDatabase);

        // load the download service
        service.downloads = DownloadService;
    };

    service.fetchStatus = function() {
        resources.status.query(function(response) {
            service.status = response[0];
        }).$promise;
    };

    service.fetchUserDatabase = function() {
        return resources.databases.query({
            'list_route': 'user'
        }, function(response) {
            var user_database = response[0];

            var user_columns = [];
            angular.forEach(user_database.tables, function(table) {
                angular.forEach(table.columns, function(column) {
                    var column_copy = angular.copy(column);
                    column_copy.name = user_database.name + '.' + table.name + '.' + column.name;
                    user_columns.push(column_copy);
                });
            });

            BrowserService.render('databases', service.databases.concat(user_database));
            BrowserService.render('columns', service.columns.concat(user_columns));
        }).$promise;
    }

    service.fetchJobs = function() {
        return resources.jobs.query(function(response) {
            service.jobs = response;
        }).$promise;
    };

    service.fetchJob = function(job) {
        return resources.jobs.get({id: job.id}, function(response) {
            service.job = response;
            service.job.time_queue = moment.duration(moment(service.job.start_time) - moment(service.job.creation_time)).seconds();
            service.job.time_query = moment.duration(moment(service.job.end_time) - moment(service.job.start_time)).seconds();
        }).$promise;
    };

    service.activateForm = function(key) {
        service.form = key;
        service.job = null;
    };

    service.activateJob = function(job) {
        service.form = null;
        service.fetchJob(job).then(function() {

            if (service.job.phase == 'COMPLETED') {
                TableService.init(service.job.database_name, service.job.table_name);
            }

            CodeMirror.runMode(service.job.query, "text/x-mariadb", angular.element('#query')[0]);
            CodeMirror.runMode(service.job.actual_query, "text/x-mariadb", angular.element('#actual-query')[0]);
        });
    };

    service.submitJob = function(values) {
        values = angular.extend({}, values, {
            'queue': service.active_queue
        });

        return resources.jobs.save(values).$promise.then(function(job) {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(job);
        });
    };

    service.showModal = function(modal, job) {
        service.errors = {};

        if (angular.isDefined(job)) {
            service.values = job;
        }

        $('#' + modal + '-modal').modal('show');
    };

    service.renameJob = function() {
        resources.jobs.update({id: service.values.id}, service.values).$promise.then(function() {
            service.fetchJobs();
            $('.modal').modal('hide');
        }, function(response) {
            service.errors = response.data;
        });
    };

    service.killJob = function() {
        resources.jobs.update({id: service.values.id, detail_route: 'kill'}, {}, function() {
            service.fetchStatus();
            service.fetchJobs();
            $('.modal').modal('hide');
        });
    };

    service.removeJob = function() {
        var index = getJobIndex(service.values);

        var next_job;
        if (index == 0) {
            next_job = service.jobs[1];
        } else {
            next_job = service.jobs[index - 1];
        }

        resources.jobs.delete({id: service.values.id}, function() {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(next_job);
            $('.modal').modal('hide');
        });
    };

    return service;

}]);
<commit_msg>update the job overview on phase change in query angular app<commit_after>app.factory('QueryService', ['$resource', '$injector', '$q', '$filter', 'PollingService', 'DownloadService', 'TableService', 'BrowserService', function($resource, $injector, $q, $filter, PollingService, DownloadService, TableService, BrowserService) {

    /* get the base url */

    var baseurl = angular.element('meta[name="baseurl"]').attr('content');

    /* configure resources */

    var resources = {
        status: $resource(baseurl + 'query/api/status/'),
        forms: $resource(baseurl + 'query/api/forms/'),
        dropdowns: $resource(baseurl + 'query/api/dropdowns/'),
        jobs: $resource(baseurl + 'query/api/jobs/:id/:detail_route/'),
        examples: $resource(baseurl + 'query/api/examples/'),
        databases: $resource(baseurl + 'query/api/databases/:list_route/'),
        functions: $resource(baseurl + 'query/api/functions/'),
        queues: $resource(baseurl + 'query/api/queues/'),
        querylanguages: $resource(baseurl + 'query/api/querylanguages/'),
    };

    /* initialise the browser service */

    BrowserService.init('databases', ['databases', 'tables', 'columns'])
    BrowserService.init('columns', ['columns'], true)
    BrowserService.init('functions', ['functions'])
    BrowserService.init('examples', ['examples'])

    /* create the query service */

    var service = {
        forms: {},
        dropdowns: {},
        values: {},
        errors: {}
    };

    service.init = function() {
        // fetch queues,  query languages and then load forms
        service.queues = resources.queues.query();
        service.query_languages = resources.querylanguages.query();

        $q.all([service.queues.$promise, service.query_languages.$promise]).then(function(){
            service.active_queue = service.queues[0].id;

            resources.forms.query(function(response) {
                angular.forEach(response, function(form) {
                    service.forms[form.key] = $injector.get(form.form_service);
                });

                // activate first form
                service.forms[response[0].key].activate();
            });
        });

        // load dropdowns
        resources.dropdowns.query(function(response) {
            angular.forEach(response, function(dropdown) {
                service.dropdowns[dropdown.key] = $injector.get(dropdown.dropdown_service);
                service.dropdowns[dropdown.key].options = dropdown.options;
            });
        });

        // fetch status
        service.fetchStatus();

        // fetch functions
        resources.functions.query(function(response) {
            BrowserService.render('functions', response);
        });

        // fetch examples
        resources.examples.query(function(response) {
            BrowserService.render('examples', response);
        });

        // fetch databases
        resources.databases.query(function(response) {
            service.databases = response;

            service.columns = []
            angular.forEach(service.databases, function(database) {
                angular.forEach(database.tables, function(table) {
                    angular.forEach(table.columns, function(column) {
                        var column_copy = angular.copy(column);
                        column_copy.name = database.name + '.' + table.name + '.' + column.name;
                        service.columns.push(column_copy);
                    });
                });
            });

            // load user database when databases have been fetched
            service.fetchUserDatabase();
        });

        // fetch joblist
        service.fetchJobs();

        // activate overview tab
        service.tab = 'overview';

        // start the polling service
        PollingService.init();
        PollingService.register('status', service.fetchStatus);
        PollingService.register('jobs', service.fetchJobs);
        PollingService.register('database', service.fetchUserDatabase);

        // load the download service
        service.downloads = DownloadService;
    };

    service.fetchStatus = function() {
        resources.status.query(function(response) {
            service.status = response[0];
        }).$promise;
    };

    service.fetchUserDatabase = function() {
        return resources.databases.query({
            'list_route': 'user'
        }, function(response) {
            var user_database = response[0];

            var user_columns = [];
            angular.forEach(user_database.tables, function(table) {
                angular.forEach(table.columns, function(column) {
                    var column_copy = angular.copy(column);
                    column_copy.name = user_database.name + '.' + table.name + '.' + column.name;
                    user_columns.push(column_copy);
                });
            });

            BrowserService.render('databases', service.databases.concat(user_database));
            BrowserService.render('columns', service.columns.concat(user_columns));
        }).$promise;
    }

    service.fetchJobs = function() {
        return resources.jobs.query(function(response) {
            service.jobs = response;

            if (service.job) {
                // get the phase of the current job in the jobs list
                var phase = $filter('filter')(service.jobs, {'id': service.job.id})[0].phase;

                // if the phase has changed, fetch it again
                if (phase != service.job.phase) {
                    service.fetchJob(service.job);
                }
            }

        }).$promise;
    };

    service.fetchJob = function(job) {
        return resources.jobs.get({id: job.id}, function(response) {
            service.job = response;
            service.job.time_queue = moment.duration(moment(service.job.start_time) - moment(service.job.creation_time)).seconds();
            service.job.time_query = moment.duration(moment(service.job.end_time) - moment(service.job.start_time)).seconds();
        }).$promise;
    };

    service.activateForm = function(key) {
        service.form = key;
        service.job = null;
    };

    service.activateJob = function(job) {
        service.form = null;
        service.fetchJob(job).then(function() {

            if (service.job.phase == 'COMPLETED') {
                TableService.init(service.job.database_name, service.job.table_name);
            }

            CodeMirror.runMode(service.job.query, "text/x-mariadb", angular.element('#query')[0]);
            CodeMirror.runMode(service.job.actual_query, "text/x-mariadb", angular.element('#actual-query')[0]);
        });
    };

    service.submitJob = function(values) {
        values = angular.extend({}, values, {
            'queue': service.active_queue
        });

        return resources.jobs.save(values).$promise.then(function(job) {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(job);
        });
    };

    service.showModal = function(modal, job) {
        service.errors = {};

        if (angular.isDefined(job)) {
            service.values = job;
        }

        $('#' + modal + '-modal').modal('show');
    };

    service.renameJob = function() {
        resources.jobs.update({id: service.values.id}, service.values).$promise.then(function() {
            service.fetchJobs();
            $('.modal').modal('hide');
        }, function(response) {
            service.errors = response.data;
        });
    };

    service.killJob = function() {
        resources.jobs.update({id: service.values.id, detail_route: 'kill'}, {}, function() {
            service.fetchStatus();
            service.fetchJobs();
            $('.modal').modal('hide');
        });
    };

    service.removeJob = function() {
        var index = service.jobs.indexOf($filter('filter')(service.jobs, {'id': service.job.id})[0]);

        var next_job;
        if (index == 0) {
            next_job = service.jobs[1];
        } else {
            next_job = service.jobs[index - 1];
        }

        resources.jobs.delete({id: service.values.id}, function() {
            service.fetchStatus();
            service.fetchJobs();
            service.activateJob(next_job);
            $('.modal').modal('hide');
        });
    };

    return service;

}]);
<|endoftext|>


<commit_before>
var browser = {
    api_location : null,
    load_button : null,
    load_spinner : null,
    box_container : null,

    last_loaded_id : null,

    init : function (configuration) {
        browser.api_location = configuration.api_location;
        browser.load_button = $("#load_more button");
        browser.load_spinner = $("#spinner");
        browser.box_container = $("#listing");

        browser.load_button.bind('click', browser.getNextPage)

        browser.load_spinner.hide()
    },

    getNextPage : function() {
        browser.load_button.hide()
        browser.load_spinner.show()
        if (browser.last_loaded_id === null) {
            $.get('/maps/listing', browser.appendLoadedData)
        } else {
            $.get('/maps/listing/' + browser.last_loaded_id, browser.appendLoadedData)
        }
    },

    appendLoadedData : function(data) {
        var arrayLength = data['maps'].length;
        for (var i = 0; i < arrayLength; i++) {
            if (browser.last_loaded_id === null || browser.last_loaded_id > data['maps'][i]['id']) {
                browser.last_loaded_id = data['maps'][i]['id'];
            }
            browser.box_container.append($("

" + data['maps'][i]['name'] + "
Uploaded: " + data['maps'][i]['created'] + "Download code: " + data['maps'][i]['code'] + "
"));
        }
        browser.load_spinner.hide()
        if (browser.last_loaded_id > 0) {
            browser.load_button.show();
        }
    }
}

$(document).ready(function() {
    browser.init(configuration);

    browser.getNextPage()
});<commit_msg>Fix to hide button when last page is not full 20 maps<commit_after>
var browser = {
    api_location : null,
    load_button : null,
    load_spinner : null,
    box_container : null,

    last_loaded_id : null,

    init : function (configuration) {
        browser.api_location = configuration.api_location;
        browser.load_button = $("#load_more button");
        browser.load_spinner = $("#spinner");
        browser.box_container = $("#listing");

        browser.load_button.bind('click', browser.getNextPage)

        browser.load_spinner.hide()
    },

    getNextPage : function() {
        browser.load_button.hide()
        browser.load_spinner.show()
        if (browser.last_loaded_id === null) {
            $.get('/maps/listing', browser.appendLoadedData)
        } else {
            $.get('/maps/listing/' + browser.last_loaded_id, browser.appendLoadedData)
        }
    },

    appendLoadedData : function(data) {
        var arrayLength = data['maps'].length;
        for (var i = 0; i < arrayLength; i++) {
            if (browser.last_loaded_id === null || browser.last_loaded_id > data['maps'][i]['id']) {
                browser.last_loaded_id = data['maps'][i]['id'];
            }
            browser.box_container.append($("

" + data['maps'][i]['name'] + "
Uploaded: " + data['maps'][i]['created'] + "Download code: " + data['maps'][i]['code'] + "
"));
        }
        browser.load_spinner.hide()
        if (browser.last_loaded_id > 0 || arrayLength < 20) {
            browser.load_button.show();
        }
    }
}

$(document).ready(function() {
    browser.init(configuration);

    browser.getNextPage()
});<|endoftext|>


<commit_before>var http = require('http'),
    sys = require('sys'),
    API_URI = 'http://api.dropbox.com/',
    CONTENT_API_URI = 'https://api-content.dropbox.com/',
    API_VERSION = '0';

// Returns a Dropbox Client, through which API calls can be made.
var DropboxClient = exports.DropboxClient =
  function(oauth, access_token, access_token_secret) {
    this.oauth = oauth;
    this.access_token = access_token;
    this.access_token_secret = access_token_secret;
  }

// Retrieves information about the user's account as a JSON response.
DropboxClient.prototype.getAccountInfo = function(status_in_res,
                                                  callback) {
  if (typeof status_in_res == 'function')
    callback = status_in_res, status_in_res = undefined;
  this.oauth.get(API_URI + API_VERSION + '/account/info/' +
                 (status_in_res ? '?status_in_response=true' : ''),
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Retrieves contents of a file specified by path argument, relative to
// user's Dropbox root.
DropboxClient.prototype.getFile = function(path, callback) {
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data);
                 });
}

// Uploads contents of a file specified by path argument, relative to
// application's directory.
DropboxClient.prototype.putFile = function(file, path, callback) {
  var boundary = 'sAxIqse3tPlHqUIUI9ofVlHvtdt3tpaG',
      content_type = 'multipart/form-data; boundary=' + boundary,
      file_contents = require('fs').readFileSync(file);

  // Build request body.
  var body = '--' + boundary + '\r\n' +
    'Content-Disposition: form-data; name=file; filename=' + file + '\r\n' +
    'Content-type: application/octet-stream\r\n' +
    '\r\n' + file_contents + '\r\n' +
    '--' + boundary + '--';
  this.oauth.post(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path +
                  '?file=' + file,
                  this.access_token, this.access_token_secret,
                  body, content_type,
                  function(err, data, res) {
                    callback(err, JSON.parse(data));
                  });
}

// Gets metadata of file/folder specified by path relative to user's
// Dropbox root.
// TODO: Add file_limit param, others?
DropboxClient.prototype.getMetadata = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/metadata/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Downloads a minimized jpeg thumbnail for a photo. See
// https://www.dropbox.com/developers/docs#thumbnails for a list of
// valid size specifiers.
DropboxClient.prototype.getThumbnail = function(path, size, callback) {
  if (typeof(size) == 'function') callback = size, size = null;
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/thumbnails/dropbox/' +
                 path + ((size) ? '?size=' + size : ''),
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data);
                 });
}

// Copies a file or folder to a new location.
// See https://www.dropbox.com/developers/docs#fileops-copy for explanation
// of arguments.
DropboxClient.prototype.copy = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/copy?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Creates a folder relative to the user's Dropbox root.
// See https://www.dropbox.com/developers/docs#fileops-create-folder
// for explanation of arguments.
DropboxClient.prototype.createFolder = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/create_folder?path='
                 + path +'&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Deletes a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-delete for
// explanation of arguments.
DropboxClient.prototype.deleteItem = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/delete?path=' +
                 path + '&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Moves a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-move for
// explanation of arguments.
DropboxClient.prototype.move = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/move?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}<commit_msg>Modify getAccountInfo to adhere to the optargs object pattern.<commit_after>var http = require('http'),
    sys = require('sys'),
    API_URI = 'http://api.dropbox.com/',
    CONTENT_API_URI = 'https://api-content.dropbox.com/',
    API_VERSION = '0';

// Returns a Dropbox Client, through which API calls can be made.
var DropboxClient = exports.DropboxClient =
  function(oauth, access_token, access_token_secret) {
    this.oauth = oauth;
    this.access_token = access_token;
    this.access_token_secret = access_token_secret;
  }

// Retrieves information about the user's account as a JSON response.
DropboxClient.prototype.getAccountInfo = function(optargs, callback) {
  if (typeof optargs == 'function')
    callback = optargs, optargs = {};
  this.oauth.get(API_URI + API_VERSION + '/account/info/' +
                 (optargs.status_in_response ? '?status_in_response=' +
                  optargs.status_in_response : ''),
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   if (err) callback(err);
                   else callback(null, JSON.parse(data));
                 });
}

// Retrieves contents of a file specified by path argument, relative to
// user's Dropbox root.
DropboxClient.prototype.getFile = function(path, callback) {
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data);
                 });
}

// Uploads contents of a file specified by path argument, relative to
// application's directory.
DropboxClient.prototype.putFile = function(file, path, callback) {
  var boundary = 'sAxIqse3tPlHqUIUI9ofVlHvtdt3tpaG',
      content_type = 'multipart/form-data; boundary=' + boundary,
      file_contents = require('fs').readFileSync(file);

  // Build request body.
  var body = '--' + boundary + '\r\n' +
    'Content-Disposition: form-data; name=file; filename=' + file + '\r\n' +
    'Content-type: application/octet-stream\r\n' +
    '\r\n' + file_contents + '\r\n' +
    '--' + boundary + '--';
  this.oauth.post(CONTENT_API_URI + API_VERSION + '/files/dropbox/' + path +
                  '?file=' + file,
                  this.access_token, this.access_token_secret,
                  body, content_type,
                  function(err, data, res) {
                    callback(err, JSON.parse(data));
                  });
}

// Gets metadata of file/folder specified by path relative to user's
// Dropbox root.
// TODO: Add file_limit param, others?
DropboxClient.prototype.getMetadata = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/metadata/dropbox/' + path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Downloads a minimized jpeg thumbnail for a photo. See
// https://www.dropbox.com/developers/docs#thumbnails for a list of
// valid size specifiers.
DropboxClient.prototype.getThumbnail = function(path, size, callback) {
  if (typeof(size) == 'function') callback = size, size = null;
  this.oauth.get(CONTENT_API_URI + API_VERSION + '/thumbnails/dropbox/' +
                 path + ((size) ? '?size=' + size : ''),
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, data);
                 });
}

// Copies a file or folder to a new location.
// See https://www.dropbox.com/developers/docs#fileops-copy for explanation
// of arguments.
DropboxClient.prototype.copy = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/copy?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Creates a folder relative to the user's Dropbox root.
// See https://www.dropbox.com/developers/docs#fileops-create-folder
// for explanation of arguments.
DropboxClient.prototype.createFolder = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/create_folder?path='
                 + path +'&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Deletes a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-delete for
// explanation of arguments.
DropboxClient.prototype.deleteItem = function(path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/delete?path=' +
                 path + '&root=dropbox',
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}

// Moves a file or folder.
// See https://www.dropbox.com/developers/docs#fileops-move for
// explanation of arguments.
DropboxClient.prototype.move = function(from_path, to_path, callback) {
  this.oauth.get(API_URI + API_VERSION + '/fileops/move?from_path=' +
                 from_path + '&root=dropbox&to_path=' + to_path,
                 this.access_token, this.access_token_secret,
                 function(err, data, res) {
                   callback(err, JSON.parse(data));
                 });
}<|endoftext|>


<commit_before>import OrbitSchema from 'orbit-common/schema';

/**
 @module ember-orbit
 */

var get = Ember.get;

var proxyProperty = function(source, property, defaultValue) {
  var _property = '_' + property;

  return Ember.computed({
    set: function(key, value) {
      if (arguments.length > 1) {
        this[_property] = value;
        if (this[source]) {
          this[source][property] = value;
        }
      }
      if (!this[_property]) {
        this[_property] = defaultValue;
      }
      return this[_property];
    },
    get: function() {
      if (!this[_property]) {
        this[_property] = defaultValue;
      }
      return this[_property];
    }
  });
};

var Schema = Ember.Object.extend({
  /**
   @property pluralize
   @type {function}
   @default OC.Schema.pluralize
   */
  pluralize: proxyProperty('_schema', 'pluralize'),

  /**
   @property singularize
   @type {function}
   @default OC.Schema.singularize
   */
  singularize: proxyProperty('_schema', 'singularize'),

  init: function() {
    this._super.apply(this, arguments);
    this._modelTypeMap = {};

    // Don't use `modelDefaults` in ember-orbit.
    // The same functionality can be achieved with a base model class that
    // can be overridden.
    var options = {
      modelDefaults: {}
    };

    var pluralize = this.get('pluralize');
    if (pluralize) {
      options.pluralize = pluralize;
    }

    var singularize = this.get('singularize');
    if (singularize) {
      options.singularize = singularize;
    }

    this._schema = new OrbitSchema(options);
  },

  defineModel: function(type, modelClass) {
    var definedModels = this._schema.models;
    if (!definedModels[type]) {
      this._schema.registerModel(type, {
        keys: get(modelClass, 'keys'),
        attributes: get(modelClass, 'attributes'),
        links: get(modelClass, 'links')
      });
    }
  },

  modelFor: function(type) {
    Ember.assert("`type` must be a string", typeof type === 'string');

    var model = this._modelTypeMap[type];
    if (!model) {
      model = get(this, 'container').lookupFactory('model:' + type);
      if (!model) {
        throw new Ember.Error("No model was found for '" + type + "'");
      }
      model.typeKey = type;

      // ensure model is defined in underlying OC.Schema
      this.defineModel(type, model);

      // save model in map for faster lookups
      this._modelTypeMap[type] = model;

      // look up related models
      this.links(type).forEach(function(link) {
        this.modelFor(this.linkProperties(type, link).model);
      }, this);
    }

    return model;
  },

  models: function() {
    return Object.keys(this._schema.models);
  },

  primaryKey: function(type) {
    return this._schema.models[type].primaryKey.name;
  },

  primaryKeyProperties: function(type) {
    return this._schema.models[type].primaryKey;
  },

  keys: function(type) {
    return Object.keys(this._schema.models[type].keys);
  },

  keyProperties: function(type, name) {
    return this._schema.models[type].keys[name];
  },

  attributes: function(type) {
    return Object.keys(this._schema.models[type].attributes);
  },

  attributeProperties: function(type, name) {
    return this._schema.models[type].attributes[name];
  },

  links: function(type) {
    return Object.keys(this._schema.models[type].links);
  },

  linkProperties: function(type, name) {
    return this._schema.models[type].links[name];
  },

  normalize: function(type, record) {
    // Normalize links to IDs contained within the `__rel` (i.e. "forward link")
    // element.
    this.links(type).forEach(function(link) {
      if (!record.__rel) {
        record.__rel = {};
      }

      var linkValue = record[link];
      if (linkValue) {
        if (Ember.isArray(linkValue)) {
          var rel = record.__rel[link] = {};
          linkValue.forEach(function(id) {
            if (typeof id === 'object') {
              id = get(id, 'primaryId');
            }
            rel[id] = true;
          });

        } else if (typeof linkValue === 'object') {
          record.__rel[link] = get(linkValue, 'primaryId');

        } else {
          record.__rel[link] = linkValue;
        }

        delete record[link];
      }
    });

    this._schema.normalize(type, record);
  }
});

export default Schema;
<commit_msg>Lazy load models as they are requested in Schema.<commit_after>import OrbitSchema from 'orbit-common/schema';

/**
 @module ember-orbit
 */

var get = Ember.get;

var proxyProperty = function(source, property, defaultValue) {
  var _property = '_' + property;

  return Ember.computed({
    set: function(key, value) {
      if (arguments.length > 1) {
        this[_property] = value;
        if (this[source]) {
          this[source][property] = value;
        }
      }
      if (!this[_property]) {
        this[_property] = defaultValue;
      }
      return this[_property];
    },
    get: function() {
      if (!this[_property]) {
        this[_property] = defaultValue;
      }
      return this[_property];
    }
  });
};

var Schema = Ember.Object.extend({
  /**
   @property pluralize
   @type {function}
   @default OC.Schema.pluralize
   */
  pluralize: proxyProperty('_schema', 'pluralize'),

  /**
   @property singularize
   @type {function}
   @default OC.Schema.singularize
   */
  singularize: proxyProperty('_schema', 'singularize'),

  init: function() {
    this._super.apply(this, arguments);
    this._modelTypeMap = {};

    // Don't use `modelDefaults` in ember-orbit.
    // The same functionality can be achieved with a base model class that
    // can be overridden.
    var options = {
      modelDefaults: {}
    };

    var pluralize = this.get('pluralize');
    if (pluralize) {
      options.pluralize = pluralize;
    }

    var singularize = this.get('singularize');
    if (singularize) {
      options.singularize = singularize;
    }

    this._schema = new OrbitSchema(options);

    // Lazy load model definitions as they are requested.
    var _this = this;
    this._schema.modelNotDefined = function(type) {
      _this.modelFor(type);
    };
  },

  defineModel: function(type, modelClass) {
    var definedModels = this._schema.models;
    if (!definedModels[type]) {
      this._schema.registerModel(type, {
        keys: get(modelClass, 'keys'),
        attributes: get(modelClass, 'attributes'),
        links: get(modelClass, 'links')
      });
    }
  },

  modelFor: function(type) {
    Ember.assert("`type` must be a string", typeof type === 'string');

    var model = this._modelTypeMap[type];
    if (!model) {
      model = get(this, 'container').lookupFactory('model:' + type);

      if (!model) {
        throw new Ember.Error("No model was found for '" + type + "'");
      }

      model.typeKey = type;

      // ensure model is defined in underlying OC.Schema
      this.defineModel(type, model);

      // save model in map for faster lookups
      this._modelTypeMap[type] = model;

      // look up related models
      this.links(type).forEach(function(link) {
        this.modelFor(this.linkProperties(type, link).model);
      }, this);
    }

    return model;
  },

  models: function() {
    return Object.keys(this._schema.models);
  },

  primaryKey: function(type) {
    return this._schema.models[type].primaryKey.name;
  },

  primaryKeyProperties: function(type) {
    return this._schema.models[type].primaryKey;
  },

  keys: function(type) {
    return Object.keys(this._schema.models[type].keys);
  },

  keyProperties: function(type, name) {
    return this._schema.models[type].keys[name];
  },

  attributes: function(type) {
    return Object.keys(this._schema.models[type].attributes);
  },

  attributeProperties: function(type, name) {
    return this._schema.models[type].attributes[name];
  },

  links: function(type) {
    return Object.keys(this._schema.models[type].links);
  },

  linkProperties: function(type, name) {
    return this._schema.models[type].links[name];
  },

  normalize: function(type, record) {
    // Normalize links to IDs contained within the `__rel` (i.e. "forward link")
    // element.
    this.links(type).forEach(function(link) {
      if (!record.__rel) {
        record.__rel = {};
      }

      var linkValue = record[link];
      if (linkValue) {
        if (Ember.isArray(linkValue)) {
          var rel = record.__rel[link] = {};
          linkValue.forEach(function(id) {
            if (typeof id === 'object') {
              id = get(id, 'primaryId');
            }
            rel[id] = true;
          });

        } else if (typeof linkValue === 'object') {
          record.__rel[link] = get(linkValue, 'primaryId');

        } else {
          record.__rel[link] = linkValue;
        }

        delete record[link];
      }
    });

    this._schema.normalize(type, record);
  }
});

export default Schema;
<|endoftext|>