<commit_before>/**
 * Utility class to automatically create Redux reducers for REST API endpoints.
 */
import request from 'superagent';
import itemStatus from './itemStatus';

export class Endpoint {
  constructor(url) {
    this.url = url;
  }

  list(params) {
    return request.get(this.url).query(params);
  }

  retrieve(id) {
    return request.get(this._getObjectURL(id));
  }

  create(conf) {
    return request.post(this.url).send(conf);
  }

  update(conf, id) {
    return request.put(this._getObjectURL(id)).send(conf);
  }

  _getObjectURL(id) {
    let slash = '';
    if (!this.url.endsWith('/')) {
      slash = '/';
    }
    return `${this.url}${slash}${id}`;
  }

}

export class ActionTypes {
  constructor(endpointName) {
    this.endpointName = endpointName;
    ['list', 'retrieve', 'create', 'update'].forEach(action => {
      this[`${action}`] = this.getConstant(action);
      ['success', 'failure'].forEach(result => {
        this[`${action}_${result}`] = this.getConstant(action, result);
      });
    });
  }

  getConstant(action, result) {
    let constant = `${this.endpointName}_${action}`;
    if (result) {
      constant = `${constant}_${result}`;
    }
    return constant;
  }
}

export class ActionCreators {
  constructor(endpointName, API, actionTypes) {
    this.actionTypes = actionTypes;
    this._pendingID = 0;
    ['list', 'retrieve', 'create', 'update'].forEach(action => {
      this[action] = this._createAction.bind(this, action, API[action].bind(API));
    });
  }
<commit_msg>Add CSRF header for POST/PUT requests<commit_after>/**
 * Utility class to automatically create Redux reducers for REST API endpoints.
 */
// TODO make ajax library pluggable
import agent from 'superagent';
import itemStatus from './itemStatus';

export class Endpoint {
  constructor(url) {
    this.url = url;
  }

  list(params) {
    return agent.get(this.url).query(params);
  }

  retrieve(id) {
    return agent.get(this._getObjectURL(id));
  }

  create(conf) {
    return this._setCRSFHeader(agent.post(this.url)).send(conf);
  }

  update(conf, id) {
    return this._setCRSFHeader(agent.put(this._getObjectURL(id))).send(conf);
  }

  _getObjectURL(id) {
    let slash = '';
    if (!this.url.endsWith('/')) {
      slash = '/';
    }
    return `${this.url}${slash}${id}`;
  }

  _setCRSFHeader(request) {
    // TODO this is django specific, needs to be customisable
    if (!this._csrfSafeMethod(request.method)) {  // && !this.crossDomain) {
      request.set('X-CSRFToken', this._getCookie('csrftoken'));
    }
    return request;
  }

  // Set csrf token for ajax requests
  // See https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
  _getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
      let cookies = document.cookie.split(';');
      for (let i = 0; i < cookies.length; i++) {
        let cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) === (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
        }
      }
    }
    return cookieValue;
  }

  _csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }
}

export class ActionTypes {
  constructor(endpointName) {
    this.endpointName = endpointName;
    ['list', 'retrieve', 'create', 'update'].forEach(action => {
      this[`${action}`] = this.getConstant(action);
      ['success', 'failure'].forEach(result => {
        this[`${action}_${result}`] = this.getConstant(action, result);
      });
    });
  }

  getConstant(action, result) {
    let constant = `${this.endpointName}_${action}`;
    if (result) {
      constant = `${constant}_${result}`;
    }
    return constant;
  }
}

export class ActionCreators {
  constructor(endpointName, API, actionTypes) {
    this.actionTypes = actionTypes;
    this._pendingID = 0;
    ['list', 'retrieve', 'create', 'update'].forEach(action => {
      this[action] = this._createAction.bind(this, action, API[action].bind(API));
    });
  }

{'fraction_non_alphanumeric': 0.1663489037178265, 'fraction_numerical': 0.0014299332697807435, 'mean_word_length': 3.1761194029850746, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 9, 'https://': 1, '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': '717519', 'n_tokens_mistral': 1369, 'n_tokens_neox': 1352, 'n_words': 273}