<commit_before>// @flow
import type { Dispatch, GetState } from 'types/redux';
import type { Source, Metadata } from 'types/claim';
import type {
  UpdatePublishFormData,
  UpdatePublishFormAction,
  PublishParams,
} from 'redux/reducers/publish';
import {
  ACTIONS,
  Lbry,
  doNotify,
  MODALS,
  selectMyChannelClaims,
  THUMBNAIL_STATUSES,
  batchActions,
  creditsToString,
  selectPendingById,
  selectMyClaimsWithoutChannels,
} from 'lbry-redux';
import { selectosNotificationsEnabled } from 'redux/selectors/settings';
import { doNavigate } from 'redux/actions/navigation';
import fs from 'fs';
import path from 'path';
import { CC_LICENSES, COPYRIGHT, OTHER } from 'constants/licenses';

type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };

export const doResetThumbnailStatus = () => (dispatch: Dispatch<Action>): Promise<Action> => {
  dispatch({
    type: ACTIONS.UPDATE_PUBLISH_FORM,
    data: {
      thumbnailPath: '',
    },
  });

  return fetch('https://spee.ch/api/config/site/publishing')
    .then(res => res.json())
    .then(status => {
      if (status.disabled) {
        throw Error();
      }

      return dispatch({
        type: ACTIONS.UPDATE_PUBLISH_FORM,
        data: {
          uploadThumbnailStatus: THUMBNAIL_STATUSES.READY,
          thumbnail: '',
          nsfw: false,
        },
      });
    })
    .catch(() =>
      dispatch({
        type: ACTIONS.UPDATE_PUBLISH_FORM,
        data: {
          uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN,
          thumbnail: '',
          nsfw: false,
        },
      })
    );
};

export const doClearPublish = () => (dispatch: Dispatch<Action>): Promise<Action> => {
  dispatch({ type: ACTIONS.CLEAR_PUBLISH });
  return dispatch(doResetThumbnailStatus());
};

export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (
  dispatch: Dispatch<Action>
): UpdatePublishFormAction =>
  dispatch(
    ({
      type: ACTIONS.UPDATE_PUBLISH_FORM,
      data: { ...publishFormValue },
    }: UpdatePublishFormAction)
  );

export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (
  dispatch: Dispatch<Action>
) => {
  const thumbnail = fs.readFileSync(filePath);
  const fileExt = path.extname(filePath);
  const fileName = path.basename(filePath);

  const makeid = () => {
    let text = '';
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < 24; i += 1) text += possible.charAt(Math.floor(Math.random() * 62));
    return text;
  };

  const uploadError = (error = '') =>
    dispatch(
      batchActions(
        {
          type: ACTIONS.UPDATE_PUBLISH_FORM,
          data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN },
        },
        dispatch(doNotify({ id: MODALS.ERROR, error }))
      )
    );

  dispatch({
    type: ACTIONS.UPDATE_PUBLISH_FORM,
    data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.IN_PROGRESS },
  });

  const data = new FormData();
  const name = makeid();
  const file = new File([thumbnail], fileName, { type: `image/${fileExt.slice(1)}` });
  data.append('name', name);
  data.append('file', file);
  data.append('nsfw', nsfw.toString());
  return fetch('https://spee.ch/api/claim/publish', {
    method: 'POST',
    body: data,
  })
    .then(response => response.json())
    .then(
      json =>
        json.success
          ? dispatch({
              type: ACTIONS.UPDATE_PUBLISH_FORM,
              data: {
                uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
                thumbnail: `${json.data.url}${fileExt}`,
              },
            })
          : uploadError(json.message)
    )
    .catch(err => uploadError(err.message));
};

export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch<Action>) => {
  const {
    name,
    amount,
    channel_name: channelName,
    value: {
      stream: { metadata },
    },
  } = claim;

  const {
    author,
    description,
    // use same values as default state
    // fee will be undefined for free content
    fee = {
      amount: 0,
      currency: 'LBC',
    },
    language,
    license,
    licenseUrl,
    nsfw,
    thumbnail,
    title,
  } = metadata;

  const publishData: UpdatePublishFormData = {
    name,
    channel: channelName,
    bid: amount,
    price: { amount: fee.amount, currency: fee.currency },
    contentIsFree: !fee.amount,
    author,
    description,
    fee,
    language,
    nsfw,
    thumbnail,
    title,
    uri,
    uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined,
    licenseUrl,
  };

  // Make sure custom liscence's are mapped properly
  if (!CC_LICENSES.some(({ value }) => value === license)) {
    if (!licenseUrl) {
      publishData.licenseType = COPYRIGHT;
    } else {
      publishData.licenseType = OTHER;
    }

    publishData.otherLicenseDescription = license;
  } else {
    publishData.licenseType = license;
  }

  dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
};

