Skip to content

Commit 1fd295e

Browse files
committed
Fix Israel ?i=on logic for RSS and more
1 parent bae49f7 commit 1fd295e

File tree

8 files changed

+89
-85
lines changed

8 files changed

+89
-85
lines changed

README.md

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# hebcal-rest-api
1+
# @hebcal/rest-api
22
Jewish holidays and Hebrew calendar as plain JSON objects, RSS, and CSV export
33

44
## Installation
@@ -79,11 +79,9 @@ Converts to lowercase and replaces non-word characters with hyphen ('-')
7979
<dd></dd>
8080
<dt><a href="#formatLeyningResult">formatLeyningResult(reading)</a> ⇒ <code>Object</code></dt>
8181
<dd></dd>
82-
<dt><a href="#getLinkAndGuid">getLinkAndGuid(ev, il)</a> ⇒ <code>Array.&lt;string&gt;</code></dt>
83-
<dd></dd>
8482
<dt><a href="#eventsToRss">eventsToRss(events, location, mainUrl, selfUrl, [lang], [evPubDate])</a> ⇒ <code>string</code></dt>
8583
<dd></dd>
86-
<dt><a href="#eventToRssItem">eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location)</a> ⇒ <code>string</code></dt>
84+
<dt><a href="#eventToRssItem">eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location, mainUrl)</a> ⇒ <code>string</code></dt>
8785
<dd></dd>
8886
<dt><a href="#eventToFullCalendar">eventToFullCalendar(ev, tzid, il)</a> ⇒ <code>Object</code></dt>
8987
<dd><p>Converts a Hebcal event to a FullCalendar.io object</p>
@@ -298,16 +296,6 @@ Converts a Hebcal event to a classic Hebcal.com JSON API object
298296
| --- | --- |
299297
| reading | <code>leyn.Leyning</code> |
300298

301-
<a name="getLinkAndGuid"></a>
302-
303-
## getLinkAndGuid(ev, il) ⇒ <code>Array.&lt;string&gt;</code>
304-
**Kind**: global function
305-
306-
| Param | Type |
307-
| --- | --- |
308-
| ev | <code>Event</code> |
309-
| il | <code>boolean</code> |
310-
311299
<a name="eventsToRss"></a>
312300

313301
## eventsToRss(events, location, mainUrl, selfUrl, [lang], [evPubDate]) ⇒ <code>string</code>
@@ -324,7 +312,7 @@ Converts a Hebcal event to a classic Hebcal.com JSON API object
324312

325313
<a name="eventToRssItem"></a>
326314

327-
## eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location) ⇒ <code>string</code>
315+
## eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location, mainUrl) ⇒ <code>string</code>
328316
**Kind**: global function
329317

330318
| Param | Type |
@@ -334,6 +322,7 @@ Converts a Hebcal event to a classic Hebcal.com JSON API object
334322
| lastBuildDate | <code>string</code> |
335323
| dayFormat | <code>Intl.DateTimeFormat</code> |
336324
| location | <code>Location</code> |
325+
| mainUrl | <code>string</code> |
337326

338327
<a name="eventToFullCalendar"></a>
339328

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hebcal/rest-api",
3-
"version": "3.3.4",
3+
"version": "3.4.0",
44
"author": "Michael J. Radwin (https://github.com/mjradwin)",
55
"keywords": [
66
"hebcal"
@@ -21,7 +21,7 @@
2121
"url": "https://github.com/hebcal/hebcal-rest-api/issues"
2222
},
2323
"dependencies": {
24-
"@hebcal/core": "^3.15.0",
24+
"@hebcal/core": "^3.17.0",
2525
"@hebcal/geo-sqlite": "^3.4.1",
2626
"@hebcal/leyning": "^4.4.0"
2727
},
@@ -52,20 +52,20 @@
5252
},
5353
"devDependencies": {
5454
"@ava/babel": "^1.0.1",
55-
"@babel/core": "^7.14.0",
56-
"@babel/preset-env": "^7.14.1",
55+
"@babel/core": "^7.14.3",
56+
"@babel/preset-env": "^7.14.2",
5757
"@babel/register": "^7.13.16",
5858
"@rollup/plugin-babel": "^5.3.0",
59-
"@rollup/plugin-commonjs": "^18.1.0",
59+
"@rollup/plugin-commonjs": "^19.0.0",
6060
"@rollup/plugin-json": "^4.1.0",
6161
"@rollup/plugin-node-resolve": "^13.0.0",
6262
"ava": "^3.15.0",
6363
"core-js": "^3.12.1",
6464
"eslint": "^7.26.0",
6565
"eslint-config-google": "^0.14.0",
66-
"jsdoc": "^3.6.6",
66+
"jsdoc": "^3.6.7",
6767
"jsdoc-to-markdown": "^5.0.3",
68-
"rollup": "^2.47.0",
68+
"rollup": "^2.48.0",
6969
"rollup-plugin-terser": "^7.0.2"
7070
}
7171
}

rest-api.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ declare module '@hebcal/rest-api' {
3131
* @param [evPubDate] - if true, use event time as pubDate (false uses lastBuildDate)
3232
*/
3333
export function eventsToRss(events: Event[], location: Location, mainUrl: string, selfUrl: string, lang?: string, evPubDate?: boolean): string;
34-
export function eventToRssItem(ev: Event, evPubDate: boolean, lastBuildDate: string, dayFormat: Intl.DateTimeFormat, location: Location): string;
34+
export function eventToRssItem(ev: Event, evPubDate: boolean, lastBuildDate: string, dayFormat: Intl.DateTimeFormat, location: Location, baseUrl: string): string;
3535
export function getDownloadFilename(options: HebrewCalendar.Options): string;
3636
export function pad2(number: number): string;
3737
export function pad4(number: number): string;

src/classic-rest-api.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
getCalendarTitle,
55
getEventCategories,
66
toISOString,
7+
appendIsraelAndTracking,
78
} from './common';
89
import countryNames from './countryNames.json';
910
import holidayDescription from './holidays.json';
@@ -104,13 +105,7 @@ export function eventToClassicApiObject(ev, options, leyning=true) {
104105
}
105106
const url = ev.url();
106107
if (url) {
107-
if (url.substring(0, 22) == 'https://www.hebcal.com') {
108-
const suffix = options.il ? 'i=on&' : '';
109-
result.link = `${url}?${suffix}utm_source=js&utm_medium=api`;
110-
} else {
111-
const sep = url.indexOf('?') == -1 ? '?' : '&';
112-
result.link = url + sep + 'utm_source=hebcal.com&utm_medium=api';
113-
}
108+
result.link = appendIsraelAndTracking(url, options.il, 'js', 'api');
114109
}
115110
}
116111
const memo = ev.memo || holidayDescription[ev.basename()];

src/common.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,22 @@ export function makeTorahMemoText(ev, il) {
266266
}
267267
return memo;
268268
}
269+
270+
/**
271+
* @private
272+
* @param {string} url
273+
* @param {boolean} il
274+
* @param {string} utmSource
275+
* @param {string} utmMedium
276+
* @return {string}
277+
*/
278+
export function appendIsraelAndTracking(url, il, utmSource, utmMedium) {
279+
if (url.substring(0, 22) !== 'https://www.hebcal.com') {
280+
utmSource = 'hebcal.com';
281+
} else if (il && url.indexOf('?') === -1) {
282+
url += '?i=on';
283+
}
284+
const sep = url.indexOf('?') === -1 ? '?' : '&';
285+
const utm = `utm_source=${utmSource}&utm_medium=${utmMedium}`;
286+
return url + sep + utm;
287+
}

src/fullcalendar.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Locale, flags, Zmanim} from '@hebcal/core';
2-
import {getEventCategories, makeTorahMemoText, toISOString} from './common';
2+
import {getEventCategories, makeTorahMemoText, toISOString,
3+
appendIsraelAndTracking} from './common';
34
import holidayDescription from './holidays.json';
45

