Плагины для Internet Explorer в браузерах на базе Chromium

Плагины для Internet Explorer в браузерах на базе Chromium

IE Tab

Столкнулся с проблемой, что в новых версиях Windows нет браузера Internet Explorer, а он необходим например для настройки видеорегистраторов на базе HiWatch, Hikvision, XMEye и т.д.

Например при попытке открыть в Chrome веб-морду регистратора на базе XMEye нам вываливается такое сообщение:

Сообщение в Chrome
Сообщение в Chrome

В нем нам предлагают установить более старую версию браузера, и соответственно ничего не работает.

Не работает в Chrome
Не работает в Chrome

Для себя я нашел отличное решение под названием IE Tab.

Что такое IE Tab?

IE Tab — расширение Firefox, созданное для просмотра сайтов, которые могут быть корректно отображены только в Internet Explorer, например, использующих элементы ActiveX или «расширения» стандарта HTML от Microsoft, в окне браузеров Google Chrome, Mozilla Firefox, Flock, Mozilla Suite и SeaMonkey.

Установив расширение из магазина нужно открыть адрес регистратора и нажать на иконку расширения

Запускаем IE Tab
Запускаем IE Tab

После чего страница откроется в расширении IE Tab

Страница открылась через IE Tab
Страница открылась через IE Tab

Как видно, все отлично работает в Chrome

Все отлично работает в Chrome
Все отлично работает в Chrome

Также в настройках плагина можно выбрать какую версию Internet Explorer эмулировать.

Выбор версии Internet Explorer в IE Tab
Выбор версии Internet Explorer в IE Tab

На этом все, спасибо за внимание! Надеюсь данная статья вам помогла 🙂

Добавляем CKEditor 4 в Laravel Orchid + Laravel Filemanager

Добавляем CKEditor 4 в Laravel Orchid + Laravel Filemanager

CKEditor в Laravel Orchid

В данной статье я расскажу как добавить поле с WYSIWYG редактором CKEditor 4 в Laravel Orchid.
В первую очередь нужно установить сам CKEditor. Для этого в консоли выполняем:

npm install ckeditor4

После создаем файл resources\js\controllers\ckeditor_controller.js со следующим содержимым:

export default class extends window.Controller {
    connect() {
        CKEDITOR.replace('ckeditor', {
            height: '500px'
        });
    }
}

Файл resources\js\dashboard.js с содержимым:

import Ckeditor_controller from './controllers/ckeditor_controller';

application.register("ckeditor", Ckeditor_controller);

В файл webpack.mix.js добавляем:

mix.copyDirectory('./node_modules/ckeditor4/', 'public/js/ckeditor4');
mix.js('resources/js/dashboard.js', 'public/js');

Собираем все:

npm run dev

Регистрируем наши ресурсы в app\Providers\AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Orchid\Platform\Dashboard;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot(Dashboard $dashboard)
    {
        $dashboard->registerResource('scripts', '/js/ckeditor4/ckeditor.js');
        $dashboard->registerResource('scripts', '/js/dashboard.js');
    }
}

Создаем класс нашего кастомного поля app\Orchid\Fields\CKEditor.php

<?php

namespace App\Orchid\Fields;

use Orchid\Screen\Field;

class CKEditor extends Field
{
    /**
     * Blade template
     *
     * @var string
     */
    protected $view = 'fields.ckeditor';

    /**
     * Default attributes value.
     *
     * @var array
     */
    protected $attributes = [];

    /**
     * Attributes available for a particular tag.
     *
     * @var array
     */
    protected $inlineAttributes = [];
}

Создаем файл представления resources\views\fields\ckeditor.blade.php

<div data-controller="ckeditor">
    <div class="form-group">
        <lable class="text-wrap mt-2 form-label">{{ $title }}</lable>
        <textarea name="{{ $name }}" id="ckeditor">{{ $value }}</textarea>
    </div>
</div>

На этом наше поле готово. Переходим в экран и добавляем:

CKEditor::make('news.text')
    ->title('Текст новости')

И получаем результат

