SQL: удаление дублей записей в таблице

Ну задача написания нужного запроса сводится к следующим шагам:

  1. Сделаем выборку записей, сгруппировав по дублирующемуся полю. Получим количество дублей, и максимальный id дубля (чтобы знать какой удалять)
  2. Если количество записей больше 1, то запись с максимальным id удалим

В итоге запрос может получится примерно таким:

delete from ls_indications where id in (
	select max_id from (
		select count(ls) as cnt,max(id) as max_id from ls_indications where period='2025-03-01' group by ls
	) as zxc where zxc.cnt>1	
)

P.S. Если дублей больше 2-х, то запрос нужно выполнить несколько раз, т.к. он удаляет за один раз только одну дублирующуюся запись. Можно конечно наваять скрипт, который этот недостаток убирает, но смысла обычно нет, проще запрос выполнить несколько раз

Подпись при помощи ЭЦП файла из консоли Linux

Посмотреть сертификаты:

/opt/cprocsp/bin/amd64/certmgr -list

Подписать файл:

/opt/cprocsp/bin/amd64/cryptcp -signf t.log -dn "L=ВОЛОГДА ГОРОД"

Ключ -signf означает, что будет создан файл с подписью t.log.sig

в параметре -dn нужно перечислить критерии поиска первого подходящего сертификата в хранилище. Критерии смотрим в строке «Субьект» в списке сертификатов

Установка туннеля с ГИС ЖКХ под Linux

Задача установить защищенный туннель с ГИС ЖКХ под Astra Linux.

Решение:

Сначала скопируем с токена сертификат в формате pfx. Для этого можно воспользоваться утилитой P12FromGostCSP (Windows). Под Linux тоже как-то можно, но как- нужно гуглить. Мне предоставили уже готовый файл.

Далее нужно установить крипто-про CSP с пакетом stunnel. Зайдя в крипто про, во вкладке «сертификаты» необходимо установить корневые сертификаты с https://my.dom.gosuslugi.ru/ и установить сертификат из файла psk.

Для настройки конфигурационного файла stunnel, нужно из файла формата pfx получить файлы key и crt

crt и pem:

openssl pkcs12 -in file.pfx -clcerts -nokeys -out public.crt
openssl x509 -in public.crt -out public.pem -outform PEM

key:

openssl pkcs12 -in SSK_obezl_3.pfx -nocerts -out private.key

Лично у меня на этом месте выскочила ошибка:

Enter Import Password:
Error outputting keys and certificates
124867336299712:error:06074079:digital envelope routines:EVP_PBE_CipherInit:unknown pbe algorithm:../crypto/evp/evp_pbe.c:95:TYPE=1.2.840.113549.1.12.1.80
124867336299712:error:23077073:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 algor cipherinit error:../crypto/pkcs12/p12_decr.c:41:
124867336299712:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:../crypto/pkcs12/p12_decr.c:94:

Которую я так и не победил, но тем не менее файл сформировался.

Далее необходимо настроить конфигурационный файл туннеля. У меня он получился вида:

pid=/home/vasya/stunnel/stunnel_cli.pid
output=/home/vasya/stunnel/t.log
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
debug = 7
[https]
client = yes
accept=localhost:8080
connect = api.dom.gosuslugi.ru:443
cert=/home/vasya/stunnel/public.pem
CAFile=/home/vasya/stunnel/CA-PPAK_2023.pem
key=/home/vasya/stunnel/private.key
verify=0

Файл CA-PPAK_2023.pem взял из архива «ГИС ЖКХ_Интеграция v.14.8.0.2.zip» с документацией скачанного с сайта https://my.dom.gosuslugi.ru/

И пробуем запустить туннель:

opt/cprocsp/sbin/amd64/stunnel_thread /home/vasya/stunnel/stunnel_run.conf

Логи будут писаться в файл t.log. Если всё хорошо, и в логах ошибок нет, то можно попробовать выполнить в браузере запрос вида:

http://127.0.0.1:8080/ext-bus-debt-service/services/DebtAsync

От ГИС ЖКХ придет что-то вроде:

<env:Envelope xmlns:ns6="http://dom.gosuslugi.ru/schema/integration/individual-registry-base/" xmlns:ns5="http://dom.gosuslugi.ru/schema/integration/account-base/" xmlns:ns8="http://dom.gosuslugi.ru/schema/integration/metering-device-base/" xmlns:ns7="http://dom.gosuslugi.ru/schema/integration/nsi-base/" xmlns:ns13="http://dom.gosuslugi.ru/schema/integration/debts/" xmlns:ns9="http://dom.gosuslugi.ru/schema/integration/organizations-registry-base/" xmlns:ns12="http://dom.gosuslugi.ru/schema/integration/bills-base/" xmlns:ns11="http://dom.gosuslugi.ru/schema/integration/payments-base/" xmlns:ns10="http://dom.gosuslugi.ru/schema/integration/organizations-base/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns4="http://dom.gosuslugi.ru/schema/integration/base/" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
   <env:Body>
      <env:Fault>
         <faultcode>env:Server</faultcode>
         <faultstring>AUT011000: Нет активной ИС с данным сертификатом</faultstring>
         <detail>
            <ns4:Fault>
               <ns4:ErrorCode>AUT011000</ns4:ErrorCode>
               <ns4:ErrorMessage>Нет активной ИС с данным сертификатом</ns4:ErrorMessage>
            </ns4:Fault>
         </detail>
      </env:Fault>
   </env:Body>
</env:Envelope>

Тут всё просто — открываем заявку на сайте ГИС ЖКХ и добавляем сертификат.

P,S. Отладку запросов далее можно делать в утилите soapui, Как? Тема отдельной будущей статьи, когда буду разбираться с запросами

Автоматизация пережатия pdf файлов

Задача: есть некоя файловая помойка, размер которой вырос до неприличных размеров. Необходимо pdf файлы пережать до «еле читабельного» состояния.

Решение: напишем соответствующий скрипт на Bash

#! /bin/bash
from='2025-01-15'
to='2025-01-17'

find ~/wedwewe -type f -newermt "$from" ! -newermt "$to" -name "*.pdf" | while read fname; do
  echo "-compress: $fname"
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=res.pdf "$fname"
  if [ $? -eq 0 ]; then
    echo OK
    mv res.pdf "$fname"
  else
    echo FAIL
  fi
done

Что делает этот скрипт? А просто ищет все файлы созданные в указанном диапазоне дат. Далее последовательно пытается пережать каждый файл, и если это происходит успешно, то заменяет оригинал на получившийся пережатый файл. Опции dPDFSETTINGS:

/screen Более низкое качество и меньший размер. (72 т/д)
/ebook Лучшее качество, но чуть больший размер (150 dpi)
/prepress Вывод имеет более высокий размер и качество (300 dpi)
/printer Качество вывода подходит для принтерной печати (300 dpi)
/default Выбирает вывод, который подходит для нескольких целей, однако может создавать большие PDF-файлы.

Update: со временем скрипт чуть изменился. А именно добавил проверку «а помогло ли сжатие». Если эффекта нет, то и не заменяем пережатый файл

#! /bin/bash
from='2025-01-13'
to='2025-01-17'

find ~/shwedwed -type f -newermt "$from" ! -newermt "$to" -name "*.pdf" | while read fname; do
  echo "-compress: $fname"
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dNOPAUSE -dQUIET -dBATCH -sOutputFile=res.pdf "$fname"
  if [ $? -eq 0 ]; then
    echo OK
    size_before=$(wc -c <"$fname")
    size_after=$(wc -c <"res.pdf")
    if [[ $size_before -gt $size_after ]]
	then 
	    echo "-результат сжатия хороший. Заменяем файл..."
	    mv res.pdf "$fname"
	else 
	    echo "-сжатие не удачное, пропускаем.."
    fi
  else
    echo FAIL
  fi
done

Печать на принтере TSC-210 из консоли

В ходе эксплуатации принтера этикеток TSC-210 в среде 1С под Linux выявилась особенность, что он не выдерживает правильные отступы при печати, даже при установке нужных параметров бумаги. Выходом явилось сохранение печати в файл, а затем печать полученного файла при помощи просто скрипта вида:

#!/usr/bin/sh
lpr -P цув-tsc210-03 -o portrait -o media=Custom.58x28mm -o page-top=5 -o page-bottom=1 -o page-left=1 -o page-right=1 -o page-border=none ~/Документы/вывод.ps
1 2 3 4 5 6 59