Giter Site home page Giter Site logo

totallynotrobots / cloudbot Goto Github PK

View Code? Open in Web Editor NEW
72.0 6.0 39.0 49.89 MB

CloudBot - The simple, fast, expandable, open-source Python IRC Bot!

License: GNU General Public License v3.0

Python 95.70% Shell 0.05% HTML 4.22% Dockerfile 0.04%
bot framework irc irc-bot python

cloudbot's People

Contributors

a-underscore-d avatar antdking avatar archaicmotion avatar blaneyxyz avatar blha303 avatar daboross avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dmptrluke avatar edillingham avatar edwardslabs avatar elonsatoshi avatar flotwig avatar ilgnome avatar ksaredfx avatar linuxdaemon avatar manyraptors avatar mwscanlon avatar n7st avatar nasonfish avatar neersighted avatar pyup-bot avatar qczar avatar rhinosf1 avatar starsparrow avatar suzip avatar thenoodle68 avatar typoguy avatar vault108 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cloudbot's Issues

feeds.py (and surprisingly many other plugins like ping.py, and more) do not sanitize user input from commands and lead to crashes and other errors..... OR WORSE | .help leads to excess flood IRC quits

As the title suggests, feeds.py for the RSS feeds will gladly accept any format URL as it does not sanitize user input, and in this case it was found that .rss file:///dev/zero floods the bot and crashes it with null chars.

There were other errors with feeds.py as well, such as

  • Some custom url request being refused with error HTTP/403 - I found that whatever is being used to make HTTP(S) requests does not specify a User-agent, which leads to some servers refusing the request. So I added a common, passable User-agent.
  • feed = feedparser.parse(addr) forced the request to parse the actual feed address? So the .rss <url> request in chan would just have the bot return the URL address. addr was changed so it parsed the actual content.

I took time to fix the plugin - which is below. Feel free to use the code, or don't. I think at this point after seeing how easily anyone can have a plugin pushed to this repo without any solid coding or basic input sanitizing - I've been deterred from continuing to use Cloudbot on IRC. I'm seeking alternatives, sadly - because I'd have to probably modify a substantial mount of plugins. It was a decent bot with good plugin options, but this type of stuff is purely unacceptable.

Someone else also found an issue that leads to more crashes (or Remote code execution????) in ping.py - here's his initial suggestion, which we quit trying to fix after the above realization:

<user> plugins/ping.py i think has a backdoor i am trying to bust,         args = ["ping", "-n", str(count), host]
<user> plugins/ping.py
<user> pingcmd = subprocess.check_output(args).decode("utf-8")
<user> no sanatizing going on in this process
<user> but it does seem to excluse some characters from somewhere, but i think a unicode conversion may kick it
-
<user> plugins/ping.py, replace line 35 with host = re.sub(r'[^a-zA-Z0-9:/._-]', '', args[0])
<user> double check to make sure i am not messing with it in a bad way
<user> we can probably refine it hurther since it shouldn't be a full url anyway
<user> host = re.sub(r'[^a-zA-Z0-9.-]', '', args[0])
<user> that may be better
<user> the file already imports re so it is very weird they didn't do this to that arg

Finally, .help leads to "Excess Flood" server quits by the bot.. I don't know if it's the newest version which I installed, but it was not a problem in the past with an older version...

* bot_nick ([email protected]) Quit (Excess Flood)
* bot_nick ([email protected]) has joined #cIRCuit
* bot_nick ([email protected]) Quit (Excess Flood)
* bot_nick ([email protected]) has joined #cIRCuit
* bot_nick ([email protected]) Quit (Excess Flood)
<hazeyez> okay how is that happening?
* bot_nick ([email protected]) has joined #cIRCuit
<hazeyez> not with .rss
* bot_nick ([email protected]) Quit (Excess Flood)
* bot_nick ([email protected]) has joined #cIRCuit
<user> nope
<user> .help

Fixed feeds.py:

import feedparser
import requests
import logging
from cloudbot import hook
from cloudbot.util import formatting, web
from urllib.parse import urlparse

