<commit_before>/**
 *
 * @license
 * Copyright (C) 2016 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author <NAME>
 * @file Configuration.js
 * @providesModule Configuration
 * @description Manages the configuration of the application.
 *
 * @flow
 */
'use strict';

// React imports
import {
  AsyncStorage,
} from 'react-native';

// Import types
import type {
  Semester,
  University,
  BusInfo,
} from 'types';

type FileUpdate = {
  name: string,
  type: string,
  url: string,
  size: number,
  oldVersion: number,
  newVersion: number
}

export type ConfigurationUpdateCallbacks = {
  onUpdateStart?: (totalSize: number, totalFiles: number) => any,
  onDownloadStart?: (download: Object) => any,
  onDownloadProgress?: (progress: Object) => any,
  onDownloadComplete?: (download: Object) => any,
}

// Imports
const Database = require('Database');
const DeviceInfo = require('react-native-device-info');
const HttpStatus = require('http-status-codes');
const Promise = require('promise');
const RNFS = require('react-native-fs');

// Subdirectories which files of certain types should be placed/found in
const CONFIG_SUBDIRECTORIES = {
  image: '/images',
  json: '/json',
};

// Directory for config files
const CONFIG_DIRECTORY = RNFS.DocumentDirectoryPath + '/config';
// Directory for downloaded config files
const TEMP_CONFIG_DIRECTORY = RNFS.DocumentDirectoryPath + '/temp/config';
// Expected filename for app_config
const APP_CONFIG_NAME: string = '/app_config.json';
// Expected directory for app_config
const APP_CONFIG_DIR: string = CONFIG_SUBDIRECTORIES.json;

// Default link to return
const DEFAULT_LINK: string = 'http://www.uottawa.ca/';

// Information about the university
let university: ?University = null;
// Information about the buses in the city
let cityBuses: ?BusInfo = null;
// List of semesters available in the app
let availableSemesters: Array < Semester > = [];

// Indicates if the configuration is initializing
let configInitializing: boolean = false;
// List of promises that should resolve or reject if the configuration is available or not
const availablePromises: Array < { resolve: () => any, reject: () => any } > = [];

// List of configuration files which have updates available
let configurationUpdates: Array < FileUpdate > = [];
// Indicates if the app has checked for a configuration update yet
let checkedForUpdate: boolean = false;

// Set to true to delete configuration when app opens. Only possible while debugging.
let clearConfigOnStart: boolean = true;

/**
 * Asynchronously gets the configuration for the application and loads the various config values into their
 * respective variables.
 */
async function _requestConfig(): Promise < void > {

  if (__DEV__ && clearConfigOnStart) {
    clearConfigOnStart = false;
    await _deleteConfiguration();
  }

  let db = null;
  try {
    db = await Database.init();
  } catch (e) {
    throw e;
  }

  let configVersions = null;
  try {
    configVersions = await Database.getConfigVersions(db);
  } catch (e) {
    throw e;
  }

  if (configVersions.length == 0) {
    throw new Error('Configuration versions were not found in database.');
  }

  // Ensure all config files exist
  let configAvailable: boolean = true;
  for (let i = 0; i < configVersions.length; i++) {
    try {
      const dir = CONFIG_SUBDIRECTORIES[configVersions[i].type];
      const exists = await RNFS.exists(CONFIG_DIRECTORY + dir + configVersions[i].name);
      configAvailable = configAvailable && exists;
      if (!exists) {
        console.log('Could not find configuration file: ' + configVersions[i].name);
      }
    } catch (e) {
      throw e;
    }
  }

  // If any config files do not exist, throw error for no available configuration
  if (!configAvailable) {
    throw new Error('Some expected configuration file does not exist.');
  }

  // Load the application configuration
  const appConfig: string = await RNFS.readFile(CONFIG_DIRECTORY + APP_CONFIG_DIR + APP_CONFIG_NAME, 'utf8');
  const configuration = JSON.parse(appConfig);

  // Reset the configuration
  university = null;
  cityBuses = null;
  availableSemesters = [];

  university = configuration.university;
  cityBuses = configuration.bus;

  // Get the current semesters available in the app
  if (configuration.semesters) {
    for (let i = 0; i < configuration.semesters.length; i++) {
      availableSemesters.push(configuration.semesters[i]);
    }
  }
}
<commit_msg>Don't fail config check for files with version 0<commit_after>/**
 *
 * @license
 * Copyright (C) 2016 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author <NAME>
 * @file Configuration.js
 * @providesModule Configuration
 * @description Manages the configuration of the application.
 *
 * @flow
 */