Поле CKEditor в Laravel Orchid
Поле CKEditor в Laravel Orchid

Добавление Laravel Filemanager в CKEditor 4

Также можно добавить Laravel Filemanager в наш CKEditor. Для этого устанавливаем его. Подробнее про файловый менеджер можно почитать тут

 composer require unisharp/laravel-filemanager
 php artisan vendor:publish --tag=lfm_config
 php artisan vendor:publish --tag=lfm_public
 php artisan storage:link

Файл resources\js\controllers\ckeditor_controller.js приводим к такому виду:

export default class extends window.Controller {
    connect() {
        CKEDITOR.replace('ckeditor', {
            height: '500px',
            filebrowserImageBrowseUrl: '/laravel-filemanager?type=Images',
            filebrowserImageUploadUrl: '/laravel-filemanager/upload?type=Images&_token=',
            filebrowserBrowseUrl: '/laravel-filemanager?type=Files',
            filebrowserUploadUrl: '/laravel-filemanager/upload?type=Files&_token='
        });
    }
}

Билдим еще раз:

npm run dev

И получаем наш результат:

Laravel Filemanager + CKEditor
Laravel Filemanager + CKEditor
Laravel Filemanager + CKEditor
Laravel Filemanager + CKEditor
Сброс триала в PhpStorm и WebStorm 2022.2 на Windows и Ubuntu

Сброс триала в PhpStorm и WebStorm 2022.2 на Windows и Ubuntu

Качаем скрипты для сброса пробного периода.

Для сброса триала необходимо выйти с текущего аккаунта JetBrains и создать новый.

Выходим с аккаунта JetBrains
Выходим с аккаунта JetBrains

Для создания нового аккаунта нужна почта. Что бы не плодить почтовые ящики можно воспользоваться анонимайзером у mail.ru

Анонимайзер Mail.ru
Анонимайзер Mail.ru

Закрываем PhpStorm или WebStorm.


Для Windows
Запускаем JetBrainsEvaluationReset.bat от имени администратора.

Для Ubuntu
Файлу JetBrainsEvaluationReset.sh даем разрешение на запуск и выполняем скрипт.

chmod +x ./JetBrainsEvaluationReset.sh
./JetBrainsEvaluationReset.sh

Скрипт вычищает триал
Скрипт вычищает триал

После выполнения скрипта запускаем PhpStorm или WebStorm, заходим под новым аккаунтом и активируем пробную версию.

Активируем пробную версию
Активируем пробную версию

Радуемся 30 дней и повторяем операцию. Данный скрипт также чистит триал и для плагинов.

Интеграция ИБП CyberPower в Home Assistant

Интеграция ИБП CyberPower в Home Assistant

В данной статье я расскажу как добавить мониторинг ИБП в Home Assistant на примере CyberPower Value500EI.

У данной модели есть USB разъем для мониторинга состояния ИБП. Для мониторинга у CyberPower есть своя утилита под названием PowerPanel. Скачать ее можно с сайта производителя. У меня на домашнем сервере стоит Ubuntu 20.04, по этому я скачал PowerPanel for Linux 64bit (deb).

Подключаем ИБП через USB и устанавливаем PowerPanel:

 dpkg -i CyberPower_PPL_Linux+64bit+\(deb\)_v1.4.1.deb

После установки проверяем командой:

pwrstat -status

В ответ, если все нормально, должны увидеть примерно следующее:

    The UPS information shows as following:

    Properties:
            Model Name................... Value500EI
            Firmware Number.............. BZAB100.B31
            Rating Voltage............... 230 V
            Rating Power................. 275 Watt(500 VA)

    Current UPS status:
            State........................ Normal
            Power Supply by.............. Utility Power
            Utility Voltage.............. 224 V
            Output Voltage............... 226 V
            Battery Capacity............. 100 %
            Remaining Runtime............ 31 min.
            Load......................... 49 Watt(18 %)
            Line Interaction............. None
            Test Result.................. Unknown
            Last Power Event............. Blackout at 2022/09/13 23:53:27 for 7 sec.

