Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"permissions": {
"allow": [
"WebSearch"
"WebSearch",
"mcp__context7__resolve-library-id",
"mcp__context7__get-library-docs",
"Bash(npm test)"
],
"deny": [],
"ask": []
Expand Down
10 changes: 7 additions & 3 deletions events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ prod:
titlePrefix: '#Brekkie'
showEditLink: true
- schedule:
enabled: false
rate: cron(0 7 ? * FRI *)
name: 'coles-dinner'
description: 'Coles Dinner'
Expand All @@ -41,6 +42,7 @@ prod:
titlePrefix: '#Dinner'
showEditLink: true
- schedule:
enabled: false
rate: cron(0 7 1-7 * ? *)
name: 'something-different-1'
description: 'Something Different 1'
Expand All @@ -54,6 +56,7 @@ prod:
titlePrefix: '#Dinner'
showEditLink: true
- schedule:
enabled: false
rate: cron(0 7 15-21 * ? *)
name: 'something-different-2'
description: 'Something Different 2'
Expand All @@ -80,6 +83,7 @@ prod:
titlePrefix: '#JamaicanDish'
showEditLink: true
- schedule:
enabled: false
rate: cron(0 7 22-28 * ? *)
name: 'jamaican-dish-2'
description: 'Jamaican Dish 2'
Expand Down Expand Up @@ -147,7 +151,7 @@ prod:
titlePrefix: '#CoupleSkills'
- schedule:
enabled: true
rate: cron(0 10 ? * 2/2 *)
rate: cron(0 10 ? * FRI-SAT *)
name: 'PillowTalk'
description: 'Pillow Talk'
input:
Expand Down Expand Up @@ -229,7 +233,7 @@ prod:
titlePrefix: '#BetterSelf'
showEditLink: true
- schedule:
rate: cron(0 10 ? * SUN-THUR *)
rate: cron(0 7 ? * MON-FRI *)
name: 'notifyer-mantras'
description: 'Mantras | Sydney | AEDT'
input:
Expand All @@ -243,7 +247,7 @@ prod:
titlePrefix: '#mantras'
showEditLink: true
- schedule:
rate: cron(0 10 ? * SUN-THUR *)
rate: cron(0 7 ? * SAT,SUN *)
name: 'notifyer-quotes'
description: 'Quotes | Sydney | AEDT'
input:
Expand Down
33 changes: 25 additions & 8 deletions lib/onenote.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,24 @@ const GraphOneNoteService = require('./graph-onenote-service');
const localStorage = require('./store');

const Chance = require('chance');
const chance = new Chance();

/**
* Calculate day of year with leap year support
* @param {Date} date - Date to calculate from (defaults to today)
* @returns {number} Day of year (1-366 for leap years)
*/
function getDayOfYear(date = new Date()) {
const start = new Date(date.getFullYear(), 0, 1);
const diff = date - start;
const oneDay = 1000 * 60 * 60 * 24;
return Math.floor(diff / oneDay) + 1;
}

/**
* seed chance with the day of the year for deterministic randomization
* that hopefully better distributes randomness across old and new notes in a section
*/
const chance = (process.env.NODE_ENV === 'production') ? new Chance(getDayOfYear()) : new Chance();

const graphService = new GraphOneNoteService();

Expand Down Expand Up @@ -142,7 +159,7 @@ async function getNotePreview(note) {

try {
const response = await graphService.getPagePreview(id)

return {
title,
preview: response,
Expand All @@ -165,10 +182,10 @@ async function getNoteContents(url) {
try {
const pageId = extractPageIdFromUrl(url)
const response = await graphService.getPageContent(pageId)

// Log page ID for debugging
console.log('Retrieved content for page ID:', pageId)

return response
} catch (error) {
console.error('getNoteContents', error)
Expand All @@ -191,13 +208,13 @@ function extractPageIdFromUrl(url) {
*/
function logRecentNote(note, sectionHandle) {
let notes = localStorage.getItem(`recent_${sectionHandle}`, true) || []

// Ensure notes is always an array
if (!Array.isArray(notes)) {
console.warn(`Expected array for recent_${sectionHandle}, got:`, typeof notes, notes)
notes = []
}

const recent = Number(process.env.RECENT_NOTE_LENGTH) || 7
console.log('recent', recent)
if (notes.length === recent) {
Expand Down Expand Up @@ -248,7 +265,7 @@ function extractFirstImage(htmlContent) {
width: firstImg.getAttribute('width') || null,
height: firstImg.getAttribute('height') || null
}

return result
}

Expand Down Expand Up @@ -302,5 +319,5 @@ module.exports = {
setNoteSection,
extractFirstImage,
downloadImage,
getImageSize
getImageSize,
}
69 changes: 69 additions & 0 deletions tests/onenote.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const Chance = require('chance');

// Import the getDayOfYear function from the actual module
const { getDayOfYear } = require('../lib/onenote');

describe('getDayOfYear function', () => {
// Test regular year
test('calculates correct day of year for a non-leap year', () => {
const testDate = new Date(2023, 0, 15); // January 15, 2023
expect(getDayOfYear(testDate)).toBe(15);
});

// Test leap year
test('calculates correct day of year for a leap year', () => {
const testDate = new Date(2024, 1, 29); // February 29, 2024 (leap year)
expect(getDayOfYear(testDate)).toBe(60);
});

// Test edge cases
test('first day of the year returns 1', () => {
const testDate = new Date(2023, 0, 1);
expect(getDayOfYear(testDate)).toBe(1);
});

test('last day of a non-leap year returns 365', () => {
const testDate = new Date(2023, 11, 31);
expect(getDayOfYear(testDate)).toBe(365);
});

test('last day of a leap year returns 366', () => {
const testDate = new Date(2024, 11, 31);
expect(getDayOfYear(testDate)).toBe(366);
});
});

describe('Seeded Chance Randomness', () => {
test('same seed produces same random results', () => {
const seed = getDayOfYear(new Date('2023-01-15'));
const chance1 = new Chance(seed);
const chance2 = new Chance(seed);

// Test multiple random generations
for (let i = 0; i < 10; i++) {
expect(chance1.natural()).toBe(chance2.natural());
expect(chance1.pickone([1, 2, 3])).toBe(chance2.pickone([1, 2, 3]));
}
});

test('different dates produce different seeds', () => {
const chance1 = new Chance(getDayOfYear(new Date('2023-01-15')));
const chance2 = new Chance(getDayOfYear(new Date('2023-02-15')));

// While not guaranteed, the probability of these being exactly the same
// for multiple generations is extremely low
const results1 = new Set();
const results2 = new Set();

for (let i = 0; i < 100; i++) {
results1.add(chance1.natural());
results2.add(chance2.natural());
}

expect(results1.size).toBeGreaterThan(1);
expect(results2.size).toBeGreaterThan(1);

// Ensure they're different sets
expect(Array.from(results1)).not.toEqual(Array.from(results2));
});
});