Greasy Fork

Gazelle Autofiller

Automatically fills a Gazelle form

// ==UserScript==
// @name        Gazelle Autofiller
// @description Automatically fills a Gazelle form
// @namespace   BlackNullerNS
// @include     http*://passtheheadphones.me/upload.php*
// @include     http*://www.passtheheadphones.me/upload.php*
// @include     http*://apollo.rip/upload.php*
// @include     http*://www.apollo.rip/upload.php*
// @include     http*://baconbits.org/upload.php*
// @include     http*://www.baconbits.org/upload.php*
// @version     0.2.10
// @require     https://greasyfork.org/scripts/13016-bencode-encoder-decoder/code/Bencode%20encoderdecoder.js?version=79776
// @require     https://greasyfork.org/scripts/13017-rusha/code/Rusha.js?version=79803
// ==/UserScript==

String.prototype.trimChar = function(chr) {
    var str = this;

    while(str.charAt(0) == chr) {
        str = str.substring(1);
    }

    while(str.charAt(str.length-1) == chr) {
        str = str.substring(0, str.length-1);
    }

    return str;
};

var Torrent = function(binaryString)
{
    var self = this,
        uniqueStringChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        mimeType = "application/x-bittorrent",
        data = bencode.decode(binaryString),
        originalAnnounceUrl = "announce" in data ? data.announce : "",

        calculateHash = function() {
            return new Rusha().digestFromBuffer(bencode.encode(data.info)).toUpperCase();
        },

        originalHash = calculateHash(),
        hash = originalHash;

    self.getBinary = function() {
        return bencode.encode(data);
    };

    self.getName = function() {
        return decodeURIComponent(escape(data.info.name));
    };

    self.setAnnounceUrl = function(value) {
        data.announce = value;
        return this;
    };

    self.getAnnounceUrl = function() {
        return data.announce;
    };

    self.getOriginalAnnounceUrl = function() {
        return originalAnnounceUrl;
    };

    self.getHash = function() {
        return hash;
    };

    self.getOriginalHash = function() {
        return originalHash;
    };

    var randomString = function (length) {
        var text = "";

        for (var i = 0; i < length; i++) {
            text += uniqueStringChars.charAt(Math.floor(Math.random() * uniqueStringChars.length));
        }

        return text;
    };

    self.changeHash = function() {
        data.info.private = 1;
        data.info.unique = randomString(30);
        hash = calculateHash();
        return hash;
    };

    self.getDownloadLink = function(text) {
        var a = document.createElement("a");
        a.setAttribute("href", "javascript:void(0);");
        a.textContent = text ? text : hash;
        a.style.cursor = "pointer";
        a.onclick = self.downloadTorrent;

        return a;
    };

    self.downloadTorrent = function(){
        var uri = "data:application/x-bittorrent;base64," + btoa(bencode.encode(data));

        var link = document.createElement("a");
        link.href = uri;
        link.style = "visibility:hidden";
        link.download = self.getName() + ".torrent";

        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        return false;
    };

    self.countFiles = function(){
        return data.info.files ? data.info.files.length : 0;
    };

    self.getFiles = function() {
        return data.info.files ? data.info.files : [];
    };

    self.getTrackerId = function() {
        return originalAnnounceUrl.split('://')[1].split('/')[0].split(':')[0].replace(/^tracker\./, "").replace(/^please\./, "");
    };

    self.getTotalSize = function() {
        var files = data.info.files;
        var size = 0;

        if (files && files instanceof Array) {
            for (var i = 0, file; file = files[i]; i++) {
                if (file.length) {
                    size += file.length;
                }
            }
        }

        return size;
    };

    self.getBlob = function() {
        var i, l, array,
            binary = self.getBinary();

        l = binary.length;
        array = new Uint8Array(l);

        for (i = 0; i < l; i++){
            array[i] = binary.charCodeAt(i);
        }

        return new Blob([array], {type: mimeType});
    }
};


