Commit eb4e16dcdfc4bbb2214151e9a066ac21fe6e4d75
0 parents
Exists in
master
Merge do Super Gerente para trunk
git-svn-id: http://svn.softwarepublico.gov.br/svn/cacic/cacic/trunk/integrador@1607 fecfc0c7-e812-0410-ae72-849f08638ee7
Showing
16 changed files
with
436 additions
and
0 deletions
Show diff stats
| 1 | +++ a/LICENSE |
| 1 | +++ a/development.ini | ||
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +[WSCBot] | ||
| 2 | +###Url de acesso ao modulo wscserver (terminar com '/') | ||
| 3 | +url_wscserver: http://http://10.209.8.39/wscserver/ | ||
| 4 | + | ||
| 5 | +###Url de acesso ao Super Gerente | ||
| 6 | +ip_superg: http://10.209.8.39/lbbulk/reg | ||
| 7 | + | ||
| 8 | +###Local do disco onde o arquivo será salvo temporariamente | ||
| 9 | +filepath: /tmp/extract/ | ||
| 10 | + | ||
| 11 | +###Nome de usuário | ||
| 12 | +username: rest | ||
| 13 | + | ||
| 14 | +###senha do usuário | ||
| 15 | +senha: rest | ||
| 16 | + | ||
| 17 | +###data da coleta | ||
| 18 | +data: 01-01-1970 | ||
| 19 | + | ||
| 20 | +###Tempo entre as leituras em busca de registros (em segundos) | ||
| 21 | +sleep_time: 86400 | ||
| 22 | + | ||
| 23 | +[Daemon] | ||
| 24 | +stdin_path = /dev/null | ||
| 25 | +stdout_path = /dev/tty | ||
| 26 | +stderr_path = /dev/tty | ||
| 27 | +pidfile_path = /var/run/wscbot.pid | ||
| 28 | +logfile_path = /var/log/wscbot.log | ||
| 29 | +pidfile_timeout = 5 |
| 1 | +++ a/production.ini | ||
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +[WSCBot] | ||
| 2 | +###Url de acesso ao modulo wscserver (terminar com '/') | ||
| 3 | +url_wscserver: http://10.209.8.39/wscserver/ | ||
| 4 | + | ||
| 5 | +###Url de acesso ao Super Gerente | ||
| 6 | +ip_superg: http://10.209.8.39/lbbulk/reg | ||
| 7 | + | ||
| 8 | +###Local do disco onde o arquivo será salvo temporariamente | ||
| 9 | +filepath: /tmp/extract/ | ||
| 10 | + | ||
| 11 | +###Nome de usuário | ||
| 12 | +username: rest | ||
| 13 | + | ||
| 14 | +###senha do usuário | ||
| 15 | +senha: rest | ||
| 16 | + | ||
| 17 | +###data da coleta | ||
| 18 | +data: 01-01-1970 | ||
| 19 | + | ||
| 20 | +###Tempo entre as leituras em busca de registros (em segundos) | ||
| 21 | +sleep_time: 3600 | ||
| 22 | + | ||
| 23 | +[Daemon] | ||
| 24 | +stdin_path = /dev/null | ||
| 25 | +stdout_path = /dev/tty | ||
| 26 | +stderr_path = /dev/tty | ||
| 27 | +pidfile_path = /var/run/wscbot.pid | ||
| 28 | +logfile_path = /var/log/wscbot.log | ||
| 29 | +pidfile_timeout = 5 |
| 1 | +++ a/setup.py | ||
| @@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
| 1 | +from setuptools import setup, find_packages | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +requires = [ | ||
| 5 | + 'ConfigParser', | ||
| 6 | + 'requests', | ||
| 7 | + 'lockfile', | ||
| 8 | + 'python-daemon', | ||
| 9 | + 'simplejson' | ||
| 10 | + ] | ||
| 11 | + | ||
| 12 | +setup( | ||
| 13 | + name = "WSCBot", | ||
| 14 | + version = "0.1.3", | ||
| 15 | + author = "Lightbase", | ||
| 16 | + author_email = "breno.brito@lightbase.com.br", | ||
| 17 | + url = "https://pypi.python.org/pypi/LBConverter", | ||
| 18 | + description = "Daemon Converter for the neo-lightbase service", | ||
| 19 | + license = "GPLv2", | ||
| 20 | + keywords = "Converter extractor lightbase daemon", | ||
| 21 | + install_requires=requires, | ||
| 22 | + packages=find_packages(), | ||
| 23 | + classifiers=[ | ||
| 24 | + "Development Status :: 2 - Pre-Alpha", | ||
| 25 | + "Environment :: No Input/Output (Daemon)", | ||
| 26 | + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", | ||
| 27 | + "Natural Language :: Portuguese (Brazilian)", | ||
| 28 | + "Programming Language :: Python :: 3.2", | ||
| 29 | + "Topic :: Database :: Database Engines/Servers", | ||
| 30 | + ] | ||
| 31 | +) |
| 1 | +++ a/wscbot/__init__.py |
| 1 | +++ a/wscbot/__main__.py | ||
| @@ -0,0 +1,102 @@ | @@ -0,0 +1,102 @@ | ||
| 1 | +#!/usr/bin/python | ||
| 2 | +# -*- coding: utf-8 -*- | ||
| 3 | +import logging | ||
| 4 | +import time | ||
| 5 | +import os | ||
| 6 | +import ConfigParser | ||
| 7 | + | ||
| 8 | +from daemon import runner | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +from app import main | ||
| 12 | + | ||
| 13 | +#exceptions | ||
| 14 | +from requests.exceptions import * | ||
| 15 | +import zipfile | ||
| 16 | +import lockfile | ||
| 17 | + | ||
| 18 | +ini_path='/srv/bot-super-gerente/WSCBot/production.ini' | ||
| 19 | +#absolute path to .ini file | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +def setconfig(config_file): | ||
| 24 | + """Função que conecta o modulo ao arquivo de configurações""" | ||
| 25 | + | ||
| 26 | + config_file = os.path.abspath(config_file) | ||
| 27 | + config = ConfigParser.ConfigParser() | ||
| 28 | + config.read(config_file) | ||
| 29 | + user = {} | ||
| 30 | + user['url_wscserver'] = config.get('WSCBot', 'url_wscserver') | ||
| 31 | + user['filepath'] = config.get('WSCBot', 'filepath') | ||
| 32 | + user['username'] = config.get('WSCBot', 'username') | ||
| 33 | + user['senha'] = config.get('WSCBot', 'senha') | ||
| 34 | + user['data'] = config.get('WSCBot', 'data') | ||
| 35 | + user['ip_superg'] = config.get('WSCBot', 'ip_superg') | ||
| 36 | + user['sleep_time'] = int(config.get('WSCBot', 'sleep_time')) | ||
| 37 | + user['stdin_path'] = config.get('Daemon', 'stdin_path') | ||
| 38 | + user['stdout_path'] = config.get('Daemon', 'stdout_path') | ||
| 39 | + user['stderr_path'] = config.get('Daemon', 'stderr_path') | ||
| 40 | + user['pidfile_path'] = config.get('Daemon', 'pidfile_path') | ||
| 41 | + user['logfile_path'] = config.get('Daemon', 'logfile_path') | ||
| 42 | + user['pidfile_timeout'] = int(config.get('Daemon', 'pidfile_timeout')) | ||
| 43 | + return user | ||
| 44 | + | ||
| 45 | +class App(): | ||
| 46 | + | ||
| 47 | + def __init__(self): | ||
| 48 | + self.stdin_path = user['stdin_path'] | ||
| 49 | + self.stdout_path = user['stdout_path'] | ||
| 50 | + self.stderr_path = user['stderr_path'] | ||
| 51 | + self.pidfile_path = user['pidfile_path'] | ||
| 52 | + self.pidfile_timeout = user['pidfile_timeout'] | ||
| 53 | + | ||
| 54 | + def run(self): | ||
| 55 | + logger.info ('Iniciando modulo WSCBot') | ||
| 56 | + while True: | ||
| 57 | + timeron = time.time() | ||
| 58 | + logger.info ('Iniciando execução') | ||
| 59 | + try: | ||
| 60 | + main(ip_servidor,username,senha,ip_superg,filepath,data) | ||
| 61 | + except (ConnectionError, Timeout): | ||
| 62 | + logger.error ('Não foi possivel estabelecer conexão com o servidor! ' + domain) | ||
| 63 | + except zipfile.BadZipfile: | ||
| 64 | + logger.error ('Arquivo zip gerado pelo WSCServer invalido ou corrompido') | ||
| 65 | + except Exception as erro: | ||
| 66 | + logger.error (erro) | ||
| 67 | + timeronff = time.time() | ||
| 68 | + tempo = (timeronff - timeron) | ||
| 69 | + m, s = divmod(sleep_time, 60) | ||
| 70 | + h, m = divmod(m, 60) | ||
| 71 | + next = "%d:%02d:%02d" % (h, m, s) | ||
| 72 | + logger.debug ('Execução durou ' + str(tempo) + ' segundos.') | ||
| 73 | + logger.info ('Proxima execução em: ' + next) | ||
| 74 | + time.sleep(sleep_time) | ||
| 75 | + | ||
| 76 | +user = setconfig(ini_path) | ||
| 77 | +ip_servidor = user['url_wscserver'] | ||
| 78 | +senha = user['senha'] | ||
| 79 | +ip_superg = user['ip_superg'] | ||
| 80 | +sleep_time = user['sleep_time'] | ||
| 81 | +username = user['username'] | ||
| 82 | +filepath = user['filepath'] | ||
| 83 | +data = user['data'] | ||
| 84 | +app = App() | ||
| 85 | +logger = logging.getLogger("WSCBot") | ||
| 86 | +logger.setLevel(logging.INFO) # Alterar para logging.INFO em produção | ||
| 87 | +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') | ||
| 88 | +handler = logging.FileHandler(user['logfile_path']) | ||
| 89 | +handler.setFormatter(formatter) | ||
| 90 | +logger.addHandler(handler) | ||
| 91 | + | ||
| 92 | +daemon_runner = runner.DaemonRunner(app) | ||
| 93 | +#This ensures that the logger file handle does not get closed during daemonization | ||
| 94 | +daemon_runner.daemon_context.files_preserve=[handler.stream] | ||
| 95 | +try: | ||
| 96 | + daemon_runner.do_action() | ||
| 97 | +except (KeyboardInterrupt, SystemExit): | ||
| 98 | + raise | ||
| 99 | +except lockfile.LockTimeout: | ||
| 100 | + print "\nErro: Já existe uma instância desse modulo em execução\n" | ||
| 101 | +except runner.DaemonRunnerStopFailureError: | ||
| 102 | + print "\nErro: Não existe nenhuma instância desse módulo em execução\n" |
| 1 | +++ a/wscbot/app.py | ||
| @@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
| 1 | + # -*- coding: utf-8 -*- | ||
| 2 | +"""Autor: Breno Rodrigues Brito""" | ||
| 3 | +import json | ||
| 4 | + | ||
| 5 | +from requests import put, post | ||
| 6 | +import logging | ||
| 7 | + | ||
| 8 | +from wscbot.scripts import req | ||
| 9 | +from wscbot.scripts import pegachave | ||
| 10 | +from wscbot.scripts import erro | ||
| 11 | +from wscbot.scripts import rotinas | ||
| 12 | +from wscbot.scripts.zipparser import ziphandler | ||
| 13 | + | ||
| 14 | +def main(ip_servidor,username,senha,ip_superg,filepath,data): | ||
| 15 | + """ | ||
| 16 | + Envia uma requisição GET HTTP para o endereço cadastrado, | ||
| 17 | + fornecendo como parâmetros da requisição o usuário e senha informados; | ||
| 18 | + Pega a resposta da requisição e escreve num arquivo; | ||
| 19 | + Criptografa o conteúdo do arquivo com base em uma chave compartilhada com o Super Gerente; | ||
| 20 | + Envia o arquivo criptografado para o Super Gerente; | ||
| 21 | + Registra a data do envio e o resultado da comunicação. | ||
| 22 | + """ | ||
| 23 | + | ||
| 24 | + # Faz a requisição do arquivo zip | ||
| 25 | + zip_path = req.req(ip_servidor, filepath) | ||
| 26 | + | ||
| 27 | + dicionario = ziphandler(zip_path) | ||
| 28 | + for arquivo in dicionario: | ||
| 29 | + logger.debug('Inicio do envio de dados') | ||
| 30 | + coleta = json.loads(dicionario[arquivo])['results'] | ||
| 31 | + for registro in coleta: | ||
| 32 | + registro = json.dumps(registro) | ||
| 33 | + | ||
| 34 | + f = post(ip_superg,data={'json_reg':registro}) | ||
| 35 | + erro.is_error_p(f) | ||
| 36 | + | ||
| 37 | +logger = logging.getLogger("WSCBot") |
| 1 | +++ a/wscbot/model/__init__.py |
| 1 | +++ a/wscbot/scripts/__init__.py |
| 1 | +++ a/wscbot/scripts/erro.py | ||
| @@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | +"""Autor: Breno Rodrigues Brito""" | ||
| 3 | +import logging | ||
| 4 | +import simplejson # for exception | ||
| 5 | + | ||
| 6 | +def is_error_p(resp): | ||
| 7 | + """verifica erros do post""" | ||
| 8 | + try: | ||
| 9 | + json = resp.json() | ||
| 10 | + except simplejson.decoder.JSONDecodeError: | ||
| 11 | + msg = 'not found' | ||
| 12 | + n_err = str(resp.status_code) | ||
| 13 | + logger.error(n_err + ': ' + msg) | ||
| 14 | + else: | ||
| 15 | + try: | ||
| 16 | + a = len(json) | ||
| 17 | + except TypeError: | ||
| 18 | + id_reg = str(json) | ||
| 19 | + logger.info('Escrito com sucesso id_reg: ' + id_reg) | ||
| 20 | + else: | ||
| 21 | + msg = json['_error_message'] | ||
| 22 | + n_err = str(json['_status']) | ||
| 23 | + logger.error(n_err + ': ' + msg) | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +def is_error_g(recebe): | ||
| 27 | + """Verifica erros do GET""" | ||
| 28 | + | ||
| 29 | + num_er = recebe.__dict__['status_code'] | ||
| 30 | + msg = recebe.__dict__['reason'] | ||
| 31 | + | ||
| 32 | + if num_er > 199 and num_er < 300: | ||
| 33 | + logger.debug('Recebido com sucesso.') | ||
| 34 | + else: | ||
| 35 | + logger.error(str(num_err) + ': ' + msg) | ||
| 36 | + | ||
| 37 | + | ||
| 38 | +logger = logging.getLogger("WSCBot") | ||
| 0 | \ No newline at end of file | 39 | \ No newline at end of file |
| 1 | +++ a/wscbot/scripts/pegachave.py | ||
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | +"""Autor: Breno Rodrigues Brito""" | ||
| 3 | +from requests import get | ||
| 4 | + | ||
| 5 | +def pegachave(domain,username,senha): | ||
| 6 | + """Envia uma requisição GET HTTP para o endereço cadastrado, | ||
| 7 | + fornecendo como parâmetros da requisição o usuário e senha informados;""" | ||
| 8 | + | ||
| 9 | + payload = {'user' : 'username', | ||
| 10 | + 'pass' : 'senha'} | ||
| 11 | + | ||
| 12 | + recebe = get(domain, data=payload) | ||
| 13 | + # jsonfull = recebe.json() | ||
| 14 | + # bases = jsonfull["results"] | ||
| 15 | + chave = t_dados(recebe) | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + return chave | ||
| 19 | + |
| 1 | +++ a/wscbot/scripts/req.py | ||
| @@ -0,0 +1,48 @@ | @@ -0,0 +1,48 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | +"""Autor: Breno Rodrigues Brito""" | ||
| 3 | +# from requests import get | ||
| 4 | +import urllib | ||
| 5 | +import logging | ||
| 6 | +import os | ||
| 7 | + | ||
| 8 | +from wscbot.scripts.erro import is_error_g | ||
| 9 | +from wscbot.scripts.tratamento import t_dados | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +def download_file(url, filepath): | ||
| 13 | + """Baixa o arquivo de coleta na url indicada""" | ||
| 14 | + | ||
| 15 | + if not os.path.isdir(filepath): | ||
| 16 | + os.mkdir(filepath) | ||
| 17 | + local_filename = filepath + "coleta.zip" | ||
| 18 | + urllib.urlretrieve(url, local_filename) | ||
| 19 | + return local_filename | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +def req(domain,filepath): #Recebia domain e data | ||
| 23 | + """Envia uma requisição GET HTTP para o endereço cadastrado, | ||
| 24 | + fornecendo como parâmetros da requisição o usuário e senha informados;""" | ||
| 25 | + | ||
| 26 | + # payload = {'user' : 'username', | ||
| 27 | + # 'pass' : 'senha'} | ||
| 28 | + logger.debug('Mandando requisição') | ||
| 29 | + url = domain + 'zip/coleta' | ||
| 30 | + | ||
| 31 | + # values = {'data_coleta':data} | ||
| 32 | + | ||
| 33 | + arquivo_coleta = download_file(url,filepath) # , param=values | ||
| 34 | + arquivo_coleta = os.path.abspath(arquivo_coleta) | ||
| 35 | + | ||
| 36 | + # ATENCAO!!! | ||
| 37 | + # tem de se testar se o data precisa de encoding!! | ||
| 38 | + | ||
| 39 | + # funcionava para o módulo requests | ||
| 40 | + # Não sei como fazer para o urllib | ||
| 41 | + # is_error_g(arquivo_coleta) | ||
| 42 | + | ||
| 43 | + return arquivo_coleta | ||
| 44 | + | ||
| 45 | +logger = logging.getLogger("WSCBot") | ||
| 46 | + | ||
| 47 | +# zip para baixar e testar: | ||
| 48 | +# http://10.0.0.149/api/doc/arquivos/29/download | ||
| 0 | \ No newline at end of file | 49 | \ No newline at end of file |
| 1 | +++ a/wscbot/scripts/rotinas.py | ||
| @@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | +"""Autor: Breno Rodrigues Brito""" | ||
| 3 | +import logging | ||
| 4 | + | ||
| 5 | +def so(): | ||
| 6 | + """SO""" | ||
| 7 | + logger.debug('Iniciando a rotina SO') | ||
| 8 | + pass | ||
| 9 | + | ||
| 10 | +def software(): | ||
| 11 | + """software""" | ||
| 12 | + logger.debug('Iniciando a rotina software') | ||
| 13 | + pass | ||
| 14 | + | ||
| 15 | +def hardware(): | ||
| 16 | + """hardware""" | ||
| 17 | + logger.debug('Iniciando a rotina hardware') | ||
| 18 | + pass | ||
| 19 | + | ||
| 20 | +def software_basico(): | ||
| 21 | + """software_basico""" | ||
| 22 | + logger.debug('Iniciando a rotina software_basico') | ||
| 23 | + pass | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +logger = logging.getLogger("WSCBot") | ||
| 0 | \ No newline at end of file | 28 | \ No newline at end of file |
| 1 | +++ a/wscbot/scripts/xmlparser.py | ||
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | + | ||
| 3 | +""" | ||
| 4 | +Faz o parse do arquivo XML | ||
| 5 | + | ||
| 6 | +""" | ||
| 7 | +"""Autor: Breno Rodrigues Brito""" | ||
| 8 | +import xml.etree.ElementTree as ET | ||
| 9 | +# from xml.dom import minidom | ||
| 10 | + | ||
| 11 | +tree = ET.parse(pathtofile) | ||
| 12 | +root = tree.getroot() | ||
| 13 | + | ||
| 14 | +# xmldoc = minidom.parse('items.xml') | ||
| 15 | +# itemlist = xmldoc.getElementsByTagName('item') | ||
| 16 | +# print len(itemlist) | ||
| 17 | +# print itemlist[0].attributes['name'].value | ||
| 18 | +# for s in itemlist : | ||
| 19 | +# print s.attributes['name'].value |
| 1 | +++ a/wscbot/scripts/zipparser.py | ||
| @@ -0,0 +1,51 @@ | @@ -0,0 +1,51 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | +"""Autor: Breno Rodrigues Brito""" | ||
| 3 | + | ||
| 4 | +import zipfile | ||
| 5 | +import logging | ||
| 6 | +import tempfile | ||
| 7 | +import json | ||
| 8 | +import os | ||
| 9 | + | ||
| 10 | +from wscbot.scripts.tratamento import t_dados | ||
| 11 | + | ||
| 12 | +def ziphandler(filename): | ||
| 13 | + """ | ||
| 14 | + Receive a zip file and parse one file at a time, returning a collection of parsed files. | ||
| 15 | + """ | ||
| 16 | + # Create the zipfile object | ||
| 17 | + z_root = zipfile.ZipFile(filename) | ||
| 18 | + | ||
| 19 | + # Create a temp dir and unzip file contents | ||
| 20 | + tmp_dir = tempfile.mkdtemp() | ||
| 21 | + | ||
| 22 | + # registros = { | ||
| 23 | + # 'import_error' : [], | ||
| 24 | + # 'registros' : [] | ||
| 25 | + # } | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + # cria um dicionario | ||
| 29 | + for arquivo in z_root.namelist(): | ||
| 30 | + # This should be a list with a all the zip files | ||
| 31 | + #print('00000000000000000000000000000 %s' % arquivo) | ||
| 32 | + z_root.extract(arquivo,tmp_dir) | ||
| 33 | + | ||
| 34 | + # This is the file object for this registro | ||
| 35 | + # z = zipfile.ZipFile(os.path.join(tmp_dir,arquivo)) | ||
| 36 | + filepath = (os.path.join(tmp_dir,arquivo)) | ||
| 37 | + | ||
| 38 | + # Lê o arquivo string que vai conter o json | ||
| 39 | + with open(filepath) as f: | ||
| 40 | + string_json = f.read() | ||
| 41 | + | ||
| 42 | + # carrega o Json | ||
| 43 | + jsonfull = json.loads(string_json) | ||
| 44 | + jsonfull = t_dados(jsonfull) | ||
| 45 | + # cria um dicionario | ||
| 46 | + dicionario = {arquivo:jsonfull} | ||
| 47 | + | ||
| 48 | + return dicionario | ||
| 49 | + # lista de arquivos | ||
| 50 | + | ||
| 51 | +logger = logging.getLogger("WSCBot") |