В файле /etc/pwrstatd.conf настраиваем выключение компьютера через время после перехода на резервное питание или при разряде аккумулятора на определенный процент. Также можно настроить отправку E-Mail или выполнение произвольного скрипта. После изменения перезапускаем демона:

service pwrstatd restart

У меня настроено выключение сервера при разряде аккумулятора до 35%. Мой конфиг:

# pwrstatd configuration file
#

# You must restart pwrstatd after changing this file in order for changes to take effect.
# Ex:/etc/init.d/pwrstatd restart

#
# Action setting for event of Power Failure
#

# A delay time in seconds since event of Power Failure occur then to run shell
# script and shutdown system. Allowed range is 0 ~ 3600. Default is 60 sec.
powerfail-delay = 60

# Enable to run shell script when the event of Power Failure occur.
# The allowed options are yes and no. Default is yes.
powerfail-active = yes

# Assign a path of script file for event of Power Failure.
# The default is /etc/pwrstatd-powerfail.sh
powerfail-cmd-path = /etc/pwrstatd-powerfail.sh

# How much time in seconds to take script running for event of Power Failure.
# The allowed range is 0 ~ 3600. Default is 0 sec.
powerfail-duration = 0

# Allow Daemon to shutdown system for event of Power Failure.
# The allowed options are yes and no. Default is yes.
powerfail-shutdown = no

#
# Action setting for event of Battery Low
#

# A threshold of Battery Capacity, If the battery capacity is lower than this
# value and a event of Battery Low will be identified. The unit is percentage.
# The allowed range is 0 ~ 90. Default is 35 %.
lowbatt-threshold = 35

# A threshold of Remaining Runtime, If the Remaining Runtime is lower than this
# value and a event of Battery Low will be identified. The unit is second.
# The allowed range is 0 ~ 3600. Default is 300 sec.
# Note: When meet this condition the below 'shutdown-sustain' property
# will be ignored.
runtime-threshold = 300

# Enable to run shell script when the event of Battery Low occur.
# The allowed options are yes and no. Default is yes.
lowbatt-active = yes

# Assign a path of script file for event of Battery Low.
# The default is /etc/pwrstatd-lowbatt.sh
lowbatt-cmd-path = /etc/pwrstatd-lowbatt.sh

# How much time in seconds to take script running for event of Battery Low.
# The allowed range is 0 ~ 60. Default is 0 sec.
lowbatt-duration = 0

# Allow Daemon to shutdown system for event of Battery Low.
# The allowed options are yes and no. Default is yes.
lowbatt-shutdown = yes

# Turn UPS alarm on or off.
# The allowed options are yes and no. Default is yes.
enable-alarm = yes

# The necessary time in seconds for system shutdown.
# The UPS will turn power off when this time is expired.
# The allowed range is 0 ~ 3600. Default is 600 sec.(10 min.)
# If the computer shutdown is cause by low runtime condition, the UPS will
# turn power off when the time is expired that time is assigned on
# 'runtime-threshold' property and it is no longer to refer the
# 'shutdown-sustain' property.

shutdown-sustain = 600

# Daemon will turn UPS power off once it ask system shutdown cause by a power
# event. Allowed options are yes and no. Default is yes.
turn-ups-off = yes

# The period of polling UPS in seconds.
# The allowed range is 1 ~ 60. Default is 3 sec.
ups-polling-rate = 3

# the period of re-try to find available UPS in seconds since find nothing at
# last time. The allowed range is 1 ~ 300. Default is 10 sec.
ups-retry-rate = 10