'use strict';

// React imports
import {
  AsyncStorage,
} from 'react-native';

// Import types
import type {
  Semester,
  University,
  BusInfo,
} from 'types';

type FileUpdate = {
  name: string,
  type: string,
  url: string,
  size: number,
  oldVersion: number,
  newVersion: number
}

export type ConfigurationUpdateCallbacks = {
  onUpdateStart?: (totalSize: number, totalFiles: number) => any,
  onDownloadStart?: (download: Object) => any,
  onDownloadProgress?: (progress: Object) => any,
  onDownloadComplete?: (download: Object) => any,
}

// Imports
const Database = require('Database');
const DeviceInfo = require('react-native-device-info');
const HttpStatus = require('http-status-codes');
const Promise = require('promise');
const RNFS = require('react-native-fs');

// Subdirectories which files of certain types should be placed/found in
const CONFIG_SUBDIRECTORIES = {
  image: '/images',
  json: '/json',
};

// Directory for config files
const CONFIG_DIRECTORY = RNFS.DocumentDirectoryPath + '/config';
// Directory for downloaded config files
const TEMP_CONFIG_DIRECTORY = RNFS.DocumentDirectoryPath + '/temp/config';
// Expected filename for app_config
const APP_CONFIG_NAME: string = '/app_config.json';
// Expected directory for app_config
const APP_CONFIG_DIR: string = CONFIG_SUBDIRECTORIES.json;

// Default link to return
const DEFAULT_LINK: string = 'http://www.uottawa.ca/';

// Information about the university
let university: ?University = null;
// Information about the buses in the city
let cityBuses: ?BusInfo = null;
// List of semesters available in the app
let availableSemesters: Array < Semester > = [];

// Indicates if the configuration is initializing
let configInitializing: boolean = false;
// List of promises that should resolve or reject if the configuration is available or not
const availablePromises: Array < { resolve: () => any, reject: () => any } > = [];

// List of configuration files which have updates available
let configurationUpdates: Array < FileUpdate > = [];
// Indicates if the app has checked for a configuration update yet
let checkedForUpdate: boolean = false;

// Set to true to delete configuration when app opens. Only possible while debugging.
let clearConfigOnStart: boolean = true;

/**
 * Asynchronously gets the configuration for the application and loads the various config values into their
 * respective variables.
 */
async function _requestConfig(): Promise < void > {

  if (__DEV__ && clearConfigOnStart) {
    clearConfigOnStart = false;
    await _deleteConfiguration();
  }

  let db = null;
  try {
    db = await Database.init();
  } catch (e) {
    throw e;
  }

  let configVersions = null;
  try {
    configVersions = await Database.getConfigVersions(db);
  } catch (e) {
    throw e;
  }

  if (configVersions.length == 0) {
    throw new Error('Configuration versions were not found in database.');
  }

  // Ensure all config files exist
  let configAvailable: boolean = true;
  for (let i = 0; i < configVersions.length; i++) {
    if (configVersions[i].version > 0) {
      try {
        const dir = CONFIG_SUBDIRECTORIES[configVersions[i].type];
        const exists = await RNFS.exists(CONFIG_DIRECTORY + dir + configVersions[i].name);
        configAvailable = configAvailable && exists;
        if (!exists) {
          console.log('Could not find configuration file: ' + configVersions[i].name);
        }
      } catch (e) {
        throw e;
      }
    }
  }

  // If any config files do not exist, throw error for no available configuration
  if (!configAvailable) {
    throw new Error('Some expected configuration file does not exist.');
  }

  // Load the application configuration
  const appConfig: string = await RNFS.readFile(CONFIG_DIRECTORY + APP_CONFIG_DIR + APP_CONFIG_NAME, 'utf8');
  const configuration = JSON.parse(appConfig);

  // Reset the configuration
  university = null;
  cityBuses = null;
  availableSemesters = [];

  university = configuration.university;
  cityBuses = configuration.bus;

  // Get the current semesters available in the app
  if (configuration.semesters) {
    for (let i = 0; i < configuration.semesters.length; i++) {
      availableSemesters.push(configuration.semesters[i]);
    }
  }
}

{'fraction_non_alphanumeric': 0.10334861470998605, 'fraction_numerical': 0.00259118995415587, 'mean_word_length': 3.829162656400385, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6477532', 'n_tokens_mistral': 2823, 'n_tokens_neox': 2761, 'n_words': 1015}