Example #1
0
    run(msg, args) {
        const member = args.member.displayName || 'yourself';

        Canvas.registerFont(path.join(__dirname, '..', '..', 'Assets', 'fonts', 'Roboto.ttf'), { family: 'Roboto' }); // eslint-disable-line max-len
        Canvas.registerFont(path.join(__dirname, '..', '..', 'Assets', 'fonts', 'NotoEmoji-Regular.ttf'), { family: 'Roboto' }); // eslint-disable-line max-len

        const canvas = Canvas.createCanvas();
        const ctx = canvas.getContext('2d');
        const { width, height } = this._textSizes(ctx, member);

        canvas.width = width < 130 ? 130 : width;
        canvas.height = height;

        const generate = () => {
            ctx.font = '700 32px Arial';
            ctx.fillStyle = '#B93F2C';
            ctx.textAlign = 'center';
            ctx.fillText('Blame', canvas.width / 2, 35);

            ctx.fillStyle = '#F01111';
            ctx.fillText(member, canvas.width / 2, 70);
        };
        generate();

        return msg.channel.send({ files: [{ attachment: canvas.toBuffer(), name: 'blame.png' }] });
    }
Example #2
0
    fonts.forEach((font) => {
        if (!fs.statSync(font.src).isFile()) {
            notFound.push(font);
            return;
        }

        Canvas.registerFont(font.src, {
            family: font.name
        });
    });
Example #3
0
  constructor(options) {
    Object.assign(this, options)
    this.imageWidth = 640
    this.imageHeight = 384
    this.width = this.orientation === 'landscape' ? this.imageWidth : this.imageHeight
    this.height = this.orientation === 'landscape' ? this.imageHeight : this.imageWidth
    this.bg = '#000000'
    this.fg = '#FFFFFF'
    this.font = 'SourceCodePro-Regular'
    registerFont(path.join(__dirname, '../../', 'assets/fonts/Source_Code_Pro/SourceCodePro-Regular.ttf'), {family: 'SourceCodePro-Regular'})

    this.canvas = createCanvas(this.width, this.height)
    this.imageCanvas = createCanvas(this.imageWidth, this.imageHeight)

    this.ctx = this.canvas.getContext('2d')
    this.imgCtx = this.imageCanvas.getContext('2d')

    //this.ctx.antialias = 'none'
    this.ctx.imageSmoothingEnabled = false
    this.imgCtx.imageSmoothingEnabled = false
    this.sctx = shapely(this.ctx)
  }
Example #4
0
const Canvas = require('canvas');
const Color = require('color');

const isHex = color => {
  const regex = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;
  const colorText = /#/.test(color) ? color : `#${color}`;

  return regex.test(colorText);
};

function getFontFile(name) {
  return path.resolve(__dirname, '../assets/', name);
}

Canvas.registerFont(getFontFile('Asap-Bold.ttf'), {
  family: 'Asap',
  weight: 'bold',
});

