-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PR2: Add new preference and AnnouncementChecker
class
#1509
base: shrivaths/changelog-announcement-1
Are you sure you want to change the base?
Changes from 20 commits
de22a57
69ff1ed
3fc0e75
0db2904
7ab6d8b
7639142
babb86d
6eddcf0
3f99b8b
f8fb1f1
d9947c3
4cb0c6a
3323115
fc856bf
39ed0b6
dce4dab
9e1ebf7
d35f029
21ea789
3cc4188
59f07ae
acdf130
fbb1039
63e329a
cbb661d
9c726af
68cb64b
2c92712
303a2d2
b708717
a679e61
02757e6
090e36f
aca6c7a
c218b10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,43 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def generate_json_file(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
with open(input_md_file, "r", encoding="utf-8") as md_file: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
markdown_content = md_file.read() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bulletin_json = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
content = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Initialize title and date with default values | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
title = "DEFAULT_TITLE" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
date = "DEFAULT_DATE" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for line in markdown_content.split("\n"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# 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("## "): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The - 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(input_md_file, output_json_file):
# rest of the code
if __name__ == "__main__":
- generate_json_file()
+ input_md_file = os.path.join(os.path.dirname(__file__), "bulletin.md")
+ output_json_file = os.path.join(os.path.dirname(__file__), "bulletin.json")
+ generate_json_file(input_md_file, output_json_file) Commitable suggestion (Beta)
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if __name__ == "__main__": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
generate_json_file() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,16 @@ | |
import attr | ||
import pandas as pd | ||
import requests | ||
from typing import List, Dict, Any | ||
from typing import List, Dict, Any, Optional, Tuple | ||
import json | ||
import os | ||
from datetime import datetime | ||
|
||
|
||
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") | ||
|
||
|
||
@attr.s(auto_attribs=True) | ||
|
@@ -146,6 +151,61 @@ def get_release(self, version: str) -> Release: | |
) | ||
|
||
|
||
@attr.s(auto_attribs=True) | ||
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 | ||
|
||
@property | ||
def previous_announcement_date(self): | ||
_previous_announcement_date = self.state["announcement last seen date"] | ||
return _previous_announcement_date | ||
Comment on lines
+165
to
+167
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider handling the case where the key "announcement last seen date" might not exist in |
||
|
||
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: | ||
data = json.load(jsf) | ||
self._latest_data = data[0] | ||
except FileNotFoundError: | ||
self._latest_data = None | ||
|
||
@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 latest_date > previous_date | ||
): | ||
return True | ||
return False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
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 ( | ||
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] | ||
self.state["announcement"] = announcement[2] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
|
||
def get_analytics_data() -> Dict[str, Any]: | ||
"""Gather data to be transmitted to analytics backend.""" | ||
import os | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"title": "title1", "date": "10/09/2023", "content": "New announcement"}, {"title": "title2", "date": "10/07/2023", "content": "Old Announcment"}] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import pytest | ||
|
||
TEST_BULLETIN_JSON = "tests/data/announcement_checker_bulletin/test_bulletin.json" | ||
|
||
|
||
@pytest.fixture | ||
def bulletin_json_path(): | ||
return TEST_BULLETIN_JSON |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,16 @@ | ||
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 | ||
import json | ||
import os | ||
from sleap.gui.commands import CommandContext | ||
from sleap.io.dataset import Labels | ||
|
||
|
||
def test_release_from_json(): | ||
|
@@ -72,6 +82,49 @@ def test_release_checker(): | |
assert checker.releases[1] != rls_test | ||
|
||
|
||
def test_announcementchecker(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" | ||
|
||
# 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) | ||
|
||
# Check if latest announcement is fetched | ||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The def test_announcementchecker(bulletin_json_path):
# ... existing test code ...
# Teardown code to remove the dummy JSON file
os.remove(bulletin_json_path) |
||
|
||
|
||
This comment was marked as off-topic.
Sorry, something went wrong. |
||
def test_get_analytics_data(): | ||
analytics_data = get_analytics_data() | ||
assert "platform" in analytics_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably needs a stronger check, like a date format regexp or another more explicit indicator. There are lots of cases where we might start a line with
"_"
in the main content.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a regex that checks if the entire line has only the date content and it is in a certain format.