Skip to content

Commit 41b686c

Browse files
feat: rebuild homepage meetup feed with public ical feed
Meetup deprecated all their public APIs :-(
1 parent 2308e43 commit 41b686c

File tree

6 files changed

+126
-18
lines changed

6 files changed

+126
-18
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[holomapping]
2+
root = "src"
3+
files = "*.php"

.holo/sources/icalparser.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[holosource]
2+
url = "https://github.com/OzzyCzech/icalparser.git"
3+
ref = "refs/heads/master"

html-templates/subtemplates/meetups.tpl

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
11
{template meetup event headingLevel=h3 showRsvp=true}
2-
{$endTime = $event.time + $event.duration}
32
<article class="event card">
43
<div class="card-body">
5-
<{$headingLevel} class="event-title">{$event.name}</{$headingLevel}>
4+
<{$headingLevel} class="event-title">{$event.title|escape}</{$headingLevel}>
65

76
<p class="event-meta">
8-
<time datetime="{$event.time/1000|date_format:'%Y-%m-%dT%G:%M'}">{$event.time/1000|date_format:"%A, %b %e <br> %l:%M%P"}</time>–<time datetime="{$endTime.time/1000|date_format:'%Y-%m-%dT%G:%M'}">{$endTime/1000|date_format:"%l:%M%P"}</time>
9-
&#32;@&nbsp;<a href="http://maps.google.com/?q={$event.venue.address_1},%20{$event.venue.zip}">{$event.venue.name}</a>
7+
{strip}
8+
<time datetime="{$event.time_start->getTimestamp()|date_format:'%Y-%m-%dT%G:%M'}">
9+
{$event.time_start->getTimestamp()|date_format:"%A, %b %e <br> %l:%M%P"}
10+
</time>
11+
12+
<time datetime="{$event.time_end->getTimestamp()|date_format:'%Y-%m-%dT%G:%M'}">
13+
{$event.time_end->getTimestamp()|date_format:"%l:%M%P"}
14+
</time>
15+
&#32;@&nbsp;
16+
<a target="_blank" href="http://maps.google.com/?q={$event.location.name|escape:url},{$event.location.address|escape:url}">
17+
{$event.location.name|default:$event.location.address|escape}
18+
</a>
19+
{/strip}
1020
</p>
1121

1222
{if $showRsvp}
13-
<p><a href="{$event.event_url}">{sprintf(_("RSVP @ %s"), parse_url($event.event_url, $.const.PHP_URL_HOST))}</a> {if $event.yes_rsvp_count}({_("%s so far")|sprintf:$event.yes_rsvp_count}){/if}</p>
23+
<p>
24+
<a href="{$event.url|escape}">
25+
{sprintf(_("RSVP @ %s"), parse_url($event.url, $.const.PHP_URL_HOST))}
26+
</a>
27+
{if $event.yes_rsvp_count}
28+
{* not currently available in the data :'( *}
29+
({_("%s so far")|sprintf:$event.yes_rsvp_count})
30+
{/if}
31+
</p>
1432
{/if}
1533
</div>
1634
</article>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace Emergence\Meetup;
4+
5+
use Cache;
6+
use om\IcalParser;
7+
8+
class Connector extends \Emergence\Connectors\AbstractConnector
9+
{
10+
public static $groupSlug;
11+
public static $feedCacheTime = 60;
12+
13+
public static function getUpcomingEvents()
14+
{
15+
$groupSlug = static::$groupSlug;
16+
if (!$groupSlug) {
17+
return [];
18+
}
19+
20+
$cacheKey = "meetup/{$groupSlug}/events";
21+
$events = Cache::fetch($cacheKey);
22+
23+
if ($events === null) {
24+
// cached failure
25+
throw new Exception('meetup feed unavailable');
26+
} elseif ($events === false) {
27+
$cal = new IcalParser();
28+
$cal->parseFile("https://www.meetup.com/{$groupSlug}/events/ical/");
29+
30+
$events = [];
31+
foreach ($cal->getSortedEvents() as $event) {
32+
$matches = null;
33+
$events[] = [
34+
'id' => preg_match('/^event_(?P<id>\d+)@meetup\\.com$/', $event['UID'], $matches)
35+
? $matches['id']
36+
: $event['UID'],
37+
'url' => $event['URL'],
38+
'title' => $event['SUMMARY'],
39+
'description' => $event['DESCRIPTION'],
40+
'location' => preg_match('/^(?P<name>.+) \((?P<address>.+)\)$/', $event['LOCATION'], $matches)
41+
? [ 'name' => $matches['name'], 'address' => $matches['address'] ]
42+
: [ 'name' => '', 'address' => $event['LOCATION'] ],
43+
'time_start' => $event['DTSTART'],
44+
'time_end' => $event['DTEND'],
45+
'ical' => $event
46+
];
47+
}
48+
49+
Cache::store($cacheKey, $events, static::$feedCacheTime);
50+
}
51+
52+
return $events;
53+
}
54+
55+
public static function getUpcomingEvents_Atom()
56+
{
57+
$groupSlug = static::$groupSlug;
58+
if (!$groupSlug) {
59+
return [];
60+
}
61+
62+
$xml = simplexml_load_file("https://www.meetup.com/{$groupSlug}/events/atom/");
63+
64+
$events = [];
65+
66+
foreach ($xml->entry as $event) {
67+
$events[] = [
68+
'id' => (string)$event->id,
69+
'name' => (string)$event->title,
70+
'description' => (string)$event->content,
71+
'url' => (string)$event->link['href']
72+
];
73+
}
74+
75+
return $events;
76+
}
77+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
/**
4+
* The name of your Meetup group as formatted in the URL
5+
*
6+
* The example value is for https://meetup.com/Code-for-Philly
7+
*/
8+
9+
// Emergence\Meetup\Connector::$groupSlug = 'Code-for-Philly';

site-root/home.php

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
<?php
22

33
// compile home page data
4-
$now = time() * 1000;
4+
$now = new DateTime();
55
$pageData = array();
66

77

88
// meetups
99
try {
10-
$meetups = RemoteSystems\Meetup::getEvents();
11-
10+
$meetups = Emergence\Meetup\Connector::getUpcomingEvents();
1211
$nextMeetup = array_shift($meetups);
13-
12+
1413
// detect if meetup is happening right now
15-
if($nextMeetup && $nextMeetup['time'] < $now) {
14+
// - use ?next_meetup_now=1 to test feature before any event
15+
if(
16+
($nextMeetup && $nextMeetup['time_start'] < $now)
17+
|| !empty($_GET['next_meetup_now'])
18+
) {
1619
$currentMeetup = $nextMeetup;
1720
$nextMeetup = array_shift($meetups);
1821
}
19-
20-
// TODO: delete this!
21-
elseif(!empty($_GET['force_current'])) {
22-
$currentMeetup = $nextMeetup;
23-
}
24-
22+
2523
if($currentMeetup) {
2624
$currentMeetup['checkins'] = Laddr\MemberCheckin::getAllForMeetupByProject($currentMeetup['id']);
2725
}
28-
26+
2927
$pageData['currentMeetup'] = $currentMeetup;
3028
$pageData['nextMeetup'] = $nextMeetup;
3129
$pageData['futureMeetups'] = $meetups;
@@ -38,7 +36,7 @@
3836
if (!$pageData['activity'] = Cache::fetch('home-activity')) {
3937
$existingTables = \DB::allValues('table_name', 'SELECT table_name FROM information_schema.TABLES WHERE TABLE_SCHEMA = SCHEMA()');
4038
$activityQueries = [];
41-
39+
4240
if (in_array(Emergence\CMS\AbstractContent::$tableName, $existingTables)) {
4341
$activityQueries[] = sprintf(
4442
'SELECT'

0 commit comments

Comments
 (0)