<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>timsa.ru: заметки с тегом программирование</title>
<link>https://timsa.ru/tags/programmirovanie/</link>
<description>Моя записная книжка. Комментарии отключены из-за спама. Для вопросов используйте эту страничку</description>
<author></author>
<language>ru</language>
<generator>Aegea 11.0 (v4079)</generator>

<itunes:subtitle>Моя записная книжка. Комментарии отключены из-за спама. Для вопросов используйте эту страничку</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>Отгадыватель кроссвордов</title>
<guid isPermaLink="false">107</guid>
<link>https://timsa.ru/all/wow/</link>
<pubDate>Tue, 21 Jul 2020 13:44:14 +0500</pubDate>
<author></author>
<comments>https://timsa.ru/all/wow/</comments>
<description>
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;#!/usr/bin/env python3

import sys
from itertools import permutations
import re
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import os.path

if len(sys.argv) &amp;lt; 4:
  print(&amp;quot;Usage: \nwords.py yandex|google|filename|none алфавит маска\n&amp;quot;)
  sys.exit()

search  = sys.argv[1]
alphabet = sys.argv[2]
pattern = sys.argv[3]

yandex = 'https://yandex.ru/search/?noreask=1&amp;amp;text='
google = 'https://www.google.ru/search?ie=UTF-8&amp;amp;hl=ru&amp;amp;spell=0&amp;amp;nfpr=1&amp;amp;q='

ua = UserAgent()
myheaders = {'User-Agent': str(ua.random), 'referer': 'https://www.google.ru'}

# все варианты перестановок
allwords = permutations(alphabet, len(pattern))

# выкидываем дубликаты
words = list(set(allwords))

# склеиваем 2-мерный список в одномерный
words2 = []
for word in words:
  str = ''.join(word)
  words2.append(str)

# проходим регекспом
obj = re.compile(pattern)
words = list(filter(lambda str: obj.search(str), words2))

print('Всего вариантов %d' % len(words))

output = []
wordlist = []

if os.path.exists(search):
  f = open(search, 'r', encoding = 'utf-8')
  wordlist = [line.strip() for line in f]
  f.close()
  print('Размер словаря %d' % len(wordlist))

for word in words:
  if search == 'google':
    r = requests.get(google + word, headers=myheaders)
    r.encoding = 'utf-8'
    soup = BeautifulSoup(r.text, 'html5lib')
    stat = soup.find('div', id='resultStats')
    if stat is not None:
      qty = re.search('Результатов:\sпримерно\s(.*)\s\(\d+,\d+\sсек.\)', stat.text)
      x = qty.group(1)
      x = x.split()
      x = ''.join(x)
      output.append([word, int(x)])
      print(&amp;quot;%s - %s&amp;quot; % (word, x))
    else:
      output.append([word, 0])

  elif search == 'yandex':
    r = requests.get(yandex + word, headers=myheaders)
    r.encoding = 'utf-8'
    soup = BeautifulSoup(r.text, 'html5lib')
    stat = soup.find('div', {'class': 'serp-adv__found'})
    if stat is not None:
      qty = re.search('Нашлось\s(.*)\sрезультатов', stat.text)
      x = qty.group(1)
      output.append([word, x])
      print(&amp;quot;%s - %s&amp;quot; % (word, x))
    else:
      output.append([word, 0])
      
  elif os.path.exists(search):
    if word in wordlist:
      output.append([word, 0])
    
  else:
    output.append([word, 0])

print('Отфильтрованно с помощью %s' % search)

output.sort(key=lambda x: x[1], reverse=True)

for str in output:
  print(str[0])&lt;/code&gt;&lt;/pre&gt;</description>
</item>

<item>
<title>Подключаем Dadget CO2 к серваку</title>
<guid isPermaLink="false">116</guid>
<link>https://timsa.ru/all/podklyuchaem-dadget-co2-k-servaku/</link>
<pubDate>Mon, 20 Jul 2020 22:38:42 +0500</pubDate>
<author></author>
<comments>https://timsa.ru/all/podklyuchaem-dadget-co2-k-servaku/</comments>
<description>
&lt;ol start="1"&gt;
&lt;li&gt;Сначала сделаем чтобы любой пользователь мог обращаться к устройству&lt;br /&gt;
создаем /etc/udev/rules.d/10-co2mon.rules&lt;br /&gt;
с содержимым&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;ACTION==&amp;quot;add|change&amp;quot;, SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;04d9&amp;quot;, ATTRS{idProduct}==&amp;quot;a052&amp;quot;, MODE:=&amp;quot;0666&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;щелкаем&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;udevadm control --reload
udevadm trigger&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;проверяем что /dev/usb/hiddev0 теперь crw-rw-rw-&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Подключаем библиотечку &lt;s&gt;PyUSB&lt;/s&gt; hid. PyUSB глючное говно вызывающее странные эффекты, например пропадение устройства hiddev0.&lt;br /&gt;
pip3 install hid (или hidapi уже не помню, это гуглится)&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Читаем (алгоритм расшифровки передрал с сишного проекта co2mod)&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;#!/usr/bin/env python3