# Prohibiting daemon to provide communication mechanism for client, such as
# pwrstat command. normally, it should be 'no'. It can be 'yes' if any security
# consideration. Allowed options are yes and no. Default is no.
prohibit-client-access = no
# The pwrstatd accepts four types of device node which includes the 'ttyS',
# 'ttyUSB', 'hiddev', and 'libusb' for communication with UPS. The pwrstatd
# defaults to enumerate all acceptable device nodes and pick up to use an
# available device node automatically. But this may cause a disturbance to the
# device node which is occupied by other software. Therefore, you can restrict
# this enumerate behave by using allowed-device-nodes option. You can assign
# the single device node path or multiple device node paths divided by a
# semicolon at this option. All groups of 'ttyS', 'ttyUSB', 'hiddev', or
# 'libusb' device node are enumerated without a suffix number assignment.
# Note, the 'libusb' does not support suffix number only.
#
# For example: restrict to use ttyS1, ttyS2 and hiddev1 device nodes at /dev
# path only.
# allowed-device-nodes = /dev/ttyS1;/dev/ttyS2;/dev/hiddev1
#
# For example: restrict to use ttyS and ttyUSB two groups of device node at
# /dev,/dev/usb, and /dev/usb/hid paths(includes ttyS0 to ttySN and ttyUSB0 to
# ttyUSBN, N is number).
# allowed-device-nodes = ttyS;ttyUSB
#
# For example: restrict to use hiddev group of device node at /dev,/dev/usb,
# and /dev/usb/hid paths(includes hiddev0 to hiddevN, N is number).
# allowed-device-nodes = hiddev
#
# For example: restrict to use libusb device.
# allowed-device-nodes = libusb
allowed-device-nodes =

# Daemon will hibernate system to instead of system shutdown when power
# event occur. Allowed options are yes and no. Default is no.
hibernate = no

# Enable cloud solution.
# The allowed options are yes and no. Default is no.
cloud-active = no

# Account for cloud server login.
cloud-account =

Далее в Docker необходимо установить контейнер, который будет парсить эту информацию и передавать в MQTT брокер:

docker pull dwinks/pwrstat_docker
docker volume create pwrstat_data
docker run -d -p 5003:5003 --name=pwrstat --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v pwrstat_data:/data dwinks/pwrstat_docker

После запуска контейнера смотрим его ID из списка:

docker ps -a
Список запущенных контейнеров

Переходим в консоль контейнера:

docker exec -it a86d79a48027 bash

В контейнере нам нужно для удобства установить nano и отредактировать конфиг. Для это выполняем:

apt update
apt install nano -y
nano /pwrstat.yaml

В конфиге указываем IP адрес и порт MQTT брокера, частота обновления, имя и пароль MQTT.

pwrstat_api: # optional
  log_level: WARNING # optional
mqtt:
  broker: "192.168.0.24"
  port: 1883
  client_id: "pwrstat_mqtt"
  topic: "sensors/basement/power/ups"
  refresh: 5
  qos: 0
  retained: true
  username: "*****" # optional
  password: "*****" # optional, required if username specified
rest:
  port: 5003
  bind_address: "0.0.0.0"
prometheus:
  port: 9222
  bind_address: "0.0.0.0"
  labels:
    rack: "0"

Перезапускаем контейнер:

docker restart pwrstat

Проверяем работоспособность по ссылкам: http://192.168.0.24:5003/health и http://192.168.0.24:5003/mqtthealth. Не забудьте поменять IP на свой. Если все нормально, то мы увидим:

{"code":"SUCCESS","message":"OK"}

Отлично! Данные отправляются в MQTT. Теперь необходимо достать их в Home Assistant. Для этого создаем сенсоры:

mqtt:
  sensor:
    # UPS Sensors
    - name: "UPS Model Name"
      icon: mdi:rename-box
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Model Name'] }}"

    - name: "UPS Rating Voltage"
      icon: mdi:flash-triangle
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Rating Voltage'] }}"

    - name: "UPS Rating Power"
      icon: mdi:lightning-bolt
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Rating Power'] }}"

    - name: "UPS State"
      icon: mdi:transmission-tower
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['State'] }}"

    - name: "UPS Power Supply by"
      icon: mdi:power-socket-eu
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Power Supply by'] }}"

    - name: "UPS Utility Voltage"
      icon: mdi:flash-triangle-outline
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Utility Voltage'] }}"

    - name: "UPS Output Voltage"
      icon: mdi:flash-triangle-outline
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Output Voltage'] }}"

    - name: "UPS Battery Capacity"
      icon: mdi:car-battery
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Battery Capacity'] }}"

    - name: "UPS Remaining Runtime"
      icon: mdi:timer-sand
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Remaining Runtime'] }}"

    - name: "UPS Load"
      icon: mdi:lightning-bolt
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Load'] }}"

    - name: "UPS Line Interaction"
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Line Interaction'] }}"

    - name: "UPS Test Result"
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Test Result'] }}"

    - name: "UPS Last Power Event"
      state_topic: "sensors/basement/power/ups"
      value_template: "{{ value_json['Last Power Event'] }}"

