Javascript arrow function on Object

parts = {
	"one": [ 2, 3, 4 ],
	"two": [ 5, 6, 7 ],
	"tree": [ 8, 9, 10 ]
}

Object.keys(parts).map((part) =>
	parts[part].map((el, index) => 
		parts[part][index] = el+1
	)
);
console.log(parts);
// Result:
// { one: [ 3, 4, 5 ], two: [ 6, 7, 8 ], tree: [ 9, 10, 11 ] }

SVG text as HTML background

И що чак сега се сетих, че мога да ползвам SVG text като background?! И не само текст. Че даже мога да си го променям динамично през javascript! Така някои дизайни можеше да станат по-фън-шуй. По-добре късно от колкото без SVG.
Едно примерче:

<!DOCTYPE html>
<html>
<body>

<button onclick="myFunction()">Try it</button>

<p style="min-height: 400px">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

<script>
function myFunction() {
   let txt = "SVG Txt";

   let s = window.btoa(`
<svg height="400" width="800" xmlns="http://www.w3.org/2000/svg">
   <text x="0" y="120" font-weight="bold" font-size="160" fill="#fef" stroke="#ddd">${txt}</text>
</svg>`
);

   document.querySelector("p").style.background = `url('data:image/svg+xml;base64,${s}') no-repeat top left`;
}
</script>

</body>
</html>

Demo: text_as_background.html

Kitchen cabinet calculator

Написах един инструмент, който да ми помогне при калкулирането на необходимите плоскости за сглобяване на кухненски шкафове. Интрумента представлява един HTML файл, който може да се стартира от всяко устройство. Кода е респонзив. Най-полезната за мен опция е възможността за експортиране на модела в Blender чрез генериране на Python скрипт. Кръстих го Kitchen cabinet calculator и е на английски, за да мога да обхвана по-голяма аудитория. Като ми остане време, ще направя и версия на български, но за сега мисля, че е достатъчно разбираем. Кода е напълно свободен и всеки с PHP 7 и по-висока версия може да си го компилира.

Demo: Kitchen cabinet calculator

Download: Kitchen cabinet calculator
Source: Kitchen cabinet calculator – Source

Видео ръководство, как се използва инструмента:
https://youtu.be/LPJBfQQgEp8

Robocopy – simple BackUp under Windows

robocopy <source> <destination> /E /Purge

/E – копира със субдиректориите
/Purge – изтрива от destination липсващите файлове в source

Трябва да се отбележи, че командата копира съдържанието на посочените директории, без да копира самата source директория.

Под Linux ползвам rsync със следната команда:

rsync -r -n -t -v --progress --delete -s /source/some_dir /destination

В този случай rsync копира директорията some_dir в /destination/some_dir.

nginx portable web server

Трябва ми лек сървар с който да управлявам едн компютър, който ползвам за нещо като локален NAS. Apache тотално не ми се вписва в сметките, защото напоследък брах ядове с пълното му деинсталиране от системата. Затова се спрях на конкурента му nginx. По-долу поствам някои интересни моменти от тестовете, които направих под Windows.
За да мога да достъпвам сървара в локална мрежа, трябваше да променя настройките на Firewall-а на Windows 10. В моя случай промених настройки на firewall на Nod32, който е асоцииран по подразбиране в firewall-a на Win.

Изтеглих Mainline version на nginx от тук: nginx download

Разархивирах го в една директория и му промених conf/nginx.conf така, че да отговаря на моите нужди. Важно е да се отбележи, че предварително имам инсталиран PHP 7.2, който е добавен в променливите на обкръжението на Win10.

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    # gzip  on;

    server {
        listen       80;
        server_name  192.168.0.21;

        location / {
            root F:\\nginx-1.19.7\\site\\local;
            index  index.php;
            try_files $uri $uri/ /index.php?$args;
        }

        #rewrite ^/(.*)$ /index.php/$1 last;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root           F:\\nginx-1.19.7\\site\\local;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}

Реда:

try_files $uri $uri/ /index.php?$args;

казва на сървара първо да потърси файл, след това директория и най-накрая ако не намери предните две да потърси index.php, като всичко след името на домейна го постави като аргумент. Примерно:
http://localhost/system-info
ще се преобразува в:
http://localhost/index.php?/system-info
По този начин мога да ползвам френдли адресиране, вместо да изписвам остарелите GET променливи. В Apache се ползва .htaccess за тая цел. Но в nginx тези инструкции се поместват в основния кофигурационен файл.

За да спирам и пускам сървара използвах batch код, който намерих някъде в мрежата. Коментирал съм с REM кодове в скрипта, които могат да са полезни след време, но които не са ми необходими, като спиране и пускане на MySQL. Напоследък за леки проекти ползвам основно SQLite с RedBeanPHP като ORM:

@echo off
REM cd C:\WebServer\nginx


IF "%1" == "stop" (
	GOTO STOPSERVER
)else IF "%1" == "start" (
	GOTO STARTSERVER
)else (
	echo Use these commands:
	echo.
	echo myserver start
	echo myserver stop
)
GOTO END

:STARTSERVER
REM QPROCESS * | find /I /N "mysqld.exe">NUL
REM IF "%ERRORLEVEL%"=="0" (
REM	 echo MYSQLD is already running.
REM )else (
REM 	RunHiddenConsole.exe mysqld --console
REM	echo MYSQLD is now running.
REM )

QPROCESS * | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
	echo NGINX is already running.
)else (
	RunHiddenConsole.exe nginx
	echo NGINX is now running.
)