# ''' NOTE: anything with this `''' '''` comment format are things added or customized by hazeyez '''
# NOTE: anything with this comment format OR NO COMMENT are part of the original script

class FeedAlias:
    def __init__(self, url, limit=3):
        self.url = url
        self.limit = limit

# predefined RSS feed aliases
# ''' need to figure out how to get the user a list of these that are available for their use - perhaps add it to the "help" response when only `.rss` command is entered and bot sends /notice to user. Also, can add/remove some feed aliases. ''' 
ALIASES = {
    "xkcd": FeedAlias("http://xkcd.com/rss.xml"),
    "ars": FeedAlias("http://feeds.arstechnica.com/arstechnica/index"),
    "pip": FeedAlias("https://pypi.python.org/pypi?%3Aaction=rss", 6),
    "pypi": FeedAlias("https://pypi.python.org/pypi?%3Aaction=rss", 6),
    "py": FeedAlias("https://pypi.python.org/pypi?%3Aaction=rss", 6),
    "pipnew": FeedAlias(
        "https://pypi.python.org/pypi?%3Aaction=packages_rss", 5
    ),
    "pypinew": FeedAlias(
        "https://pypi.python.org/pypi?%3Aaction=packages_rss", 5
    ),
    "pynew": FeedAlias(
        "https://pypi.python.org/pypi?%3Aaction=packages_rss", 5
    ),
    "world": FeedAlias(
        "https://news.google.com/news?cf=all&ned=us&hl=en&topic=w&output=rss"
    ),
    "us": FeedAlias(
        "https://news.google.com/news?cf=all&ned=us&hl=en&topic=n&output=rss"
    ),
    "usa": FeedAlias(
        "https://news.google.com/news?cf=all&ned=us&hl=en&topic=n&output=rss"
    ),
    "nz": FeedAlias(
        "https://news.google.com/news?pz=1&cf=all&ned=nz&hl=en&topic=n&output=rss"
    ),
    "anand": FeedAlias("http://www.anandtech.com/rss/"),
    "anandtech": FeedAlias("http://www.anandtech.com/rss/"),
}

# ''' added some logging features to coincide with the existing debugging and logging system in the bot '''
logger = logging.getLogger(__name__)

# formats feed results into shortened URL with title
def format_item(item):
    url = web.try_shorten(item.link)
    title = formatting.strip_html(item.title)
    return f"{title} ({url})"

# ''' verify all custom feed links (non-aliases) have HTTP/HTTPS prefix - sanitize URL input, where `.rss file:///dev/zero` command crashed bot with null chars previously '''
def is_valid_url(url):
    parsed_url = urlparse(url)
    return parsed_url.scheme in ["http", "https"]

# gets first 3 items in RSS feed to return. can be modified to return more in `limit =`
@hook.command("feed", "rss", "news")
def rss(text):
    t = text.lower().strip()
    if t in ALIASES:
        alias = ALIASES[t]
        addr = alias.url
        limit = alias.limit
    else:
        addr = text
        limit = 3

    # ''' validate URL - more sanitizing input to avoid bot being crashed with file:///dev/zero null chars vuln '''
    if not is_valid_url(addr):
        return "Invalid URL. Only HTTP and HTTPS protocols are supported."

    try:
        # ''' had to add custom user-agent to requests as most feeds return HTTP/403 error for certain user-agents or non-browser requests '''
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
        }
        response = requests.get(addr, headers=headers, timeout=10)
        response.raise_for_status()
        content = response.content

        # ''' log the content fetched for debugging purposes - to terminal STDOUT and also existing logging system '''
        logger.debug(f"Fetched content: {content[:1000]}") 

        feed = feedparser.parse(content) # ''' "(content)" replaced "(addr)" because "addr" forced it to parse the URL itself instead of the feed content '''
        if not feed.entries:
            return "Feed not found."

        out = []
        for item in feed.entries[:limit]:
            logger.debug(f"Feed item: {item}") # ''' more debugging logging added for each feed item parsed '''
            out.append(format_item(item))

        if "title" in feed.feed:
            start = f"\x02{feed.feed.title}\x02: "
        else:
            start = ""

        return start + ", ".join(out)

    # ''' more error logging, and also returns "not found" error to user if applicable '''
    except requests.exceptions.RequestException as e:
        logger.error(f"Error fetching RSS feed: {e}")
        return f"Error fetching RSS feed: {e}"

