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, като всичко след името на домейна го постави като аргумент. Примерно:
https://localhost/system-info
ще се преобразува в:
https://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. Този файлов мениджър е поместен само в един файл и има достатъчно опции за редактиране, които са ми напълно достатъчни.

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

Share and Enjoy !

Shares

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

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

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

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

Share and Enjoy !

Shares

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

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

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

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

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

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


Share and Enjoy !

Shares

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

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

  • Кода е изцяло пренаписан, като вече е обектен, което ще ме улесни да прилагам нови методи на редене
  • Добавен е диагонален модел за редене на плочките
  • Добавен е генериран код за CAD-софтуера QCad

Програмата работи с всички модерни браузери и мобилни устройства. Калкулатора може да се зареди онлайн от тук:
Tile Calculator

Изтегляне на калкулатора + source: Simple_Tile_Calculator-v.002.zip

След разархивиране на архива може да се ползва само html-файла в основната директория. В папката source е развойната версия на калкулатора с scss-кода.

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

Share and Enjoy !

Shares




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.
Кратко видео по темата:

Share and Enjoy !

Shares

Batch get latest C Sharp compiler from Microsoft.NET directory

Простичък код на batch който взима последния csc.exe от Microsoft.NET\Framework. Кода се пейства в bat-файл и при двоен клик компилира script.cs.

1
2
3
4
5
6
7
@echo off
for /f "TOKENS=1" %%x in ('dir %windir%\Microsoft.Net\framework\v* /b ^| findstr "v[1-9]"') do (
  set myPID=%%x
)
set csc=%windir%\Microsoft.Net\framework\%myPID%\csc.exe
 
%csc% /t:winexe script.cs

Share and Enjoy !

Shares




Chrome Extension – how to. Кратък урок за създаване на Chrome добавка.

Ще се опитам да опиша простичко, как се разработва прост extension add-on за Chrome. Понякога е много полезно да се работи с подобни скриптове, особено при скрапване на web-съдържание, когато конвенционалните методи не работят или изискват прекалено много усилия.
За да се създаде подобен скрипт с потребителски интерфейс ще са ни необходими няколко файла:
manifest.json – всяка добавка (extension) за Chrome (а и за другите браузери) съдържа подобен скрипт, който предоставя важна информация на браузера. Повече тук: Manifest File Format
popup.html – стандартно наименование на файла с потребителския интерфейс, който се появява при клик с мишката върху добавката. Разбира се, можем да създадем добавка, която няма нужда от потребителски интерфейс, но в случая аз искам да имам. Името на този файл се посочва в manifest.json.
popup.js – файл, който се зарежда чрез popup.html. Можем и да нямаме подобен файл и да поместим javascript кода направо в popup.html. Но тенденциите в модерното програмиране съветват да се диференцира всичко – стилове, скриптове, html. В моя случай popup.js е двигателя на Chrome добавката. Той посочва какво, кога и къде да се активира.
getPagesSource.js – файл за инжектиране в web-страницата и извлича информацията от нея. Този файл се зарежда от popup.js.
icon.png – някаква иконка, която да се показва в листата с добавките на Chrome.

Нека създадем скрипт, който извлиза съдържанието на определени тагове, като използваме javascript функцията querySelectorAll(). Много приятна функция, която заменя в известна степен нуждата от XPath при web-скрапинга.

Да започваме! Първо създаваме manifest.json, като описваме какво прави тая добавка:

1
2
3
4
5
6
7
8
9
10
11
{
  "name": "Simple web scraper",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Get content from tags through querySelector",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": ["tabs", "<all_urls>"]
}

След това си правим потребителския интерфейс popup.html – бутончета, поленца, форми, стилове, каквото ни е кеф. В случая ще се огранича на минимума за моите нужди – текстово поле, бутон, слой за резултата:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html style=''>
<head>
 
