Quellcode durchsuchen

Add comments, items models + list command

theenglishway (time) vor 6 Jahren
Ursprung
Commit
7ba73ebeff
5 geänderte Dateien mit 172 neuen und 22 gelöschten Zeilen
  1. 52 21
      pyplanner/cli.py
  2. 19 0
      pyplanner/database.py
  3. 5 1
      pyplanner/models/__init__.py
  4. 28 0
      pyplanner/models/comments.py
  5. 68 0
      pyplanner/models/items.py

+ 52 - 21
pyplanner/cli.py

@@ -9,9 +9,7 @@ from .models import *
 def main(ctx, db_url):
     """Basic CLI project-handling"""
     ctx.ensure_object(dict)
-    db = Database(db_url)
-    ctx.obj['db'] = db
-    ctx.obj['session'] = db.session_factory()
+    ctx.obj['db'] = Database(db_url)
 
 
 @main.command()
@@ -37,26 +35,59 @@ def milestone(ctx):
     ctx.obj['model'] = Milestone
 
 
-@milestone.command('new')
-@click.option('--name', prompt='Milestone name')
-@click.option('--description', prompt='Milestone description')
+@main.group()
+@click.pass_context
+def sprint(ctx):
+    """Handle sprints"""
+    ctx.obj['model'] = Sprint
+
+
+@main.group()
+@click.pass_context
+def item(ctx):
+    """Handle items"""
+    ctx.obj['model'] = Item
+
+
+@main.group()
+@click.pass_context
+def comment(ctx):
+    """Handle comments"""
+    ctx.obj['model'] = Comment
+
+
+@click.command('new')
+@click.option('--name', prompt='Name')
+@click.option('--description', prompt='Description')
+@click.pass_context
+def new(ctx, **data):
+    """Add new content"""
+    model = ctx.obj['model']
+    db = ctx.obj['db']
+    try:
+        instance = db.add(model, data)
+        click.echo(instance)
+    except ValueError as e:
+        click.echo(e.args[0])
+
+
+@click.command('list')
 @click.pass_context
-def new_milestone(ctx, name, description):
-    """Add a new milestone"""
+def list(ctx):
+    """List content"""
     model = ctx.obj['model']
-    session = ctx.obj['session']
-    data = {
-        'name': name,
-        'description': description,
-        'uuid': 'pouet'
-    }
-    ok, errors = model.validate(data)
-    if ok :
-        m = model(**data)
-        session.add(m)
-        session.commit()
-    else:
-        click.echo(errors)
+    db = ctx.obj['db']
+    click.echo(db.list(model))
+
+
+milestone.add_command(new)
+milestone.add_command(list)
+sprint.add_command(new)
+sprint.add_command(list)
+item.add_command(new)
+item.add_command(list)
+comment.add_command(new)
+comment.add_command(list)
 
 
 if __name__ == '__main__':

+ 19 - 0
pyplanner/database.py

@@ -3,6 +3,7 @@ from sqlalchemy.orm import sessionmaker
 from sqlalchemy.ext.declarative import declarative_base
 import inspect
 from ruamel import yaml
+import uuid
 
 
 SQLABase = declarative_base()
@@ -12,6 +13,7 @@ yaml = yaml.YAML()
 yaml.default_flow_style = False
 yaml.allow_unicode = True
 
+
 class Database:
     def __init__(self, db_url):
         self.engine = create_engine(db_url)
@@ -23,6 +25,23 @@ class Database:
             if inspect.isclass(v) and issubclass(v, SQLABase)
         }
 
+    def add(self, model, data):
+        session = self.session_factory()
+        data.update({'uuid': uuid.uuid4().hex})
+
+        ok, errors = model.validate(data)
+        if ok:
+            m = model(**data)
+            session.add(m)
+            session.commit()
+            return m
+        else:
+            raise ValueError(errors)
+
+    def list(self, model):
+        session = self.session_factory()
+        return session.query(model).all()
+
     def dump(self, file):
         session = self.session_factory()
         instances_dict = {}

+ 5 - 1
pyplanner/models/__init__.py

@@ -31,8 +31,12 @@ class Base:
 
 from .milestones import Milestone
 from .sprints import Sprint
+from .items import Item
+from .comments import Comment
 
 __all__ = [
     'Milestone',
-    'Sprint'
+    'Sprint',
+    'Item',
+    'Comment'
 ]

+ 28 - 0
pyplanner/models/comments.py

@@ -0,0 +1,28 @@
+from pyplanner.database import SQLABase
+from pyplanner.models import Base
+from sqlalchemy import Column, Integer, String, Text, ForeignKey
+from sqlalchemy.orm import relationship, backref
+from pydantic import BaseModel
+
+
+class SchemaComment(BaseModel):
+    name: str
+    description: str
+    type: str
+    uuid: str
+
+    milestone_id: int
+    sprint_id: int
+
+    priority: str
+    length: str
+
+class Comment(SQLABase, Base):
+    __tablename__ = 'comments'
+    id = Column(Integer, primary_key=True)
+
+    text = Column(Text)
+    uuid = Column(String)
+
+    item_id = Column(Integer, ForeignKey('items.id'))
+    item = relationship('Item', backref=backref('comments'))

+ 68 - 0
pyplanner/models/items.py

@@ -0,0 +1,68 @@
+from pyplanner.database import SQLABase
+from pyplanner.models import Base
+from sqlalchemy import Column, Integer, String, Text, ForeignKey
+from sqlalchemy.orm import relationship, backref
+from pydantic import BaseModel
+
+
+class SchemaItem(BaseModel):
+    name: str
+    description: str
+    type: str
+    uuid: str
+
+    milestone_id: int
+    sprint_id: int
+
+    priority: str
+    length: str
+
+
+class Item(SQLABase, Base):
+    _schema = SchemaItem
+
+    __tablename__ = 'items'
+    id = Column(Integer, primary_key=True)
+
+    name = Column(String)
+    description = Column(Text)
+    uuid = Column(String)
+    type = Column(String)
+
+    milestone_id = Column(Integer, ForeignKey('milestones.id'))
+    milestone = relationship('Milestone', backref=backref('items'))
+
+    sprint_id = Column(Integer, ForeignKey('sprints.id'))
+    sprint = relationship('Sprint', backref=backref('items'))
+
+    priority = Column(String)
+    length = Column(String)
+
+    __mapper_args__ = {
+        'polymorphic_on': type,
+        'polymorphic_identity': 'item'
+    }
+
+
+class Limitation(Item):
+    __mapper_args__ = {
+        'polymorphic_identity': 'limitation'
+    }
+
+
+class Feature(Item):
+    __mapper_args__ = {
+        'polymorphic_identity': 'feature'
+    }
+
+
+class Constraint(Item):
+    __mapper_args__ = {
+        'polymorphic_identity': 'constraint'
+    }
+
+
+class Unknown(Item):
+    __mapper_args__ = {
+        'polymorphic_identity': 'unknown'
+    }