xkcd plugin not working

The xkcd plugin is not working properly.
It often returns nothing when supplying the exact comic title or comic ID.

Apparently it uses ohnorobot for search results, but that itself is not working.
E.g.: http://www.ohnorobot.com/index.php?s=wisdom+of+the+ancients&Search=Search&comic=56 should return https://xkcd.com/979/. But it returns nothing.
It also has only 1705 comics in its archive, but even older comics are not found.
I cannot find the source for ohnorobot, it might be closed-source.

I propose these alternatives:

Unfortunately I couldn't find a solution that returns a result based upon an (exact) title search. But maybe either of those could be made to do that.

crontab

I have a crontab job to start the bot:
@reboot /usr/bin/python3 CloudBot/cloudbot >/dev/null 2>&1 2> /home/cloud/cloudbot.log

It was working well, but since few day I got that error into the cron log:

Traceback (most recent call last):
File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "CloudBot/cloudbot/main.py", line 8, in
from cloudbot.bot import CloudBot
ModuleNotFoundError: No module named 'cloudbot'

Amazon plugin no longer working

I've been noticing a large amount of Amazon API errors being returned to channels as responses and decided to look into it. In the response text to the request, Amazon has this to say:

text = '<!--\n        To discuss automated access to Amazon data please contact [email protected].\n        For information about migrating to our APIs refer to our Marketplace APIs at https://developer.amazonservices.com/ref=rm_5_sv, or our Product Advertising API at https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html/ref=rm_5_ac for advertising use cases.\n-->\n<!doctype html>\n<html>\n<head>\n  <meta charset="utf-8">\n  <meta http-equiv="x-ua-compatible" content="ie=edge">\n  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">\n  <title>Sorry! Something went wrong!</title>\n  <style>\n  html, body {\n    padding: 0;\n    margin: 0\n  }\n\n  img {\n    border: 0\n  }\n\n  #a {\n    background: #232f3e;\n    padding: 11px 11px 11px 192px\n  }\n\n  #b {\n    position: absolute;\n    left: 22px;\n    top: 12px\n  }\n\n  #c {\n    position: relative;\n    max-width: 800px;\n    padding: 0 40px 0 0\n  }\n\n  #e, #f {\n    height: 35px;\n    border: 0;\n    font-size: 1em\n  }\n\n  #e {\n    width: 100%;\n    margin: 0;\n    padding: 0 10px;\n    border-radius: 4px 0 0 4px\n  }\n\n  #f {\n    cursor: pointer;\n    background: #febd69;\n    font-weight: bold;\n    border-radius: 0 4px 4px 0;\n    -webkit-appearance: none;\n    position: absolute;\n    top: 0;\n    right: 0;\n    padding: 0 12px\n  }\n\n  @media (max-width: 500px) {\n    #a {\n      padding: 55px 10px 10px\n    }\n\n    #b {\n      left: 6px\n    }\n  }\n\n  #g {\n    text-align: center;\n    margin: 30px 0\n  }\n\n  #g img {\n    max-width: 90%\n  }\n\n  #d {\n    display: none\n  }\n\n  #d[src] {\n    display: inline\n  }\n  </style>\n</head>\n<body>\n    <a href="/ref=cs_503_logo"><img id="b" src="https://images-na.ssl-images-amazon.com/images/G/01/error/logo._TTD_.png" alt="Amazon.com"></a>\n    <form id="a" accept-charset="utf-8" action="/s" method="GET" role="search">\n        <div id="c">\n            <input id="e" name="field-keywords" placeholder="Search">\n            <input name="ref" type="hidden" value="cs_503_search">\n            <input id="f" type="submit" value="Go">\n        </div>\n    </form>\n<div id="g">\n  <div><a href="/ref=cs_503_link"><img src="https://images-na.ssl-images-amazon.com/images/G/01/error/500_503.png"\n                                        alt="Sorry! Something went wrong on our end. Please go back and try again or go to Amazon\'s home page."></a>\n  </div>\n  <a href="/dogsofamazon/ref=cs_503_d" target="_blank" rel="noopener noreferrer"><img id="d" alt="Dogs of Amazon"></a>\n  <script>document.getElementById("d").src = "https://images-na.ssl-images-amazon.com/images/G/01/error/" + (Math.floor(Math.random() * 43) + 1) + "._TTD_.jpg";</script>\n</div>\n</body>\n</html>\n'

