diff --git a/migration/extract.py b/migration/extract.py
index 5dd7ccba..d67275a9 100644
--- a/migration/extract.py
+++ b/migration/extract.py
@@ -27,6 +27,39 @@ def replace_tooltips(body):
return newbody
+
+def extract_footnotes(body, shout_dict):
+ parts = body.split("&&&")
+ lll = len(parts)
+ newparts = list(parts)
+ placed = False
+ if lll & 1:
+ if lll > 1:
+ i = 1
+ print("[extract] found %d footnotes in body" % (lll - 1))
+ for part in parts[1:]:
+ if i & 1:
+ placed = True
+ if 'a class="footnote-url" href=' in part:
+ print("[extract] footnote: " + part)
+ fn = 'a class="footnote-url" href="'
+ exxtracted_link = part.split(fn, 1)[1].split('"', 1)[0]
+ extracted_body = part.split(fn, 1)[1].split('>', 1)[1].split('', 1)[0]
+ print("[extract] footnote link: " + extracted_link)
+ with local_session() as session:
+ Reaction.create({
+ "shout": shout_dict['id'],
+ "kind": ReactionKind.FOOTNOTE,
+ "body": extracted_body,
+ "range": str(body.index(fn + link) - len('<')) + ':' + str(body.index(extracted_body) + len(''))
+ })
+ newparts[i] = "ℹ️"
+ else:
+ newparts[i] = part
+ i += 1
+ return ("".join(newparts), placed)
+
+
def place_tooltips(body):
parts = body.split("&&&")
lll = len(parts)
@@ -203,7 +236,7 @@ def extract_dataimages(parts, prefix):
di = "data:image"
-def extract_md_images(body, oid):
+def extract_md_images(body, prefix):
newbody = ""
body = (
body.replace("\n! [](" + di, "\n 
@@ -212,7 +245,7 @@ def extract_md_images(body, oid):
)
parts = body.split(di)
if len(parts) > 1:
- newbody = extract_dataimages(parts, oid)
+ newbody = extract_dataimages(parts, prefix)
else:
newbody = body
return newbody
@@ -238,24 +271,24 @@ def cleanup(body):
return newbody
-def extract_md(body, oid=""):
+def extract_md(body, shout_dict = None):
newbody = body
if newbody:
- uid = oid or uuid.uuid4()
- newbody = extract_md_images(newbody, uid)
- if not newbody:
- raise Exception("extract_images error")
-
newbody = cleanup(newbody)
if not newbody:
raise Exception("cleanup error")
- newbody, placed = place_tooltips(newbody)
- if not newbody:
- raise Exception("place_tooltips error")
+ if shout_dict:
+
+ uid = shout_dict['id'] or uuid.uuid4()
+ newbody = extract_md_images(newbody, uid)
+ if not newbody:
+ raise Exception("extract_images error")
+
+ newbody, placed = extract_footnotes(body, shout_dict)
+ if not newbody:
+ raise Exception("extract_footnotes error")
- if placed:
- newbody = "import Tooltip from '$/components/Article/Tooltip'\n\n" + newbody
return newbody
@@ -342,7 +375,9 @@ def prepare_html_body(entry):
return body
-def extract_html(entry):
+def extract_html(entry, shout_id = None):
body_orig = (entry.get("body") or "").replace('\(', '(').replace('\)', ')')
+ if shout_id:
+ extract_footnotes(body_orig, shout_id)
body_html = str(BeautifulSoup(body_orig, features="html.parser"))
return body_html
diff --git a/migration/tables/remarks.py b/migration/tables/remarks.py
index 78f52c92..026b95c6 100644
--- a/migration/tables/remarks.py
+++ b/migration/tables/remarks.py
@@ -1,31 +1,42 @@
from base.orm import local_session
from migration.extract import extract_md
from migration.html2text import html2text
-from orm.remark import Remark
+from orm.reaction import Reaction, ReactionKind
def migrate(entry, storage):
post_oid = entry['contentItem']
print(post_oid)
shout_dict = storage['shouts']['by_oid'].get(post_oid)
- remark = {
- "shout": shout_dict['id'],
- "body": extract_md(
- html2text(entry['body']),
- entry['_id']
- ),
- "desc": extract_md(
- html2text(
- entry['textAfter'] or '' + \
- entry['textBefore'] or '' + \
- entry['textSelected'] or ''
+ if shout_dict:
+ print(shout_dict['body'])
+ remark = {
+ "shout": shout_dict['id'],
+ "body": extract_md(
+ html2text(entry['body']),
+ shout_dict
),
- entry["_id"]
- )
- }
+ "kind": ReactionKind.REMARK
+ }
- with local_session() as session:
- rmrk = Remark.create(**remark)
- session.commit()
- del rmrk["_sa_instance_state"]
- return rmrk
+ if entry.get('textBefore'):
+ remark['range'] = str(
+ shout_dict['body']
+ .index(
+ entry['textBefore'] or ''
+ )
+ ) + ':' + str(
+ shout_dict['body']
+ .index(
+ entry['textAfter'] or ''
+ ) + len(
+ entry['textAfter'] or ''
+ )
+ )
+
+ with local_session() as session:
+ rmrk = Reaction.create(**remark)
+ session.commit()
+ del rmrk["_sa_instance_state"]
+ return rmrk
+ return
diff --git a/migration/tables/topics.py b/migration/tables/topics.py
index 3287adb7..17804376 100644
--- a/migration/tables/topics.py
+++ b/migration/tables/topics.py
@@ -10,7 +10,7 @@ def migrate(entry):
"slug": entry["slug"],
"oid": entry["_id"],
"title": entry["title"].replace(" ", " "),
- "body": extract_md(html2text(body_orig), entry["_id"])
+ "body": extract_md(html2text(body_orig))
}
with local_session() as session:
diff --git a/orm/reaction.py b/orm/reaction.py
index f484808a..c2b43856 100644
--- a/orm/reaction.py
+++ b/orm/reaction.py
@@ -19,6 +19,8 @@ class ReactionKind(Enumeration):
REJECT = 0 # -1
LIKE = 11 # +1
DISLIKE = 12 # -1
+ REMARK = 13
+ FOOTNOTE = 14
# TYPE = # rating diff
diff --git a/orm/remark.py b/orm/remark.py
deleted file mode 100644
index 9432a3f5..00000000
--- a/orm/remark.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from datetime import datetime
-from enum import Enum as Enumeration
-
-from sqlalchemy import Column, DateTime, Enum, ForeignKey, String
-
-from base.orm import Base
-
-
-class Remark(Base):
-
- __tablename__ = "remark"
-
- body = Column(String, nullable=False)
- desc = Column(String, default='')
- shout = Column(ForeignKey("shout.id"), nullable=True, index=True, comment="Shout")
diff --git a/resolvers/zine/reactions.py b/resolvers/zine/reactions.py
index 56bcafca..0aaa55cf 100644
--- a/resolvers/zine/reactions.py
+++ b/resolvers/zine/reactions.py
@@ -132,6 +132,23 @@ async def create_reaction(_, info, reaction={}):
reaction['createdBy'] = auth.user_id
with local_session() as session:
r = Reaction.create(**reaction)
+ shout = session.query(Shout).where(Shout.id == r.shout).one()
+
+ # Proposal accepting logix
+ if r.replyTo is not None and \
+ r.kind == ReactionKind.ACCEPT and \
+ user_id in shout.dict()['authors']:
+ replied_reaction = session.query(Reaction).when(Reaction.id == r.replyTo).first()
+ if replied_reaction and replied_reaction.kind == ReactionKind.PROPOSE:
+ if replied_reaction.range:
+ old_body = shout.body
+ start, end = replied_reaction.range.split(':')
+ start = int(start)
+ end = int(end)
+ new_body = old_body[:start] + replied_reaction.body + old_body[end:]
+ shout.body = new_body
+ # TODO: update git version control
+
session.add(r)
session.commit()
@@ -205,7 +222,9 @@ async def delete_reaction(_, info, reaction=None):
return {"error": "access denied"}
r.deletedAt = datetime.now(tz=timezone.utc)
session.commit()
- return {}
+ return {
+ "reaction": r
+ }
@query.field("loadReactionsBy")
diff --git a/resolvers/zine/remark.py b/resolvers/zine/remark.py
deleted file mode 100644
index 6f5f9d48..00000000
--- a/resolvers/zine/remark.py
+++ /dev/null
@@ -1,48 +0,0 @@
-
-from datetime import datetime, timedelta, timezone
-from sqlalchemy.orm import joinedload, aliased
-from sqlalchemy.sql.expression import desc, asc, select, func
-from base.orm import local_session
-from base.resolvers import query, mutation
-from base.exceptions import ObjectNotExist
-from orm.remark import Remark
-
-
-@mutation.field("createRemark")
-@login_required
-async def create_remark(_, info, slug, body):
- auth = info.context["request"].auth
- user_id = auth.user_id
- with local_session() as session:
- tt = Remark.create(slug=slug, body=body)
- session.commit()
- return
-
-@mutation.field("updateRemark")
-@login_required
-async def update_remark(_, info, slug, body = ''):
- auth = info.context["request"].auth
- user_id = auth.user_id
- with local_session() as session:
- rmrk = session.query(Remark).where(Remark.slug == slug).one()
- if body:
- tt.body = body
- session.add(rmrk)
- session.commit()
- return
-
-@mutation.field("deleteRemark")
-@login_required
-async def delete_remark(_, info, slug):
- auth = info.context["request"].auth
- user_id = auth.user_id
- with local_session() as session:
- rmrk = session.query(Remark).where(Remark.slug == slug).one()
- rmrk.remove()
- session.commit()
- return
-
-@query.field("loadRemark")
-@login_required
-async def load_remark(_, info, slug):
- pass
diff --git a/schema.graphql b/schema.graphql
index 080cb371..cf66d24d 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -407,6 +407,9 @@ enum ReactionKind {
PROPOSE
ASK
+ REMARK
+ FOOTNOTE
+
ACCEPT
REJECT
}