Socialify

Folder ..

Viewing index.js
104 lines (89 loc) • 3.9 KB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
const fs = require('fs');
const path = require('path');
const pathWalker = require('walk');
export default class RandomAvatars {
    constructor(string, hashcount = 11, ignoreext = true) {
        /**
         * This creates our avatar.
         * Takes in a string and makes an picture out of it.
         */
        let string = string;
        if (ignoreext) string = removeExts(this, string);

        this.hexdigest = crypto.createHash('sha512').update(string).digest('hex');
        this.hasharray = [];
        // Start this at 4, so earlier is reserved
        // 0 = Color
        // 1 = Set
        // 2 = bgset
        // 3 = BG
        this.iter = 4;
        createhashes(this, hashcount);
        this.resourceDir = __dirname + '/';
        // Get the list of Backgrounds and Robosets
        this.sets = this.listDirs(resourceDir + 'sets')
        this.bgsets = this.listDirs(resourceDir + 'backgrounds');
        
        // Get the colors in set 1
        this.colors = this.listDirs(resourceDir + 'sets/set1');
        this.format = 'png';
    }

    removeExts(string) {
        /**
         * Sets the input string to create an avatar
         */
    
        // If the user hasn't disabled it, we will detect image extensions, such as .png, .jpg, etc.
        // We'll remove them from the string before hashing.
        // This ensures that /Bear.png and /Bear.bmp will send back the same image, in different formats.
    
        let input = (String(string)).toLowerCase();
        if (input.endsWith('.png') || input.endsWith('.gif') || input.endsWith('.jpg') || input.endsWith('.bmp') || input.endsWith('.jpeg') || input.endsWith('.ppm') || input.endsWith('.datauri')) {
            let format = input.substr(input.lastIndexOf('.') + 1, input.length);
            if (format.toLowerCase() === 'jpg') format = 'jpg';
            this.format = format;
            input = input.substr(0, input.lastIndexOf('.'));
        }
        return input;
    }
    
    createhashes(count) {
        /**
         * Breaks up our hash into slots, so we can pull them out later.
         * Essentially, it splits our SHA/MD5/etc into X parts.
         */
    
        for (const i of Array(count).keys()) {
            // Get 1/numblocks of the hash
            const blocksize = parseInt(this.hexdigest.length/count);
            const currentStart = ((i + 1) * blocksize) - blocksize;
            const currentEnd = (1 +i) * blocksize;
            this.hasharray.push(parseInt(this.hexdigest.substr(currentStart, currentEnd), 16));
        }
        this.hasharray = this.hasharray + this.hasharray;
    }

    listDirs(path) {
        return fs.readdirSync(path, {withFileTypes: true}).filter((dir) => dir.isDirectory()).map((dir) => dir.name);
    }

    getListOfFiles(path) {
        // Go through each subdirectory of `path`, and choose one file from each to use in our hash.
        // Continue to increase self.iter, so we use a different 'slot' of randomness each time.

        const walker = pathWalker.walk(path);
        const chosenFiles = [];

        // Get a list of all subdirectories
        const directories = [];
        walker.on('directory', (root, fileStats, next) => {
            if (fileStats.name.substr(0,1) !== '.') {
                directories.push(path.join(root, fileStats.name));
            }
            next();
        });

        // Go through each directory in the list, and choose one file from each.
        // Add this file to our master list of robotparts.

        for (const directory of directories) {
            const filesInDir = [];
            for (const imagefile of this.listDirs(directory)) {
                filesInDir.push(imagefile);
            }

            // Use some of our hash bits to choose which file
            const elementInList = this.hasharray[this.iter] % filesInDir.length();
            chosenFiles.push(filesInDir[elementInList]);
            this.iter += 1;
        }

        return chosenFiles;
    }
}