module.exports.drawImage = (req, res) => {
  const palette = req.params.palette.replace('.png', '');

  if (!palette === -1) {
    res.status(404);
    return res.end('Error');
  }

  const formattedPalette = palette.split('-').filter(color => isHex(color));

  if (formattedPalette.length === 0) {
    res.status(404);
    return res.end('Error');
Example #5
0
    async run(message, channel, user, args) {
        const metric = args.indexOf("-f") > -1;
        let geolocation;

        // Remove -f identifier
        if (metric) {
            const pos = args.indexOf("-f");
            args.splice(pos, 1);
        }

        // No Args Supplied
        if (args.length === 0 && message.pung.length === 0) {
            const userDB = await Database.Models.Users.findOne({ where: { id: user.id } });
            const error = `Please provide a query, or set your location with \`${message.prefix}set location <location>\``;

            // Check if User exists in DB
            if (userDB) {
                const data = JSON.parse(userDB.data);

                // Checks if User has a set location
                if (data.weather || data.location) {
                    geolocation = data.weather || data.location;

                    if (typeof geolocation === "string") return this.error(geolocation, channel);
                    if (Array.isArray(geolocation)) {
                        geolocation = {
                            line1: geolocation[0].long_name,
                            line2: geolocation[1].long_name || "",
                            geocode: geolocation[2]
                        };
                    }

                    this.log(`Using Cached Geolocation (${geolocation.line1}, ${geolocation.line2})`, "debug");
                } else {
                    return message.reply(error);
                }
            } else {
                return message.reply(error);
            }
        }

        // If Pinged User
        if (message.pung.length > 0) {
            this.log(`Getting Weather for user ${message.pung[0].id}`, "debug");
            const userDB = await Database.Models.Users.findOne({ where: { id: message.pung[0].id } });

            // Check if User exists in DB
            if (userDB) {
                const data = JSON.parse(userDB.data);

                // Checks if User has a set location
                if (data.weather || data.location) {
                    geolocation = data.weather || data.location;

                    if (typeof geolocation === "string") return this.error(geolocation, channel);
                    if (Array.isArray(geolocation)) {
                        geolocation = {
                            line1: geolocation[0].long_name,
                            line2: geolocation[1].long_name || "",
                            geocode: geolocation[2]
                        };
                    }

                    this.log(`Using Cached Geolocation (${geolocation.line1}, ${geolocation.line2})`, "debug");
                } else {
                    return message.reply("this user has not set their location.");
                }
            } else {
                return message.reply("this user does not have a database entry for their location.");
            }
        }

        // Ignore geolocation request if User has set a location
        if (!geolocation) {
            geolocation = await this.fetchGeolocation(args);
            if (typeof geolocation === "string") return this.error(geolocation, channel);
            if (Array.isArray(geolocation)) {
                geolocation = {
                    line1: geolocation[0].long_name,
                    line2: geolocation[1].long_name,
                    geocode: geolocation[2]
                };
            }
        }

        // console.log(geolocation);

        // Get Weather
        const weather = await request({
            headers: { "User-Agent": "Mozilla/5.0" },
            uri: `https://api.darksky.net/forecast/${this.keychain.darksky}/${geolocation.geocode.join(",")}`,
            json: true,
            qs: {
                units: metric ? "us" : "si",
                excludes: "minutely,hourly,alerts"
            }
        }).catch(error => this.error(error.response.body.error, channel));

        // console.log(weather);

        if (!weather) return false;

        const locale = weather.flags.units === "us" ? "F" : "C";
        const condition = weather.currently.summary;
        const icon = weather.currently.icon;
        const temperature = Math.round(weather.currently.temperature);
        const datetime = moment().tz(weather.timezone).format("h:mm A");
        const forecast = weather.daily.data;

        this.log(`${geolocation.line1}, ${geolocation.line2}: ${temperature}°${locale}, ${condition}, ${datetime}`, "debug");

        Canvas.registerFont(path.join(__dirname, "fonts", "Inter-UI-Medium.ttf"), { family: "InterUI" });

        // Generate Response Image
        const canvas = Canvas.createCanvas(800, 430);
        const ctx = canvas.getContext("2d");
        const { Image } = Canvas;
        const base = new Image();
        const cond = new Image();
        const day1 = new Image();
        const day2 = new Image();
        const high = new Image();
        const low = new Image();

        base.src = path.join(__dirname, "base", `${this.getBaseImage(icon)}.png`);
        cond.src = path.join(__dirname, "icons", `${this.getConditionImage(icon)}.png`);
        day1.src = path.join(__dirname, "icons", `${this.getConditionImage(forecast[1].icon)}.png`);
        day2.src = path.join(__dirname, "icons", `${this.getConditionImage(forecast[2].icon)}.png`);
        high.src = path.join(__dirname, "icons", "high.png");
        low.src = path.join(__dirname, "icons", "low.png");

        // Environment Variables
        ctx.drawImage(base, 0, 0);
        ctx.scale(1, 1);
        ctx.patternQuality = "bilinear";
        ctx.filter = "bilinear";
        ctx.antialias = "subpixel";

        // Town/City/District
        ctx.font = "40px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 1)";
        ctx.fillText(geolocation.line1, 60, 70);

        // State/Region/Country
        ctx.font = "28px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
        ctx.fillText(geolocation.line2, 60, 115);

        // Condition
        ctx.drawImage(cond, 643, 30);

        // Temperature
        ctx.font = "56px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 1)";
        ctx.fillText(`${temperature}°${locale}`, 60, 240);

        // Daily Forecast
        const width = 200 + (temperature.toString().length - 1) * 28; // eslint-disable-line no-mixed-operators
        ctx.font = "28px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 1)";
        ctx.fillText(`${Math.round(forecast[0].temperatureMax)}°`, width + 40, 210);
        ctx.drawImage(high, width, 188);
        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
        ctx.fillText(`${Math.round(forecast[0].temperatureMin)}°`, width + 40, 247);
        ctx.drawImage(low, width, 226);

        // Time
        ctx.textAlign = "right";
        ctx.font = "32px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 0.9)";
        ctx.fillText(datetime, 740, 231);

        // Details
        ctx.textAlign = "left";
        ctx.font = "28px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 1)";
        ctx.fillText(`${Math.round(weather.currently.humidity * 100)}%`, 112, 341);
        ctx.fillText(`${Math.round(weather.currently.precipProbability * 100)}%`, 112, 391);

        // Forecast
        ctx.textAlign = "right";
        ctx.font = "28px InterUI";
        ctx.fillStyle = "rgba(255, 255, 255, 1)";

        // tomorrow
        ctx.fillText("Tomorrow", 530, 341);
        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
        ctx.fillText(`${Math.round(forecast[1].temperatureMin)}°`, 530, 391);
        ctx.fillStyle = "rgba(255, 255, 255, 1)";
        ctx.fillText(`${Math.round(forecast[1].temperatureMax)}°`, 465, 391);
        ctx.drawImage(day1, 360, 364, 36, 36);

        // day after
        ctx.fillText(moment.unix(forecast[2].time).format("dddd"), 740, 341);
        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
        ctx.fillText(`${Math.round(forecast[2].temperatureMin)}°`, 740, 391);
        ctx.fillStyle = "rgba(255, 255, 255, 1)";
        ctx.fillText(`${Math.round(forecast[2].temperatureMax)}°`, 675, 391);
        ctx.drawImage(day2, 570, 364, 36, 36);

        // Send
        /*
        const etho = require("os").networkInterfaces().eth0;
        if (!etho || !etho[0] || etho[0].mac !== this.config.server) {
            const { RichEmbed } = require("discord.js");
            const embed = new RichEmbed()
                .setColor(this.config.colours.warn)
                .setTitle("Notice")
                .setDescription("This command is currently under active redevelopment. As such, you may experience unexpected results when running this command. Feel free to ping me (Kurisu#7700) if you have any questions.");

            channel.send({ embed });
        }
        */

        await channel.send({ files: [{ attachment: canvas.toBuffer(), url: "weather.png" }] });
        return this.delete(message);
    }
Example #6
0
	async run(msg, args) {
		const { location } = args;
		const Image = Canvas.Image;

		Canvas.registerFont(path.join(__dirname, '..', '..', 'assets', 'weather', 'fonts', 'Roboto-Regular.ttf'), { family: 'Roboto' }); // eslint-disable-line max-len
		Canvas.registerFont(path.join(__dirname, '..', '..', 'assets', 'weather', 'fonts', 'RobotoCondensed-Regular.ttf'), { family: 'Roboto Condensed' }); // eslint-disable-line max-len
		Canvas.registerFont(path.join(__dirname, '..', '..', 'assets', 'weather', 'fonts', 'RobotoMono-Light.ttf'), { family: 'Roboto Mono' }); // eslint-disable-line max-len

		if (!GOOGLE_API) return msg.reply('my Commander has not set the Google API Key. Go yell at him.');
		if (!WEATHER_API) return msg.reply('my Commander has not set the Weather API Key. Go yell at him.');

		const locationURI = encodeURIComponent(location.replace(/ /g, '+'));
		const response = await request({
			uri: `https://maps.googleapis.com/maps/api/geocode/json?address=${locationURI}&key=${GOOGLE_API}`,
			headers: { 'User-Agent': `Commando v${version} (https://github.com/WeebDev/Commando/)` },
			json: true
		});

		if (response.status !== 'OK') return msg.reply(this.handleNotOK(msg, response.status));
		if (response.results.length === 0) return msg.reply('your request returned no results.');

		const geocodelocation = response.results[0].formatted_address;
		const params = `${response.results[0].geometry.location.lat},${response.results[0].geometry.location.lng}`;

		const locality = response.results[0].address_components.find(loc => loc.types.includes('locality'));
		const governing = response.results[0].address_components.find(gov => gov.types.includes('administrative_area_level_1')); // eslint-disable-line max-len
		const country = response.results[0].address_components.find(cou => cou.types.includes('country'));
		const continent = response.results[0].address_components.find(con => con.types.includes('continent'));

		const city = locality || governing || country || continent || {};
		const state = locality && governing ? governing : locality ? country : {};

		const res = await request({
			uri: `https://api.darksky.net/forecast/${WEATHER_API}/${params}?exclude=minutely,hourly,flags&units=auto`,
			headers: { 'User-Agent': `Commando v${version} (https://github.com/WeebDev/Commando/)` },
			json: true
		});

		const condition = res.currently.summary;
		const icon = res.currently.icon;
		const chanceofrain = Math.round((res.currently.precipProbability * 100) / 5) * 5;
		const temperature = Math.round(res.currently.temperature);
		const humidity = Math.round(res.currently.humidity * 100);

		const canvas = new Canvas(400, 180);
		const ctx = canvas.getContext('2d');
		const base = new Image();
		const cond = new Image();
		const humid = new Image();
		const precip = new Image();

		let theme = 'light';
		let fontColor = '#FFFFFF';
		if (icon === 'snow' || icon === 'sleet' || icon === 'fog') {
			theme = 'dark';
			fontColor = '#444444';
		}

		const generate = () => {
			// Environment Variables
			ctx.drawImage(base, 0, 0);
			ctx.scale(1, 1);
			ctx.patternQuality = 'billinear';
			ctx.filter = 'bilinear';
			ctx.antialias = 'subpixel';

			// City Name
			ctx.font = '20px Roboto';
			ctx.fillStyle = fontColor;
			ctx.fillText(city.long_name ? city.long_name : 'Unknown', 35, 50);

			// Prefecture Name
			ctx.font = '16px Roboto';
			ctx.fillStyle = theme === 'light' ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.8)';
			ctx.fillText(state.long_name ? state.long_name : '', 35, 72.5);

			// Temperature
			ctx.font = "48px 'Roboto Mono'";
			ctx.fillStyle = fontColor;
			ctx.fillText(`${temperature}°`, 35, 140);

			// Condition
			ctx.font = '16px Roboto';
			ctx.textAlign = 'right';
			ctx.fillText(condition, 370, 142);

			// Condition Image
			ctx.drawImage(cond, 325, 31);

			// Humidity Image
			ctx.drawImage(humid, 358, 88);

			// Precip Image
			ctx.drawImage(precip, 358, 108);

			// Titles
			ctx.font = "16px 'Roboto Condensed'";
			ctx.fillText(`${humidity}%`, 353, 100);
			ctx.fillText(`${chanceofrain}%`, 353, 121);
		};

		base.src = await fs.readFileAsync(this.getBase(icon));
		cond.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'weather', 'icons', theme, `${icon}.png`)); // eslint-disable-line max-len
		humid.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'weather', 'icons', theme, 'humidity.png')); // eslint-disable-line max-len
		precip.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'weather', 'icons', theme, 'precip.png')); // eslint-disable-line max-len
		generate();

		return msg.channel.send({ files: [{ attachment: canvas.toBuffer(), name: `${geocodelocation}.png` }] });
	}
 fonts.forEach(function(font){
   Canvas.registerFont(font.file, _.pick(font, "family", "weight", "style"));
 });
