From de22a576108a02b65294a3e1d975484a43e2af91 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Tue, 19 Sep 2023 17:39:51 +0530 Subject: [PATCH 01/25] Add new preference and annoucementchecker class --- sleap/gui/app.py | 2 ++ sleap/gui/web.py | 27 ++++++++++++++++++++++++++- sleap/prefs.py | 2 ++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/sleap/gui/app.py b/sleap/gui/app.py index de6ce9fbf..cdc968f35 100644 --- a/sleap/gui/app.py +++ b/sleap/gui/app.py @@ -152,6 +152,7 @@ def __init__( self.state["share usage data"] = prefs["share usage data"] self.state["skeleton_preview_image"] = None self.state["skeleton_description"] = "No skeleton loaded yet" + self.state["announcement last seen date"] = prefs["announcement last seen date"] if no_usage_data: self.state["share usage data"] = False self.state["clipboard_track"] = None @@ -215,6 +216,7 @@ def closeEvent(self, event): prefs["color predicted"] = self.state["color predicted"] prefs["trail shade"] = self.state["trail_shade"] prefs["share usage data"] = self.state["share usage data"] + prefs["announcement last seen date"] = self.state["announcement last seen date"] # Save preferences. prefs.save() diff --git a/sleap/gui/web.py b/sleap/gui/web.py index d753ea16e..9f166d2ee 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -3,7 +3,9 @@ import attr import pandas as pd import requests -from typing import List, Dict, Any +from typing import List, Dict, Any, Optional +from sleap import prefs +from datetime import date REPO_ID = "talmolab/sleap" @@ -146,6 +148,29 @@ def get_release(self, version: str) -> Release: ) +@attr.s(auto_attribs=True) +class AnnouncementChecker: + """Checker for new announcements on the releases page of sleap.""" + + def check_for_new_announcements(self) -> bool: + """Check for new announcements on the releases page not seen by user.""" + if date.today().strftime("%Y%m%d") > prefs.prefs["announcement last seen date"]: + return True + return False + + def get_latest_announcement(self) -> Optional[date]: + """Return latest announcement date if available.""" + if self.check_for_new_announcements(): + return date.today().strftime("%Y%m%d") + return None + + def update_announcement_last_seen(self): + """Update the last seen date of announcement in preferences.""" + latest_announcement_date = self.get_latest_announcement() + if latest_announcement_date is not None: + prefs.prefs["announcement last seen date"] = latest_announcement_date + + def get_analytics_data() -> Dict[str, Any]: """Gather data to be transmitted to analytics backend.""" import os diff --git a/sleap/prefs.py b/sleap/prefs.py index 3d5a2113e..43aa10b9a 100644 --- a/sleap/prefs.py +++ b/sleap/prefs.py @@ -5,6 +5,7 @@ """ from sleap import util +from datetime import date class Preferences(object): @@ -28,6 +29,7 @@ class Preferences(object): "node label size": 12, "show non-visible nodes": True, "share usage data": True, + "announcement last seen date": date.today().strftime("%Y%m%d") } _filename = "preferences.yaml" From 0db2904822fd6ae9f30a6b26275f0508a396ef5b Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Thu, 28 Sep 2023 12:35:27 +0530 Subject: [PATCH 02/25] Add new preferences and bulletin json converter --- docs/bulletin.md | 3 ++ docs/make_bulletin_json.py | 30 +++++++++++++++++++ sleap/gui/app.py | 5 +++- sleap/gui/web.py | 59 ++++++++++++++++++++++++++------------ sleap/prefs.py | 3 +- 5 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 docs/make_bulletin_json.py diff --git a/docs/bulletin.md b/docs/bulletin.md index a1be0e7b7..c578cb63e 100644 --- a/docs/bulletin.md +++ b/docs/bulletin.md @@ -1,6 +1,9 @@ # Bulletin ## SLEAP v1.3.2 + +_mm/dd/yyyy_ + SLEAP 1.3.2 adds some nice usability features thanks to both the community ideas and new contributors! See [1.3.0](https://github.com/talmolab/sleap/releases/tag/v1.3.0) and [1.3.1](https://github.com/talmolab/sleap/releases/tag/v1.3.1) for previous notable changes. As a reminder: > The 1.3.1 dependency update requires [Mamba](https://mamba.readthedocs.io/en/latest/index.html) for faster dependency resolution. If you already have anaconda installed, then you _can_ set the solver to libmamba in the base environment: diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py new file mode 100644 index 000000000..d6db254b1 --- /dev/null +++ b/docs/make_bulletin_json.py @@ -0,0 +1,30 @@ +import json + +# Set the file paths +input_md_file = 'D:\TalmoLab\sleap\docs\bulletin.md' +output_json_file = 'D:\TalmoLab\sleap\docs\\bulletin.json' + +def generate_json_file(): + with open(input_md_file, 'r', encoding='utf-8') as md_file: + markdown_content = md_file.read() + bulletin_json = [] + content = '' + + for line in markdown_content.split('\n'): + if line.startswith('---'): + bulletin_json.append({'title': title, 'date': date, 'content':content}) + content = '' + elif line.startswith('##'): + title = line[3:].strip() + elif line.startswith('_'): + date = line[1:len(line)-1].strip() + else: + content += (line + '\n') + # Append last section + bulletin_json.append({'title': title, 'date': date, 'content':content}) + + with open(output_json_file, 'w', encoding='utf-8') as json_file: + json.dump(bulletin_json, json_file, ensure_ascii=False, indent=4) + +if __name__ == '__main__': + generate_json_file() diff --git a/sleap/gui/app.py b/sleap/gui/app.py index cdc968f35..37f46057a 100644 --- a/sleap/gui/app.py +++ b/sleap/gui/app.py @@ -67,7 +67,7 @@ from sleap.gui.overlays.tracks import TrackListOverlay, TrackTrailOverlay from sleap.gui.shortcuts import Shortcuts from sleap.gui.state import GuiState -from sleap.gui.web import ReleaseChecker, ping_analytics +from sleap.gui.web import ReleaseChecker, AnnouncementChecker, ping_analytics from sleap.gui.widgets.docks import ( InstancesDock, SkeletonDock, @@ -153,6 +153,7 @@ def __init__( self.state["skeleton_preview_image"] = None self.state["skeleton_description"] = "No skeleton loaded yet" self.state["announcement last seen date"] = prefs["announcement last seen date"] + self.state["announcement"] = prefs["announcement"] if no_usage_data: self.state["share usage data"] = False self.state["clipboard_track"] = None @@ -163,6 +164,7 @@ def __init__( self.state.connect("show non-visible nodes", self.plotFrame) self.release_checker = ReleaseChecker() + self.announcement_checker = AnnouncementChecker() if self.state["share usage data"]: ping_analytics() @@ -217,6 +219,7 @@ def closeEvent(self, event): prefs["trail shade"] = self.state["trail_shade"] prefs["share usage data"] = self.state["share usage data"] prefs["announcement last seen date"] = self.state["announcement last seen date"] + prefs["announcement"] = self.state["announcement"] # Save preferences. prefs.save() diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 9f166d2ee..381a34448 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -3,13 +3,14 @@ import attr import pandas as pd import requests -from typing import List, Dict, Any, Optional +from typing import List, Dict, Any, Optional, Tuple from sleap import prefs -from datetime import date +import json REPO_ID = "talmolab/sleap" ANALYTICS_ENDPOINT = "https://analytics.sleap.ai/ping" +BULLETIN_JSON = "D:\TalmoLab\sleap\docs\\bulletin.json" @attr.s(auto_attribs=True) @@ -150,25 +151,45 @@ def get_release(self, version: str) -> Release: @attr.s(auto_attribs=True) class AnnouncementChecker: - """Checker for new announcements on the releases page of sleap.""" - - def check_for_new_announcements(self) -> bool: - """Check for new announcements on the releases page not seen by user.""" - if date.today().strftime("%Y%m%d") > prefs.prefs["announcement last seen date"]: - return True - return False - - def get_latest_announcement(self) -> Optional[date]: - """Return latest announcement date if available.""" - if self.check_for_new_announcements(): - return date.today().strftime("%Y%m%d") + """Checker for new announcements on the bulletin page of sleap.""" + + bulletin_json_path: str = BULLETIN_JSON + previous_announcement_date: str = prefs.prefs["announcement last seen date"] + + def check_for_announcement(self) -> bool: + """Returns if new announcements are available.""" + try: + # Attempt to open the file in read mode + with open(self.bulletin_json_path, 'r', encoding='utf-8') as jsf: + # Load the JSON data into a Python data structure + data = json.load(jsf) + latest_data = data[0] + + if latest_data['date'] != self.previous_announcement_date: + return True + except FileNotFoundError: + return False + + def get_latest_announcement(self) -> Optional[Tuple[str, str]]: + """Return latest announcements on the releases page not seen by user.""" + success = self.check_for_announcement() + if success: + # Attempt to open the file in read mode + with open(self.bulletin_json_path, 'r', encoding='utf-8') as jsf: + # Load the JSON data into a Python data structure + data = json.load(jsf) + latest_data = data[0] + + if latest_data['date'] != self.previous_announcement_date: + return (latest_data['date'], latest_data['content']) return None - - def update_announcement_last_seen(self): + + def update_announcement(self): """Update the last seen date of announcement in preferences.""" - latest_announcement_date = self.get_latest_announcement() - if latest_announcement_date is not None: - prefs.prefs["announcement last seen date"] = latest_announcement_date + announcement = self.get_latest_announcement() + if announcement is not None: + prefs.prefs["announcement last seen date"] = announcement[0] + prefs.prefs["announcement"] = announcement[1] def get_analytics_data() -> Dict[str, Any]: diff --git a/sleap/prefs.py b/sleap/prefs.py index 43aa10b9a..b7f50c9e1 100644 --- a/sleap/prefs.py +++ b/sleap/prefs.py @@ -29,7 +29,8 @@ class Preferences(object): "node label size": 12, "show non-visible nodes": True, "share usage data": True, - "announcement last seen date": date.today().strftime("%Y%m%d") + "announcement last seen date": None, + "announcement": None, } _filename = "preferences.yaml" From 6eddcf09402854f0db8023dd91da550a12ceb4b5 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Tue, 3 Oct 2023 19:53:33 +0530 Subject: [PATCH 03/25] Add some of the suggestions --- docs/make_bulletin_json.py | 12 +++++++++-- sleap/gui/app.py | 4 +++- sleap/gui/web.py | 42 +++++++++++++++----------------------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index d6db254b1..f6ba6b98b 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -1,8 +1,9 @@ import json +import os # Set the file paths -input_md_file = 'D:\TalmoLab\sleap\docs\bulletin.md' -output_json_file = 'D:\TalmoLab\sleap\docs\\bulletin.json' +input_md_file = os.path.join(os.path.dirname(__file__), 'bulletin.md') +output_json_file = os.path.join(os.path.dirname(__file__), 'bulletin.json') def generate_json_file(): with open(input_md_file, 'r', encoding='utf-8') as md_file: @@ -10,10 +11,17 @@ def generate_json_file(): bulletin_json = [] content = '' + # Initialize title and date with default values + title = "DEFAULT_TITLE" + date = "DEFAULT_DATE" + for line in markdown_content.split('\n'): if line.startswith('---'): bulletin_json.append({'title': title, 'date': date, 'content':content}) content = '' + # Reset title and date to their default values after each section + title = "DEFAULT_TITLE" + date = "DEFAULT_DATE" elif line.startswith('##'): title = line[3:].strip() elif line.startswith('_'): diff --git a/sleap/gui/app.py b/sleap/gui/app.py index 37f46057a..8183b0c32 100644 --- a/sleap/gui/app.py +++ b/sleap/gui/app.py @@ -164,7 +164,9 @@ def __init__( self.state.connect("show non-visible nodes", self.plotFrame) self.release_checker = ReleaseChecker() - self.announcement_checker = AnnouncementChecker() + self.announcement_checker = AnnouncementChecker( + app = self + ) if self.state["share usage data"]: ping_analytics() diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 381a34448..4a03b773a 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -4,13 +4,14 @@ import pandas as pd import requests from typing import List, Dict, Any, Optional, Tuple -from sleap import prefs import json +import os REPO_ID = "talmolab/sleap" ANALYTICS_ENDPOINT = "https://analytics.sleap.ai/ping" -BULLETIN_JSON = "D:\TalmoLab\sleap\docs\\bulletin.json" +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +BULLETIN_JSON = os.path.join(BASE_DIR, "..", "docs", "bulletin.json") @attr.s(auto_attribs=True) @@ -153,43 +154,34 @@ def get_release(self, version: str) -> Release: class AnnouncementChecker: """Checker for new announcements on the bulletin page of sleap.""" + app: "MainWindow" bulletin_json_path: str = BULLETIN_JSON - previous_announcement_date: str = prefs.prefs["announcement last seen date"] + previous_announcement_date: str = app.state["announcement last seen date"] + _latest_data: Optional[Dict[str, str]] = None - def check_for_announcement(self) -> bool: - """Returns if new announcements are available.""" + def _read_bulletin_data(self) -> Dict[str, str]: + """Reads the bulletin data from the JSON file.""" try: - # Attempt to open the file in read mode with open(self.bulletin_json_path, 'r', encoding='utf-8') as jsf: - # Load the JSON data into a Python data structure data = json.load(jsf) - latest_data = data[0] - - if latest_data['date'] != self.previous_announcement_date: - return True + return data[0] except FileNotFoundError: - return False + return {} def get_latest_announcement(self) -> Optional[Tuple[str, str]]: """Return latest announcements on the releases page not seen by user.""" - success = self.check_for_announcement() - if success: - # Attempt to open the file in read mode - with open(self.bulletin_json_path, 'r', encoding='utf-8') as jsf: - # Load the JSON data into a Python data structure - data = json.load(jsf) - latest_data = data[0] - - if latest_data['date'] != self.previous_announcement_date: - return (latest_data['date'], latest_data['content']) + self._latest_datalatest_data = self._read_bulletin_data() + if self._latest_data and self._latest_data['date'] != self.previous_announcement_date: + return (self._latest_data['date'], self._latest_data['content']) return None def update_announcement(self): """Update the last seen date of announcement in preferences.""" announcement = self.get_latest_announcement() - if announcement is not None: - prefs.prefs["announcement last seen date"] = announcement[0] - prefs.prefs["announcement"] = announcement[1] + if announcement is None: + return + self.app.state["announcement last seen date"] = announcement[0] + self.app.state["announcement"] = announcement[1] def get_analytics_data() -> Dict[str, Any]: From 3f99b8beadbe4dae90ead4bfa1afd7d350444f92 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Tue, 3 Oct 2023 22:30:14 +0530 Subject: [PATCH 04/25] Typo --- sleap/gui/web.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 4a03b773a..52abe6acd 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -156,7 +156,7 @@ class AnnouncementChecker: app: "MainWindow" bulletin_json_path: str = BULLETIN_JSON - previous_announcement_date: str = app.state["announcement last seen date"] + previous_announcement_date: str = None _latest_data: Optional[Dict[str, str]] = None def _read_bulletin_data(self) -> Dict[str, str]: @@ -170,7 +170,7 @@ def _read_bulletin_data(self) -> Dict[str, str]: def get_latest_announcement(self) -> Optional[Tuple[str, str]]: """Return latest announcements on the releases page not seen by user.""" - self._latest_datalatest_data = self._read_bulletin_data() + self._latest_data = self._read_bulletin_data() if self._latest_data and self._latest_data['date'] != self.previous_announcement_date: return (self._latest_data['date'], self._latest_data['content']) return None From d9947c38b0550ecf2fe04e42e2e9e0f8c090e618 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 16 Oct 2023 13:05:32 -0700 Subject: [PATCH 05/25] Add test function for the announcement checker class --- docs/make_bulletin_json.py | 36 ++++++++++++++++--------------- sleap/gui/app.py | 4 +--- sleap/gui/web.py | 20 +++++++++++++----- tests/gui/test_web.py | 43 +++++++++++++++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index f6ba6b98b..e9c7f4d89 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -2,37 +2,39 @@ import os # Set the file paths -input_md_file = os.path.join(os.path.dirname(__file__), 'bulletin.md') -output_json_file = os.path.join(os.path.dirname(__file__), 'bulletin.json') +input_md_file = os.path.join(os.path.dirname(__file__), "bulletin.md") +output_json_file = os.path.join(os.path.dirname(__file__), "bulletin.json") + def generate_json_file(): - with open(input_md_file, 'r', encoding='utf-8') as md_file: + with open(input_md_file, "r", encoding="utf-8") as md_file: markdown_content = md_file.read() bulletin_json = [] - content = '' + content = "" # Initialize title and date with default values title = "DEFAULT_TITLE" date = "DEFAULT_DATE" - for line in markdown_content.split('\n'): - if line.startswith('---'): - bulletin_json.append({'title': title, 'date': date, 'content':content}) - content = '' + for line in markdown_content.split("\n"): + if line.startswith("---"): + bulletin_json.append({"title": title, "date": date, "content": content}) + content = "" # Reset title and date to their default values after each section title = "DEFAULT_TITLE" date = "DEFAULT_DATE" - elif line.startswith('##'): + elif line.startswith("##"): title = line[3:].strip() - elif line.startswith('_'): - date = line[1:len(line)-1].strip() + elif line.startswith("_"): + date = line[1 : len(line) - 1].strip() else: - content += (line + '\n') - # Append last section - bulletin_json.append({'title': title, 'date': date, 'content':content}) - - with open(output_json_file, 'w', encoding='utf-8') as json_file: + content += line + "\n" + # Append last section + bulletin_json.append({"title": title, "date": date, "content": content}) + + with open(output_json_file, "w", encoding="utf-8") as json_file: json.dump(bulletin_json, json_file, ensure_ascii=False, indent=4) -if __name__ == '__main__': + +if __name__ == "__main__": generate_json_file() diff --git a/sleap/gui/app.py b/sleap/gui/app.py index ed9b34600..1d6b9d976 100644 --- a/sleap/gui/app.py +++ b/sleap/gui/app.py @@ -170,9 +170,7 @@ def __init__( self.state.connect("show non-visible nodes", self.plotFrame) self.release_checker = ReleaseChecker() - self.announcement_checker = AnnouncementChecker( - app = self - ) + self.announcement_checker = AnnouncementChecker(app=self) if self.state["share usage data"]: ping_analytics() diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 52abe6acd..624c9f66c 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -10,7 +10,9 @@ REPO_ID = "talmolab/sleap" ANALYTICS_ENDPOINT = "https://analytics.sleap.ai/ping" -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +BASE_DIR = os.path.dirname( + os.path.abspath(os.path.join(__file__, os.path.pardir, os.pardir)) +) BULLETIN_JSON = os.path.join(BASE_DIR, "..", "docs", "bulletin.json") @@ -156,13 +158,18 @@ class AnnouncementChecker: app: "MainWindow" bulletin_json_path: str = BULLETIN_JSON - previous_announcement_date: str = None + _previous_announcement_date: str = None _latest_data: Optional[Dict[str, str]] = None + @property + def previous_announcement_date(self): + _previous_announcement_date = self.app.state["announcement last seen date"] + return _previous_announcement_date + def _read_bulletin_data(self) -> Dict[str, str]: """Reads the bulletin data from the JSON file.""" try: - with open(self.bulletin_json_path, 'r', encoding='utf-8') as jsf: + with open(self.bulletin_json_path, "r") as jsf: data = json.load(jsf) return data[0] except FileNotFoundError: @@ -171,8 +178,11 @@ def _read_bulletin_data(self) -> Dict[str, str]: def get_latest_announcement(self) -> Optional[Tuple[str, str]]: """Return latest announcements on the releases page not seen by user.""" self._latest_data = self._read_bulletin_data() - if self._latest_data and self._latest_data['date'] != self.previous_announcement_date: - return (self._latest_data['date'], self._latest_data['content']) + if ( + self._latest_data + and self._latest_data["date"] != self.previous_announcement_date + ): + return (self._latest_data["date"], self._latest_data["content"]) return None def update_announcement(self): diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index cf6bf45ec..d23b6655e 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -1,6 +1,15 @@ import pandas as pd -from sleap.gui.web import ReleaseChecker, Release, get_analytics_data, ping_analytics +from sleap.gui.web import ( + ReleaseChecker, + Release, + AnnouncementChecker, + get_analytics_data, + ping_analytics, +) import pytest +from sleap.gui.app import create_app +import json +import os def test_release_from_json(): @@ -72,6 +81,38 @@ def test_release_checker(): assert checker.releases[1] != rls_test +def test_announcementchecker(): + + BULLETIN_JSON_PATH = os.environ["test_bulletin_json"] + app = create_app() + app.state = {} + app.state["announcement last seen date"] = "10/10/2023" + checker = AnnouncementChecker(app=app, bulletin_json_path=BULLETIN_JSON_PATH) + + # Check if the announcement checker gets the correct date from the app + assert checker.previous_announcement_date == "10/10/2023" + + # Create dummy JSON file to check + bulletin_data = [ + {"title": "title1", "date": "10/11/2023", "content": "New announcement"}, + {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}, + ] + with open(BULLETIN_JSON_PATH, "w") as test_file: + json.dump(bulletin_data, test_file) + assert checker._read_bulletin_data() == bulletin_data[0] + + # Check if latest announcement is fetched + announcement = checker.get_latest_announcement() + assert announcement == ("10/11/2023", "New announcement") + + checker.update_announcement() + assert app.state["announcement last seen date"] == "10/11/2023" + assert app.state["announcement"] == "New announcement" + + # Delete the JSON file + os.remove(BULLETIN_JSON_PATH) + + def test_get_analytics_data(): analytics_data = get_analytics_data() assert "platform" in analytics_data From 4cb0c6a1ac45e7df6b5fe84aa0739873979ffd37 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 16 Oct 2023 14:01:37 -0700 Subject: [PATCH 06/25] Fix path bug --- tests/gui/test_web.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index d23b6655e..ac098c6c9 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -83,7 +83,7 @@ def test_release_checker(): def test_announcementchecker(): - BULLETIN_JSON_PATH = os.environ["test_bulletin_json"] + BULLETIN_JSON_PATH = "D:\\TalmoLab\\sleap\\tests\\data\\announcement_checker_bulletin\\test_bulletin.json" app = create_app() app.state = {} app.state["announcement last seen date"] = "10/10/2023" From 33231156b378d95332cd71a79d9fc4a07f597953 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 16 Oct 2023 23:06:55 -0700 Subject: [PATCH 07/25] Add boolean for new announcement --- sleap/gui/web.py | 18 ++++++++++++------ tests/gui/test_web.py | 7 +++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 624c9f66c..daf3d3de7 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -166,22 +166,28 @@ def previous_announcement_date(self): _previous_announcement_date = self.app.state["announcement last seen date"] return _previous_announcement_date - def _read_bulletin_data(self) -> Dict[str, str]: + def _read_bulletin_data(self): """Reads the bulletin data from the JSON file.""" try: with open(self.bulletin_json_path, "r") as jsf: data = json.load(jsf) - return data[0] + self._latest_data = data[0] except FileNotFoundError: - return {} + self._latest_data = {} - def get_latest_announcement(self) -> Optional[Tuple[str, str]]: - """Return latest announcements on the releases page not seen by user.""" - self._latest_data = self._read_bulletin_data() + @property + def new_announcement(self) -> bool: + self._read_bulletin_data() if ( self._latest_data and self._latest_data["date"] != self.previous_announcement_date ): + return True + return False + + def get_latest_announcement(self) -> Optional[Tuple[str, str]]: + """Return latest announcements on the releases page not seen by user.""" + if self.new_announcement: return (self._latest_data["date"], self._latest_data["content"]) return None diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index ac098c6c9..1e3009ee5 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -94,19 +94,18 @@ def test_announcementchecker(): # Create dummy JSON file to check bulletin_data = [ - {"title": "title1", "date": "10/11/2023", "content": "New announcement"}, + {"title": "title1", "date": "10/12/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}, ] with open(BULLETIN_JSON_PATH, "w") as test_file: json.dump(bulletin_data, test_file) - assert checker._read_bulletin_data() == bulletin_data[0] # Check if latest announcement is fetched announcement = checker.get_latest_announcement() - assert announcement == ("10/11/2023", "New announcement") + assert announcement == ("10/12/2023", "New announcement") checker.update_announcement() - assert app.state["announcement last seen date"] == "10/11/2023" + assert app.state["announcement last seen date"] == "10/12/2023" assert app.state["announcement"] == "New announcement" # Delete the JSON file From fc856bff504f67b7e594425ab36e6cd738d6716b Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Wed, 18 Oct 2023 16:27:11 -0700 Subject: [PATCH 08/25] Add fixtures, pass mainwindow states --- sleap/gui/app.py | 2 +- sleap/gui/web.py | 10 ++++---- tests/conftest.py | 1 + .../test_bulletin.json | 1 + tests/fixtures/announcements.py | 7 ++++++ tests/gui/test_web.py | 24 +++++++++---------- 6 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 tests/data/announcement_checker_bulletin/test_bulletin.json create mode 100644 tests/fixtures/announcements.py diff --git a/sleap/gui/app.py b/sleap/gui/app.py index 1d6b9d976..053e1007b 100644 --- a/sleap/gui/app.py +++ b/sleap/gui/app.py @@ -170,7 +170,7 @@ def __init__( self.state.connect("show non-visible nodes", self.plotFrame) self.release_checker = ReleaseChecker() - self.announcement_checker = AnnouncementChecker(app=self) + self.announcement_checker = AnnouncementChecker(state=self.state) if self.state["share usage data"]: ping_analytics() diff --git a/sleap/gui/web.py b/sleap/gui/web.py index daf3d3de7..24a72dfa0 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -156,14 +156,14 @@ def get_release(self, version: str) -> Release: class AnnouncementChecker: """Checker for new announcements on the bulletin page of sleap.""" - app: "MainWindow" + state: "GuiState" bulletin_json_path: str = BULLETIN_JSON _previous_announcement_date: str = None _latest_data: Optional[Dict[str, str]] = None @property def previous_announcement_date(self): - _previous_announcement_date = self.app.state["announcement last seen date"] + _previous_announcement_date = self.state["announcement last seen date"] return _previous_announcement_date def _read_bulletin_data(self): @@ -176,7 +176,7 @@ def _read_bulletin_data(self): self._latest_data = {} @property - def new_announcement(self) -> bool: + def new_announcement(self): self._read_bulletin_data() if ( self._latest_data @@ -196,8 +196,8 @@ def update_announcement(self): announcement = self.get_latest_announcement() if announcement is None: return - self.app.state["announcement last seen date"] = announcement[0] - self.app.state["announcement"] = announcement[1] + self.state["announcement last seen date"] = announcement[0] + self.state["announcement"] = announcement[1] def get_analytics_data() -> Dict[str, Any]: diff --git a/tests/conftest.py b/tests/conftest.py index 1b2294682..0f6c388b1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,3 +11,4 @@ from tests.fixtures.datasets import * from tests.fixtures.videos import * from tests.fixtures.models import * +from tests.fixtures.announcements import * diff --git a/tests/data/announcement_checker_bulletin/test_bulletin.json b/tests/data/announcement_checker_bulletin/test_bulletin.json new file mode 100644 index 000000000..a6dbf01a4 --- /dev/null +++ b/tests/data/announcement_checker_bulletin/test_bulletin.json @@ -0,0 +1 @@ +[{"title": "title1", "date": "10/12/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}] \ No newline at end of file diff --git a/tests/fixtures/announcements.py b/tests/fixtures/announcements.py new file mode 100644 index 000000000..708090c9c --- /dev/null +++ b/tests/fixtures/announcements.py @@ -0,0 +1,7 @@ +import pytest + +TEST_BULLETIN_JSON = "tests/data/announcement_checker_bulletin/test_bulletin.json" + +@pytest.fixture +def bulletin_json_path(): + return TEST_BULLETIN_JSON diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index 1e3009ee5..b8a6cff38 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -7,9 +7,10 @@ ping_analytics, ) import pytest -from sleap.gui.app import create_app import json import os +from sleap.gui.commands import CommandContext +from sleap.io.dataset import Labels def test_release_from_json(): @@ -81,13 +82,13 @@ def test_release_checker(): assert checker.releases[1] != rls_test -def test_announcementchecker(): +def test_announcementchecker(bulletin_json_path): - BULLETIN_JSON_PATH = "D:\\TalmoLab\\sleap\\tests\\data\\announcement_checker_bulletin\\test_bulletin.json" - app = create_app() - app.state = {} - app.state["announcement last seen date"] = "10/10/2023" - checker = AnnouncementChecker(app=app, bulletin_json_path=BULLETIN_JSON_PATH) + labels = Labels() + context = CommandContext.from_labels(labels=labels) + context.state = {} + context.state["announcement last seen date"] = "10/10/2023" + checker = AnnouncementChecker(state=context.state, bulletin_json_path=bulletin_json_path) # Check if the announcement checker gets the correct date from the app assert checker.previous_announcement_date == "10/10/2023" @@ -97,7 +98,7 @@ def test_announcementchecker(): {"title": "title1", "date": "10/12/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}, ] - with open(BULLETIN_JSON_PATH, "w") as test_file: + with open(bulletin_json_path, "w") as test_file: json.dump(bulletin_data, test_file) # Check if latest announcement is fetched @@ -105,11 +106,8 @@ def test_announcementchecker(): assert announcement == ("10/12/2023", "New announcement") checker.update_announcement() - assert app.state["announcement last seen date"] == "10/12/2023" - assert app.state["announcement"] == "New announcement" - - # Delete the JSON file - os.remove(BULLETIN_JSON_PATH) + assert context.state["announcement last seen date"] == "10/12/2023" + assert context.state["announcement"] == "New announcement" def test_get_analytics_data(): From 39ed0b6d29763587b0179ec2de61e947813bfa35 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Wed, 18 Oct 2023 23:31:59 -0700 Subject: [PATCH 09/25] Lint files --- tests/fixtures/announcements.py | 1 + tests/gui/test_web.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/fixtures/announcements.py b/tests/fixtures/announcements.py index 708090c9c..969c7df43 100644 --- a/tests/fixtures/announcements.py +++ b/tests/fixtures/announcements.py @@ -2,6 +2,7 @@ TEST_BULLETIN_JSON = "tests/data/announcement_checker_bulletin/test_bulletin.json" + @pytest.fixture def bulletin_json_path(): return TEST_BULLETIN_JSON diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index b8a6cff38..5d920429c 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -88,7 +88,9 @@ def test_announcementchecker(bulletin_json_path): context = CommandContext.from_labels(labels=labels) context.state = {} context.state["announcement last seen date"] = "10/10/2023" - checker = AnnouncementChecker(state=context.state, bulletin_json_path=bulletin_json_path) + checker = AnnouncementChecker( + state=context.state, bulletin_json_path=bulletin_json_path + ) # Check if the announcement checker gets the correct date from the app assert checker.previous_announcement_date == "10/10/2023" From dce4dab00b156d3255fdfa31ddc57dbc8c3ce47e Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 30 Oct 2023 01:24:27 -0700 Subject: [PATCH 10/25] Fix bulletin json creation --- docs/make_bulletin_json.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index e9c7f4d89..8376968e1 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -17,13 +17,16 @@ def generate_json_file(): date = "DEFAULT_DATE" for line in markdown_content.split("\n"): - if line.startswith("---"): + # Skip if the line begins with # + if line.startswith("# "): + continue + elif line.startswith("---"): bulletin_json.append({"title": title, "date": date, "content": content}) content = "" # Reset title and date to their default values after each section title = "DEFAULT_TITLE" date = "DEFAULT_DATE" - elif line.startswith("##"): + elif line.startswith("## "): title = line[3:].strip() elif line.startswith("_"): date = line[1 : len(line) - 1].strip() From 9e1ebf7985e6bf306a4b5a7d42dda37795688060 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 30 Oct 2023 16:28:57 -0700 Subject: [PATCH 11/25] Set latest data with title --- sleap/gui/web.py | 6 +++--- tests/gui/test_web.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 24a72dfa0..f4ed06f67 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -188,7 +188,7 @@ def new_announcement(self): def get_latest_announcement(self) -> Optional[Tuple[str, str]]: """Return latest announcements on the releases page not seen by user.""" if self.new_announcement: - return (self._latest_data["date"], self._latest_data["content"]) + return (self._latest_data["title"], self._latest_data["date"], self._latest_data["content"]) return None def update_announcement(self): @@ -196,8 +196,8 @@ def update_announcement(self): announcement = self.get_latest_announcement() if announcement is None: return - self.state["announcement last seen date"] = announcement[0] - self.state["announcement"] = announcement[1] + self.state["announcement last seen date"] = announcement[1] + self.state["announcement"] = announcement[2] def get_analytics_data() -> Dict[str, Any]: diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index 5d920429c..942d4e84f 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -105,7 +105,7 @@ def test_announcementchecker(bulletin_json_path): # Check if latest announcement is fetched announcement = checker.get_latest_announcement() - assert announcement == ("10/12/2023", "New announcement") + assert announcement == ("title1", "10/12/2023", "New announcement") checker.update_announcement() assert context.state["announcement last seen date"] == "10/12/2023" From d35f02906d348ad5acd949a85a3389f6f3c1640f Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Wed, 1 Nov 2023 23:43:06 -0700 Subject: [PATCH 12/25] Correct json directory --- docs/make_bulletin_json.py | 2 +- sleap/gui/web.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index 8376968e1..4f474dbb6 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -19,7 +19,7 @@ def generate_json_file(): for line in markdown_content.split("\n"): # Skip if the line begins with # if line.startswith("# "): - continue + continue elif line.startswith("---"): bulletin_json.append({"title": title, "date": date, "content": content}) content = "" diff --git a/sleap/gui/web.py b/sleap/gui/web.py index f4ed06f67..104649c65 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -10,9 +10,7 @@ REPO_ID = "talmolab/sleap" ANALYTICS_ENDPOINT = "https://analytics.sleap.ai/ping" -BASE_DIR = os.path.dirname( - os.path.abspath(os.path.join(__file__, os.path.pardir, os.pardir)) -) +BASE_DIR = os.path.dirname(os.path.abspath(os.path.join(__file__, os.path.pardir))) BULLETIN_JSON = os.path.join(BASE_DIR, "..", "docs", "bulletin.json") @@ -188,7 +186,11 @@ def new_announcement(self): def get_latest_announcement(self) -> Optional[Tuple[str, str]]: """Return latest announcements on the releases page not seen by user.""" if self.new_announcement: - return (self._latest_data["title"], self._latest_data["date"], self._latest_data["content"]) + return ( + self._latest_data["title"], + self._latest_data["date"], + self._latest_data["content"], + ) return None def update_announcement(self): From 21ea789b44f16d770b7874c80fb522847ea21867 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Thu, 30 Nov 2023 11:15:36 -0800 Subject: [PATCH 13/25] additional condition to announcementchecker class --- sleap/gui/web.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index 104649c65..a6fe79d1f 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -171,13 +171,13 @@ def _read_bulletin_data(self): data = json.load(jsf) self._latest_data = data[0] except FileNotFoundError: - self._latest_data = {} + self._latest_data = None @property - def new_announcement(self): + def new_announcement_available(self): self._read_bulletin_data() if ( - self._latest_data + self._latest_data and self.previous_announcement_date and self._latest_data["date"] != self.previous_announcement_date ): return True @@ -185,7 +185,7 @@ def new_announcement(self): def get_latest_announcement(self) -> Optional[Tuple[str, str]]: """Return latest announcements on the releases page not seen by user.""" - if self.new_announcement: + if self.new_announcement_available: return ( self._latest_data["title"], self._latest_data["date"], From 3cc4188b99d63c3cd1205b548a8f9d41a006a596 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Sat, 2 Dec 2023 00:45:30 -0800 Subject: [PATCH 14/25] Better date comparison, more tests --- sleap/gui/web.py | 12 ++++++++---- .../test_bulletin.json | 2 +- tests/gui/test_web.py | 13 +++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index a6fe79d1f..fa10242dd 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -6,6 +6,7 @@ from typing import List, Dict, Any, Optional, Tuple import json import os +from datetime import datetime REPO_ID = "talmolab/sleap" @@ -164,7 +165,7 @@ def previous_announcement_date(self): _previous_announcement_date = self.state["announcement last seen date"] return _previous_announcement_date - def _read_bulletin_data(self): + def _read_bulletin_data(self) -> Optional[Dict]: """Reads the bulletin data from the JSON file.""" try: with open(self.bulletin_json_path, "r") as jsf: @@ -176,14 +177,17 @@ def _read_bulletin_data(self): @property def new_announcement_available(self): self._read_bulletin_data() + latest_date = datetime.strptime(self._latest_data["date"], "%m/%d/%Y") + previous_date = datetime.strptime(self.previous_announcement_date, "%m/%d/%Y") if ( - self._latest_data and self.previous_announcement_date - and self._latest_data["date"] != self.previous_announcement_date + self._latest_data + and self.previous_announcement_date + and latest_date > previous_date ): return True return False - def get_latest_announcement(self) -> Optional[Tuple[str, str]]: + def get_latest_announcement(self) -> Optional[Tuple[str, str, str]]: """Return latest announcements on the releases page not seen by user.""" if self.new_announcement_available: return ( diff --git a/tests/data/announcement_checker_bulletin/test_bulletin.json b/tests/data/announcement_checker_bulletin/test_bulletin.json index a6dbf01a4..a4b2e60c8 100644 --- a/tests/data/announcement_checker_bulletin/test_bulletin.json +++ b/tests/data/announcement_checker_bulletin/test_bulletin.json @@ -1 +1 @@ -[{"title": "title1", "date": "10/12/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}] \ No newline at end of file +[{"title": "title1", "date": "10/09/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}] \ No newline at end of file diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index 942d4e84f..bd0d7d26e 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -107,10 +107,23 @@ def test_announcementchecker(bulletin_json_path): announcement = checker.get_latest_announcement() assert announcement == ("title1", "10/12/2023", "New announcement") + # Check if announcement is updated checker.update_announcement() assert context.state["announcement last seen date"] == "10/12/2023" assert context.state["announcement"] == "New announcement" + # Create dummy JSON file + bulletin_data = [ + {"title": "title1", "date": "10/09/2023", "content": "New announcement"}, + {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}, + ] + with open(bulletin_json_path, "w") as test_file: + json.dump(bulletin_data, test_file) + + # Check to ensure no new announcement is created + announcement = checker.get_latest_announcement() + assert announcement == None + def test_get_analytics_data(): analytics_data = get_analytics_data() From 59f07aee7012d513ce1ec8ddb2300c748f37e2cf Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Tue, 5 Dec 2023 00:35:24 -0800 Subject: [PATCH 15/25] Add more conditions to announcementchecker class --- sleap/gui/web.py | 27 +++++++++++++++------------ tests/gui/test_web.py | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index fa10242dd..a1a946184 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -174,22 +174,24 @@ def _read_bulletin_data(self) -> Optional[Dict]: except FileNotFoundError: self._latest_data = None - @property - def new_announcement_available(self): + def new_announcement_available(self) -> bool: + """Check if latest announcement is available.""" self._read_bulletin_data() - latest_date = datetime.strptime(self._latest_data["date"], "%m/%d/%Y") - previous_date = datetime.strptime(self.previous_announcement_date, "%m/%d/%Y") - if ( - self._latest_data - and self.previous_announcement_date - and latest_date > previous_date - ): + if self.previous_announcement_date and self._latest_data: + latest_date = datetime.strptime(self._latest_data["date"], "%m/%d/%Y") + previous_date = datetime.strptime( + self.previous_announcement_date, "%m/%d/%Y" + ) + if latest_date > previous_date: + return True + else: + return False + else: return True - return False def get_latest_announcement(self) -> Optional[Tuple[str, str, str]]: """Return latest announcements on the releases page not seen by user.""" - if self.new_announcement_available: + if self.new_announcement_available(): return ( self._latest_data["title"], self._latest_data["date"], @@ -203,7 +205,8 @@ def update_announcement(self): if announcement is None: return self.state["announcement last seen date"] = announcement[1] - self.state["announcement"] = announcement[2] + new_announcement = "\n".join(announcement[2].split("\n")) + self.state["announcement"] = "## " + announcement[0] + "\n" + new_announcement def get_analytics_data() -> Dict[str, Any]: diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index bd0d7d26e..edc5b28f0 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -110,7 +110,7 @@ def test_announcementchecker(bulletin_json_path): # Check if announcement is updated checker.update_announcement() assert context.state["announcement last seen date"] == "10/12/2023" - assert context.state["announcement"] == "New announcement" + assert context.state["announcement"] == "## title1\nNew announcement" # Create dummy JSON file bulletin_data = [ From acdf1300ec16bed5efafa914713543b1246915fe Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Tue, 5 Dec 2023 00:58:06 -0800 Subject: [PATCH 16/25] Correct default value in prefs --- sleap/prefs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sleap/prefs.py b/sleap/prefs.py index b7f50c9e1..17a49e029 100644 --- a/sleap/prefs.py +++ b/sleap/prefs.py @@ -29,8 +29,8 @@ class Preferences(object): "node label size": 12, "show non-visible nodes": True, "share usage data": True, - "announcement last seen date": None, - "announcement": None, + "announcement last seen date": False, + "announcement": False, } _filename = "preferences.yaml" From 68cb64b82851460a69b0e8fa9b42322157aaf81b Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Fri, 5 Jan 2024 17:20:23 -0800 Subject: [PATCH 17/25] add branch to website workflow --- .github/workflows/website.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index e33c9df3e..380a1e80e 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -9,6 +9,7 @@ on: - main - develop - shrivaths/changelog-announcement-1 + - shrivaths/changelog-announcement-2 paths: - "docs/**" - "README.rst" From 2c92712340147411e1e870f7ae36269bae685197 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 8 Jan 2024 15:22:11 -0800 Subject: [PATCH 18/25] add json file to the website --- .github/workflows/website.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 380a1e80e..cdb644ecc 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -49,6 +49,7 @@ jobs: run: | cd docs python make_api_doctree.py + python make_bulletin_json.py make html - name: Deploy (sleap.ai) From 303a2d2760e01934df1553d5fbc9b64079fd4d05 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 8 Jan 2024 16:40:35 -0800 Subject: [PATCH 19/25] generate json in the correct path --- docs/make_bulletin_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index 4f474dbb6..e5852aaee 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -35,7 +35,7 @@ def generate_json_file(): # Append last section bulletin_json.append({"title": title, "date": date, "content": content}) - with open(output_json_file, "w", encoding="utf-8") as json_file: + with open("bulletin.json", "w", encoding="utf-8") as json_file: json.dump(bulletin_json, json_file, ensure_ascii=False, indent=4) From b70871717c98be96088928a57dfc4f74623c783c Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 8 Jan 2024 17:05:34 -0800 Subject: [PATCH 20/25] store json as text file --- docs/make_bulletin_json.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index e5852aaee..7c8b81bfb 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -35,8 +35,8 @@ def generate_json_file(): # Append last section bulletin_json.append({"title": title, "date": date, "content": content}) - with open("bulletin.json", "w", encoding="utf-8") as json_file: - json.dump(bulletin_json, json_file, ensure_ascii=False, indent=4) + with open("bulletin.json", "w") as f: + f.write(repr(bulletin_json)) if __name__ == "__main__": From a679e618cc612f172bf35d691a682a59abd720a5 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Mon, 8 Jan 2024 21:54:09 -0800 Subject: [PATCH 21/25] keep_files is set true --- .github/workflows/website.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index cdb644ecc..c5a0ba568 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -68,4 +68,5 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} publish_branch: gh-pages publish_dir: docs/build/html - destination_dir: develop \ No newline at end of file + destination_dir: develop + keep_files: true \ No newline at end of file From 02757e6ab5dac6bd6a71d6fbda4f3c80728a6983 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Tue, 9 Jan 2024 15:55:53 -0800 Subject: [PATCH 22/25] add json to _static directory --- docs/make_bulletin_json.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index 7c8b81bfb..b0a6c0b47 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -35,8 +35,8 @@ def generate_json_file(): # Append last section bulletin_json.append({"title": title, "date": date, "content": content}) - with open("bulletin.json", "w") as f: - f.write(repr(bulletin_json)) + with open("_static/bulletin.json", "w") as json_file: + json.dump(bulletin_json, json_file, indent=4) if __name__ == "__main__": From 090e36f7ebf42d5d4b2ef0d0bb79a2ffd49537c4 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Wed, 10 Jan 2024 16:52:02 -0800 Subject: [PATCH 23/25] Modify AnnouncementChecker Class with bulletin url --- sleap/gui/web.py | 75 ++++++++++++++++++++++--------------------- tests/gui/test_web.py | 42 ++++++++++++------------ 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index a1a946184..a5443be79 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -11,8 +11,8 @@ REPO_ID = "talmolab/sleap" ANALYTICS_ENDPOINT = "https://analytics.sleap.ai/ping" -BASE_DIR = os.path.dirname(os.path.abspath(os.path.join(__file__, os.path.pardir))) -BULLETIN_JSON = os.path.join(BASE_DIR, "..", "docs", "bulletin.json") +# TODO: Change the Bulletin URL to the main website before deploying +BULLETIN_JSON_ENDPOINT = "https://sleap.ai/develop/docs/_static/bulletin.json" @attr.s(auto_attribs=True) @@ -156,57 +156,58 @@ class AnnouncementChecker: """Checker for new announcements on the bulletin page of sleap.""" state: "GuiState" - bulletin_json_path: str = BULLETIN_JSON _previous_announcement_date: str = None - _latest_data: Optional[Dict[str, str]] = None + bulletin_json_data: Optional[List[Dict[str, str]]] = None + json_data_url: str = BULLETIN_JSON_ENDPOINT + checked: bool = attr.ib(default=False, init=False) @property def previous_announcement_date(self): _previous_announcement_date = self.state["announcement last seen date"] return _previous_announcement_date - def _read_bulletin_data(self) -> Optional[Dict]: - """Reads the bulletin data from the JSON file.""" + def check_for_bulletin_data(self) -> Optional[List[Dict]]: + """Reads the bulletin data from the JSON file endpoint.""" try: - with open(self.bulletin_json_path, "r") as jsf: - data = json.load(jsf) - self._latest_data = data[0] - except FileNotFoundError: - self._latest_data = None + self.checked = True + self.bulletin_json_data = requests.get(self.json_data_url).json() + except (requests.ConnectionError, requests.Timeout): + self.bulletin_json_data = None def new_announcement_available(self) -> bool: """Check if latest announcement is available.""" - self._read_bulletin_data() - if self.previous_announcement_date and self._latest_data: - latest_date = datetime.strptime(self._latest_data["date"], "%m/%d/%Y") - previous_date = datetime.strptime( - self.previous_announcement_date, "%m/%d/%Y" - ) - if latest_date > previous_date: - return True + if not self.checked: + self.check_for_bulletin_data() + if self.bulletin_json_data: + if self.previous_announcement_date: + latest_date = datetime.strptime( + self.bulletin_json_data[0]["date"], "%m/%d/%Y" + ) + previous_date = datetime.strptime( + self.previous_announcement_date, "%m/%d/%Y" + ) + if latest_date > previous_date: + return True + else: + return False else: - return False + return True else: - return True + return False - def get_latest_announcement(self) -> Optional[Tuple[str, str, str]]: + def update_latest_announcement(self) -> Optional[Tuple[str, str, str]]: """Return latest announcements on the releases page not seen by user.""" if self.new_announcement_available(): - return ( - self._latest_data["title"], - self._latest_data["date"], - self._latest_data["content"], - ) - return None - - def update_announcement(self): - """Update the last seen date of announcement in preferences.""" - announcement = self.get_latest_announcement() - if announcement is None: - return - self.state["announcement last seen date"] = announcement[1] - new_announcement = "\n".join(announcement[2].split("\n")) - self.state["announcement"] = "## " + announcement[0] + "\n" + new_announcement + announcement_markdown = "" + for announcement in self.bulletin_json_data: + announcement_content = "\n".join(announcement["content"].split("\n")) + announcement_markdown += ( + "## " + announcement["title"] + "\n" + announcement_content + "\n" + ) + self.state["announcement"] = announcement_markdown + self.state["announcement last seen date"] = self.bulletin_json_data[0][ + "date" + ] def get_analytics_data() -> Dict[str, Any]: diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index edc5b28f0..045f0b6a4 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -82,47 +82,47 @@ def test_release_checker(): assert checker.releases[1] != rls_test -def test_announcementchecker(bulletin_json_path): - +def test_announcementchecker(): labels = Labels() context = CommandContext.from_labels(labels=labels) context.state = {} context.state["announcement last seen date"] = "10/10/2023" - checker = AnnouncementChecker( - state=context.state, bulletin_json_path=bulletin_json_path - ) - - # Check if the announcement checker gets the correct date from the app - assert checker.previous_announcement_date == "10/10/2023" - # Create dummy JSON file to check bulletin_data = [ {"title": "title1", "date": "10/12/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}, ] - with open(bulletin_json_path, "w") as test_file: - json.dump(bulletin_data, test_file) + checker = AnnouncementChecker(state=context.state, bulletin_json_data=bulletin_data) + checker.checked = True + # Check if the announcement checker gets the correct date from the app + assert checker.previous_announcement_date == "10/10/2023" # Check if latest announcement is fetched - announcement = checker.get_latest_announcement() - assert announcement == ("title1", "10/12/2023", "New announcement") + is_announcement_available = checker.new_announcement_available() + assert is_announcement_available == True + + # Concatenate the bulletin content to check updated announcement text + announcement_markdown = "" + for announcement in bulletin_data: + announcement_content = "\n".join(announcement["content"].split("\n")) + announcement_markdown += ( + "## " + announcement["title"] + "\n" + announcement_content + "\n" + ) # Check if announcement is updated - checker.update_announcement() + checker.update_latest_announcement() assert context.state["announcement last seen date"] == "10/12/2023" - assert context.state["announcement"] == "## title1\nNew announcement" + assert context.state["announcement"] == announcement_markdown - # Create dummy JSON file + # Create another dummy JSON file bulletin_data = [ {"title": "title1", "date": "10/09/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}, ] - with open(bulletin_json_path, "w") as test_file: - json.dump(bulletin_data, test_file) - + checker.bulletin_json_data = bulletin_data # Check to ensure no new announcement is created - announcement = checker.get_latest_announcement() - assert announcement == None + is_announcement_available = checker.new_announcement_available() + assert is_announcement_available == False def test_get_analytics_data(): From aca6c7a62770582c7994bfc77cb2030ecb0ef870 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Thu, 11 Jan 2024 01:49:48 -0800 Subject: [PATCH 24/25] add date to announcement --- sleap/gui/web.py | 8 +++++++- tests/gui/test_web.py | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/sleap/gui/web.py b/sleap/gui/web.py index a5443be79..98f664d56 100644 --- a/sleap/gui/web.py +++ b/sleap/gui/web.py @@ -202,7 +202,13 @@ def update_latest_announcement(self) -> Optional[Tuple[str, str, str]]: for announcement in self.bulletin_json_data: announcement_content = "\n".join(announcement["content"].split("\n")) announcement_markdown += ( - "## " + announcement["title"] + "\n" + announcement_content + "\n" + "## " + + announcement["title"] + + "\n" + + announcement["date"] + + "\n" + + announcement_content + + "\n" ) self.state["announcement"] = announcement_markdown self.state["announcement last seen date"] = self.bulletin_json_data[0][ diff --git a/tests/gui/test_web.py b/tests/gui/test_web.py index 045f0b6a4..c3c1fc397 100644 --- a/tests/gui/test_web.py +++ b/tests/gui/test_web.py @@ -106,7 +106,13 @@ def test_announcementchecker(): for announcement in bulletin_data: announcement_content = "\n".join(announcement["content"].split("\n")) announcement_markdown += ( - "## " + announcement["title"] + "\n" + announcement_content + "\n" + "## " + + announcement["title"] + + "\n" + + announcement["date"] + + "\n" + + announcement_content + + "\n" ) # Check if announcement is updated From c218b10958d1c7071b7e49b086096473166b0633 Mon Sep 17 00:00:00 2001 From: Shrivaths Shyam Date: Wed, 17 Jan 2024 13:51:29 -0800 Subject: [PATCH 25/25] add regex for date check --- docs/make_bulletin_json.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/make_bulletin_json.py b/docs/make_bulletin_json.py index b0a6c0b47..3c4789ba6 100644 --- a/docs/make_bulletin_json.py +++ b/docs/make_bulletin_json.py @@ -1,10 +1,12 @@ import json -import os +import re +from pathlib import Path -# Set the file paths -input_md_file = os.path.join(os.path.dirname(__file__), "bulletin.md") -output_json_file = os.path.join(os.path.dirname(__file__), "bulletin.json") +# Set the file path to the markdown file +input_md_file = Path(__file__).resolve().parent / "bulletin.md" +# Regex for date +date_pattern = r'^_(\d{2}/\d{2}/\d{4})_$' def generate_json_file(): with open(input_md_file, "r", encoding="utf-8") as md_file: @@ -28,7 +30,7 @@ def generate_json_file(): date = "DEFAULT_DATE" elif line.startswith("## "): title = line[3:].strip() - elif line.startswith("_"): + elif re.match(date_pattern, line): date = line[1 : len(line) - 1].strip() else: content += line + "\n"