Перейти к главному содержимому

Системные сертификаты в python requests

При запросе по https при помощи requests из скрипта на python есть несколько вариантов для проверки сертификата. За это отвечает параметр verify.

Отключение проверки

Если параметр verify равен False, то проверка будет отключена. Это в целом нехорошо, да и будут выводиться всякие предупреждения. Для закрытой локалки как временное решение может и сойдёт...

import requests

r = requests.get(url, verify=False)

Проверка по умолчанию

Если параметр verify равен True (это значение по умолчанию), то проверка будет проводиться на соответствие python-certifi.

import requests

r = requests.get(url, verify=True)

Проверка "вручную"

Можно вручную сохранить сертификаты в текстовый файл (всю цепочку, от корневого центра до сертификата сайта) и путь до этого файла дать в качестве параметра. Тогда сертификаты будут проверяться на соответствие сохраненным в этом файле.

import requests

r = requests.get(url, verify='/path/to/certfile')

Использование системных сертификатов

Обычная включенная проверка (verify=True) проверяет сертификаты "встроенные" в certifi, при этом игнорируя сертификаты установленные в системе. Иногда это неудобно. Решением данной проблемы может служить установка пакета pip-system-certs:

pip3 install pip-system-certs

После этого обычная проверка (verify=True) будет учитывать установленные в системе сертификаты.

Источник: https://stackoverflow.com/questions/50422136/python-requests-with-wincertstore

LaTeX: параметры ключ=значение

Определение команды:

\ExplSyntaxOn

\keys_define:nn { mymodule }
  {
    color .tl_set:N = \l_mymodule_color_tl ,
    color .initial:n = { black } ,
    text .tl_set:N = \l_mymodule_text_tl ,
    text .initial:n = { Default~Text } ,
    size .dim_set:N = \l_mymodule_size_dim ,
    size .initial:n = { 12pt } ,
  }

\NewDocumentCommand { \mycommand } { O{} }
  {
    \keys_set:nn { mymodule } { #1 }
    \group_begin:
      \color{\l_mymodule_color_tl}
      \fontsize{\l_mymodule_size_dim}{\dim_eval:n{\l_mymodule_size_dim * 1.2}}\selectfont
      \l_mymodule_text_tl
    \group_end:
  }

\ExplSyntaxOff

Использование:

\begin{document}

\mycommand % Uses default values
\par
\mycommand[color=blue, text=Hello~World, size=18pt]
\par
\mycommand[size=24pt, color=red]

Свойства ключей в keys_define

Каждый ключ в keys_define может иметь набор свойств:

  • .code:n = code to execute: задает код для выполнения, когда ключ задан, при этом в коде может использоваться #1 и туда будет подставлено значение ключа.
  • .initial:n = initial value: Задает начальное значение. Оно будет использоваться, если ключ вообще не задан.
  • .default:n = default value: Задает значение по умолчанию. Оно будет использоваться если ключ задан без значения (например, key=).
  • .choices:nn = { список выбора }: Задает список допустимых значений для ключа. Для каждого возможного значения задается код, который должен выполниться в соответствующем случае.
  • .bool_set:N, .bool_set_true:N, .bool_set_false:N: Задает что делать для boolean-ключей, установить значение, true или false.
  • .int_set:N, .dim_set:N, .tl_set:N: Задает присвоение переменным для числа, размера или строки.

Пример:

\ExplSyntaxOn
\keys_define:nn { mymodule }
  {
    color .code:n = \tl_set:Nn \l_mymodule_color_tl { #1 },
    color .initial:n = black,
    shape .choices:nn =
      {
        circle .code:n = \tl_set:Nn \l_mymodule_shape_tl { circle },
        square .code:n = \tl_set:Nn \l_mymodule_shape_tl { square }
      },
    shape .initial:n = circle,
    linewidth .int_set:N = \l_mymodule_linewidth_int,
    linewidth .initial:n = 1
  }
\ExplSyntaxOff

В этом примере определены ключи color, shape и linewidth для модуля mymodule.

color принимает значение, shape значение из списка, a linewidth задает числовую переменную.

LaTeX mbox на список

Есть: строка, разделенная запятыми.

Надо: завернуть каждый элемент отдельно в функцию (например, в \mbox) и собрать строку обратно, возможно с другими разделителями.

\ExplSyntaxOn

\NewDocumentCommand{\MBoxingList}{O{,\ }m}
{
  \seq_clear_new:N \l__in_seq
  \seq_set_from_clist:Nn \l__in_seq {#2}
  \seq_set_map:NNn \l__in_seq \l__in_seq {\mbox{##1}}
  \seq_use:Nn \l__in_seq {#1}
%  \quad\seq_count:N \l__in_seq
}

\ExplSyntaxOff

Использовать так: `\expanded{\MBoxingList[, ]{123, 123, 5234, 6543}}

Как вариант определить через \NewExpandableDocumentCommand, но тогда вызывать без \expanded и могут быть сюрпризы если исходная строка передается не явно, а определена командой.

P.S. Вроде и работает, но с этим expansion что-нибудь да не нравится. В общем, глаз да глаз.

P.P.S. Можно попробовать через пакет listofitems.

P.P.P.S Есть какое-то решение на классическом синтаксисе:

\makeatletter

% Functional foreach construct
% #1 - Function to call on each comma-separated item in #3
% #2 - Parameter to pass to function in #1 as first parameter
% #3 - Comma-separated list of items to pass as second parameter to function #1
\def\foreach#1#2#3{%
  \@test@foreach{#1}{#2}#3,\@end@token%
}

% Internal helper function - Eats one input
\def\@swallow#1{}

% Internal helper function - Checks the next character after #1 and #2 and
% continues loop iteration if \@end@token is not found
\def\@test@foreach#1#2{%
  \@ifnextchar\@end@token%
    {\@swallow}%
    {\@foreach{#1}{#2}}%
}

% Internal helper function - Calls #1{#2}{#3} and recurses
% The magic of splitting the third parameter occurs in the pattern matching of the \def
\def\@foreach#1#2#3,#4\@end@token{%
  #1{#2}{#3}%
  \@test@foreach{#1}{#2}#4\@end@token%
}

\makeatother

%% Функция для использования
\def\makembox#1#2{\mbox{#2}, }

HTML redirect

Перенаправить статически страницу можно html-тегом <meta... внутри <head>...</head>, можно при помощи javascript. Лучше использовать и то и другое. И на всякий случай ещё и явную ссылку, вдруг у кого-то браузер сам не перейдёт.

Вот пример:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <!-- html redirect with timeout=0 -->
  <meta http-equiv="refresh" content="0; url=http://example.com">
  <!-- for search engines -->
  <link rel="canonical" href="http://www.example.com"/>
  <!-- javascript redirect -->
  <script type="text/javascript">
      window.location.href = "http://example.com";
  </script>
  <title>Page Redirection</title>
</head>
<body>
  <!-- Note: don't tell people to `click` the link, 
       just tell them that it is a link. -->
  If you are not redirected automatically, 
  follow this <a href='http://example.com'>link to example</a>.
</body>
</html>

Вызов сторонних скриптов из LaTeX

Latex при сборке документа может вызывать сторонние программы. Иногда это удобно.

По умолчанию такое поведение запрещено, но опцией командной строки --shell-escape это разрешается.

Настройка latexmk

Если сборка производится через latexmk, то в файл конфигурации latexmkrc надо добавить строчки:

push @extra_pdflatex_options, '-shell-escape';
push @extra_xelatex_options, '-shell-escape';
push @extra_lualatex_options, '-shell-escape';

Альтернативный вариант для того же latexmkrc переопределить переменные для запуска, по сути:

$latex = 'latex  %O  --shell-escape %S';
$pdflatex = 'pdflatex  %O  --shell-escape %S';

В документе

В самом документе можно вызывать внешние программы с параметрами и сразу же вставлять на это место документа их выхлоп. Например:

\makeatletter
\@@input|"python3 ff.py"
\makeatother

Функции в bash

Задать функцию

Функции в bash можно задавать двумя способами:

# Способ 1
function_name () {
  commands
}

# Способ 2
function function_name {
  commands
}

Простые функции можно объявлять в одну строку. При этом пробелы между фигурными скобками и телом функции важны!. И последним в теле должен быть ; (точка с запятой).

Объявление функций в одну строку:

# Способ 1
function_name () { commands; }

# Способ 2
function function_name { commands; }

Итого по объявлению функций:

  • Тело функций (всё что между фигурными скобками) должно отделяться от самих фигурных скобок переносом строки или пробелами;
  • Определение функции не вызывает её (как и в нормальных языках);
  • Определение функции должно быть выше чем её вызовы;
  • Тело однострочных функций должно заканчиваться ; (точкой с запятой).

Переменные

Глобальные переменные видны в функциях и могут быть модифицированы в функциях. Локальные переменные (область видимости внутри функции) должны объявляться с ключевым словом local.

Локальные переменные имеют приоритет над глобальными если используется одно и то же имя.

#!/bin/bash

var1='A'
var2='B'

my_function () {
  local var1='C'
  var2='D'
  echo "Inside function: var1: $var1, var2: $var2"
}

echo "Before executing function: var1: $var1, var2: $var2"

my_function

echo "After executing function: var1: $var1, var2: $var2"

Вывод этого скрипта:

Before executing function: var1: A, var2: B
Inside function: var1: C, var2: D
After executing function: var1: A, var2: D

Параметры

Чтобы передать параметры в функцию надо просто написать их после вызова, разделяя пробелами. Имеет смысл заключать их в кавычки, тогда можно передавать параметры с пробелами.

  • Внутри функции доступ к параметрам осуществляется через переменные $1, $2, $3 и т.д.
  • Переменная $0 содержит имя самой функции.
  • Переменная $# содержит количество переданных параметров.
  • Переменные $* и $@ содержать все парамеры, переданные функцию.

Отличия переменных $* и $@

  • Если эти переменные НЕ заключать в кавычки, то они эквивалентны;
  • В кавычках "$*" раскрывается в одну строку "$1 $2 ... $n";
  • В кавычках "$@" раскрывается в разные строки "$1" "$2" ... "$n".

Пример:

#!/bin/bash

greeting () {
  echo "Hello $1"
}

greeting "World"

Возвращаемые значения

В отличие от функций в "настоящих" языках программирования, функции в Bash не позволяют возвращать значения как это принято. Когда функция bash заканчивает выполнение, ее возвращаемое значение это статус последней выполненной команды в теле функции, обычно 0 при успешном завершении, число 1-255 код ошибки.

Это число можно указать явно при использовании команды return, после чего оно будет сохранено в специальной переменной $?. Команда return прерывает выполнение функции (как и в обычных языках), а код ошибки можно рассматривать как статус выполнения.

Пример:

#!/bin/bash

my_function () {
  echo "some result"
  return 55
}

my_function
echo $?

Вывод этого скрипта:

some result
55

Чтобы по-настоящему что-то вернуть из функции надо использовать что-то другое. Самый простой вариант - присвоить что-то глобальной переменной:

#!/bin/bash

my_function () {
  func_result="some result"
}

my_function
echo $func_result

Вывод этого скрипта:

some result

Есть способ получше. Отправить требуемое возвращаемое значение на вывод (при помощи echo или printf, например):

#!/bin/bash

my_function () {
  local func_result="some result"
  echo "$func_result"
}

func_result="$(my_function)"
echo $func_result

Вывод этого скрипта:

some result

Тут вместо простого вызова (который просто напечатает строку) вызов функции "оборачивается" в оператор $(...), после чего переменная будет содержать то, что функция "хотела" напечатать.

Переопределение команд

Можно сделать функцию с именем, таким же как существующая команда. В этом случае, вместо команды будет вызываться функция. так можно добавлять, например, дополнительные опции во все вызовы команд сразу, или ещё как-то шаманить, чтоб не править много мест в скрипте сразу.

Пример:

#!/bin/bash

#overriding command
echo(){
    builtin echo "The name is : $1"
}

echo "Edward III"

Вывод этого скрипта:

The name is : Edward III

SSH через прокси

Для работы ssh через прокси используется может использоваться ряд программ:

Для того, чтобы подключаться через прокси ко всем или выборочным серверам надо прописать в файле config (~/.ssh/config) соответствующие настройки. Там можно настроить и другие параметры: имя пользователя, порт и т. п.

Работает и под Windows тоже (proxytunnel уж точно):

Пример:

Host имя_хоста1
  ProxyCommand connect -H 192.168.25.2:3128 %h %p

Host имя_хоста2
  ProxyCommand corkscrew 192.168.25.2 3128 %h %p

Host имя_хоста3
  ProxyCommand proxytunnel -q -p 127.0.0.1:8081 -d %h:%p -H "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32)"

Копирование метаданных с одного mp3 в другой (ffmpeg)

Файл mp3copy_id.bat следующего содержания:

@echo off

:: имя второго файла без пути и расширения
set F=%~n2
:: расширение второго файла
set E=%~x2

ffmpeg -i "%1" -y -f ffmetadata _metadata.txt

ffmpeg -i "%2" -f ffmetadata -i _metadata.txt -c copy -map_metadata 1 "%F%.1%E%"

del _metadata.txt

Запускать так:

mp3copy_id <src_mp3_file> <dest_mp3_file>

Скрипт создаст третий файл (медиа скопировано со второго, метаданные с первого). Имя файла будет такое же как у второго, но с добавленной .1 в имя файла.

QEMU run

Скрипт для запуска qemu с типовыми ключами (и образом CD в качестве опционального параметра).

#!/bin/bash

# Имя файла образа жесткого диска
IMG=./img/main_disk.img

if [[ "$OSTYPE" == "linux-gnu" ]]; then
  mkdir -p tmp
  CMDLINE=qemu-system-x86_64
  OPTS="-cpu qemu64 -enable-kvm -cpu host -hdb fat:rw:./tmp"
else
  CMDLINE=qemu-system-x86_64
  OPTS="-cpu qemu64"
fi

if [ $# -gt 0 ]; then
echo "external iso as cdrom $1"
CDROM=-cdrom $1 -boot d
else
CDROM=
fi

$CMDLINE \
    -hda $IMG \
    $CDROM $OPTS \
    -m 8192 \
    -vga cirrus \
    -net nic,model=rtl8139 \
    -net user \
    -usbdevice tablet \
    -vga virtio

Для начального создания образа диска можно использовать:

qemu-img create -f qcow2 main_disk.img 20G

Если надо упаковать каталог tmp в iso-образ, например, чтобы подсунуть в качестве cdrom при запуске qemu, то сделать можно так:

mkisofs -R -J -o dat.iso tmp/*

Boosty video download

Открыть страницу с видео, видеоплеер должен быть виден на странице.

В консоли средств разработчика (F12) выполнить:

document.querySelector('vk-video-player').store.actions.internal.downloadVideo()