From 30ee2a36ed23f1c6044ff25275edca4062a1a3e9 Mon Sep 17 00:00:00 2001 From: Shanee Date: Mon, 7 Feb 2022 13:52:25 -0500 Subject: [PATCH 01/11] Adds class `typeQF` from link type `quotation_auto` for easy QA for content team. --- static/css/s2.css | 4 ++++ static/js/TextList.jsx | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 8f39a6c52b..cacc98a922 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -5978,6 +5978,10 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus .textListTextRangeBox { position: relative; } + +.textListTextRangeBox.typeQF { + color: red; +} .textListTextRangeBox .textRange{ margin-bottom: 0; padding-bottom: 0; diff --git a/static/js/TextList.jsx b/static/js/TextList.jsx index f54908937e..949ae1b863 100644 --- a/static/js/TextList.jsx +++ b/static/js/TextList.jsx @@ -12,7 +12,7 @@ import Sefaria from './sefaria/sefaria'; import PropTypes from 'prop-types'; import TextRange from './TextRange'; import Component from 'react-class'; - +import classNames from 'classnames'; class TextList extends Component { constructor(props) { @@ -216,7 +216,8 @@ class TextList extends Component { key={i + link.anchorRef} />); } else { var hideTitle = link.category === "Commentary" && this.props.filter[0] !== "Commentary"; - return (
+ const classes = classNames({ textListTextRangeBox: 1, typeQF: link.type === 'quotation_auto'}); + return (
Date: Mon, 7 Feb 2022 15:11:44 -0500 Subject: [PATCH 02/11] typeQF color change only to the title. --- static/css/s2.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index cacc98a922..42e51bd376 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -5045,7 +5045,7 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus color: var(--inline-link-blue); } .segment .he sup { - font-size: 0.5em; + font-size: 0.6em; } .segment sup:hover { text-decoration: underline; @@ -5062,7 +5062,7 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus .segment sup.itag { text-decoration: none; font-family: var(--hebrew-sans-serif-font-family); - font-size: 0.6em; + font-size: 0.5em; line-height: 1; color: var(--inline-link-blue); } @@ -5979,8 +5979,8 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus position: relative; } -.textListTextRangeBox.typeQF { - color: red; +.textListTextRangeBox.typeQF .titleBox{ + color: forestgreen; } .textListTextRangeBox .textRange{ margin-bottom: 0; From 8d6dd633f97e7a34b14ddbb2d942d6ea78e5c984 Mon Sep 17 00:00:00 2001 From: Shanee Date: Tue, 15 Feb 2022 13:15:36 -0500 Subject: [PATCH 03/11] Fix to parsing ranged Refs for books with a 2 and 3 part name (ex. Chronicles I,II) --- sefaria/model/tests/he_ref_test.py | 1 + sefaria/model/tests/ref_test.py | 2 ++ sefaria/model/text.py | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sefaria/model/tests/he_ref_test.py b/sefaria/model/tests/he_ref_test.py index b39945a814..d222d548ea 100644 --- a/sefaria/model/tests/he_ref_test.py +++ b/sefaria/model/tests/he_ref_test.py @@ -295,6 +295,7 @@ def test_hebrew_range_simple(self): assert m.Ref('שמות, כ"ד, יג-יד') == m.Ref('Exodus 24:13-14') assert m.Ref('במדבר, כ"ז, טו - כג') == m.Ref("Numbers 27:15-23") assert m.Ref('במדבר, כ"ז, טו -כ״ט כג') == m.Ref("Numbers 27:15-29:23") + assert m.Ref('דברי הימים א ט״ו:ט״ו - דברי הימים א ט״ז:י״ז') == m.Ref('I Chronicles 15:15-16:17') def test_hebrew_range_with_colons(self): assert m.Ref('רות ג:יח-ד:א') == m.Ref("Ruth 3:18-4:1") diff --git a/sefaria/model/tests/ref_test.py b/sefaria/model/tests/ref_test.py index 92b28a34d5..5a7eae618f 100644 --- a/sefaria/model/tests/ref_test.py +++ b/sefaria/model/tests/ref_test.py @@ -28,6 +28,8 @@ def test_bible_range(self): assert ref.toSections == [7, 18] ref = Ref("Jeremiah 7:17\u201118") # test with unicode dash assert ref.toSections == [7, 18] + ref = Ref("I Chronicles 1:2 - I Chronicles 1:3") # test with unicode dash + assert ref.toSections == [1, 3] def test_short_bible_refs(self): assert Ref("Exodus") != Ref("Exodus 1") diff --git a/sefaria/model/text.py b/sefaria/model/text.py index ed30b8c0c5..b89561cdf1 100644 --- a/sefaria/model/text.py +++ b/sefaria/model/text.py @@ -2811,7 +2811,10 @@ def __init_tref(self): base_wout_title = base.replace(title + " ", "") address_class.parse_range_end(self, parts, base_wout_title) elif len(parts) == 2: # Parse range end portion, if it exists - self._parse_range_end(re.split("[.:, ]+", parts[1])) + try: + self.toSections = Ref(parts[1]).sections + except InputError: + self._parse_range_end(re.split("[.:, ]+", parts[1])) def _parse_range_end(self, range_parts): From b38bd504a498ff40933ce5ee8798a5421910dd00 Mon Sep 17 00:00:00 2001 From: Shanee Date: Tue, 8 Mar 2022 12:23:02 -0500 Subject: [PATCH 04/11] typeQf can contain the mode in it. --- static/js/TextList.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/js/TextList.jsx b/static/js/TextList.jsx index 949ae1b863..01c274cf69 100644 --- a/static/js/TextList.jsx +++ b/static/js/TextList.jsx @@ -216,7 +216,7 @@ class TextList extends Component { key={i + link.anchorRef} />); } else { var hideTitle = link.category === "Commentary" && this.props.filter[0] !== "Commentary"; - const classes = classNames({ textListTextRangeBox: 1, typeQF: link.type === 'quotation_auto'}); + const classes = classNames({ textListTextRangeBox: 1, typeQF: link.type.startsWith('quotation_auto')}); return (
Date: Wed, 16 Mar 2022 16:28:02 -0400 Subject: [PATCH 05/11] override preciselink option. plus a logic fix in previous lines. --- reader/views.py | 3 +++ sefaria/model/link.py | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/reader/views.py b/reader/views.py index 27cfd5ab5d..23f1595179 100644 --- a/reader/views.py +++ b/reader/views.py @@ -1899,12 +1899,15 @@ def _internal_do_delete(request, link_id_or_ref, uid): j = json.loads(j) skip_check = request.GET.get("skip_lang_check", 0) + override_preciselink = request.GET.get("override_preciselink", 0) if isinstance(j, list): res = [] for i in j: try: if skip_check: i["_skip_lang_check"] = True + if override_preciselink: + i["_override_preciselink"] = True retval = _internal_do_post(request, i, uid, **kwargs) res.append({"status": "ok. Link: {} | {} Saved".format(retval["ref"], retval["anchorRef"])}) except Exception as e: diff --git a/sefaria/model/link.py b/sefaria/model/link.py index 351afd6613..e4c664e61d 100644 --- a/sefaria/model/link.py +++ b/sefaria/model/link.py @@ -90,14 +90,14 @@ def _validate(self): def _pre_save(self): if getattr(self, "_id", None) is None: # Don't bother saving a connection that already exists, or that has a more precise link already - if self.refs != sorted(self.refs) and hasattr(self, 'charLevelData'): - self.charLevelData.reverse() - orig_refs = self.refs - self.refs = sorted(self.refs) #make sure ref order is deterministic - if orig_refs != self.refs and getattr(self, "versions", False) and getattr(self, "displayedText", False): - #if reversed self.refs, make sure to reverse self.versions and self.displayedText - self.versions = self.versions[::-1] - self.displayedText = self.displayedText[::-1] + if self.refs != sorted(self.refs): + if hasattr(self, 'charLevelData'): + self.charLevelData.reverse() + if getattr(self, "versions", False) and getattr(self, "displayedText", False): + # if reversed self.refs, make sure to reverse self.versions and self.displayedText + self.versions = self.versions[::-1] + self.displayedText = self.displayedText[::-1] + self.refs = sorted(self.refs) # make sure ref order is deterministic samelink = Link().load({"refs": self.refs}) if samelink: @@ -130,7 +130,11 @@ def _pre_save(self): if preciselink: # logger.debug("save_link: More specific link exists: " + link["refs"][1] + " and " + preciselink["refs"][1]) - raise DuplicateRecordError("A more precise link already exists: {} - {}".format(preciselink.refs[0], preciselink.refs[1])) + if getattr(self, "_override_preciselink", False): + preciselink.delete() + #and the new link will be posted (supposedly) + else: + raise DuplicateRecordError("A more precise link already exists: {} - {}".format(preciselink.refs[0], preciselink.refs[1])) # else: # this is a good new link if not getattr(self, "_skip_lang_check", False): From f43eba98cc9a3bdfbc8d544f506cb062c96f7cce Mon Sep 17 00:00:00 2001 From: Shanee Date: Thu, 17 Mar 2022 13:49:13 -0400 Subject: [PATCH 06/11] override preciselink option documented in generated_by --- sefaria/model/link.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sefaria/model/link.py b/sefaria/model/link.py index e4c664e61d..2168cc9e70 100644 --- a/sefaria/model/link.py +++ b/sefaria/model/link.py @@ -132,6 +132,7 @@ def _pre_save(self): # logger.debug("save_link: More specific link exists: " + link["refs"][1] + " and " + preciselink["refs"][1]) if getattr(self, "_override_preciselink", False): preciselink.delete() + self.generated_by = self.generated_by+'_preciselink_override' #and the new link will be posted (supposedly) else: raise DuplicateRecordError("A more precise link already exists: {} - {}".format(preciselink.refs[0], preciselink.refs[1])) From 15beb95ce46ab0a99fe5e3d7f60fb60e4a62836c Mon Sep 17 00:00:00 2001 From: Shanee Date: Fri, 18 Mar 2022 14:50:01 -0400 Subject: [PATCH 07/11] more robust samelink logic takes into account ranged links v.s. section links --- sefaria/model/link.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sefaria/model/link.py b/sefaria/model/link.py index 2168cc9e70..67ae7375dc 100644 --- a/sefaria/model/link.py +++ b/sefaria/model/link.py @@ -100,10 +100,26 @@ def _pre_save(self): self.refs = sorted(self.refs) # make sure ref order is deterministic samelink = Link().load({"refs": self.refs}) + if not samelink: + #check for samelink section level vs ranged ref + ranged0 = ranged1 = samelink_sec = None + oref0 = text.Ref(self.refs[0]) + oref1 = text.Ref(self.refs[1]) + if oref0.is_section_level() or oref0.is_range(): + ranged0 = text.Ref(f"{oref0.all_segment_refs()[0]}-{oref0.all_segment_refs()[-1]}").normal() + section0 = oref0.sections[0] + samelink = Link().load({"$or": [{"refs": ranged0, "refs": self.refs[1]}, {"refs": section0, "refs": self.refs[1]}]}) + elif text.Ref(self.refs[1]).is_section_level() or oref1.is_range(): # this is an elif since it anyway overrides the samelink see note in 4 lines + ranged1 = text.Ref(f"{oref1.all_segment_refs()[0]}-{oref1.all_segment_refs()[-1]}").normal() + section1 = oref1.sections[0] + samelink = Link().load({"$or": [{"refs": ranged1, "refs": self.refs[0]}, {"refs": section1, "refs": self.refs[0]}]}) + #note: The above code neglects the case where both refs in the link are section or ranged and there is a ranged section link in the db with the opposite situation on both refs. + if samelink: if hasattr(self, 'score') and hasattr(self, 'charLevelData'): samelink.score = self.score samelink.charLevelData = self.charLevelData + samelink.save() raise DuplicateRecordError("Updated existing link with the new score and charLevelData data") elif not self.auto and self.type and not samelink.type: From 1dcf7ae68a733277a6f137c3bd39f81fb0050b1d Mon Sep 17 00:00:00 2001 From: Shanee Date: Fri, 18 Mar 2022 14:56:12 -0400 Subject: [PATCH 08/11] more robust samelink logic takes into account ranged links v.s. section links --- sefaria/model/link.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sefaria/model/link.py b/sefaria/model/link.py index 67ae7375dc..fe667aa4a8 100644 --- a/sefaria/model/link.py +++ b/sefaria/model/link.py @@ -102,7 +102,6 @@ def _pre_save(self): if not samelink: #check for samelink section level vs ranged ref - ranged0 = ranged1 = samelink_sec = None oref0 = text.Ref(self.refs[0]) oref1 = text.Ref(self.refs[1]) if oref0.is_section_level() or oref0.is_range(): From e1f45f20d3d8927e196212a2a6061bc2fedb5d13 Mon Sep 17 00:00:00 2001 From: Shanee Date: Mon, 21 Mar 2022 14:33:41 -0400 Subject: [PATCH 09/11] fix to the ranged links v.s. section links logic --- sefaria/model/link.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sefaria/model/link.py b/sefaria/model/link.py index fe667aa4a8..0482a60983 100644 --- a/sefaria/model/link.py +++ b/sefaria/model/link.py @@ -104,15 +104,19 @@ def _pre_save(self): #check for samelink section level vs ranged ref oref0 = text.Ref(self.refs[0]) oref1 = text.Ref(self.refs[1]) - if oref0.is_section_level() or oref0.is_range(): - ranged0 = text.Ref(f"{oref0.all_segment_refs()[0]}-{oref0.all_segment_refs()[-1]}").normal() - section0 = oref0.sections[0] - samelink = Link().load({"$or": [{"refs": ranged0, "refs": self.refs[1]}, {"refs": section0, "refs": self.refs[1]}]}) - elif text.Ref(self.refs[1]).is_section_level() or oref1.is_range(): # this is an elif since it anyway overrides the samelink see note in 4 lines - ranged1 = text.Ref(f"{oref1.all_segment_refs()[0]}-{oref1.all_segment_refs()[-1]}").normal() - section1 = oref1.sections[0] - samelink = Link().load({"$or": [{"refs": ranged1, "refs": self.refs[0]}, {"refs": section1, "refs": self.refs[0]}]}) - #note: The above code neglects the case where both refs in the link are section or ranged and there is a ranged section link in the db with the opposite situation on both refs. + section0 = oref0.section_ref() + section1 = oref1.section_ref() + if oref0.is_range() and oref0.all_segment_refs() == section0.all_segment_refs(): + samelink = Link.load({"$and": [{"refs": section0}, {"refs": self.refs[1]}]}) + elif oref0.is_section_level(): + ranged0 = text.Ref(f"{oref0.all_segment_refs()[0]}-{oref0.all_segment_refs()[-1]}") + samelink = Link.load({"$and": [{"refs": ranged0}, {"refs": self.refs[1]}]}) + elif oref1.is_range() and oref1.all_segment_refs() == section1.all_segment_refs(): # this is an elif since it anyway overrides the samelink see note in 4 lines + samelink = Link.load({"$and": [{"refs": section1}, {"refs": self.refs[0]}]}) + elif oref1.is_section_level(): + ranged1 = text.Ref(f"{oref1.all_segment_refs()[0]}-{oref1.all_segment_refs()[-1]}") + samelink = Link.load({"$and": [{"refs": ranged1}, {"refs": self.refs[0]}]}) + #note: The above code neglects the case where both refs in the link are section or ranged and there is a ranged/section link in the db with the opposite situation on both refs. if samelink: if hasattr(self, 'score') and hasattr(self, 'charLevelData'): From 73e13dfe8edd307b6914c1761b11ea9ba9274472 Mon Sep 17 00:00:00 2001 From: Shanee Date: Mon, 21 Mar 2022 14:38:42 -0400 Subject: [PATCH 10/11] coloring links css not for prod. --- static/css/s2.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 9e6e06d062..55c5bf16e1 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -6132,9 +6132,6 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus position: relative; } -.textListTextRangeBox.typeQF .titleBox{ - color: forestgreen; -} .textListTextRangeBox .textRange{ margin-bottom: 0; padding-bottom: 0; From f5f469df89c9b848a22a73e054f5ec7215b2810c Mon Sep 17 00:00:00 2001 From: Shanee Date: Mon, 21 Mar 2022 16:42:46 -0400 Subject: [PATCH 11/11] missed parentheses --- sefaria/model/link.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sefaria/model/link.py b/sefaria/model/link.py index 0482a60983..7efe4a0582 100644 --- a/sefaria/model/link.py +++ b/sefaria/model/link.py @@ -107,15 +107,15 @@ def _pre_save(self): section0 = oref0.section_ref() section1 = oref1.section_ref() if oref0.is_range() and oref0.all_segment_refs() == section0.all_segment_refs(): - samelink = Link.load({"$and": [{"refs": section0}, {"refs": self.refs[1]}]}) + samelink = Link().load({"$and": [{"refs": section0}, {"refs": self.refs[1]}]}) elif oref0.is_section_level(): ranged0 = text.Ref(f"{oref0.all_segment_refs()[0]}-{oref0.all_segment_refs()[-1]}") - samelink = Link.load({"$and": [{"refs": ranged0}, {"refs": self.refs[1]}]}) + samelink = Link().load({"$and": [{"refs": ranged0.normal()}, {"refs": self.refs[1]}]}) elif oref1.is_range() and oref1.all_segment_refs() == section1.all_segment_refs(): # this is an elif since it anyway overrides the samelink see note in 4 lines - samelink = Link.load({"$and": [{"refs": section1}, {"refs": self.refs[0]}]}) + samelink = Link().load({"$and": [{"refs": section1}, {"refs": self.refs[0]}]}) elif oref1.is_section_level(): ranged1 = text.Ref(f"{oref1.all_segment_refs()[0]}-{oref1.all_segment_refs()[-1]}") - samelink = Link.load({"$and": [{"refs": ranged1}, {"refs": self.refs[0]}]}) + samelink = Link().load({"$and": [{"refs": ranged1.normal()}, {"refs": self.refs[0]}]}) #note: The above code neglects the case where both refs in the link are section or ranged and there is a ranged/section link in the db with the opposite situation on both refs. if samelink: