Publish to git

This commit is contained in:
Cole Deck
2024-09-03 16:50:04 -05:00
commit bfebba3e9e
22 changed files with 1440 additions and 0 deletions

View File

@ -0,0 +1,7 @@
from .root_page import RootPage
from .about_page import AboutPage
from .add_page import AddPage
from .browse_page import BrowsePage
from .login_page import LoginPage
from .item_page import ItemPage

View File

@ -0,0 +1,63 @@
from __future__ import annotations
from dataclasses import KW_ONLY, field
from typing import * # type: ignore
import rio
from .. import components as comps
class AboutPage(rio.Component):
"""
A sample page, which displays a humorous description of the company.
"""
def build(self) -> rio.Component:
return rio.Markdown(
"""
# About Us
Welcome to Buzzwordz Inc.! Unleashing Synergistic Paradigms for Unprecedented
Excellence since the day after yesterday.
## About Our Company
At buzzwordz, we are all talk and no action. Our mission is to be the vanguards
of industry-leading solutions, leveraging bleeding-edge technologies to catapult
your business into the stratosphere of success. Our unparalleled team of ninjas,
gurus, and rockstars is dedicated to disrupting the status quo and actualizing
your wildest business dreams. We live, breathe, and eat operational excellence
and groundbreaking innovation.
## Synergistic Consulting
Unlock your business's quantum potential with our bespoke, game-changing
strategies. Our consulting services synergize cross-functional paradigms to
create a holistic ecosystem of perpetual growth and exponential ROI. Did I
mention paradigm-shifts? We've got those too.
## Agile Hyper-Development
We turn moonshot ideas into reality with our agile, ninja-level development
techniques. Our team of coding wizards crafts robust, scalable, and future-proof
solutions that redefine industry standards. 24/7 Proactive Hyper-Support
Experience next-gen support that anticipates your needs before you do. Our
omnipresent customer happiness engineers ensure seamless integration,
frictionless operation, and infinite satisfaction, day and night.
Embark on a journey of transformational growth and stratospheric success. Don't
delay, give us your money today.
Phone: (123) 456-7890
Email: info@yourwebsite.com
Address: 123 Main Street, City, Country
""",
width=60,
margin_bottom=4,
align_x=0.5,
align_y=0,
)

247
inventory/pages/add_page.py Normal file
View File

