diff --git a/README.mkd b/README.mkd
index 4d0372dc01..0ee74bec18 100644
--- a/README.mkd
+++ b/README.mkd
@@ -108,7 +108,7 @@ If the server isn't running, you may need to run `docker-compose up` again.
#### Run locally
#### 1) Install Python 3.7
-*We Recommend using the latest Python 3.7 as opposed to later versions of Python (esp 3.10 and up) since it has been known to cause some compatability issues. These are solvable, but for an easier install experience, we currently recommend 3.7*
+*We Recommend using the latest Python 3.7 as opposed to later versions of Python (esp 3.10 and up) since it has been known to cause some compatibility issues. These are solvable, but for an easier install experience, we currently recommend 3.7*
###### Linux and macOS
Most UNIX systems come with a python interpreter pre-installed. However, this is generally still Python 2. The recommended way to get Python 3, and not mess up any software the OS is dependent on, is by using Pyenv. You can use the instructions [here](https://github.com/pyenv/pyenv#installation) and also [here](https://opensource.com/article/19/5/python-3-default-mac#what-we-should-do).
diff --git a/helm-chart/sefaria-project/templates/configmap/mongo-destroy.yaml b/helm-chart/sefaria-project/templates/configmap/mongo-destroy.yaml
index 6874c016c4..edbd30be88 100644
--- a/helm-chart/sefaria-project/templates/configmap/mongo-destroy.yaml
+++ b/helm-chart/sefaria-project/templates/configmap/mongo-destroy.yaml
@@ -37,8 +37,8 @@ data:
DB_NAME=$SEFARIA_DB
{{ end }}
- URI="${URI}${MONGO_HOST}/${DATABASE}?ssl=false&authSource=admin"
APSCHEDULER_URI="${URI}${MONGO_HOST}/${APSCHEDULER_NAME}?ssl=false&authSource=admin"
+ URI="${URI}${MONGO_HOST}/${DATABASE}?ssl=false&authSource=admin"
if [[ ! -z "$MONGO_REPLICASET_NAME" ]]; then
URI="${URI}&replicaSet=${MONGO_REPLICASET_NAME}"
diff --git a/reader/views.py b/reader/views.py
index 58b2d1dba9..90ef843091 100644
--- a/reader/views.py
+++ b/reader/views.py
@@ -856,8 +856,9 @@ def search(request):
desc = _("Search 3,000 years of Jewish texts in Hebrew and English translation.") if SITE_SETTINGS["TORAH_SPECIFIC"] else _("Search")
return render_template(request,'base.html', props, {
- "title": (search_params["query"] + " | " if search_params["query"] else "") + _(SITE_SETTINGS["SITE_NAME"]["en"]+" Search"),
- "desc": desc
+ "title": (search_params["query"] + " | " if search_params["query"] else "") + _(SITE_SETTINGS["SITE_NAME"]["en"],
+ "desc": desc,
+ "noindex": True
})
diff --git a/sefaria/helper/topic.py b/sefaria/helper/topic.py
index 36ebef5f48..a18f15cea0 100644
--- a/sefaria/helper/topic.py
+++ b/sefaria/helper/topic.py
@@ -114,7 +114,7 @@ def merge_props_for_similar_refs(curr_link, new_link):
# as well as datasource and descriptions of all the similar refs
data_source = new_link.get('dataSource', None)
if data_source:
- curr_link = update_refs(curr_link, new_link, data_source)
+ curr_link = update_refs(curr_link, new_link)
curr_link = update_data_source_in_link(curr_link, new_link, data_source)
if not curr_link['is_sheet']:
@@ -128,20 +128,9 @@ def update_data_source_in_link(curr_link, new_link, data_source):
del new_link['dataSource']
return curr_link
-def is_data_source_learning_team(func):
- def wrapper(curr_link, new_link, data_source):
- if data_source == 'learning-team':
- return func(curr_link, new_link)
- else:
- return curr_link
- return wrapper
-
-@is_data_source_learning_team
def update_refs(curr_link, new_link):
- # in case the new_link was created by the learning team, we want to use ref of learning team link
- # in the case when both links are from the learning team, use whichever ref covers a smaller range
- if 'learning-team' not in curr_link['dataSources'] or len(curr_link['expandedRefs']) > len(
- new_link['expandedRefs']):
+ # use whichever ref covers a smaller range
+ if len(curr_link['expandedRefs']) > len(new_link['expandedRefs']):
curr_link['ref'] = new_link['ref']
curr_link['expandedRefs'] = new_link['expandedRefs']
return curr_link
@@ -171,6 +160,20 @@ def update_curated_primacy(curr_link, new_link):
curr_link['order']['curatedPrimacy'] = curr_curated_primacy
return curr_link
+def is_learning_team(dataSource):
+ return dataSource == 'learning-team' or dataSource == 'learning-team-editing-tool'
+
+def iterate_and_merge(new_ref_links, new_link, subset_ref_map, temp_subset_refs):
+ # temp_subset_refs contains the refs within link's expandedRefs that overlap with other refs
+ # subset_ref_map + new_ref_links contain mappings to get from the temp_subset_refs to the actual link objects
+ for seg_ref in temp_subset_refs:
+ for index in subset_ref_map[seg_ref]:
+ new_ref_links[index]['similarRefs'] += [new_link]
+ curr_link_learning_team = any([is_learning_team(dataSource) for dataSource in new_ref_links[index]['dataSources']])
+ if not curr_link_learning_team: # if learning team, ignore source with overlapping refs
+ new_ref_links[index] = merge_props_for_similar_refs(new_ref_links[index], new_link)
+ return new_ref_links
+
def sort_and_group_similar_refs(ref_links):
ref_links.sort(key=cmp_to_key(sort_refs_by_relevance))
subset_ref_map = defaultdict(list)
@@ -178,11 +181,11 @@ def sort_and_group_similar_refs(ref_links):
for link in ref_links:
del link['topic']
temp_subset_refs = subset_ref_map.keys() & set(link.get('expandedRefs', []))
- for seg_ref in temp_subset_refs:
- for index in subset_ref_map[seg_ref]:
- new_ref_links[index]['similarRefs'] += [link]
- new_ref_links[index] = merge_props_for_similar_refs(new_ref_links[index], link)
- if len(temp_subset_refs) == 0:
+ new_data_source = link.get("dataSource", None)
+ should_merge = len(temp_subset_refs) > 0 and not is_learning_team(new_data_source) # learning team links should be handled separately from one another and not merged
+ if should_merge:
+ new_ref_links = iterate_and_merge(new_ref_links, link, subset_ref_map, temp_subset_refs)
+ else:
link['similarRefs'] = []
link['dataSources'] = {}
if link.get('dataSource', None):
@@ -1250,12 +1253,12 @@ def delete_ref_topic_link(tref, to_topic, link_type, lang):
if link is None:
return {"error": f"Link between {tref} and {to_topic} doesn't exist."}
- if lang in link.order['availableLangs']:
+ if lang in link.order.get('availableLangs', []):
link.order['availableLangs'].remove(lang)
- if lang in link.order['curatedPrimacy']:
+ if lang in link.order.get('curatedPrimacy', []):
link.order['curatedPrimacy'].pop(lang)
- if len(link.order['availableLangs']) > 0:
+ if len(link.order.get('availableLangs', [])) > 0:
link.save()
return {"status": "ok"}
else: # deleted in both hebrew and english so delete link object
diff --git a/sefaria/model/text.py b/sefaria/model/text.py
index 75109055d3..b20197f2a3 100644
--- a/sefaria/model/text.py
+++ b/sefaria/model/text.py
@@ -687,6 +687,12 @@ def _validate(self):
if not Category().load({"path": self.categories}):
raise InputError("You must create category {} before adding texts to it.".format("/".join(self.categories)))
+ for date_key in ['compDate', 'pubDate']:
+ if hasattr(self, date_key):
+ val = getattr(self, date_key)
+ if not isinstance(val, list) or not all([isinstance(x, int) for x in val]):
+ raise InputError(f"Optional attribute '{date_key}' must be list of integers.")
+
'''
for cat in self.categories:
if not hebrew_term(cat):
diff --git a/sefaria/model/topic.py b/sefaria/model/topic.py
index e61f7054ca..639aa5695f 100644
--- a/sefaria/model/topic.py
+++ b/sefaria/model/topic.py
@@ -416,8 +416,9 @@ def annotate_place(self, d):
if place and heKey not in properties:
value, dataSource = place['value'], place['dataSource']
place_obj = Place().load({"key": value})
- name = place_obj.primary_name('he')
- d['properties'][heKey] = {'value': name, 'dataSource': dataSource}
+ if place_obj:
+ name = place_obj.primary_name('he')
+ d['properties'][heKey] = {'value': name, 'dataSource': dataSource}
return d
def contents(self, **kwargs):
diff --git a/static/js/CategoryEditor.jsx b/static/js/CategoryEditor.jsx
index 5cfafa8180..61f5b2c80e 100644
--- a/static/js/CategoryEditor.jsx
+++ b/static/js/CategoryEditor.jsx
@@ -22,7 +22,7 @@ const Reorder = ({subcategoriesAndBooks, updateOrder, displayType, updateParentC
const clickHandler = (dir, child) => {
const index = subcategoriesAndBooks.indexOf(child);
let index_to_swap = -1;
- if (dir === 'down' && index < subcategoriesAndBooks.length)
+ if (dir === 'down' && index < subcategoriesAndBooks.length - 1)
{
index_to_swap = index + 1;
}
diff --git a/static/js/NavSidebar.jsx b/static/js/NavSidebar.jsx
index 9ed1b38ce2..b300f3754b 100644
--- a/static/js/NavSidebar.jsx
+++ b/static/js/NavSidebar.jsx
@@ -501,8 +501,13 @@ const AboutTopics = ({hideTitle}) => (