mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 10:12:41 +01:00
Bring macros to IRC
Summary: Adds a macro handler that spams your channel with macros. Config is: - macro.size: scale macros to this size before rasterizing - macro.sleep: sleep this many seconds between lines (evade flood protection) Test Plan: derpderp Reviewers: kdeggelman, btrahan Reviewed By: btrahan CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D1838
This commit is contained in:
parent
226d0321af
commit
6712dbb709
8 changed files with 346 additions and 1 deletions
|
@ -10,12 +10,17 @@
|
||||||
"PhabricatorIRCObjectNameHandler",
|
"PhabricatorIRCObjectNameHandler",
|
||||||
"PhabricatorIRCLogHandler",
|
"PhabricatorIRCLogHandler",
|
||||||
"PhabricatorIRCWhatsNewHandler",
|
"PhabricatorIRCWhatsNewHandler",
|
||||||
"PhabricatorIRCDifferentialNotificationHandler"
|
"PhabricatorIRCDifferentialNotificationHandler",
|
||||||
|
"PhabricatorIRCMacroHandler"
|
||||||
],
|
],
|
||||||
|
|
||||||
"conduit.uri" : null,
|
"conduit.uri" : null,
|
||||||
"conduit.user" : null,
|
"conduit.user" : null,
|
||||||
"conduit.cert" : null,
|
"conduit.cert" : null,
|
||||||
|
|
||||||
|
"macro.size" : 48,
|
||||||
|
"macro.sleep" : 0.25,
|
||||||
|
"macro.aspect" : 0.66,
|
||||||
|
|
||||||
"notification.channels" : ["#phabot-test"]
|
"notification.channels" : ["#phabot-test"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,8 @@ phutil_register_library_map(array(
|
||||||
'ConduitAPI_file_download_Method' => 'applications/conduit/method/file/download',
|
'ConduitAPI_file_download_Method' => 'applications/conduit/method/file/download',
|
||||||
'ConduitAPI_file_info_Method' => 'applications/conduit/method/file/info',
|
'ConduitAPI_file_info_Method' => 'applications/conduit/method/file/info',
|
||||||
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
|
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
|
||||||
|
'ConduitAPI_macro_Method' => 'applications/conduit/method/macro/base',
|
||||||
|
'ConduitAPI_macro_query_Method' => 'applications/conduit/method/macro/query',
|
||||||
'ConduitAPI_maniphest_Method' => 'applications/conduit/method/maniphest/base',
|
'ConduitAPI_maniphest_Method' => 'applications/conduit/method/maniphest/base',
|
||||||
'ConduitAPI_maniphest_createtask_Method' => 'applications/conduit/method/maniphest/createtask',
|
'ConduitAPI_maniphest_createtask_Method' => 'applications/conduit/method/maniphest/createtask',
|
||||||
'ConduitAPI_maniphest_find_Method' => 'applications/conduit/method/maniphest/find',
|
'ConduitAPI_maniphest_find_Method' => 'applications/conduit/method/maniphest/find',
|
||||||
|
@ -581,6 +583,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorIRCDifferentialNotificationHandler' => 'infrastructure/daemon/irc/handler/differentialnotification',
|
'PhabricatorIRCDifferentialNotificationHandler' => 'infrastructure/daemon/irc/handler/differentialnotification',
|
||||||
'PhabricatorIRCHandler' => 'infrastructure/daemon/irc/handler/base',
|
'PhabricatorIRCHandler' => 'infrastructure/daemon/irc/handler/base',
|
||||||
'PhabricatorIRCLogHandler' => 'infrastructure/daemon/irc/handler/log',
|
'PhabricatorIRCLogHandler' => 'infrastructure/daemon/irc/handler/log',
|
||||||
|
'PhabricatorIRCMacroHandler' => 'infrastructure/daemon/irc/handler/macro',
|
||||||
'PhabricatorIRCMessage' => 'infrastructure/daemon/irc/message',
|
'PhabricatorIRCMessage' => 'infrastructure/daemon/irc/message',
|
||||||
'PhabricatorIRCObjectNameHandler' => 'infrastructure/daemon/irc/handler/objectname',
|
'PhabricatorIRCObjectNameHandler' => 'infrastructure/daemon/irc/handler/objectname',
|
||||||
'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/irc/handler/protocol',
|
'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/irc/handler/protocol',
|
||||||
|
@ -1018,6 +1021,8 @@ phutil_register_library_map(array(
|
||||||
'ConduitAPI_file_download_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_file_download_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_file_info_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_file_info_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
|
||||||
|
'ConduitAPI_macro_Method' => 'ConduitAPIMethod',
|
||||||
|
'ConduitAPI_macro_query_Method' => 'ConduitAPI_macro_Method',
|
||||||
'ConduitAPI_maniphest_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_maniphest_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_maniphest_createtask_Method' => 'ConduitAPI_maniphest_Method',
|
'ConduitAPI_maniphest_createtask_Method' => 'ConduitAPI_maniphest_Method',
|
||||||
'ConduitAPI_maniphest_find_Method' => 'ConduitAPI_maniphest_Method',
|
'ConduitAPI_maniphest_find_Method' => 'ConduitAPI_maniphest_Method',
|
||||||
|
@ -1359,6 +1364,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorIRCBot' => 'PhabricatorDaemon',
|
'PhabricatorIRCBot' => 'PhabricatorDaemon',
|
||||||
'PhabricatorIRCDifferentialNotificationHandler' => 'PhabricatorIRCHandler',
|
'PhabricatorIRCDifferentialNotificationHandler' => 'PhabricatorIRCHandler',
|
||||||
'PhabricatorIRCLogHandler' => 'PhabricatorIRCHandler',
|
'PhabricatorIRCLogHandler' => 'PhabricatorIRCHandler',
|
||||||
|
'PhabricatorIRCMacroHandler' => 'PhabricatorIRCHandler',
|
||||||
'PhabricatorIRCObjectNameHandler' => 'PhabricatorIRCHandler',
|
'PhabricatorIRCObjectNameHandler' => 'PhabricatorIRCHandler',
|
||||||
'PhabricatorIRCProtocolHandler' => 'PhabricatorIRCHandler',
|
'PhabricatorIRCProtocolHandler' => 'PhabricatorIRCHandler',
|
||||||
'PhabricatorIRCWhatsNewHandler' => 'PhabricatorIRCHandler',
|
'PhabricatorIRCWhatsNewHandler' => 'PhabricatorIRCHandler',
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group conduit
|
||||||
|
*/
|
||||||
|
abstract class ConduitAPI_macro_Method extends ConduitAPIMethod {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
12
src/applications/conduit/method/macro/base/__init__.php
Normal file
12
src/applications/conduit/method/macro/base/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/conduit/method/base');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ConduitAPI_macro_Method.php');
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group conduit
|
||||||
|
*/
|
||||||
|
final class ConduitAPI_macro_query_Method extends ConduitAPI_macro_Method {
|
||||||
|
|
||||||
|
public function getMethodDescription() {
|
||||||
|
return "Retrieve image macro information.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineParamTypes() {
|
||||||
|
return array(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineReturnType() {
|
||||||
|
return 'list<dict>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineErrorTypes() {
|
||||||
|
return array(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(ConduitAPIRequest $request) {
|
||||||
|
|
||||||
|
$macros = id(new PhabricatorFileImageMacro())->loadAll();
|
||||||
|
|
||||||
|
$files = array();
|
||||||
|
if ($macros) {
|
||||||
|
$files = id(new PhabricatorFile())->loadAllWhere(
|
||||||
|
'phid IN (%Ls)',
|
||||||
|
mpull($macros, 'getFilePHID'));
|
||||||
|
$files = mpull($files, null, 'getPHID');
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($macros as $macro) {
|
||||||
|
if (empty($files[$macro->getFilePHID()])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$results[$macro->getName()] = array(
|
||||||
|
'uri' => $files[$macro->getFilePHID()]->getBestURI(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/applications/conduit/method/macro/query/__init__.php
Normal file
16
src/applications/conduit/method/macro/query/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/conduit/method/macro/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/files/storage/file');
|
||||||
|
phutil_require_module('phabricator', 'applications/files/storage/imagemacro');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ConduitAPI_macro_query_Method.php');
|
|
@ -0,0 +1,200 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group irc
|
||||||
|
*/
|
||||||
|
final class PhabricatorIRCMacroHandler extends PhabricatorIRCHandler {
|
||||||
|
|
||||||
|
private $macros;
|
||||||
|
private $regexp;
|
||||||
|
|
||||||
|
private $buffer = array();
|
||||||
|
private $next = 0;
|
||||||
|
|
||||||
|
private function init() {
|
||||||
|
if ($this->macros === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->macros !== null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$macros = $this->getConduit()->callMethodSynchronous(
|
||||||
|
'macro.query',
|
||||||
|
array());
|
||||||
|
|
||||||
|
$this->macros = $macros;
|
||||||
|
|
||||||
|
$regexp = array();
|
||||||
|
foreach ($this->macros as $macro_name => $macro) {
|
||||||
|
$regexp[] = preg_quote($macro_name, '/');
|
||||||
|
}
|
||||||
|
$regexp = '/('.implode('|', $regexp).')/';
|
||||||
|
|
||||||
|
$this->regexp = $regexp;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function receiveMessage(PhabricatorIRCMessage $message) {
|
||||||
|
if (!$this->init()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($message->getCommand()) {
|
||||||
|
case 'PRIVMSG':
|
||||||
|
$reply_to = $message->getReplyTo();
|
||||||
|
if (!$reply_to) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = $message->getMessageText();
|
||||||
|
|
||||||
|
$matches = null;
|
||||||
|
if (!preg_match($this->regexp, $message, $matches)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$macro = $matches[1];
|
||||||
|
|
||||||
|
$ascii = idx($this->macros[$macro], 'ascii');
|
||||||
|
if ($ascii === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$ascii) {
|
||||||
|
$this->macros[$macro]['ascii'] = $this->rasterize(
|
||||||
|
$this->macros[$macro],
|
||||||
|
$this->getConfig('macro.size', 48),
|
||||||
|
$this->getConfig('macro.aspect', 0.66));
|
||||||
|
$ascii = $this->macros[$macro]['ascii'];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($ascii as $line) {
|
||||||
|
$this->buffer[$reply_to][] = $line;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runBackgroundTasks() {
|
||||||
|
if (microtime(true) < $this->next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->buffer as $channel => $lines) {
|
||||||
|
if (empty($lines)) {
|
||||||
|
unset($this->buffer[$channel]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach ($lines as $key => $line) {
|
||||||
|
$this->write('PRIVMSG', "{$channel} :{$line}");
|
||||||
|
unset($this->buffer[$channel][$key]);
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sleep = $this->getConfig('macro.sleep', 0.25);
|
||||||
|
$this->next = microtime(true) + ((mt_rand(75, 150) / 100) * $sleep);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rasterize($macro, $size, $aspect) {
|
||||||
|
$image = @file_get_contents($macro['uri']);
|
||||||
|
if (!$image) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$img = @imagecreatefromstring($image);
|
||||||
|
if (!$img) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sx = imagesx($img);
|
||||||
|
$sy = imagesy($img);
|
||||||
|
|
||||||
|
if ($sx > $size || $sy > $size) {
|
||||||
|
$scale = max($sx, $sy) / $size;
|
||||||
|
$dx = floor($sx / $scale);
|
||||||
|
$dy = floor($sy / $scale);
|
||||||
|
} else {
|
||||||
|
$dx = $sx;
|
||||||
|
$dy = $sy;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dy = floor($dy * $aspect);
|
||||||
|
|
||||||
|
$dst = imagecreatetruecolor($dx, $dy);
|
||||||
|
if (!$dst) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
imagealphablending($dst, false);
|
||||||
|
|
||||||
|
$ok = imagecopyresampled(
|
||||||
|
$dst, $img,
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
$dx, $dy,
|
||||||
|
$sx, $sy);
|
||||||
|
|
||||||
|
if (!$ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$map = array(
|
||||||
|
' ',
|
||||||
|
'.',
|
||||||
|
',',
|
||||||
|
':',
|
||||||
|
';',
|
||||||
|
'!',
|
||||||
|
'|',
|
||||||
|
'*',
|
||||||
|
'=',
|
||||||
|
'@',
|
||||||
|
'$',
|
||||||
|
'#',
|
||||||
|
);
|
||||||
|
|
||||||
|
$lines = array();
|
||||||
|
|
||||||
|
for ($ii = 0; $ii < $dy; $ii++) {
|
||||||
|
$buf = '';
|
||||||
|
for ($jj = 0; $jj < $dx; $jj++) {
|
||||||
|
$c = imagecolorat($dst, $jj, $ii);
|
||||||
|
|
||||||
|
$a = ($c >> 24) & 0xFF;
|
||||||
|
$r = ($c >> 16) & 0xFF;
|
||||||
|
$g = ($c >> 8) & 0xFF;
|
||||||
|
$b = ($c) & 0xFF;
|
||||||
|
|
||||||
|
$luma = (255 - ((0.30 * $r) + (0.59 * $g) + (0.11 * $b))) / 256;
|
||||||
|
$luma *= ((127 - $a) / 127);
|
||||||
|
|
||||||
|
$char = $map[max(0, floor($luma * count($map)))];
|
||||||
|
$buf .= $char;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lines[] = $buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/infrastructure/daemon/irc/handler/macro/__init__.php
Normal file
14
src/infrastructure/daemon/irc/handler/macro/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/irc/handler/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorIRCMacroHandler.php');
|
Loading…
Reference in a new issue