</head>
<body style="width:400px;">
 
	<input type="text" id="selector" style="width:300px;" />
	<button id="getselector">Get Selector</button><br /><hr />
 
	<div id='message'>Injecting Script....</div>
 
	<script src='popup.js'></script>
</body>
</html>

В по-горния скрипт се вижда, че зареждам popup.js. Неговото съдържание е следното:

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
chrome.runtime.onMessage.addListener(function(request, sender) {
  if (request.action == "getSlectedContent") {
    message.innerHTML = request.source;
  }
});
 
document.querySelector('#getselector').addEventListener('click', winLoad);
 
function winLoad() {
 
  var message = document.querySelector('#message');
  var inputSel = document.querySelector('#selector').value;
 
  var queryInfo = {
    active: true,
    currentWindow: true
  };
 
  chrome.tabs.query(queryInfo, function(tabs) {
    chrome.tabs.sendMessage(
      tabs[0].id, {
        customSelector: inputSel
      },
      function(response) {
    });
  });
 
  chrome.tabs.executeScript(null, {
    file: "getPageContent.js"
  }, function() {
    if (chrome.runtime.lastError) {
      message.innerText = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
    }
  });
}

Чрез popup.js зарежда javascripta, който се инжектира в страницата – getPageContent.js:

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
chrome.runtime.onMessage.addListener(function(request, sender) {
  selElements(document, request.customSelector);
});
 
function selElements(document_root, s){
 
  // Tova go dobaviam zaradi kefa da polzvam foreach() v JavaScript
  var forEach = function (array, callback, scope) {
    for (var i = 0; i < array.length; i++) {
    callback.call(scope, i, array[i]);
    }
  };
 
  var myNodeList = document.querySelectorAll(s);
  var concatenateall = '';
  forEach(myNodeList, function (index, value) {
    concatenateall = concatenateall + value.innerHTML + "<hr />";
  });
 
  // return concatenateall;
  chrome.runtime.sendMessage({
    action: "getSlectedContent",
    source: concatenateall
  });
}

Това е.
Сега остава да заредим добавката в Chrome. Това става като отворим More Tools -> Extensions. След това кликаме на бутона Load unpacked и избираме директорията с файловете на нашата добавка.
На базата на тази добавка могат да се направят много други, тъй като съдържа базата за писане на добавки за Chrome.

Сорс кода може да се изтегли от тук: Chrome_Extension-Simple.zip

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

Share and Enjoy !

Shares




Viber Export Conversation – експортиране на разговори от Viber

Viber Export Conversation
Viber е удобен чат клиент, но възможностите за експортиране на разговор са никакви. За това написах проста програмка на AutoIt, която да експортира разговор с избран потребител до по-достъпен формат. За сега експортира до Excel и HTML. Програмката се казва Viber Export Conversation. Сорса е много прост и е писан набързо, колкото да свърши работа. За сега е тествана под Windows 7 64bit. Няма си на идея, дали ще работи под други Windows-и. Ще съм благодарен, ако някой намери бъг или не може да подкара програмата и ми сподели като коментар.

Може да се изтегли от тук: Viber Export Conversation-v0.02.zip

В архива се намира и сорса за компилиране с AutoIt.
За да се ползва програмката, трябва да се разархивира. Конвертираните файлове (excel или html) се записват в директорията на exe-то.
PS: Имах желание да портна програмата до Android, но ще иска root, за да чете базата данни на Viber, а не всеки потребител иска да си рутва телефона. За това, поне за сега я оставям във версия за PC.

Share and Enjoy !

Shares




Bootstrap and tinyMCE examples

Bootstrap и tinyMCE са ми редовна комбинация. И за да не откривам топлата вода всеки път, ще постна малко подсетки с прост мой плъгин за tinyMCE.
Важно е да се промени javascript променливата current_host.
Bootstrap 3 and tinyMCE editor - examples
Demo
Download

Share and Enjoy !

Shares