Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F101023305
PhabricatorBotObjectNameHandler.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Feb 4, 22:05
Size
5 KB
Mime Type
text/x-php
Expires
Thu, Feb 6, 22:05 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
24075636
Attached To
rPH Phabricator
PhabricatorBotObjectNameHandler.php
View Options
<?php
/**
* Looks for Dxxxx, Txxxx and links to them.
*
* @group irc
*/
final
class
PhabricatorBotObjectNameHandler
extends
PhabricatorBotHandler
{
/**
* Map of PHIDs to the last mention of them (as an epoch timestamp); prevents
* us from spamming chat when a single object is discussed.
*/
private
$recentlyMentioned
=
array
();
public
function
receiveMessage
(
PhabricatorBotMessage
$original_message
)
{
switch
(
$original_message
->
getCommand
())
{
case
'MESSAGE'
:
$message
=
$original_message
->
getBody
();
$matches
=
null
;
$pattern
=
'@'
.
'(?<!/)(?:^|
\b
)'
.
// Negative lookbehind prevent matching "/D123".
'(D|T|P|V|F)(
\d
+)'
.
'(?:
\b
|$)'
.
'@'
;
$revision_ids
=
array
();
$task_ids
=
array
();
$paste_ids
=
array
();
$commit_names
=
array
();
$vote_ids
=
array
();
$file_ids
=
array
();
if
(
preg_match_all
(
$pattern
,
$message
,
$matches
,
PREG_SET_ORDER
))
{
foreach
(
$matches
as
$match
)
{
switch
(
$match
[
1
])
{
case
'D'
:
$revision_ids
[]
=
$match
[
2
];
break
;
case
'T'
:
$task_ids
[]
=
$match
[
2
];
break
;
case
'P'
:
$paste_ids
[]
=
$match
[
2
];
break
;
case
'V'
:
$vote_ids
[]
=
$match
[
2
];
break
;
case
'F'
:
$file_ids
[]
=
$match
[
2
];
break
;
}
}
}
$pattern
=
'@'
.
'(?<!/)(?:^|
\b
)'
.
'(r[A-Z]+[0-9a-z]{1,40})'
.
'(?:
\b
|$)'
.
'@'
;
if
(
preg_match_all
(
$pattern
,
$message
,
$matches
,
PREG_SET_ORDER
))
{
foreach
(
$matches
as
$match
)
{
$commit_names
[]
=
$match
[
1
];
}
}
$output
=
array
();
if
(
$revision_ids
)
{
$revisions
=
$this
->
getConduit
()->
callMethodSynchronous
(
'differential.query'
,
array
(
'ids'
=>
$revision_ids
,
));
$revisions
=
array_select_keys
(
ipull
(
$revisions
,
null
,
'id'
),
$revision_ids
);
foreach
(
$revisions
as
$revision
)
{
$output
[
$revision
[
'phid'
]]
=
'D'
.
$revision
[
'id'
].
' '
.
$revision
[
'title'
].
' - '
.
$revision
[
'uri'
];
}
}
if
(
$task_ids
)
{
foreach
(
$task_ids
as
$task_id
)
{
if
(
$task_id
==
1000
)
{
$output
[
1000
]
=
'T1000: A nanomorph mimetic poly-alloy'
.
'(liquid metal) assassin controlled by Skynet: '
.
'http://en.wikipedia.org/wiki/T-1000'
;
continue
;
}
$task
=
$this
->
getConduit
()->
callMethodSynchronous
(
'maniphest.info'
,
array
(
'task_id'
=>
$task_id
,
));
$output
[
$task
[
'phid'
]]
=
'T'
.
$task
[
'id'
].
': '
.
$task
[
'title'
].
' (Priority: '
.
$task
[
'priority'
].
') - '
.
$task
[
'uri'
];
}
}
if
(
$vote_ids
)
{
foreach
(
$vote_ids
as
$vote_id
)
{
$vote
=
$this
->
getConduit
()->
callMethodSynchronous
(
'slowvote.info'
,
array
(
'poll_id'
=>
$vote_id
,
));
$output
[
$vote
[
'phid'
]]
=
'V'
.
$vote
[
'id'
].
': '
.
$vote
[
'question'
].
' Come Vote '
.
$vote
[
'uri'
];
}
}
if
(
$file_ids
)
{
foreach
(
$file_ids
as
$file_id
)
{
$file
=
$this
->
getConduit
()->
callMethodSynchronous
(
'file.info'
,
array
(
'id'
=>
$file_id
,
));
$output
[
$file
[
'phid'
]]
=
$file
[
'objectName'
].
": "
.
$file
[
'uri'
].
" - "
.
$file
[
'name'
];
}
}
if
(
$paste_ids
)
{
foreach
(
$paste_ids
as
$paste_id
)
{
$paste
=
$this
->
getConduit
()->
callMethodSynchronous
(
'paste.info'
,
array
(
'paste_id'
=>
$paste_id
,
));
// Eventually I'd like to show the username of the paster as well,
// however that will need something like a user.username_from_phid
// since we (ideally) want to keep the bot to Conduit calls...and
// not call to Phabricator-specific stuff (like actually loading
// the User object and fetching his/her username.)
$output
[
$paste
[
'phid'
]]
=
'P'
.
$paste
[
'id'
].
': '
.
$paste
[
'uri'
].
' - '
.
$paste
[
'title'
];
if
(
$paste
[
'language'
])
{
$output
[
$paste
[
'phid'
]]
.=
' ('
.
$paste
[
'language'
].
')'
;
}
}
}
if
(
$commit_names
)
{
$commits
=
$this
->
getConduit
()->
callMethodSynchronous
(
'diffusion.getcommits'
,
array
(
'commits'
=>
$commit_names
,
));
foreach
(
$commits
as
$commit
)
{
if
(
isset
(
$commit
[
'error'
]))
{
continue
;
}
$output
[
$commit
[
'commitPHID'
]]
=
$commit
[
'uri'
];
}
}
foreach
(
$output
as
$phid
=>
$description
)
{
// Don't mention the same object more than once every 10 minutes
// in public channels, so we avoid spamming the chat over and over
// again for discsussions of a specific revision, for example.
$reply_to
=
$original_message
->
getReplyTo
();
if
(
empty
(
$this
->
recentlyMentioned
[
$reply_to
]))
{
$this
->
recentlyMentioned
[
$reply_to
]
=
array
();
}
$quiet_until
=
idx
(
$this
->
recentlyMentioned
[
$reply_to
],
$phid
,
0
)
+
(
60
*
10
);
if
(
time
()
<
$quiet_until
)
{
// Remain quiet on this channel.
continue
;
}
$this
->
recentlyMentioned
[
$reply_to
][
$phid
]
=
time
();
$this
->
replyTo
(
$original_message
,
$description
);
}
break
;
}
}
}
Event Timeline
Log In to Comment