diff --git a/sourcing/model.py b/sourcing/model.py index 94b5ab6..0a3cb35 100644 --- a/sourcing/model.py +++ b/sourcing/model.py @@ -5,15 +5,19 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, ForeignKey from sqlalchemy.types import String, Unicode, Integer, DateTime, Boolean, UnicodeText, Enum from sqlalchemy import func -from sqlalchemy.orm import relationship, validates, synonym +from sqlalchemy.orm import relationship, validates, synonym, configure_mappers from sqlalchemy.sql import exists from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash from sqlalchemy.ext.hybrid import hybrid_property +from sqlalchemy_continuum import make_versioned +from sqlalchemy_continuum.plugins import FlaskPlugin, ActivityPlugin import re - from hashids import Hashids +activity_plugin = ActivityPlugin() +make_versioned(plugins=[FlaskPlugin(), activity_plugin]) + doc_hashids = Hashids(min_length=8) Base = declarative_base() @@ -119,7 +123,9 @@ class User(TimeStampedModel, UserMixin): return user class Item(TimeStampedModel): + __versioned__ = {} __tablename__ = 'item' + id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('user.id')) published = Column(DateTime) @@ -148,7 +154,19 @@ class Item(TimeStampedModel): @property def url(self): - return url_for('.view_item', username=self.user.username, hashid=self.hashid) + return url_for('.view_item', + username=self.user.username, + hashid=self.hashid) + + def version_url(self, version): + return url_for('.view_item', + username=self.user.username, + hashid=self.hashid, + v=version.transaction_id) + + @property + def history_url(self): + return url_for('.history', username=self.user.username, hashid=self.hashid) @property def external_url(self): @@ -245,3 +263,6 @@ class SourceDoc(Item): return self.db_price_per_character or self.db_document_price / len(self.text) __mapper_args__ = {'polymorphic_identity': 'sourcedoc'} + + +configure_mappers() diff --git a/sourcing/templates/edit.html b/sourcing/templates/edit.html index 7359322..df3742a 100644 --- a/sourcing/templates/edit.html +++ b/sourcing/templates/edit.html @@ -21,7 +21,7 @@ {% endif %}
Revision as of {{ version.modified.strftime('%H:%M, %d %B %Y') }}
+{% endif %} -+ {%- for start, line in add_highlight(text, span_start, span_length) if line -%} +
{% for i in line %} {%- if i.highlight -%} {%- if i.highlight != '\n' and i.highlight != '\r\n' -%} @@ -42,15 +46,16 @@
{%- endfor -%} {% else %} - {%- for start, line in iter_lines(doc.text) if line -%} + {%- for start, line in iter_lines(text) if line -%} {#{% if line != "\n" and line != "\r\n" %}{{ line }}{% else %} {% endif %}
#}{{ nbsp_at_start(line) }}
{%- endfor -%} {% endif %}span:
@@ -60,7 +65,7 @@ {% block scripts %} {% endblock %} diff --git a/sourcing/view.py b/sourcing/view.py index 882925f..1070be6 100644 --- a/sourcing/view.py +++ b/sourcing/view.py @@ -16,6 +16,7 @@ from jinja2 import evalcontextfilter, Markup from functools import wraps from .utils import nbsp_at_start from itsdangerous import URLSafeTimedSerializer +from sqlalchemy_continuum import version_class import re @@ -212,14 +213,31 @@ def view_item(username, hashid, raw=False): if raw: return Response(item.text, mimetype='text/plain') + if 'v' in request.args and request.args['v'].isdigit(): + ItemVersion = version_class(Item) + version = (session.query(ItemVersion) + .filter_by(transaction_id=int(request.args['v'])) + .first()) + text = version.text + else: + version = None + text = item.text + return render_template('view.html', doc=item, + version=version, + text=text, span_start=start, span_length=length, add_highlight=add_highlight, nbsp_at_start=nbsp_at_start, iter_lines=iter_lines) +@bp.route('/