export const doPublish = (params: PublishParams) => (
  dispatch: Dispatch<Action>,
  getState: () => {}
) => {
  const state = getState();
  const myChannels = selectMyChannelClaims(state);
  const myClaims = selectMyClaimsWithoutChannels(state);

  const {
    name,<commit_msg>fix license type on edit<commit_after>// @flow
import type { Dispatch, GetState } from 'types/redux';
import type { Source, Metadata } from 'types/claim';
import type {
  UpdatePublishFormData,
  UpdatePublishFormAction,
  PublishParams,
} from 'redux/reducers/publish';
import {
  ACTIONS,
  Lbry,
  doNotify,
  MODALS,
  selectMyChannelClaims,
  THUMBNAIL_STATUSES,
  batchActions,
  creditsToString,
  selectPendingById,
  selectMyClaimsWithoutChannels,
} from 'lbry-redux';
import { selectosNotificationsEnabled } from 'redux/selectors/settings';
import { doNavigate } from 'redux/actions/navigation';
import fs from 'fs';
import path from 'path';
import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses';

type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };

export const doResetThumbnailStatus = () => (dispatch: Dispatch<Action>): Promise<Action> => {
  dispatch({
    type: ACTIONS.UPDATE_PUBLISH_FORM,
    data: {
      thumbnailPath: '',
    },
  });

  return fetch('https://spee.ch/api/config/site/publishing')
    .then(res => res.json())
    .then(status => {
      if (status.disabled) {
        throw Error();
      }

      return dispatch({
        type: ACTIONS.UPDATE_PUBLISH_FORM,
        data: {
          uploadThumbnailStatus: THUMBNAIL_STATUSES.READY,
          thumbnail: '',
          nsfw: false,
        },
      });
    })
    .catch(() =>
      dispatch({
        type: ACTIONS.UPDATE_PUBLISH_FORM,
        data: {
          uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN,
          thumbnail: '',
          nsfw: false,
        },
      })
    );
};

export const doClearPublish = () => (dispatch: Dispatch<Action>): Promise<Action> => {
  dispatch({ type: ACTIONS.CLEAR_PUBLISH });
  return dispatch(doResetThumbnailStatus());
};

export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (
  dispatch: Dispatch<Action>
): UpdatePublishFormAction =>
  dispatch(
    ({
      type: ACTIONS.UPDATE_PUBLISH_FORM,
      data: { ...publishFormValue },
    }: UpdatePublishFormAction)
  );

export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (
  dispatch: Dispatch<Action>
) => {
  const thumbnail = fs.readFileSync(filePath);
  const fileExt = path.extname(filePath);
  const fileName = path.basename(filePath);

  const makeid = () => {
    let text = '';
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < 24; i += 1) text += possible.charAt(Math.floor(Math.random() * 62));
    return text;
  };

  const uploadError = (error = '') =>
    dispatch(
      batchActions(
        {
          type: ACTIONS.UPDATE_PUBLISH_FORM,
          data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN },
        },
        dispatch(doNotify({ id: MODALS.ERROR, error }))
      )
    );

  dispatch({
    type: ACTIONS.UPDATE_PUBLISH_FORM,
    data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.IN_PROGRESS },
  });

  const data = new FormData();
  const name = makeid();
  const file = new File([thumbnail], fileName, { type: `image/${fileExt.slice(1)}` });
  data.append('name', name);
  data.append('file', file);
  data.append('nsfw', nsfw.toString());
  return fetch('https://spee.ch/api/claim/publish', {
    method: 'POST',
    body: data,
  })
    .then(response => response.json())
    .then(
      json =>
        json.success
          ? dispatch({
              type: ACTIONS.UPDATE_PUBLISH_FORM,
              data: {
                uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
                thumbnail: `${json.data.url}${fileExt}`,
              },
            })
          : uploadError(json.message)
    )
    .catch(err => uploadError(err.message));
};

export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch<Action>) => {
  const {
    name,
    amount,
    channel_name: channelName,
    value: {
      stream: { metadata },
    },
  } = claim;

  const {
    author,
    description,
    // use same values as default state
    // fee will be undefined for free content
    fee = {
      amount: 0,
      currency: 'LBC',
    },
    language,
    license,
    licenseUrl,
    nsfw,
    thumbnail,
    title,
  } = metadata;

  const publishData: UpdatePublishFormData = {
    name,
    channel: channelName,
    bid: amount,
    price: { amount: fee.amount, currency: fee.currency },
    contentIsFree: !fee.amount,
    author,
    description,
    fee,
    language,
    nsfw,
    thumbnail,
    title,
    uri,
    uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined,
    licenseUrl,
  };

  // Make sure custom liscence's are mapped properly
  // If the license isn't one of the standard licenses, map the custom license and description/url
  if (!CC_LICENSES.some(({ value }) => value === license)) {
    if (!license || license === NONE || license === PUBLIC_DOMAIN) {
      publishData.licenseType = license;
    } else if (license && !licenseUrl && license !== NONE) {
      publishData.licenseType = COPYRIGHT;
    } else {
      publishData.licenseType = OTHER;
    }

    publishData.otherLicenseDescription = license;
  } else {
    publishData.licenseType = license;
  }

  dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
};

export const doPublish = (params: PublishParams) => (
  dispatch: Dispatch<Action>,
  getState: () => {}
) => {
  const state = getState();
  const myChannels = selectMyChannelClaims(state);
  const myClaims = selectMyClaimsWithoutChannels(state);

  const {
    name,
{'fraction_non_alphanumeric': 0.12970287921994297, 'fraction_numerical': 0.0033115628737006714, 'mean_word_length': 2.9206635412910207, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 63, 'https://': 4, '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': '234123', 'n_tokens_mistral': 3569, 'n_tokens_neox': 3461, 'n_words': 728}