from ldsnotes.content import Content, clean_html
import re
from datetime import datetime
def make_annotation(json):
# fetch all context stuff (do it all at once to be faster) # TODO: Reparse
# this, this is unreadable
uris = []
for j in json:
if 'highlight' in j:
uris += [f"/{j['locale']}{i['uri']}" for i in j['highlight']['content']] # noqa: E501
if 'refs' in j:
uris += [f"/{j['locale']}{i['uri']}" for i in j['refs']]
content_jsons = Content.fetch(uris, json=True) if len(uris) != 0 else []
# re-sort uris
uris = [j['uri'] for j in content_jsons]
# put it back together
annotations = []
for j in json:
if j['type'] == "bookmark":
annotations.append(Bookmark(j))
elif j['type'] == "journal":
annotations.append(Journal(j))
elif j['type'] == 'highlight':
content = []
for i in j['highlight']['content']:
content.append(
content_jsons[uris.index(f"/{j['locale']}{i['uri']}")])
annotations.append(Highlight(j, content))
elif j['type'] == 'reference':
content = []
for i in j['highlight']['content']:
content.append(
content_jsons[uris.index(f"/{j['locale']}{i['uri']}")])
ref_content = []
for i in j['refs']:
ref_content.append(
content_jsons[uris.index(f"/{j['locale']}{i['uri']}")])
annotations.append(Reference(j, content, ref_content))
else:
raise ValueError("Unknown Type of note")
if len(annotations) == 1:
return annotations[0]
else:
return annotations
[docs]class Annotation:
"""Base class for all annotations.
Attributes
-----------
tags : list
List of strings of tag names.
folders_id : list
List of strings of folder ids.
last_update : datetime
Last time annotation was edited.
id : string
Id of annotation."""
def __init__(self, json):
# pull out other info
self.tags = json['tags']
self.folders_id = [i['id'] for i in json['folders']]
# pull out last updated date
self.last_update = datetime.fromisoformat(json["lastUpdated"])
# pull out id
self.id = json['id']
[docs]class Bookmark(Annotation):
"""A bookmark annotation. Inherits from annotation.
Attributes
-----------
tags : list
List of strings of tag names.
folders_id : list
List of strings of folder ids.
last_update : datetime
Last time annotation was edited.
id : string
Id of annotation.
headline : string
Name of article ie name of conference talk or Helaman 3.
reference : string
Full reference for scriptures like Helaman 3:29.
publication : string
Refers to book (ie GC 2020 or BoM).
url : string
Url to bookmark location.
"""
def __init__(self, json):
super().__init__(json)
# name of article ie name of conference talk or Helaman 3
self.headline = json['bookmark']['name']
# full reference for scriptures like Helaman 3:29
self.reference = json['bookmark']['reference']
# refers to book (ie GC 2020, or BOM)
self.publication = json['bookmark']['publication']
# pull out url to highlight
lang = json['locale']
self.url = "https://www.churchofjesuschrist.org" + \
json['bookmark']['uri'] + "?lang=" + lang
def __print__(self):
return "(Bookmark) " + self.reference
__repr__ = __print__
[docs]class Journal(Annotation):
"""A journal entry. Inherits from Annotation.
Attributes
-----------
tags : list
List of strings of tag names.
folders_id : list
List of strings of folder ids.
last_update : datetime
Last time annotation was edited.
id : string
Id of annotation.
title : string
Title of journal entry.
note : string
Actual note taken."""
def __init__(self, json):
super().__init__(json)
# pull out note if there is one
if "note" in json and 'content' in json['note']:
self.note = json['note']['content']
else:
self.note = ""
# pull title of note
if "note" in json and 'title' in json['note']:
self.title = json['note']['title']
else:
self.title = ""
def __print__(self):
more = self.note
if self.title != "":
more = self.title
return "(Journal) " + more
__repr__ = __print__
split_reg = "[— ()#¶]"
[docs]class Highlight(Journal):
"""A scripture highlight. Inherits from Journal.
Attributes
-----------
tags : list
List of strings of tag names.
folders_id : list
List of strings of folder ids.
last_update : datetime
Last time annotation was edited.
id : string
Id of annotation.
title : string
Title of journal entry.
note : string
Actual note taken.
color : string
Color of annotation.
content : string
Content of verse/paragraph(s) being highlighted.
hl : string
Portion of verse that's been highlighted.
url : string
Url to verse/paragraph(s)
headline : string
Name of article ie name of conference talk or Helaman 3.
reference : string
Full reference for scriptures like Helaman 3:29.
publication : string
Refers to book (ie GC 2020 or BoM)."""
def __init__(self, json, content_jsons):
super().__init__(json)
# get highlight color
self.color = json['highlight']['content'][0]['color']
# Some notes don't actually have style
# self.style = json['highlight']['content'][0]['style']
# pull out content
sep_content = []
for j in content_jsons:
sep_content.append(clean_html(j['content'][0]['markup']))
self.content = "\n".join(sep_content).replace("#", "")
# pull out highlight
sep_hl = []
# iterate through each paragraph/verse included
for i, (c, hl) in enumerate(
zip(sep_content, json['highlight']['content'])):
# convert start/end word offset into string index
if int(hl['startOffset']) != -1:
start = int(hl['startOffset']) - 1
hl_and_end = re.split(split_reg, c, maxsplit=start)[-1]
else:
hl_and_end = c
if int(hl['endOffset']) != -1:
stop = int(hl['endOffset'])
len_end = -len(re.split(split_reg, c, maxsplit=stop)[-1])
else:
len_end = None
# Put into note altogether
sep_hl.append(hl_and_end[:len_end].strip())
# join all together. Remove # used for word counting
self.hl = "\n".join(sep_hl).replace("#", "")
# pull out url to highlight
lang = json['locale']
self.url = "https://www.churchofjesuschrist.org/study" + \
json['highlight']['content'][0]['uri']
# if multiple verses, make url reflect that
if len(json['highlight']['content']) > 1:
end_p = json['highlight']['content'][-1]['uri'].split('.')[-1]
self.url += "-" + end_p
self.url += "?lang=" + lang
# name of article ie name of conference talk or Helaman 3
self.headline = clean_html(content_jsons[0]['headline'])
# full reference for scriptures like Helaman 3:29
self.reference = clean_html(
content_jsons[0]['referenceURIDisplayText'])
# refers to book (ie GC 2020, or BOM)
self.publication = clean_html(content_jsons[0]['publication'])
def __print__(self):
return "(Highlight) " + self.hl
__repr__ = __print__
[docs] def markdown(self, syntax="=="):
"""Returns content with the highlight wrapped in markdown syntax.
Parameters
-----------
syntax : string
String to wrap highlight in. Defaults to ==
Returns
--------
Content with wrapped highlight."""
return self.content.replace(self.hl, syntax + self.hl + syntax)
[docs]class Reference(Highlight):
"""A scripture link/reference. Inherits from Highlight.
Attributes
-----------
tags : list
List of strings of tag names.
folders_id : list
List of strings of folder ids.
last_update : datetime
Last time annotation was edited.
id : string
Id of annotation.
title : string
Title of journal entry.
note : string
Actual note taken.
color : string
Color of annotation.
content : string
Content of verse/paragraph(s) being highlighted.
hl : string
Portion of verse that's been highlighted.
url : string
Url to verse/paragraph(s)
headline : string
Name of article ie name of conference talk or Helaman 3.
reference : string
Full reference for scriptures like Helaman 3:29.
publication : string
Refers to book (ie GC 2020 or BoM).
ref_content : string
Content of verse/paragraph(s) that are linked to
ref_headline : string
Headline of reference. See headline for examples.
ref_reference : string
Reference of reference. See reference for examples.
ref_publication : string
Publication of reference. See publication for examples."""
def __init__(self, json, hl_json, ref_json):
super().__init__(json, hl_json)
# pull out reference content
# pull out content
sep_content = []
for j in ref_json:
sep_content.append(clean_html(j['content'][0]['markup']))
self.ref_content = "\n".join(sep_content).replace("#", "")
# pull out url to reference
lang = json['locale']
self.ref_url = "https://www.churchofjesuschrist.org/study" + \
json['refs'][0]['uri']
if len(json['highlight']['content']) > 1:
end_p = json['refs'][-1]['uri'].split('.')[-1]
self.ref_url += "-" + end_p
self.ref_url += "?lang=" + lang
# name of article ie name of conference talk or Helaman 3
self.ref_headline = clean_html(ref_json[0]['headline'])
# full reference for scriptures like Helaman 3:29
self.ref_reference = clean_html(ref_json[0]['referenceURIDisplayText'])
# refers to book (ie GC 2020, or BOM)
self.ref_publication = clean_html(ref_json[0]['publication'])
def __print__(self):
return "(Reference) " + self.hl
__repr__ = __print__