Merge branch 'main' of https://git.myitr.org/Jukebox/jukebox-software
This commit is contained in:
commit
051cc1d003
11
Dockerfile
Normal file
11
Dockerfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
FROM python:latest
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y libgl1-mesa-glx ghostscript && apt-get clean && rm -rf /var/lib/apt/lists
|
||||||
|
COPY . .
|
||||||
|
#COPY config-server.yml config.yml
|
||||||
|
RUN pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
CMD ["python3", "run.py"]
|
||||||
|
EXPOSE 5000
|
||||||
|
EXPOSE 8000
|
||||||
|
EXPOSE 9000
|
166
banner_ivu_export.py
Executable file
166
banner_ivu_export.py
Executable file
@ -0,0 +1,166 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import socket
|
||||||
|
from datetime import datetime
|
||||||
|
from time import sleep
|
||||||
|
from util import fprint
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from: https://github.com/MoisesBrito31/ve_data_log/blob/main/serverContagem/VE/drive.py
|
||||||
|
(no license)
|
||||||
|
|
||||||
|
(partially) adapted to English language & iVu camera instead of classic VE by Cole Deck
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def gravaLog(ip="1",tipo="Evento", msg="", file="log_imagem.txt"):
|
||||||
|
# removed full logging
|
||||||
|
fprint(msg)
|
||||||
|
|
||||||
|
class DriveImg():
|
||||||
|
HEADERSIZE = 100
|
||||||
|
ip = "192.168.0.1"
|
||||||
|
port = 32200
|
||||||
|
onLine = False
|
||||||
|
|
||||||
|
def __init__(self, ip, port, pasta = "media/"):
|
||||||
|
self.pasta = pasta
|
||||||
|
self.ip=ip
|
||||||
|
self.port = port
|
||||||
|
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||||
|
self.trans.settimeout(5)
|
||||||
|
fprint("Trying to connect...")
|
||||||
|
try:
|
||||||
|
self.trans.connect((self.ip,self.port))
|
||||||
|
self.onLine = True
|
||||||
|
fprint("Camera Online")
|
||||||
|
#self.trans.close()
|
||||||
|
except:
|
||||||
|
self.onLine = False
|
||||||
|
fprint("Offline")
|
||||||
|
|
||||||
|
def read_img(self):
|
||||||
|
resposta = 'Falha'
|
||||||
|
try:
|
||||||
|
if not self.onLine:
|
||||||
|
#print(f'tentando Conectar camera {self.ip}...')
|
||||||
|
gravaLog(ip=self.ip,msg=f'Trying to connect...')
|
||||||
|
sleep(2)
|
||||||
|
try:
|
||||||
|
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||||
|
self.trans.connect((self.ip,self.PORT))
|
||||||
|
self.onLine = True
|
||||||
|
gravaLog(ip=self.ip,msg=f'Connection established.')
|
||||||
|
except:
|
||||||
|
self.onLine = False
|
||||||
|
self.trans.close()
|
||||||
|
return resposta
|
||||||
|
ret = self.trans.recv(64)
|
||||||
|
try:
|
||||||
|
valida = str(ret[0:15].decode('UTF-8'))
|
||||||
|
#print(valida)
|
||||||
|
if valida.find("TC IMAGE")<0:
|
||||||
|
self.onLine = False
|
||||||
|
self.trans.close()
|
||||||
|
sleep(2)
|
||||||
|
gravaLog(ip=self.ip,tipo="Falha",msg=f'Unable to find TC IMAGE bookmark')
|
||||||
|
return "Error"
|
||||||
|
except Exception as ex:
|
||||||
|
self.onLine = False
|
||||||
|
self.trans.close()
|
||||||
|
sleep(2)
|
||||||
|
gravaLog(ip=self.ip,tipo="Falha",msg=f'Error - {str(ex)}')
|
||||||
|
return "Error"
|
||||||
|
if ret:
|
||||||
|
frame = int.from_bytes(ret[24:27],"little")
|
||||||
|
isJpeg = int.from_bytes(ret[32:33],"little")
|
||||||
|
img_size = int.from_bytes(ret[20:23],"little")
|
||||||
|
data = self.trans.recv(5000)
|
||||||
|
while img_size>len(data) and ret:
|
||||||
|
ret = self.trans.recv(10000)
|
||||||
|
if ret:
|
||||||
|
data = data+ret
|
||||||
|
#print(f'{len(ret)}b dados recebidos, total de: {len(data)+64}b')
|
||||||
|
else:
|
||||||
|
gravaLog(ip=self.ip,tipo="Falha",msg="Unable to recieve the image")
|
||||||
|
self.onLine = False
|
||||||
|
return "Unable to recieve the image"
|
||||||
|
hoje = datetime.now()
|
||||||
|
idcam = self.ip.split('.')
|
||||||
|
"""try:
|
||||||
|
nomeFile = f'{hoje.day}{hoje.month}{hoje.year}-{idcam[3]}-{frame}'
|
||||||
|
if isJpeg==1:
|
||||||
|
file = open(f'{self.pasta}{nomeFile}.jpg','wb')
|
||||||
|
nomeFile = f'{nomeFile}.jpg'
|
||||||
|
else:
|
||||||
|
file = open(f'{self.pasta}{nomeFile}.bmp','wb')
|
||||||
|
nomeFile = f'{nomeFile}.bmp'
|
||||||
|
file.write(data)
|
||||||
|
file.close()
|
||||||
|
except Exception as ex:
|
||||||
|
sleep(2)
|
||||||
|
gravaLog(ip=self.ip,tipo="Falha",msg=f'Error - {str(ex)}')
|
||||||
|
return "Falha"
|
||||||
|
"""
|
||||||
|
if isJpeg==1:
|
||||||
|
return "jpeg",data
|
||||||
|
else:
|
||||||
|
return "bmp",data
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
gravaLog(ip=self.ip,tipo="Falha Generica",msg=f'Error - {str(ex)}')
|
||||||
|
#print(f'erro {str(ex)}')
|
||||||
|
self.onLine = False
|
||||||
|
self.trans.close()
|
||||||
|
sleep(2)
|
||||||
|
return resposta
|
||||||
|
|
||||||
|
class DriveData():
|
||||||
|
HEADERSIZE = 100
|
||||||
|
ip = "192.168.0.1"
|
||||||
|
port = 32100
|
||||||
|
onLine = False
|
||||||
|
|
||||||
|
def __init__(self, ip, port):
|
||||||
|
gravaLog(ip=self.ip,msg=f'iniciou drive',file="log_data.txt")
|
||||||
|
self.ip=ip
|
||||||
|
self.port = port
|
||||||
|
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||||
|
try:
|
||||||
|
self.trans.connect((self.ip,self.port))
|
||||||
|
self.onLine = True
|
||||||
|
except:
|
||||||
|
self.onLine = False
|
||||||
|
|
||||||
|
def read_data(self):
|
||||||
|
resposta = 'falha'
|
||||||
|
try:
|
||||||
|
if not self.onLine:
|
||||||
|
#print(f'tentando Conectar...\n')
|
||||||
|
gravaLog(ip=self.ip,msg=f'tentando Conectar...',file="log_data.txt")
|
||||||
|
sleep(2)
|
||||||
|
try:
|
||||||
|
self.trans = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||||
|
self.trans.connect((self.ip,self.PORT))
|
||||||
|
self.onLine = True
|
||||||
|
gravaLog(ip=self.ip,msg=f'Conexão restabelecida...',file="log_data.txt")
|
||||||
|
except:
|
||||||
|
self.onLine = False
|
||||||
|
return resposta
|
||||||
|
resposta = self.trans.recv(self.HEADERSIZE).decode("utf-8")
|
||||||
|
resposta = str(resposta).split(',')
|
||||||
|
return resposta
|
||||||
|
except Exception as ex:
|
||||||
|
self.onLine = False
|
||||||
|
gravaLog(ip=self.ip,tipo="Falha Generica",msg=f'erro {str(ex)}',file="log_data.txt")
|
||||||
|
sleep(2)
|
||||||
|
return resposta
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test = DriveImg("192.168.1.125", 32200)
|
||||||
|
x = 0
|
||||||
|
while x < 100:
|
||||||
|
x=x+1
|
||||||
|
imgtype, img = test.read_img()
|
14
config.yml
14
config.yml
@ -7,6 +7,12 @@ core:
|
|||||||
arm:
|
arm:
|
||||||
ip: 192.168.1.145
|
ip: 192.168.1.145
|
||||||
|
|
||||||
|
#cable_map:
|
||||||
|
cameras:
|
||||||
|
banner:
|
||||||
|
ip: 192.168.1.125
|
||||||
|
port: 32200
|
||||||
|
|
||||||
led:
|
led:
|
||||||
fps: 90
|
fps: 90
|
||||||
timeout: 0
|
timeout: 0
|
||||||
@ -26,13 +32,13 @@ led:
|
|||||||
ledstart: 288
|
ledstart: 288
|
||||||
ledend: 431
|
ledend: 431
|
||||||
mode: rgb
|
mode: rgb
|
||||||
- universe: 1
|
- universe: 4
|
||||||
ip: 192.168.68.130
|
ip: 192.168.5.40
|
||||||
ledstart: 432
|
ledstart: 432
|
||||||
ledend: 575
|
ledend: 575
|
||||||
mode: rgb
|
mode: rgb
|
||||||
- universe: 4
|
- universe: 1
|
||||||
ip: 192.168.68.131
|
ip: 192.168.5.4
|
||||||
ledstart: 576
|
ledstart: 576
|
||||||
ledend: 719
|
ledend: 719
|
||||||
mode: rgb
|
mode: rgb
|
||||||
|
140
database.py
Normal file
140
database.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
"""This module contains functionality for interacting with a PostgreSQL database. It will automatically handle error
|
||||||
|
conditions (i.e. missing columns) without terminating the entire program. Use the :py:class:`DBConnector` class to
|
||||||
|
handle database interactions, either as a standalone object or in a context manager."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import psycopg2
|
||||||
|
from psycopg2 import DatabaseError, OperationalError
|
||||||
|
from psycopg2.errors import UndefinedColumn
|
||||||
|
|
||||||
|
DB_ADDRESS = os.getenv('DB_ADDRESS', 'localhost')
|
||||||
|
DB_PORT = os.getenv('DB_PORT', 5432)
|
||||||
|
DB_USER = os.getenv('DB_USER', 'postgres')
|
||||||
|
DB_PASSWORD = os.getenv('DB_PASSWORD', '')
|
||||||
|
DB_NAME = os.getenv('DB_NAME', 'postgres')
|
||||||
|
DB_TABLE = os.getenv('DB_TABLE', 'cables')
|
||||||
|
|
||||||
|
|
||||||
|
class DBConnector:
|
||||||
|
"""Context managed database class. Use with statements to automatically open and close the database connection, like
|
||||||
|
so:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
with DBConnector() as db:
|
||||||
|
db.read()
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _db_start(self):
|
||||||
|
"""Setup the database connection and cursor."""
|
||||||
|
try:
|
||||||
|
self.conn = psycopg2.connect(
|
||||||
|
f"host={DB_ADDRESS} port={DB_PORT} dbname={DB_NAME} user={DB_USER} password={DB_PASSWORD}")
|
||||||
|
self.cur = self.conn.cursor()
|
||||||
|
except OperationalError as e:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def _db_stop(self):
|
||||||
|
"""Close the cursor and connection."""
|
||||||
|
self.cur.close()
|
||||||
|
self.conn.close()
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._db_start()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self._db_stop()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self._db_start()
|
||||||
|
|
||||||
|
def __exit__(self):
|
||||||
|
self._db_stop()
|
||||||
|
|
||||||
|
def _get_cols(self) -> set[str]:
|
||||||
|
"""Get the list of columns in the database.
|
||||||
|
|
||||||
|
:return: A list of column names."""
|
||||||
|
query = f"select COLUMN_NAME from information_schema.columns where table_name={DB_TABLE}"
|
||||||
|
rows = {x["COLUMN_NAME"] for x in self._query(query)}
|
||||||
|
return rows
|
||||||
|
|
||||||
|
def _column_parity(self, columns: list[str] | set[str]) -> set[str]:
|
||||||
|
"""If the listed columns are not in the database, add them.
|
||||||
|
|
||||||
|
:param columns: The columns we expect are in the database.
|
||||||
|
:return: The list of columns in the database after querying."""
|
||||||
|
cols = set(columns)
|
||||||
|
existing = self._get_cols()
|
||||||
|
needs = cols.difference(existing.intersection(cols))
|
||||||
|
if len(needs) > 0:
|
||||||
|
query = f"ALTER TABLE {DB_TABLE} {', '.join([f'ADD COLUMN {c}' for c in needs])}"
|
||||||
|
self._query(query)
|
||||||
|
existing = self._get_cols()
|
||||||
|
return existing
|
||||||
|
|
||||||
|
def _query(self, sql) -> list[dict]:
|
||||||
|
"""Basic function for running queries.
|
||||||
|
|
||||||
|
:param sql: SQL query as plaintext.
|
||||||
|
:return: Results of the query, or an empty list if none."""
|
||||||
|
result = []
|
||||||
|
try:
|
||||||
|
self.cur.execute(sql)
|
||||||
|
result = self._read_dict()
|
||||||
|
except DatabaseError as e:
|
||||||
|
print(f"ERROR {e.pgcode}: {e.pgerror}\n"
|
||||||
|
f"Caused by query: {sql}")
|
||||||
|
finally:
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _read_dict(self) -> list[dict]:
|
||||||
|
"""Read the cursor as a list of dictionaries. psycopg2 defaults to using a list of tuples, so we want to convert
|
||||||
|
each row into a dictionary before we return it."""
|
||||||
|
cols = [i.name for i in self.cur.description]
|
||||||
|
results = []
|
||||||
|
for row in self.cur:
|
||||||
|
row_dict = {}
|
||||||
|
for i in range(0, len(row)):
|
||||||
|
if row[i]:
|
||||||
|
row_dict = {**row_dict, cols[i]: row[i]}
|
||||||
|
results.append(row_dict)
|
||||||
|
return results
|
||||||
|
|
||||||
|
def read(self, **kwargs) -> list[dict]:
|
||||||
|
"""Read rows from a database that match the specified filters.
|
||||||
|
|
||||||
|
:param kwargs: Column constraints; i.e. what value to filter by in what column.
|
||||||
|
:returns: A list of dictionaries of all matching rows, or an empty list if no match."""
|
||||||
|
args = []
|
||||||
|
for kw in kwargs.keys():
|
||||||
|
args.append(f"{kw} ILIKE {kwargs['kw']}")
|
||||||
|
query = f"SELECT * FROM {DB_TABLE}"
|
||||||
|
if len(args) > 0:
|
||||||
|
query += f" WHERE {' AND '.join(args)}"
|
||||||
|
return self._query(query)
|
||||||
|
|
||||||
|
def write(self, **kwargs) -> dict:
|
||||||
|
"""Write a row to the database.
|
||||||
|
|
||||||
|
:param kwargs: Values to write for each database; specify each column separately!
|
||||||
|
:returns: The row you just added."""
|
||||||
|
self._column_parity(set(kwargs.keys()))
|
||||||
|
values = []
|
||||||
|
for val in kwargs.keys():
|
||||||
|
values.append(kwargs[val])
|
||||||
|
query = f"INSERT INTO {DB_TABLE} ({', '.join(kwargs.keys())}) VALUES ({', '.join(values)})"
|
||||||
|
self._query(query)
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def write_all(self, items: list[dict]) -> list[dict]:
|
||||||
|
"""Write multiple rows to the database.
|
||||||
|
|
||||||
|
:param items: Rows to write, as a list of dictionaries.
|
||||||
|
:returns: The rows that were added successfully."""
|
||||||
|
successes = []
|
||||||
|
for i in items:
|
||||||
|
res0 = self.write(**i)
|
||||||
|
if res0:
|
||||||
|
successes.append(res0)
|
||||||
|
return successes
|
110
get_specs.py
110
get_specs.py
@ -26,7 +26,7 @@ def check_internet(url='https://belden.com', timeout=5):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def query_search(partnum):
|
def query_search(partnum, source):
|
||||||
"""token_url = "https://www.belden.com/coveo/rest/token?t=" + str(int(time.time()))
|
"""token_url = "https://www.belden.com/coveo/rest/token?t=" + str(int(time.time()))
|
||||||
with requests.get(token_url) as r:
|
with requests.get(token_url) as r:
|
||||||
out = json.loads(r.content)
|
out = json.loads(r.content)
|
||||||
@ -49,15 +49,50 @@ def query_search(partnum):
|
|||||||
# Bash script uses some crazy json formatting that I could not figure out
|
# Bash script uses some crazy json formatting that I could not figure out
|
||||||
# Despite the fact that I wrote it
|
# Despite the fact that I wrote it
|
||||||
# So I'll just leave it, becuase it works.
|
# So I'll just leave it, becuase it works.
|
||||||
|
if source == "Belden":
|
||||||
|
command = ["./query-search.sh", partnum]
|
||||||
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||||
|
if result.returncode != 0: # error
|
||||||
|
fprint("No results found in search database for " + partnum + ". No hi-res part image available.", result.stderr)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
data_out = json.loads(result.stdout)
|
||||||
|
return data_out
|
||||||
|
elif source == "Alphawire":
|
||||||
|
alphaurl = "https://www.alphawire.com//sxa/search/results/?l=en&s={4A774076-6068-460C-9CC6-A2D8E85E407F}&itemid={BF82F58C-EFD9-4D8B-AE3E-097DD12CF7DA}&sig=&autoFireSearch=true&productpartnumber=*" + partnum + "*&v={B22CD56D-AB95-4048-8AA1-5BBDF2F2D17F}&p=10&e=0&o=ProductPartNumber%2CAscending"
|
||||||
|
r = requests.get(url=alphaurl)
|
||||||
|
data = r.json()
|
||||||
|
output = dict()
|
||||||
|
#print(data)
|
||||||
|
try:
|
||||||
|
if data["Count"] > 0:
|
||||||
|
print(data["Results"][0]["Url"])
|
||||||
|
result = data["Results"][0]
|
||||||
|
if result["Url"].split("/")[-1] == partnum:
|
||||||
|
#print(partnum)
|
||||||
|
print(result["Html"])
|
||||||
|
try:
|
||||||
|
imgidx = result["Html"].index("<img src=") + 10
|
||||||
|
imgidx2 = result["Html"].index("?", imgidx)
|
||||||
|
output["image"] = result["Html"][imgidx:imgidx2]
|
||||||
|
if output["image"].index("http") != 0:
|
||||||
|
output["image"] = ""
|
||||||
|
print("No cable image found.")
|
||||||
|
except:
|
||||||
|
print("No cable image found.")
|
||||||
|
|
||||||
command = ["./query-search.sh", partnum]
|
dsidx = result["Html"].index("<a href=\"/disteAPI/") + 9
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
dsidx2 = result["Html"].index(partnum, dsidx) + len(partnum)
|
||||||
if result.returncode != 0: # error
|
output["datasheet"] = "https://www.alphawire.com" + result["Html"][dsidx:dsidx2]
|
||||||
fprint("No results found in search database for " + partnum + ". No hi-res part image available.", result.stderr)
|
#"test".index()
|
||||||
|
print(output)
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
except:
|
||||||
|
return False
|
||||||
return False
|
return False
|
||||||
else:
|
|
||||||
data_out = json.loads(result.stdout)
|
|
||||||
return data_out
|
|
||||||
|
|
||||||
def touch(path):
|
def touch(path):
|
||||||
with open(path, 'a'):
|
with open(path, 'a'):
|
||||||
@ -126,7 +161,7 @@ def get_multi(partnums):
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
def _download_image(url, output_dir): # Download datasheet with known URL
|
def _download_image(url, output_dir): # Download image with known URL
|
||||||
global bartext
|
global bartext
|
||||||
|
|
||||||
#fprint(url)
|
#fprint(url)
|
||||||
@ -151,25 +186,31 @@ def get_multi(partnums):
|
|||||||
os.remove(partnum + "/datasheet.pdf")
|
os.remove(partnum + "/datasheet.pdf")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def __use_cached_datasheet(partnum, path, output_dir):
|
def __use_cached_datasheet(partnum, path, output_dir, dstype):
|
||||||
fprint("Using cached datasheet for " + partnum)
|
fprint("Using cached datasheet for " + partnum)
|
||||||
bar.text = "Using cached datasheet for " + partnum
|
bar.text = "Using cached datasheet for " + partnum
|
||||||
bar(skipped=True)
|
bar(skipped=True)
|
||||||
fprint("Parsing Datasheet contents of " + partnum)
|
fprint("Parsing Datasheet contents of " + partnum)
|
||||||
bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..."
|
bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..."
|
||||||
read_datasheet.parse(path, output_dir)
|
read_datasheet.parse(path, output_dir, partnum, dstype)
|
||||||
bar(skipped=False)
|
bar(skipped=False)
|
||||||
|
|
||||||
def __downloaded_datasheet(partnum, path, output_dir):
|
def __downloaded_datasheet(partnum, path, output_dir, dstype):
|
||||||
fprint("Downloaded " + path)
|
fprint("Downloaded " + path)
|
||||||
bar.text = "Downloaded " + path
|
bar.text = "Downloaded " + path
|
||||||
bar(skipped=False)
|
bar(skipped=False)
|
||||||
fprint("Parsing Datasheet contents of " + partnum)
|
fprint("Parsing Datasheet contents of " + partnum)
|
||||||
bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..."
|
bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..."
|
||||||
read_datasheet.parse(path, output_dir)
|
read_datasheet.parse(path, output_dir, partnum, dstype)
|
||||||
bar(skipped=False)
|
bar(skipped=False)
|
||||||
|
|
||||||
for partnum in partnums:
|
for fullpartnum in partnums:
|
||||||
|
if fullpartnum[0:2] == "BL": # catalog.belden.com entry\
|
||||||
|
partnum = fullpartnum[2:]
|
||||||
|
dstype = "Belden"
|
||||||
|
elif fullpartnum[0:2] == "AW":
|
||||||
|
partnum = fullpartnum[2:]
|
||||||
|
dstype = "Alphawire"
|
||||||
output_dir = "cables/" + partnum
|
output_dir = "cables/" + partnum
|
||||||
path = output_dir + "/datasheet.pdf"
|
path = output_dir + "/datasheet.pdf"
|
||||||
bartext = "Downloading files for part " + partnum
|
bartext = "Downloading files for part " + partnum
|
||||||
@ -177,7 +218,7 @@ def get_multi(partnums):
|
|||||||
#
|
#
|
||||||
if (not os.path.exists(output_dir + "/found_part_hires")) or not (os.path.exists(path) and os.path.getsize(path) > 1):
|
if (not os.path.exists(output_dir + "/found_part_hires")) or not (os.path.exists(path) and os.path.getsize(path) > 1):
|
||||||
# Use query
|
# Use query
|
||||||
search_result = query_search(partnum.replace(" ", ""))
|
search_result = query_search(partnum.replace(" ", ""), dstype)
|
||||||
# Try to use belden.com search
|
# Try to use belden.com search
|
||||||
if search_result is not False:
|
if search_result is not False:
|
||||||
# Download high resolution part image if available and needed
|
# Download high resolution part image if available and needed
|
||||||
@ -190,17 +231,17 @@ def get_multi(partnums):
|
|||||||
|
|
||||||
# Download datasheet from provided URL if needed
|
# Download datasheet from provided URL if needed
|
||||||
if os.path.exists(path) and os.path.getsize(path) > 1:
|
if os.path.exists(path) and os.path.getsize(path) > 1:
|
||||||
__use_cached_datasheet(partnum, path, output_dir)
|
__use_cached_datasheet(partnum, path, output_dir, dstype)
|
||||||
|
|
||||||
elif _download_datasheet(search_result["datasheet"], output_dir) is not False:
|
elif _download_datasheet(search_result["datasheet"], output_dir) is not False:
|
||||||
__downloaded_datasheet(partnum, path, output_dir)
|
__downloaded_datasheet(partnum, path, output_dir, dstype)
|
||||||
|
|
||||||
elif os.path.exists(path) and os.path.getsize(path) > 1:
|
elif os.path.exists(path) and os.path.getsize(path) > 1:
|
||||||
__use_cached_datasheet(partnum, path, output_dir)
|
__use_cached_datasheet(partnum, path, output_dir, dstype)
|
||||||
|
|
||||||
# If search fails, and we don't already have the datasheet, guess datasheet URL and skip the hires image download
|
# If search fails, and we don't already have the datasheet, guess datasheet URL and skip the hires image download
|
||||||
elif _try_download_datasheet(partnum, output_dir) is not False:
|
elif _try_download_datasheet(partnum, output_dir) is not False:
|
||||||
__downloaded_datasheet(partnum, path, output_dir)
|
__downloaded_datasheet(partnum, path, output_dir, dstype)
|
||||||
|
|
||||||
# Failed to download with search or guess :(
|
# Failed to download with search or guess :(
|
||||||
else:
|
else:
|
||||||
@ -213,7 +254,7 @@ def get_multi(partnums):
|
|||||||
# We already have a hi-res image and the datasheet - perfect!
|
# We already have a hi-res image and the datasheet - perfect!
|
||||||
else:
|
else:
|
||||||
fprint("Using cached hi-res part image for " + partnum)
|
fprint("Using cached hi-res part image for " + partnum)
|
||||||
__use_cached_datasheet(partnum, path, output_dir)
|
__use_cached_datasheet(partnum, path, output_dir, dstype)
|
||||||
|
|
||||||
if len(failed) > 0:
|
if len(failed) > 0:
|
||||||
fprint("Failed to download:")
|
fprint("Failed to download:")
|
||||||
@ -227,21 +268,22 @@ def get_multi(partnums):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
partnums = ["10GXS12", "RST 5L-RKT 5L-949",
|
partnums = ["BL7958A", "BL10GXS12", "BLRST 5L-RKT 5L-949",
|
||||||
"10GXS13",
|
"BL10GXS13",
|
||||||
"10GXW12",
|
"BL10GXW12",
|
||||||
"10GXW13",
|
"BL10GXW13",
|
||||||
"2412",
|
"BL2412",
|
||||||
"2413",
|
"BL2413",
|
||||||
"OSP6AU",
|
"BLOSP6AU",
|
||||||
"FI4D024P9",
|
"BLFI4D024P9",
|
||||||
"FISD012R9",
|
"BLFISD012R9",
|
||||||
"FDSD012A9",
|
"BLFDSD012A9",
|
||||||
"FSSL024NG",
|
"BLFSSL024NG",
|
||||||
"FISX006W0",
|
"BLFISX006W0",
|
||||||
"FISX00103",
|
"BLFISX00103",
|
||||||
"C6D1100007"
|
"BLC6D1100007"
|
||||||
]
|
]
|
||||||
get_multi(partnums)
|
get_multi(partnums)
|
||||||
|
#query_search("3248", "Alphawire")
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ def init():
|
|||||||
data = list()
|
data = list()
|
||||||
for x in range(len(leds)):
|
for x in range(len(leds)):
|
||||||
if leds_size[x] == 3:
|
if leds_size[x] == 3:
|
||||||
data.append((50,50,255))
|
data.append((20,20,127))
|
||||||
elif leds_size[x] == 4:
|
elif leds_size[x] == 4:
|
||||||
data.append((50,50,255,0))
|
data.append((50,50,255,0))
|
||||||
else:
|
else:
|
||||||
@ -178,9 +178,9 @@ def init():
|
|||||||
sendall(data)
|
sendall(data)
|
||||||
#time.sleep(50000)
|
#time.sleep(50000)
|
||||||
fprint("Running start-up test sequence...")
|
fprint("Running start-up test sequence...")
|
||||||
for y in range(1):
|
for y in range(100):
|
||||||
for x in range(len(leds)):
|
for x in range(len(leds)):
|
||||||
setpixel(5,5,5,x)
|
setpixel(0,0,150,x)
|
||||||
sendall(data)
|
sendall(data)
|
||||||
#time.sleep(2)
|
#time.sleep(2)
|
||||||
#alloffsmooth()
|
#alloffsmooth()
|
||||||
@ -290,7 +290,7 @@ def close():
|
|||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
sender.stop()
|
sender.stop()
|
||||||
|
|
||||||
def mapimage(image, fps=30):
|
def mapimage(image, fps=90):
|
||||||
global start
|
global start
|
||||||
while uptime() - start < 1/fps:
|
while uptime() - start < 1/fps:
|
||||||
time.sleep(0.00001)
|
time.sleep(0.00001)
|
||||||
|
BIN
map.png
BIN
map.png
Binary file not shown.
Before Width: | Height: | Size: 381 KiB After Width: | Height: | Size: 381 KiB |
45
process_video.py
Executable file
45
process_video.py
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import banner_ivu_export
|
||||||
|
import numpy as np
|
||||||
|
from util import fprint
|
||||||
|
|
||||||
|
class qr_reader():
|
||||||
|
camera = None
|
||||||
|
def __init__(self, ip, port):
|
||||||
|
self.camera = banner_ivu_export.DriveImg(ip, port)
|
||||||
|
|
||||||
|
def read_qr(self, tries=1):
|
||||||
|
print("Trying " + str(tries) + " frames.")
|
||||||
|
for x in range(tries):
|
||||||
|
try:
|
||||||
|
imgtype, img = self.camera.read_img()
|
||||||
|
#fprint(imgtype)
|
||||||
|
image_array = np.frombuffer(img, np.uint8)
|
||||||
|
img = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
|
||||||
|
#cv2.imshow('Image', img)
|
||||||
|
#cv2.waitKey(1)
|
||||||
|
detect = cv2.QRCodeDetector()
|
||||||
|
value, points, straight_qrcode = detect.detectAndDecode(img)
|
||||||
|
return value
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class video_streamer():
|
||||||
|
camera = None
|
||||||
|
def __init__(self, ip, port):
|
||||||
|
self.camera = banner_ivu_export.DriveImg(ip, port)
|
||||||
|
|
||||||
|
def get_frame(self):
|
||||||
|
try:
|
||||||
|
return self.camera.read_img()
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test = qr_reader("192.168.1.125", 32200)
|
||||||
|
while True:
|
||||||
|
fprint(test.read_qr(5))
|
@ -9,8 +9,10 @@ from PIL import Image
|
|||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
from util import fprint
|
from util import fprint
|
||||||
|
import uuid
|
||||||
|
from util import run_cmd
|
||||||
|
|
||||||
def parse(filename, output_dir):
|
def parse(filename, output_dir, partnum, dstype):
|
||||||
|
|
||||||
# Extract table data
|
# Extract table data
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ def parse(filename, output_dir):
|
|||||||
page = reader.pages[0]
|
page = reader.pages[0]
|
||||||
table_list = {}
|
table_list = {}
|
||||||
for table in tables:
|
for table in tables:
|
||||||
|
table.df.infer_objects(copy=False)
|
||||||
table.df.replace('', np.nan, inplace=True)
|
table.df.replace('', np.nan, inplace=True)
|
||||||
table.df.dropna(inplace=True, how="all")
|
table.df.dropna(inplace=True, how="all")
|
||||||
table.df.dropna(inplace=True, axis="columns", how="all")
|
table.df.dropna(inplace=True, axis="columns", how="all")
|
||||||
@ -137,44 +140,104 @@ def parse(filename, output_dir):
|
|||||||
|
|
||||||
|
|
||||||
# multi-page table check
|
# multi-page table check
|
||||||
if table_name.isdigit() and len(tables) > 1:
|
if dstype == "Belden":
|
||||||
fprint(table_name)
|
if table_name.isdigit() and len(tables) > 1:
|
||||||
fprint(previous_table)
|
fprint(table_name)
|
||||||
|
fprint(previous_table)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main_key = previous_table
|
main_key = previous_table
|
||||||
cont_key = table_name
|
cont_key = table_name
|
||||||
fprint(tables)
|
fprint(tables)
|
||||||
if vertical == False:
|
if vertical == False:
|
||||||
main_keys = list(tables[main_key].keys())
|
main_keys = list(tables[main_key].keys())
|
||||||
for i, (cont_key, cont_values) in enumerate(tables[cont_key].items()):
|
for i, (cont_key, cont_values) in enumerate(tables[cont_key].items()):
|
||||||
if i < len(main_keys):
|
if i < len(main_keys):
|
||||||
fprint(tables[main_key][main_keys[i]])
|
fprint(tables[main_key][main_keys[i]])
|
||||||
tables[main_key][main_keys[i]] = (tables[main_key][main_keys[i]] + (cont_key,) + cont_values)
|
tables[main_key][main_keys[i]] = (tables[main_key][main_keys[i]] + (cont_key,) + cont_values)
|
||||||
|
|
||||||
del tables[table_name]
|
del tables[table_name]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for key in tables[cont_key].keys():
|
for key in tables[cont_key].keys():
|
||||||
tables[main_key][key] = tables[cont_key][key]
|
tables[main_key][key] = tables[cont_key][key]
|
||||||
del tables[table_name]
|
del tables[table_name]
|
||||||
|
|
||||||
previous_table = table_name
|
previous_table = table_name
|
||||||
|
|
||||||
|
# remove multi-line values that occasionally squeak through
|
||||||
|
def replace_newlines_in_dict(d):
|
||||||
|
for key, value in d.items():
|
||||||
|
if isinstance(value, str):
|
||||||
|
# Replace \n with " " if the value is a string
|
||||||
|
d[key] = value.replace('\n', ' ')
|
||||||
|
elif isinstance(value, dict):
|
||||||
|
# Recursively call the function if the value is another dictionary
|
||||||
|
replace_newlines_in_dict(value)
|
||||||
|
return d
|
||||||
|
|
||||||
fprint(tables)
|
tables = replace_newlines_in_dict(tables)
|
||||||
with open(output_dir + "/tables.json", 'w') as json_file:
|
|
||||||
json.dump(tables, json_file)
|
# summary
|
||||||
|
|
||||||
|
output_table = dict()
|
||||||
|
output_table["partnum"] = partnum
|
||||||
|
id = str(uuid.uuid4())
|
||||||
|
output_table["id"] = id
|
||||||
|
#output_table["position"] = id
|
||||||
|
#output_table["brand"] = brand
|
||||||
|
output_table["fullspecs"] = tables
|
||||||
|
output_table["searchspecs"] = {"partnum": partnum, **flatten(tables)}
|
||||||
|
|
||||||
|
output_table["searchspecs"]["id"] = id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(output_table)
|
||||||
|
|
||||||
|
run_cmd("rm " + output_dir + "/*.json") # not reliable!
|
||||||
|
with open(output_dir + "/" + output_table["searchspecs"]["id"] + ".json", 'w') as json_file:
|
||||||
|
json.dump(output_table["searchspecs"], json_file)
|
||||||
|
|
||||||
|
return output_table
|
||||||
|
|
||||||
|
|
||||||
return tables
|
def flatten(tables):
|
||||||
|
def convert_to_number(s):
|
||||||
|
try:
|
||||||
|
# First, try converting to an integer.
|
||||||
|
return int(s)
|
||||||
|
except ValueError:
|
||||||
|
# If that fails, try converting to a float.
|
||||||
|
try:
|
||||||
|
return float(s)
|
||||||
|
except ValueError:
|
||||||
|
# If it fails again, return the original string.
|
||||||
|
return s
|
||||||
|
out = dict()
|
||||||
|
print("{")
|
||||||
|
for table in tables.keys():
|
||||||
|
for key in tables[table].keys():
|
||||||
|
if len(key) < 64:
|
||||||
|
keyname = key
|
||||||
|
else:
|
||||||
|
keyname = key[0:64]
|
||||||
|
|
||||||
|
fullkeyname = (table + ": " + keyname).replace(".","")
|
||||||
|
if type(tables[table][key]) is not tuple:
|
||||||
|
out[fullkeyname] = convert_to_number(tables[table][key])
|
||||||
|
print("\"" + keyname + "\":", "\"" + str(out[fullkeyname]) + "\",")
|
||||||
|
elif len(tables[table][key]) == 1:
|
||||||
|
out[fullkeyname] = convert_to_number(tables[table][key][0])
|
||||||
|
|
||||||
|
print("\"" + keyname + "\":", "\"" + str(out[fullkeyname]) + "\",")
|
||||||
|
|
||||||
|
print("}")
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parse("test2.pdf", "10GXS13")
|
parse("test2.pdf", "cables/10GXS13", "10GXS13")
|
@ -5,6 +5,7 @@ pypdf2==2.12.1
|
|||||||
alive-progress
|
alive-progress
|
||||||
requests
|
requests
|
||||||
git+https://github.com/Byeongdulee/python-urx.git
|
git+https://github.com/Byeongdulee/python-urx.git
|
||||||
|
psycopg2-binary
|
||||||
pyyaml
|
pyyaml
|
||||||
Flask
|
Flask
|
||||||
selenium
|
selenium
|
||||||
|
26
run.py
26
run.py
@ -21,6 +21,7 @@ import led_control
|
|||||||
import server
|
import server
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
|
import process_video
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ vm_ready = False
|
|||||||
killme = None
|
killme = None
|
||||||
#pool = None
|
#pool = None
|
||||||
serverproc = None
|
serverproc = None
|
||||||
|
camera = None
|
||||||
|
|
||||||
to_server_queue = Queue()
|
to_server_queue = Queue()
|
||||||
from_server_queue = Queue()
|
from_server_queue = Queue()
|
||||||
@ -78,7 +80,7 @@ def start_server_socket():
|
|||||||
app.run(host='0.0.0.0', port=5000)"""
|
app.run(host='0.0.0.0', port=5000)"""
|
||||||
global to_server_queue
|
global to_server_queue
|
||||||
global from_server_queue
|
global from_server_queue
|
||||||
|
fprint("Starting WebSocket server...")
|
||||||
websocket_process = server.start_websocket_server(to_server_queue, from_server_queue)
|
websocket_process = server.start_websocket_server(to_server_queue, from_server_queue)
|
||||||
|
|
||||||
# Example
|
# Example
|
||||||
@ -86,9 +88,10 @@ def start_server_socket():
|
|||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
#print("HI")
|
||||||
if not from_server_queue.empty():
|
if not from_server_queue.empty():
|
||||||
message = from_server_queue.get()
|
client_id, message = from_server_queue.get()
|
||||||
fprint(f"Message from client: {message}")
|
fprint(f"Message from client {client_id}: {message}")
|
||||||
|
|
||||||
# Message handler
|
# Message handler
|
||||||
try:
|
try:
|
||||||
@ -141,6 +144,13 @@ def start_server_socket():
|
|||||||
fprint("")
|
fprint("")
|
||||||
elif call == "request":
|
elif call == "request":
|
||||||
fprint("")
|
fprint("")
|
||||||
|
if data["enabled"] == True:
|
||||||
|
# todo : send this to client
|
||||||
|
p = Process(target=run_cmd, args=("./keyboard-up.ps1",))
|
||||||
|
p.start()
|
||||||
|
elif data["enabled"] == False:
|
||||||
|
p = Process(target=run_cmd, args=("./keyboard-down.ps1",))
|
||||||
|
p.start()
|
||||||
|
|
||||||
case "machine_settings":
|
case "machine_settings":
|
||||||
fprint("machine_settings message")
|
fprint("machine_settings message")
|
||||||
@ -202,10 +212,10 @@ def setup_server(pool):
|
|||||||
global led_ready
|
global led_ready
|
||||||
global arm_ready
|
global arm_ready
|
||||||
global serverproc
|
global serverproc
|
||||||
|
global camera
|
||||||
|
|
||||||
pool.apply_async(ur5_control.init, (config["arm"]["ip"],), callback=arm_start_callback)
|
pool.apply_async(ur5_control.init, (config["arm"]["ip"],), callback=arm_start_callback)
|
||||||
pool.apply_async(led_control.init, callback=led_start_callback)
|
pool.apply_async(led_control.init, callback=led_start_callback)
|
||||||
#pool.apply_async(camera_control.init, callback=camera_start_callback)
|
|
||||||
#pool.apply_async(sensor_control.init, callback=sensor_start_callback)
|
#pool.apply_async(sensor_control.init, callback=sensor_start_callback)
|
||||||
serverproc = Process(target=start_server_socket)
|
serverproc = Process(target=start_server_socket)
|
||||||
serverproc.start()
|
serverproc.start()
|
||||||
@ -225,10 +235,11 @@ def setup_server(pool):
|
|||||||
|
|
||||||
if camera_ready is False:
|
if camera_ready is False:
|
||||||
fprint("waiting for " + "Camera initilization" + " to complete...", sendqueue=to_server_queue)
|
fprint("waiting for " + "Camera initilization" + " to complete...", sendqueue=to_server_queue)
|
||||||
while camera_ready is False:
|
camera = process_video.qr_reader(config["cameras"]["banner"]["ip"], config["cameras"]["banner"]["port"])
|
||||||
sleep(0.1)
|
|
||||||
fprint("Camera initialized.", sendqueue=to_server_queue)
|
fprint("Camera initialized.", sendqueue=to_server_queue)
|
||||||
|
|
||||||
|
arm_ready = True
|
||||||
if arm_ready is False:
|
if arm_ready is False:
|
||||||
fprint("waiting for " + "UR5 initilization" + " to complete...", sendqueue=to_server_queue)
|
fprint("waiting for " + "UR5 initilization" + " to complete...", sendqueue=to_server_queue)
|
||||||
while arm_ready is False:
|
while arm_ready is False:
|
||||||
@ -251,6 +262,9 @@ def mainloop_server(pool):
|
|||||||
killall()
|
killall()
|
||||||
counter = counter + 1
|
counter = counter + 1
|
||||||
|
|
||||||
|
fprint("Looking for QR code...")
|
||||||
|
print(camera.read_qr(30))
|
||||||
|
|
||||||
def run_loading_app():
|
def run_loading_app():
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
27
server.py
27
server.py
@ -50,32 +50,37 @@ def run_server():
|
|||||||
import asyncio
|
import asyncio
|
||||||
import websockets
|
import websockets
|
||||||
from multiprocessing import Process, Queue
|
from multiprocessing import Process, Queue
|
||||||
|
from util import fprint
|
||||||
|
import uuid
|
||||||
|
|
||||||
connected_clients = set()
|
connected_clients = {}
|
||||||
|
|
||||||
async def handler(websocket, path, to_server_queue, from_server_queue):
|
async def handler(websocket, path, to_server_queue, from_server_queue):
|
||||||
# Register websocket connection
|
# Register websocket connection
|
||||||
connected_clients.add(websocket)
|
client_id = str(uuid.uuid4())
|
||||||
|
connected_clients[client_id] = websocket
|
||||||
try:
|
try:
|
||||||
# Handle incoming messages
|
# Handle incoming messages
|
||||||
async for message in websocket:
|
async for message in websocket:
|
||||||
#print(f"Received message: {message}")
|
#print(f"Received message: {message}")
|
||||||
from_server_queue.put(message) # Put received message into from_server_queue
|
print(client_id)
|
||||||
|
from_server_queue.put((client_id, message))
|
||||||
finally:
|
finally:
|
||||||
# Unregister websocket connection
|
# Unregister websocket connection
|
||||||
connected_clients.remove(websocket)
|
if client_id in connected_clients:
|
||||||
|
del connected_clients[client_id]
|
||||||
|
print(f"Client {client_id} connection closed")
|
||||||
|
|
||||||
async def send_messages(to_server_queue):
|
async def send_messages(to_server_queue):
|
||||||
while True:
|
while True:
|
||||||
if not to_server_queue.empty():
|
if not to_server_queue.empty():
|
||||||
message = to_server_queue.get()
|
client_id, message = to_server_queue.get()
|
||||||
if connected_clients: # Check if there are any connected clients
|
if client_id in connected_clients: # Send message to specific client
|
||||||
#await asyncio.wait([client.send(message) for client in connected_clients])
|
await connected_clients[client_id].send(message)
|
||||||
#await [client.send(message) for client in connected_clients]
|
elif len(connected_clients) > 0: # Broadcast message to all clients
|
||||||
for client in connected_clients:
|
for client in connected_clients.values():
|
||||||
await client.send(message)
|
await client.send(message)
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
await asyncio.sleep(0.1) # Prevent the loop from running too fast
|
|
||||||
|
|
||||||
def websocket_server(to_server_queue, from_server_queue):
|
def websocket_server(to_server_queue, from_server_queue):
|
||||||
start_server = websockets.serve(lambda ws, path: handler(ws, path, to_server_queue, from_server_queue), "localhost", 9000)
|
start_server = websockets.serve(lambda ws, path: handler(ws, path, to_server_queue, from_server_queue), "localhost", 9000)
|
||||||
|
10
util.py
10
util.py
@ -62,7 +62,7 @@ def fprint(msg, settings = None, sendqueue = None):
|
|||||||
|
|
||||||
print(logMsg)
|
print(logMsg)
|
||||||
if (sendqueue is not None):
|
if (sendqueue is not None):
|
||||||
sendqueue.put("{ \"type\": \"log\", \"call\":\"send\", \"data\": \"" + logMsg + "\" }")
|
sendqueue.put(("*", "{ \"type\": \"log\", \"call\":\"send\", \"data\": \"" + logMsg + "\" }"))
|
||||||
if (settings is not None):
|
if (settings is not None):
|
||||||
tmpList = settings["logMsg"]
|
tmpList = settings["logMsg"]
|
||||||
tmpList.append(logMsg)
|
tmpList.append(logMsg)
|
||||||
@ -111,9 +111,9 @@ def run_cmd(cmd):
|
|||||||
return completed
|
return completed
|
||||||
|
|
||||||
def setup_child(sets=None):
|
def setup_child(sets=None):
|
||||||
#if not getattr(sys, "frozen", False):
|
if not getattr(sys, "frozen", False):
|
||||||
# sys.stdout = Logger(filename=find_data_file("output.log"))
|
sys.stdout = Logger(filename=find_data_file("output.log"))
|
||||||
# sys.stderr = Logger(filename=find_data_file("output.log"))
|
sys.stderr = Logger(filename=find_data_file("output.log"))
|
||||||
if sets is not None:
|
if sets is not None:
|
||||||
settings = sets
|
settings = sets
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ class Logger(object):
|
|||||||
self.terminal = sys.stdout
|
self.terminal = sys.stdout
|
||||||
|
|
||||||
def write(self, message):
|
def write(self, message):
|
||||||
self.log.write(message)
|
#self.log.write(message)
|
||||||
#close(filename)
|
#close(filename)
|
||||||
#self.log = open(filename, "a")
|
#self.log = open(filename, "a")
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user