spox-mod_spox 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +174 -0
- data/INSTALL +15 -0
- data/LICENSE +674 -0
- data/README.rdoc +73 -0
- data/bin/mod_spox +112 -0
- data/data/mod_spox/extras/AOLSpeak.rb +257 -0
- data/data/mod_spox/extras/AutoKick.rb +152 -0
- data/data/mod_spox/extras/AutoMode.rb +122 -0
- data/data/mod_spox/extras/AutoRejoin.rb +37 -0
- data/data/mod_spox/extras/Bash.rb +55 -0
- data/data/mod_spox/extras/Bouncer.rb +220 -0
- data/data/mod_spox/extras/Bullshit.rb +19 -0
- data/data/mod_spox/extras/Bytes.rb +11 -0
- data/data/mod_spox/extras/Confess.rb +244 -0
- data/data/mod_spox/extras/DCC.rb +182 -0
- data/data/mod_spox/extras/DevWatch.rb +153 -0
- data/data/mod_spox/extras/DownForEveryoneOrJustMe.rb +47 -0
- data/data/mod_spox/extras/EightBall.rb +33 -0
- data/data/mod_spox/extras/FML.rb +35 -0
- data/data/mod_spox/extras/FloodKicker.rb +129 -0
- data/data/mod_spox/extras/Fortune.rb +76 -0
- data/data/mod_spox/extras/GoogleIt.rb +13 -0
- data/data/mod_spox/extras/Headers.rb +59 -0
- data/data/mod_spox/extras/Karma.rb +302 -0
- data/data/mod_spox/extras/Locator.rb +44 -0
- data/data/mod_spox/extras/Logger.rb +182 -0
- data/data/mod_spox/extras/LolSpeak.rb +21 -0
- data/data/mod_spox/extras/NickServ.rb +84 -0
- data/data/mod_spox/extras/PhpCli.rb +308 -0
- data/data/mod_spox/extras/PhpFuncLookup.rb +297 -0
- data/data/mod_spox/extras/Pinger.rb +11 -0
- data/data/mod_spox/extras/Quotes.rb +79 -0
- data/data/mod_spox/extras/RegexTracker.rb +158 -0
- data/data/mod_spox/extras/Roulette.rb +267 -0
- data/data/mod_spox/extras/RubyCli.rb +93 -0
- data/data/mod_spox/extras/Search.rb +49 -0
- data/data/mod_spox/extras/Seen.rb +150 -0
- data/data/mod_spox/extras/Slashdot.rb +35 -0
- data/data/mod_spox/extras/SlashdotHeadlineGenerator.rb +500 -0
- data/data/mod_spox/extras/Talk.rb +32 -0
- data/data/mod_spox/extras/Topten.rb +103 -0
- data/data/mod_spox/extras/TracTicket.rb +66 -0
- data/data/mod_spox/extras/Translate.rb +132 -0
- data/data/mod_spox/extras/Twitter.rb +458 -0
- data/data/mod_spox/extras/UrbanDictionary.rb +55 -0
- data/data/mod_spox/extras/Weather.rb +55 -0
- data/data/mod_spox/plugins/Authenticator.rb +289 -0
- data/data/mod_spox/plugins/Banner.rb +585 -0
- data/data/mod_spox/plugins/BotNick.rb +18 -0
- data/data/mod_spox/plugins/Helper.rb +49 -0
- data/data/mod_spox/plugins/Initializer.rb +35 -0
- data/data/mod_spox/plugins/Joiner.rb +23 -0
- data/data/mod_spox/plugins/Nicker.rb +14 -0
- data/data/mod_spox/plugins/Parter.rb +23 -0
- data/data/mod_spox/plugins/Permissions.rb +60 -0
- data/data/mod_spox/plugins/PluginLoader.rb +180 -0
- data/data/mod_spox/plugins/Ponger.rb +70 -0
- data/data/mod_spox/plugins/PoolConfig.rb +52 -0
- data/data/mod_spox/plugins/Quitter.rb +15 -0
- data/data/mod_spox/plugins/Servers.rb +57 -0
- data/data/mod_spox/plugins/Status.rb +31 -0
- data/data/mod_spox/plugins/Triggers.rb +85 -0
- data/lib/mod_spox/BaseConfig.rb +51 -0
- data/lib/mod_spox/Bot.rb +604 -0
- data/lib/mod_spox/BotConfig.rb +65 -0
- data/lib/mod_spox/ConfigurationWizard.rb +180 -0
- data/lib/mod_spox/Database.rb +51 -0
- data/lib/mod_spox/Exceptions.rb +84 -0
- data/lib/mod_spox/Helpers.rb +122 -0
- data/lib/mod_spox/Loader.rb +60 -0
- data/lib/mod_spox/Logger.rb +37 -0
- data/lib/mod_spox/MessageFactory.rb +112 -0
- data/lib/mod_spox/Pipeline.rb +207 -0
- data/lib/mod_spox/Plugin.rb +97 -0
- data/lib/mod_spox/PluginHolder.rb +22 -0
- data/lib/mod_spox/PluginManager.rb +257 -0
- data/lib/mod_spox/PriorityQueue.rb +69 -0
- data/lib/mod_spox/Socket.rb +201 -0
- data/lib/mod_spox/Sockets.rb +226 -0
- data/lib/mod_spox/Timer.rb +60 -0
- data/lib/mod_spox/Version.rb +14 -0
- data/lib/mod_spox/handlers/BadNick.rb +19 -0
- data/lib/mod_spox/handlers/Bounce.rb +24 -0
- data/lib/mod_spox/handlers/Created.rb +27 -0
- data/lib/mod_spox/handlers/Handler.rb +39 -0
- data/lib/mod_spox/handlers/Invite.rb +28 -0
- data/lib/mod_spox/handlers/Join.rb +38 -0
- data/lib/mod_spox/handlers/Kick.rb +36 -0
- data/lib/mod_spox/handlers/LuserChannels.rb +19 -0
- data/lib/mod_spox/handlers/LuserClient.rb +18 -0
- data/lib/mod_spox/handlers/LuserMe.rb +16 -0
- data/lib/mod_spox/handlers/LuserOp.rb +19 -0
- data/lib/mod_spox/handlers/LuserUnknown.rb +19 -0
- data/lib/mod_spox/handlers/Mode.rb +62 -0
- data/lib/mod_spox/handlers/Motd.rb +38 -0
- data/lib/mod_spox/handlers/MyInfo.rb +24 -0
- data/lib/mod_spox/handlers/Names.rb +86 -0
- data/lib/mod_spox/handlers/Nick.rb +50 -0
- data/lib/mod_spox/handlers/NickInUse.rb +19 -0
- data/lib/mod_spox/handlers/Notice.rb +35 -0
- data/lib/mod_spox/handlers/Part.rb +39 -0
- data/lib/mod_spox/handlers/Ping.rb +25 -0
- data/lib/mod_spox/handlers/Pong.rb +23 -0
- data/lib/mod_spox/handlers/Privmsg.rb +39 -0
- data/lib/mod_spox/handlers/Quit.rb +29 -0
- data/lib/mod_spox/handlers/Topic.rb +38 -0
- data/lib/mod_spox/handlers/Welcome.rb +30 -0
- data/lib/mod_spox/handlers/Who.rb +83 -0
- data/lib/mod_spox/handlers/Whois.rb +117 -0
- data/lib/mod_spox/handlers/YourHost.rb +20 -0
- data/lib/mod_spox/messages/Messages.rb +6 -0
- data/lib/mod_spox/messages/incoming/BadNick.rb +16 -0
- data/lib/mod_spox/messages/incoming/Bounce.rb +18 -0
- data/lib/mod_spox/messages/incoming/Created.rb +15 -0
- data/lib/mod_spox/messages/incoming/Invite.rb +21 -0
- data/lib/mod_spox/messages/incoming/Join.rb +19 -0
- data/lib/mod_spox/messages/incoming/Kick.rb +26 -0
- data/lib/mod_spox/messages/incoming/LuserChannels.rb +15 -0
- data/lib/mod_spox/messages/incoming/LuserClient.rb +24 -0
- data/lib/mod_spox/messages/incoming/LuserMe.rb +18 -0
- data/lib/mod_spox/messages/incoming/LuserOp.rb +15 -0
- data/lib/mod_spox/messages/incoming/LuserUnknown.rb +15 -0
- data/lib/mod_spox/messages/incoming/Message.rb +22 -0
- data/lib/mod_spox/messages/incoming/Mode.rb +42 -0
- data/lib/mod_spox/messages/incoming/Motd.rb +18 -0
- data/lib/mod_spox/messages/incoming/MyInfo.rb +24 -0
- data/lib/mod_spox/messages/incoming/Names.rb +24 -0
- data/lib/mod_spox/messages/incoming/Nick.rb +26 -0
- data/lib/mod_spox/messages/incoming/NickInUse.rb +15 -0
- data/lib/mod_spox/messages/incoming/Notice.rb +9 -0
- data/lib/mod_spox/messages/incoming/Part.rb +21 -0
- data/lib/mod_spox/messages/incoming/Ping.rb +18 -0
- data/lib/mod_spox/messages/incoming/Pong.rb +9 -0
- data/lib/mod_spox/messages/incoming/Privmsg.rb +90 -0
- data/lib/mod_spox/messages/incoming/Quit.rb +18 -0
- data/lib/mod_spox/messages/incoming/Topic.rb +21 -0
- data/lib/mod_spox/messages/incoming/TopicInfo.rb +21 -0
- data/lib/mod_spox/messages/incoming/Welcome.rb +27 -0
- data/lib/mod_spox/messages/incoming/Who.rb +18 -0
- data/lib/mod_spox/messages/incoming/Whois.rb +49 -0
- data/lib/mod_spox/messages/incoming/YourHost.rb +18 -0
- data/lib/mod_spox/messages/internal/BotInitialized.rb +11 -0
- data/lib/mod_spox/messages/internal/ChangeNick.rb +15 -0
- data/lib/mod_spox/messages/internal/Connected.rb +20 -0
- data/lib/mod_spox/messages/internal/ConnectionFailed.rb +23 -0
- data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
- data/lib/mod_spox/messages/internal/Disconnected.rb +8 -0
- data/lib/mod_spox/messages/internal/Disconnecting.rb +8 -0
- data/lib/mod_spox/messages/internal/EstablishConnection.rb +22 -0
- data/lib/mod_spox/messages/internal/HaltBot.rb +8 -0
- data/lib/mod_spox/messages/internal/NickRequest.rb +9 -0
- data/lib/mod_spox/messages/internal/NickResponse.rb +15 -0
- data/lib/mod_spox/messages/internal/PluginLoadRequest.rb +21 -0
- data/lib/mod_spox/messages/internal/PluginLoadResponse.rb +17 -0
- data/lib/mod_spox/messages/internal/PluginModuleRequest.rb +14 -0
- data/lib/mod_spox/messages/internal/PluginModuleResponse.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginReload.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginRequest.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginResponse.rb +21 -0
- data/lib/mod_spox/messages/internal/PluginUnloadRequest.rb +9 -0
- data/lib/mod_spox/messages/internal/PluginUnloadResponse.rb +9 -0
- data/lib/mod_spox/messages/internal/PluginsReady.rb +10 -0
- data/lib/mod_spox/messages/internal/QueueSocket.rb +8 -0
- data/lib/mod_spox/messages/internal/Reconnect.rb +8 -0
- data/lib/mod_spox/messages/internal/Request.rb +15 -0
- data/lib/mod_spox/messages/internal/Response.rb +15 -0
- data/lib/mod_spox/messages/internal/Shutdown.rb +8 -0
- data/lib/mod_spox/messages/internal/SignaturesUpdate.rb +8 -0
- data/lib/mod_spox/messages/internal/StatusRequest.rb +10 -0
- data/lib/mod_spox/messages/internal/StatusResponse.rb +18 -0
- data/lib/mod_spox/messages/internal/TimerAdd.rb +36 -0
- data/lib/mod_spox/messages/internal/TimerClear.rb +16 -0
- data/lib/mod_spox/messages/internal/TimerRemove.rb +23 -0
- data/lib/mod_spox/messages/internal/TimerResponse.rb +34 -0
- data/lib/mod_spox/messages/internal/TriggersUpdate.rb +8 -0
- data/lib/mod_spox/messages/internal/UnqueueSocket.rb +8 -0
- data/lib/mod_spox/messages/outgoing/Admin.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Away.rb +11 -0
- data/lib/mod_spox/messages/outgoing/ChannelMode.rb +25 -0
- data/lib/mod_spox/messages/outgoing/Connect.rb +24 -0
- data/lib/mod_spox/messages/outgoing/Die.rb +9 -0
- data/lib/mod_spox/messages/outgoing/Info.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Invite.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Ison.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Join.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Kick.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Kill.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Links.rb +19 -0
- data/lib/mod_spox/messages/outgoing/List.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Lusers.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Motd.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Names.rb +20 -0
- data/lib/mod_spox/messages/outgoing/Nick.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Notice.rb +12 -0
- data/lib/mod_spox/messages/outgoing/Oper.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Part.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Pass.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Ping.rb +11 -0
- data/lib/mod_spox/messages/outgoing/Pong.rb +17 -0
- data/lib/mod_spox/messages/outgoing/Privmsg.rb +43 -0
- data/lib/mod_spox/messages/outgoing/Quit.rb +11 -0
- data/lib/mod_spox/messages/outgoing/Raw.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Rehash.rb +9 -0
- data/lib/mod_spox/messages/outgoing/Restart.rb +9 -0
- data/lib/mod_spox/messages/outgoing/ServList.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Simple.rb +12 -0
- data/lib/mod_spox/messages/outgoing/Squery.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Squit.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Stats.rb +18 -0
- data/lib/mod_spox/messages/outgoing/Summon.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Time.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Topic.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Trace.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Unaway.rb +9 -0
- data/lib/mod_spox/messages/outgoing/User.rb +23 -0
- data/lib/mod_spox/messages/outgoing/UserHost.rb +15 -0
- data/lib/mod_spox/messages/outgoing/UserMode.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Users.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Version.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Who.rb +23 -0
- data/lib/mod_spox/messages/outgoing/WhoWas.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Whois.rb +19 -0
- data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
- data/lib/mod_spox/migrations/002_persistent_sigs.rb +14 -0
- data/lib/mod_spox/migrations/003_auth_restructure.rb +31 -0
- data/lib/mod_spox/migrations/004_mode_index_fix.rb +18 -0
- data/lib/mod_spox/migrations/005_nick_mode_nopark.rb +18 -0
- data/lib/mod_spox/models/Auth.rb +65 -0
- data/lib/mod_spox/models/AuthMask.rb +13 -0
- data/lib/mod_spox/models/Channel.rb +89 -0
- data/lib/mod_spox/models/Config.rb +30 -0
- data/lib/mod_spox/models/Group.rb +30 -0
- data/lib/mod_spox/models/Models.rb +4 -0
- data/lib/mod_spox/models/Nick.rb +195 -0
- data/lib/mod_spox/models/NickMode.rb +32 -0
- data/lib/mod_spox/models/Server.rb +27 -0
- data/lib/mod_spox/models/Setting.rb +52 -0
- data/lib/mod_spox/models/Signature.rb +52 -0
- data/lib/mod_spox/models/Trigger.rb +9 -0
- data/lib/mod_spox/rfc2812.rb +49 -0
- data/populate_gemspec.rb +15 -0
- data/tests/BotHolder.rb +24 -0
- data/tests/handlers/tc_BadNick.rb +21 -0
- data/tests/handlers/tc_Created.rb +24 -0
- data/tests/handlers/tc_Invite.rb +50 -0
- data/tests/handlers/tc_Join.rb +33 -0
- data/tests/handlers/tc_Kick.rb +32 -0
- data/tests/handlers/tc_Mode.rb +85 -0
- data/tests/handlers/tc_Names.rb +35 -0
- data/tests/handlers/tc_Nick.rb +55 -0
- data/tests/handlers/tc_Part.rb +44 -0
- data/tests/handlers/tc_Ping.rb +40 -0
- data/tests/handlers/tc_Pong.rb +28 -0
- data/tests/handlers/tc_Privmsg.rb +85 -0
- data/tests/handlers/tc_Quit.rb +40 -0
- data/tests/handlers/tc_Who.rb +50 -0
- data/tests/handlers/tc_Whois.rb +61 -0
- data/tests/models/tc_Auth.rb +39 -0
- data/tests/models/tc_Channel.rb +52 -0
- data/tests/models/tc_Config.rb +19 -0
- data/tests/models/tc_Nick.rb +144 -0
- data/tests/models/tc_NickMode.rb +40 -0
- data/tests/models/tc_Setting.rb +21 -0
- data/tests/models/tc_Signature.rb +14 -0
- data/tests/run_tests.rb +6 -0
- metadata +362 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
class TracTicket < ModSpox::Plugin
|
4
|
+
|
5
|
+
def initialize(pipeline)
|
6
|
+
super
|
7
|
+
admin = Group.find_or_create(:name => 'admin')
|
8
|
+
add_sig(:sig => 'ticket (defect|enhancement|task) (.+?)( # (.+))?', :method => :add_ticket,
|
9
|
+
:desc => 'Add new ticket to trac ticket tracker', :params => [:type, :short, :trash, :long])
|
10
|
+
add_sig(:sig => 'ticket trac( (\S+))?', :method => :trac_location, :group => admin,
|
11
|
+
:desc => 'Show/set trac site', :params => [:trash, :site])
|
12
|
+
add_sig(:sig => 'ticket site', :method => :trac_location, :desc => 'Show trac site')
|
13
|
+
@site = Config.val(:trac)
|
14
|
+
end
|
15
|
+
|
16
|
+
def trac_location(message, params)
|
17
|
+
if(params[:site])
|
18
|
+
site = Config.set(:trac, params[:site])
|
19
|
+
@site = params[:site]
|
20
|
+
reply message.replyto, "\2Trac Update:\2 Location of trac system has been updated: #{params[:site]}"
|
21
|
+
else
|
22
|
+
output = "\2Error:\2 Trac site has not yet been set"
|
23
|
+
unless(@site.nil?)
|
24
|
+
output = "\2Trac location:\2 #{@site}"
|
25
|
+
end
|
26
|
+
reply message.replyto, output
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_ticket(message, params)
|
31
|
+
if(@site =~ /(http:\/\/)?([^\/:]+)(:\d+)?(.+)$/)
|
32
|
+
addr = $2
|
33
|
+
port = $3
|
34
|
+
path = $4
|
35
|
+
port = port.nil? ? 80 : port.gsub(/:/, '').to_i
|
36
|
+
con = Net::HTTP.new(addr, port)
|
37
|
+
begin
|
38
|
+
cookie, fid = get_form_info(con, path)
|
39
|
+
long = params[:long] ? params[:long] : params[:short]
|
40
|
+
headers = {
|
41
|
+
'Cookie' => cookie,
|
42
|
+
'Referer' => @site,
|
43
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
44
|
+
}
|
45
|
+
data = "field_reporter=#{URI.escape(message.source.nick)}&field_summary=#{URI.escape(params[:short])}&field_description=#{URI.escape(long)}&field_type=#{URI.escape(params[:type])}&field_status=new&submit=Create%20ticket&field_priority=minor&__FORM_TOKEN=#{URI.escape(fid)}"
|
46
|
+
resp, data = con.post(path, data, headers)
|
47
|
+
reply message.replyto, 'Ticket was successfully added to tracker'
|
48
|
+
rescue Object => boom
|
49
|
+
reply message.replyto, "\2Error:\2 Encountered unexpected error while submitting ticket: #{boom}"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
reply message.replyto, "\2Error:\2 Trac location has not been set"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_form_info(con, path)
|
57
|
+
res, content = con.get(path, {})
|
58
|
+
cookie = res['set-cookie']
|
59
|
+
if(content =~ /name="__FORM_TOKEN" value="(.+?)"/i)
|
60
|
+
return cookie, $1
|
61
|
+
else
|
62
|
+
raise 'Failed to locate proper identification'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
class Translate < ModSpox::Plugin
|
2
|
+
|
3
|
+
include Models
|
4
|
+
|
5
|
+
def initialize(pipeline)
|
6
|
+
super(pipeline)
|
7
|
+
add_sig(:sig => 'translate ([a-z]{2}\|[a-z]{2}) (.+)', :method => :translate, :desc => 'Translate text', :params => [:lang, :text])
|
8
|
+
add_sig(:sig => 'autotranslate add ([a-z]{2}) (\S+)', :method => :auto_add, :desc => 'Add a nick to the autotranslate service', :params => [:lang, :nick])
|
9
|
+
add_sig(:sig => 'autotranslate remove (\S+)', :method => :auto_remove, :desc => 'Remove a nick from the autotranslate service', :params => [:nick])
|
10
|
+
add_sig(:sig => 'translate languages', :method => :langs, :desc => 'Show available languages')
|
11
|
+
@pipeline.hook(self, :listener, :Incoming_Privmsg)
|
12
|
+
@watchers = {}
|
13
|
+
@cache = {}
|
14
|
+
@allowed = {'zh'=>'Chinese-simplified','zt'=>'Chinese-traditional','en'=>'English','nl'=>'Dutch',
|
15
|
+
'fr'=>'French','de'=>'German','el'=>'Greek','it'=>'Italian','ja'=>'Japanese',
|
16
|
+
'ko'=>'Korean','pt'=>'Portuguese','ru'=>'Russian','es'=>'Spanish'}
|
17
|
+
@allowed_trans = ['zh_en','zh_zt', 'zt_en', 'zt_zh', 'en_zh', 'en_zt', 'en_nl', 'en_fr', 'en_de',
|
18
|
+
'en_el', 'en_it', 'en_ja', 'en_ko', 'en_pt', 'en_ru', 'en_es', 'nl_en', 'nl_fr',
|
19
|
+
'fr_nl', 'fr_en', 'fr_de', 'fr_el', 'fr_it', 'fr_pt', 'fr_es', 'de_en', 'de_fr',
|
20
|
+
'el_en', 'el_fr', 'it_en', 'it_fr', 'ja_en', 'ko_en', 'pt_en', 'pt_fr', 'ru_en',
|
21
|
+
'es_en', 'es_fr']
|
22
|
+
end
|
23
|
+
|
24
|
+
def langs(m, params)
|
25
|
+
output = ['Available languages for translate:']
|
26
|
+
s = []
|
27
|
+
@allowed.each_pair{|k,v| s << "#{v} (\2#{k}\2)"}
|
28
|
+
output << s.join(', ')
|
29
|
+
reply m.replyto, output
|
30
|
+
end
|
31
|
+
|
32
|
+
def auto_add(message, params)
|
33
|
+
return unless message.is_public?
|
34
|
+
if(@allowed_trans.include?("en_#{params[:lang]}") && @allowed_trans.include?("#{params[:lang]}_en"))
|
35
|
+
nick = Helpers.find_model(params[:nick], false)
|
36
|
+
if(nick && nick.channels.include?(message.target))
|
37
|
+
@watchers[message.target.pk] = {} unless @watchers.has_key?(message.target.pk)
|
38
|
+
@watchers[message.target.pk][nick.pk] = params[:lang] unless @watchers[message.target.pk].has_key?(nick.pk)
|
39
|
+
reply message.replyto, "#{params[:nick]} is now being tracked for auto translation"
|
40
|
+
else
|
41
|
+
reply message.replyto, "\2Error:\2 Failed to locate #{params[:nick]}"
|
42
|
+
end
|
43
|
+
else
|
44
|
+
reply message.replyt, "\2Error:\2 Unsupported bi-directional translation"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def auto_remove(message, params)
|
49
|
+
return unless message.is_public?
|
50
|
+
nick = Models::Nick.locate(params[:nick], false)
|
51
|
+
if(nick)
|
52
|
+
if(@watchers.has_key?(message.target.pk))
|
53
|
+
@watchers[message.target.pk].delete(nick.pk) if @watchers[message.target.pk].has_key?(nick.pk)
|
54
|
+
@watchers.delete(message.target.pk) if @watchers[message.target.pk].empty?
|
55
|
+
reply message.replyto, "#{params[:nick]} is no longer being tracked for auto translation"
|
56
|
+
else
|
57
|
+
reply message.replyto, "No one is currently being tracked"
|
58
|
+
end
|
59
|
+
else
|
60
|
+
reply message.replyto, "\2Error:\2 Failed to locate #{params[:nick]}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def translate(message, params)
|
65
|
+
begin
|
66
|
+
reply message.replyto, "\2Translation:\2 #{do_translation(params[:lang], params[:text])}"
|
67
|
+
rescue Object => boom
|
68
|
+
reply message.replyto, "\2Error:\2 #{boom}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def listener(message)
|
73
|
+
if(message.is_public? && @watchers.has_key?(message.target.pk))
|
74
|
+
if(@watchers[message.target.pk].has_key?(message.source.pk))
|
75
|
+
trans_message = do_translation("#{@watchers[message.target.pk][message.source.pk]}|en", message.message)
|
76
|
+
reply message.replyto, "\2Translation (#{message.source.nick}):\2 #{trans_message}" unless trans_message == message.message
|
77
|
+
elsif(message.message =~ /^(\S+[:, ])/)
|
78
|
+
message.message.slice!(0..$1.size)
|
79
|
+
Logger.info("Translate matched a followed nick: #{$1}")
|
80
|
+
nick = Helpers.find_model($1, false)
|
81
|
+
return unless nick.is_a?(Models::Nick)
|
82
|
+
if(@watchers[message.target.pk].has_key?(nick.pk))
|
83
|
+
reply message.replyto, "\2(#{do_translation("en|#{@watchers[message.target.pk][nick.pk]}", 'translation')})\2 #{do_translation("en|#{@watchers[message.target.pk][nick.pk]}", message.message)}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def do_translation(langs, text)
|
92
|
+
raise 'Unsupported language combination for translation' unless @allowed_trans.include?(langs.gsub(/\|/, '_'))
|
93
|
+
if(@cache.has_key?(langs) && @cache[langs].has_key?(text))
|
94
|
+
return @cache[langs][text]
|
95
|
+
end
|
96
|
+
headers = {'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7'}
|
97
|
+
url = URI.parse('http://babelfish.yahoo.com/translate_txt')
|
98
|
+
post = Net::HTTP::Post.new(url.path, headers)
|
99
|
+
post.set_form_data({
|
100
|
+
'ei' => 'UTF-8',
|
101
|
+
'doit' => 'done',
|
102
|
+
'fr' => 'bf-res',
|
103
|
+
'intl' => '1',
|
104
|
+
'tt' => 'urltext',
|
105
|
+
'trtext' => text,
|
106
|
+
'lp' => langs.gsub(/\|/, '_'),
|
107
|
+
'btnTrTxt' => 'Translate'
|
108
|
+
})
|
109
|
+
result = Net::HTTP.new(url.host, url.port).start do |http|
|
110
|
+
http.request(post)
|
111
|
+
end
|
112
|
+
if(result.is_a?(Net::HTTPSuccess))
|
113
|
+
content = result.body
|
114
|
+
if(content =~ /<div id="result">(.+?)<input/im)
|
115
|
+
tr = $1
|
116
|
+
tr.gsub!(/<.+?>/, '')
|
117
|
+
tr.gsub!(/[\r\n]/, ' ')
|
118
|
+
tr.gsub!(/\s+/, ' ')
|
119
|
+
if(text.length < 15)
|
120
|
+
@cache[langs] = {} unless @cache.has_key?(langs)
|
121
|
+
@cache[langs][text] = tr
|
122
|
+
end
|
123
|
+
return Helpers.convert_entities(tr).strip
|
124
|
+
else
|
125
|
+
raise 'Failed to locate translation'
|
126
|
+
end
|
127
|
+
else
|
128
|
+
raise "Failed to receive result from server"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,458 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'uri'
|
3
|
+
require 'mod_spox/messages/internal/TimerAdd'
|
4
|
+
require 'mod_spox/messages/internal/TimerRemove'
|
5
|
+
class Twitter < ModSpox::Plugin
|
6
|
+
|
7
|
+
def initialize(pipeline)
|
8
|
+
super
|
9
|
+
begin
|
10
|
+
require 'htmlentities'
|
11
|
+
rescue Object => boom
|
12
|
+
Logger.warn('Error: This plugin requires the HTMLEntities gem. Please install and reload plugin.')
|
13
|
+
raise Exceptions::BotException.new("Missing required HTMLEntities library")
|
14
|
+
end
|
15
|
+
begin
|
16
|
+
require 'twitter'
|
17
|
+
require 'json'
|
18
|
+
c = %q{
|
19
|
+
class ModClient < Object::Twitter::Client
|
20
|
+
def login
|
21
|
+
return @login
|
22
|
+
end
|
23
|
+
def login=(l)
|
24
|
+
@login = l
|
25
|
+
end
|
26
|
+
def password
|
27
|
+
return @password
|
28
|
+
end
|
29
|
+
def password=(p)
|
30
|
+
@password = p
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}
|
34
|
+
Twitter.class_eval(c)
|
35
|
+
ModClient.configure do |conf|
|
36
|
+
conf.user_agent = 'mod_spox twitter for twits'
|
37
|
+
conf.application_name = 'mod_spox IRC bot'
|
38
|
+
conf.application_version = "#{ModSpox.botversion} (#{ModSpox.botcodename})"
|
39
|
+
conf.application_url = 'http://rubyforge.org/projects/mod_spox'
|
40
|
+
conf.source = 'modspoxircbot'
|
41
|
+
end
|
42
|
+
rescue Object => boom
|
43
|
+
Logger.warn("Failed to load Twitter4R. Install gem to use Twitter plugin. (#{boom})")
|
44
|
+
raise Exceptions::BotException.new('Failed to locate required gem: Twitter4R')
|
45
|
+
end
|
46
|
+
twitter = Models::Group.find_or_create(:name => 'twitter')
|
47
|
+
admin = Models::Group.find_or_create(:name => 'admin')
|
48
|
+
add_sig(:sig => 'tweet (.+)', :method => :tweet, :group => twitter, :desc => 'Send a tweet', :params => [:message])
|
49
|
+
add_sig(:sig => 'twitter auth( (\S+) (\S+))?', :method => :auth, :group => admin, :desc => 'Set/view authentication information',
|
50
|
+
:params => [:info, :username, :password], :req => 'private')
|
51
|
+
add_sig(:sig => 'twitter search (.+)', :method => :search, :desc => 'Basic twitter search', :params => [:term])
|
52
|
+
add_sig(:sig => 'twitter asearch (.+)', :method => :advanced_search, :desc => 'Advanced search (http://apiwiki.twitter.com/Search-API-Documentation#Search)',
|
53
|
+
:params => [:term])
|
54
|
+
add_sig(:sig => 'twitter followers( \S+)?', :method => :followers, :desc => 'Show followers', :params => [:twit])
|
55
|
+
add_sig(:sig => 'twitter friends( \S+)?', :method => :friends, :desc => 'Show friends', :params => [:twit])
|
56
|
+
add_sig(:sig => 'twitter friend (\S+)', :method => :add_friend, :desc => 'Add a friend', :params => [:twit], :group => admin)
|
57
|
+
add_sig(:sig => 'twitter unfriend (\S+)', :method => :remove_friend, :desc => 'Remove a friend', :params => [:twit], :group => admin)
|
58
|
+
add_sig(:sig => 'twitter info', :method => :info, :desc => 'Show twitter info')
|
59
|
+
add_sig(:sig => 'twit (\S+) (.+)', :method => :twat, :group => twitter, :desc => 'Send a direct tweet to twit', :params => [:twit, :message])
|
60
|
+
add_sig(:sig => 'twit inbox', :method => :inbox, :group => twitter, :desc => 'Show inbox contents')
|
61
|
+
add_sig(:sig => 'twitter del (\d+)', :method => :inbox_del, :group => twitter, :desc => 'Delete direct message from twitter', :params => [:m_id])
|
62
|
+
add_sig(:sig => 'tweets del (\d+)', :method => :tweets_del, :group => twitter, :desc => 'Delete a status message from twitter', :params => [:m_id])
|
63
|
+
add_sig(:sig => 'tweets (\d+)', :method => :tweets, :desc => 'Get a given message or the current message', :params => [:m_id])
|
64
|
+
add_sig(:sig => 'autotweets ?(on|off)?', :method => :auto_tweets, :desc => 'Turn on/off auto tweet for a channel', :params => [:action],
|
65
|
+
:group => admin, :req => 'public')
|
66
|
+
add_sig(:sig => 'autotweets interval( \d+)?', :method => :auto_tweets_interval, :desc => 'Set/show interval for auto tweet checks',
|
67
|
+
:group => admin, :params => [:interval])
|
68
|
+
add_sig(:sig => 'autotweets burst( \d+)?', :method => :auto_tweets_burst, :desc => 'Set/show maximum number of tweets to display at once',
|
69
|
+
:group => admin, :params => [:burst])
|
70
|
+
add_sig(:sig => 'twitter alias (\S+) (\S+)', :method => :alias_user, :desc => 'Set alias for twitter account', :group => twitter, :params => [:twit, :irc])
|
71
|
+
add_sig(:sig => 'twitter aliases (\S+)', :method => :show_aliases, :desc => 'Show alias for twit', :params => [:twit])
|
72
|
+
add_sig(:sig => 'twitter dealias (\S+)', :method => :remove_alias, :desc => 'Remove alias for twit', :params => [:twit], :group => twitter)
|
73
|
+
@pipeline.hook(self, :get_timer, :Internal_TimerResponse)
|
74
|
+
@auth_info = Models::Setting.find_or_create(:name => 'twitter').value
|
75
|
+
@twitter = ModClient.new
|
76
|
+
@search_url = 'http://search.twitter.com/search.json'
|
77
|
+
@aliases = Models::Setting.find_or_create(:name => 'twitter_aliases').value
|
78
|
+
@aliases = {} if @aliases.nil?
|
79
|
+
@burst = Models::Setting.find_or_create(:name => 'twitter_burst').value
|
80
|
+
@burst = @burst.nil? ? 5 : @burst.to_i
|
81
|
+
unless(@auth_info.is_a?(Hash))
|
82
|
+
@auth_info = {:username => nil, :password => nil, :interval => 0, :channels => []}
|
83
|
+
else
|
84
|
+
connect if @twitter.authenticate?(@auth_info[:username], @auth_info[:password])
|
85
|
+
end
|
86
|
+
@last_check = Time.now
|
87
|
+
@lock = Mutex.new
|
88
|
+
@running = false
|
89
|
+
@timer = {:action => nil, :id => nil}
|
90
|
+
@friends = []
|
91
|
+
populate_friends
|
92
|
+
start_auto
|
93
|
+
end
|
94
|
+
|
95
|
+
def auto_tweets_burst(m, params)
|
96
|
+
if(params[:burst])
|
97
|
+
params[:burst] = params[:burst].to_i
|
98
|
+
if(params[:burst] == 0)
|
99
|
+
error m.replyto, 'Invalid value. Must supply a positive integer.'
|
100
|
+
else
|
101
|
+
@burst = params[:burst]
|
102
|
+
information m.replyto, "Updated maximum autotweet burst to: #{@burst}"
|
103
|
+
end
|
104
|
+
else
|
105
|
+
information m.replyto, "Maximum number of tweets to auto report: #{@burst}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def alias_user(m, params)
|
110
|
+
begin
|
111
|
+
raise "twit #{params[:twit]} is not in my friends list" unless @friends.include?(params[:twit])
|
112
|
+
raise "twit is already aliased to #{Models::Nick[@aliases[params[:twit].to_sym]].nick}" if @aliases.has_key?(params[:twit].to_sym)
|
113
|
+
nick = Helpers.find_model(params[:irc])
|
114
|
+
raise "failed to find nick #{params[:irc]}. is this a new user?" if nick.nil?
|
115
|
+
@aliases[params[:twit].to_sym] = nick.pk
|
116
|
+
save_aliases
|
117
|
+
information m.replyto, "Nick #{params[:irc]} is now aliased to twit #{params[:twit]}"
|
118
|
+
rescue Object => boom
|
119
|
+
error m.replyto, "Failed to alias user: #{boom}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def save_aliases
|
124
|
+
t = Models::Setting.find_or_create(:name => 'twitter_aliases')
|
125
|
+
t.value = @aliases
|
126
|
+
t.save
|
127
|
+
end
|
128
|
+
|
129
|
+
def show_aliases(m, params)
|
130
|
+
begin
|
131
|
+
raise "twit #{params[:twit]} has no alias" unless @aliases.has_key?(params[:twit].to_sym)
|
132
|
+
information m.replyto, "Twit #{params[:twit]} is aliased to: #{Models::Nick[@aliases[params[:twit].to_sym]].nick}"
|
133
|
+
rescue Object => boom
|
134
|
+
error m.replyto, "Failed to find alias. Reason: #{boom}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def remove_alias(m, params)
|
139
|
+
begin
|
140
|
+
raise "twit #{params[:twit]} has no alias" unless @aliases.has_key?(params[:twit].to_sym)
|
141
|
+
@aliases.delete(params[:twit].to_sym)
|
142
|
+
save_aliases
|
143
|
+
information m.replyto, "Twit #{params[:twit]} is no longer aliased"
|
144
|
+
rescue Object => boom
|
145
|
+
error m.replyto, "Failed to remove alias: #{boom}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def search(m, params)
|
150
|
+
url = URI.escape("#{@search_url}?rpp=1&q=#{params[:term]}")
|
151
|
+
reply m.replyto, do_search(url, params[:term])
|
152
|
+
end
|
153
|
+
|
154
|
+
def advanced_search(m, params)
|
155
|
+
opt = {:lang => nil, :rpp => 1, :page => 1, :since_id => nil}
|
156
|
+
term = params[:term]
|
157
|
+
opt.keys.each do |sym|
|
158
|
+
if(term =~ /\b#{sym.to_s}:(\S+)\b/)
|
159
|
+
opt[sym] = $1
|
160
|
+
term.sub!(/#{sym.to_s}:\S+/, '')
|
161
|
+
end
|
162
|
+
end
|
163
|
+
opt[:rpp] = 5 if opt[:rpp].to_i > 5
|
164
|
+
opt[:rpp] = 1 if opt[:rpp].to_i < 1
|
165
|
+
term.gsub!(/\s{2,}/, ' ')
|
166
|
+
url = URI.escape("#{@search_url}?q=#{term}&#{opt.to_a.map{|a| "#{a[0]}=#{a[1]}"}.join('&')}")
|
167
|
+
reply m.replyto, do_search(url, term)
|
168
|
+
end
|
169
|
+
|
170
|
+
def do_search(url, term)
|
171
|
+
begin
|
172
|
+
buf = open(url, 'UserAgent' => 'mod_spox IRC bot').read
|
173
|
+
result = JSON.parse(buf)
|
174
|
+
output = ["Twitter match for: \2#{term}:\2"]
|
175
|
+
result['results'].each do |item|
|
176
|
+
t = Time.parse(item['created_at'])
|
177
|
+
output << "[#{t.strftime("%Y/%m/%d-%H:%M:%S")}] <#{item['from_user']}> #{Helpers.convert_entities(item['text'])}"
|
178
|
+
end
|
179
|
+
if(output.size < 2)
|
180
|
+
output = "\2Error:\2 No results found for term: #{term}"
|
181
|
+
end
|
182
|
+
return output
|
183
|
+
rescue Object => boom
|
184
|
+
return "\2Error:\2 Failed to receive search results (over quota?)"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def inbox(m, params)
|
189
|
+
msgs = @twitter.messages(:received)
|
190
|
+
reply m.replyto, "\2Twitter INBOX\2 Messages in inbox: #{msgs.size} (only last 5 displayed)"
|
191
|
+
msgs.slice(0..5).each do | msg |
|
192
|
+
reply m.replyto, "\2#{msg.sender.screen_name}:\2 [#{msg.id}] #{Helpers.convert_entities(msg.text)}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def inbox_del(m, params)
|
197
|
+
begin
|
198
|
+
@twitter.message(:delete, params[:m_id])
|
199
|
+
information m.replyto, "message with ID: #{params[:m_id]} has been deleted"
|
200
|
+
rescue Object => boom
|
201
|
+
warning m.replyto, "failed to delete message with ID: #{params[:m_id]}"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def tweets_del(m, params)
|
206
|
+
begin
|
207
|
+
@twitter.status(:delete, params[:m_id])
|
208
|
+
information m.replyto, "message with ID: #{params[:m_id]} has been deleted"
|
209
|
+
rescue Object => boom
|
210
|
+
warning m.replyto, "failed to delete status message with ID: #{params[:m_id]}"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def info(m, params)
|
215
|
+
unless(@auth_info[:username].nil?)
|
216
|
+
information m.replyto, "http://twitter.com/#{@auth_info[:username]}"
|
217
|
+
else
|
218
|
+
warning m.replyto, 'currently not configured'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def auto_tweets_interval(m, params)
|
223
|
+
if(params[:interval])
|
224
|
+
int = params[:interval].strip.to_i
|
225
|
+
@auth_info[:interval] = int
|
226
|
+
save_info
|
227
|
+
update_auto
|
228
|
+
information m.replyto, "auto tweet interval updated to: #{int > 0 ? int : 'stopped'}"
|
229
|
+
else
|
230
|
+
information m.replyto, "auto tweet interval is: #{@auth_info[:interval] > 0 ? "#{@auth_info[:interval]} seconds" : 'stopped'}"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def auto_tweets(m, params)
|
235
|
+
if(params[:action])
|
236
|
+
on = @auth_info[:channels].include?(m.target.id)
|
237
|
+
if(params[:action] == 'on')
|
238
|
+
if(on)
|
239
|
+
warning m.replyto, 'this channel is already enabled for auto tweets'
|
240
|
+
else
|
241
|
+
@auth_info[:channels] << m.target.id
|
242
|
+
save_info
|
243
|
+
update_auto
|
244
|
+
information m.replyto, 'auto tweets are now enabled for this channel'
|
245
|
+
end
|
246
|
+
else
|
247
|
+
if(on)
|
248
|
+
@auth_info[:channels].delete(m.target.id)
|
249
|
+
save_info
|
250
|
+
update_auto
|
251
|
+
information m.replyto, 'auto tweets are now disabled for this channel'
|
252
|
+
else
|
253
|
+
warning m.replyto, 'this channel is not currently enabled for auto tweets'
|
254
|
+
end
|
255
|
+
end
|
256
|
+
else
|
257
|
+
information m.replyto, "auto tweets currently enabled in: #{@auth_info[:channels].size > 0 ? @auth_info[:channels].map{|i| Models::Channel[i].name}.join(', ') : 'not enabled'}"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def auth(m, params)
|
262
|
+
if(params[:info])
|
263
|
+
begin
|
264
|
+
@auth_info[:username] = params[:username]
|
265
|
+
@auth_info[:password] = params[:password]
|
266
|
+
@twitter.authenticate?(params[:username], params[:password])
|
267
|
+
save_info
|
268
|
+
information m.replyto, 'Authentication information has been updated'
|
269
|
+
rescue Object => boom
|
270
|
+
error m.replyto, "Failed to save authentication information: #{boom}"
|
271
|
+
end
|
272
|
+
else
|
273
|
+
information m.replyto, "username -> #{@auth_info[:username].nil? ? 'unset' : @auth_info[:username]} password -> #{@auth_info[:password].nil? ? 'unset' : @auth_info[:password]}"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def tweet(m, params)
|
278
|
+
begin
|
279
|
+
@twitter.status(:post, params[:message])
|
280
|
+
information m.replyto, 'tweet has been sent'
|
281
|
+
rescue Object => boom
|
282
|
+
error m.replyto, "failed to send tweet. (#{boom})"
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def twat(m, params)
|
287
|
+
begin
|
288
|
+
user = @twitter.user(params[:twit])
|
289
|
+
@twitter.message(:post, params[:message], user)
|
290
|
+
information m.replyto, 'tweet has been sent'
|
291
|
+
rescue Object => boom
|
292
|
+
error m.replyto, "failed to send tweet. (#{boom})"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def followers(m, params)
|
297
|
+
begin
|
298
|
+
fs = @twitter.my(:followers)
|
299
|
+
if(fs.size > 0)
|
300
|
+
reply m.replyto, "\2Followers:\2 #{fs.map{|u| u.screen_name}.join(', ')}"
|
301
|
+
else
|
302
|
+
warning m.replyto, 'no followers found'
|
303
|
+
end
|
304
|
+
rescue Object => boom
|
305
|
+
error m.replyto, "failed to locate followers list. (#{boom})"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def friends(m, params)
|
310
|
+
if(@friends.size > 0)
|
311
|
+
reply m.replyto, "\2Friends:\2 #{@friends.join(', ')}"
|
312
|
+
else
|
313
|
+
warning m.replyto, 'no friends found'
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def add_friend(m, params)
|
318
|
+
begin
|
319
|
+
user = @twitter.user(params[:twit])
|
320
|
+
unless(@twitter.my(:friends).include?(user))
|
321
|
+
@twitter.friend(:add, user)
|
322
|
+
information m.replyto, "added new friend: #{params[:twit]}"
|
323
|
+
@friends << params[:twit]
|
324
|
+
else
|
325
|
+
warning m.replyto, "#{params[:twit]} is already in friend list"
|
326
|
+
end
|
327
|
+
rescue Object => boom
|
328
|
+
error m.replyto, "failed to add friend #{params[:twit]}. (#{boom})"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def remove_friend(m, params)
|
333
|
+
begin
|
334
|
+
user = @twitter.user(params[:twit])
|
335
|
+
if(@twitter.my(:friends).map{|u|u.screen_name}.include?(user.screen_name))
|
336
|
+
@twitter.friend(:remove, user)
|
337
|
+
information m.replyto, "removed user from friend list: #{params[:twit]}"
|
338
|
+
@friends.delete(params[:twit])
|
339
|
+
else
|
340
|
+
warning m.replyto, "#{params[:twit]} is not in friend list"
|
341
|
+
end
|
342
|
+
rescue Object => boom
|
343
|
+
error m.replyto, "failed to remove friend #{params[:twit]}. (#{boom})"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def tweets(m, params)
|
348
|
+
begin
|
349
|
+
msg = @twitter.status(:get, params[:m_id])
|
350
|
+
if(msg)
|
351
|
+
reply m.replyto, "\2Tweet:\2 [#{msg.created_at.strftime("%Y/%m/%d-%H:%M:%S")}] <#{screen_name(msg.user.screen_name)}> #{Helpers.convert_entities(msg.text)}"
|
352
|
+
else
|
353
|
+
warning m.replyto, "failed to find message with ID: #{params[:m_id].strip}"
|
354
|
+
end
|
355
|
+
rescue Object => boom
|
356
|
+
error m.replyto, "error encountered while attempting to fetch message. (#{boom})"
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
private
|
361
|
+
|
362
|
+
def populate_friends
|
363
|
+
return unless @lock.try_lock
|
364
|
+
begin
|
365
|
+
fs = @twitter.my(:friends)
|
366
|
+
@friends = []
|
367
|
+
if(fs.size > 0)
|
368
|
+
@friends = fs.map{|u| u.screen_name}
|
369
|
+
end
|
370
|
+
rescue Object => boom
|
371
|
+
Logger.info("Failed to populate friends: #{boom}")
|
372
|
+
@pipeline << Messages::Internal::TimerAdd.new(self, 200, nil, true){ populate_friends }
|
373
|
+
ensure
|
374
|
+
@lock.unlock
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
def screen_name(n)
|
379
|
+
return @aliases.has_key?(n.to_sym) ? Models::Nick[@aliases[n.to_sym]].nick : n
|
380
|
+
end
|
381
|
+
|
382
|
+
def replace_names(s)
|
383
|
+
s.scan(/@\S+/).each do |n|
|
384
|
+
n.slice!(0)
|
385
|
+
s.gsub!("@#{n}", "@#{screen_name(n)}")
|
386
|
+
end
|
387
|
+
return s
|
388
|
+
end
|
389
|
+
|
390
|
+
def check_timeline
|
391
|
+
if(@auth_info[:channels].size < 1 || @auth_info[:interval].to_i < 1)
|
392
|
+
Logger.warn('Twitter has no channels to send information to')
|
393
|
+
else
|
394
|
+
begin
|
395
|
+
things = []
|
396
|
+
@twitter.my(:friends).each do |f|
|
397
|
+
@twitter.timeline_for(:friend, :id => f.screen_name, :since => @last_check) do |status|
|
398
|
+
next if status.created_at < @last_check
|
399
|
+
if(Helpers.convert_entities(status.text) =~ /^@(\S+)/)
|
400
|
+
next unless @twitter.my(:friends).map{|f|f.screen_name}.include?($1) || $1 == @twitter.login
|
401
|
+
end
|
402
|
+
things << "[#{status.created_at.strftime("%H:%M:%S")}] <#{screen_name(status.user.screen_name)}> #{Helpers.convert_entities(replace_names(status.text))}"
|
403
|
+
end
|
404
|
+
end
|
405
|
+
@twitter.timeline_for(:me, :since => @last_check) do |status|
|
406
|
+
next if status.created_at < @last_check
|
407
|
+
things << "[#{status.created_at.strftime("%H:%M:%S")}] <#{screen_name(status.user.screen_name)}> #{Helpers.convert_entities(replace_names(status.text))}"
|
408
|
+
end
|
409
|
+
unless(things.empty?)
|
410
|
+
things.uniq!
|
411
|
+
things.sort!
|
412
|
+
things = things[-@burst,@burst] if things.size > @burst
|
413
|
+
things.each do |status|
|
414
|
+
@auth_info[:channels].each{|i| reply Models::Channel[i], "\2AutoTweet:\2 #{status}"}
|
415
|
+
end
|
416
|
+
end
|
417
|
+
@last_check = Time.now
|
418
|
+
rescue Object => boom
|
419
|
+
Logger.warn("Twitter encountered an error during autotweets check: #{boom}")
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
def save_info
|
425
|
+
i = Models::Setting.find_or_create(:name => 'twitter')
|
426
|
+
i.value = @auth_info
|
427
|
+
i.save
|
428
|
+
end
|
429
|
+
|
430
|
+
def connect
|
431
|
+
@twitter.login = @auth_info[:username]
|
432
|
+
@twitter.password = @auth_info[:password]
|
433
|
+
end
|
434
|
+
|
435
|
+
def get_timer(m)
|
436
|
+
if(m.id == @timer[:id])
|
437
|
+
@timer[:action] = m.action_added? ? m.action : nil
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
def update_auto
|
442
|
+
if(@auth_info[:interval] > 0 && !@auth_info[:channels].empty?)
|
443
|
+
@pipeline << Messages::Internal::TimerRemove.new(@timer[:action]) if @timer[:action].nil?
|
444
|
+
start_auto
|
445
|
+
else
|
446
|
+
@pipeline << Messages::Internal::TimerRemove.new(@timer[:action]) unless @timer[:action].nil?
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
def start_auto
|
451
|
+
if(@auth_info[:interval] > 0 && @timer[:action].nil?)
|
452
|
+
m = Messages::Internal::TimerAdd.new(self, @auth_info[:interval].to_i){ check_timeline }
|
453
|
+
@timer[:id] = m.id
|
454
|
+
@pipeline << m
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
end
|