QPROCESS * | find /I /N "php-cgi.exe">NUL
IF "%ERRORLEVEL%"=="0" (
	echo PHP-CGI is already running.
)else (
	RunHiddenConsole.exe php-cgi -b 127.0.0.1:9000
	echo PHP-CGI is now running.
)

echo.
echo To stop, type "myserver stop"

GOTO END

:STOPSERVER

REM QPROCESS * | find /I /N "mysqld.exe">NUL
REM IF "%ERRORLEVEL%"=="0" (
REM 	taskkill /F /IM mysqld.exe>NUL
REM 	echo MYSQLD ended successfully.
REM )else (
REM 	echo MYSQLD is not running
REM )

QPROCESS * | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
	::nginx -s stop
	taskkill /F /IM nginx.exe>NUL
	echo NGINX ended successfully.
)else (
	echo NGINX is not running
)

QPROCESS * | find /I /N "php-cgi.exe">NUL
IF "%ERRORLEVEL%"=="0" (
	taskkill /F /IM php-cgi.exe>NUL
	echo PHP-CGI ended successfully.
)else (
	echo PHP-CGI is not running
)

:END

Запазих по-горния код в директорията с exe-то на nginx в файла myserver.bat. Пускане и спиране на сървара става с командите:

myserver start
myserver stop

За файлов фмениджър на NAS-чето за сега съм се спрял на Tiny File Manager. Този файлов мениджър е поместен само в един файл и има достатъчно опции за редактиране, които са ми напълно достатъчни.

Това е. Получи се много гот.

Прост генератор на тестове по математика за 4-ти клас

За да ми е по-лесно да преговаряме с дъщеря ми по математика, си правя простички файлчета тест-генератори на Excel. Споделям един тест-файл по математика за 4-ти клас. Добавих му малко екстри, за да може да се използва от начални учители или от други деца. Освен задачите автоматично се генерират и отговорите. Генерирането на нов тест става като се натисне бутона F9 от клавиатурта. Основната страница на теста е форматираната като страница за принтиране, файла може да се запази като PDF и така да се генерират множество готови тестове с отговорите.

Изтегли файла: Test_Matematika_IVkl.xlsx

Кратко видео, което показва как може да се ползва файла:

PHP Captcha Generator – с възможности за настройка

В различните ми проекти с PHP съм ползвал различни Captcha генератори, за да се пазя от спамери и ботове. Но винаги нещо ми е липсвало или са били прекалено грамадански за семплите ми нужди. За това си написах един клас, който лесно да мога да интегрирам в проектите. Всъщност идеята беше друга – да направя голямо количество предефинирани капчи и да ги набутам в SQLite файл, така скоростта на зареждане става муцка. Това и направих. Но така или иначе написах голяма част от кода, та реших да направя и един самостоятелен клас. В последствие, ако ми текне музата, мога да напиша и туториал и със сесии да демострирам, как използвам капчата в реални условия.

Моя Captcha Generator има няколко готини опции за настройка:

  • използване на множесвно TTF-шрифтове. Аз ползвам такива от https://fonts.google.com
  • настройка големината на шрифта
  • настройка на отстоянието между отделните знаци
  • дефиниране на различни ъгли за наклон на знаците
  • дефиниране на собствен масив от знаци

Captcha generator класа с много простичко примерче може да се изтегли от тук:
http://blog.nediko.info/examples/captcha_generator/CaptchaGen_PHP.zip

А ето и един видео урок, който направих набързо, за да е ясно как се настройва генератора:


Simple Tile Calculator – прост калкулатор за редене на плочки

Престои ми ремонт и имам нужда от нещо, което да ми смята бързо броя плочки, като добавя фугите. За това си написах калкулатор на jacascript. Представлява обикновена web-страница. Работи с почти всички модерни браузери. Калкулатора може да се зареди от тук:
Tile Calculator

Или да се изтегли: TileCalculator_v.001.zip

Кратко видео, което показва моя начин на ползване на това тулче:

C programming – run time tasks

Езикът C винаги може да помогне в критични моменти. Той е парен чук! Трябваше ми просто, малко по размер и прецизно по време приложение за Windows. За да се свързвам с Arduino контролер. Мислих, мислих и се върнах към C. Башка, че Arduino също е почти C, макар и да е повече Processing. Поствам програмка, която прави нещо на всеки 5 секунди.

#include <stdio.h>
#include <windows.h>
#include <time.h>

#define interval 5

int do_something(char *i);

int main()
{
    // main
    int h, m, s, once;
    char str[100];
    time_t now;
    struct tm *tm;

    while (1)
    {
        now = time(0);
        tm = localtime (&now);

        h = tm->tm_hour;
        m = tm->tm_min;
        s = tm->tm_sec;

        if (!(s % interval) && once != 1 ){
            sprintf(str, "Time: %d:%d:%d\n", h, m, s);
            do_something(str);
            once = 1;
        } else if (!(s % interval) && once == 1 ) {
            continue;
        } else {
            once = 2;
        }

        Sleep(990);
    }

    return 0;
}

int do_something(char *i){
  printf(i);
}

Source file: time_tasks.c

За програматор използвах Tiny C.
Кратко видео по темата: