basic tagging

This commit is contained in:
dave 2018-09-09 16:47:21 -07:00
parent 1ff3e2106b
commit 018faecc3a
5 changed files with 141 additions and 11 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -36,7 +36,15 @@
{{ img.path | basename }}
</div>
<div>
{{ img.size | filesizeformat }} - {{ img.format }}
{{ img.size | filesizeformat }} - {{ img.width }} x {{ img.height }}
</div>
{% if img.orientation > 0 %}
<div>
Rotation: {{ img.orientation * 90 }}&deg;
</div>
{% endif %}
<div>
{{ img.format }}
</div>
<div>
<a href="/download/one/{{ img.uuid }}">download</a>
@ -47,6 +55,16 @@
{% endfor %}
</ul>
</div>
<div class="photo-tags">
<h2>Tags <a href="/photo/{{ image.uuid }}/tag">add</a></h2>
<ul class="tags-picker">
{% for tagi in image.tags %}
<li>
<a href="/tags/{{ tagi.tag.uuid }}">{{ tagi.tag.title }}</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>

43
templates/photo_tag.html Normal file
View File

@ -0,0 +1,43 @@
{% set title = "Placeholder Title" %}
{% set subtitle = image.uuid %}
{% include "page-top.html" %}
<div class="photo-tagging pure-g">
<div class="current-tags pure-u-1-3">
<h2>Current Tags</h2>
<a href="/photo/{{ image.uuid }}">
<img src="/thumb/set/small/{{ image.uuid }}.jpg" />
</a>
<ul class="tags-picker">
{% for tagi in image.tags %}
<li>
<a href="/tags/{{ tagi.tag.uuid }}">{{ tagi.tag.title }}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="all-tags pure-u-1-3">
<h2>All tags</h2>
<ul class="tags-picker">
{% for tag in alltags %}
<li>
<form action="/photo/{{ image.uuid }}/tag_add" method="post">
<input type="hidden" name="tag" value="{{ tag.uuid }}" />
<input class="submit-link" type="submit" value="{{ tag.title }}" />
</form>
</li>
{% endfor %}
</ul>
</div>
<div class="add-tags pure-u-1-3">
<h2>Add tag</h2>
<form action="/photo/{{ image.uuid }}/tag_create" method="post" class="pure-form">
<input type="text" name="tag" placeholder="new tag name" />
<input type="submit" value="Add" class="pure-button pure-button-primary" />
</form>
</div>
</div>
{% include "page-bottom.html" %}