Skip to content

Commit 9b51430

Browse files
authored
Merge pull request #15 from LuisAPI/codex/find-and-fix-an-important-bug
Fix channel parsing in fetch_channels_needing_updates
2 parents 60c3662 + d1e13f8 commit 9b51430

3 files changed

Lines changed: 62 additions & 37 deletions

File tree

src/utils.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,37 @@ def generate_wiki_content(channel_info, username, join_date, statistics):
6868
* Please leave the bottom part alone *
6969
* The channel box is updated regularly *
7070
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■-->"""
71-
infobox_content = f"""{{Infobox channel
71+
infobox_content_top = f"""{{{{Infobox channel
7272
|channel_name = {channel_info['title']}
7373
|subscribers = {statistics.get('subscriberCount', '')}
7474
|views = {statistics.get('viewCount', '')}
7575
|years_active = {channel_info.get('years_active', '')}
76-
|as_of = {{subst:#time:j F Y}}
76+
|as_of = {{{{subst:#time:j F Y}}}}
7777
"""
7878

7979
if new_top_marker in boilerplate and new_bottom_marker in boilerplate:
8080
# Extract content between new markers
81-
parts = boilerplate.split(new_bottom_marker)
82-
top_part = parts[0].split(new_top_marker)[0] + new_top_marker
81+
82+
# Split at the top marker
83+
top_split = boilerplate.split(new_top_marker, 1)
84+
top = top_split[0]
85+
rest = top_split[1] if len(top_split) > 1 else ""
86+
87+
# Split the rest at the bottom marker
88+
middle_split = rest.split(new_bottom_marker, 1)
89+
middle = middle_split[0]
90+
bottom = middle_split[1] if len(middle_split) > 1 else ""
91+
92+
# Now you have:
93+
# top -> before new_top_marker
94+
# middle -> between new_top_marker and new_bottom_marker
95+
# bottom -> after new_bottom_marker
96+
97+
top_part = infobox_content_top + new_top_marker + rest
98+
bottom_part = new_bottom_marker + bottom
8399

84100
# Combine the top part, autogenerated paragraph, and bottom part
85-
wiki_content = f"{top_part}\n\n{auto_paragraph}\n\n{parts[1]}"
101+
wiki_content = f"{top_part}\n\n{auto_paragraph}\n\n{bottom_part}"
86102
marker_comment = new_top_marker
87103

88104
elif old_bottom_marker in boilerplate:
@@ -95,8 +111,23 @@ def generate_wiki_content(channel_info, username, join_date, statistics):
95111
marker_comment = old_bottom_marker
96112

97113
else:
98-
# Fallback if no markers are found
99-
wiki_content = boilerplate
114+
# Split at the top marker
115+
top_split = boilerplate.split(new_top_marker, 1)
116+
top = top_split[0]
117+
rest = top_split[1] if len(top_split) > 1 else ""
118+
119+
# Split the rest at the bottom marker
120+
middle_split = rest.split(new_bottom_marker, 1)
121+
middle = middle_split[0]
122+
bottom = middle_split[1] if len(middle_split) > 1 else ""
123+
124+
# Now you have:
125+
# top -> before new_top_marker
126+
# middle -> between new_top_marker and new_bottom_marker
127+
# bottom -> after new_bottom_marker
128+
129+
wiki_content = infobox_content_top + new_top_marker + "\n\n" + auto_paragraph + "\n\n" + middle + bottom
130+
# No marker comment since this is a new page
100131
marker_comment = ""
101132

102133
return marker_comment, wiki_content

src/wiki_bot.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# wiki_bot.py
22

33
import mwclient
4+
import re
45

56
def connect_to_wiki(wiki_url, wiki_path, username, password):
67
"""Connects to the MediaWiki site."""
@@ -21,20 +22,14 @@ def check_page_exists(site, page_title):
2122

2223
def fetch_channels_needing_updates(site, page_title):
2324
"""Fetches the list of channels needing updates from the specified wiki page."""
24-
# Access the specified page
2525
page = site.pages[page_title]
2626
content = page.text()
27-
28-
# Parse the content to find channels (assumes a simple list format)
27+
2928
channels = []
30-
lines = content.splitlines()
31-
for line in lines:
32-
if line.startswith('*'):
33-
# Extract the channel handle from the line
34-
channel_info = line.split('(')
35-
if len(channel_info) > 1:
36-
# Get the handle without "Handle: " label
37-
channel_handle = channel_info[1].replace('Handle: ', '').strip(') ')
38-
channels.append(channel_handle)
39-
29+
for line in content.splitlines():
30+
if line.lstrip().startswith('*'):
31+
match = re.search(r'@[^\s)]+', line)
32+
if match:
33+
channels.append(match.group(0))
34+
4035
return channels

tests/test_wiki_bot.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,44 @@
1717
def mock_site():
1818
"""Fixture to mock mwclient.Site."""
1919
with patch('mwclient.Site') as MockSite:
20-
mock_site_instance = MockSite.return_value
21-
yield mock_site_instance
20+
yield MockSite
2221

2322
def test_connect_to_wiki(mock_site):
2423
"""Test connecting to the wiki."""
25-
mock_site.login.return_value = True # Mock successful login
24+
mock_site.return_value.login.return_value = True # Mock successful login
2625

2726
# Call the function with test settings
2827
site = connect_to_wiki(TEST_WIKI_URL, TEST_WIKI_PATH, TEST_USERNAME, TEST_PASSWORD)
2928

3029
# Assertions
3130
mock_site.assert_called_once_with(TEST_WIKI_URL, path=TEST_WIKI_PATH)
32-
mock_site.login.assert_called_once_with(TEST_USERNAME, TEST_PASSWORD)
33-
assert site == mock_site
31+
mock_site.return_value.login.assert_called_once_with(TEST_USERNAME, TEST_PASSWORD)
32+
assert site == mock_site.return_value
3433

3534
def test_update_wiki_page(mock_site):
3635
"""Test updating a wiki page."""
3736
mock_page = MagicMock()
38-
mock_site.pages.__getitem__.return_value = mock_page # Mock accessing the page
37+
mock_site.return_value.pages.__getitem__.return_value = mock_page # Mock accessing the page
3938

4039
# Call the function
41-
update_wiki_page(mock_site, 'Test Page', 'New content', 'Test summary')
40+
update_wiki_page(mock_site.return_value, 'Test Page', 'New content', 'Test summary')
4241

4342
# Assertions
44-
mock_site.pages.__getitem__.assert_called_once_with('Test Page')
43+
mock_site.return_value.pages.__getitem__.assert_called_once_with('Test Page')
4544
mock_page.save.assert_called_once_with('New content', summary='Test summary')
4645

4746
def test_check_page_exists(mock_site):
4847
"""Test checking if a wiki page exists."""
4948
mock_page = MagicMock()
5049
mock_page.exists = True
5150
mock_page.text.return_value = "Page content"
52-
mock_site.pages.__getitem__.return_value = mock_page # Mock accessing the page
51+
mock_site.return_value.pages.__getitem__.return_value = mock_page # Mock accessing the page
5352

5453
# Call the function
55-
exists, content = check_page_exists(mock_site, 'Test Page')
54+
exists, content = check_page_exists(mock_site.return_value, 'Test Page')
5655

5756
# Assertions
58-
mock_site.pages.__getitem__.assert_called_once_with('Test Page')
57+
mock_site.return_value.pages.__getitem__.assert_called_once_with('Test Page')
5958
assert exists is True
6059
assert content == "Page content"
6160

@@ -66,13 +65,13 @@ def test_fetch_channels_needing_updates(mock_site):
6665
* Handle: @example_channel
6766
* Handle: @another_channel
6867
"""
69-
mock_site.pages.__getitem__.return_value = mock_page # Mock accessing the page
68+
mock_site.return_value.pages.__getitem__.return_value = mock_page # Mock accessing the page
7069

7170
# Call the function
72-
channels = fetch_channels_needing_updates(TEST_WIKI_URL, 'Channel Update Requests', TEST_USERNAME, TEST_PASSWORD)
71+
channels = fetch_channels_needing_updates(mock_site.return_value, 'Channel Update Requests')
7372

7473
# Assertions
75-
mock_site.pages.__getitem__.assert_called_once_with('Channel Update Requests')
74+
mock_site.return_value.pages.__getitem__.assert_called_once_with('Channel Update Requests')
7675
assert channels == ['@example_channel', '@another_channel']
7776

7877
@pytest.mark.parametrize("page_text, expected_channels", [
@@ -85,11 +84,11 @@ def test_fetch_channels_needing_updates_various(mock_site, page_text, expected_c
8584
"""Test fetching channels under various content scenarios."""
8685
mock_page = MagicMock()
8786
mock_page.text.return_value = page_text
88-
mock_site.pages.__getitem__.return_value = mock_page # Mock accessing the page
87+
mock_site.return_value.pages.__getitem__.return_value = mock_page # Mock accessing the page
8988

9089
# Call the function
91-
channels = fetch_channels_needing_updates(mock_site, 'Channel Update Requests')
90+
channels = fetch_channels_needing_updates(mock_site.return_value, 'Channel Update Requests')
9291

9392
# Assertions
94-
mock_site.pages.__getitem__.assert_called_once_with('Channel Update Requests')
93+
mock_site.return_value.pages.__getitem__.assert_called_once_with('Channel Update Requests')
9594
assert channels == expected_channels

0 commit comments

Comments
 (0)