Инструменты пользователя

Инструменты сайта


develop:pyton:sqlite

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
develop:pyton:sqlite [2022/07/03 08:44]
admin
develop:pyton:sqlite [2024/07/15 05:29] (текущий)
admin
Строка 2: Строка 2:
  
  
-==== Аргументы командной строки ==== +===== Модули/Настройки окружения ===== 
-Параметры с префиксом тире необязательные, без префикса обязательные они видимо и являются обязательными\\+<code bash> 
 +  # Установка модуля для конкретного python 
 +python3.8 -m pip install pyTelegramBotAPI 
 +  # Модуль для телеграм бота бота 
 +pyTelegramBotAPI 
 +  # Модуль для json логов 
 +python-json-logger 
 +  # Модуль для виндовых хостов 
 +/usr/bin/python3.9 -m pip install pywinrm 
 +знать на каком именно питоне работает ансибл ansible --version)
  
 +  # 
 +pip3 install --upgrade pip
 +pip3 install --upgrade setuptools
 +</code>
 +
 +
 +===== Аргументы командной строки =====
 +Параметры с префиксом тире необязательные, без префикса обязательные они видимо и являются обязательными\\
 <details> <details>
   * **name or flags** - или имя, или список строк опций, например foo или -f, --foo,   * **name or flags** - или имя, или список строк опций, например foo или -f, --foo,
Строка 48: Строка 65:
  
  
-==== Web API === 
  
 +===== Zabbix Web API =====
 <details> <details>
 <summary>:!: Обращение к Zabbix, работа с JSON результатом</summary> <summary>:!: Обращение к Zabbix, работа с JSON результатом</summary>
Строка 82: Строка 99:
 </details> </details>
  
-==== SQLite ==== 
  
 +<details>
 +<summary>:!: Обращение к Zabbix, токен авторизации</summary>
 +<code python>
 +query= """{"jsonrpc": "2.0",
 +    "method": "user.login",
 +    "params": {
 +        "user": "Admin",
 +        "password": "Admin"
 +    },
 +    "id": 1,
 +    "auth": null
 +    }""".replace('\n', '')
 +    answer= requests.post('http://10.10.10.30/zabbix/api_jsonrpc.php', json=json.loads(query))
 +</code>
 +</details>
 +
 +
 +
 +===== SQLite =====
 <details> <details>
 <summary>:!: Работа с SQLite </summary> <summary>:!: Работа с SQLite </summary>
Строка 113: Строка 148:
 #for row in cur.fetchall(): #for row in cur.fetchall():
 #        print(row)</code> #        print(row)</code>
- 
  
 # #
Строка 125: Строка 159:
 #for member in r: #for member in r:
 #    print(member[0]+ ' -==- '+ member[1]) #    print(member[0]+ ' -==- '+ member[1])
- 
 </details> </details>
  
Строка 159: Строка 192:
         self.cur.execute('select `MessageId` from `IdMessages` where `AlertId`= "'+AlertId+'"; ');         self.cur.execute('select `MessageId` from `IdMessages` where `AlertId`= "'+AlertId+'"; ');
         return self.cur.fetchall();         return self.cur.fetchall();
- 
- 
  
 def main(): def main():
Строка 199: Строка 230:
             print(answer.json());             print(answer.json());
             print('***************************************');             print('***************************************');
-     
     #print(answer.json());     #print(answer.json());
- 
  
 if __name__ == "__main__": if __name__ == "__main__":
Строка 209: Строка 238:
  
  
-==== Работа с текстом === 
  
 +===== Работа с текстом =====
 <details> <details>
 <summary>:!: Разбор auth.log </summary> <summary>:!: Разбор auth.log </summary>
Строка 276: Строка 305:
  
  
-==== e-mail === +===== e-mail =====
 <details> <details>
 <summary>:!: Отправка письма</summary> <summary>:!: Отправка письма</summary>
Строка 285: Строка 313:
 <code python> <code python>
 #!/usr/bin/python3 #!/usr/bin/python3
- 
 import smtplib import smtplib
  
Строка 318: Строка 345:
               server="127.0.0.1"):               server="127.0.0.1"):
     assert isinstance(send_to, list)     assert isinstance(send_to, list)
- 
     msg = MIMEMultipart()     msg = MIMEMultipart()
     msg['From'] = send_from     msg['From'] = send_from
Строка 345: Строка 371:
  
  
-==== Файлы === 
  
 +===== Файлы =====
   * **read()** - загружает **весь файл в ОЗУ**   * **read()** - загружает **весь файл в ОЗУ**
   * **readline()** - читает одну строчку   * **readline()** - читает одну строчку
   * **for line in file:** - цикл обработки всего файла построчно   * **for line in file:** - цикл обработки всего файла построчно
-  * ** ** -  
- 
 <details> <details>
 <summary>:!: Последовательная обработка файла </summary> <summary>:!: Последовательная обработка файла </summary>
Строка 368: Строка 392:
  
  
-==== WSGI Server ===+===== WSGI Server =====
 Сервер может обрабатывать веб запросы, передавать их приложениям\\ Сервер может обрабатывать веб запросы, передавать их приложениям\\
- 
 Переменная **environ** содержит служебную информацию о клиенте\\ Переменная **environ** содержит служебную информацию о клиенте\\
 В **start_response** собсна помещаем ответ В **start_response** собсна помещаем ответ
- 
 <details> <details>
 <summary>:!: Простой ответ на веб запросы к хосту </summary> <summary>:!: Простой ответ на веб запросы к хосту </summary>
 <code python> <code python>
 #!/usr/bin/python3 #!/usr/bin/python3
- 
 import wsgiserver import wsgiserver
 from wsgiref.simple_server import make_server, demo_app from wsgiref.simple_server import make_server, demo_app
Строка 402: Строка 423:
 </code> </code>
 </details> </details>
- 
  
  
Строка 409: Строка 429:
 **raw** получаем вручную\\ **raw** получаем вручную\\
 **pip install beautifulsoup4**\\ **pip install beautifulsoup4**\\
- 
 <code python> <code python>
 from bs4 import BeautifulSoup from bs4 import BeautifulSoup
Строка 454: Строка 473:
         outfile.write(';\t'.join(line)+ '\n')         outfile.write(';\t'.join(line)+ '\n')
         count += 1         count += 1
-     
     print("Всего записей - "+ str(count))     print("Всего записей - "+ str(count))
- 
  
 if __name__ == "__main__": if __name__ == "__main__":
Строка 464: Строка 481:
  
  
-==== Yandex Disk API === 
  
 +===== Yandex Disk API =====
 <details> <details>
 <summary>:!: Yandex Disk API </summary> <summary>:!: Yandex Disk API </summary>
Строка 522: Строка 539:
                         '{0}/{1}{2}/{3}'.format(savepath, date_folder, address.replace(loadpath, ""), file))                         '{0}/{1}{2}/{3}'.format(savepath, date_folder, address.replace(loadpath, ""), file))
         bar.finish()         bar.finish()
- 
  
 if __name__ == '__main__': if __name__ == '__main__':
Строка 528: Строка 544:
     #backup('Backup', os.getcwd())     #backup('Backup', os.getcwd())
 </code> </code>
 +{{:develop:pyton:screenshot_4.jpg?direct&800|}}
 </details> </details>
 +
 +
 +<details>
 +<summary>:!: Yandex Disk API. += На скорую руку, загрузка указанного файла </summary>
 +<code python>
 +#!/bin/python3
 +
 +import os, argparse
 +import requests
 +from datetime import datetime
 +from progress.bar import Bar
 +
 +argParser= argparse.ArgumentParser()
 +argParser.add_argument('upFilename', type= str, help= 'Файл для загрузки')
 +argParser.add_argument('saveFolder', type= str, help= 'Папка дял сохранения')
 +args= argParser.parse_args()
 +
 +URL = 'https://cloud-api.yandex.net/v1/disk/resources'
 +TOKEN = 'AQAAAAA5-bYIAADLW5YbQ0L1yUakkN5VrOYQtto'
 +headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': f'OAuth {TOKEN}'}
 +
 +def create_folder(path):
 +    """Создание папки. \n path: Путь к создаваемой папке."""
 +    requests.put(f'{URL}?path={path}', headers=headers)
 +
 +def upload_file(loadfile, savefile, replace=False):
 +    """Загрузка файла.
 +    savefile: Путь к файлу на Диске
 +    loadfile: Путь к загружаемому файлу
 +    replace: true or false Замена файла на Диске"""
 +    res = requests.get(f'{URL}/upload?path={savefile}&overwrite={replace}', headers=headers, verify=False).json()
 +    with open(loadfile, 'rb') as f:
 +        try:
 +            requests.put(res['href'], files={'file':f}, verify=False)
 +        except KeyError:
 +            print(res)
 +
 +def backup(savepath, loadpath):
 +    """Загрузка папки на Диск. \n savepath: Путь к папке на Диске для сохранения \n loadpath: Путь к загружаемой папке"""
 +        # Формируем название папки на диске, название целевой папки (из переданного пути) + дата-время
 +        # `loadpath.split('/')[-1]` разбиваем путь на list, и возвращаем последний элемент т.е. папку
 +    date_folder = 'currDate'#'{0}_{1}'.format(loadpath.split('/')[-1], datetime.now().strftime("%Y-%m-%d_%H:%M"))
 +    
 +    create_folder(savepath)
 +        # ф-я `os.walk` возвращает массив файлов из дерева каталогов (в параметрах можно указать направление обхода)
 +        # возвращает тройной кортеж - "dirpath (тек путь), dirnames (папки), filenames (файлы)"
 +        # по дефолту вложенность вся, идет по порядку от указанного пути и далее
 +    for address, _, files in os.walk(loadpath):
 +            # тут создаем подпапки, из путей, что приходят в цикле обхода
 +                # `address.replace(loadpath, "")[1:]` - здесь вычитаем исходный путь из вложенного
 +        create_folder('{0}/{1}/{2}'.format(savepath, date_folder, address.replace(loadpath, "")[1:]))
 +        bar = Bar('Loading', fill='X', max=len(files))
 +            # Циклом проходим по всем файлам что есть в данном каталоге
 +        for file in files:
 +            bar.next()
 +                # в первой части путь в ФС, во второй путь на диске, исходный снова вырезан
 +            upload_file('{0}/{1}'.format(address, file),\
 +                        '{0}/{1}{2}/{3}'.format(savepath, date_folder, address.replace(loadpath, ""), file+ "this_my_file"))
 +        bar.finish()
 +        
 +        
 +def backupOnce(diskFolder, uploadFilePath):
 +    """Загрузка папки на Диск. \n diskFolder: Путь к папке на Диске для сохранения \n uploadFilePath: Путь к загружаемой папке"""
 +        # Формируем название папки на диске, название целевой папки (из переданного пути) + дата-время
 +        # `uploadFilePath.split('/')[-1]` разбиваем путь на list, и возвращаем последний элемент т.е. папку
 +    currDateTime = datetime.now().strftime("%Y-%m-%d_%H-%M")
 +    
 +    create_folder(diskFolder)
 +    upload_file(uploadFilePath, '{0}/{1}'.format(diskFolder, currDateTime+'_'+ uploadFilePath.split('/')[-1] ))
 +
 +if __name__ == '__main__':
 +    backupOnce(args.saveFolder, args.upFilename)
 +    #backup('Backup', os.getcwd())
 +</code>
 +</details>
 +
  
  
  
-==== Хеш функции. Hashlib ===+===== Хеш функции. Hashlib =====
 Читать файл лучше всего по блокам, функцией **update()** данные помещаются в объект, можно делать это поблочно\\ Читать файл лучше всего по блокам, функцией **update()** данные помещаются в объект, можно делать это поблочно\\
 Собсна каждый алгоритм имеет свою функцию, с соответствующим названием\\ Собсна каждый алгоритм имеет свою функцию, с соответствующим названием\\
 **digest()** - хеш в виде байтов, **hexdigest()** в виде строки\\ **digest()** - хеш в виде байтов, **hexdigest()** в виде строки\\
- 
- 
 <details> <details>
 <summary>:!: Хеш строка из файла </summary> <summary>:!: Хеш строка из файла </summary>
Строка 551: Строка 642:
     hsh.update(fileData)     hsh.update(fileData)
 result= hsh.hexdigest() result= hsh.hexdigest()
- 
 print(result) print(result)
 </code> </code>
Строка 557: Строка 647:
  
  
-====  ===+<details> 
 +<summary>:!: Перебор папки </summary> 
 +<code python> 
 +#!/usr/bin/python3 
 +import hashlib, argparse, os
  
 +argParser= argparse.ArgumentParser()
 +argParser.add_argument('filename', type= str, help= 'Проверяемый файл')
 +argParser.add_argument('folder', type= str, help= 'Путь для проверки')
 +args= argParser.parse_args()
 +
 +def main():
 +    # Хеш из проверяемого файла
 +    #checkFileHash= GetHash(args.filename)
 +    # Перебираем целевую папку
 +    for file in os.listdir(args.folder):
 +        currentHash= GetHash(args.folder +'/'+ file)
 +        print(file +' - '+ currentHash)
 +
 +def GetHash(fullFileName):
 +    """ Сгенерировать хеш строку из указанного файла """
 +    openedFile= open(fullFileName, 'rb')
 +    md5= hashlib.md5()
 +    while True:
 +        fileData= openedFile.read(2048)
 +        if not fileData:
 +            break   
 +        md5.update(fileData)
 +    return md5.hexdigest()
 +
 +if __name__ == "__main__":
 +    main()
 +</code>
 +</details>
 +
 +
 +
 +===== Работа с оболочкой =====
 <details> <details>
-<summary>:!:  </summary>+<summary>:!: Пару вариантов </summary> 
 +Вроде более рекомендованный способ, как то заморочено вроде
 <code python> <code python>
 +import subprocess
  
 +var= subprocess.run("ls /home/admin", shell=True, stdout=subprocess.PIPE, encoding='utf-8')
 +print(var.stdout)
 +</code>
 +Вывод сразу на консоль, возвращает код возврата\\
 +<code python>
 +import os
 +os.system("ls /home/admin >/dev/null")
 </code> </code>
 </details> </details>
  
  
 +
 +===== Цвет текста =====
 +<details>
 +<summary>:!: ANSI последовательности, работает для *nix консолей </summary>
 +{{:develop:pyton:py_color.png?direct&400|}}
 +<code python>
 +class bcolors:
 +    HEADER = '\033[95m'
 +    OKBLUE = '\033[94m'
 +    OKCYAN = '\033[96m'
 +    OKGREEN = '\033[92m'
 +    WARNING = '\033[93m'
 +    FAIL = '\033[91m'
 +    ENDC = '\033[0m'
 +    BOLD = '\033[1m'
 +    UNDERLINE = '\033[4m'
 +print(bcolors.HEADER+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.OKBLUE+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.OKCYAN+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.OKGREEN+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.WARNING+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.FAIL+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.BOLD+ 'This is test TeXt in color'+ bcolors.ENDC)
 +print(bcolors.UNDERLINE+ 'This is test TeXt in color'+ bcolors.ENDC)
 +</code>
 +</details>
 +
 +
 +<details>
 +<summary>:!: Обширный пример </summary>
 +<code python>
 +#!/usr/bin/python
 +import subprocess, os
 +glNameNewImport= ""
 +glSelectedMultip= ""
 +glDictFreePorts= {}
 +glHostIP= ""
 +
 +class bcolors:
 +    HEADER = '\033[95m'
 +    OKBLUE = '\033[94m'
 +    OKCYAN = '\033[96m'
 +    OKGREEN = '\033[92m'
 +    WARNING = '\033[93m'
 +    FAIL = '\033[91m'
 +    ENDC = '\033[0m'
 +    BOLD = '\033[1m'
 +    UNDERLINE = '\033[4m'
 +
 +def main():
 +    global glNameNewImport
 +
 +    #
 +    # -= IP адрес хоста =-
 +    getHostIP()
 +
 +    #
 +    # -= Имя нового инстанса =-
 +    getNameNewImport()
 +
 +    #
 +    # -= Ищем порты для нового инстанса (все) =-
 +    GetFreePorts()
 +
 +    #
 +    # -= Выбор мультипликатора =- 
 +    if SelectMultipl():
 +        # -= Ветка создания нового мультипл =-
 +        createNewMultip()
 +        
 +        # Создаем входящую директорию
 +        CreateFolder("/tank/IN/"+ glSelectedMultip.replace('FileMultiplicator_', ''))
 +        
 +        # Шарим ее по самбе
 +        addSambaShared("/tank/IN/"+ glSelectedMultip.replace('FileMultiplicator_', ''))
 +    else:
 +        # -= Использование существующего =-
 +        useExistMultip()
 +
 +    #
 +    # Переходим к импорту
 +    # -= Создаем входящую папку импорта и папки для ошибок =-
 +    CreateFolder("/tank/MGA_IN/IN_"+ glNameNewImport)
 +    CreateFolder("/tank_storage/dberrors/DBERROR_"+ glNameNewImport)
 +    CreateFolder("/tank_storage/septics/SEPTIC_"+ glNameNewImport)
 +
 +    #
 +    # -= Создаем копированием новый импорт, пишем ему параметры =-
 +    createNewImport()
 +
 +    print("""\n\033[92mНовый импорт успешно создан!\033[0m
 +Параметры следующие:
 +    Имя: \033[92m'"""+ glNameNewImport+"""'\033[0m
 +    Расположение: \033[92m'/tank/BIN/MgaImport/MgaImport_"""+ glNameNewImport+"""'\033[0m
 +    Входящая директория: \033[92m'/tank/MGA_IN/IN_"""+ glNameNewImport+"""'\033[0m
 +    Jmx-порт: \033[92m'"""+ glDictFreePorts['ImportJmxPort']+"""'\033[0m
 +    Командный порт: \033[92m'"""+ glDictFreePorts['ImportCommandPort']+"""'\033[0m
 +    Конфигурация импорта: \033[92m'/tank/BIN/MgaImport/MgaImport_"""+ glNameNewImport+"""/properties/mgaimport.toml'\033[0m
 +    Общая конфигурация всех импортов: \033[92m'/tank/BIN/MgaImport/app.conf'\033[0m
 +    Файл мультипликатор: \033[92m'/tank/BIN/FileMultiplicators/"""+ glSelectedMultip+"""'\033[0m
 +Укажите \033[96mпараметры импорта в БД\033[0m в файле конфигурации импорта
 +Используя Jmx-порт, создайте самостоятельно \033[96mмониторинг в Zabbix\033[0m, при необходимости\n""")
 +
 +def getNameNewImport():
 +    """ Ввод имени импорта пользователем
 +    """
 +    global glNameNewImport
 +
 +    glNameNewImport= input("\nВведите имя для нового импорта: ").replace(' ', '')
 +    if len(glNameNewImport)== 0:
 +        print(bcolors.FAIL+ "Вы не указали имя новому сервису, не надо так :("+ bcolors.ENDC)
 +        exit(1)
 +
 +    # Проверим уникальность имени
 +    existImports= subprocess.run('cat /tank/BIN/MgaImport/app.conf | grep -Poi "WORKSPACE=.*MgaImport_\K.*"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +    if glNameNewImport in existImports:
 +        print(bcolors.FAIL+ "Импорт с таким именем уже существует"+ bcolors.ENDC)
 +        exit(1)
 +
 +def createNewImport():
 +    """ Создание нового импорта
 +    """
 +    global glNameNewImport, glDictFreePorts, glHostIP
 +    
 +    # Копированием создаем сам новый мультип
 +    subprocess.run('cp -r ClearImport /tank/BIN/MgaImport/MgaImport_'+ glNameNewImport, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
 +    
 +    # Меняем права доступа юзеру mgaimport
 +    subprocess.run('chown -R mgaimport:mgaimport /tank/BIN/MgaImport/MgaImport_'+ glNameNewImport, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
 +    
 +    # Пишем параметры в "cmd.properties"
 +    Configuration= subprocess.run("cat /tank/BIN/MgaImport/MgaImport_"+glNameNewImport +"/cmd.properties", shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout
 +    
 +    Configuration= Configuration.replace('%JmxPort%', glDictFreePorts['ImportJmxPort'])
 +    Configuration= Configuration.replace('%CommandPort%', glDictFreePorts['ImportCommandPort'])
 +    Configuration= Configuration.replace('%ImportName%', glNameNewImport)
 +
 +    multipConfig= open("/tank/BIN/MgaImport/MgaImport_"+glNameNewImport +"/cmd.properties", "w", encoding='utf-8')
 +    multipConfig.write(Configuration)
 +    multipConfig.close()
 +
 +    # Пишем параметры в "./properties/mgaimport.toml"
 +    Configuration= subprocess.run("cat /tank/BIN/MgaImport/MgaImport_"+glNameNewImport +"/properties/mgaimport.toml", shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout
 +
 +    Configuration= Configuration.replace('%InputDir%', "/tank/MGA_IN/"+ glNameNewImport)
 +    Configuration= Configuration.replace('%SepticDir%', "/tank_storage/septics/SEPTIC_"+ glNameNewImport)
 +    Configuration= Configuration.replace('%DBErrorDir%', "/tank_storage/dberrors/DBERROR_"+ glNameNewImport)
 +    Configuration= Configuration.replace('%CommandPort%', glDictFreePorts['ImportCommandPort'])
 +
 +    multipConfig= open("/tank/BIN/MgaImport/MgaImport_"+glNameNewImport +"/properties/mgaimport.toml", "w", encoding='utf-8')
 +    multipConfig.write(Configuration)
 +    multipConfig.close()
 +
 +    # Делаем запись о новом мультипе в общем конфиге
 +    newText= """\n["""+glNameNewImport +"""]
 +#---------------------------------------- 1
 +  ENABLE="true"
 +  JAVA_HOME=/usr/lib/jvm/bellsoft-java14-full.x86_64/bin
 +  START_USER=mgaimport
 +  START_TIME=30
 +  STOP_TIME=90
 +  COMMAND_PORT="""+glDictFreePorts['ImportCommandPort'] +"""
 +  WORKSPACE=/tank/BIN/MgaImport/MgaImport_"""+glNameNewImport +"""
 +
 +  CMD='java -XX:+UnlockExperimentalVMOptions
 +  -XX:+UseG1GC
 +  -XX:+DisableExplicitGC
 +  -Xmx16G
 +  -Xms3G
 +  -XX:InitiatingHeapOccupancyPercent=75
 +  -XX:G1NewSizePercent=1
 +  -XX:G1MaxNewSizePercent=15
 +  -XX:G1MixedGCLiveThresholdPercent=90
 +  -XX:G1HeapWastePercent=5
 +  -XX:G1ReservePercent=1
 +  -XX:+ExplicitGCInvokesConcurrent
 +  -XX:+HeapDumpOnOutOfMemoryError
 +  -XX:HeapDumpPath="/tank/BIN/MgaImport/MgaImport_"""+glNameNewImport +"""/out_of_memory_dump/dump.hprof"
 +  -XX:-OmitStackTraceInFastThrow
 +  -Dcom.sun.management.jmxremote
 +  -Dcom.sun.management.jmxremote.port="""+glDictFreePorts['ImportJmxPort'] +"""
 +  -Dcom.sun.management.jmxremote.authenticate=false
 +  -Dcom.sun.management.jmxremote.ssl=false
 +  -Djava.rmi.server.hostname="""+glHostIP +"""
 +  -Djava.net.preferIPv4Stack=true
 +  -jar mgaimport.jar'\n"""
 +
 +    configFile= open("/tank/BIN/MgaImport/app.conf", "a", encoding='utf-8')
 +    configFile.write(newText)
 +    configFile.close()
 +
 +def getHostIP():
 +    """ Получаем IP адрес хоста
 +    """
 +    global glHostIP
 +
 +    # Получаем перечень ИПшников в системе
 +    haveList= []
 +    haveList= subprocess.run('ip a | grep -Po "inet \K[^/]*" | grep -v "127.0.0.1"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +
 +    # Если не удалось, просим ввести вручную, если несколько, просим выбрать
 +    if len(haveList) == 0:
 +        glHostIP= input('\nНе найден IP адрес хоста, укажите вручную: ').replace(' ', '')
 +        if len(glHostIP)== 0:
 +            print(bcolors.FAIL+ "Вы не указали IP адрес хоста, не надо так :("+ bcolors.ENDC)
 +            exit(1)
 +    elif len(haveList) == 1:
 +        glHostIP= haveList[0]
 +    else:
 +        print("\nНайдено несколько IP адресов:")
 +        showList= {}
 +        i= 1
 +        for itemIP in haveList:
 +            showList[i] = itemIP 
 +            i += 1
 +        
 +        for x, y in showList.items():
 +            print(str(x) +" - "+ y)
 +
 +        SelectItem= input("\nВыберите актуальный: ")
 +        if not SelectItem.isdigit():
 +            print(bcolors.FAIL+ "Указано некорректное значение :("+ bcolors.ENDC)
 +            exit(1)
 +        
 +        glHostIP= showList[int(SelectItem)]
 +
 +    print(bcolors.OKGREEN+ "\nIP адрес хоста - "+ glHostIP+ bcolors.ENDC)
 +
 +
 +
 +def addSambaShared(fullPath):
 +    """ Добавляем шаринг папки в конфиг самбы
 +        Параметры дефолтные (для импортов)
 +    """
 +    # Добавляем запись о новой шаре в конфиг самбы 
 +    newText= """\n["""+fullPath.split('/')[-1] +"""]
 +path = """+fullPath +"""
 +guest ok = no
 +browsable = no
 +writeable = yes
 +create mask = 0770
 +directory mask = 0770
 +write list = xlogssupplier
 +valid users = xlogssupplier
 +force user = mgaimport
 +force group = mgaimport\n"""
 +    
 +    configFile= open("/etc/samba/smb.conf", "a", encoding='utf-8')
 +    configFile.write(newText)
 +    configFile.close()
 +    
 +    # Перезапускаем самбу
 +    subprocess.run('systemctl restart smb', shell=True)
 +    
 +    # Напоминаем пользователю что нужно примонтировать ее на источнике источника 
 +    print("""\033[91m   Внимание!\033[0m
 +    Создана входящая папка для файлмультипликатора \033[96m'"""+ fullPath+ """'\033[0m
 +    К ней \033[96mоткрыт сетевой доступ\033[0m через "smb", \033[96mее необходимо примонтировать\033[0m на сервере "лог-дистрибьютора" (либо какой то другой источник) для получения входящих логов""")
 +
 +
 +
 +def createNewMultip():
 +    """ Создание нового мультипа
 +    """
 +    global glNameNewImport, glSelectedMultip, glDictFreePorts, glHostIP
 +    
 +    # Копированием создаем сам новый мультип
 +    subprocess.run('cp -r ClearFileMultiplicator /tank/BIN/FileMultiplicators/'+ glSelectedMultip, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
 +    
 +    # Меняем права доступа юзеру mgaimport
 +    subprocess.run('chown -R mgaimport:mgaimport /tank/BIN/FileMultiplicators/'+ glSelectedMultip, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
 +    
 +    # Пишем параметры в конфиг нового мультипа
 +    Configuration= subprocess.run("cat /tank/BIN/FileMultiplicators/"+glSelectedMultip +"/FileMultiplicator.toml", shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout
 +    
 +    Configuration= Configuration.replace('%InputDir%', '"/tank/IN/'+ glSelectedMultip.replace('FileMultiplicator_', '') +'"')
 +    Configuration= Configuration.replace('%CommandPort%', glDictFreePorts['MultipCommandPorts'])
 +    Configuration= Configuration.replace('%ImportName%', glNameNewImport)
 +    Configuration= Configuration.replace('%ImportPath%', '"/tank/MGA_IN/in_'+ glNameNewImport +'"')
 +        
 +    multipConfig= open("/tank/BIN/FileMultiplicators/"+glSelectedMultip +"/FileMultiplicator.toml", "w", encoding='utf-8')
 +    multipConfig.write(Configuration)
 +    multipConfig.close()
 +
 +    # Делаем запись о новом мультипе в общем конфиге
 +    newText= """\n["""+glSelectedMultip +"""]
 +# ----------------------------------- 
 +  ENABLE="true"
 +  JAVA_HOME=/usr/lib/jvm/bellsoft-java14-full.x86_64/bin
 +  START_USER=mgaimport
 +  START_TIME=5
 +  STOP_TIME=10
 +  WORKSPACE=/tank/BIN/FileMultiplicators/"""+glSelectedMultip +"""
 +
 +  CMD='java
 +  -XX:+UnlockExperimentalVMOptions
 +  -XX:+UseG1GC
 +  -XX:+DisableExplicitGC
 +  -Xmx2G
 +  -Dcom.sun.management.jmxremote
 +  -Dcom.sun.management.jmxremote.port="""+glDictFreePorts['MultipJmxPort'] +"""
 +  -Dcom.sun.management.jmxremote.authenticate=false
 +  -Dcom.sun.management.jmxremote.ssl=false
 +  -Djava.rmi.server.hostname="""+glHostIP +"""
 +  -Djava.net.preferIPv4Stack=true
 +  -jar filemultiplicator-all.jar'\n"""
 +    
 +    configFile= open("/tank/BIN/FileMultiplicators/app.conf", "a", encoding='utf-8')
 +    configFile.write(newText)
 +    configFile.close()
 +
 +def useExistMultip():
 +    """ Использование существующего мультипа, 
 +        дописываем в его конфиг блок по новому импорту
 +    """
 +    global glNameNewImport, glSelectedMultip
 +    
 +    newText= """\n[[DestDir]]
 +        name = \""""+glNameNewImport +"""\"
 +        destDir = "/tank/MGA_IN/in_"""+glNameNewImport +""""
 +        pattern = "^.*$"\n"""
 +    
 +    configFile= open("/tank/BIN/FileMultiplicators/"+glSelectedMultip +"/FileMultiplicator.toml", "a", encoding='utf-8')
 +    configFile.write(newText)
 +    configFile.close()
 +    
 +    # Перезапуск сервиса, для принятия изменений
 +    os.system('/bin/bash /tank/BIN/FileMultiplicators/'+glSelectedMultip +'/restart.sh')
 +    os.system('/bin/bash /tank/BIN/FileMultiplicators/'+glSelectedMultip +'/status.sh')
 +
 +def SelectMultipl():
 +    """ Выбор мультипликатора (в т.ч. создание нового)
 +    """  
 +    global glSelectedMultip
 +
 +    # Перечень мультипликаторов с путями из общешго конфига
 +    listMultiplLocate= subprocess.run('cat /tank/BIN/FileMultiplicators/app.conf | grep "WORKSPACE" | grep -Po "/.*"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +
 +    # Проходим циклом, из конфига каждого мультип берем параметр "srcDir", и делаем сопоставление в словаре
 +    availableMultiples= {}
 +    i= 1
 +    listNamesForCheckUnique= []
 +    for itemLocate in listMultiplLocate:
 +        availableMultiples[i] = {
 +            'HomeDir': itemLocate.split('/')[-1], 
 +            'SrcDir': subprocess.run('cat '+ itemLocate +'/FileMultiplicator.toml | grep srcDir | grep -Po "\\".*\\""', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()[0] }
 +        i += 1
 +        listNamesForCheckUnique.append(itemLocate.split('/')[-1])
 +
 +    # Выводм перечеь доступных мультипликаторов пользователю, для выбора
 +    print("\nВыберите "+bcolors.OKCYAN +"существующий"+bcolors.ENDC+" файлмультипликатор, либо создайте "+bcolors.OKCYAN+"новый"+bcolors.ENDC+", исходя из источника данных:")
 +    print("0: Создать новый файлмультипликатор")
 +    for x, y in availableMultiples.items():
 +        print(str(x) +": "+ y['HomeDir'] +';  srcDir: '+ y['SrcDir'])
 +    
 +    SelectItem= input("\nВыберите действие: ")
 +    if not SelectItem.isdigit():
 +        print(bcolors.FAIL+ "Указано некорректное значение :("+ bcolors.ENDC)
 +        exit(1)
 +    
 +    # Выбирается мультип либо создание нового если выбран 0 (или вне диапазона)
 +    if int(SelectItem) in availableMultiples:
 +        glSelectedMultip= availableMultiples[int(SelectItem)]['HomeDir']
 +        return 0
 +    else:
 +        glSelectedMultip= 'FileMultiplicator_'+ input("Укажите название новому файлмультипликатору: "+bcolors.OKCYAN +"FileMultiplicator_").replace(' ', '')
 +        print(bcolors.ENDC)
 +        if glSelectedMultip== 'FileMultiplicator_':
 +            print(bcolors.FAIL+ "Вы не указали имя новому сервису, не надо так :("+ bcolors.ENDC)
 +            exit(1)
 +        elif glSelectedMultip in listNamesForCheckUnique:
 +            print(bcolors.FAIL+ "Сервис с таким именем уже существует"+ bcolors.ENDC)
 +            exit(1)
 +        return 1
 +
 +def CreateFolder(fullPath):
 +    """ Создаем указанную директорию, сразу назначаем пользователя и права
 +    """
 +    result= subprocess.run('install -d -m 775 -o mgaimport -g mgaimport '+ fullPath, shell=True)
 +    if result.returncode: 
 +        if input("\nОшибка при создании директории, можете создать вручную. Важно задать доступ пользователю mgaimport\nПродолжить скрипт? ")!= 'y':
 +            exit(1)
 +
 +def GetFreePorts():
 +    """ Подбираем свободные порты (Командный + Jmx) для нового инстанса
 +    """
 +    global glDictFreePorts
 +    
 +    # Мультипликатор
 +        # Команный порт
 +    MultipCommandPorts= subprocess.run('cat /tank/BIN/FileMultiplicators/*/FileMultiplicator.toml | grep "listeningCommandPort" | grep -Po "\d*"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +    glDictFreePorts['MultipCommandPorts'] = FindFreePort(MultipCommandPorts, 5550)
 +
 +        # Jmx порт
 +    MultipJmxPorts= subprocess.run('cat /tank/BIN/FileMultiplicators/app.conf | grep "jmxremote.port" | grep -Po "\d*"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +    glDictFreePorts['MultipJmxPort']= FindFreePort(MultipJmxPorts, 10040)
 +
 +    # Импорт
 +        # Команный порт
 +    ImportCommandPorts= subprocess.run('cat /tank/BIN/MgaImport/app.conf | grep "COMMAND_PORT" | grep -Po "\d*"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +    glDictFreePorts['ImportCommandPort']= FindFreePort(ImportCommandPorts, 6660)
 +
 +        # Jmx порт
 +    ImportJmxPorts= subprocess.run('cat /tank/BIN/MgaImport/app.conf | grep "jmxremote.port" | grep -Po "\d*"', shell=True, stdout=subprocess.PIPE, encoding='utf-8').stdout.split()
 +    glDictFreePorts['ImportJmxPort']= FindFreePort(ImportJmxPorts, 10050)
 +    
 +def FindFreePort(listExistPorts, defaultNewPort):
 +    """ Ищем новый свободный порт.
 +        Передаем сюда список используемых, ищем наибольший, увеличиваем его на единицу
 +        Если список пуст, используем начальный, выбор начального передается сюда же
 +    """
 +    if len(listExistPorts)== 0:
 +        return str(defaultNewPort)
 +    else:
 +        listExistPorts.sort(reverse=True)
 +        return str(int(listExistPorts[0])+ 1)
 +
 +if __name__ == "__main__":
 +    main()
 +</code>
 +</details>
 +
 +
 +
 +===== Кодировка =====
 +[[https://chase-seibert.github.io/blog/2014/01/12/python-unicode-console-output.html|На счет вывода]]\\
 +
 +<details>
 +<summary>:!: Кодировка</summary>
 +<code python>
 +  # При открытии файла
 +with open(my_file, 'r', encoding="utf-8") as raw_input_log:
 +...
 +
 +  # Так же проблема может возникнуть при записи в консоль
 +# Ошибка "UnicodeEncodeError: 'ascii' codec can't encode character"
 +# Смысл в том что python путает какую кодировку принимает консоль, нужно установить ее явно
 +# можно установить через переменную окружения, напирмер перед запуском скрипта
 +set PYTHONIOENCODING=UTF-8 & python make_backup.py
 +
 +</code>
 +</details>
 +
 +
 +
 +===== Ошибка при отсутствии lxml =====
 +Была трабла при ее установке, как вариант эти пару команд\\
 +<code bash>
 +yum install python-devel
 +pip3 install -U pip setuptools
 +python3 -m pip install lxml
 +</code>
 +
 +
 +
 +===== Ошибка при отсутствии lxml =====
 +
 +<details>
 +<summary>:!:  </summary>
 +<code python>
 +
 +</code>
 +</details>
  
develop/pyton/sqlite.1656837885.txt.gz · Последнее изменение: 2022/07/03 08:44 — admin