Example #8
0
    async parse(data, debug) {
        this.log("Running EEW Parser", "debug");

        const channel = debug ? this.debugChannel : this.postChannel;

        const response = await request({
            headers: { "User-Agent": "Mozilla/5.0" },
            uri: "https://maps.googleapis.com/maps/api/staticmap",
            encoding: "binary",
            qs: {
                zoom: 6,
                size: "386x159",
                format: "png",
                maptype: "roadmap",
                style: "feature:road|color:0xFFFFF",
                center: `${data.details.geography.lat},${data.details.geography.long}`,
                markers: `${data.details.geography.lat},${data.details.geography.long}`
            }
        }).catch(err => {
            this.log(err, "fatal", true);
            return this.error(err, this.debugChannel);
        });

        Canvas.registerFont(path.join(__dirname, "Roboto.ttf"), { family: "Roboto" });

        const canvas = new Canvas(400, 280);
        const ctx = canvas.getContext("2d");

        const { Image } = Canvas;
        const map = new Image();
        const base = new Image();

        map.src = new Buffer(response, "binary");
        base.src = fs.readFileSync(path.join(__dirname, "base.png"));

        // Draw Image
        ctx.drawImage(base, 0, 0);
        ctx.drawImage(map, 7, 73);
        ctx.scale(1, 1);
        ctx.patternQuality = "bilinear";
        ctx.filter = "bilinear";
        ctx.antialias = "subpixel";

        // Epicenter
        ctx.font = "17px Roboto";
        ctx.fillStyle = "#FFF";
        ctx.fillText(data.details.epicenter.en, 20, 35);

        // Details
        ctx.font = "15px Roboto";
        ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
        ctx.fillText(`Magnitude ${data.details.magnitude}, Seismic ${data.details.seismic.en}, Depth ${data.details.geography.depth}km`, 20, 58);

        // Footer
        ctx.font = "15px Roboto";
        ctx.fillStyle = "#000";
        ctx.fillText("Information is preliminary", 56, 257);

        // New Quake
        if (!(data.id in previous_quake)) {
            previous_quake[data.id] = data;
            previous_message = await channel.sendFile(canvas.toBuffer());
            this.log(`Posted Image to #${channel.name}`, "debug");
            return true;
        // Last Revision
        } else if (data.situation === 1) {
            previous_quake[data.id] = data;
            await previous_message.delete().catch(err => err.message);
            this.log(`Deleted Previous Image from #${channel.name}`, "debug");
            previous_message = "";
            await channel.sendFile(canvas.toBuffer());
            this.log(`Posted Image to #${channel.name}`, "debug");
            return true;
        }

        return false;
    }