(function()
{
    var self = this;
    var fileInput = document.querySelector("input[type='file']");

    if (!fileInput) {
        console.log("File input not found.");
        return;
    }

    self.input = fileInput;
    self.form = self.input.closest("form");
    self.host = document.location.href.split('://')[1].split('/')[0].split(':')[0].replace(/^(www|tls|ssl)\./, "");
    self.formats = {
        flac: 'FLAC',
        mp3: 'MP3',
        ogg: 'Ogg Vorbis',
        m4a: 'AAC'
    };
    self.bitrates = ['192','256','320','V0','V1','V2'];

    fileInput.addEventListener("change", function(ev) {
        if (!ev.target.files || ev.target.files[0].name.toLowerCase().indexOf(".torrent") === -1) {
            return;
        }
        var reader = new FileReader();
        reader.onload = function(e) {
            self.addTorrent(e.target.result);
        };
        reader.readAsBinaryString(ev.target.files[0]);
    });

    self.addTorrent = function(binaryString)
    {
        try {
            self.analyze(new Torrent(binaryString));
        } catch (e) {
            console.log(e);
        }
    };

    self.analyze = function(torrent) {

        var i, l, ext, format, media, bitrate, year, artist, album, releaseType,
            torrentName = torrent.getName(),
            torrentNameLc = torrentName.toLowerCase(),
            files = torrent.getFiles();

        for (i = 0, l = files.length; i < l; i++) {
            ext = self.getExtension(files[i].path[0]);

            if (self.formats.hasOwnProperty(ext)) {
                format = self.formats[ext];
            }

            if (ext === 'cue') {
                media = 'CD';
            }
        }

        var segments = torrentName.split(/(\s+(-|–)\s+|[\{\}\[\]]{1}|\(|\)|_)/g)
            .map(function (val) {
                if (typeof val !== "string") {
                    return '';
                }
                return val.trim()
                    .trimChar('(')
                    .trimChar(')')
                    .trimChar('[')
                    .trimChar(']')
                    .trimChar('{')
                    .trimChar('}')
                    .trimChar('-')
                    .trimChar('–')
                    .trim();
            })
            .filter(function (val) {
                return val && !self.isYear(val) && !self.isFormat(val) && !self.isBitrate(val);
            });

        var nonAlbumData = ' ' + segments.slice(2).join(' - ').toLowerCase() + ' ';

        album = segments[1] ? segments[1] : segments[0];
        artist = segments[1] ? segments[0] : null;

        var yearMatch = torrentName.match(/\D*([\d]{4})\D*/i);
        if (yearMatch) {
            self.setYear(yearMatch[1]);
        }

        if (!media) {
            if (torrentName.indexOf('WEB') > -1 || torrentNameLc.indexOf('bandcamp') > -1 || torrentNameLc.indexOf('qobuz') > -1 || torrentNameLc.indexOf('beatport') > -1) {
                media = 'WEB';
            } else if (nonAlbumData.indexOf('vinyl') > -1 || nonAlbumData.indexOf('180g') > -1 || nonAlbumData.indexOf('200g') > -1) {
                media = 'Vinyl';
            } else if (torrentName.indexOf('SACD') > -1) {
                media = 'SACD';
            }
        }

        if (format === 'FLAC') {
            bitrate = 'Lossless';
        } else {
            var bitrateMatch = torrentName.match(/\D*(192|256|320|V0|V1|V2)\D*/i);
            if (bitrateMatch) bitrate = bitrateMatch[1];
        }

        // Release type
        if (nonAlbumData.indexOf(' single ') > -1) {
            releaseType = 'Single';
        } else if (nonAlbumData.indexOf(' ep ') > -1) {
            releaseType = 'EP';
        } else if (artist && (artist === 'VA' || artist === 'Various Artists')) {
            releaseType = 'Compilation';
        } else if (torrentNameLc.indexOf(' ost ') > -1 || torrentNameLc.indexOf('soundtrack') > -1) {
            releaseType = 'Soundtrack';
        } else if (nonAlbumData.indexOf(' live ') > -1 || torrentNameLc.indexOf('live in ') > -1 || torrentNameLc.indexOf('live at ') > -1) {
            releaseType = 'Live album';
        } else {
            var trackCount = self.getMediaFiles(torrent).length;
            if (trackCount > 5) {
                releaseType = 'Album';
            } else if (trackCount === 4 || trackCount === 5) {
                releaseType = 'EP';
            } else {
                releaseType = 'Single';
            }
        }

        // Release description
        self.generateReleaseDesc(self.getTracks(torrent));
        
        if (artist) self.setArtist(artist);
        if (album) self.setAlbum(album);
        if (releaseType) self.setReleaseType(releaseType);
        if (format) self.setFormat(format);
        if (media) self.setMedia(media);
        if (bitrate) self.setBitrate(bitrate);
    };

    self.setArtist = function (artist) {
        document.getElementById('artist').value = artist;
    };

    self.setAlbum = function (album) {
        document.getElementById('title').value = album;
    };

    self.setYear = function (year) {
        if (self.isYear(year)) {
            document.getElementById('year').value = year;
        }
    };

    self.setFormat = function (format) {
        var el = document.getElementById('format');
        el.value = format;
        var event = document.createEvent("HTMLEvents");
        event.initEvent("change", true, true);
        event.eventName = "change";
        el.dispatchEvent(event);
    };

    self.setReleaseType = function (type) {
        document.getElementById('releasetype').value = document.evaluate("//select[@id='releasetype']/option[contains(., '" + type + "')]", document, null, XPathResult.ANY_TYPE, null).iterateNext().getAttribute('value');
    };

    self.setMedia = function (media) {
        document.getElementById('media').value = media;
    };

    self.setBitrate = function (bitrate) {
        if (bitrate[0].toUpperCase() === 'V') {
            bitrate = bitrate.toUpperCase() + ' (VBR)';
        }

        document.getElementById('bitrate').value = bitrate;
    };

    self.isYear = function (year) {
        try {
            year = parseInt(year);
            return (year > 1948 && year < new Date().getFullYear() + 1);
        } catch (e) {}
    };

    self.isFormat = function (format) {
        return self.formats.hasOwnProperty(format.toLowerCase());
    };

    self.isBitrate = function (bitrate) {
        return self.bitrates.indexOf(bitrate) > -1;
    };

    self.getMediaFiles = function (torrent) {
        return torrent.getFiles().filter(function (file) {
            return self.formats.hasOwnProperty(self.getExtension(file.path[file.path.length - 1]));
        });
    };

    self.getTracks = function (torrent) {
        var files = self.getMediaFiles(torrent);

        var medium, tracklist = {};
        for (var i = 0, l = files.length; i < l; i++) {
            medium = files[i].path.length - 2 < 0 ? '' : files[i].path[files[i].path.length - 2];
            if (!tracklist[medium]) tracklist[medium] = [];
            tracklist[medium].push(files[i].path[files[i].path.length - 1]);
        }

        var media = Object.keys(tracklist).sort();

        for (medium in tracklist) {
            tracklist[medium].sort(function (a, b) {
                return a < b ? -1 : 1;
            });
            tracklist[medium] = tracklist[medium].map(function (file) {
                return '[#]' + decodeURIComponent(escape(file)).replace(/^[\d\-\(\)\[\]]+\.?\s*\-?/, '').replace(/\.([a-zA-Z0-9]+)$/, '').trim();
            });
        }

        return tracklist;
    };

    self.generateReleaseDesc = function (tracklist) {
        var desc = "[size=3][b]Tracklist:[/b][/size]\n",
            media = Object.keys(tracklist);

        if (media.length === 1) {
            desc += tracklist[media[0]].join("\n");
        } else {
            media.sort();
            desc += "\n";
            for (i = 0, l = media.length; i < l; i++) {
                desc += "[b]" + (media[i] ? media[i] : 'CD1')  + "[/b]\n" + tracklist[media[i]].join("\n") + "\n\n";
            }
        }

        document.getElementById('album_desc').value = desc.trim();
    };

    self.getExtension = function (path) {
        var ext = path.split('.');
        return ext[ext.length - 1].toLowerCase();
    };
})();