<commit_before>var Q = require('q');
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var mime = require('mime-types');
var progress = require('progress-stream');

var model = require('./model');
var ReleaseAsset = require('./release-asset');

var Release = model.create(function(repo, releaseId) {
    this.repo = repo;
    this.id = releaseId;
    this._infos;
});

// Relations
Release.prototype.asset = model.getter(ReleaseAsset);

// Return list of assets
Release.prototype.assets = function() {
    return this.client.get(this.url('assets'))
        .get('body');
};

// Return api url for the release
Release.prototype.url = function(part) {
    return this.repo.url('releases/'+this.id, part);
};

// Get details about the release
Release.prototype.info = function() {
    var that = this;

    return this.client.get(this.url())
        .get('body')
        .tap(function(infos) {
            that._infos = infos;
        });
};

// Edit this release
Release.prototype.edit = function(params) {
    return this.client.patch(this.url(), params)
        .get('body');
};

// Upload an asset
Release.prototype.upload = function(output, opts) {
    var that = this;
    var originalOutput;

    opts = _.defaults(opts || {}, {
        name: null,
        mime: null,
        size: null
    });

    // Normalize to a stream
    if (_.isString(output)) {
        originalOutput = output;
        opts.name = opts.name || path.basename(output);
        output = fs.createReadStream(output);
    } else {
        if (!opts.name || !opts.size) throw "Need 'name' and 'size' options when uploading a stream";
    }
    if (!opts.mime) opts.mime = mime.lookup(opts.name) || 'application/octet-stream';

    return Q()
    .then(function() {
        if (opts.size) return opts.size;

        return Q.nfcall(fs.stat, originalOutput).get('size');
    })
    .then(function(size) {
        opts.size = size;
        return that._infos || that.info();
    })
    .then(function(release) {
        var count = 0;
        var d = Q.defer();
        var uploadUrl = release.upload_url.replace('{?name}', '?name='+encodeURIComponent(opts.name));

        var prg = progress({
            length: opts.size,
            time: 100
        });

        prg.on('progress', function(state) {
            d.notify(state);
        });
<commit_msg>Handle correctly all upload urls<commit_after>var Q = require('q');
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var mime = require('mime-types');
var querystring = require('querystring');
var progress = require('progress-stream');

var model = require('./model');
var ReleaseAsset = require('./release-asset');

var Release = model.create(function(repo, releaseId) {
    this.repo = repo;
    this.id = releaseId;
    this._infos;
});

// Relations
Release.prototype.asset = model.getter(ReleaseAsset);

// Return list of assets
Release.prototype.assets = function() {
    return this.client.get(this.url('assets'))
        .get('body');
};

// Return api url for the release
Release.prototype.url = function(part) {
    return this.repo.url('releases/'+this.id, part);
};

// Get details about the release
Release.prototype.info = function() {
    var that = this;

    return this.client.get(this.url())
        .get('body')
        .tap(function(infos) {
            that._infos = infos;
        });
};

// Edit this release
Release.prototype.edit = function(params) {
    return this.client.patch(this.url(), params)
        .get('body');
};

// Upload an asset
Release.prototype.upload = function(output, opts) {
    var that = this;
    var originalOutput;

    opts = _.defaults(opts || {}, {
        name: null,
        label: undefined,
        mime: null,
        size: null
    });

    // Normalize to a stream
    if (_.isString(output)) {
        originalOutput = output;
        opts.name = opts.name || path.basename(output);
        output = fs.createReadStream(output);
    } else {
        if (!opts.name || !opts.size) throw "Need 'name' and 'size' options when uploading a stream";
    }
    if (!opts.mime) opts.mime = mime.lookup(opts.name) || 'application/octet-stream';

    return Q()
    .then(function() {
        if (opts.size) return opts.size;

        return Q.nfcall(fs.stat, originalOutput).get('size');
    })
    .then(function(size) {
        opts.size = size;
        return that._infos || that.info();
    })
    .then(function(release) {
        var count = 0;
        var d = Q.defer();
        var uploadUrl = release.upload_url.replace(/\{(\S+)\}/, '')+'?'+querystring.stringify({
            name: opts.name,
            label: opts.label
        });

        var prg = progress({
            length: opts.size,
            time: 100
        });

        prg.on('progress', function(state) {
            d.notify(state);
        });

{'fraction_non_alphanumeric': 0.15924481838703058, 'fraction_numerical': 0.0016416991586291811, 'mean_word_length': 2.4939068100358424, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '4575156', 'n_tokens_mistral': 1511, 'n_tokens_neox': 1468, 'n_words': 349}