]> jfr.im git - irc/rizon/acid.git/commitdiff
Merge branch 'master' into geoserv+chgclass
authorAdam <redacted>
Mon, 27 Apr 2015 21:25:57 +0000 (17:25 -0400)
committerAdam <redacted>
Mon, 27 Apr 2015 21:25:57 +0000 (17:25 -0400)
14 files changed:
acid/src/main/java/net/rizon/acid/core/Plugin.java
pyva/config.example.ini
pyva/pyva-native
pyva/pyva/src/main/java/net/rizon/acid/plugins/pyva/pyva/pyva.java
pyva/pyva/src/main/python/core.py
pyva/pyva/src/main/python/ctcp/ctcp.py
pyva/pyva/src/main/python/internets/api/google.py
pyva/pyva/src/main/python/internets/cmd_user.py
pyva/pyva/src/main/python/internets/internets.py
pyva/pyva/src/main/python/limitserv/limitserv.py
pyva/pyva/src/main/python/moo/moo.py
pyva/pyva/src/main/python/pseudoclient/cmd_admin.py
pyva/pyva/src/main/python/pseudoclient/sys_log.py
pyva/pyva/src/main/python/quotes/quotes.py

index 805302bd45505ee94cc58edfc02ed852ac41f828..cf7c45d38a918f1cce6f394c5095a3345dcc4c8c 100644 (file)
@@ -64,7 +64,15 @@ public abstract class Plugin
                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;
        }
 
index 2d0ffec44b554e3d583271d92279a2c7fe7dd052..e454a67cfa5f9de08e9f7030c781548f0ad42969 100644 (file)
@@ -58,6 +58,7 @@ key_lastfm: xxx
 key_fml: xxx
 key_wolframalpha: xxx
 key_steam: xxx
+key_google: xxx
 
 [limitserv]
 nick: Limitserv
index e2d4ad88b2d45dbf8351082d458dff8f35e775a4..7af06c821c6ba0e8aa4645a3180180b879576dd9 160000 (submodule)
@@ -1 +1 @@
-Subproject commit e2d4ad88b2d45dbf8351082d458dff8f35e775a4
+Subproject commit 7af06c821c6ba0e8aa4645a3180180b879576dd9
index 32b9d601fef609bd1a473f199bd11653d29c7971..7af46b226ad120301b24f445b7ce4686afa68439 100644 (file)
@@ -141,11 +141,19 @@ public class pyva extends Plugin
 
                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();
        }
index 19a77284b4712a1baa8234d0ce0441ff42d22aec..d9d1bcf6afc4c2ce977f2eb0206f21f73994dabd 100644 (file)
@@ -32,12 +32,12 @@ import sys
 
 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()
index 59be6837bbaa18b1cb25efc8bce41ca099a76630..5a310803979b21831ffc8b5afcf68d5b374e9825 100644 (file)
@@ -9,6 +9,7 @@ import istring
 from operator import itemgetter #for sort
 from collections import defaultdict
 import time
+import re
 
 from pyva import *
 import logging
@@ -327,6 +328,75 @@ class ctcp(AcidPlugin):
 
                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
 
@@ -363,4 +433,8 @@ class ctcp(AcidPlugin):
                         '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."}),
                )
index 24fb58c827a0954beffca4c50c65e656c91b6096..660a73ca7e1ceada5adad6c53568d159d7a02e30 100644 (file)
@@ -5,32 +5,8 @@ from feed import HtmlFeed, XmlFeed, get_json
 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&'
@@ -50,24 +26,37 @@ class Google(object):
                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'])
                        }
index 7e0dedb29b5147ccf37f305496047364f78d2ba6..a9ff6dc74a1cdb40299cedfd9053aee2aedbd4ab 100644 (file)
@@ -187,7 +187,7 @@ def command_bing_translate(self, manager, opts, arg, channel, sender, userinfo):
 
 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
@@ -212,7 +212,7 @@ def command_google_search(self, manager, opts, arg, channel, sender, userinfo):
 
 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
@@ -259,7 +259,7 @@ def command_calc(self, manager, opts, arg, channel, sender, userinfo):
 
 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
@@ -269,13 +269,11 @@ def command_youtube_search(self, manager, opts, arg, channel, sender, userinfo):
                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
                        })
index 7d4226e2f6f9335962c68160c61a0746e1625b01..8196639c7371d67bdae7c75f1b1399aef15bfbdf 100644 (file)
@@ -113,7 +113,7 @@ class internets(
                        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'))
index d61fc3f4f3d9629e3559b9fa3d64e54ec1db4c3c..4b9e7da1940d51568519c18a1a064ef838377c2f 100644 (file)
@@ -130,7 +130,8 @@ class limitserv(
        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)
index 4c3d94960be47b845924de62c3e7f9a7d4cdc766..b02bf7ec33f4bb4d985b6cb33449a70ee1b96461 100644 (file)
@@ -61,7 +61,8 @@ class moo(AcidPlugin):
                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
        
index 16f34423c4441e3a15cd146788b3a850fe384f98..49645c6c7112a905d5d9d87e634843fccd43d501 100644 (file)
@@ -7,7 +7,7 @@ from datetime import datetime
 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
index ff39bc079ba0de071b16b0330050102236d35684..f20b7adf95b4d32762ca04429b840bbea88083d6 100644 (file)
@@ -1,3 +1,5 @@
+import pyva_net_rizon_acid_core_Acidictive as Acidictive
+
 IRCCOLOR_WHITE      = 0
 IRCCOLOR_BLACK      = 1
 IRCCOLOR_BLUE       = 2
@@ -63,4 +65,5 @@ class LogManager(object):
                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))
index 7ed058c52bdb886dbb83602e8c45d3c66333045d..e3d6a01708989e11ddc0bef4593ac04db6a49407 100644 (file)
@@ -291,6 +291,10 @@ class quotes(
                                                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])