@ -0,0 +1,247 @@
from __future__ import annotations
from dataclasses import KW_ONLY, field
from typing import * # type: ignore
import rio
import datetime
from mac_vendor_lookup import AsyncMacLookup
from db_classes import *
from .. import components as comps
class AddPage(rio.Component):
partnum: str = ""
mac: str = ""
serial: str = ""
fwver: str = ""
code: str = ""
popup_message: str = ""
popup_show: bool = False
popup_color: str = 'warning'
date: datetime.date = datetime.date.today()
tz: datetime.tzinfo = datetime.tzinfo()
time: datetime.datetime = datetime.datetime.now()
time_start: str = datetime.datetime.now().strftime(format="%H:%M")
macvendor: str = ""
manu: str = ""
manufield: str = ""
office: str = ""
@rio.event.periodic(1)
def set_office_init(self):
self.office = self.session[comps.Settings].office
#print("Populated:", self.office)
async def check_mac(self,mac):
print("Checking", mac)
try:
macvendor = await AsyncMacLookup().lookup(mac)
if self.manufield == "" or self.manufield == self.macvendor: # blank or set by MAC already
self.manu = macvendor
self.manufield = macvendor
self.macvendor = macvendor
#print(macvendor)
except:
pass
# not valid MAC?
async def check_all(self):
await self.check_mac(self.mac)
# check part number
# lookup in PL_Export_rel
async def add_part(self):
await self.check_all()
if self.code == "":
# FAIL
self.popup_message = "\n Missing barcode! \n\n"
self.popup_show = True
self.popup_color = 'danger'
else:
# OK, add part
if create_item(self.partnum, self.serial, self.office, self.code, location=None, description=None, manufacturer=self.manu, mac=self.mac, fwver=self.fwver) == False:
self.popup_message = "\n Duplicate barcode! \n\n"
self.popup_show = True
self.popup_color = 'warning'
else:
self.popup_message = "\n Part added! \n\n"
self.popup_show = True
self.popup_color = 'success'
self.name: str = ""
self.partnum: str = ""
self.mac: str = ""
self.serial: str = ""
self.fwver: str = ""
self.code: str = ""
self.macvendor: str = ""
self.manu: str = ""
self.manufield: str = ""
async def _add_part_enter(self, event: rio.TextInputConfirmEvent):
await self.add_part()
async def _add_part_button(self):
await self.add_part()
@rio.event.periodic(1)
def update_time_view(self):
self.time_start = self.session.timezone.fromutc(datetime.datetime.now()).now().strftime(format="%m/%d/%Y %H:%M:%S")
self.time = datetime.datetime.now()
def _set_time(self, event: rio.TextInputChangeEvent):
time_str = event.text
try:
time_obj = datetime.datetime.strptime(time_str, "%H:%M").time()
dt_with_time = datetime.datetime.combine(self.date, time_obj)
dt_with_tz = dt_with_time.replace(tzinfo=self.session.timezone)
self.time = dt_with_tz
#event.text =
#print(self.time)
except ValueError:
pass
async def _update_mac(self, event: rio.TextInputChangeEvent):
await self.check_mac(event.text)
def _update_partnum(self, event: rio.TextInputChangeEvent):
def __find_hm_header(txt):
searchlist = ["RSPS", "RSPE", "RSP", "RSB", "LRS", "RS", "OS", "RED", "MSP", "MSM", "MS", "MM", "EESX", "EES", "OZD", "OBR"]
for header in searchlist:
if txt.find(header) >= 0:
return txt.find(header) + len(header) + 2
def __find_header_general(txt):
acount = 0
ncount = 0
dash = False
for char in txt:
if char == '-':
dash = True
break
if char.isdigit():
ncount += 1
if char.isalpha():
acount += 1
if dash and acount <= 5 and ncount <= 5:
return acount+ncount
return -1
def __find_hm_fwver(txt):
a = txt.find(".")
if a > 5:
return a-2
return -1
def __find_hm_fwmode(txt):
a = __find_hm_fwver(txt)
#print(a)
if txt.find("BRS") == 0:
a -= 1
if txt[a] in ['S', 'A']:
return txt[a]
a = __find_hm_fwver(txt)
if txt.find("GRS") == 0:
a -= 4
if txt[a:a+2] in ['2S', '2A', '3S', '3A']: # 1040
return txt[a:a+2]
elif txt[a+2:a+4] in ['2S', '2A', '3S', '3A']: # 1020/30
return txt[a+2:a+4]
a = __find_hm_fwver(txt)
if txt.find("RSP") == 0 or txt.find("OS") == 0 or txt.find("MSP") == 0 or txt.find("EESX") == 0 or txt.find("RED"):
a -= 2
if txt[a:a+2] in ['2S', '2A', '3S', '3A']:
return txt[a:a+2]
a = __find_hm_fwver(txt)
if txt.find("RS") == 0 or txt.find("MS") == 0:
a -= 3
print(txt,txt[a])
if txt[a] in ['P', 'E']:
return txt[a]
a = __find_hm_fwver(txt)
if txt.find("EAGLE") == 0:
a -= 2
if txt[a:a+2] in ['3F', 'MB', 'IN', 'UN', 'OP', '01', 'SU', 'NF']:
return txt[a:a+2]
print("Failed to match software level", repr(txt))
return ""
pn = event.text
self.name = ""
if __find_header_general(pn) >= 0:
# hirschmann switch detected
self.name = pn[0:__find_header_general(pn)]
if __find_hm_fwver(pn) >= 0:
self.fwver = pn[__find_hm_fwver(pn):]
if len(__find_hm_fwmode(pn)) > 0:
self.fwver += " SWL-" + __find_hm_fwmode(pn)
def build(self) -> rio.Component:
return rio.Column(
rio.Popup(
anchor=rio.Text(
text="Add a part below:",
style='heading1',
align_x = 0.5
),
color=self.bind().popup_color,
is_open=self.bind().popup_show,
content=rio.Text(
text=self.bind().popup_message,
),
),
rio.TextInput(
label="Barcode",
text=self.bind().code
),
rio.TextInput(
label="Full part number",
text=self.bind().partnum,
on_change=self._update_partnum
),
rio.TextInput(
label="Serial",
text=self.bind().serial
),
rio.TextInput(
label="MAC",
text=self.bind().mac,
on_change=self._update_mac
),
rio.TextInput(
label="Manufacturer",
text=self.bind().manufield
),
rio.TextInput(
label="FW Ver",
text=self.bind().fwver,
on_confirm=self._add_part_enter
),
rio.Row(
# rio.DateInput(
# label="Timestamp",
# value=self.bind().date
# ),
rio.TextInput(
#text=
is_sensitive=False,
text = self.bind().time_start,
#on_change=self._set_time
)
),
rio.Button(
content="Add",
on_press=self._add_part_button
),
spacing=2,
width=60,
margin_bottom=4,
align_x=0.5,
align_y=0,
)

View File