У меня это выглядит вот так:

Список датчиков UPS

Так же я настроил уведомления в Telegramm при отключении и включении электричества.

- alias: "Уведомления - Питание от ИБП"
  mode: single
  trigger:
    - platform: template
      value_template: "{{ states('sensor.ups_state') == 'Power Failure' }}"
  action:
    - service: notify.me
      data:
        message: "Внимание! Проблемы с питанием, переход на питание от аккумулятора."

- alias: "Уведомления - Питание от сети"
  mode: single
  trigger:
    - platform: template
      value_template: "{{ states('sensor.ups_state') == 'Normal' }}"
  action:
    - service: notify.me
      data:
        message: "Питание восстановлено"

На этом настройка завершена! Спасибо за внимание 🙂

Не открывается Центр обновления в Windows 11

Не открывается Центр обновления в Windows 11

Что делать если не открывается Центр обновления Windows? С такой проблемой я недавно столкнулся. Решается она достаточно просто: через пуск открываем Изменение групповой политики.

Открываем изменение групповой политики
Открываем изменение групповой политики

Выбираем Конфигурация компьютера > Административные шаблоны > Панель управления, справа жмем два раза по Отображение страницы параметров и в открывшемся окне выбираем Отключено.

Отображение страницы параметров
Отображение страницы параметров
Выбираем "Отключено"
Выбираем «Отключено»

Далее аналогично переходим в Конфигурация пользователя > Административные шаблоны > Панель управления. Справа нажимаем два раза по Отображать только указанные элементы панели управления и точно также выбираем Отключено.

Отображать только указанные элементы панели управления
Отображать только указанные элементы панели управления
Также выбираем "Отключено"
Также выбираем «Отключено»

После этих манипуляций даже без перезагрузки Центр обновления Windows должен открываться как обычно.

Центр обновления Windows
Центр обновления Windows
Исправление ошибки The system found unauthorized changes on the firmare

Исправление ошибки The system found unauthorized changes on the firmare

Исправление ошибки The system found unauthorized changes on the firmare

После отключения электричества на объекте один из серверов Trassir выпал в ошибку:

The system found unauthorized changes on the firmware, operating system or UEFI drivers.

Press [N] to run the next boot device, or enter drectly to BIOS Setup if there are no other boot devices installed.
Go to BIOS Setup > Advanced > Boot and change the current boot device into other secured boot devices.

Для исправления данной ошибки необходимо зайти в BIOS > Advanced > Boot > Secure Boot > OS Type и из списка выбрать Other OS.

После этого жмем F10 > Yes.


Активация PhpStorm 2022.2.X

Активация PhpStorm 2022.2.X

Данный способ активации не актуален. Смотрите данную статью.

Активация JetBrains PhpStorm 2022.2 происходит примерно также как и рассказано в статье про версию 2022.1. Для активации PhpStorm необходимо скачать архив с активатором ниже. Активация работает на Windows, Linux и MacOS.

GitHub автора

Архив необходимо распаковать в любую удобную папку. Я распаковал в корень диска C.
Далее переходим в папку PhpStorm 2022.2. Например у меня это C:\Program Files\JetBrains\PhpStorm 2022.2.2. В папке bin ищем файл phpstorm64.vmoptions или phpstorm64.exe.vmoptions. Открываем этот файл текстовым редактором, например NotePad++ и добавляем в самый конец:

-javaagent:С:\jetbrains\jetbrains.jar=jetbrains

Укажите свой путь, куда распаковали активатор!

