p = (Plugin) con.newInstance();
p.name = name;
p.loader = cl;
- p.start();
+ try
+ {
+ p.start();
+ }
+ catch (Exception ex)
+ {
+ plugins.remove(p);
+ throw ex;
+ }
return p;
}
key_fml: xxx
key_wolframalpha: xxx
key_steam: xxx
+key_google: xxx
[limitserv]
nick: Limitserv
-Subproject commit e2d4ad88b2d45dbf8351082d458dff8f35e775a4
+Subproject commit 7af06c821c6ba0e8aa4645a3180180b879576dd9
pyva.init();
+ try
+ {
+ for (String plugin : conf.plugins)
+ loadPyvaPlugin(plugin);
+ }
+ catch (Exception ex)
+ {
+ pyva.stop();
+ throw ex;
+ }
+
e = new PyvaEvent();
- for (String plugin : conf.plugins)
- loadPyvaPlugin(plugin);
-
t = new GCTimer();
t.start();
}
class StdOutWriter(object):
def write(self, what):
- # print is Python keyword, so call println with what.strip() instead of print
- javasys.out.println(what.rstrip())
+ # print is a Python keyword
+ javasys.out['print'](what)
class StdErrWriter(object):
def write(self, what):
- javasys.err.println(what.rstrip())
+ javasys.err['print'](what)
sys.stdout = StdOutWriter()
sys.stderr = StdErrWriter()
from operator import itemgetter #for sort
from collections import defaultdict
import time
+import re
from pyva import *
import logging
Acidictive.privmsg(self.client, target, "END OF VLIST (%d results)" % count)
return True
+
+ # Version regex check link to see what it does:
+ # http://regexper.com/#%28%28%3F%3A\%28%3Fv%3F\d%2B\.[^\s]%2B\%29%3F%29|%28%3F%3AClient%3A\d%2B%3A\d%2B%29%29
+ versionRegex = re.compile("\(?v?(\d+\.[\d\.\-A-z]+)\)?|(Client:\d+:\d+)")
+ nameRegex = re.compile("([http://]*[\.\w+]+)")
+ # regex to strip control codes + colour codes from messages.
+ controlRegex = re.compile(u'([\u0000-\u0002\u0004-\u001F]|\u0003\d{1,2}(?:,\d{1,2}){0,1})')
+
+ def cmd_ctcpCurrentVersionList(self, source, target, pieces):
+ hasLimit = False
+ showVersions = False
+ limit = 25
+
+ for piece in pieces:
+ if hasLimit == False:
+ try:
+ limit = int(piece)
+ hasLimit = True
+ continue
+ except ValueError:
+ limit = 25
+ if showVersions == False and piece.lower() == "+versions":
+ showVersions = True
+
+ version_list = [];
+
+ def compare(item1, item2):
+ return item2['count'] - item1['count']
+
+ def select(list, key, value, newItem):
+ for item in list:
+ if item[key] == value:
+ return item
+ else:
+ list.append(newItem)
+ return newItem
+
+ for user in User.getUsersC():
+ try:
+ cv = self.controlRegex.sub("", user['version'])
+ clientVersion = self.versionRegex.search(cv)
+ clientName = nameRegex.search(cv)
+ try:
+ clientName = clientName.group(0)
+ except:
+ continue
+ item = select(version_list, 'name', clientName, { 'name': clientName, 'count': 0, 'versions': [] })
+ item['count'] += 1
+ if clientVersion.group(1) != None:
+ v = clientVersion.group(1)
+ version = select(item['versions'], 'version', v, { 'version': v, 'count': 0 })
+ version['count'] += 1
+ except AttributeError:
+ continue
+
+ version_list.sort(cmp=compare)
+
+ counter = 0
+
+ for item in version_list:
+ Acidictive.privmsg(self.client, target, u"%s [%s %s]" % (item['name'], item['count'], 'time' if item['count'] == 1 else 'times'))
+ if showVersions:
+ item['versions'].sort(cmp=compare)
+ for version in item['versions']:
+ Acidictive.privmsg(self.client, target, u" %s [%s %s]" % (version['version'], version['count'], 'time' if version['count'] == 1 else 'times'))
+
+ counter += 1
+ if counter >= limit:
+ return
## End Command hooks
'permission': 'v',
'callback': self.cmd_ctcpVersionList,
'usage': "{top|search} [num|searchstring] - shows the top client version replies or searches them. Defaults to showing top"}),
+ ('cvlist', {
+ 'permission': 'v',
+ 'callback': self.cmd_ctcpCurrentVersionList,
+ 'usage': "[limit] [+versions] - Shows the client types, and their version numbers (when +versions is provided as argument), currently online. Default limit is 25."}),
)
from utils import unescape
class Google(object):
- def __init__(self):
- pass
-
- # Google shutdown their iGoogle "API",
- #def calc(self, expr):
- # url = 'http://www.google.com/ig/calculator?'
- # url += urlencode({'q': expr})
- # page = HtmlFeed(url) #, fake_ua=True)
- # text = page.html()
- # # Convert to valid JSON: {foo: "1"} -> {"foo" : "1"},
- # # {"foo": "\x25"} -> {"foo": "\u0025"}
- # result = re.sub("([a-z]+):", '"\\1" :', text)
- # # XXX: HACK; using two substitutes instead of one, but I can't into regex
- # result = re.sub('\\\\x([0-9a-f]{2})', '\\u00\\1', result)
- # result = re.sub('\\\\x([0-9a-f]{1})', '\\u000\\1', result)
- #
- # result = unicode(result, 'unicode_escape')
- # result = unescape(result)
- # # Special case: fractions; those are <sup></sup> unicode-slash <sub></sub>
- # result = re.sub(u'<sup>([^<]*)</sup>\u2044<sub>([^<]*)</sub>', ' \\1/\\2', result)
- # # Also un-html-ify <sup>/</sup> because google doesn't send proper plaintext
- # result = re.sub('<sup>([^<]*)</sup>', '^\\1', result)
- # # Same with <sub>.
- # result = re.sub('<sub>([^<]*)</sub>', '_\\1', result)
- # result = json.loads(result.encode('utf-8'))
- # return result
+ def __init__(self, api_key):
+ self.api_key = api_key
def search(self, query, userip=None):
url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&'
json = get_json(url)
return json
- def yt_search(self, query, num=1):
- url = 'https://gdata.youtube.com/feeds/api/videos?v=2&max-results=5&'
- url += urlencode({'q': query})
- xml = XmlFeed(url)
- entry = xml.elements('/feed/entry[%d]' % num)
- if not entry:
+ def yt_search(self, query, num=0, userip=None):
+ url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&order=relevance&type=video&maxResults=5&'
+ parameters = {'q': query, 'key': self.api_key}
+ if userip:
+ parameters['userip'] = userip
+
+ url += urlencode(parameters)
+ js = get_json(url)
+ if not js['items']:
return None
- v = entry[0]
+ video_info = js['items'][num]
+ url = 'https://www.googleapis.com/youtube/v3/videos?&part=contentDetails,statistics&'
+ parameters = {'id': video_info['id']['videoId'], 'key': self.api_key}
+ if userip:
+ parameters['userip'] = userip
+
+ url += urlencode(parameters)
+ js = get_json(url)
+ video_details = js['items'][0]
+ m = re.search(r'P((?:\d)+D)?T?(\d+H)?(\d+M)?(\d+S)?', video_details['contentDetails']['duration'])
+ days, hours, minutes, seconds = map(lambda x: int(x[:-1]) if x else 0, m.groups())
+ stats = video_details['statistics']
+
return {
- 'title': v.text('title'),
- 'duration': v.int('media:group/yt:duration/@seconds'),
- 'uploaded': v.text('media:group/yt:uploaded'),
- 'id': v.text('media:group/yt:videoid'),
- 'rating': v.decimal('gd:rating/@average'),
- 'rate_count': v.int('gd:rating/@numRaters'),
- 'favorite_count': v.int('yt:statistics/@favoriteCount'),
- 'view_count': v.int('yt:statistics/@viewCount'),
- 'liked': v.int('yt:rating/@numLikes'),
- 'disliked': v.int('yt:rating/@numDislikes')
+ 'title': video_info['snippet']['title'],
+ 'duration': 86400 * days + 3600 * hours + 60 * minutes + seconds,
+ 'uploaded': video_info['snippet']['publishedAt'],
+ 'id': video_info['id']['videoId'],
+ 'favorite_count': int(stats['favoriteCount']),
+ 'view_count': int(stats['viewCount']),
+ 'liked': int(stats['likeCount']),
+ 'disliked': int(stats['dislikeCount'])
}
def command_google_search(self, manager, opts, arg, channel, sender, userinfo):
try:
- result = self.google.search(arg, userinfo['ip'] if userinfo['ip'] != '0' else '255.255.255.255')
+ result = self.google.search(arg, userinfo['ip'] if userinfo['ip'] != '0' else None)
except FeedError, e:
self.errormsg(channel, e.msg)
return
def command_google_image_search(self, manager, opts, arg, channel, sender, userinfo):
try:
- result = self.google.image_search(arg, userinfo['ip'] if userinfo['ip'] != '0' else '255.255.255.255')
+ result = self.google.image_search(arg, userinfo['ip'] if userinfo['ip'] != '0' else None)
except FeedError, e:
self.errormsg(channel, e.msg)
return
def command_youtube_search(self, manager, opts, arg, channel, sender, userinfo):
try:
- res = self.google.yt_search(arg)
+ res = self.google.yt_search(arg, userip=userinfo['ip'] if userinfo['ip'] != '0' else None)
except FeedError, e:
self.errormsg(channel, e.msg)
return
return
self.msg(channel, """@sep @bYouTube@b %(title)s @sep @bURL@b %(url)s (%(duration)s) @sep @bViews@b %(views)s @sep \
-@bRating@b %(rating)s/5 - %(votes)s votes @c3@b[+]@b %(liked)s likes @c4@b[-]@b %(disliked)s dislikes @sep""" % {
+@bRating@b @c3@b[+]@b %(liked)s likes @c4@b[-]@b %(disliked)s dislikes @sep""" % {
'title': res['title'],
'url': 'http://www.youtube.com/watch?v=' + res['id'],
'duration': '%s' % format_hms(res['duration']),
'views': format_thousand(res['view_count']),
- 'rating': round(res['rating'], 2) if res['rating'] else 0,
- 'votes': format_thousand(res['rate_count']) if res['rate_count'] else 0,
'liked': format_thousand(res['liked']) if res['liked'] else 0,
'disliked': format_thousand(res['disliked']) if res['disliked'] else 0
})
except Exception, err:
self.log.exception('Error initializing internets bing API (%s)' % err)
self.nsp = calc.NumericStringParser()
- self.google = google.Google()
+ self.google = google.Google(self.config.get('internets', 'key_google'))
self.imdb = imdb.Imdb()
self.ipinfo = ipinfo.IpInfo(self.config.get('internets', 'key_ipinfodb'))
self.lastfm = lastfm.LastFm(self.config.get('internets', 'key_lastfm'))
def join(self, channel):
me = User.findUser(self.nick)
me.joinChan(channel)
- self.msg('ChanServ', 'OP %s' % channel) # and the channel is not empty. For now, use /cs op
+ if Acidictive.me and not Acidictive.me.isBursting():
+ self.msg('ChanServ', 'OP %s' % channel) # and the channel is not empty. For now, use /cs op
def part(self, channel):
me = User.findUser(self.nick)
self.elog.debug('Started core subsystems.')
self.initialized = True
- self.msg('HostServ', 'WAITING') # Check if we missed requests while down
+ if Acidictive.me and not Acidictive.me.isBursting():
+ self.msg('HostServ', 'WAITING') # Check if we missed requests while down
return True
from utils import *
import pyva_net_rizon_acid_core_User as User
-import pyva_net_rizon_acid_core_Channel as Channe;
+import pyva_net_rizon_acid_core_Channel as Channel
def build_ban_message(entity):
message = 'Source: @b%s@b.' % entity.ban_source
+import pyva_net_rizon_acid_core_Acidictive as Acidictive
+
IRCCOLOR_WHITE = 0
IRCCOLOR_BLACK = 1
IRCCOLOR_BLUE = 2
if level > self.level:
return
- self.module.msg(self.chan, '@c%d[%d] %s@o' % (color, level, message))
+ if Acidictive.me and not Acidictive.me.isBursting():
+ self.module.msg(self.chan, '@c%d[%d] %s@o' % (color, level, message))
self.notice(sender, args[1] + " is not a valid quote number.")
return
+ if len(args) == 1:
+ self.notice(sender, "Please specify quote number to delete.")
+ return
+
self.notice(sender, "Checking if you are the channel founder.")
self.auth.request(sender, channel, 'delete_quote' + args[1])