]>
jfr.im git - irc/rizon/acid.git/blob - pyva/src/main/python/internets/internets.py
1 #!/usr/bin/python pseudoserver.py
3 # module for pypseudoserver
4 # written by ElChE <elche@rizon.net>, martin <martin@rizon.net>
11 from istring
import istring
12 from datetime
import datetime
13 from decimal
import Decimal
, InvalidOperation
19 import mythreading
as threading
20 from pseudoclient
import sys_antiflood
, sys_auth
, sys_channels
, sys_log
, sys_options
, cmd_manager
, inviteable
22 import cmd_admin
, cmd_user
, erepparser
, internets_users
23 from api
import bing
, calc
, google
, imdb
, ipinfo
, lastfm
, quotes
, urbandictionary
, urls
, weather
, wolfram
, words
24 from internets_utils
import *
28 inviteable
. InviteablePseudoclient
32 def bind_function ( self
, function
):
33 func
= types
. MethodType ( function
, self
, internets
)
34 setattr ( internets
, function
.__ name
__ , func
)
37 def bind_admin_commands ( self
):
38 list = cmd_admin
. get_commands ()
39 self
. commands_admin
= []
42 self
. commands_admin
. append (
46 'callback' : self
. bind_function ( list [ command
][ 0 ]),
47 'usage' : list [ command
][ 1 ]
53 AcidPlugin
.__ init
__ ( self
)
55 self
. name
= "internets"
56 self
. log
= logging
. getLogger ( __name__
)
59 self
. nick
= istring ( self
. config
. get ( 'internets' , 'nick' ))
60 except Exception , err
:
61 self
. log
. exception ( "Error reading 'internets:nick' configuration option: %s " % err
)
65 self
. chan
= istring ( self
. config
. get ( 'internets' , 'channel' ))
66 except Exception , err
:
67 self
. log
. exception ( "Error reading 'internets:channel' configuration option: %s " % err
)
70 self
. bind_admin_commands ()
72 def start_threads ( self
):
77 self
. antiflood
. start ()
81 AcidPlugin
. start ( self
)
82 inviteable
. InviteablePseudoclient
. start ( self
)
84 self
. options
= sys_options
. OptionManager ( self
)
85 self
. elog
= sys_log
. LogManager ( self
)
86 self
. commands_user
= cmd_user
. UserCommandManager ()
87 except Exception , err
:
88 self
. log
. exception ( 'Error initializing core subsystems for internets module ( %s )' % err
)
91 self
. elog
. debug ( 'Started core subsystems.' )
94 self
. channels
= sys_channels
. ChannelManager ( self
)
95 self
. users
= internets_users
. InternetsUserManager ( self
)
96 self
. auth
= sys_auth
. AuthManager ( self
)
97 self
. antiflood
= sys_antiflood
. AntiFloodManager ( self
)
98 except Exception , err
:
99 self
. log
. exception ( 'Error initializing subsystems for internets module ( %s )' % err
)
102 self
. elog
. debug ( 'Started subsystems.' )
106 self
. bing
= bing
. Bing ( self
. config
. get ( 'internets' , 'bing_appid' ))
107 except Exception , err
:
108 self
. log
. exception ( 'Error initializing internets bing API ( %s )' % err
)
109 self
. nsp
= calc
. NumericStringParser ()
110 self
. google
= google
. Google ()
111 self
. imdb
= imdb
. Imdb ()
112 self
. ipinfo
= ipinfo
. IpInfo ( self
. config
. get ( 'internets' , 'key_ipinfodb' ))
113 self
. lastfm
= lastfm
. LastFm ( self
. config
. get ( 'internets' , 'key_lastfm' ))
114 self
. quotes
= quotes
. Quotes ( self
. config
. get ( 'internets' , 'key_fml' ))
115 self
. urbandictionary
= urbandictionary
. UrbanDictionary ()
116 self
. urls
= urls
. Urls ( self
. config
. get ( 'internets' , 'user_bitly' ), self
. config
. get ( 'internets' , 'key_bitly' ))
117 self
. weather
= weather
. Weather ( self
. config
. get ( 'internets' , 'key_openweathermap' ))
118 self
. wolfram
= wolfram
. Wolfram ( self
. config
. get ( 'internets' , 'key_wolframalpha' ))
119 self
. wordnik
= words
. Words ( self
. config
. get ( 'internets' , 'key_wordnik' ))
120 except Exception , err
:
121 self
. log
. exception ( 'Error initializing internets module ( %s )' % err
)
124 for channel
in self
. channels
. list_valid ():
125 self
. join ( channel
. name
)
127 self
. log
. debug ( 'Joined channels.' )
131 except Exception , err
:
132 self
. log
. exception ( 'Error starting threads for internets module ( %s )' % err
)
135 self
. initialized
= True
137 self
. elog
. debug ( 'Started threads.' )
141 for channel
in self
. channels
. list_valid ():
142 self
. join ( channel
. name
)
144 self
. log
. debug ( 'Joined channels.' )
147 if hasattr ( self
, 'antiflood' ):
148 self
. antiflood
. stop ()
150 if hasattr ( self
, 'auth' ):
153 if hasattr ( self
, 'users' ):
158 self
. users
. db_close ()
160 if hasattr ( self
, 'channels' ):
162 self
. channels
. force ()
165 self
. channels
. db_close ()
167 if hasattr ( self
, 'options' ):
172 self
. options
. db_close ()
174 def join ( self
, channel
):
175 me
= self
. inter
. findUser ( self
. nick
)
178 def part ( self
, channel
):
179 me
= self
. inter
. findUser ( self
. nick
)
182 def errormsg ( self
, target
, message
):
183 self
. msg ( target
, '@b@c4Error:@o %s ' % message
)
185 def usagemsg ( self
, target
, description
, examples
):
186 message
= '@errsep @bUsage@b %s @errsep' % description
189 message
+= ' @bExamples@b %s @errsep' % ', ' . join ( examples
)
191 self
. msg ( target
, message
)
193 def msg ( self
, target
, message
):
195 self
. inter
. privmsg ( self
. nick
, target
, format_ascii_irc ( message
))
197 def multimsg ( self
, target
, count
, intro
, separator
, pieces
, outro
= '' ):
200 while cur
< len ( pieces
):
201 self
. msg ( target
, intro
+ separator
. join ( pieces
[ cur
: cur
+ count
]) + outro
)
204 def notice ( self
, target
, message
):
206 self
. inter
. notice ( self
. nick
, target
, format_ascii_irc ( message
))
208 def execute ( self
, manager
, command
, argument
, channel
, sender
, userinfo
):
209 full_command
= ' %s%s ' % ( command
, ' %s ' % argument
if len ( argument
) else '' )
210 cmd
= manager
. get_command ( command
)
213 self
. msg ( channel
, manager
. invalid
)
214 self
. elog
. debug ( 'Parsed command @b %s @b: invalid command.' % full_command
)
217 if self
. users
. is_banned ( sender
) or self
. antiflood
. check_user ( sender
, command
, argument
):
218 user
= self
. users
[ sender
]
219 message
= 'You were banned by @b %s @b.' % user
. ban_source
221 if user
. ban_reason
!= None :
222 message
+= ' Reason: @b %s @b.' % user
. ban_reason
224 if user
. ban_expiry
!= None :
225 message
+= ' Expires: @b %s @b.' % datetime
. fromtimestamp ( user
. ban_expiry
)
227 self
. notice ( sender
, message
)
228 self
. elog
. debug ( 'Parsed command @b %s @b: user is banned.' % full_command
)
231 self
. elog
. command ( ' %s%s > %s ' % ( sender
, ': %s ' % channel
if channel
!= sender
else '' , full_command
))
233 parser
= erepparser
. ErepublikParser ( add_help_option
= False , option_class
= erepparser
. ErepublikParserOption
)
237 parser
. add_option ( '-?' , '--help' , action
= 'store_true' )
239 for cmd_arg
in cmd_args
:
240 parser
. add_option ( cmd_arg
[ 1 ], '--' + cmd_arg
[ 0 ], ** cmd_arg
[ 3 ])
243 ( popts
, pargs
) = parser
. parse_args ( args
= argument
. split ( ' ' ))
244 except erepparser
. ErepublikParserError
, err
:
245 self
. msg ( channel
, str ( err
)) #TODO: Avoid str, use unicode.
247 self
. elog
. debug ( 'Parsed command @b %s @b: invalid options.' % full_command
)
250 if popts
. help == True :
251 manager
. commands
[ 'help' ][ 0 ]( self
, manager
, {}, command
, channel
, sender
)
253 self
. elog
. debug ( 'Parsed command @b %s @b: help intercepted.' % full_command
)
257 larg
= ' ' . join ( pargs
). strip ()
260 for cmd_arg
in cmd_args
:
261 parg
= getattr ( popts
, cmd_arg
[ 0 ])
264 if len ( cmd_arg
) <= 4 or not ( cmd_arg
[ 4 ] & cmd_manager
. ARG_OFFLINE
):
267 if len ( cmd_arg
) > 4 and ( cmd_arg
[ 4 ] & cmd_manager
. ARG_YES
) and larg
== '' :
268 self
. msg ( channel
, 'Error: %s option requires an argument.' % cmd_arg
[ 1 ])
270 self
. elog
. debug ( 'Parsed command @b %s @b: option constraint was broken.' % full_command
)
273 opt_dict
[ cmd_arg
[ 0 ]] = parg
274 elif len ( cmd_arg
) > 4 and ( cmd_arg
[ 4 ] & cmd_manager
. ARG_OFFLINE
and cmd_arg
[ 4 ] & cmd_manager
. ARG_OFFLINE_REQ
):
277 if not self
. online
and (( len ( pargs
) > 0 and not ( cmd_type
& cmd_manager
. ARG_OFFLINE
)) or not is_offline
):
278 self
. notice ( sender
, 'The eRepublik API is offline. Please retry later.' )
280 self
. elog
. debug ( 'Parsed command @b %s @b: offline.' % full_command
)
283 if ( cmd_type
& cmd_manager
. ARG_YES
) and ( larg
== None or larg
== '' ):
284 self
. notice ( sender
, '@bUsage@b: %s @b %s @b' % ( command
, cmd
[ 4 ] if len ( cmd
) > 4 else 'argument' ))
287 cmd
[ 0 ]( self
, manager
, opt_dict
, larg
, channel
, sender
, userinfo
)
289 tb
= traceback
. extract_tb ( sys
. exc_info ()[ 2 ])
293 length
= len ( entry
[ 2 ])
298 self
. elog
. exception ( ' %s%s > @b %s @b: %s ' % ( sender
, ': %s ' % channel
if channel
!= sender
else '' , full_command
, e
))
299 self
. log
. exception ( "internets error!" )
302 self
. elog
. traceback ( '@b %- *s@b : %d %s ' % ( longest
, entry
[ 2 ], entry
[ 1 ], entry
[ 3 ]))
304 self
. msg ( channel
, 'An exception occurred and has been reported to the developers. If this error persists please do not use the faulty command until it has been fixed.' )
307 self
. elog
. debug ( 'Parsed command @b %s @b: execution terminated.' % full_command
)
309 def onChanModes ( self
, prefix
, channel
, modes
):
310 if not self
. initialized
:
313 if not modes
== '-z' :
316 if channel
in self
. channels
:
317 self
. channels
. remove ( channel
)
318 self
. elog
. request ( 'Channel @b %s @b was dropped. Deleting it.' % channel
)
320 def getCommands ( self
):
321 return self
. commands_admin
323 def get_location ( self
, opts
, arg
, channel
, sender
):
335 location
= self
. users
. get ( nick
, 'location' )
339 self
. msg ( channel
, 'No location found linked to nick %s .' % arg
)
341 self
. msg ( channel
, 'No location found linked to your nick. To link one type: @b.register_location <location>@b' )