The user agent in amazon.py appears to be very old (Chrome 41), perhaps it needs an update?

issues

Some errors :)

########
.amazon:
########
.amazon gives "No results found." for everything

########
cypher:
########
me: .cypher TESTING12345678910TESTING test1337
bot: w4jCqsOGw4h6woF6aA==
me: .decypher test1337 w4jCqsOGw4h6woF6aA==
bot: TESTING1

bot doesn't paste whole line of decypher result.

########
dig:
########
me: .dig nsa.gov MX
bot: no reply.. Error:

Error occurred in dig.dig
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http://dig.jsondns.org/IN/nsa.gov/MX
Traceback: https://hastebin.com/zudukoselo.txt
Event: http://sprunge.us/PLR9ro?txt

########
.doggifs:
########
Error occurred in animal_gifs.doggifs
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 5260: invalid start byte
Traceback: https://hastebin.com/afakilinab.txt
Event: http://sprunge.us/qR8sAn?txt

########
.fml:
########
no reply, error:
Error occurred in mylife.fml
IndexError: pop from empty list
Traceback: https://hastebin.com/anegolozec.txt
Event: http://sprunge.us/GgWFUN?txt

########
.gif
########
Error occurred in giphy.giphy
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: http://api.giphy.com/v1/gifs/search?q=funny&limit=10&fmt=json
Traceback: https://hastebin.com/yavuyareta.txt
Event: http://sprunge.us/6ukwCN?txt

> ----- no where to put giphy API key in config.json < ----

########
.pre
########
orlydb.com is down, and it's been down for years.. remove command?

########
.twitch
########
me: .twitch username
bot: nada, just error:

Error occurred in twitch.twitch
urllib.error.HTTPError: HTTP Error 400: Bad Request
Traceback: https://hastebin.com/bicekodude.txt
Event: http://sprunge.us/AE0M5I?txt

>> https://api.twitch.tv/ <- Not Found <- errors: <<

########
.whois
########
.whois domainname gives nothing, broken/no error/no reply

########
.wyr
########

Event: http://sprunge.us/eJ62Mb?txt
Error occurred in wyr.wyr
requests.exceptions.HTTPError: 522 Server Error: Origin Connection Time-out for url: https://www.rrrather.com/botapi
Traceback: http://sprunge.us/uJONi0?txt
Event: https://hastebin.com/ovagugeyun.txt

########
.metacritic
########

Error occurred in metacritic.metacritic
KeyError: 'search_term'
Traceback: https://hastebin.com/haqihamoha.txt
Event: http://sprunge.us/d2B3NP?txt

Imdb is broken

Originally reported by MPenguin in #gonzobot
It appears that anything scraped in 2021 is not scraping properly:

https://imdb-scraper.herokuapp.com/search?q=Bobs+Burgers&limit=1 :