56
/**
@@ -35,13 +36,7 @@ export function eventToFullCalendar(ev, tzid, il) {
3536
}
3637
const url = ev.url();
3738
if (url) {
38-
if (url.substring(0, 22) == 'https://www.hebcal.com') {
39-
const suffix = il ? 'i=on&' : '';
40-
result.url = `${url}?${suffix}utm_source=js&utm_medium=fc`;
41-
} else {
42-
const sep = url.indexOf('?') == -1 ? '?' : '&';
43-
result.url = url + sep + 'utm_source=hebcal.com&utm_medium=fc';
44-
}
39+
result.url = appendIsraelAndTracking(url, il, 'js', 'fc');
4540
}
4641
const desc = ev.getDesc();
4742
const candles = desc === 'Havdalah' || desc === 'Candle lighting';

src/rss.js

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,27 @@
1-
import {getEventCategories, makeAnchor} from './common';
1+
import {getEventCategories, makeAnchor, appendIsraelAndTracking} from './common';
22
import {Locale, HebrewCalendar} from '@hebcal/core';
33

4-
const utmParam = 'utm_source=shabbat1c&amp;utm_medium=rss';
5-
64
/**
5+
* @private
76
* @param {Event} ev
87
* @param {boolean} il
8+
* @param {string} mainUrl
99
* @return {string[]}
1010
*/
11-
function getLinkAndGuid(ev, il) {
11+
function getLinkAndGuid(ev, il, mainUrl) {
1212
let link;
1313
let guid;
1414
const dt = ev.eventTime || ev.getDate().greg();
1515
const dtStr0 = dt.toISOString();
1616
const dtStr = encodeURIComponent(dtStr0.substring(0, ev.eventTime ? 19 : 10));
1717
const url0 = ev.url();
18-
const url = url0 && il ? url0 + '?i=on' : url0;
19-
if (url) {
20-
const question = url.indexOf('?');
21-
if (question == -1) {
22-
link = url + '?' + utmParam;
23-
} else {
24-
link = url + '&amp;' + utmParam;
25-
}
18+
const url = appendIsraelAndTracking(url0 || mainUrl, il, 'shabbat1c', 'rss').replace(/&/g, '&amp;');
19+
if (url0) {
20+
link = url;
2621
guid = link + '&amp;dt=' + dtStr;
2722
} else {
2823
const anchor = makeAnchor(ev.getDesc());
29-
guid = link = 'https://www.hebcal.com/shabbat?' + utmParam + '&amp;dt=' + dtStr + '#' + anchor;
24+
guid = link = url + '&amp;dt=' + dtStr + '#' + anchor;
3025
}
3126
return [link, guid];
3227
}
@@ -51,21 +46,21 @@ export function eventsToRss(events, location, mainUrl, selfUrl, lang='en-US', ev
5146
month: 'long',
5247
year: 'numeric',
5348
});
54-
mainUrl = mainUrl.replace(/&/g, '&amp;');
49+
const mainUrlEsc = appendIsraelAndTracking(mainUrl, location.getIsrael(), 'shabbat1c', 'rss').replace(/&/g, '&amp;');
5550
selfUrl = selfUrl.replace(/&/g, '&amp;');
5651
let str = `<?xml version="1.0" encoding="UTF-8"?>
5752
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:atom="http://www.w3.org/2005/Atom">
5853
<channel>
5954
<title>${title}</title>
60-
<link>${mainUrl}&amp;${utmParam}</link>
55+
<link>${mainUrlEsc}</link>
6156
<atom:link href="${selfUrl}" rel="self" type="application/rss+xml" />
6257
<description>Weekly Shabbat candle lighting times for ${cityDescr}</description>
6358
<language>${lang}</language>
6459
<copyright>Copyright (c) ${thisYear} Michael J. Radwin. All rights reserved.</copyright>
6560
<lastBuildDate>${lastBuildDate}</lastBuildDate>
6661
`;
6762
events.forEach((ev) => {
68-
str += eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location);
63+
str += eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location, mainUrl);
6964
});
7065
str += '</channel>\n</rss>\n';
7166
return str;
@@ -96,13 +91,14 @@ function getPubDate(ev, evPubDate, evDate, lastBuildDate) {
9691
* @param {string} lastBuildDate
9792
* @param {Intl.DateTimeFormat} dayFormat
9893
* @param {Location} location
94+
* @param {string} mainUrl
9995
* @return {string}
10096
*/
101-
export function eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location) {
97+
export function eventToRssItem(ev, evPubDate, lastBuildDate, dayFormat, location, mainUrl) {
10298
let subj = ev.render();
10399
const evDate = ev.getDate().greg();
104100
const pubDate = getPubDate(ev, evPubDate, evDate, lastBuildDate);
105-
const linkGuid = getLinkAndGuid(ev, location.getIsrael());
101+
const linkGuid = getLinkAndGuid(ev, location.getIsrael(), mainUrl);
106102
const link = linkGuid[0];
107103
const guid = linkGuid[1];
108104
const description = dayFormat.format(evDate);

src/rss.spec.js

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ import test from 'ava';
33
import {HebrewCalendar, Location} from '@hebcal/core';
44
import {eventsToRss, eventToRssItem} from './rss';
55

6+
const dayFormat = new Intl.DateTimeFormat('en-US', {
7+
weekday: 'long',
8+
day: '2-digit',
9+
month: 'long',
10+
year: 'numeric',
11+
});
12+
613
test('eventsToRss', (t) => {
714
const location = new Location(41.85003, -87.65005, false, 'America/Chicago', 'Chicago', 'US', 4887398);
815
const options = {
@@ -41,19 +48,14 @@ test('eventToRssItem', (t) => {
4148
location: location,
4249
};
4350
const events = HebrewCalendar.calendar(options).slice(0, 3);
44-
const dayFormat = new Intl.DateTimeFormat('en-US', {
45-
weekday: 'long',
46-
day: '2-digit',
47-
month: 'long',
48-
year: 'numeric',
49-
});
5051
const lastBuildDate = 'Mon, 22 Jun 2020 20:03:18 GMT';
51-
const items = events.map((ev) => eventToRssItem(ev, true, lastBuildDate, dayFormat, location));
52+
const mainUrl = 'https://www.hebcal.com/shabbat?city=Eilat';
53+
const items = events.map((ev) => eventToRssItem(ev, true, lastBuildDate, dayFormat, location, mainUrl));
5254
const expected = [
5355
'<item>\n' +
5456
'<title>Candle lighting: 18:43</title>\n' +
55-
'<link>https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-06T15%3A43%3A00#candle-lighting</link>\n' +
56-
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-06T15%3A43%3A00#candle-lighting</guid>\n' +
57+
'<link>https://www.hebcal.com/shabbat?city=Eilat&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-06T15%3A43%3A00#candle-lighting</link>\n' +
58+
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?city=Eilat&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-06T15%3A43%3A00#candle-lighting</guid>\n' +
5759
'<description>Friday, April 06, 1990</description>\n' +
5860
'<category>candles</category>\n' +
5961
'<pubDate>Fri, 06 Apr 1990 15:43:00 GMT</pubDate>\n' +
@@ -62,8 +64,8 @@ test('eventToRssItem', (t) => {
6264
'</item>\n',
6365
'<item>\n' +
6466
'<title>Havdalah (50 min): 19:52</title>\n' +
65-
'<link>https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-07T16%3A52%3A00#havdalah</link>\n' +
66-
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-07T16%3A52%3A00#havdalah</guid>\n' +
67+
'<link>https://www.hebcal.com/shabbat?city=Eilat&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-07T16%3A52%3A00#havdalah</link>\n' +
68+
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?city=Eilat&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=1990-04-07T16%3A52%3A00#havdalah</guid>\n' +
6769
'<description>Saturday, April 07, 1990</description>\n' +
6870
'<category>havdalah</category>\n' +
6971
'<pubDate>Sat, 07 Apr 1990 16:52:00 GMT</pubDate>\n' +
@@ -86,14 +88,8 @@ test('parsha', (t) => {
8688
end: new Date(2020, 10, 28),
8789
sedrot: true,
8890
});
89-
const dayFormat = new Intl.DateTimeFormat('en-US', {
90-
weekday: 'long',
91-
day: '2-digit',
92-
month: 'long',
93-
year: 'numeric',
94-
});
9591
const location = Location.lookup('Kiev');
96-
const item = eventToRssItem(events[0], true, '', dayFormat, location);
92+
const item = eventToRssItem(events[0], true, '', dayFormat, location, '');
9793
const expected = '<item>\n' +
9894
'<title>Parashat Vayetzei</title>\n' +
9995
'<link>https://www.hebcal.com/sedrot/vayetzei-20201128?utm_source=shabbat1c&amp;utm_medium=rss</link>\n' +
@@ -105,6 +101,25 @@ test('parsha', (t) => {
105101
t.is(item, expected);
106102
});
107103

104+
test('parsha-il', (t) => {
105+
const events = HebrewCalendar.calendar({
106+
start: new Date(2020, 10, 28),
107+
end: new Date(2020, 10, 28),
108+
sedrot: true,
109+
});
110+
const location = Location.lookup('Jerusalem');
111+
const item = eventToRssItem(events[0], true, '', dayFormat, location, '');
112+
const expected = '<item>\n' +
113+
'<title>Parashat Vayetzei</title>\n' +
114+
'<link>https://www.hebcal.com/sedrot/vayetzei-20201128?i=on&amp;utm_source=shabbat1c&amp;utm_medium=rss</link>\n' +
115+
'<guid isPermaLink="false">https://www.hebcal.com/sedrot/vayetzei-20201128?i=on&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2020-11-28</guid>\n' +
116+
'<description>Saturday, November 28, 2020</description>\n' +
117+
'<category>parashat</category>\n' +
118+
'<pubDate>Sat, 28 Nov 2020 00:00:00 GMT</pubDate>\n' +
119+
'</item>\n';
120+
t.is(item, expected);
121+
});
122+
108123
test('fastStartEnd', (t) => {
109124
const location = Location.lookup('Tel Aviv');
110125
const options = {
@@ -115,19 +130,14 @@ test('fastStartEnd', (t) => {
115130
candlelighting: true,
116131
};
117132
const events = HebrewCalendar.calendar(options);
118-
const dayFormat = new Intl.DateTimeFormat('en-US', {
119-
weekday: 'long',
120-
day: '2-digit',
121-
month: 'long',
122-
year: 'numeric',
123-
});
124133
const lastBuildDate = 'Mon, 22 Jun 2020 20:03:18 GMT';
125-
const items = events.map((ev) => eventToRssItem(ev, true, lastBuildDate, dayFormat, location));
134+
const mainUrl = 'https://www.hebcal.com/shabbat?city=Tel+Aviv';
135+
const items = events.map((ev) => eventToRssItem(ev, true, lastBuildDate, dayFormat, location, mainUrl));
126136
const expected = [
127137
'<item>\n' +
128138
'<title>Fast begins: 04:09</title>\n' +
129-
'<link>https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T01%3A09%3A00#fast-begins</link>\n' +
130-
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T01%3A09%3A00#fast-begins</guid>\n' +
139+
'<link>https://www.hebcal.com/shabbat?city=Tel+Aviv&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T01%3A09%3A00#fast-begins</link>\n' +
140+
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?city=Tel+Aviv&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T01%3A09%3A00#fast-begins</guid>\n' +
131141
'<description>Sunday, June 27, 2021</description>\n' +
132142
'<category>zmanim</category>\n' +
133143
'<pubDate>Sun, 27 Jun 2021 01:09:00 GMT</pubDate>\n' +
@@ -142,8 +152,8 @@ test('fastStartEnd', (t) => {
142152
'</item>\n',
143153
'<item>\n' +
144154
'<title>Fast ends: 20:25</title>\n' +
145-
'<link>https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T17%3A25%3A00#fast-ends</link>\n' +
146-
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T17%3A25%3A00#fast-ends</guid>\n' +
155+
'<link>https://www.hebcal.com/shabbat?city=Tel+Aviv&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T17%3A25%3A00#fast-ends</link>\n' +
156+
'<guid isPermaLink="false">https://www.hebcal.com/shabbat?city=Tel+Aviv&amp;utm_source=shabbat1c&amp;utm_medium=rss&amp;dt=2021-06-27T17%3A25%3A00#fast-ends</guid>\n' +
147157
'<description>Sunday, June 27, 2021</description>\n' +
148158
'<category>zmanim</category>\n' +
149159
'<pubDate>Sun, 27 Jun 2021 17:25:00 GMT</pubDate>\n' +

0 commit comments

Comments
 (0)