diff --git a/photoapp/daemon.py b/photoapp/daemon.py index 4b23f73..0b526ac 100644 --- a/photoapp/daemon.py +++ b/photoapp/daemon.py @@ -138,6 +138,36 @@ class PhotoView(object): # yield "viewing {}".format(uuid) + @cherrypy.expose + def tag(self, uuid): + s = self.master.session() + photo = s.query(PhotoSet).filter(PhotoSet.uuid == uuid).first() + alltags = s.query(Tag).order_by(Tag.title).all() + yield self.master.tpl.get_template("photo_tag.html").render(image=photo, alltags=alltags) + + @cherrypy.expose + def tag_create(self, uuid, tag): + # TODO validate uuid ? + s = self.master.session() + s.add(Tag(title=tag)) # TODO slug + # TODO generate slug now or in model? + s.commit() + raise cherrypy.HTTPRedirect('/photo/{}/tag'.format(uuid), 302) + + @cherrypy.expose + def tag_add(self, uuid, tag): + # TODO validate uuid ? + # TODO validate tag ? + s = self.master.session() + tag = s.query(Tag).filter(Tag.uuid == tag).first() + item = s.query(PhotoSet).filter(PhotoSet.uuid == uuid).first() + s.add(TagItem(tag_id=tag.id, set_id=item.id)) + try: + s.commit() + except IntegrityError: # tag already applied + pass + raise cherrypy.HTTPRedirect('/photo/{}/tag'.format(uuid), 302) + def main(): import argparse diff --git a/photoapp/types.py b/photoapp/types.py index a0fada4..1b01a65 100644 --- a/photoapp/types.py +++ b/photoapp/types.py @@ -1,6 +1,8 @@ from sqlalchemy import Column, Integer, String, DateTime, Unicode, DECIMAL, ForeignKey from sqlalchemy.orm import relationship +from sqlalchemy.schema import UniqueConstraint from sqlalchemy.ext.declarative import declarative_base +from datetime import datetime import uuid @@ -11,12 +13,13 @@ class PhotoSet(Base): __tablename__ = 'photos' id = Column(Integer, primary_key=True) - uuid = Column(Unicode, default=lambda: str(uuid.uuid4())) + uuid = Column(Unicode, unique=True, default=lambda: str(uuid.uuid4())) date = Column(DateTime) lat = Column(DECIMAL(precision=11)) lon = Column(DECIMAL(precision=11)) files = relationship("Photo", back_populates="set") + tags = relationship("TagItem", back_populates="set") title = Column(String) description = Column(String) @@ -27,7 +30,7 @@ class Photo(Base): id = Column(Integer, primary_key=True) set_id = Column(Integer, ForeignKey("photos.id")) - uuid = Column(Unicode, default=lambda: str(uuid.uuid4())) + uuid = Column(Unicode, unique=True, default=lambda: str(uuid.uuid4())) set = relationship("PhotoSet", back_populates="files", foreign_keys=[set_id]) @@ -44,11 +47,11 @@ class Tag(Base): __tablename__ = 'tags' id = Column(Integer, primary_key=True) - uuid = Column(Unicode, default=lambda: str(uuid.uuid4())) - created = Column(DateTime) - modified = Column(DateTime) - title = Column(String) - slug = Column(String) + uuid = Column(Unicode, unique=True, default=lambda: str(uuid.uuid4())) + created = Column(DateTime, default=lambda: datetime.now()) + modified = Column(DateTime, default=lambda: datetime.now()) + title = Column(String, unique=True) + slug = Column(String, unique=True) description = Column(String) entries = relationship("TagItem", back_populates="tag") @@ -59,8 +62,10 @@ class TagItem(Base): id = Column(Integer, primary_key=True) tag_id = Column(Integer, ForeignKey("tags.id")) + set_id = Column(Integer, ForeignKey("photos.id")) + order = Column(Integer, default=0) tag = relationship("Tag", back_populates="entries", foreign_keys=[tag_id]) + set = relationship("PhotoSet", back_populates="tags", foreign_keys=[set_id]) - item_uuid = Column(String, unique=True) - order = Column(Integer, default=0) + UniqueConstraint(tag_id, set_id) diff --git a/styles/less/main.less b/styles/less/main.less index 8abd8f9..4745847 100644 --- a/styles/less/main.less +++ b/styles/less/main.less @@ -2,9 +2,12 @@ box-sizing: border-box; } + +@linkcolor: #1b98f8; + a { text-decoration: none; - color: #1b98f8; + color: @linkcolor; } #layout, #nav, #list, #main { @@ -204,4 +207,35 @@ a { max-width: 100px; } } + .photo-tags { + h2 a { + font-weight: normal; + font-size: 14px; + } + } +} + +.photo-tagging { + img { + float: left; + padding: 0px 20px 20px 0px; + } +} + +.tags-picker { + ul { + + } + li { + display: inline-block; + padding-right: 15px; + } + input.submit-link { + border: 0; + background: none; + color: @linkcolor; + &:hover { + text-decoration: underline; + } + } } diff --git a/templates/photo.html b/templates/photo.html index 08dcae7..5318057 100644 --- a/templates/photo.html +++ b/templates/photo.html @@ -36,7 +36,15 @@ {{ img.path | basename }}
- {{ img.size | filesizeformat }} - {{ img.format }} + {{ img.size | filesizeformat }} - {{ img.width }} x {{ img.height }} +
+ {% if img.orientation > 0 %} +
+ Rotation: {{ img.orientation * 90 }}° +
+ {% endif %} +
+ {{ img.format }}
download @@ -47,6 +55,16 @@ {% endfor %}
+
+

Tags add

+ +
diff --git a/templates/photo_tag.html b/templates/photo_tag.html new file mode 100644 index 0000000..c9dcd7c --- /dev/null +++ b/templates/photo_tag.html @@ -0,0 +1,43 @@ +{% set title = "Placeholder Title" %} +{% set subtitle = image.uuid %} + +{% include "page-top.html" %} + + +
+
+

Current Tags

+ + + + +
+
+

All tags

+ +
+
+

Add tag

+
+ + +
+
+
+ +{% include "page-bottom.html" %}