This commit is contained in:
parent
db86cf3392
commit
891bcd4181
@ -9,8 +9,8 @@ from collections import defaultdict
|
||||
from urllib.parse import urlparse
|
||||
from datetime import datetime, timedelta
|
||||
from photoapp.thumbtool import ThumbGenerator
|
||||
from photoapp.types import APPROOT, Photo, PhotoSet, Tag, TagItem, PhotoStatus, User, mime2ext, \
|
||||
regular_mimes, video_mimes, ftypes
|
||||
from photoapp.types import APPROOT, Photo, PhotoSet, Tag, TagItem, PhotoStatus, User, Job, JobTarget, JobTargetStatus, \
|
||||
JobTargetState, mime2ext, regular_mimes, video_mimes, ftypes
|
||||
from photoapp.dbsession import DatabaseSession
|
||||
from photoapp.common import pwhash
|
||||
from photoapp.api import PhotosApi, LibraryManager
|
||||
@ -45,6 +45,7 @@ class PhotosWeb(object):
|
||||
self.tag = TagView(self)
|
||||
self.album = self.tag
|
||||
self.search = SearchView(self)
|
||||
self.jobs = JobsView(self)
|
||||
|
||||
def render(self, template, **kwargs):
|
||||
"""
|
||||
@ -620,6 +621,45 @@ class SearchView(object):
|
||||
)
|
||||
|
||||
|
||||
@cherrypy.popargs('uuid')
|
||||
class JobsView(object):
|
||||
def __init__(self, master):
|
||||
self.master = master
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self, uuid=None):
|
||||
if uuid is None:
|
||||
return self.index_alljobs()
|
||||
else:
|
||||
return self.index_onejob(uuid)
|
||||
|
||||
def index_alljobs(self):
|
||||
jobs = db.query(Job).all()
|
||||
|
||||
yield self.master.render("jobs.html", jobs=jobs)
|
||||
|
||||
def index_onejob(self, uuid):
|
||||
job = db.query(Job).filter(Job.uuid == uuid).first()
|
||||
if not job:
|
||||
raise cherrypy.HTTPError(404)
|
||||
|
||||
statuses = db.query(Photo, PhotoSet, JobTargetStatus, JobTarget) \
|
||||
.join(PhotoSet) \
|
||||
.join(JobTargetStatus) \
|
||||
.join(JobTarget) \
|
||||
.filter(JobTarget.job_id == job.id) \
|
||||
.all()
|
||||
|
||||
status_totals = {i: 0 for i in JobTargetState}
|
||||
for state, count in db.query(JobTargetStatus.status, func.count(JobTargetStatus.status)) \
|
||||
.filter(JobTargetStatus.job_id == job.id) \
|
||||
.group_by(JobTargetStatus.status) \
|
||||
.all():
|
||||
status_totals[state] = count
|
||||
|
||||
yield self.master.render("job.html", job=job, statuses=statuses, status_totals=status_totals)
|
||||
|
||||
|
||||
def setup_webapp(
|
||||
database_engine,
|
||||
library_client,
|
||||
|
@ -158,6 +158,8 @@ class Photo(Base):
|
||||
format = Column(String(length=32)) # TODO how long can a mime string be
|
||||
fname = Column(String(length=64)) # seems generous enough
|
||||
|
||||
job_statuses = relationship("JobTargetStatus", back_populates="photo")
|
||||
|
||||
def to_json(self):
|
||||
j = {attr: getattr(self, attr) for attr in
|
||||
{"uuid", "size", "width", "height", "orientation", "format", "hash", "fname"}}
|
||||
@ -297,6 +299,7 @@ class JobTargetStatus(Base):
|
||||
- tag: same as photoset but iterated across all photosets with the tag
|
||||
"""
|
||||
photo_id = Column(Integer, ForeignKey("files.id"), nullable=False)
|
||||
photo = relationship(Photo, back_populates="job_statuses", foreign_keys=[photo_id])
|
||||
|
||||
status = Column(Enum(JobTargetState), nullable=False, default=JobTargetState.new)
|
||||
|
||||
|
47
templates/job.html
Normal file
47
templates/job.html
Normal file
@ -0,0 +1,47 @@
|
||||
{% set title = job.uuid %}
|
||||
{% extends "page.html" %}
|
||||
{% block title %}{{ job.uuid }}{% endblock %}
|
||||
{% block subtitle %}{{ job.status.name | title }}{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<a href="#"><button class="secondary-button pure-button">Pause</button></a>
|
||||
<a href="#"><button class="secondary-button pure-button">Cancel</button></a>
|
||||
<a href="/jobs"><button class="secondary-button pure-button">All Jobs</button></a>
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
lol head
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{{ job }}
|
||||
|
||||
<h2>Progress</h2>
|
||||
|
||||
<table>
|
||||
{% for status, count in status_totals.items(): %}
|
||||
<tr>
|
||||
<td>{{ status }}</td>
|
||||
<td>{{ count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h2>Targets</h2>
|
||||
|
||||
Table of target -> how many photos it selected
|
||||
|
||||
<h2>Target photos</h2>
|
||||
<ul>
|
||||
{% for photo, photoset, target_status, target in statuses %}
|
||||
<li>
|
||||
target: {{ target.id }}<br>
|
||||
target_status: {{ target_status.id }}<br>
|
||||
photo: <a href="/thumb/one/big/{{ photo.uuid }}.jpg">{{ photo.uuid }}</a><br />
|
||||
set: <a href="/photo/{{ photoset.uuid }}">{{ photoset.uuid }}</a><br />
|
||||
status: {{ target_status.status }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
25
templates/jobs.html
Normal file
25
templates/jobs.html
Normal file
@ -0,0 +1,25 @@
|
||||
{% set title = "title todo" %}
|
||||
{% extends "page.html" %}
|
||||
{% block title %}Jobs{% endblock %}
|
||||
{% block subtitle %}subtitle todo{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<a href="/jobs"><button class="secondary-button pure-button">New</button></a>
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
lol head
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<ul>
|
||||
{% for job in jobs %}
|
||||
<li>
|
||||
uuid: <a href="jobs/{{ job.uuid }}">{{ job.uuid }}</a><br />
|
||||
status: {{ job.status }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -18,6 +18,7 @@
|
||||
<li class="pure-menu-item"><a href="/search" class="pure-menu-link">Search</a></li>
|
||||
<li class="pure-menu-item"><a href="/date" class="pure-menu-link">Dates</a></li>
|
||||
<li class="pure-menu-item"><a href="/map" class="pure-menu-link">Map</a></li>
|
||||
<li class="pure-menu-item"><a href="/jobs" class="pure-menu-link">Jobs</a></li>
|
||||
<li class="pure-menu-item"><a href="/stats" class="pure-menu-link">Stats</a></li>
|
||||
<li class="pure-menu-heading">Albums</li>
|
||||
{% for tag in all_tags %}{% if tag.is_album %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user