import hid
import time

def decode_co(data):
    # кручу-верчу
    data[0], data[2] = data[2], data[0]
    data[1], data[4] = data[4], data[1]
    data[3], data[7] = data[7], data[3]
    data[5], data[6] = data[6], data[5]
    
    result = bytearray(8)

    # всех обмануть хочу
    result[7] = ((data[6] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[7] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[6] = ((data[5] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[6] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[5] = ((data[4] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[5] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[4] = ((data[3] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[4] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[3] = ((data[2] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[3] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[2] = ((data[1] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[2] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[1] = ((data[0] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[1] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    result[0] = ((data[7] &amp;lt;&amp;lt; 5) &amp;amp; 0xFF) | ((data[0] &amp;gt;&amp;gt; 3) &amp;amp; 0xFF)
    
    magic_word = b'Htemp99e'
    for i in range(8):
        r = ((magic_word[i] &amp;lt;&amp;lt; 4) &amp;amp; 0xFF) | ((magic_word[i] &amp;gt;&amp;gt; 4) &amp;amp; 0xFF)
        if result[i] &amp;lt; r:
            result[i] = 0xFF - r + result[i]
        else:
            result[i] = result[i] - r

    # не знаю почему, но у меня проверка чек-суммы никогда не сходилась    
    #if result[0]+result[1]+result[2] != result[3]:
    #    return 0

    res = (result[1] &amp;lt;&amp;lt; 8) + result[2]

    if result[0] == 0x42:
        print(&amp;quot;T={0}&amp;quot;.format(res * 0.0625 - 273.15))
        return 1
    elif result[0] == 0x50:
        print(&amp;quot;CO={0}&amp;quot;.format(res))
        return 2
    return 0
    
try:
    h = hid.device()
    h.open(0x04d9, 0xa052)

    # хз, не вникал
    h.set_nonblocking(1)

    # по идее это отправка некой magic_table которой шифруется ответ, но и без любой из этих строк работает
    #h.write(b'8\x00\x00\x00\x00\x00\x00\x00\x00')
    h.send_feature_report([0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
    time.sleep(0.05)

    co = 1
    t = 1
    while co | t:
        d = h.read(8)
        if d:
            n = decode_co(d)
            if n == 1:
                t = 0
            elif n == 2:
                co = 0

    h.close()

except IOError as ex:
    print(ex)&lt;/code&gt;&lt;/pre&gt;</description>
</item>

<item>
<title>GPS tracker (Deest D69 Pet locator)</title>
<guid isPermaLink="false">61</guid>
<link>https://timsa.ru/all/gps-tracker-deest-d69-pet-locator/</link>
<pubDate>Mon, 18 Sep 2017 10:11:59 +0500</pubDate>
<author></author>
<comments>https://timsa.ru/all/gps-tracker-deest-d69-pet-locator/</comments>
<description>
&lt;p&gt;Покупал когда то такую вот шнягу&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://timsa.ru/pictures/2017-09-18-10.01.16.jpg" width="1625" height="1617" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Хотел кошку на даче отпустить гулять. А она весом с кирпич оказалась.&lt;/p&gt;
&lt;p&gt;Тем не менее раз купил надо извлечь пользу. Поделие китайское, инфы почти никакой нет, на трекинг сайтах over9000 моделей трекеров поддерживается, а этого нет ни у кого. Родной сайт 102.gpsjm.com говно полное, приложение аналогично. Но, можно смской передать трекеру свой адрес и порт для логирования.&lt;br /&gt;
Протокол неизвестен, поэтому пока что написал на питоне прокси и смотрю что эта голова шлет на свой сайт.&lt;/p&gt;
&lt;p&gt;update:&lt;br /&gt;
Долбанные китайцы сделали keep-alive соединение, которое шняга поднимает и держит открытым.&lt;br /&gt;
Если оно открыто сервак без предупреждения шлет команды, а шняга по расписанию кидает координаты. Если в помещении и координат нет то только заряд аккума.&lt;/p&gt;
</description>
</item>


</channel>
</rss>