Pull to refresh

Comments 10

pronskiy ошибочка «Пошаговое УРКоводство по созданию первого приложения на Laravel»
Говорили, говорили, говорили не размещать .svn, .git, .env в папках, которые доступны веб-серверу, а воз и нынче там…
Где-то на StackOverflow видел как рекомендовали при использовании Apache все с public выносить в корень, так как он дефолтно смотрит в корень xDDD
[RFC] Typed Properties 2.0 — Предложение по типизированным свойства принято практически единогласно: 70 против 1! Типизированные свойства будут добавлены в PHP 7.4.

А против проголосовал как раз Дмитрий Стогов. Интересно, кстати, почему?
О, да, вполне возможно, кстати. Но по-моему, что это всего лишь обуславливается «сыростью» патча, т.к. он на перспективу позволяет облегчить Zval, избавив поля от лишних данных в режиме strict_types.
Ник на рэддите [объяснял](https://www.reddit.com/r/PHP/comments/9j2oel/rfc_about_typed_properties_has_been_accepted/e6o94hd/).

Прикольный слон. Кстати сделан скорее всего с помощью https://github.com/fogleman/primitive.


Вот бота писал для телеграмм


Заголовок спойлера
const fs = require('fs');
const exec = require('child_process').execSync;
const temp = require("temp").track();
const pathComponent = require('path');
const TelegramBot = require('node-telegram-bot-api');

const Settings = function () {
    this.defaultSettings = {
        rect: 1,
        type: 0
    };

    this.container = {};
};

Settings.prototype = {
    getValue: function (chatId, value = null) {
        if (this.container.hasOwnProperty(chatId)) {
            return value ? this.container[chatId][value] : this.container[chatId]
        }

        return value ? this.getDefault()[value] : this.getDefault();
    },
    setValue: function (chatId, key, value) {
        if (!this.container.hasOwnProperty(chatId)) {
            this.container[chatId] = this.getDefault();
        }

        if (Object.keys(this.defaultSettings).indexOf(key) === -1) {
            console.log('Try to set unknown setting: ' + key);
            return;
        }

        if (key === 'type' || key === 'rect') {
            value = parseInt(value, 10)
        }

        this.container[chatId][key] = value;
    },
    getDefault: function () {
        return Object.assign({}, this.defaultSettings);
    }
};

const settingsContainer = new Settings();

// Устанавливаем токен, который выдавал нам бот.
const token = '';
const downloadDir = './downloaded/';

const rectOptions = {
    reply_markup: JSON.stringify({
        inline_keyboard: [
            [{text: 'Треугольники', callback_data: 'rect_1'}],
            [{text: 'Прямоугольники', callback_data: 'rect_2'}],
            [{text: 'Эллипсы', callback_data: 'rect_3'}],
            [{text: 'Круги', callback_data: 'rect_4'}],
            [{text: 'Прямоугольники(rotated)', callback_data: 'rect_5'}],
            [{text: 'Кривые', callback_data: 'rect_6'}],
            [{text: 'Эллипсы(rotated)', callback_data: 'rect_7'}],
            [{text: 'Полигоны', callback_data: 'rect_8'}],
        ]
    })
};

const typeOptions = {
    reply_markup: JSON.stringify({
        inline_keyboard: [
            [{text: 'Простая картинка', callback_data: 'type_0'}],
            [{text: 'Движущаяся картинка', callback_data: 'type_1'}]
        ]
    })
};

// Включить опрос сервера
const bot = new TelegramBot(token, {polling: true});

bot.onText(/\/start/, function (msg) {
    bot.sendMessage(msg.chat.id, '/status /settype /setfig');
});

bot.onText(/\/status/, function (msg) {
    bot.sendMessage(msg.chat.id, 'I am alive!');
});

bot.onText(/\/setfig/, function (msg) {
    bot.sendMessage(msg.chat.id, 'Выберите фигуры из которых будет формируется изображение:', rectOptions);
});

bot.onText(/\/settype/, function (msg) {
    bot.sendMessage(msg.chat.id, 'Выберите тип возвращаемого изображения:', typeOptions);
});

bot.on('callback_query', function (msg) {
    let chatId = msg.message.chat.id;

    let answer = msg.data.split('_');
    if (answer.length === 2) {
        settingsContainer.setValue(chatId, answer[0], answer[1]);
    }
    bot.sendMessage(chatId, 'ok');
});

bot.on('message', function (msg) {
   console.log(msg); 
});

bot.on('photo', onPhoto);

async function onPhoto (msg) {
    let chatId = msg.chat.id;

    try {
        let image = initImage(msg);
        let originalImagePath = await bot.downloadFile(image.file_id, downloadDir);
        let ext = pathComponent.extname(originalImagePath);
        let resizedImagePath = temp.path({suffix: ext});
        let processedImagePath;

        await resizeImage(image, originalImagePath, resizedImagePath);

        let settings = settingsContainer.getValue(chatId);
        console.log(settings);
        if (settings.type === 0) {
            processedImagePath = temp.path({suffix: ext});
            makeSimpleImage(settings, resizedImagePath, processedImagePath);
            await bot.sendPhoto(chatId, processedImagePath, {});
        } else if (settings.type === 1) {
            processedImagePath = temp.path({suffix: '.gif'});
            await makeGif(settings, image, resizedImagePath, processedImagePath);
            await bot.sendVideo(chatId, processedImagePath, {});
        }

        temp.cleanupSync();
    } catch (err) {
        console.log(err);
        return bot.sendMessage(chatId, err);
    }
}

function initImage(msg) {
    let photo = msg.photo || [];
    let lastFileSize = 0;
    let maxResId = -1;
    let i;

    for (i = 0; i < photo.length; i++) {
        if ((photo[i].file_size || 0) > lastFileSize) {
            maxResId = i;
        }
    }

    if (maxResId === -1) {
        throw new Error('No photo info');
    }

    let msgPhoto = photo[maxResId];
    ['file_id', 'width', 'height'].forEach(function (prop) {
        if (!msgPhoto.hasOwnProperty(prop)) {
            throw new Error('No photo size');
        }
    });

    return msgPhoto;
}

function resizeImage (image, from_path, to_path) {
    let resize = image.width > image.height ? '256x' : 'x256';
    return exec('convert -geometry ' + resize + ' ' + from_path + ' ' + to_path)
}

function makeSimpleImage(settings, from_path, to_path) {
    return exec('primitive -n 250 -m ' + settings.rect + ' -i ' + from_path + ' -o ' + to_path)
}

async function makeGif(settings, image, from_path, to_path) {
    let dir = './series/' + makeRandName();
    let size = image.width > image.height ? '512:' : ':512';

    if (!fs.existsSync(dir)){
        fs.mkdirSync(dir);
    }

    for (let i = 1; i <=5 ; i++) {
        makeSimpleImage(settings, from_path, '/ ' + i + '.svg');
        exec('node node_modules/svgexport/bin/index.js ' + dir + '/' + i + '.svg ' + dir + '/' + i +'.png ' + size);
    }

    let makeGifCommand = 'convert -loop 0 -delay 12 ' +
        dir + '/1.png ' +
        dir + '/2.png ' +
        dir + '/3.png ' +
        dir + '/4.png ' +
        dir + '/5.png ' +
        to_path;

    console.log(makeGifCommand);

    return exec(makeGifCommand);
}

function makeRandName() {
    let text = "";
    let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (let i = 0; i < 8; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}
Sign up to leave a comment.