<commit_before>import m from 'mithril';
import _ from 'underscore';
import {
    catarse,
    commonPayment
} from '../api';
import models from '../models';
import h from '../h';
import loadMoreBtn from '../c/load-more-btn';
import filterText from '../c/filter-text';
import FilterDropdown from '../c/filter-dropdown';
import filterDropdownNumberRange from '../c/filter-dropdown-number-range';
import projectDashboardMenu from '../c/project-dashboard-menu';
import dashboardSubscriptionCard from '../c/dashboard-subscription-card';
import projectsSubscriptionReportVM from '../vms/projects-subscription-report-vm';
import projectsContributionReportVM from '../vms/projects-contribution-report-vm';

const statusCustomFilter = {
    view: () => m('.fontsize-smaller.u-text-center', [
        'Status ',
        m('a.fontsize-smallest.tooltip-wrapper.fa.fa-question-circle.fontcolor-secondary', {
            href: 'https://suporte.catarse.me/hc/pt-br/articles/115005632746-Catarse-Assinaturas-FAQ-Realizadores#status',
            target: '_blank'
        })
    ])
};

const dropdownFilterCustomLabel = {
    view: function(ctrl, args)
    {
        return m('.fontsize-smaller.u-text-center', args.label);
    }
};

const projectSubscriptionReport = {
    controller: function (args) {
        const filterVM = projectsSubscriptionReportVM,
            catarseVM = projectsContributionReportVM,
            dropdownNumber = m.prop(0),
            error = m.prop(false),
            loader = m.prop(true),
            isProjectDataLoaded = m.prop(false),
            isRewardsDataLoaded = m.prop(false),
            rewards = m.prop([]),
            subscriptions = commonPayment.paginationVM(models.userSubscription, 'last_payment_data_created_at.desc', {
                Prefer: 'count=exact'
            }),
            submit = () => {
                // Set order by last paid on filters too
                filterVM.order({ last_payment_data_created_at: 'desc' });
                if (filterVM.reward_external_id() === 'null') {
                    subscriptions.firstPage(filterVM.withNullParameters()).then(null);
                } else {
                    subscriptions.firstPage(filterVM.parameters()).then(null);
                }

                return false;
            },
            filterBuilder = [{
                component: filterText,
                label: 'text_filter',
                data: {
                    label: 'Nome ou email',
                    vm: filterVM.search_index,
                    onchange: submit,
                    wrapper_class: '.u-marginbottom-20.w-col.w-col-3',
                    placeholder: 'Busque por assinantes',
                    onclick: submit
                }
            },
            {
                label: 'status_filter',
                component: FilterDropdown,
                data: {
                    custom_label: [
                        statusCustomFilter,
                        null
                    ],
                    onchange: submit,
                    name: 'status',
                    vm: filterVM.status,
                    wrapper_class: '.w-col.w-col-3',
                    options: [{
                        value: '',
                        option: 'Todos'
                    },
                    {
                        value: 'active',
                        option: 'Ativa'
                    },
                    {
                        value: 'started',
                        option: 'Iniciada'
                    },
                    {
                        value: 'canceling',
                        option: 'Cancelamento solicitado'
                    },
                    {
                        value: 'canceled',
                        option: 'Cancelada'
                    },
                    {
                        value: 'inactive',
                        option: 'Inativa'
                    }
                    ]
                }
            },
            {
                label: 'reward_filter',
                component: FilterDropdown,
                data: {
                    custom_label: [
                        dropdownFilterCustomLabel,
                        {label: 'Recompensa'}
                    ],
                    onchange: submit,
                    name: 'reward_external_id',
                    vm: filterVM.reward_external_id,
                    wrapper_class: '.w-col.w-col-3',
                    options: []
                }
            },
            {
                label: 'payment_filter',
                component: FilterDropdown,
                data: {
                    custom_label: [
                        dropdownFilterCustomLabel,
                        {label: 'Meio de pgto.'}
                    ],
                    onchange: submit,
                    name: 'payment_method',
                    vm: filterVM.payment_method,
                    wrapper_class: '.w-col.w-col-2',
                    options: [{
                        value: '',
                        option: 'Todos'
                    },
                    {
                        value: 'credit_card',
                        option: 'Cartão de crédito'
                    },
                    {
                        value: 'boleto',
                        option: 'Boleto'
                    }
                    ]
                }
            },
            {
                label: 'total_paid_filter',
                component: filterDropdownNumberRange,
                data: {
                    index: 1,
                    selectable: dropdownNumber,
                    label: 'Total apoiado',
                    name: 'total_paid',
                    onapply: submit,
                    vm: filterVM.total_paid,
                    wrapper_class: '.w-col.w-col-2',
                    init_lower_value: '0',
                    init_higher_value: 'mais',
                    value_change_placeholder: 'R$#V1 ou #V2',
                    value_change_both_placeholder: 'R$#V1 a R$#V2',
                    inner_field_placeholder: '0',
                    inner_field_label: 'R$',
                    value_multiplier: 100,
                    min: 0
                }
            },
            {
                label: 'paid_count_filter',
                component: filterDropdownNumberRange,
                data: {
                    index: 2,
                    selectable: dropdownNumber,
                    label: 'Qtde. de apoios',
                    name: 'paid_count',
                    onapply: submit,
                    vm: filterVM.paid_count,
                    wrapper_class: '.w-col.w-col-2',
                    init_lower_value: '0',
                    init_higher_value: 'mais',
                    value_change_placeholder: '#V1 ou #V2',
                    value_change_both_placeholder: '#V1 a #V2',
                    inner_field_placeholder: '0',
                    value_multiplier: 1,
                    min: 0,
                    dropdown_inline_style: {
                        right: '0'
                    }
                }
            }

            ],
            handleError = () => {
                error(true);
                loader(false);
                isProjectDataLoaded(true);
                m.redraw();
            },
            project = m.prop([{}]);

        catarseVM.project_id(args.project_id);

        const lReward = catarse.loaderWithToken(models.rewardDetail.getPageOptions({
            project_id: `eq.${catarseVM.project_id()}`
        }));

        lReward.load().then((loadedRewards) => {
            rewards(loadedRewards);
            isRewardsDataLoaded(true);
        });
        const mapRewardsToOptions = () => {
            let options = [];
            if (!lReward()) {
                options = _.map(rewards(), r => ({
                    value: r.id,
                    option: `R$ ${h.formatNumber(r.minimum_value, 2, 3)} - ${(r.title ? r.title : r.description).substring(0, 20)}`
                }));
            }

            options.unshift({
                value: null,
                option: 'Sem recompensa'
            });

            options.unshift({
                value: '',
                option: 'Todas'
            });

            return options;
        };

        const lProject = catarse.loaderWithToken(models.projectDetail.getPageOptions({
            project_id: `eq.${catarseVM.project_id()}`
        }));

        lProject.load().then((data) => {
            filterVM.project_id(_.first(data).common_id);
            // override default 'created_at' order on vm
            filterVM.order({ last_payment_data_created_at: 'desc' });
            subscriptions.firstPage(filterVM.parameters()).then(() => {
                loader(false);
                isProjectDataLoaded(true);
            }).catch(handleError);
            project(data);
        });

        return {
            filterVM,
            mapRewardsToOptions,
            filterBuilder,
            submit,
            subscriptions,
            lProject,
            project,
            isProjectDataLoaded,
            isRewardsDataLoaded
        };
    },
    view: function (ctrl, args) {

        const subsCollection = ctrl.subscriptions.collection(),
            filterBuilder = ctrl.filterBuilder,
            statusFilter = _.findWhere(filterBuilder, {
                label: 'status_filter'
            }),
            textFilter = _.findWhere(filterBuilder, {
                label: 'text_filter'
            }),
            rewardFilter = _.findWhere(filterBuilder, {
                label: 'reward_filter'
            }),
            paymentFilter = _.findWhere(filterBuilder, {
                label: 'payment_filter'
            }),
            totalPaidFilter = _.findWhere(filterBuilder, {
                label: 'total_paid_filter'
            }),
            paidCountFilter = _.findWhere(filterBuilder, {
                label: 'paid_count_filter'
            });
        rewardFilter.data.options = ctrl.mapRewardsToOptions();
        if (ctrl.isProjectDataLoaded() && ctrl.isRewardsDataLoaded()) {
            return m('div', [
                m.component(projectDashboardMenu, {
                    project: m.prop(_.first(ctrl.project()))
                }),
                m('.dashboard-header', [
                    m('.w-container',
                        m('.w-row', [
                            m('.w-col.w-col-3'),
                            m('.w-col.w-col-6',
                                m('.fontsize-larger.fontweight-semibold.lineheight-looser.u-marginbottom-30.u-text-center',
                                    'Base de assinantes'
                                )
                            ),
                            m('.w-col.w-col-3')
                        ])
                    ),
                    m('.u-marginbottom-30.w-container',
                        m('.w-form', [
                            m('form', {
                                onsubmit: ctrl.submit
                            },
                                m('w-row', [
                                    m.component(textFilter.component, textFilter.data),
                                    m('.w-col.w-col-9',
                                        m('.w-row', [
                                            m.component(statusFilter.component, statusFilter.data),
                                            m.component(rewardFilter.component, rewardFilter.data),
                                            m.component(paymentFilter.component, paymentFilter.data),
                                            m.component(totalPaidFilter.component, totalPaidFilter.data),
                                            m.component(paidCountFilter.component, paidCountFilter.data),
                                        ])
                                    )
                                ])
                            )
                        ])
                    )
                ]),
                m('.divider'),
                m('.before-footer.bg-gray.section', [
                    m('.w-container', [
                        m('div',
                            m('.w-row', [
                                m('.u-marginbottom-20.u-text-center-small-only.w-col.w-col-6',
                                    m('.w-inline-block.fontsize-base.u-marginright-10', [
                                        m('span.fontweight-semibold',
                                            ctrl.subscriptions.total()
                                        ),
                                        ' pessoas',
                                        m.trust(' ')
                                    ])
                                ),
                                m('.w-col.w-col-6',
                                    m(`a.alt-link.fontsize-small.u-right[href='/projects/${args.project_id}/subscriptions_report_download']`, {
                                        config: m.route
                                    }, [
                                            m('span.fa.fa-download',
                                                m.trust(' ')
                                            ),
                                            'Baixar relatórios'
                                        ])
                                )
                            ])
                        ),
                        m('.u-marginbottom-60', [
                            m('.card.card-secondary.fontsize-smallest.fontweight-semibold.lineheight-tighter.u-marginbottom-10',
                                m('.w-row', [
                                    m('.table-col.w-col.w-col-3',
                                        m('div',
                                            'Assinante'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2',
                                        m('div',
                                            'Recompensa'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-1.u-text-center',
                                        m('div',
                                            'Apoio mensal'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2.u-text-center',
                                        m('div',
                                            'Total apoiado'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2.u-text-center',
                                        m('div',
                                            'Último pagamento'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2.u-text-center',
                                        m('div',
                                            'Status da Assinatura'
                                        )
                                    )
                                ])
                            ),
                            m('.fontsize-small', [
                                _.map(subsCollection, subscription =>
                                    m(dashboardSubscriptionCard, {
                                        subscription
                                    }))
                            ])
                        ])
                    ]),
                    m('.bg-gray.section',
                        m('.w-container',
                            m('.u-marginbottom-60.w-row', [
                                m(loadMoreBtn, {
                                    collection: ctrl.subscriptions,
                                    cssClass: '.w-col-push-4'
                                })
                            ])
                        )
                    )
                ])
            ]);
        }
        return m('', h.loader());
    }
};

export default projectSubscriptionReport;
<commit_msg>Change pagamento to cobrança in sub report online<commit_after>import m from 'mithril';
import _ from 'underscore';
import {
    catarse,
    commonPayment
} from '../api';
import models from '../models';
import h from '../h';
import loadMoreBtn from '../c/load-more-btn';
import filterText from '../c/filter-text';
import FilterDropdown from '../c/filter-dropdown';
import filterDropdownNumberRange from '../c/filter-dropdown-number-range';
import projectDashboardMenu from '../c/project-dashboard-menu';
import dashboardSubscriptionCard from '../c/dashboard-subscription-card';
import projectsSubscriptionReportVM from '../vms/projects-subscription-report-vm';
import projectsContributionReportVM from '../vms/projects-contribution-report-vm';

const statusCustomFilter = {
    view: () => m('.fontsize-smaller.u-text-center', [
        'Status ',
        m('a.fontsize-smallest.tooltip-wrapper.fa.fa-question-circle.fontcolor-secondary', {
            href: 'https://suporte.catarse.me/hc/pt-br/articles/115005632746-Catarse-Assinaturas-FAQ-Realizadores#status',
            target: '_blank'
        })
    ])
};

const dropdownFilterCustomLabel = {
    view: function(ctrl, args)
    {
        return m('.fontsize-smaller.u-text-center', args.label);
    }
};

const projectSubscriptionReport = {
    controller: function (args) {
        const filterVM = projectsSubscriptionReportVM,
            catarseVM = projectsContributionReportVM,
            dropdownNumber = m.prop(0),
            error = m.prop(false),
            loader = m.prop(true),
            isProjectDataLoaded = m.prop(false),
            isRewardsDataLoaded = m.prop(false),
            rewards = m.prop([]),
            subscriptions = commonPayment.paginationVM(models.userSubscription, 'last_payment_data_created_at.desc', {
                Prefer: 'count=exact'
            }),
            submit = () => {
                // Set order by last paid on filters too
                filterVM.order({ last_payment_data_created_at: 'desc' });
                if (filterVM.reward_external_id() === 'null') {
                    subscriptions.firstPage(filterVM.withNullParameters()).then(null);
                } else {
                    subscriptions.firstPage(filterVM.parameters()).then(null);
                }

                return false;
            },
            filterBuilder = [{
                component: filterText,
                label: 'text_filter',
                data: {
                    label: 'Nome ou email',
                    vm: filterVM.search_index,
                    onchange: submit,
                    wrapper_class: '.u-marginbottom-20.w-col.w-col-3',
                    placeholder: 'Busque por assinantes',
                    onclick: submit
                }
            },
            {
                label: 'status_filter',
                component: FilterDropdown,
                data: {
                    custom_label: [
                        statusCustomFilter,
                        null
                    ],
                    onchange: submit,
                    name: 'status',
                    vm: filterVM.status,
                    wrapper_class: '.w-col.w-col-3',
                    options: [{
                        value: '',
                        option: 'Todos'
                    },
                    {
                        value: 'active',
                        option: 'Ativa'
                    },
                    {
                        value: 'started',
                        option: 'Iniciada'
                    },
                    {
                        value: 'canceling',
                        option: 'Cancelamento solicitado'
                    },
                    {
                        value: 'canceled',
                        option: 'Cancelada'
                    },
                    {
                        value: 'inactive',
                        option: 'Inativa'
                    }
                    ]
                }
            },
            {
                label: 'reward_filter',
                component: FilterDropdown,
                data: {
                    custom_label: [
                        dropdownFilterCustomLabel,
                        {label: 'Recompensa'}
                    ],
                    onchange: submit,
                    name: 'reward_external_id',
                    vm: filterVM.reward_external_id,
                    wrapper_class: '.w-col.w-col-3',
                    options: []
                }
            },
            {
                label: 'payment_filter',
                component: FilterDropdown,
                data: {
                    custom_label: [
                        dropdownFilterCustomLabel,
                        {label: 'Meio de pgto.'}
                    ],
                    onchange: submit,
                    name: 'payment_method',
                    vm: filterVM.payment_method,
                    wrapper_class: '.w-col.w-col-2',
                    options: [{
                        value: '',
                        option: 'Todos'
                    },
                    {
                        value: 'credit_card',
                        option: 'Cartão de crédito'
                    },
                    {
                        value: 'boleto',
                        option: 'Boleto'
                    }
                    ]
                }
            },
            {
                label: 'total_paid_filter',
                component: filterDropdownNumberRange,
                data: {
                    index: 1,
                    selectable: dropdownNumber,
                    label: 'Total apoiado',
                    name: 'total_paid',
                    onapply: submit,
                    vm: filterVM.total_paid,
                    wrapper_class: '.w-col.w-col-2',
                    init_lower_value: '0',
                    init_higher_value: 'mais',
                    value_change_placeholder: 'R$#V1 ou #V2',
                    value_change_both_placeholder: 'R$#V1 a R$#V2',
                    inner_field_placeholder: '0',
                    inner_field_label: 'R$',
                    value_multiplier: 100,
                    min: 0
                }
            },
            {
                label: 'paid_count_filter',
                component: filterDropdownNumberRange,
                data: {
                    index: 2,
                    selectable: dropdownNumber,
                    label: 'Qtde. de apoios',
                    name: 'paid_count',
                    onapply: submit,
                    vm: filterVM.paid_count,
                    wrapper_class: '.w-col.w-col-2',
                    init_lower_value: '0',
                    init_higher_value: 'mais',
                    value_change_placeholder: '#V1 ou #V2',
                    value_change_both_placeholder: '#V1 a #V2',
                    inner_field_placeholder: '0',
                    value_multiplier: 1,
                    min: 0,
                    dropdown_inline_style: {
                        right: '0'
                    }
                }
            }

            ],
            handleError = () => {
                error(true);
                loader(false);
                isProjectDataLoaded(true);
                m.redraw();
            },
            project = m.prop([{}]);

        catarseVM.project_id(args.project_id);

        const lReward = catarse.loaderWithToken(models.rewardDetail.getPageOptions({
            project_id: `eq.${catarseVM.project_id()}`
        }));

        lReward.load().then((loadedRewards) => {
            rewards(loadedRewards);
            isRewardsDataLoaded(true);
        });
        const mapRewardsToOptions = () => {
            let options = [];
            if (!lReward()) {
                options = _.map(rewards(), r => ({
                    value: r.id,
                    option: `R$ ${h.formatNumber(r.minimum_value, 2, 3)} - ${(r.title ? r.title : r.description).substring(0, 20)}`
                }));
            }

            options.unshift({
                value: null,
                option: 'Sem recompensa'
            });

            options.unshift({
                value: '',
                option: 'Todas'
            });

            return options;
        };

        const lProject = catarse.loaderWithToken(models.projectDetail.getPageOptions({
            project_id: `eq.${catarseVM.project_id()}`
        }));

        lProject.load().then((data) => {
            filterVM.project_id(_.first(data).common_id);
            // override default 'created_at' order on vm
            filterVM.order({ last_payment_data_created_at: 'desc' });
            subscriptions.firstPage(filterVM.parameters()).then(() => {
                loader(false);
                isProjectDataLoaded(true);
            }).catch(handleError);
            project(data);
        });

        return {
            filterVM,
            mapRewardsToOptions,
            filterBuilder,
            submit,
            subscriptions,
            lProject,
            project,
            isProjectDataLoaded,
            isRewardsDataLoaded
        };
    },
    view: function (ctrl, args) {

        const subsCollection = ctrl.subscriptions.collection(),
            filterBuilder = ctrl.filterBuilder,
            statusFilter = _.findWhere(filterBuilder, {
                label: 'status_filter'
            }),
            textFilter = _.findWhere(filterBuilder, {
                label: 'text_filter'
            }),
            rewardFilter = _.findWhere(filterBuilder, {
                label: 'reward_filter'
            }),
            paymentFilter = _.findWhere(filterBuilder, {
                label: 'payment_filter'
            }),
            totalPaidFilter = _.findWhere(filterBuilder, {
                label: 'total_paid_filter'
            }),
            paidCountFilter = _.findWhere(filterBuilder, {
                label: 'paid_count_filter'
            });
        rewardFilter.data.options = ctrl.mapRewardsToOptions();
        if (ctrl.isProjectDataLoaded() && ctrl.isRewardsDataLoaded()) {
            return m('div', [
                m.component(projectDashboardMenu, {
                    project: m.prop(_.first(ctrl.project()))
                }),
                m('.dashboard-header', [
                    m('.w-container',
                        m('.w-row', [
                            m('.w-col.w-col-3'),
                            m('.w-col.w-col-6',
                                m('.fontsize-larger.fontweight-semibold.lineheight-looser.u-marginbottom-30.u-text-center',
                                    'Base de assinantes'
                                )
                            ),
                            m('.w-col.w-col-3')
                        ])
                    ),
                    m('.u-marginbottom-30.w-container',
                        m('.w-form', [
                            m('form', {
                                onsubmit: ctrl.submit
                            },
                                m('w-row', [
                                    m.component(textFilter.component, textFilter.data),
                                    m('.w-col.w-col-9',
                                        m('.w-row', [
                                            m.component(statusFilter.component, statusFilter.data),
                                            m.component(rewardFilter.component, rewardFilter.data),
                                            m.component(paymentFilter.component, paymentFilter.data),
                                            m.component(totalPaidFilter.component, totalPaidFilter.data),
                                            m.component(paidCountFilter.component, paidCountFilter.data),
                                        ])
                                    )
                                ])
                            )
                        ])
                    )
                ]),
                m('.divider'),
                m('.before-footer.bg-gray.section', [
                    m('.w-container', [
                        m('div',
                            m('.w-row', [
                                m('.u-marginbottom-20.u-text-center-small-only.w-col.w-col-6',
                                    m('.w-inline-block.fontsize-base.u-marginright-10', [
                                        m('span.fontweight-semibold',
                                            ctrl.subscriptions.total()
                                        ),
                                        ' pessoas',
                                        m.trust(' ')
                                    ])
                                ),
                                m('.w-col.w-col-6',
                                    m(`a.alt-link.fontsize-small.u-right[href='/projects/${args.project_id}/subscriptions_report_download']`, {
                                        config: m.route
                                    }, [
                                            m('span.fa.fa-download',
                                                m.trust(' ')
                                            ),
                                            'Baixar relatórios'
                                        ])
                                )
                            ])
                        ),
                        m('.u-marginbottom-60', [
                            m('.card.card-secondary.fontsize-smallest.fontweight-semibold.lineheight-tighter.u-marginbottom-10',
                                m('.w-row', [
                                    m('.table-col.w-col.w-col-3',
                                        m('div',
                                            'Assinante'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2',
                                        m('div',
                                            'Recompensa'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-1.u-text-center',
                                        m('div',
                                            'Apoio mensal'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2.u-text-center',
                                        m('div',
                                            'Total apoiado'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2.u-text-center',
                                        m('div',
                                            'Última cobrança'
                                        )
                                    ),
                                    m('.table-col.w-col.w-col-2.u-text-center',
                                        m('div',
                                            'Status da Assinatura'
                                        )
                                    )
                                ])
                            ),
                            m('.fontsize-small', [
                                _.map(subsCollection, subscription =>
                                    m(dashboardSubscriptionCard, {
                                        subscription
                                    }))
                            ])
                        ])
                    ]),
                    m('.bg-gray.section',
                        m('.w-container',
                            m('.u-marginbottom-60.w-row', [
                                m(loadMoreBtn, {
                                    collection: ctrl.subscriptions,
                                    cssClass: '.w-col-push-4'
                                })
                            ])
                        )
                    )
                ])
            ]);
        }
        return m('', h.loader());
    }
};

export default projectSubscriptionReport;
<|endoftext|>


<commit_before>'use strict';

// Runs `bower install` in cwd
const fs = require('fs-extra');
const path = require('path');
const existsSync = require('exists-sync');
const execa = require('execa');
const RSVP = require('rsvp');
const Task = require('../models/task');
const formatPackageList = require('../utilities/format-package-list');

const logger = require('heimdalljs-logger')('ember-cli:tasks:bower-install');

const Promise = RSVP.Promise;
const resolve = RSVP.denodeify(require('resolve'));
const writeJson = RSVP.denodeify(fs.writeJson);

const cliPath = path.resolve(`${__dirname}/../..`);

class BowerInstallTask extends Task {

  resolveBower() {
    logger.info('Resolving "bower" from %s ...', cliPath);
    return resolve('bower', { basedir: cliPath });
  }

  importBower(path) {
    logger.info('Importing "bower" from: %s', path);
    this.bower = require(path);
  }

  ensureBower() {
    if (this.bower) {
      return Promise.resolve();
    }

    return this.resolveBower()
      .catch(error => {
        if (error.message.indexOf('Cannot find module \'bower\'') === -1) {
          throw error;
        }

        return this.installBower().then(() => this.resolveBower());
      })
      .then(bowerPath => this.importBower(bowerPath));
  }

  installBower() {
    logger.info('Installing "bower" via NPM into: %s', cliPath);

    let ui = this.ui;
    const chalk = require('chalk');

    ui.startProgress(chalk.green('NPM: Installing bower ...'));

    return Promise.resolve(execa('npm', ['install', 'bower@^1.3.12'], { cwd: cliPath }))
      .finally(() => ui.stopProgress())
      .then(() => ui.writeLine(chalk.green('NPM: Installed bower')));
  }

  get bowerJsonPath() {
    return path.join(this.project.root, 'bower.json');
  }

  hasBowerJson() {
    return existsSync(this.bowerJsonPath);
  }

  ensureBowerJson() {
    if (this.hasBowerJson()) {
      return Promise.resolve();
    }

    let projectName = this.project.name();
    let bowerJsonPath = this.bowerJsonPath;

    logger.info('Creating "bower.json" for: %s at: %s', projectName, bowerJsonPath);

    return writeJson(bowerJsonPath, { name: projectName });
  }

  // Options: Boolean verbose
  run(options) {
    let ui = this.ui;

    let packages = options.packages || [];
    let installOptions = options.installOptions || {};
    let savePackages = installOptions.save || installOptions.saveDev;

    // if we are running "bower install" from "ember init" and there is
    // no "bower.json" we return early
    if (!this.hasBowerJson() && !savePackages) {
      logger.info('Skipping "bower install" since "bower.json" does not exist');
      return Promise.resolve();
    }

    // resolve "bower" and install via NPM if necessary
    // -> then check if a "bower.json" file exists and create if necessary
    // -> then run the actual "bower install"
    return this.ensureBower().then(() => this.ensureBowerJson()).then(() => {
      const chalk = require('chalk');
      let bowerConfig = this.bowerConfig || require('bower-config');

      let startMessage = this.formatStartMessage(packages);
      let completeMessage = this.formatCompleteMessage(packages);

      logger.info('Installing %j via Bower with options: %j', packages, installOptions);

      ui.startProgress(chalk.green(startMessage));

      let config = bowerConfig.read();
      config.interactive = true;

      return new Promise((resolve, reject) => {
        this.bower.commands.install(packages, installOptions, config) // Packages, options, config
          .on('log', logBowerMessage)
          .on('prompt', ui.prompt.bind(ui))
          .on('error', reject)
          .on('end', resolve);
      })
        .finally(() => ui.stopProgress())
        .then(() => ui.writeLine(chalk.green(completeMessage)));

      function logBowerMessage(message) {
        if (message.level === 'conflict') {
          // e.g.
          //   conflict Unable to find suitable version for ember-data
          //     1) ember-data 1.0.0-beta.6
          //     2) ember-data ~1.0.0-beta.7
          ui.writeLine(`  ${chalk.red('conflict')} ${message.message}`);
          message.data.picks.forEach((pick, index) => {
            ui.writeLine(`    ${chalk.green(`${index + 1})`)} ${message.data.name} ${pick.endpoint.target}`);
          });
        } else if (message.level === 'info' && options.verbose) {
          // e.g.
          //   cached git://example.com/some-package.git#1.0.0
          ui.writeLine(`  ${chalk.green(message.id)} ${message.message}`);
        }
      }
    });
  }

  formatStartMessage(packages) {
    return `Bower: Installing ${formatPackageList(packages)} ...`;
  }

  formatCompleteMessage(packages) {
    return `Bower: Installed ${formatPackageList(packages)}`;
  }
}

module.exports = BowerInstallTask;
<commit_msg>tasks/bower-install: Add helpful error message for known npm bug<commit_after>'use strict';

// Runs `bower install` in cwd
const fs = require('fs-extra');
const path = require('path');
const existsSync = require('exists-sync');
const execa = require('execa');
const RSVP = require('rsvp');
const SilentError = require('silent-error');
const Task = require('../models/task');
const formatPackageList = require('../utilities/format-package-list');

const logger = require('heimdalljs-logger')('ember-cli:tasks:bower-install');

const Promise = RSVP.Promise;
const resolve = RSVP.denodeify(require('resolve'));
const writeJson = RSVP.denodeify(fs.writeJson);

const cliPath = path.resolve(`${__dirname}/../..`);

class BowerInstallTask extends Task {

  resolveBower() {
    logger.info('Resolving "bower" from %s ...', cliPath);
    return resolve('bower', { basedir: cliPath });
  }

  importBower(path) {
    logger.info('Importing "bower" from: %s', path);
    this.bower = require(path);
  }

  ensureBower() {
    if (this.bower) {
      return Promise.resolve();
    }

    return this.resolveBower()
      .catch(error => {
        if (error.message.indexOf('Cannot find module \'bower\'') === -1) {
          throw error;
        }

        return this.installBower().then(() => this.resolveBower());
      })
      .then(bowerPath => this.importBower(bowerPath));
  }

  installBower() {
    logger.info('Installing "bower" via NPM into: %s', cliPath);

    let ui = this.ui;
    const chalk = require('chalk');

    ui.startProgress(chalk.green('NPM: Installing bower ...'));

    return Promise.resolve(execa('npm', ['install', 'bower@^1.3.12'], { cwd: cliPath }))
      .finally(() => ui.stopProgress())
      .catch(error => this.handleInstallBowerError(error))
      .then(() => ui.writeLine(chalk.green('NPM: Installed bower')));
  }

  handleInstallBowerError(error) {
    if (error.message.indexOf('Cannot read property \'target\' of null') !== -1) {
      throw new SilentError('Bower could not be installed due to a bug in your npm installation.\n' +
        'Please update your npm version by running: npm install -g npm');
    }

    throw error;
  }

  get bowerJsonPath() {
    return path.join(this.project.root, 'bower.json');
  }

  hasBowerJson() {
    return existsSync(this.bowerJsonPath);
  }

  ensureBowerJson() {
    if (this.hasBowerJson()) {
      return Promise.resolve();
    }

    let projectName = this.project.name();
    let bowerJsonPath = this.bowerJsonPath;

    logger.info('Creating "bower.json" for: %s at: %s', projectName, bowerJsonPath);

    return writeJson(bowerJsonPath, { name: projectName });
  }

  // Options: Boolean verbose
  run(options) {
    let ui = this.ui;

    let packages = options.packages || [];
    let installOptions = options.installOptions || {};
    let savePackages = installOptions.save || installOptions.saveDev;

    // if we are running "bower install" from "ember init" and there is
    // no "bower.json" we return early
    if (!this.hasBowerJson() && !savePackages) {
      logger.info('Skipping "bower install" since "bower.json" does not exist');
      return Promise.resolve();
    }

    // resolve "bower" and install via NPM if necessary
    // -> then check if a "bower.json" file exists and create if necessary
    // -> then run the actual "bower install"
    return this.ensureBower().then(() => this.ensureBowerJson()).then(() => {
      const chalk = require('chalk');
      let bowerConfig = this.bowerConfig || require('bower-config');

      let startMessage = this.formatStartMessage(packages);
      let completeMessage = this.formatCompleteMessage(packages);

      logger.info('Installing %j via Bower with options: %j', packages, installOptions);

      ui.startProgress(chalk.green(startMessage));

      let config = bowerConfig.read();
      config.interactive = true;

      return new Promise((resolve, reject) => {
        this.bower.commands.install(packages, installOptions, config) // Packages, options, config
          .on('log', logBowerMessage)
          .on('prompt', ui.prompt.bind(ui))
          .on('error', reject)
          .on('end', resolve);
      })
        .finally(() => ui.stopProgress())
        .then(() => ui.writeLine(chalk.green(completeMessage)));

      function logBowerMessage(message) {
        if (message.level === 'conflict') {
          // e.g.
          //   conflict Unable to find suitable version for ember-data
          //     1) ember-data 1.0.0-beta.6
          //     2) ember-data ~1.0.0-beta.7
          ui.writeLine(`  ${chalk.red('conflict')} ${message.message}`);
          message.data.picks.forEach((pick, index) => {
            ui.writeLine(`    ${chalk.green(`${index + 1})`)} ${message.data.name} ${pick.endpoint.target}`);
          });
        } else if (message.level === 'info' && options.verbose) {
          // e.g.
          //   cached git://example.com/some-package.git#1.0.0
          ui.writeLine(`  ${chalk.green(message.id)} ${message.message}`);
        }
      }
    });
  }

  formatStartMessage(packages) {
    return `Bower: Installing ${formatPackageList(packages)} ...`;
  }

  formatCompleteMessage(packages) {
    return `Bower: Installed ${formatPackageList(packages)}`;
  }
}

module.exports = BowerInstallTask;
<|endoftext|>


<commit_before>(function(Items) {

	// This will fetch the tutorial template and render it.
	Items.Views.Thumb = Backbone.View.extend({

		tagName : 'li',

		className:'list-fancymedia',

		events: {

		    //'click': function(){alert('hi');},
		    'mouseenter':function () {

						    $(this.el).css('color','#08c');
						    $(this.el).css('cursor','move');
						    $(this.el).find('.jdicon-small-drag').show();

						  },
			'mouseleave':function () {

						    $(this.el).css('color','inherit');
						    $(this.el).css('cursor','auto');
						    $(this.el).find('.jdicon-small-drag').hide();

						  },
		 },
		 initialize: function () {

	        this.el.id = this.model.id;

	        //this is for fancy box to know to group these into a gallery
	        $(this.el).attr("rel", "group");

    	},
		render: function(done)
		{
			var _this = this;

			var template = (this.model.get('media_type') == 'Collection' ? this.getCollectionTemplate() : this.getDefaultTemplate());
			var blanks = this.model.attributes;

			$(this.el).html( _.template( template, blanks ) );

			//if no thumbnail or if it's a tweet then just show the grey icon instead of thumb
			if (this.model.get('media_type') == 'Tweet' || this.model.get('thumbnail_url').length ==0)
			{

				$(this.el).find('img').replaceWith(	'');
			}
			if (this.model.get('media_type') == 'Collection')
			{
				$(this.el).find('.label').show();
				$(this.el).find('img').css('opacity','0.8');
				$(this.el).find('.label').click(function(){
					jda.app.addCollectionFilter(_this.model);
					return false;
				});
				$(this.el).hover(
					function(){
						$(_this.el).find('img').css('opacity','1.0');
					},function(){
						$(_this.el).find('img').css('opacity','0.8');
					}
				);
			} else{
				$(this.el).popover({'title':this.model.get('title'), 'content':this.model.get('description'), 'delay':{ show: 2000, hide: 100 },'placement':'bottom'});

			}
			$(this.el).draggable({

			    cursor : 'move',
			    appendTo : 'body',
			    opacity : .8,

			    helper : function(){
			      var drag = $(this)
			      .clone()
			      .css({
			      	'width':'940px',
			        'z-index':'3',

			      });
			      return drag;
			    },

			      //init the dragged item variable
			      start : function(){
			        $(this).draggable('option','revert',true);

			      },

			      stop : function(){

			      }

			});
			$(this.el).find(".jdicon-small-drag").tooltip({'title':'Drag to add to your collection','placement':'bottom', delay: { show: 600, hide: 100 }});
			//$(this.el).find(".label").tooltip({'placement':'bottom', delay: { show: 600, hide: 100 }});

			//Replace broken thumbnail images with the media type icon
			$(this.el).find('img').error(function() {
			  $(_this.el).find('img').replaceWith(	'');
			});
			return this;
		},

		getCollectionTemplate : function()
		{
			var html =

				''+
					''+
					''+
					' <%= child_items_count%> items'+
					'<img src="<%=thumbnail_url%>" alt="<%=title%>" style="width:160px;height:120px">'+

				'';

			return html;
		},
		getDefaultTemplate : function()
		{

			var html =

				''+
					''+
					'<img src="<%=thumbnail_url%>" alt="<%=title%>" style="width:160px;height:120px">'+
				'';

			return html;

		}

	});

})(jda.module("items"));<commit_msg>collection thumbnails UI<commit_after>(function(Items) {

	// This will fetch the tutorial template and render it.
	Items.Views.Thumb = Backbone.View.extend({

		tagName : 'li',

		className:'list-fancymedia',

		events: {

		    //'click': function(){alert('hi');},
		    'mouseenter':function () {

						    $(this.el).css('color','#08c');
						    $(this.el).css('cursor','move');
						    $(this.el).find('.jdicon-small-drag').show();

						  },
			'mouseleave':function () {

						    $(this.el).css('color','inherit');
						    $(this.el).css('cursor','auto');
						    $(this.el).find('.jdicon-small-drag').hide();

						  },
		 },
		 initialize: function () {

	        this.el.id = this.model.id;

	        //this is for fancy box to know to group these into a gallery
	        $(this.el).attr("rel", "group");

    	},
		render: function(done)
		{
			var _this = this;

			var template = (this.model.get('media_type') == 'Collection' ? this.getCollectionTemplate() : this.getDefaultTemplate());
			var blanks = this.model.attributes;

			$(this.el).html( _.template( template, blanks ) );

			//if no thumbnail or if it's a tweet then just show the grey icon instead of thumb
			if (this.model.get('media_type') == 'Tweet' || this.model.get('thumbnail_url').length ==0)
			{

				$(this.el).find('img').replaceWith(	'');
			}
			if (this.model.get('media_type') == 'Collection')
			{
				$(this.el).find('.label').show();

				$(this.el).find('.label').click(function(){
					jda.app.addCollectionFilter(_this.model);
					return false;
				});

			} else{
				$(this.el).popover({'title':this.model.get('title'), 'content':this.model.get('description'), 'delay':{ show: 2000, hide: 100 },'placement':'bottom'});

			}
			$(this.el).draggable({

			    cursor : 'move',
			    appendTo : 'body',
			    opacity : .8,

			    helper : function(){
			      var drag = $(this)
			      .clone()
			      .css({
			      	'width':'940px',
			        'z-index':'3',

			      });
			      return drag;
			    },

			      //init the dragged item variable
			      start : function(){
			        $(this).draggable('option','revert',true);

			      },

			      stop : function(){

			      }

			});
			$(this.el).find(".jdicon-small-drag").tooltip({'title':'Drag to add to your collection','placement':'bottom', delay: { show: 600, hide: 100 }});
			$(this.el).find(".label").tooltip({'placement':'bottom', delay: { show: 600, hide: 100 }});

			//Replace broken thumbnail images with the media type icon
			$(this.el).find('img').error(function() {
			  $(_this.el).find('img').replaceWith(	'');
			});
			return this;
		},

		getCollectionTemplate : function()
		{
			var html =

				''+
					''+
					''+
					''+
					'<img src="<%=thumbnail_url%>" alt="<%=title%>" style="width:160px;height:120px">'+

				'';

			return html;
		},
		getDefaultTemplate : function()
		{

			var html =

				''+
					''+
					'<img src="<%=thumbnail_url%>" alt="<%=title%>" style="width:160px;height:120px">'+
				'';

			return html;

		}

	});

})(jda.module("items"));<|endoftext|>


<commit_before>(function(Browser) {

	Browser.Users = Browser.Users || {};
	Browser.Users.Views = Browser.Users || {};

	Browser.Users.Views.UserPage = Backbone.View.extend({

		el : $('#jda-user-filter'),

		events: {

			'click button.edit' : 'editMetadata',
			'click button.save' : 'saveMetadata',
			'click button.cancel' : 'cancelEdits',
		},
		initialize: function () {

			//for looking up address from lat/lon
			this.geocoder = new google.maps.Geocoder();

			var facetExists = false;

			/* Adjust layout for filter */
			//$('.tab-content').addClass('jda-low-top');
			$('#zeega-right-column').addClass('zeega-right-column-user-page');

			//first remove other user filters
			_.each( VisualSearch.searchBox.facetViews, function( facet ){
				if (facet.model.get("category")=="user" && facet.model.get("value") != _this.model.get('display_name')) {
					facet.model.set({'value': null });
					facet.remove();
				} else if (facet.model.get("category")=="user" && facet.model.get("value") == _this.model.get('display_name')){
					facetExists = true;
				}
			});

			//add user filter to the VisualSearch box
			if (!facetExists){
				VisualSearch.searchBox.addFacet('user', this.model.get('display_name'), 0);
			}

			//user filter close removes the filter from the DOM and sets the object to null
			_.each( VisualSearch.searchBox.facetViews, function( facet ){

				if (facet.model.get("category")=="user") {
					$(facet.el).find('.VS-icon-cancel').click(function(){
						jda.app.removeFilter('user');

					});
				}
			});

		},
		render: function(done)
		{
			var _this = this;

			/***************************************************************************
				Put template together
			***************************************************************************/
			var template = this.getTemplate();
			var blanks = this.model.attributes;

			$(this.el).html( _.template( template, blanks ) );

			$(this.el).find('.jda-user-filter-edit-profile-image').click(function(){
				alert('Edits profile image for user');
				return false;
			});

			/***************************************************************************
				Map
			***************************************************************************/
			this.cloudmadeUrl = 'http://{s}.tiles.mapbox.com/v2/mapbox.mapbox-streets/{z}/{x}/{y}.png',
	    	this.cloudmadeAttrib = '',
	   		this.cloudmade = new L.TileLayer(this.cloudmadeUrl, {maxZoom: 18, attribution: this.cloudmadeAttrib});

			var values = {
				latitude : 38.266667,//this.model.get('media_geo_latitude'),
				longitude : 140.866667,
			};
			this.latlng = new L.LatLng( values.latitude,values.longitude);
			var div = $(this.el).find('.jda-user-map').get(0);
			this.map = new L.Map(div);
			this.map.setView(this.latlng, 8).addLayer(this.cloudmade);
			this.marker = new L.Marker(this.latlng,{draggable:true});
			this.marker.addEventListener( 'drag', this.updateLatLng, this );
			this.marker.addEventListener( 'dragend', this.updateLocation, this );
			this.map.addLayer(this.marker);

			this.geocoder.geocode( { 'latLng' : new google.maps.LatLng(values.latitude,values.longitude) }, function(results, status) {
				if (status == google.maps.GeocoderStatus.OK) {
					if (results[0].formatted_address)
					{
						console.log(results)
						$(_this.el).find('.jda-collection-map-location').html( results[ results.length-3 ].formatted_address );
					}
				}
			});

			/***************************************************************************
				Edit button
			***************************************************************************/
			if (this.model.get('editable')){
				$(this.el).find('button.edit').show();

			}

			return this;
		},
		saveMetadata : function()
		{
			this.turnOffEditMode();
			this.saveFields();
		},

		saveFields : function()
		{
			//TODO - WTH  -why isn't setting proper values?

			this.model.save({

				'bio' : $(this.el).find('.jda-user-filter-description').text(),
				'thumbnail_url' : $(this.el).find('.jda-user-filter-profile-image').attr('src'),
				//TODO SAVE GEO COORDINATES
			})
		},

		cancelEdits : function()
		{
			this.turnOffEditMode();
		},

		turnOffEditMode : function()
		{
			$(this.el).find('.jda-user-edit-profile-image').hide();
			$(this.el).find('button.edit').removeClass('active');
			$(this.el).find('.editing').removeClass('editing').attr('contenteditable', false);
			$(this.el).find('.jda-user-map-location').removeClass('editing').attr('contenteditable', false);
			$(this.el).find('.save-data button').hide();
		},
		editMetadata : function()
		{
			console.log('edit the metadata!')
			var _this  = this;

			$(this.el).find('.jda-user-edit-profile-image').show();
			$(this.el).find('.save-data button').show();
			$(this.el).find('button.edit').addClass('active');
			$(this.el).find('.jda-user-filter-description').addClass('editing').attr('contenteditable', true);

			$(this.el).find('.jda-user-map-location').addClass('editing').attr('contenteditable', true).keypress(function(e){
				if(e.which==13)
				{
					_this.geocodeString();
					return false;
				}
			});

			$(this.el).find('.jda-user-edit-profile-image').droppable({
			    accept : '.list-fancymedia',

			    tolerance : 'pointer',
			    over: function(event, ui) {
			    	var newCover = jda.app.draggedItem.get('thumbnail_url');
			      	$(_this.el).find('.jda-user-filter-profile-image').attr('src', newCover).show();
				 	$(_this.el).find('.jda-user-edit-profile-image').hide();
			    },
			    out: function(){

			      	$(_this.el).find('.jda-user-filter-profile-image').hide();
				 	$(_this.el).find('.jda-user-edit-profile-image').show();
			    },
			    drop : function( event, ui )
			    {

			      	var newCover = jda.app.draggedItem.get('thumbnail_url');
			      	$(_this.el).find('.jda-user-filter-profile-image').attr('src', newCover).show();
				 	$(_this.el).find('.jda-user-edit-profile-image').hide();

			      ui.draggable.draggable('option','revert',false);

			    }
			});
		},
		geocodeString : function()
		{
			var _this = this;
			var placeText = $(this.el).find('.jda-user-map-location').text();
			this.geocoder.geocode( { 'address': placeText}, function(results, status) {

				if (status == google.maps.GeocoderStatus.OK)
				{
					console.log(results)
					_this.latlng=new L.LatLng(results[0].geometry.location.lat(),results[0].geometry.location.lng());

					_this.map.setView( _this.latlng,8);
					_this.marker.setLatLng(_this.latlng);
					console.log(results[0].geometry.location.lat(),results[0].geometry.location.lng())
					/*_this.model.save({
						'media_geo_latitude': results[0].geometry.location.lat(),
						'media_geo_longitude': results[0].geometry.location.lng()
					})*/
				}
				else console.log("Geocoder failed at address look for "+$(that.el).find('.locator-search-input').val()+": " + status);
			});
		},
		remove:function(){

			//remove from DOM
			$(this.el).empty();
			$('.jda-separate-collections-and-items').hide();
			$('.tab-content').removeClass('jda-low-top');

			$('.tab-content').css('top','auto');

			$('#zeega-right-column').removeClass('zeega-right-column-user-page');

		},

		getTemplate : function()
		{
			html =

			'
'+
				'<img class="pull-left jda-user-filter-profile-image" src="<%=thumbnail_url%>" alt="" style="width:160px;height:160px;margin-right:10px;border: 1px solid grey;">'+
				'
'+
					' '+
					'
Drag a new image here
'+
				'
'+
			'
'+
			'
'+
				'
<%=display_name%>
'+

				'
'+
					'
Joined on March 20th, 2012
'+
					'<%=bio%>'+
					'
<button class="btn btn-info btn-mini edit" style="display:none"></button>
'+
					'
'+
						'<button class="btn btn-success btn-mini save hide">save</button>'+
						'<button class="btn btn-mini cancel hide">cancel</button>'+
					'
'+
				'
'+
				'
'+
					'

'+
					'

'+
				'
'+
			'
';

			return html;
		},

	});

})(jda.module("browser"));<commit_msg>updates to user page<commit_after>(function(Browser) {

	Browser.Users = Browser.Users || {};
	Browser.Users.Views = Browser.Users || {};

	Browser.Users.Views.UserPage = Backbone.View.extend({

		el : $('#jda-user-filter'),

		events: {

			'click button.edit' : 'editMetadata',
			'click button.save' : 'saveMetadata',
			'click button.cancel' : 'cancelEdits',
		},
		initialize: function () {

			//for looking up address from lat/lon
			this.geocoder = new google.maps.Geocoder();

			var facetExists = false;

			/* Adjust layout for filter */
			//$('.tab-content').addClass('jda-low-top');
			$('#zeega-right-column').addClass('zeega-right-column-user-page');

			//first remove other user filters
			_.each( VisualSearch.searchBox.facetViews, function( facet ){
				if (facet.model.get("category")=="user" && facet.model.get("value") != _this.model.get('display_name')) {
					facet.model.set({'value': null });
					facet.remove();
				} else if (facet.model.get("category")=="user" && facet.model.get("value") == _this.model.get('display_name')){
					facetExists = true;
				}
			});

			//add user filter to the VisualSearch box
			if (!facetExists){
				VisualSearch.searchBox.addFacet('user', this.model.get('display_name'), 0);
			}

			//user filter close removes the filter from the DOM and sets the object to null
			_.each( VisualSearch.searchBox.facetViews, function( facet ){

				if (facet.model.get("category")=="user") {
					$(facet.el).find('.VS-icon-cancel').click(function(){
						jda.app.removeFilter('user');

					});
				}
			});

		},
		render: function(done)
		{
			var _this = this;

			/***************************************************************************
				Put template together
			***************************************************************************/
			var template = this.getTemplate();
			var blanks = this.model.attributes;

			if (blanks["created_at"] == null){
				blanks["created_at"] = "March 20th, 2011";
			}
			$(this.el).html( _.template( template, blanks ) );

			$(this.el).find('.jda-user-filter-edit-profile-image').click(function(){
				alert('Edits profile image for user');
				return false;
			});

			/***************************************************************************
				Map
			***************************************************************************/
			this.cloudmadeUrl = 'http://{s}.tiles.mapbox.com/v2/mapbox.mapbox-streets/{z}/{x}/{y}.png',
	    	this.cloudmadeAttrib = '',
	   		this.cloudmade = new L.TileLayer(this.cloudmadeUrl, {maxZoom: 18, attribution: this.cloudmadeAttrib});

			var values = {
				latitude : this.model.get('location_latitude') == null ? 38.266667 : this.model.get('location_latitude'),//this.model.get('media_geo_latitude'),
				longitude : this.model.get('location_longitude') == null ? 140.866667 : this.model.get('location_longitude'),
			};
			this.latlng = new L.LatLng( values.latitude,values.longitude);
			var div = $(this.el).find('.jda-user-map').get(0);
			this.map = new L.Map(div);
			this.map.setView(this.latlng, 8).addLayer(this.cloudmade);
			this.marker = new L.Marker(this.latlng,{draggable:true});
			this.marker.addEventListener( 'drag', this.updateLatLng, this );
			this.marker.addEventListener( 'dragend', this.updateLocation, this );
			this.map.addLayer(this.marker);

			this.geocoder.geocode( { 'latLng' : new google.maps.LatLng(values.latitude,values.longitude) }, function(results, status) {
				if (status == google.maps.GeocoderStatus.OK) {
					if (results[0].formatted_address)
					{
						console.log(results)
						$(_this.el).find('.jda-collection-map-location').html( results[ results.length-3 ].formatted_address );
					}
				}
			});

			/***************************************************************************
				Edit button
			***************************************************************************/
			if (this.model.get('editable')){
				$(this.el).find('button.edit').show();

			}

			return this;
		},
		saveMetadata : function()
		{
			this.turnOffEditMode();
			this.saveFields();
		},

		saveFields : function()
		{

			this.model.save({

				'bio' : $(this.el).find('.jda-user-filter-description').text(),
				'thumbnail_url' : $(this.el).find('.jda-user-filter-profile-image').attr('src'),

			})
		},

		cancelEdits : function()
		{
			this.turnOffEditMode();
		},

		turnOffEditMode : function()
		{
			$(this.el).find('.jda-user-edit-profile-image').hide();
			$(this.el).find('button.edit').removeClass('active');
			$(this.el).find('.editing').removeClass('editing').attr('contenteditable', false);
			$(this.el).find('.jda-user-map-location').removeClass('editing').attr('contenteditable', false);
			$(this.el).find('.save-data button').hide();
		},
		editMetadata : function()
		{
			console.log('edit the metadata!')
			var _this  = this;

			$(this.el).find('.jda-user-edit-profile-image').show();
			$(this.el).find('.save-data button').show();
			$(this.el).find('button.edit').addClass('active');
			$(this.el).find('.jda-user-filter-description').addClass('editing').attr('contenteditable', true);

			$(this.el).find('.jda-user-map-location').addClass('editing').attr('contenteditable', true).keypress(function(e){
				if(e.which==13)
				{
					_this.geocodeString();
					return false;
				}
			});

			$(this.el).find('.jda-user-edit-profile-image').droppable({
			    accept : '.list-fancymedia',

			    tolerance : 'pointer',
			    over: function(event, ui) {
			    	var newCover = jda.app.draggedItem.get('thumbnail_url');
			      	$(_this.el).find('.jda-user-filter-profile-image').attr('src', newCover).show();
				 	$(_this.el).find('.jda-user-edit-profile-image').hide();
			    },
			    out: function(){

			      	$(_this.el).find('.jda-user-filter-profile-image').hide();
				 	$(_this.el).find('.jda-user-edit-profile-image').show();
			    },
			    drop : function( event, ui )
			    {

			      	var newCover = jda.app.draggedItem.get('thumbnail_url');
			      	$(_this.el).find('.jda-user-filter-profile-image').attr('src', newCover).show();
				 	$(_this.el).find('.jda-user-edit-profile-image').hide();

			      ui.draggable.draggable('option','revert',false);

			    }
			});
		},
		geocodeString : function()
		{
			var _this = this;
			var placeText = $(this.el).find('.jda-user-map-location').text();
			this.geocoder.geocode( { 'address': placeText}, function(results, status) {

				if (status == google.maps.GeocoderStatus.OK)
				{
					console.log(results)
					_this.latlng=new L.LatLng(results[0].geometry.location.lat(),results[0].geometry.location.lng());

					_this.map.setView( _this.latlng,8);
					_this.marker.setLatLng(_this.latlng);
					console.log(results[0].geometry.location.lat(),results[0].geometry.location.lng())
					_this.model.save({
						'location_latitude': results[0].geometry.location.lat(),
						'location_longitude': results[0].geometry.location.lng()
					})
				}
				else console.log("Geocoder failed at address look for "+$(that.el).find('.locator-search-input').val()+": " + status);
			});
		},
		remove:function(){

			//remove from DOM
			$(this.el).empty();
			$('.jda-separate-collections-and-items').hide();
			$('.tab-content').removeClass('jda-low-top');

			$('.tab-content').css('top','auto');

			$('#zeega-right-column').removeClass('zeega-right-column-user-page');

		},

		getTemplate : function()
		{
			html =

			'
'+
				'<img class="pull-left jda-user-filter-profile-image" src="<%=thumbnail_url%>" alt="" style="width:160px;height:160px;margin-right:10px;border: 1px solid grey;">'+
				'
'+
					' '+
					'
Drag a new image here
'+
				'
'+
			'
'+
			'
'+
				'
<%=display_name%>
'+

				'
'+
					'
Joined on <%= created_at%>
'+
					'<%=bio%>'+
					'
<button class="btn btn-info btn-mini edit" style="display:none"></button>
'+
					'
'+
						'<button class="btn btn-success btn-mini save hide">save</button>'+
						'<button class="btn btn-mini cancel hide">cancel</button>'+
					'
'+
				'
'+
				'
'+
					'

'+
					'

'+
				'
'+
			'
';

			return html;
		},

	});

})(jda.module("browser"));<|endoftext|>


<commit_before>'use strict';

const http = require('http');

/**
 * @param {Object}  options
 */
class TokendTransformer {
  constructor(options) {
    options = Object.assign({
      host: '127.0.0.1',
      port: 4500
    }, options);

    this.host = options.host;
    this.port = options.port;
  }

  /**
   * Transform properties by fetching secrets from tokend
   *
   * @param  {Object}  properties
   * @return {Promise<Properties>}  resolved after properties have been transformed
   */
  transform(properties) {
    const promises = [];
    const transformedProperties = {};
    let key = null, keys = [];

    for (key in properties) {
      keys = Object.keys(properties[key]);
      if (keys.length === 1 && keys[0] === '$tokend') {
        promises.push(new Promise((resolve, reject) => {
          const params = properties[key]['$tokend'];
          let data = '';

          const req = http.get({
            host: this.host,
            port: this.port,
            path: params.resource
          }, (res) => {
            res.setEncoding('utf8');
            res.on('data', (chunk) => {
              data += chunk;
            });
            res.on('end', () => {
              data = JSON.parse(data);
              transformedProperties[key] = data.secret;
              resolve();
            });
          });

          req.on('error', (e) => {
            reject(e);
          });
        }));
      }
    }

    return Promise.all(promises).then(() => {
      return Object.assign({}, properties, transformedProperties);
    });
  }
}

module.exports = TokendTransformer;
<commit_msg>Refactor to remove lint complaints about for loops.<commit_after>'use strict';

const http = require('http');

/**
 * @param {Object}  options
 */
class TokendTransformer {
  constructor(options) {
    options = Object.assign({
      host: '127.0.0.1',
      port: 4500
    }, options);

    this.host = options.host;
    this.port = options.port;
  }

  /**
   * Transform properties by fetching secrets from tokend
   *
   * @param  {Object}  properties
   * @return {Promise<Properties>}  resolved after properties have been transformed
   */
  transform(properties) {
    const transformedProperties = {};

    const promises = Object.keys(properties).filter((key) => {
      const keys = Object.keys(properties[key]);

      return keys.length === 1 && keys[0] === '$tokend';
    }).map((key) => {
      return new Promise((resolve, reject) => {
        const params = properties[key].$tokend;
        let data = '';

        const req = http.get({
          host: this.host,
          port: this.port,
          path: params.resource
        }, (res) => {
          res.setEncoding('utf8');
          res.on('data', (chunk) => {
            data += chunk;
          });
          res.on('end', () => {
            data = JSON.parse(data);
            transformedProperties[key] = data.secret;
            resolve();
          });
        });

        req.on('error', (e) => {
          reject(e);
        });
      });
    });

    return Promise.all(promises).then(() => {
      return Object.assign({}, properties, transformedProperties);
    });
  }
}

module.exports = TokendTransformer;
<|endoftext|>


<commit_before>var _ = require('lodash'),
    async = require('async'),
    seq = require('seq'),
    query = require('../query');

module.exports = function (options) {
    options = options || {};
    var followRelationsMatcher = query.queryObjToMatcherFunction(options.followRelations),
        stopAssetsMatcher = function () {
            return false;
        };

    if (options.stopAssets) {
        stopAssetsMatcher = query.queryObjToMatcherFunction(options.stopAssets);
    }
    return function populate(assetGraph, cb) {
        var assetQueue = assetGraph.findAssets(_.extend({isInline: false}, options.startAssets || options.from)),
            maxWaitingCallbacks = options.concurrency || 100,
            numWaitingCallbacks = 0,
            firstErrorOrNull = null;

        (function proceed() {
            function processAssetCallback(err) {
                if (err && !firstErrorOrNull) {
                    firstErrorOrNull = err;
                }
                numWaitingCallbacks -= 1;
                proceed();
            }
            while (!firstErrorOrNull && assetQueue.length && numWaitingCallbacks < maxWaitingCallbacks) {
                numWaitingCallbacks += 1;
                processAsset(assetQueue.shift(), processAssetCallback);
            }
            if (numWaitingCallbacks === 0) {
                cb(firstErrorOrNull);
            }
        }());

        function processAsset(asset, cb) {
            seq()
                .seq(function () {
                    var callback = this;
                    asset.load(function (err) {
                        if (err) {
                            err.message += '\nIncluding assets:\n    ' + asset.incomingRelations.map(function (incomingRelation) {
                                return incomingRelation.from.urlOrDescription;
                            }).join('\n    ') + '\n';
                            err.asset = asset;
                            assetGraph.emit('warn', err);
                            return cb();
                        }
                        var externalRelations = [];
                        (function gatherExternalRelations(asset) {
                            if (asset.keepUnpopulated) {
                                return;
                            }
                            asset.outgoingRelations.forEach(function (outgoingRelation) {
                                if (outgoingRelation.to.isInline) {
                                    gatherExternalRelations(outgoingRelation.to);
                                } else if (!outgoingRelation.to.isAsset) {
                                    externalRelations.push(outgoingRelation);
                                }
                            });
                        }(asset));
                        callback(null, externalRelations);
                    });
                })
                .flatten()
                .parEach(function (originalRelation) {
                    originalRelation.resolve(function (err, resolvedAssetConfig) {
                        if (!err) {
                            this.vars[originalRelation.id] = resolvedAssetConfig;
                        }
                        this();
                    }.bind(this));
                })
                .seqEach(function (originalRelation) {
                    var multipliedRelations = this.vars[originalRelation.id] || [];
                    async.eachLimit(multipliedRelations, 1, function (multipliedRelation, cb) {
                        if (followRelationsMatcher(multipliedRelation, assetGraph)) {
                            assetGraph.ensureAssetConfigHasType(multipliedRelation.to, function (err) {
                                if (err) {
                                    err.message += '\nIncluding asset [' + multipliedRelation.type + ']: ' + multipliedRelation.from.nonInlineAncestor.url;
                                    err.asset = multipliedRelation.to;
                                    err.relation = multipliedRelation;
                                    assetGraph.emit('warn', err);
                                    return cb();
                                }

                                var targetAsset;
                                if (multipliedRelation.to.url) {
                                    // See if the target asset is already in the graph by looking up its url:
                                    var targetAssets = assetGraph.findAssets({
                                        url: multipliedRelation.to.url
                                    });
                                    // If multiple assets share the url, prefer the one that was added last (should be customizable?):
                                    if (targetAssets.length) {
                                        targetAsset = targetAssets[targetAssets.length - 1];
                                    }
                                }
                                if (targetAsset) {
                                    multipliedRelation.to = targetAsset;
                                    multipliedRelation.refreshHref();
                                } else {
                                    multipliedRelation.to = assetGraph.createAsset(multipliedRelation.to);
                                    assetGraph.addAsset(multipliedRelation.to);
                                    if (!stopAssetsMatcher(multipliedRelation.to)) {
                                        assetQueue.push(multipliedRelation.to);
                                    }
                                }
                                cb();
                            });
                        } else {
                            setImmediate(cb);
                        }
                    }, this);
                })
                .seq(function () {
                    cb();
                })['catch'](cb);
        }
    };
};
<commit_msg>populate: Default to assetGraph.followRelations if the option isn't given explicitly.<commit_after>var _ = require('lodash'),
    async = require('async'),
    seq = require('seq'),
    query = require('../query');

module.exports = function (options) {
    options = options || {};
    var stopAssetsMatcher = function () {
        return false;
    };

    if (options.stopAssets) {
        stopAssetsMatcher = query.queryObjToMatcherFunction(options.stopAssets);
    }
    return function populate(assetGraph, cb) {
        var followRelationsMatcher = query.queryObjToMatcherFunction(options.followRelations || assetGraph.followRelations),
            assetQueue = assetGraph.findAssets(_.extend({isInline: false}, options.startAssets || options.from)),
            maxWaitingCallbacks = options.concurrency || 100,
            numWaitingCallbacks = 0,
            firstErrorOrNull = null;

        (function proceed() {
            function processAssetCallback(err) {
                if (err && !firstErrorOrNull) {
                    firstErrorOrNull = err;
                }
                numWaitingCallbacks -= 1;
                proceed();
            }
            while (!firstErrorOrNull && assetQueue.length && numWaitingCallbacks < maxWaitingCallbacks) {
                numWaitingCallbacks += 1;
                processAsset(assetQueue.shift(), processAssetCallback);
            }
            if (numWaitingCallbacks === 0) {
                cb(firstErrorOrNull);
            }
        }());

        function processAsset(asset, cb) {
            seq()
                .seq(function () {
                    var callback = this;
                    asset.load(function (err) {
                        if (err) {
                            err.message += '\nIncluding assets:\n    ' + asset.incomingRelations.map(function (incomingRelation) {
                                return incomingRelation.from.urlOrDescription;
                            }).join('\n    ') + '\n';
                            err.asset = asset;
                            assetGraph.emit('warn', err);
                            return cb();
                        }
                        var externalRelations = [];
                        (function gatherExternalRelations(asset) {
                            if (asset.keepUnpopulated) {
                                return;
                            }
                            asset.outgoingRelations.forEach(function (outgoingRelation) {
                                if (outgoingRelation.to.isInline) {
                                    gatherExternalRelations(outgoingRelation.to);
                                } else if (!outgoingRelation.to.isAsset) {
                                    externalRelations.push(outgoingRelation);
                                }
                            });
                        }(asset));
                        callback(null, externalRelations);
                    });
                })
                .flatten()
                .parEach(function (originalRelation) {
                    originalRelation.resolve(function (err, resolvedAssetConfig) {
                        if (!err) {
                            this.vars[originalRelation.id] = resolvedAssetConfig;
                        }
                        this();
                    }.bind(this));
                })
                .seqEach(function (originalRelation) {
                    var multipliedRelations = this.vars[originalRelation.id] || [];
                    async.eachLimit(multipliedRelations, 1, function (multipliedRelation, cb) {
                        if (followRelationsMatcher(multipliedRelation, assetGraph)) {
                            assetGraph.ensureAssetConfigHasType(multipliedRelation.to, function (err) {
                                if (err) {
                                    err.message += '\nIncluding asset [' + multipliedRelation.type + ']: ' + multipliedRelation.from.nonInlineAncestor.url;
                                    err.asset = multipliedRelation.to;
                                    err.relation = multipliedRelation;
                                    assetGraph.emit('warn', err);
                                    return cb();
                                }

                                var targetAsset;
                                if (multipliedRelation.to.url) {
                                    // See if the target asset is already in the graph by looking up its url:
                                    var targetAssets = assetGraph.findAssets({
                                        url: multipliedRelation.to.url
                                    });
                                    // If multiple assets share the url, prefer the one that was added last (should be customizable?):
                                    if (targetAssets.length) {
                                        targetAsset = targetAssets[targetAssets.length - 1];
                                    }
                                }
                                if (targetAsset) {
                                    multipliedRelation.to = targetAsset;
                                    multipliedRelation.refreshHref();
                                } else {
                                    multipliedRelation.to = assetGraph.createAsset(multipliedRelation.to);
                                    assetGraph.addAsset(multipliedRelation.to);
                                    if (!stopAssetsMatcher(multipliedRelation.to)) {
                                        assetQueue.push(multipliedRelation.to);
                                    }
                                }
                                cb();
                            });
                        } else {
                            setImmediate(cb);
                        }
                    }, this);
                })
                .seq(function () {
                    cb();
                })['catch'](cb);
        }
    };
};
<|endoftext|>