Добавляем vmoptions
Добавляем vmoptions

Далее запускаем PhpStorm и выбираем Activation PhpStorm -> License server. В Server address вставляем любой адрес из списка ниже и нажимаем Activate.

Активация PhpStorm 2022.2.2

http://49.234.70.205
http://60.247.72.31:8888
http://91.210.51.48:8080
http://34.206.48.129
http://13.232.35.56
http://153.106.195.23:8080
http://158.193.243.40
http://200.13.89.3:8080
http://140.238.85.244:8080
http://193.6.57.174:8080
http://150.254.118.138:8080
http://195.208.239.74
http://193.2.42.18:8080
http://200.17.85.220
http://186.211.99.100
http://212.73.75.141
http://203.23.253.45:8081
http://129.22.25.52
http://20.24.96.101
http://194.83.68.123
http://46.248.165.184:7777
http://80.169.232.216:8080
http://185.76.145.167:8080
http://94.100.93.228:8080
http://216.118.207.58:8181
http://62.76.124.130:8081
http://178.124.205.99:8090
http://185.14.45.25:8282
http://license.engr.ship.edu:8080
http://licence.fit.cvut.cz:9000
https://jblicense2.wappworks.com
https://jetbrains-license.learning.casareal.co.jp
https://license.fahai.org
https://lic.gotoweb.top
https://flm.nighthawkcodingsociety.com
https://fls-jetbrains.spacetechies.com
https://jbls.x-root.info
https://license-server.tmk.edu.hk
https://jenkins.wf-wolves.de
http://bumblebee.bhasvic.ac.uk
http://cse-lic-02.engineering.cwru.edu
http://lic-server.mephi.ru
http://license.runtime.kz
https://licenses.cerebotani.it
https://jetbrains.blackboard.com
http://adsk06.tpu.ru:8080
https://fls.aventus.work

Если все делали правильно, то получаем активированный PhpStorm 2022.2.2.

Активированный PhpStorm 2022.2.2

Если сервера лицензий не доступны, то выбираем пункт Activation Code и вставляем в поле ключ указанный ниже.

