Browse Source

Some cosmetic changes

theenglishway (time) 6 years ago
parent
commit
1e3e2af7d4
6 changed files with 74 additions and 18 deletions
  1. 11 1
      planner/__init__.py
  2. 29 6
      planner/cli.py
  3. 9 1
      planner/models/milestones.py
  4. 5 0
      planner/models/mixins.py
  5. 9 9
      planner/models/sprints.py
  6. 11 1
      planner/validator.py

+ 11 - 1
planner/__init__.py

@@ -1,3 +1,5 @@
+import json
+from datetime import datetime
 from tinydb import TinyDB
 from cerberus import schema_registry
 
@@ -7,7 +9,15 @@ __author__ = """theenglishway"""
 __email__ = 'me@theenglishway.eu'
 __version__ = '0.1.0'
 
-db = TinyDB('planning.json', indent=4)
+
+class Encoder(json.JSONEncoder):
+    def default(self, o):
+        if isinstance(o, datetime):
+            return o.strftime("%c %z")
+
+        return o.__dict__
+
+db = TinyDB('planning.json', indent=4, cls=Encoder)
 validator = DbValidator(db)
 
 from planner.models import *

+ 29 - 6
planner/cli.py

@@ -22,11 +22,11 @@ def sprint(ctx):
     """Handle sprints"""
     ctx.obj['model'] = Sprint
 
-@click.command()
+@milestone.command('new')
 @click.option('--name', prompt='Milestone name')
 @click.option('--description', prompt='Milestone description')
 @click.pass_context
-def new(ctx, name, description):
+def new_milestone(ctx, name, description):
     """Add a new milestone"""
     model = ctx.obj['model']
     data = {
@@ -35,21 +35,44 @@ def new(ctx, name, description):
     }
     ok, m_doc = model.validate(data)
     if ok :
-        m = model.create(m_doc)
+        m = model.get(m_doc)
+        click.secho(f"{m} was successfully added", fg='green')
+        m.save()
+    else:
+        click.secho(f"Errors : {m_doc}", fg='red')
+
+@sprint.command('new')
+@click.option('--name', prompt='Sprint name')
+@click.option('--description', prompt='Sprint description')
+@click.option('--milestone_id', prompt='Related milestone ID', type=int)
+@click.pass_context
+def new_sprint(ctx, name, description, milestone_id):
+    """Add a new sprint"""
+    model = ctx.obj['model']
+    data = {
+        'name': name,
+        'description': description,
+        'milestone_id': milestone_id
+    }
+    ok, m_doc = model.validate(data)
+    if ok :
+        m = model.get(m_doc)
+        click.secho(f"{m} was successfully added", fg='green')
         m.save()
+    else:
+        click.secho(f"Errors : {m_doc}", fg='red')
 
 @click.command()
 @click.pass_context
 def list(ctx):
     """List"""
     model = ctx.obj['model']
-    click.echo(model.list())
+    list = model.list()
+    click.echo('\n'.join([i.__terminal__() for i in list]))
 
 
-milestone.add_command(new)
 milestone.add_command(list)
 
-sprint.add_command(new)
 sprint.add_command(list)
 
 if __name__ == '__main__':

+ 9 - 1
planner/models/milestones.py

@@ -1,4 +1,6 @@
-from dataclasses import dataclass
+import click
+
+from dataclasses import dataclass, field
 from datetime import datetime
 
 from .mixins import SchemaMixin, DbMixin
@@ -9,6 +11,7 @@ class Milestone(SchemaMixin, DbMixin):
     document: dict
     name: str
     description: str
+    date_added: datetime = None
     date_expected: datetime = None
     date_started: datetime = None
 
@@ -20,6 +23,9 @@ class Milestone(SchemaMixin, DbMixin):
         description:
             required: true
             type: string
+        date_added:
+            type: datetime
+            default_setter: utcnow
         date_expected: 
             type: date
         date_started:
@@ -29,3 +35,5 @@ class Milestone(SchemaMixin, DbMixin):
     def __repr__(self):
         return "{}(name='{}')".format(self.__class__.__qualname__, self.name)
 
+    def __terminal__(self):
+        return click.style(f"Milestone : {self.name}")

+ 5 - 0
planner/models/mixins.py

@@ -34,5 +34,10 @@ class DbMixin:
     def get(cls, document):
         return cls(document=document, **document)
 
+    @classmethod
+    def fetch(cls, doc_id):
+        document = db.table(cls.class_name()).get(doc_id=doc_id)
+        return cls(document=document, **document)
+
     def save(self):
         db.table(self.class_name()).insert(self.document)

+ 9 - 9
planner/models/sprints.py

@@ -2,7 +2,6 @@ from dataclasses import dataclass
 from datetime import datetime
 from copy import deepcopy
 
-from planner import db
 from .mixins import SchemaMixin, DbMixin
 from .milestones import Milestone
 
@@ -13,6 +12,7 @@ class Sprint(SchemaMixin, DbMixin):
     name: str
     description: str
     milestone: Milestone
+    date_added: datetime = None
     date_expected: datetime = None
     date_started: datetime = None
 
@@ -30,19 +30,19 @@ class Sprint(SchemaMixin, DbMixin):
         milestone_id:
             required: true
             is_fk: milestone
+        date_added:
+            type: datetime
+            default_setter: utcnow
     """
 
     @classmethod
     def get(cls, document):
         kwargs = deepcopy(document)
-        milestone = Milestone.get(db.table(Milestone.class_name()).get(doc_id=kwargs.pop('milestone_id')))
-        return cls(document=document, milestone=milestone, **kwargs)
-
-    @classmethod
-    def create(cls, document):
-        kwargs = deepcopy(document)
-        milestone = db.table(Milestone.class_name()).get(doc_id=kwargs.pop('milestone_id'))
+        milestone = Milestone.fetch(kwargs.pop('milestone_id'))
         return cls(document=document, milestone=milestone, **kwargs)
 
     def __repr__(self):
-        return "{}(name='{}', milestone='{}')".format(self.__class__.__qualname__, self.name, repr(self.milestone))
+        return "{}(name='{}', milestone='{}')".format(self.__class__.__qualname__, self.name, repr(self.milestone))
+
+    def __terminal__(self):
+        return f"Sprint : {self.name}"

+ 11 - 1
planner/validator.py

@@ -1,5 +1,6 @@
 from tinydb import Query
 from cerberus import Validator
+from datetime import datetime
 
 
 class DbValidator(Validator):
@@ -10,6 +11,7 @@ class DbValidator(Validator):
     def _validate_is_fk(self, table_name, field, value):
         """ {'type': 'string'} """
         table = self.db.table(table_name)
+        print(table)
         if not table.get(doc_id=value):
             self._error(field, "No value found in {}".format(table_name))
 
@@ -36,4 +38,12 @@ class DbValidator(Validator):
         table = self.db.table(defs['table'])
         all_fields = field, *defs['fields']
         if table.search(make_query(*all_fields)):
-            self._error(field, "Value '{}' is already present in the database".format(value))
+            self._error(
+                field,
+                "Value with same fields '{}' is already present in the database".format(
+                    ', '.join(all_fields)
+                )
+            )
+
+    def _normalize_default_setter_utcnow(self, document):
+        return datetime.utcnow()