{
	"success": true,
	"result": [{
		"id": "tt1561755",
		"title": "",
		"year": "2011",
		"genres": [],
		"plot": "",
		"runtime": "",
		"rating": "unrated",
		"votes": "0",
		"directors": [],
		"writers": [],
		"stars": [],
		"retrieved": "2021-08-23T07:14:37.629Z"
	}]
}
https://imdb-scraper.herokuapp.com/search?q=Game+of+Thrones&limit=1
{
	"success": true,
	"result": [{
		"id": "tt0944947",
		"title": "Game of Thrones",
		"year": "2011",
		"genres": [],
		"plot": "Nine noble families fight for control over the mythical lands of Westeros, while an ancient enemy returns after being dormant for thousands of years.",
		"runtime": "57min",
		"rating": "9.4",
		"votes": "1614138",
		"photoUrl": "https://m.media-amazon.com/images/M/MV5BMjA5NzA5NjMwNl5BMl5BanBnXkFtZTgwNjg2OTk2NzM@._V1_UX182_CR0,0,182,268_AL_.jpg",
		"directors": [],
		"writers": [],
		"stars": [],
		"retrieved": "2019-12-17T16:51:02.139Z"
	}]
}

could be possible to rewrite with: https://github.com/alberanid/imdbpy
@IlGnome wanna help me take a stab?

Document config

Might be a good idea to move to a more robust config system for plugins, but we should at least document the core options.

libenchant requirement

libenchant as a system requirement doesn't seem to be used anywhere in the project. I don't see any usage of PyEnchant, which uses enchant under the hood. Am I missing something?

COVID-19 Plugin

I'd like to propose a plugin for listing the current cases/deaths of COVID-19 in a selected area. A possible API to use is https://corona.lmao.ninja (repo, docs).

Example command for worldwide cases: .covid19 -> World: Cases: 2250000 - Deaths: 154000 - Recovered: 574000

Example commands for cases in the US: .covid19 us -> United States: Cases: 710000 - Deaths: 37000 - Recovered: 63000

Kind regards and stay safe.

API used by Stock plugin doesn't return results for securities listed on the ASX

The API in use by the stock plugin (AlphaVantage) seems to have dropped support for the Australian Securities Exchange sometime over the last couple of years. As a result, attempting to query stock prices for companies listed on the ASX returns no results. For example with $CBA.AX

[10:53:12] <@iownall555> .stock CBA.AX
[10:53:13] <gonzobot> (iownall555) Unknown stock symbol 'CBA.AX'

This issue has been documented elsewhere by people using AV in scripts and programs. Unfortunately the ASX charges enormous fees for market data so there may not be any other free APIs that work with it.
https://www.reddit.com/r/ausstocks/comments/f3illc/alphavantage_for_asx/
https://www.reddit.com/r/ausstocks/comments/gmhutc/alphavantage_with_the_asx/

Merge Duck Score limitation

HI,
Its possible we merge duck score partially how much we can from a user to another user for example if a user want to merge his 100 ducks to another user? how could that possible to change in duckhunt.py file?

.git shortening does not work properly

The .git command does not shorten urls properly(how ever converting a short url to the full url works as expected) it results in the following message from the bot:

