Page MenuHomeDevCentral

No OneTemporary

diff --git a/finger/ThimblDocument.php b/finger/ThimblDocument.php
index 0c11c7c..de068b7 100644
--- a/finger/ThimblDocument.php
+++ b/finger/ThimblDocument.php
@@ -1,210 +1,212 @@
<?php
/**
* Thimbl document
*/
class ThimblDocument {
/**
* The Thimbl raw deserialized .plan data
* @var Object
*/
private $data;
/**
* Initializes a new instance of the ThimblDocument object
*
* @param Object $data An object matching a deserialized json Thimbl plan file
*/
public function __construct ($data) {
$this->data = $data;
}
/**
* Cleans a string, for JSON decode error
*
* @param string &$string The string to clean
*/
private static function ApplyCleanKludge (&$string) {
$string = clean_string($string);
//Issue for nknouf@zeitkunst.org
$wrongText = <<<'END'
âM-^Y» @zeminlu: UNIX' Russian Roulette: sudo [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo âM-^@M-^\You liveâM-^@M-^]
END;
$rightText = "@zeminlu: UNIX' Russian Roulette: sudo [ \$[ \$RANDOM % 6 ] == 0 ] && rm -rf / || echo";
//$rightText = "x";
$string = str_replace(trim($wrongText), $rightText, $string);
}
/**
* Gets a new instance of the ThimblDocument object from a JSON string
+ *
+ * @return ThimblDocument|null
*/
public static function FromJSON ($string) {
self::ApplyCleanKludge($string);
$data = json_decode($string);
return is_object($data) ? new ThimblDocument($data) : null;
}
/**
* Gets the finger address
*
* @return string The finger address
*/
public function GetAddress () {
return $this->data->address;
}
/**
* Gets the name
*
* @return string The name
*/
public function GetName () {
return $this->data->name;
}
/**
* Gets the properties
*
* @return Array An array with the properties
*/
public function GetProperties () {
return (array)$this->data->properties;
}
/**
* Gets the specified property
*
* @param string $property The property
* @return string The property value
*/
public function GetProperty ($property) {
$properties = $this->GetProperties();
if (array_key_exists($property, $properties)) {
return $properties[$property];
}
return null;
}
/**
* Gets the messages
*
* @return Array An array with the messages
*/
public function GetMessages () {
$messages = array();
foreach ($this->data->messages as $message) {
$messages[] = (array)$message;
}
return array_reverse($messages);
}
/**
* Gets the people the current user follows
*
* @param int $avatarSize The avatar width
* @param string $avatarFallbackStyle The avatar fallback Gravatar style ('mm', 'blank', '404', 'identicon', 'wavatar', 'retro')
* @return Array An array with the followed people
*/
public function GetFollowing ($avatarSize = 80, $avatarFallbackStyle = 'mm') {
$following = array();
foreach ($this->data->following as $contact) {
$following[] = [
'nick' => $contact->nick,
'address' => $contact->address,
'avatar' => self::GetGravatar($contact->address, $avatarSize, $avatarFallbackStyle)
];
}
return $following;
}
/**
* Gets the gravatar
*
* @param string $email The e-mail address
* @param int $size The avatar width
* @param string $fallbackStyle The avatar fallback Gravatar style ('mm', 'blank', '404', 'identicon', 'wavatar', 'retro')
* @return string The Gravatar URL, or if not available a fallback representation
*/
private static function GetGravatar ($email, $size = 200, $fallbackStyle = 'mm') {
$hash = md5(strtolower(trim($email)));
return "//www.gravatar.com/avatar/$hash?s=$size&d=$fallbackStyle";
}
/**
* Gets the avatar
*
* @param int $size The avatar width
* @param string $fallbackStyle The avatar fallback Gravatar style ('mm', 'blank', '404', 'identicon', 'wavatar', 'retro')
* @return string The Gravatar URL, or if not available a fallback representation
*/
public function GetAvatar ($size = 200, $fallbackStyle = 'mm') {
return self::GetGravatar($this->data->properties->email, $size, $fallbackStyle);
}
/**
* Gets the unixtime from a Thimbl time
*
* @param long $time The date, in a Thimbl time representation
* @return int The date, in a unixtime representation
*/
public static function ThimblTimeToUnixtime ($time) {
return strtotime($time);
}
/**
* Formats a message
*
* @param string $message The message to format
* @return string The formatted message
*/
public function FormatMessage ($message) {
$message = preg_replace(
"/(?<!a href=\")(?<!src=\")((http|ftp)+(s)?:\/\/[^<>\s]+)/i",
"<a href=\"\\0\">\\0</a>",
$message
);
return $message;
}
}
/*
Here a minimal representation of a deserialized Thimbl .plan file:
stdClass Object
(
[messages] => Array
(
[0] => stdClass Object
(
[text] => A message
[time] => 20130917204527
)
)
[replies] => stdClass Object
(
)
[address] => user@domain.tld
[following] => Array
(
[0] => stdClass Object
(
[nick] => dk
[address] => dk@telekommunisten.org
)
)
[name] => user
[properties] => stdClass Object
(
[website] => http://www.domain.tld
[email] => user@domain.tld
[mobile] => Mobile withheld
)
)
*/
diff --git a/finger/thimbl.php b/finger/thimbl.php
index 4088c34..56b05b2 100644
--- a/finger/thimbl.php
+++ b/finger/thimbl.php
@@ -1,47 +1,145 @@
<?php
-if (array_key_exists('user', $_REQUEST)) {
- require_once('FingerClient.php');
- $client = FingerClient::fromAddress($_REQUEST['user']);
- $blackListFile = 'finger/blacklist.txt';
- if (file_exists($blackListFile)) {
- $client->AddToBlacklist(explode("\n", file_get_contents($blackListFile)));
+/**
+ * Represents a controller to process the Thimbl client request
+ */
+class ThimblController {
+ ///
+ /// Constants
+ ///
+
+ /**
+ * The path to the server to not finger
+ *
+ * @const
+ */
+ const BLACKLIST_FILE = 'finger/blacklist.txt';
+
+ ///
+ /// Private properties
+ ///
+
+ /**
+ * Thimbl document from a plan file
+ *
+ * @var ThimblDocument|null
+ */
+ private $thimblDocument = null;
+
+ /**
+ * A finger client instance used to fetch the plan file containing the Thimbl feed
+ *
+ * @var FingerClient
+ */
+ private $client;
+
+ /**
+ * Errors occured during request processing
+ *
+ * @var array
+ */
+ private $errors = [];
+
+ /**
+ * Runs the controller logic
+ */
+ public function run () {
+ if (array_key_exists('user', $_REQUEST)) {
+ $this->processThimblClientRequest();
+ }
+
+ if (count($this->errors)) {
+ $this->printErrors();
+ }
+
+ $this->printInputForm();
+
+ if ($this->thimblDocument !== null) {
+ $this->printThimblFeed();
+ }
}
- if ($client == null) {
- echo '<div class="alert-box alert">Invalid Finger address format.</div>';
- } elseif (!$client->Run()) {
- echo '<div class="alert-box alert">', $client->lastError, '</div>';
- } else {
- $client->Parse();
- if (!$planField = $client->Get('Plan')) {
- echo '<div class="alert-box alert">Finger connection successful, but there is no plan file.</div>';
- } else {
- require_once('ThimblDocument.php');
- if (!$plan = ThimblDocument::FromJSON($planField)) {
- echo '<div class="alert-box alert">Finger connection successful, but the plan file format is not a Thimbl one.<br />';
- echo 'JSON error returned by the parser: ', json_last_error_msg();
- echo '</div>';
- echo "<h2>Plan file for $_REQUEST[user]</h2>";
- echo '<pre>', clean_string($planField), '</pre>';
- }
+
+ /**
+ * Processes Thimbl client request
+ */
+ public function processThimblClientRequest() {
+ require_once('FingerClient.php');
+
+ $this->client = FingerClient::fromAddress($_REQUEST['user']);
+ if ($this->client === null) {
+ $this->errors[] = 'Invalid Finger address format.';
+ return;
+ }
+
+ $this->handleBlackList();
+
+ if (!$this->client->Run()) {
+ $this->errors[] = $this->client->lastError;
+ return;
+ }
+
+ $this->client->Parse();
+ if (!$planField = $this->client->Get('Plan')) {
+ $this->errors[] = 'Finger connection successful, but there is no plan file.';
+ return;
+ }
+
+ require_once('ThimblDocument.php');
+ if (!$this->thimblDocument = ThimblDocument::FromJSON($planField)) {
+ $this->printDebugPlanMessage($planField);
}
}
+
+ /**
+ * Prints debug .plan message
+ *
+ * @param string $planField
+ */
+ private function printDebugPlanMessage ($planField) {
+ echo '<div class="alert-box alert">Finger connection successful, but the plan file format is not a Thimbl one.<br />';
+ echo 'JSON error returned by the parser: ', json_last_error_msg();
+ echo '</div>';
+ echo "<h2>Plan file for $_REQUEST[user]</h2>";
+ echo '<pre>', clean_string($planField), '</pre>';
+ }
+
+ /**
+ * Handles blacklist
+ */
+ private function handleBlackList () {
+ if (file_exists(self::BLACKLIST_FILE)) {
+ $blackListedServers = explode(
+ "\n",
+ trim(
+ file_get_contents(self::BLACKLIST_FILE)
+ )
+ );
+ $this->client->AddToBlacklist($blackListedServers);
+ }
+ }
+
+ /**
+ * Prints errors
+ */
+ public function printErrors () {
+ foreach ($this->errors as $error) {
+ echo '<div class="alert-box alert">', $error, '</div>';
+ }
+ }
+
+ /**
+ * Prints input form
+ */
+ public function printInputForm () {
+ include('thimbl_inputForm.html');
+ }
+
+ public function printThimblFeed () {
+ $plan = $this->thimblDocument;
+
+ echo "<h2>Thimbl feed for $_REQUEST[user]</h2>";
+ require_once('thimbl_feed.php');
+ }
}
-?>
-<h2>Who?</h2>
-<form>
-<div class="row collapse">
- <div class="ten mobile-three columns">
- <input type="text" name="user" id="user" value="<?= $_REQUEST['user'] ?>" placeholder="username@server" />
- </div>
- <div class="two mobile-one columns">
- <input type="submit" class="button expand postfix" value="Finger" />
- </div>
-</div>
-</form>
-<?php
-if ($plan) {
- echo "<h2>Thimbl feed for $_REQUEST[user]</h2>";
- require_once('thimbl_feed.php');
-}
-?>
+
+(new ThimblController())->run();
diff --git a/finger/thimbl_inputForm.html b/finger/thimbl_inputForm.html
new file mode 100644
index 0000000..fecd169
--- /dev/null
+++ b/finger/thimbl_inputForm.html
@@ -0,0 +1,11 @@
+<h2>Who?</h2>
+<form>
+<div class="row collapse">
+ <div class="ten mobile-three columns">
+ <input type="text" name="user" id="user" value="<?= $_REQUEST['user'] ?>" placeholder="username@server" />
+ </div>
+ <div class="two mobile-one columns">
+ <input type="submit" class="button expand postfix" value="Finger" />
+ </div>
+</div>
+</form>

File Metadata

Mime Type
text/x-diff
Expires
Mon, Sep 15, 03:56 (1 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2978092
Default Alt Text
(12 KB)

Event Timeline