ZEW8I0GZC6-eyJsaWNlbnNlSWQiOiJaRVc4STBHWkM2IiwibGljZW5zZWVOYW1lIjoia2lkZHkgaW5zZWFtcyIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IlBTSSIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUENXTVAiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBTIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUFBTIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQV1MiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9XSwibWV0YWRhdGEiOiIwMTIwMjIwODAxUFNBTjAwMDAwNSIsImhhc2giOiJUUklBTDo5NzM1MDQ0MzkiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-UVh/hXrqvTl8syZGee3sWsipAUdbN7XBg2XpFkSNh+oGBGzwvsj2k5A3v2LGO6+46rDU/HdG14jHYnT1iDMum5K5I7aCVYOIcJcmSAViwNDLqvTcOjMOdDZ4XS3aDg/KeaX5PozDa+H/KgHdGL07nKCBuhopAesiGXZC0RYerwCnYX1DjG9b/02igSyCuIYfsCO8d3GL+/ESz+sI8FiXmyZB7N413SJDGnp9klF51Kz469YzWZNEIXp9zg3Wu/Vsq8zlW9mGCFmsyiu0btTkS5PZfxp5BebH8Ef5SvPP7SyLJ2Q0FqeCJ9ESXp6aNBW8lmTVY+R0ZpqgsBOwbkq2xg==-MIIETDCCAjSgAwIBAgIBDTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTIwMTAxOTA5MDU1M1oXDTIyMTAyMTA5MDU1M1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyMDEwMTkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUlaUFc1wf+CfY9wzFWEL2euKQ5nswqb57V8QZG7d7RoR6rwYUIXseTOAFq210oMEe++LCjzKDuqwDfsyhgDNTgZBPAaC4vUU2oy+XR+Fq8nBixWIsH668HeOnRK6RRhsr0rJzRB95aZ3EAPzBuQ2qPaNGm17pAX0Rd6MPRgjp75IWwI9eA6aMEdPQEVN7uyOtM5zSsjoj79Lbu1fjShOnQZuJcsV8tqnayeFkNzv2LTOlofU/Tbx502Ro073gGjoeRzNvrynAP03pL486P3KCAyiNPhDs2z8/COMrxRlZW5mfzo0xsK0dQGNH3UoG/9RVwHG4eS8LFpMTR9oetHZBAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUJNoRIpb1hUHAk0foMSNM9MCEAv8wSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBABqRoNGxAQct9dQUFK8xqhiZaYPd30TlmCmSAaGJ0eBpvkVeqA2jGYhAQRqFiAlFC63JKvWvRZO1iRuWCEfUMkdqQ9VQPXziE/BlsOIgrL6RlJfuFcEZ8TK3syIfIGQZNCxYhLLUuet2HE6LJYPQ5c0jH4kDooRpcVZ4rBxNwddpctUO2te9UU5/FjhioZQsPvd92qOTsV+8Cyl2fvNhNKD1Uu9ff5AkVIQn4JU23ozdB/R5oUlebwaTE6WZNBs+TA/qPj+5/we9NH71WRB0hqUoLI2AKKyiPw++FtN4Su1vsdDlrAzDj9ILjpjJKA1ImuVcG329/WTYIKysZ1CWK3zATg9BeCUPAV1pQy8ToXOq+RSYen6winZ2OO93eyHv2Iw5kbn1dqfBw1BuTE29V2FJKicJSu8iEOpfoafwJISXmz1wnnWL3V/0NxTulfWsXugOoLfv0ZIBP1xH9kmf22jjQ2JiHhQZP7ZDsreRrOeIQ/c4yR8IQvMLfC0WKQqrHu5ZzXTH4NO3CwGWSlTY74kE91zXB5mwWAx1jig+UXYc2w4RkVhy0//lOmVya/PEepuuTTI4+UJwC7qbVlh5zfhj8oTNUXgN0AOc+Q0/WFPl1aw5VV/VrO8FCoB15lFVlpKaQ1Yh+DVU8ke+rt9Th0BCHXe0uZOEmH0nOnH/0onD

Также автор говорит, что активатор прекрасно справляется с активацией плагинов.

Меняем Fn и Ctrl местами на Lenovo ThinkPad L15

Меняем Fn и Ctrl местами на Lenovo ThinkPad L15

Меняет местами Fn и Ctrl местами на Lenovo ThinkPad

Недавно приобрел себе и жене пару новых ноутбуков Lenovo ThinkPad L15 Gen 2. Классный мощный аппарат, Ryzen 5 PRO, 32Gb Ram, SSD M.2, клавиатура с подсветкой, сенсорный матовый экран с IPS матрицей и довольно не плохим звуком Dolby® Audio Premium. Но мне с самого его приобретения не давала покоя проблема с неудобным расположением клавиш Fn и Ctrl. Это жутко не удобно, особенно когда пересаживаешься из-за ПК с механической клавиатурой за ноутбук.

Поподробнее почитать о ноутбуке можно здесь.

Клавиши Fn и Ctrl на Lenovo ThinkPad
Клавиши Fn и Ctrl на Lenovo ThinkPad

По началу очень мучался с этим недоразумением, но как оказалось функционально можно поменять местами эти две клавиши. Можно сделать это двумя способами — через BIOS или через стандартную программу Lenovo Commercial Vantage.

Способ через BIOS

Для того чтобы поменять через BIOS на стадии загрузки жмем F1. После того как попали в BIOS необходимо слева в меню выбрать пункт Config.

Выбираем пункт Config в биосе
Выбираем пункт Config в биосе

Далее нужно выбрать в правой части пункт Keyboard/Mouse.

Выбираем пункт Keyboard/Mouse
Выбираем пункт Keyboard/Mouse

Ну собственно на данном этапе как нетрудно догадаться переключаем параметр Fn and Ctrl Key swap в положение On.

Параметр Fn and Ctrl Key swap
Параметр Fn and Ctrl Key swap

После этого жмем F10 и перезагружаемся.