01:05:51 AM .git https://github.com/xxxxx/xxxxxxx/commit/xxxxxxxxx
01:05:52 AM <%gonzobot> (xxxxxxxxx) [HTTP 200] <title>git.io</title> <script src="/javascripts/modernizr.js" type="text/javascript"></script> <script src="/javascripts/modernizr-tests.js" type="text/javascript"></script> <!--[if (gte IE 6)

Actual url masked for privacy reasons

The console provides the following message:

[01:09:43] [ERROR] Error in hook shorten:gitio
Traceback (most recent call last):
  File "/home/vault108/CloudBot-1/cloudbot/plugin.py", line 530, in internal_launch
    out = await task
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/vault108/CloudBot-1/cloudbot/plugin.py", line 499, in _execute_hook_threaded
    return call_with_args(hook.function, event)
  File "/home/vault108/CloudBot-1/cloudbot/util/func_utils.py", line 26, in call_with_args
    return func(*args)
  File "/home/vault108/CloudBot-1/plugins/shorten.py", line 80, in gitio
    return web.shorten(url, custom=custom, service="git.io")
  File "/home/vault108/CloudBot-1/cloudbot/util/web.py", line 109, in shorten
    return impl.shorten(url, custom, key)
  File "/home/vault108/CloudBot-1/cloudbot/util/web.py", line 327, in shorten
    raise ServiceHTTPError(r.text, r) 
cloudbot.util.web.ServiceHTTPError: [HTTP 200] <!DOCTYPE html>
<html lang='en'>
  <head>
    <title>git.io</title>
    <meta charset='utf-8' />
    <meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible' />
    <link href="/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" />
    <script src="/javascripts/modernizr.js" type="text/javascript"></script>
    <script src="/javascripts/modernizr-tests.js" type="text/javascript"></script>
    <!--[if (gte IE 6)&(lte IE 8)]>
      <script src="/javascripts/selectivizr-min.js" type="text/javascript"></script>
    <![endif]-->
  </head>
  <body>
    <div id='container'>
      <div id='bar'>
        <span id="error" class='arrow_box'>
          Sorry yo. That's an invalid URL.
        </span>
        <div class='side' id='front'>
          <form action="/create" method="post">
            <h1 class="logo"><a href="https://git.io/">Git.io</a></h1>
            <input id="input-url" placeholder="Enter a URL to shorten..." type="text" />
            <button>Shorten</button>
          </form>
        </div>
        <div class='side' id='back'>
          <h1 class="logo"><a href="https://git.io/">Git.io</a></h1>
          <input id="output-url" readonly type="text" />
          <button id="copy-button">Copy</button>
          <span id='copied-msg'>Copied!</span>
          <a id="restart" href="#">Shorten another URL</a>
        </div>
      </div>
      <footer>
        <a href="https://github.com/site/terms">Terms of Service</a>
        <a href="https://github.com/site/privacy">Privacy</a>
        <a href="https://github.com/security">Security</a>
        <a href="https://github.com" class="invertocat">
          <img src="/images/invertocat.png" width="24" height="24" />
        </a>
        &copy; <span id="year">2021</span> GitHub Inc. All rights reserved.
      </footer>
    </div>
  </body>
  <script src="/javascripts/jquery-1.7.1.min.js" type="text/javascript"></script>
  <script src="/javascripts/ZeroClipboard.js" type="text/javascript"></script>
  <script src="/javascripts/jquery.defaultvalue.js" type="text/javascript"></script>
  <script src="/javascripts/site.js" type="text/javascript"></script>
  <script type="text/javascript">
    GitIO.url = "https://git.io";
  </script>
</html>

Pastebins are broken

Both hastebin and sprunge are non-functional now, so pastes aren't working again. I have plans for the Snoonet instance of gonzobot to use a google cloud storage bucket for pastes but as that is a paid service and requires a lot of setup, I think we need to replace the existing pastebins in the core.

I'm not sure what the best pastebins are these days, which ones have APIs, etc. so any help or input would be welcome.

"NSFW" inconsistently marked on YouTube video links

When pasting a YouTube link into chat (#casualconversation), gonzobot provides the title, runtime, author, etc. At times, video links are marked as NSFW (in red text) by gonzobot, although this NSFW branding does not exist on the YouTube page.

Sometimes, posting the video multiple times does not trigger the NSFW marking on repeated postings.

A few possibilities for this issue:

  • The NSFW branding is provided by YouTube, but is being inconsistently interpreted by gonzobot
  • The NSFW branding is applied by gonzobot (based on what?) and being applied inconsistently.

This does not appear to be related to Channel or User Modes.

Duckhunt output

If a hunt was never started in a channel, [prefix]killers and [prefix]friends reply It appears no one has {verb} any ducks yet.
Seems related to this line:

no_ducks = "It appears no one has {verb} any ducks yet."

Should be:

 no_ducks = "It appears no one has {verb} any ducks yet.".format(
        verb=score_type.verb
    )

Integration with IRC BOT RELAY

Good afternoon! With the increasingly common inclusion of BOTS in the RELAY model like 'matterbridge' that unifies IRC x WhatsApp x Telegram x Discod ... would you be able to code the 'duckhunt' plugin so that it, like other plugins, respond from these channels? For example, today on cloudbot if I post via whatsapp or telegrasm and disagree with a site, whether it's search or YouTube, it responds normally, but it doesn't do the same with the 'duckhunt' plugin.

Would you be able to adjust, or inform which file is capable of editing this function, so that it recognizes and responds to commands through other sending sources?

TVDB plugin not working

Hey folks. The tvdb plugin hasn't worked since the last time they decided to change things and let implode on itself. I know folks probably don't use it as much as others but our group is a bunch of old farts who still use irc for basics things. Any chance on it being updated to function with the current version of their api? Thanks a bunch.

.urban fails if query end in a numeric character

.urban fails if query end in a numeric character. For example, the following command will return no results, despite there being an entry for it in urban dictionary:

.urban 999

The problem lies on line #27 of \plugins\urban.py:

 # if the last word is a number, set the ID to that number
 if parts[-1].isdigit():

It then removes the number from the input string, resulting in an empty query.
However, it doesn't check if the word is the only word, in which case it is the query, not the definition number.

The solution, then is to replace line #27 with this:
if parts[-1].isdigit() and len(parts) > 1:

I have already made this fix/change. I am creating this ticket to go with my pull request.

.google truncates URLs

If you google for something with a long URL like "serbian laundromat", gonzobot may truncate the URL if it is too long.

The title should get truncated before the URL, so the URL is clickable in all but the most dire situations. Maybe a minimum length of 20 chars for the title would be appropriate.

DarkSky API removal

Now that Apple bought darksky, the api will be retired and new signups are already disabled. We should investigate other weather APIs.

AttributeError triggered importing module `wl`

The wolfram engine library for python uses the next imports

from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr

The inclusion of the wl module causes the next error (even if I don't use it):

  File "/usr/lib/python3.8/runpy.py", line 193, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/user/projects/IRC/CloudBot/cloudbot/__main__.py", line 92, in <module>
    main()
  File "/home/user/projects/IRC/CloudBot/cloudbot/__main__.py", line 63, in main
    restart = _bot.run()
  File "/home/user/projects/IRC/CloudBot/cloudbot/bot.py", line 186, in run
    self.loop.run_until_complete(self._init_routine())
  File "/usr/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete
    return future.result()
  File "/home/user/projects/IRC/CloudBot/cloudbot/bot.py", line 266, in _init_routine
    await self.plugin_manager.load_all(os.path.abspath("plugins"))
  File "/home/user/projects/IRC/CloudBot/cloudbot/plugin.py", line 194, in load_all
    await asyncio.gather(*[self.load_plugin(path) for path in path_list], loop=self.bot.loop)
  File "/home/user/projects/IRC/CloudBot/cloudbot/plugin.py", line 240, in load_plugin
    plugin = Plugin(str(file_path), file_name, title, plugin_module)
  File "/home/user/projects/IRC/CloudBot/cloudbot/plugin.py", line 638, in __init__
    self.hooks = find_hooks(self, code)
  File "/home/user/projects/IRC/CloudBot/cloudbot/plugin.py", line 41, in find_hooks
    delattr(func, HOOK_ATTR)
AttributeError: _cloudbot_hook

The plugin works if I remove the wl module.
Error happens on 170bbc5 and on release 1.2.0.

Configuration reloading is non-functional.

Much of the bot uses shallow references to the config, meaning once the config is reloaded in its entirety, the old references aren't updated, and much of the bot continues using the old data.

Twitter Not Working? Read Below

Starting February 9, twitter will no longer support free access to the Twitter API, both v2 and v1.1. A paid basic tier will be available instead. However according to Musk, "Twitter will enable a light, write-only API for bots providing good content that is free"

https://twitter.com/TwitterDev/status/1621026986784337922

This could cause issues, for first time users setting the bot up, or for existing users.

Multiple changes: hastebin_server, cap end after sasl, error core.chan_track:on_mode

It all started with seeing that the bot authorizes after connecting... even when using SASL.

So, digging I saw it does "CAP REQ" for each capability, one by one... why not all at once?
More digging made me see that CAP END is sent immediately instead of doing it after sasl.
If no sasl, I don't want it to connect anyway... this can and should be improved.

[ERROR] Error in hook core.chan_track:on_mode AttributeError: 'NoneType' object has no attribute 'type' for https://github.com/TotallyNotRobots/CloudBot/blob/main/cloudbot/util/irc.py#L49

Also the HASTEBIN_SERVER is a redirect and all sorts of errors show up for /documents...

I'm not a coder, I'm sure I did something wrong but oh well..

Here are my changes:

diff --git a/cloudbot/util/irc.py b/cloudbot/util/irc.py
index 0de64a71..c5dadd9d 100644
--- a/cloudbot/util/irc.py
+++ b/cloudbot/util/irc.py
@@ -83,8 +83,9 @@ def parse_mode_string(
             else:
                 param = None

-            new_modes.append(
-                ModeChange(char=c, adding=adding, param=param, info=mode_info)
-            )
+            if mode_info:
+                new_modes.append(
+                    ModeChange(char=c, adding=adding, param=param, info=mode_info)
+                )

     return new_modes
diff --git a/cloudbot/util/web.py b/cloudbot/util/web.py
index 80a3484c..a27614d5 100644
--- a/cloudbot/util/web.py
+++ b/cloudbot/util/web.py
@@ -26,7 +26,7 @@ from requests import HTTPError, PreparedRequest, RequestException, Response
 DEFAULT_SHORTENER = "is.gd"
 DEFAULT_PASTEBIN = ""

-HASTEBIN_SERVER = "https://hastebin.com"
+HASTEBIN_SERVER = "https://www.toptal.com/developers/hastebin"

 logger = logging.getLogger("cloudbot")

@@ -340,7 +340,7 @@ class Hastebin(Pastebin):

         try:
             r = requests.post(self.url + "/documents", data=encoded)
-            r.raise_for_status()
+            # r.raise_for_status()
         except HTTPError as e:
             r = e.response
             raise ServiceHTTPError(r.reason, r) from e
diff --git a/plugins/core/cap.py b/plugins/core/cap.py
index 77ceec53..14d4d61e 100644
--- a/plugins/core/cap.py
+++ b/plugins/core/cap.py
@@ -20,9 +20,11 @@ def send_cap_ls(conn):


 async def handle_available_caps(conn, caplist, event, irc_paramlist, bot):
+    sasl_auth = conn.config.get("sasl")
     available_caps = conn.memory["available_caps"]  # type: CapList
     available_caps.extend(caplist)
     cap_queue = conn.memory["cap_queue"]
+    tosend = ""
     for cap in caplist:
         name = cap.name
         name_cf = name.casefold()
@@ -36,12 +38,14 @@ async def handle_available_caps(conn, caplist, event, irc_paramlist, bot):
         results = await asyncio.gather(*tasks)
         if any(ok and (res or res is None) for ok, res in results):
             cap_queue[name_cf] = async_util.create_future(conn.loop)
-            conn.cmd("CAP", "REQ", name)
-
-    if irc_paramlist[2] != "*":
-        await asyncio.gather(*cap_queue.values())
-        cap_queue.clear()
-        conn.send("CAP END")
+            tosend = " "+tosend+" "+name
+    conn.cmd("CAP", "REQ", tosend)
+
+    if not sasl_auth or not sasl_auth.get("enabled", False):
+        if irc_paramlist[2] != "*":
+            await asyncio.gather(*cap_queue.values())
+            cap_queue.clear()
+            conn.send("CAP END")


diff --git a/plugins/core/sasl.py b/plugins/core/sasl.py
index 12c9dc83..c6dd498b 100644
--- a/plugins/core/sasl.py
+++ b/plugins/core/sasl.py
@@ -39,6 +39,8 @@ async def sasl_ack(conn):
                 logger.warning("[%s|sasl] SASL nick locked", conn.name)
             elif numeric == "903":
                 logger.info("[%s|sasl] SASL auth successful", conn.name)
+                conn.send("CAP END")
+
             elif numeric == "904":
                 logger.warning("[%s|sasl] SASL auth failed", conn.name)
             elif numeric == "905":

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.