<commit_before>/*
 * HTTP GitHub project access.
 */

import { Base } from './base.jsx'
import * as util from '../util.jsx'

export default class Filesystem extends Base {
    constructor(path, options) {
        super('github', path, options)

        if(options.repo) {
            this.repo = options.repo
        } else {
            throw new Error("[github] repo option required")
        }

        if(options.token) {
            this.token = options.token
        }

        if(options.branch) {
            this.branch = options.branch
        }
    }

    async statinfo(json) {
        delete json['content']
        delete json['encoding']

        let type = 'file'

        if(json['type'] === 'dir')
            type = 'directory'

        return {
            type: type,
            name: json['name'],
            size: json['size']
        }
    }

    async stat(path) {
        let githubHeaders = new Headers()
        if (this.token) {
            githubHeaders.append('Authorization', 'token ' + this.token)
        }

        let branchParam = ''
        if (this.branch) {
            branchParam = '?ref=' + this.branch
        }

        let response = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents/' + path + branchParam, {headers: githubHeaders})

        if(response.status < 200 || response.status >= 300) {
            return response
        }

        let json    = await response.json()
        let content = do {
            if(Array.isArray(json)) {
                JSON.stringify({
                    type: 'directory',
                    contents: await* [for(item of json) this.statinfo(item)]
                }, null, '\t')
            } else {
                JSON.stringify(await this.statinfo(json), null, '\t')
            }
        }

        return new Response(content, {
            status: 200,
            headers: {'Allow': 'GET,OPTIONS'}
        })
    }

    async read(path) {
        let githubHeaders = new Headers()
        if (this.token) {
            githubHeaders.append('Authorization', 'token ' + this.token)
        }

        let branchParam = ''
        if (this.branch) {
            branchParam = '?ref=' + this.branch
        }

        let response = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents/' + path + branchParam, {headers: githubHeaders})

        if(response.status < 200 || response.status >= 300) {
            throw new Error(response.statusText)
        }

        let json = await response.json()

        if(Array.isArray(json)) {
            return new Response(null, {
                status: 405,
                statusMessage: 'EISDIR',
                headers: {'Allow': 'OPTIONS'}
            })
        } else {
            return new Response(atob(json['content']), {
                status: 200
            })
        }
    }

    async write(path, fileContent) {
        let githubHeaders = new Headers()
        githubHeaders.append('Authorization', 'token ' + this.token)

        let getResponse = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents' + path, {headers: githubHeaders})

        if (getResponse.status != 200) {
            throw new Error(getResponse.statusText)
        }

        let getJson = await getResponse.json()

        if (Array.isArray(getJson)) {
            throw new Error('What you are trying to overwrite is not a file. It\'s a directory.')
        }

        if (getJson['type'] != 'file') {
            throw new Error('What you are trying to overwrite is not a file. It\'s a ' + getJson['type'] + '.')
        }

        let request = {
            message: 'Update file ' + path + ' with webclient file backend',
            sha: getJson['sha'],
            content: btoa(await fileContent)
        }

        if (this.branch) {
            request['branch'] = this.branch
        }

        let response = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents/' + path, {
            headers: githubHeaders,
            body: JSON.stringify(request),
            method: 'PUT'})

        if(response.status < 200 || response.status >= 300) {
            throw new Error(response.statusText)
        }

        return fileContent
    }
}

// class GHFile extends File
<commit_msg>Github fs accepts base option (as repo)<commit_after>/*
 * HTTP GitHub project access.
 */

import { Base } from './base.jsx'
import * as util from '../util.jsx'

export default class Filesystem extends Base {
    constructor(path, options) {
        super('github', path, options)

        if(!options.repo && options.base)
            options.repo = options.base

        if(options.repo) {
            this.repo = options.repo
        } else {
            throw new Error("[github] repo option required")
        }

        if(options.token) {
            this.token = options.token
        }

        if(options.branch) {
            this.branch = options.branch
        }
    }

    async statinfo(json) {
        delete json['content']
        delete json['encoding']

        let type = 'file'

        if(json['type'] === 'dir')
            type = 'directory'

        return {
            type: type,
            name: json['name'],
            size: json['size']
        }
    }

    async stat(path) {
        let githubHeaders = new Headers()
        if (this.token) {
            githubHeaders.append('Authorization', 'token ' + this.token)
        }

        let branchParam = ''
        if (this.branch) {
            branchParam = '?ref=' + this.branch
        }

        let response = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents/' + path + branchParam, {headers: githubHeaders})

        if(response.status < 200 || response.status >= 300) {
            return response
        }

        let json    = await response.json()
        let content = do {
            if(Array.isArray(json)) {
                JSON.stringify({
                    type: 'directory',
                    contents: await* [for(item of json) this.statinfo(item)]
                }, null, '\t')
            } else {
                JSON.stringify(await this.statinfo(json), null, '\t')
            }
        }

        return new Response(content, {
            status: 200,
            headers: {'Allow': 'GET,OPTIONS'}
        })
    }

    async read(path) {
        let githubHeaders = new Headers()
        if (this.token) {
            githubHeaders.append('Authorization', 'token ' + this.token)
        }

        let branchParam = ''
        if (this.branch) {
            branchParam = '?ref=' + this.branch
        }

        let response = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents/' + path + branchParam, {headers: githubHeaders})

        if(response.status < 200 || response.status >= 300) {
            throw new Error(response.statusText)
        }

        let json = await response.json()

        if(Array.isArray(json)) {
            return new Response(null, {
                status: 405,
                statusMessage: 'EISDIR',
                headers: {'Allow': 'OPTIONS'}
            })
        } else {
            return new Response(atob(json['content']), {
                status: 200
            })
        }
    }

    async write(path, fileContent) {
        let githubHeaders = new Headers()
        githubHeaders.append('Authorization', 'token ' + this.token)

        let getResponse = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents' + path, {headers: githubHeaders})

        if (getResponse.status != 200) {
            throw new Error(getResponse.statusText)
        }

        let getJson = await getResponse.json()

        if (Array.isArray(getJson)) {
            throw new Error('What you are trying to overwrite is not a file. It\'s a directory.')
        }

        if (getJson['type'] != 'file') {
            throw new Error('What you are trying to overwrite is not a file. It\'s a ' + getJson['type'] + '.')
        }

        let request = {
            message: 'Update file ' + path + ' with webclient file backend',
            sha: getJson['sha'],
            content: btoa(await fileContent)
        }

        if (this.branch) {
            request['branch'] = this.branch
        }

        let response = await self.fetch('https://api.github.com/repos/' + this.repo + '/contents/' + path, {
            headers: githubHeaders,
            body: JSON.stringify(request),
            method: 'PUT'})

        if(response.status < 200 || response.status >= 300) {
            throw new Error(response.statusText)
        }

        return fileContent
    }
}

// class GHFile extends File

{'fraction_non_alphanumeric': 0.1278444825614637, 'fraction_numerical': 0.00686106346483705, 'mean_word_length': 1.6343373493975903, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 8, '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': '1641453', 'n_tokens_mistral': 2480, 'n_tokens_neox': 2323, 'n_words': 594}