summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaise Thompson <blaise@untzag.com>2019-11-12 08:32:41 -0600
committerBlaise Thompson <blaise@untzag.com>2019-11-12 08:32:41 -0600
commitbe8b011c9c4c44f8de99d5cf19ebd1dae5b7dfe9 (patch)
treebcbb5b931f6fb8649c20f435c7d8c28ea7ff99a3
parent0a526a560a44581047970a6f1057ca1d283499d9 (diff)
coloring
-rw-r--r--.gitignore1
-rw-r--r--setup.py3
-rw-r--r--shopdb/__init__.py10
-rw-r--r--shopdb/__main__.py123
-rw-r--r--shopdb/_associations.py24
-rw-r--r--shopdb/_base.py16
-rw-r--r--shopdb/_customer.py16
-rw-r--r--shopdb/_group.py15
-rw-r--r--shopdb/_job.py25
-rw-r--r--shopdb/_staff.py14
-rw-r--r--shopdb/_status.py30
11 files changed, 273 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index bc58411..1222794 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@ temp/
flycheck_*.el
.projectile
*.#*
+*#*#
# images
*.jpg
diff --git a/setup.py b/setup.py
index 5f0c0c0..111d9c0 100644
--- a/setup.py
+++ b/setup.py
@@ -21,9 +21,10 @@ setup(
packages=find_packages(),
package_data=extra_files,
python_requires=">=3.7",
- install_requires=[],
+ install_requires=["appdirs", "prettytable"],
extras_require={"dev": ["black", "pre-commit", "pydocstyle"]},
version=version,
author="Blaise Thompson",
author_email="bthompson@chem.wisc.edu",
+ entry_points={"console_scripts": ["shopdb=shopdb.__main__:main"]},
)
diff --git a/shopdb/__init__.py b/shopdb/__init__.py
index d2be0a7..bf39e5c 100644
--- a/shopdb/__init__.py
+++ b/shopdb/__init__.py
@@ -1 +1,11 @@
from ._base import *
+from ._customer import *
+from ._job import *
+from ._staff import *
+from ._status import *
+
+Base.metadata.create_all(engine)
+
+from ._associations import *
+
+Base.metadata.create_all(engine)
diff --git a/shopdb/__main__.py b/shopdb/__main__.py
new file mode 100644
index 0000000..059aad2
--- /dev/null
+++ b/shopdb/__main__.py
@@ -0,0 +1,123 @@
+from datetime import datetime
+import click
+import prettytable
+from ._base import Session
+from ._customer import Customer
+from ._group import Group
+from ._job import Job, JobPriorities
+from ._staff import Staff
+from ._status import Status, StatusValues
+
+
+session = Session()
+
+
+@click.group()
+def main():
+ pass
+
+
+@main.command(name="customer")
+@click.option("--add", is_flag=True, default=False)
+def customer(add):
+ if add:
+ click.echo("adding new customer")
+ name = click.prompt("name")
+ email = click.prompt("email")
+ room = click.prompt("room")
+ groups = click.prompt("group id(s)").split(',')
+ groups = [session.query(Group).filter(Group.id == int(g))[0] for g in groups]
+ new = Customer(name=name, email=email, room=room, groups=groups)
+ session.add(new)
+ session.commit()
+ click.echo("...done!")
+ else:
+ out = prettytable.PrettyTable()
+ out.field_names = ["id", "name", "email", "room", "group(s)"]
+ out.align = "l"
+ for instance in session.query(Customer).order_by(Customer.id):
+ groups = ",".join([g.name for g in instance.groups])
+ out.add_row([instance.id, instance.name, instance.email, instance.room, groups])
+ print(out)
+
+
+@main.command(name="group")
+@click.option("--add", is_flag=True, default=False)
+def group(add):
+ if add:
+ click.echo("adding new group")
+ name = click.prompt("name")
+ new = Group(name=name)
+ session.add(new)
+ session.commit()
+ click.echo("...done!")
+ else:
+ out = prettytable.PrettyTable()
+ out.field_names = ["id", "name"]
+ out.align = "l"
+ for instance in session.query(Group).order_by(Group.id):
+ out.add_row([instance.id, instance.name])
+ print(out)
+
+
+@main.command(name="job")
+@click.option("--add", is_flag=True, default=False)
+def job(add):
+ if add:
+ click.echo("adding new job")
+ name = click.prompt("name")
+ customers = click.prompt("customer id(s)").split(',')
+ customers = [session.query(Customer).filter(Customer.id == int(g))[0] for g in customers]
+ priority = click.prompt("priority", type=click.Choice([a.name for a in (JobPriorities)]))
+ new = Job(name=name, customers=customers, priority=priority)
+ session.add(new)
+ session.commit()
+ click.echo("...done!")
+ else:
+ out = prettytable.PrettyTable()
+ out.field_names = ["id", "priority", "name", "customer(s)"]
+ out.align = "l"
+ for instance in session.query(Job).order_by(Job.id):
+ customers = ",".join([c.name for c in instance.customers])
+ out.add_row([instance.id, instance.priority.name, instance.name, customers])
+ print(out)
+
+
+@main.command(name="staff")
+@click.option("--add", is_flag=True, default=False)
+def staff(add):
+ if add:
+ click.echo("adding new staff member")
+ name = click.prompt("name")
+ new = Staff(name=name)
+ session.add(new)
+ session.commit()
+ click.echo("...done!")
+ else:
+ out = prettytable.PrettyTable()
+ out.field_names = ["id", "name"]
+ out.align = "l"
+ for instance in session.query(Staff).order_by(Staff.id):
+ out.add_row([instance.id, instance.name])
+ print(out)
+
+
+@main.command(name="status")
+@click.option("--add", is_flag=True, default=False)
+def staff(add):
+ if add:
+ click.echo("recording status change")
+ job = session.query(Job).filter(Job.id == click.prompt("job id", int))[0]
+ value = click.prompt("new status", type=click.Choice([a.name for a in (StatusValues)]))
+ comment = click.prompt("comment")
+ new = Status(job=job, comment=comment, value=str(value), timestamp=datetime.utcnow())
+ session.add(new)
+ session.commit()
+ click.echo("...done!")
+ else:
+ out = prettytable.PrettyTable()
+ out.field_names = ["id", "timestamp (UTC)", "job", "value", "comment"]
+ out.align = "l"
+ for instance in session.query(Status).order_by(Status.id):
+ out.add_row([instance.id,instance.timestamp, instance.job.name, instance.value.name, instance.comment])
+ print(out)
diff --git a/shopdb/_associations.py b/shopdb/_associations.py
new file mode 100644
index 0000000..e0e25bf
--- /dev/null
+++ b/shopdb/_associations.py
@@ -0,0 +1,24 @@
+from sqlalchemy import Column, Integer, String, Table
+from sqlalchemy.orm import relationship
+from sqlalchemy import ForeignKey
+from ._base import Base
+from ._customer import Customer
+from ._group import Group
+from ._job import Job
+
+
+customer_group = Table('customer_group', Base.metadata,
+ Column('customer_id', Integer, ForeignKey('customers.id')),
+ Column('group_id', Integer, ForeignKey('groups.id'))
+)
+Customer.groups = relationship("Group", secondary=customer_group, back_populates="members")
+Group.members = relationship("Customer", secondary=customer_group, back_populates="groups")
+
+
+
+customer_job = Table('customer_job', Base.metadata,
+ Column('customer_id', Integer, ForeignKey('customers.id')),
+ Column('job_id', Integer, ForeignKey('jobs.id'))
+)
+Customer.jobs = relationship("Job", secondary=customer_job, back_populates="customers")
+Job.customers = relationship("Customer", secondary=customer_job, back_populates="jobs")
diff --git a/shopdb/_base.py b/shopdb/_base.py
index 8033d28..5e8c3bc 100644
--- a/shopdb/_base.py
+++ b/shopdb/_base.py
@@ -1,8 +1,18 @@
-__all__ = ["engine", "Base"]
+__all__ = ["engine", "Base", "Session"]
+import appdirs
+import pathlib
import sqlalchemy
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
-engine = sqlalchemy.create_engine("sqlite:///:memory:", echo=True)
-Base = sqlalchemy.ext.declarative.declarative_base
+
+path = pathlib.Path(appdirs.user_data_dir(appname="shopdb")) / "sqlite3.db"
+path.parent.mkdir(parents=True, exist_ok=True)
+engine = sqlalchemy.create_engine(f"sqlite:///{path}", echo=False)
+
+Base = declarative_base()
+
+Session = sessionmaker(bind=engine)
diff --git a/shopdb/_customer.py b/shopdb/_customer.py
new file mode 100644
index 0000000..05447b5
--- /dev/null
+++ b/shopdb/_customer.py
@@ -0,0 +1,16 @@
+__all__ = ["Customer"]
+
+
+from sqlalchemy import Column, Integer, String, Table
+from ._base import Base, engine
+
+
+class Customer(Base):
+ __tablename__ = 'customers'
+ id = Column(Integer, primary_key=True)
+ name = Column(String)
+ email = Column(String)
+ room = Column(String)
+
+ def __repr__(self):
+ return "<Customer(name='%s')>" % (self.name)
diff --git a/shopdb/_group.py b/shopdb/_group.py
new file mode 100644
index 0000000..f79d446
--- /dev/null
+++ b/shopdb/_group.py
@@ -0,0 +1,15 @@
+__all__ = ["Group"]
+
+
+from sqlalchemy import Column, Integer, String
+from sqlalchemy.orm import relationship
+from ._base import Base, engine
+
+
+class Group(Base):
+ __tablename__ = 'groups'
+ id = Column(Integer, primary_key=True)
+ name = Column(String)
+
+ def __repr__(self):
+ return "<Group(name='%s')>" % (self.name)
diff --git a/shopdb/_job.py b/shopdb/_job.py
new file mode 100644
index 0000000..13f2988
--- /dev/null
+++ b/shopdb/_job.py
@@ -0,0 +1,25 @@
+__all__ = ["Job"]
+
+
+import enum
+from sqlalchemy import Column, Integer, String, Enum
+from sqlalchemy.orm import relationship
+from ._base import Base, engine
+from ._status import Status
+
+
+class JobPriorities(enum.Enum):
+ high = 1
+ medium = 2
+ low = 3
+
+
+class Job(Base):
+ __tablename__ = 'jobs'
+ id = Column(Integer, primary_key=True)
+ name = Column(String)
+ priority = Column(Enum(JobPriorities), default="medium")
+ status_updates = relationship("Status", back_populates="job")
+
+ def __repr__(self):
+ return "<Job(name='%s')>" % (self.name)
diff --git a/shopdb/_staff.py b/shopdb/_staff.py
new file mode 100644
index 0000000..27e1944
--- /dev/null
+++ b/shopdb/_staff.py
@@ -0,0 +1,14 @@
+__all__ = ["Staff"]
+
+
+from sqlalchemy import Column, Integer, String
+from ._base import Base, engine
+
+
+class Staff(Base):
+ __tablename__ = 'staff'
+ id = Column(Integer, primary_key=True)
+ name = Column(String)
+
+ def __repr__(self):
+ return "<Staff(name='%s')>" % (self.name)
diff --git a/shopdb/_status.py b/shopdb/_status.py
new file mode 100644
index 0000000..4011048
--- /dev/null
+++ b/shopdb/_status.py
@@ -0,0 +1,30 @@
+__all__ = ["Status"]
+
+
+import enum
+from sqlalchemy import Column, Integer, String, DateTime, Enum
+from sqlalchemy.orm import relationship
+from sqlalchemy import ForeignKey
+from ._base import Base, engine
+
+
+class StatusValues(enum.Enum):
+ unstarted = 1
+ proceeding = 2
+ completed = 3
+ deferred = 4
+ waiting = 5
+ canceled = 6
+
+
+class Status(Base):
+ __tablename__ = 'event'
+ id = Column(Integer, primary_key=True)
+ comment = Column(String)
+ value = Column(Enum(StatusValues))
+ timestamp = Column(DateTime)
+ job_id = Column(Integer, ForeignKey("jobs.id"))
+ job = relationship("Job", back_populates="status_updates")
+
+ def __repr__(self):
+ return "<Status(value='%s')>" % (self.value)