Вообще не могу понять как два швеллера между собой изолированы: и там и там наварены удлиненные гайки и закручена шпилька. Для чего текстолитовые квадратики?
Да. Так и указано - уровень сложности "простой". Был бы вариант - "нулевой", но его нет к выбору. Многопоточность здесь не требуется, кроссплатформенность делалась бы по другому. Просто показал, что решить задачу не сложно. П.с. я не программист, не зарабатываю этим и опыта не имею соответствующего.
Да, с токеном это вопрос. И если уж создавать для общего пользования, то его надо решать. На написание приложения и, в последствии, статьи сподвиг комментарий о сложности. Захотелось попробовать, о чем и написал).
Ну PyScripter интуитивно понятен, схож с остальными IDE. Я пробовал и пайчарм, и VSC, и другие. Пайчарм конечно монстр, но уж через чур, не пришло еще время для него). VSC тож понравился и одно время 2-мя пользовался. Но вот мне, как практически новичку, PyScripter полностью устроил. Наворотами я не пользуюсь в виде точек останова, трассеров, да даже отслеживания переменных. Потому моё руководство будет "никаким". Там просто можно попробовать, не понравилось - удалил и забыл).
Таким слиянием не пользовался. А ворд терпеть не могу - постоянно форматирование уплывает по неведомым законам. Да и в экселе сумму столбца узнать, что-то посчитать мгновенно можно, а ворд бестолковый. Я его б вообще запретил. Ну вот вы скажете, а как же письма писать - дык я вам отвечу: письма в экселе просто замечательные выходят. Под рукой практически все есть в непечатаемой зоне: все объекты, все договора, все адресаты и обращения к ним, все исполнители и даже шапки всех филиалов если надо. Болванка письма делается мгновенно, без необходимости как в ворде искать предыдущее письмо для заготовки. Одно только плохо - все остальные делопроизводители начинают биться в истерике и вешаться.
Ну тут так скажу - работа не постоянная в плане места и одного объекта. Начали объект, построили, сдали, поехали на другой. К тому же не все время работаешь, ездишь на перевахтовки, а то и на другие объекты. Дальше - не все ПТО-шники могут/знают/умеют или хотят научится. Как стандарта по ведению документооборота в организации не принято. Я вот до сих пор борюсь с правильным наименованием файлов, шо б на него глянул и понимал, что внутри, но...не могу победить. Когда работу передаю всем легко, так как у меня все структурировано и по полочкам разложено. А как мне подхватывать чью-то работу - это ужас. По большому счету все как в фильме "Ночной продавец"))). Потому и не используем(.
Дабы не закидывать в ЯД файлы вручную, набросал скрипт. Использует он тот же файл с токенами, что и бот cfg_token. Возле скрипта кладу файлы, внутри в нем отмечаю папку куда надо закинуть (правлю или как вариант заготовить на каждую отдельно) и запускаю его. После загрузки он удаляет обработанные файлы.
код скрипта наполнения папки на ЯД
import cfg_token
import yadisk
import glob, os, shutil
import sys
import time
from datetime import datetime
# токен яндекс диска
y = yadisk.YaDisk(token=cfg_token.ya_dsk_token)
# загружаемый файл должен иметь расширение
format_move_files = ('.pdf', '.doc', '.docx', '.djvu', '.rar')#, '.rtf') '.zip', - зипы плохо обраб. ЯД
up_dir = 'Serii' #папка для хранения
## 'GOST' 'SP' 'VSN' 'STO'
def up_to_dir(file_name):
try:
# путь к загружаемым в облако файлам от пользователей
src = '/'+up_dir
dst = src+'/'+file_name
if not y.is_dir(src): # если папки нет, то создать
y.mkdir(src)
# грузим в облако файл
if os.path.exists(file_name):
if y.is_file(dst): # если такой файл есть то яндя даст ошибку, поэтому: вот
dst = src+'/Double-'+datetime.now().strftime("%d.%m.%Y-%H.%M.%S")+'-'+ file_name
y.upload(file_name, dst)
print('Загружен файл: '+file_name+' в облако '+dst)
os.remove(file_name)
print('Удален файл: '+file_name)
except Exception as e:
print('Ошибка: ', e)
k_file=0
file_in_dir = os.listdir(os.getcwd())
for file in file_in_dir:
if file.endswith(format_move_files, 0, len(file)): #'.pdf' if file.endswith('.pdf'):tuple(
print('Обрабатываю файл: ',file)
up_to_dir(file)
k_file=k_file+1
print('-----------------------------------------------')
else:
continue
print('Обработано файлов: '+str(k_file))
input("Работа завершена. Тисни ентер.")
Пока GitHub для меня сложноватая штука, код в принципе весь выложен, копипастой можно собрать, но раз весь надо, то тут и выложу. Под спойлером попытаюсь
Весь код (истинные сервисные не покажу, сделал замену)))
# pip install aiogram
# pip install yadisk
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
import cfg_token
import yadisk
import glob, os
import sys
import time
from datetime import datetime
import sqlite3 as sl
bot = Bot(token=cfg_token.telebot_token)
dp = Dispatcher(bot)
codirovk = 'utf-8'
# токен яндекс диска
y = yadisk.YaDisk(token=cfg_token.ya_dsk_token)
# загружаемый файл должен содержать в своем имени
format_name_files =['ГОСТ', 'Гост', 'гост', 'GOST', 'Gost', 'gost',
'SP', 'sp', 'СП', 'сп', 'VSN', 'vsn', 'ВСН', 'всн', 'STO', 'sto', 'СТО', 'сто',
'RD', 'rd', 'РД', 'рд', 'Rd', 'Рд', 'Серия', 'СЕРИЯ', 'серия']
# загружаемый файл должен иметь расширение
format_ext_files = ['.pdf', '.doc', '.docx', '.rtf', '.djvu']
search_dir = 'GOST' #папка по умолчанию стартовая для поиска
def sget_base_bot(user_id, name_dir):
con = sl.connect('databasebot.db')
cur = con.cursor()
with con:
cur.execute("CREATE TABLE IF NOT EXISTS user_seadir(id INTEGER NOT NULL PRIMARY KEY, seadir TEXT)")
with con:
cur.execute("SELECT seadir FROM user_seadir WHERE id = " + str(user_id))
dat = cur.fetchone()
if name_dir == '': # блок запроса установленной папки
if dat is not None:
return dat[0]
else:
return 'GOST'
cur.execute('INSERT INTO user_seadir (id, seadir) values(?, ?)', (user_id, 'GOST'))
else: # блок установки папки поиска
if dat is None:
cur.execute('INSERT INTO user_seadir (id, seadir) values(?, ?)', (user_id, name_dir))
else:
cur.execute('UPDATE user_seadir SET seadir = ? WHERE id = ?', (name_dir, user_id))
return name_dir
cur.close()
con.close()
#----------------записать данные в рапорт---------------
def report_to_txt(str15):
try:
with open('Report.txt', 'a', encoding=codirovk) as file4:
file4.write(str15)
except Exception as e:
print('Ошибка: '+e)
#--------------- bot command user begin ----------------------------------------
@dp.message_handler(commands=['start', 'старт']) ## команда /start
async def process_start_command(message: types.Message):
await bot.send_message(message.from_user.id, "Прива! Я бот-помошник! Ищу НТД и выдаю их Вам")
await bot.send_message(message.from_user.id, "Работаю, правда, только в рабочее время в основном")
await bot.send_message(message.from_user.id, "Имейте ввиду - я различаю большие и малые буквы. А НТД загружаю по 1шт за раз")
await bot.send_message(message.from_user.id, "Также можно мне прислать файл НТД, которого у меня нет и я его добавлю")
await bot.send_message(message.from_user.id, "Дополнительную информацию можно получить по команде /help")
await bot.send_message(message.from_user.id, "Текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'GOST')+'. Её можно переключить командой (см. /help)')
await bot.send_message(message.from_user.id, "Введите запрос на НТД (можно только номер или часть наименования):")
@dp.message_handler(commands=['help', 'хелп']) ## команда /help
async def process_help_command(message: types.Message):
# тут не высттавляем папку поиска, берем ее из базы
await bot.send_message(message.from_user.id, "Введите запрос на НТД (можно только номер или часть наименования) и отправьте мне, а я поищу где-то и если найду, то отправлю Вам файл, по 1шт за раз.")
await bot.send_message(message.from_user.id, "Еще мне можно прислать то чего нет пока у меня, после проверки добавлю к себе и тогда оно будет:).")
await bot.send_message(message.from_user.id, "Доступны команды: /start (или /старт) - инфа при старте бота")
await bot.send_message(message.from_user.id, "/about (или /абут) - инфа о боте и разработчике")
await bot.send_message(message.from_user.id, "/status (или /статус) - выдает ответ о работе. Если ответа нет - не в сети")
await bot.send_message(message.from_user.id, "/sms MESSAGE (или /смс <текст сообщения>) — отправить любое сообщение MESSAGE разработчику бота.")
await bot.send_message(message.from_user.id, "/gost , /sp , /vsn, /sto, /rd (или русскими буквами)- Установка папки для поиска по виду НТД.")
await bot.send_message(message.from_user.id, "В данный момент включен поиск в папке: "+sget_base_bot(message.from_user.id, ''))
@dp.message_handler(commands=['GOST', 'gost', 'ГОСТ', 'гост']) ## команда /GOST
async def process_gost_command(message: types.Message):
await bot.send_message(message.from_user.id, "Установлена текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'GOST'))
@dp.message_handler(commands=['SP', 'sp', 'СП', 'сп']) ## команда /SP
async def process_sp_command(message: types.Message):
await bot.send_message(message.from_user.id, "Установлена текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'SP'))
@dp.message_handler(commands=['RD', 'rd', 'РД', 'рд']) ## команда /SP
async def process_rd_command(message: types.Message):
await bot.send_message(message.from_user.id, "Установлена текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'RD'))
@dp.message_handler(commands=['VSN', 'vsn', 'ВСН', 'всн']) ## команда /VSN
async def process_vsn_command(message: types.Message):
await bot.send_message(message.from_user.id, "Установлена текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'VSN'))
@dp.message_handler(commands=['STO', 'sto', 'СТО', 'сто']) ## команда /STO
async def process_sto_command(message: types.Message):
await bot.send_message(message.from_user.id, "Установлена текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'STO'))
@dp.message_handler(commands=['Serii', 'SERII', 'serii', 'Серии', 'СЕРИИ', 'серии', 'Серия', 'СЕРИЯ', 'серия']) ## команда /SERII
async def process_serii_command(message: types.Message):
await bot.send_message(message.from_user.id, "Установлена текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, 'Serii'))
@dp.message_handler(commands=['about', 'абут', 'разработчик']) ## команда /about
async def process_about_command(message: types.Message):
await bot.send_message(message.from_user.id, "Разработчик revalpam@ya.ru. Бот создан для оперативного получения документации в лично-производственных целях.")
@dp.message_handler(commands=['status', 'статус']) ## команда /status
async def process_status_command(message: types.Message):
await bot.send_message(message.from_user.id, "Работаю. Тут я. А шо такое? Вводите запрос и тисните Ентер:)")
await bot.send_message(message.from_user.id, "Текущая папка для поиска НТД: "+sget_base_bot(message.from_user.id, ''))
@dp.message_handler(commands=['sms', 'смс']) ## команда /sms сообщение разработчику
async def process_sms_command(message: types.Message):
report_to_txt('\nПользователь id'+str(message.from_user.id)+' отправил сообщение: '+message.text)
await bot.send_message(message.from_user.id, "Сообщение разработчику отправлено")
#--------------- bot command user end ------------------------------------------
#--------------- service command admin begin -----------------------------------
# выгружает файл отчета в облако и удаляет!!! его с диска
@dp.message_handler(commands=['rep123456789']) ## команда /rep отчет
async def process_rep_command(message: types.Message):
try:
# путь к загружаемым в облако файлам от пользователей
src = '/ReportBot'
if not y.is_dir(src):
y.mkdir(src)
destin_file = src+ '/Report-'+datetime.now().strftime("%d.%m.%Y-%H.%M.%S")+'.txt'
if y.is_file(destin_file):
y.remove(destin_file, permanently=True)
# грузим в облако файлы
if os.path.exists('Report.txt'):
y.upload('Report.txt', destin_file)
os.remove('Report.txt')
await bot.send_message(message.from_user.id, "Отчёт обработан")
except Exception as e:
print('Ошибка: '+e)
# показывает файл отчета с диска
@dp.message_handler(commands=['view-rep123456789']) ## команда показать отчет
async def process_view_report_command(message: types.Message):
try:
if os.path.exists('Report.txt'):
with open('Report.txt', encoding=codirovk) as f5:
ch_file = len(f5.read())
if ch_file<2400:
with open('Report.txt', 'r', encoding=codirovk) as f5:
await bot.send_message(message.from_user.id, f5.read())
else:
await bot.send_message(message.from_user.id, "Отчёт слишком большой. Лучше смотреть в облаке после команды /rep")
else:
await bot.send_message(message.from_user.id, "Отчёт не создавался пока")
except Exception as e:
print('Ошибка: '+e)
##@dp.message_handler(commands=['stop']) ## команда /stop работает криво - много ошибок иде показывает
##async def process_stop_command(message: types.Message):
## await bot.send_message(message.from_user.id, "Останавливаюсь.")
## sys.exit()
#--------------- service command admin end -------------------------------------
@dp.message_handler(content_types=['text']) ## получаем сообщение от юзера
async def get_text_messages(message: types.Message):
search_dir = sget_base_bot(message.from_user.id, '')
report_to_txt('\nПользователь id'+str(message.from_user.id)+' сделал запрос на поиск в папке ' + search_dir +': '+message.text)
await bot.send_message(message.from_user.id, 'Запускаю процесс поиска в папке ' + search_dir +' : '+message.text)
if y.check_token():
if not y.is_dir('/'+search_dir):
await bot.send_message(message.from_user.id, 'Папка ' + search_dir +' не обнаружена. Шо-то поломалось. Извините.')
else:
Spis = []
for item in y.listdir(search_dir):
if message.text in item['name']:
if len(Spis) < 7:
await bot.send_message(message.from_user.id, 'Обнаружен документ: '+item['name'])
Spis.append(item['name'])
if len(Spis) == 0:
await bot.send_message(message.from_user.id, 'Извините, пока такого документа в папке '+ search_dir +' не нашлось.')
await bot.send_message(message.from_user.id, 'Но если Вы мне его сюда скинете, после проверки я его добавлю.')
if len(Spis) == 1:
# ------------даем ссылку на файл-------------------
y.publish('/'+search_dir+'/'+Spis[0]) # делаем публичный файл
# шлем ссылку
await bot.send_message(message.from_user.id, y.get_meta('/'+search_dir+'/'+Spis[0]).public_url)
if len(Spis) > 1:
await bot.send_message(message.from_user.id, 'Найдено документов: '+str(len(Spis)) + '. Уточните запрос:')
else:
await bot.send_message(message.from_user.id, 'Извините по каким-то причинам диск не доступен. Попробуйте в другой раз')
@dp.message_handler(content_types=['document']) # получаем файл от юзера
async def handle_file(message):
try:
# если файл такой как надо, то качаем
str_nam_file = str(message.document.file_name)
len_str_nf = len(str_nam_file)
if str_nam_file.endswith(tuple(format_name_files), 0, len_str_nf) and str_nam_file.endswith(tuple(format_ext_files), 0, len_str_nf):
file_id = message.document.file_id
file = await bot.get_file(file_id)
file_path = file.file_path
# ------------Вариант загрузки файлов в яндекс-облако------------
# путь к загружаемым в облако файлам от пользователей
if not y.is_dir('/DownloadBot'):
y.mkdir('/DownloadBot')
src = '/DownloadBot/'+ message.document.file_name
print(src)
# грузим в облако файл от пользователя
if y.is_file(src): # если такой файл есть то яндя даст ошибку, поэтому: вот
src = '/DownloadBot/Double-'+datetime.now().strftime("%d.%m.%Y-%H.%M.%S")+'-'+ message.document.file_name
y.upload(await bot.download_file(file_path), src)
await bot.send_message(message.from_user.id, 'Загрузил. Спасибо. После проверки добавлю в свою базу:)')
# сделать запись после загрузки в файл Report.txt
report_to_txt('\nПользователь id'+str(message.from_user.id)+' прислал файл: '+message.document.file_name)
else:
await bot.send_message(message.from_user.id, 'Простите, но присланный Вами файл не содержит в имени тип НТД (ГОСТ, СП, ВСН и т.д.) и/или не подходит по формату, нужен .pdf или .doc')
except Exception as e:
print('Ошибка: '+e)
await bot.send_message(message.from_user.id, 'Я наверное не смогу загрузить, шо-то сломалось и выдает ошибку: '+e)
if __name__ == '__main__':
executor.start_polling(dp)
## executor.start_polling(dp, skip_updates=True)
##Параметр skip_updates=True позволяет пропустить накопившиеся входящие сообщения, если они нам не важны
Скорость электрона в проводнике не равна скорости света, очень даже не равна.
зачем линейка - посчитайте кол-во монет.
если только 2 в С ушла
Работает, когда я на работе. Задеплоил в виртуалбокс на TinyCore.
Ну и в связи с выходом обновлений пакетов, встретился с "неработой" бота - aiogram переделали, поэтому актуально указывать версию:
Интересно, а сборка tiny10 тоже с телеметрией?....надо будет глянуть
Вообще не могу понять как два швеллера между собой изолированы: и там и там наварены удлиненные гайки и закручена шпилька. Для чего текстолитовые квадратики?
Я тож балдею от Delphi. Как бы там не ругали ее, но GUI делается мгновенно и без кода.
В этом варианте и кроссплатформенность лучше будет
Спасибо. Я еще не сильно знаком с новыми системами. На D7 больше был.
Да. Так и указано - уровень сложности "простой". Был бы вариант - "нулевой", но его нет к выбору. Многопоточность здесь не требуется, кроссплатформенность делалась бы по другому. Просто показал, что решить задачу не сложно. П.с. я не программист, не зарабатываю этим и опыта не имею соответствующего.
я ж не заставляю. каждый сам выберет шо ему надо.
Да. Там примеров много из них много чего вытянуть можно.
Возможно. Но Вы гляньте сколько вопросов про GUI новички Python-a задают. Вот как еще один путь для изучения.
Да, с токеном это вопрос. И если уж создавать для общего пользования, то его надо решать. На написание приложения и, в последствии, статьи сподвиг комментарий о сложности. Захотелось попробовать, о чем и написал).
https://habr.com/ru/articles/763054/
))
Статья без конкретики. Без цифр. Все фотки чьи-то.
Ну PyScripter интуитивно понятен, схож с остальными IDE. Я пробовал и пайчарм, и VSC, и другие. Пайчарм конечно монстр, но уж через чур, не пришло еще время для него). VSC тож понравился и одно время 2-мя пользовался. Но вот мне, как практически новичку, PyScripter полностью устроил. Наворотами я не пользуюсь в виде точек останова, трассеров, да даже отслеживания переменных. Потому моё руководство будет "никаким". Там просто можно попробовать, не понравилось - удалил и забыл).
Таким слиянием не пользовался. А ворд терпеть не могу - постоянно форматирование уплывает по неведомым законам. Да и в экселе сумму столбца узнать, что-то посчитать мгновенно можно, а ворд бестолковый. Я его б вообще запретил. Ну вот вы скажете, а как же письма писать - дык я вам отвечу: письма в экселе просто замечательные выходят. Под рукой практически все есть в непечатаемой зоне: все объекты, все договора, все адресаты и обращения к ним, все исполнители и даже шапки всех филиалов если надо. Болванка письма делается мгновенно, без необходимости как в ворде искать предыдущее письмо для заготовки. Одно только плохо - все остальные делопроизводители начинают биться в истерике и вешаться.
Ну тут так скажу - работа не постоянная в плане места и одного объекта. Начали объект, построили, сдали, поехали на другой. К тому же не все время работаешь, ездишь на перевахтовки, а то и на другие объекты. Дальше - не все ПТО-шники могут/знают/умеют или хотят научится. Как стандарта по ведению документооборота в организации не принято. Я вот до сих пор борюсь с правильным наименованием файлов, шо б на него глянул и понимал, что внутри, но...не могу победить. Когда работу передаю всем легко, так как у меня все структурировано и по полочкам разложено. А как мне подхватывать чью-то работу - это ужас. По большому счету все как в фильме "Ночной продавец"))). Потому и не используем(.
Дабы не закидывать в ЯД файлы вручную, набросал скрипт. Использует он тот же файл с токенами, что и бот cfg_token. Возле скрипта кладу файлы, внутри в нем отмечаю папку куда надо закинуть (правлю или как вариант заготовить на каждую отдельно) и запускаю его. После загрузки он удаляет обработанные файлы.
код скрипта наполнения папки на ЯД
Пока GitHub для меня сложноватая штука, код в принципе весь выложен, копипастой можно собрать, но раз весь надо, то тут и выложу. Под спойлером попытаюсь
Весь код (истинные сервисные не покажу, сделал замену)))