Способ через программу Lenovo Commercial Vantage

Ищем в меню пуск Lenovo Commercial Vantage в меню Пуск
Ищем в меню пуск Lenovo Commercial Vantage в меню Пуск

Ищем в меню пуск Lenovo Commercial Vantage.

Выбираем More settings
Выбираем More settings

После запуска нажимаем на More settings.

Выбираем Input & Accessories
Выбираем Input & Accessories

После того как попадаем в меню настроек, сверху выбираем вкладку Input & Accessories и листаем в низ.

Переключаем пункт Fn and Ctrl key swap
Переключаем пункт Fn and Ctrl key swap

Здесь также как и в BIOS переключаем параметр Fn and Ctrl key swap в положение On. После переключения действия клавиш меняются местами моментально. Перезагружаться нет необходимости.

Активация PhpStorm 2022.1.4

Активация PhpStorm 2022.1.4

PhpStorm 2022.1.4

Данный способ подходит и для активации WebStorm 2022.1.4

В данной статье я расскажу как бесплатно активировать лицензию PhpStorm. Данный метод работает в PhpStorm не выше версии 2022.1.4.

Предыдущие версии PhpStorm можно скачать отсюда. Архив с кряком качаем ниже.

Устанавливаем PhpStorm 2022.1.4, распаковываем папку ja-netfilter в корень диска C.

Распаковываем папку ja-netfilter в корень диска C
Распаковываем папку ja-netfilter в корень диска C

Идем в C:\Program Files\JetBrains\PhpStorm 2022.1.4\bin\phpstorm64.exe.vmoptions и в конец вставляем -javaagent:C:\ja-netfilter-all\ja-netfilter.jar=jetbrains


Добавляем ja-netfilter в vmoptions
Добавляем ja-netfilter в vmoptions

Далее запускаем PhpStorm и заходим в меню лицензии. Выбираем License server, в Server address пишем https://jetbra.in и нажимаем Activate.

Активация лицензии
Активация лицензии

Если все сделали правильно, то PhpStorm должен проглотить лицензию.

Активированный PhpStormа
Активированный PhpStormа

Пользуйтесь! Самое главное не обновляйтесь на версию выше. Данный способ взлома PhpStorm уже не работает на версии 2022.2!

Также данный способ работает на Linux и MacOS.

Автоматическое удаление записей в ZoneMinder

Автоматическое удаление записей в ZoneMinder

Автоматическое удаление записей в  ZoneMinder

Сколько не искал как настроить ZM, чтобы он сам удалял старые записи, так и не смог найти. Пришлось сделать свой костыль на PHP. Скрипт писался исключительно для себя, и не претендует на правильность.

<?php
$servername = ""; // IP адрес MySQL сервера
$database = "zm"; // Имя БД
$username = ""; // Имя пользователя БД
$password = ""; // Пароль пользователя БД
$path = ""; // Путь к папке с записями
$interval = "7"; // Удалять записи старше N дней

// Создаем соединение
$mysqli = new mysqli($servername, $username, $password, $database);

// Получаем записи старше N дней
$result = $mysqli->query('SELECT * FROM `Events` WHERE StartDateTime < (NOW() - INTERVAL '.$interval.' DAY)');
$rows = $result->fetch_all(MYSQLI_ASSOC);

// Форматируем дату
$arrDates = array();
foreach($rows as $row) {
    $date = explode(' ', $row['StartDateTime'])[0];
    array_push($arrDates, $date);
}
// Удаляем дубликаты дат
$arrDates = array_unique($arrDates);

// Удаляем папки старше N дней
foreach($arrDates as $date) {
    // Удаление для каждого монитора отдельно
    exec('rm -R '.$path.'5/'.$date);
    exec('rm -R '.$path.'6/'.$date);
}

// Удаляем записи старше N дней
$mysqli->query('DELETE FROM `Events` WHERE StartDateTime < (NOW() - INTERVAL '.$interval.' DAY)');

// Закрываем соединение
$mysqli->close();

Скрипт запускается командой php script.php из консоли и может быть добавлен в cron.