Skip to content

Instantly share code, notes, and snippets.

@archipoeta
Created July 22, 2015 03:48
Show Gist options
  • Save archipoeta/599c1c6caa544d5fcd9f to your computer and use it in GitHub Desktop.
Save archipoeta/599c1c6caa544d5fcd9f to your computer and use it in GitHub Desktop.
PHPBB Forum Topic to Google Calendar Event Parser
<?php
// by Archpoet
set_include_path(get_include_path() . PATH_SEPARATOR . './google-api-php-client/src');
require 'google-api-php-client/src/Google/autoload.php';
define('APPLICATION_NAME', 'Torch Events Parser');
define('CREDENTIALS_PATH', '~/.credentials/torch-events.json');
define('CLIENT_SECRET_PATH', '../client_secret_961515209467.json');
define('SCOPES', implode(' ', array(
Google_Service_Calendar::CALENDAR
)));
define('IN_PHPBB', false);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './forum/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup('viewforum');
$events = array();
$existing_events = array();
$search_limit = 5;
$threshold = 1; # CRON: minutes
$event_label = "/# EVENT:/";
$forum_id = array(7);
$forum_id_where = create_where_clauses($forum_id, 'forum');
$topic_id = array(20, 50);
$topic_id_where = create_where_clauses($topic_id, 'topic');
$posts_ary = array(
'SELECT' => 'p.*, t.*',
'FROM' => array(
POSTS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(TOPICS_TABLE => 't'),
'ON' => 't.topic_first_post_id = p.post_id'
)
),
'WHERE' => str_replace( array('WHERE ', 'forum_id'), array('', 't.forum_id'), $forum_id_where ) .
'AND t.topic_status <> ' . ITEM_MOVED . ' AND t.topic_visibility = 1',
'ORDER_BY' => 'p.post_id DESC',
);
$posts = $db->sql_build_query('SELECT', $posts_ary);
$posts_result = $db->sql_query_limit($posts, $search_limit);
while( $posts_row = $db->sql_fetchrow($posts_result) ) {
$topic_title = $posts_row['topic_title'];
$topic_author = get_username_string('full', $posts_row['topic_poster'], $posts_row['topic_first_poster_name'], $posts_row['topic_first_poster_colour']);
$topic_date = $user->format_date($posts_row['topic_time']);
$topic_link = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $posts_row['forum_id'] . '&amp;t=' . $posts_row['topic_id']);
# TODO: flip to > for production
if ( (time()-($threshold*60)) < $posts_row['topic_time']) {
continue;
}
$post_title = censor_text($topic_title);
if ( preg_match( $event_label, $post_title ) ) {
$this_event = array();
$post_text = nl2br($posts_row['post_text']);
$bbcode = new bbcode(base64_encode($bbcode_bitfield));
$bbcode->bbcode_second_pass($post_text, $posts_row['bbcode_uid'], $posts_row['bbcode_bitfield']);
$post_text = smiley_text($post_text);
$post_text = censor_text($post_text);
$lines = explode( "\n", $post_text );
foreach ( $lines as $line ) {
$array = preg_split( "/: /", $line, 2 );
$data = rtrim($array[1], "<br />");
switch ( $array[0] ) {
case "SUMMARY":
$this_event['summary'] = $data;
break;
case "LOCATION":
$this_event['location'] = $data;
break;
case "DESCRIPTION":
$this_event['description'] = $data . "\n\n" . "http://torch.republicalliance.net/$topic_link";
break;
case "EVENT_START":
$date = explode( ' ', $data );
$this_event['start']['dateTime'] = $date[0] . "T" . $date[1] . "-0700";
$this_event['start']['timeZone'] = 'America/Los_Angeles';
break;
case "EVENT_END":
$date = explode( ' ', $data );
$this_event['end']['dateTime'] = $date[0] . "T" . $date[1] . "-0700";
$this_event['end']['timeZone'] = 'America/Los_Angeles';
break;
case "RECURRING":
$this_event['recurrence'][] = $data;
break;
}
}
$events[] = $this_event;
}
}
if (php_sapi_name() == "cli") {
///// CAL API /////
// Instantiate the google client
$client = get_gclient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = '[email protected]';
/*$optParams = array(
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);*/
$results = $service->events->listEvents($calendarId);
if (count($results->getItems()) > 0) {
foreach ($results->getItems() as $event) {
//printf("%s %s\n", $event->id, $event->getSummary());
$existing_events[] = $event->getSummary();
}
}
foreach ( $events as $e ) {
if ( ! in_array( $e['summary'], $existing_events ) ) {
$event = new Google_Service_Calendar_Event( $e );
$event = $service->events->insert($calendarId, $event);
printf('Event created: %s\n', $event->htmlLink);
}
}
}
//
// Functions
//
function create_where_clauses($gen_id, $type)
{
global $db, $auth;
$size_gen_id = sizeof($gen_id);
switch($type)
{
case 'forum':
$type = 'forum_id';
break;
case 'topic':
$type = 'topic_id';
break;
default:
trigger_error('No type defined');
}
// Set $out_where to nothing, this will be used of the gen_id
// size is empty, in other words "grab from anywhere" with
// no restrictions
$out_where = '';
if( $size_gen_id > 0 )
{
// Get a list of all forums the user has permissions to read
$auth_f_read = array_keys($auth->acl_getf('f_read', true));
if( $type == 'topic_id' )
{
$sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $gen_id) . '
AND ' . $db->sql_in_set('forum_id', $auth_f_read);
$result = $db->sql_query($sql);
while( $row = $db->sql_fetchrow($result) )
{
// Create an array with all acceptable topic ids
$topic_id_list[] = $row['topic_id'];
}
unset($gen_id);
$gen_id = $topic_id_list;
$size_gen_id = sizeof($gen_id);
}
$j = 0;
for( $i = 0; $i < $size_gen_id; $i++ )
{
$id_check = (int) $gen_id[$i];
// If the type is topic, all checks have been made and the query can start to be built
if( $type == 'topic_id' )
{
$out_where .= ($j == 0) ? 'WHERE ' . $type . ' = ' . $id_check . ' ' : 'OR ' . $type . ' = ' . $id_check . ' ';
}
// If the type is forum, do the check to make sure the user has read permissions
else if( $type == 'forum_id' && $auth->acl_get('f_read', $id_check) )
{
$out_where .= ($j == 0) ? 'WHERE ' . $type . ' = ' . $id_check . ' ' : 'OR ' . $type . ' = ' . $id_check . ' ';
}
$j++;
}
}
if( $out_where == '' && $size_gen_id > 0 )
{
trigger_error('A list of topics/forums has not been created');
}
return $out_where;
}
/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function get_gclient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfigFile(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = file_get_contents($credentialsPath);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->authenticate($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, $accessToken);
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->refreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, $client->getAccessToken());
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* @param string $path the path to expand.
* @return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv("HOMEDRIVE") . getenv("HOMEPATH");
}
return str_replace('~', realpath($homeDirectory), $path);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment