<commit_before>import $ from 'jquery';
import _ from 'underscore';
import 'jquery-zoom';
import is from 'is_js';
import app from '../../../app';
import '../../../lib/select2';
import '../../../utils/velocity';
import { getAvatarBgImage } from '../../../utils/responsive';
import { convertAndFormatCurrency } from '../../../utils/currency';
import loadTemplate from '../../../utils/loadTemplate';
import { launchEditListingModal } from '../../../utils/modalManager';
import { getTranslatedCountries } from '../../../data/countries';
import BaseModal from '../BaseModal';
import Purchase from '../purchase/Purchase';
import Rating from './Rating';
import Reviews from './Reviews';
import { events as listingEvents } from '../../../models/listing/';
import PopInMessage from '../../PopInMessage';
import { openSimpleMessage } from '../SimpleMessage';

export default class extends BaseModal {
  constructor(options = {}) {
    if (!options.model) {
      throw new Error('Please provide a model.');
    }

    const opts = {
      removeOnClose: false,
      ...options,
    };

    super(opts);
    this.options = opts;
    this._shipsFreeToMe = this.model.shipsFreeToMe;
    this.activePhotoIndex = 0;
    this.totalPrice = this.model.get('item').get('price');

    // Sometimes a profile model is available and the vendor info
    // can be obtained from that.
    if (opts.profile) {
      const avatarHashes = opts.profile.get('avatarHashes');

      this.vendor = {
        peerID: opts.profile.id,
        name: opts.profile.get('name'),
        handle: opts.profile.get('handle'),
        avatar: {
          tiny: avatarHashes.get('tiny'),
          small: avatarHashes.get('small'),
        },
      };
    }

    // In most cases the page opening this modal will already have and be able
    // to provide the vendor information. If it cannot, then I suppose we
    // could fetch the profile and lazy load it in, but we can cross that
    // bridge when we get to it.
    this.vendor = this.vendor || opts.vendor;

    this.countryData = getTranslatedCountries(app.settings.get('language'))
      .map(countryObj => ({ id: countryObj.dataName, text: countryObj.name }));

    this.defaultCountry = app.settings.get('shippingAddresses').length ?
      app.settings.get('shippingAddresses').at(0).get('country') : app.settings.get('country');

    this.listenTo(app.settings, 'change:country', () =>
      (this.shipsFreeToMe = this.model.shipsFreeToMe));

    this.listenTo(app.settings.get('shippingAddresses'), 'update',
      (cl, updateOpts) => {
        if (updateOpts.changes.added.length ||
          updateOpts.changes.removed.length) {
          this.shipsFreeToMe = this.model.shipsFreeToMe;
        }
      });

    if (this.model.isOwnListing) {
      this.listenTo(listingEvents, 'saved', (md, savedOpts) => {
        const slug = this.model.get('slug');

        if (savedOpts.slug === slug && savedOpts.hasChanged()) {
          this.showDataChangedMessage();
        }
      });

      this.listenTo(app.profile.get('avatarHashes'), 'change', () => {
        this.$storeOwnerAvatar
          .attr('style', getAvatarBgImage(app.profile.get('avatarHashes').toJSON()));
      });

      this.listenTo(app.settings, 'change:localCurrency', () => this.showDataChangedMessage());
      this.listenTo(app.localSettings, 'change:bitcoinUnit', () => this.showDataChangedMessage());
    }

    this.rating = this.createChild(Rating);

    // get the ratings data, if any
    this.ratingsFetch =
      $.get(app.getServerUrl(`ob/ratings/${this.vendor.peerID}/${this.model.get('slug')}`))
        .done(data => this.onRatings(data))
        .fail((jqXhr) => {
          if (jqXhr.statusText === 'abort') return;
          // if there are no ratings, no response or a 404 is returned.
          if (jqXhr.status === 200 || jqXhr.status === 404) {
            this.onRatings();
            return;
          }
          const failReason = jqXhr.responseJSON && jqXhr.responseJSON.reason || '';
          openSimpleMessage(
            app.polyglot.t('listingDetail.errors.fetchRatings'),
            failReason);
        });
<commit_msg>Remove 404 check, the server will return 200 now.<commit_after>import $ from 'jquery';
import _ from 'underscore';
import 'jquery-zoom';
import is from 'is_js';
import app from '../../../app';
import '../../../lib/select2';
import '../../../utils/velocity';
import { getAvatarBgImage } from '../../../utils/responsive';
import { convertAndFormatCurrency } from '../../../utils/currency';
import loadTemplate from '../../../utils/loadTemplate';
import { launchEditListingModal } from '../../../utils/modalManager';
import { getTranslatedCountries } from '../../../data/countries';
import BaseModal from '../BaseModal';
import Purchase from '../purchase/Purchase';
import Rating from './Rating';
import Reviews from './Reviews';
import { events as listingEvents } from '../../../models/listing/';
import PopInMessage from '../../PopInMessage';
import { openSimpleMessage } from '../SimpleMessage';

export default class extends BaseModal {
  constructor(options = {}) {
    if (!options.model) {
      throw new Error('Please provide a model.');
    }

    const opts = {
      removeOnClose: false,
      ...options,
    };

    super(opts);
    this.options = opts;
    this._shipsFreeToMe = this.model.shipsFreeToMe;
    this.activePhotoIndex = 0;
    this.totalPrice = this.model.get('item').get('price');

    // Sometimes a profile model is available and the vendor info
    // can be obtained from that.
    if (opts.profile) {
      const avatarHashes = opts.profile.get('avatarHashes');

      this.vendor = {
        peerID: opts.profile.id,
        name: opts.profile.get('name'),
        handle: opts.profile.get('handle'),
        avatar: {
          tiny: avatarHashes.get('tiny'),
          small: avatarHashes.get('small'),
        },
      };
    }

    // In most cases the page opening this modal will already have and be able
    // to provide the vendor information. If it cannot, then I suppose we
    // could fetch the profile and lazy load it in, but we can cross that
    // bridge when we get to it.
    this.vendor = this.vendor || opts.vendor;

    this.countryData = getTranslatedCountries(app.settings.get('language'))
      .map(countryObj => ({ id: countryObj.dataName, text: countryObj.name }));

    this.defaultCountry = app.settings.get('shippingAddresses').length ?
      app.settings.get('shippingAddresses').at(0).get('country') : app.settings.get('country');

    this.listenTo(app.settings, 'change:country', () =>
      (this.shipsFreeToMe = this.model.shipsFreeToMe));

    this.listenTo(app.settings.get('shippingAddresses'), 'update',
      (cl, updateOpts) => {
        if (updateOpts.changes.added.length ||
          updateOpts.changes.removed.length) {
          this.shipsFreeToMe = this.model.shipsFreeToMe;
        }
      });

    if (this.model.isOwnListing) {
      this.listenTo(listingEvents, 'saved', (md, savedOpts) => {
        const slug = this.model.get('slug');

        if (savedOpts.slug === slug && savedOpts.hasChanged()) {
          this.showDataChangedMessage();
        }
      });

      this.listenTo(app.profile.get('avatarHashes'), 'change', () => {
        this.$storeOwnerAvatar
          .attr('style', getAvatarBgImage(app.profile.get('avatarHashes').toJSON()));
      });

      this.listenTo(app.settings, 'change:localCurrency', () => this.showDataChangedMessage());
      this.listenTo(app.localSettings, 'change:bitcoinUnit', () => this.showDataChangedMessage());
    }

    this.rating = this.createChild(Rating);

    // get the ratings data, if any
    this.ratingsFetch =
      $.get(app.getServerUrl(`ob/ratings/${this.vendor.peerID}/${this.model.get('slug')}`))
        .done(data => this.onRatings(data))
        .fail((jqXhr) => {
          if (jqXhr.statusText === 'abort') return;
          // if there are no ratings, no response is returned.
          if (jqXhr.status === 200) {
            this.onRatings();
            return;
          }
          const failReason = jqXhr.responseJSON && jqXhr.responseJSON.reason || '';
          openSimpleMessage(
            app.polyglot.t('listingDetail.errors.fetchRatings'),
            failReason);
        });

{'fraction_non_alphanumeric': 0.16001927943125677, 'fraction_numerical': 0.0028919146885166887, 'mean_word_length': 2.695458593054319, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4810509', 'n_tokens_mistral': 2446, 'n_tokens_neox': 2403, 'n_words': 547}