@ -0,0 +1,71 @@
from __future__ import annotations
from dataclasses import KW_ONLY, field
from typing import * # type: ignore
import rio
from .. import components as comps
from db_classes import *
import functools
class BrowsePage(rio.Component):
searchtext: str = ""
items: dict = {}
office: str = ""
filters: dict = {}
@rio.event.on_populate
async def _search(self, query=searchtext):
self.office = self.session[comps.Settings].office
self.filters['office'] = self.office
self.items = search_item(query, self.filters)
await self.force_refresh()
@rio.event.periodic(1)
async def set_office_init(self):
if self.office != self.session[comps.Settings].office:
self.office = self.session[comps.Settings].office
#print(self.office)
await self._search()
async def _search_trigger(self, event: rio.TextInputChangeEvent):
await self._search(event.text)
def click_item(self, code):
self.session[comps.Settings].selected_item = code
self.session.attach(self.session[comps.Settings])
self.session.navigate_to("/item")
def build(self) -> rio.Component:
searchview: rio.ListView = rio.ListView(height='grow')
for item in self.items:
if item["loc"] is not None:
loc = item["loc"]["name"]
else:
loc = ""
if item["checkout"]:
checkout = item["checkout_user"] + " - " + loc
else:
checkout = loc
searchview.add(rio.SimpleListItem(text=item["fullname"],secondary_text=(item["manufacturer"] + " - Serial: " + item["serial"] + "\n" + checkout), on_press=functools.partial(
self.click_item,
code=item["barcode"])))
return rio.Column(
rio.Row(
rio.TextInput(
text=self.bind().searchtext,
on_change=self._search_trigger,
label="Search"
)
),
searchview,
spacing=2,
width=60,
align_x=0.5,
align_y=0,
)

View File

@ -0,0 +1,101 @@
from __future__ import annotations
from dataclasses import KW_ONLY, field
from typing import * # type: ignore
import rio
from .. import components as comps
from db_classes import *
import functools
class ItemPage(rio.Component):
itm: dict = {}
barcode: str = ""
@rio.event.on_populate
async def _get(self):
self.barcode = self.session[comps.Settings].selected_item
self.itm = find_item(self.barcode)
#print(find_item(self.barcode))
#print(self.itm)
await self.force_refresh()
def build(self) -> rio.Component:
if 'barcode' in self.itm:
if self.itm["loc"] is not None:
loc = self.itm["loc"]["name"]
else:
loc = ""
if self.itm["checkout"]:
checkout = self.itm["checkout_user"] + " - " + loc
else:
checkout = loc
# searchview.add(rio.SimpleListItem(text=item["fullname"],secondary_text=(item["manufacturer"] + " - Serial: " + item["serial"] + "\n" + checkout), on_press=functools.partial(
# self.click_item,
# file=item["barcode"])))
return rio.Column(
rio.Text(
text=str(self.itm["fullname"]),
style='heading1',
align_x = 0.5
),
rio.Text(
text=str(self.itm["manufacturer"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Serial: " + str(self.itm["serial"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="MAC: " + str(self.itm["mac"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="FW Version: " + str(self.itm["fwver"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Location: " + str(checkout),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Checked out?: " + str(self.itm["checkout"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Checkout start/end: " + str(self.itm["checkout_start"]) + " to " + str(self.itm["checkout_end"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Office: " + str(self.itm["office"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Barcode: " + str(self.itm["barcode"]),
style='heading2',
align_x = 0.5
),
rio.Text(
text="Description: " + str(self.itm["description"]),
style='heading2',
align_x = 0.5,
),
spacing=2,
width=60,
align_x=0.5,
align_y=0,
)
else:
return rio.Text("This item does not exist!")

View File

@ -0,0 +1,49 @@
from __future__ import annotations
from dataclasses import KW_ONLY, field
from typing import * # type: ignore
import rio
import datetime
from .. import components as comps
class LoginPage(rio.Component):
name: str = ""
def build(self) -> rio.Component:
return rio.Column(
rio.Popup(
anchor=rio.Text(
text="Login",
style='heading1',
align_x = 0.5
),
color=self.bind().popup_color,
is_open=self.bind().popup_show,
content=rio.Text(
text=self.bind().popup_message,
),
),
rio.TextInput(
label="User",
text=self.bind().code
),
rio.TextInput(
label="Password",
text=self.bind().partnum
),
rio.Button(
content="Login",
on_press=self._add_part_button
),
spacing=2,
width=60,
margin_bottom=4,
align_x=0.5,
align_y=0,
)

View File

@ -0,0 +1,39 @@
from __future__ import annotations
from dataclasses import KW_ONLY, field
from typing import * # type: ignore
import rio
from .. import components as comps
class RootPage(rio.Component):
"""
This page will be used as the root component for the app. This means, that
it will always be visible, regardless of which page is currently active.
This makes it the perfect place to put components that should be visible on
all pages, such as a navbar or a footer.
Additionally, the root page will contain a `rio.PageView`. Page views don't
have any appearance on their own, but they are used to display the content
of the currently active page. Thus, we'll always see the navbar and footer,
with the content of the current page in between.
"""
def build(self) -> rio.Component:
return rio.Column(
# The navbar contains a `rio.Overlay`, so it will always be on top
# of all other components.
comps.Navbar(),
# Add some empty space so the navbar doesn't cover the content.
rio.Spacer(height=10),
# The page view will display the content of the current page.
rio.PageView(
# Make sure the page view takes up all available space.
height="grow",
),
# The footer is also common to all pages, so place it here.
comps.Footer(),
)