Git Product home page Git Product logo

ch.py's Introduction

Hi, I'm Nullspeaker.

Government Name: Nicholas Hammond
Preferred Name: Auralyn (or just Aura for short)


I'm a maths enthusiast and software developer.
I don't have much industry experience1, but I'm comfortable hacking around with anything and everything.

Currently doing freelance work!

Feel free to contact me about anything that might interest me.
I'm slow at checking my personal email, so if you want a within-a-day response, ping me on Discord.

If you want to support my projects, thank me for some help, or just want me to eat more cheese, I'm accepting financial support via ko-fi and paypal. :)


Contact me:

Discord: null#0999 nullspeaker

Email

#!/usr/bin/env python3
from base64 import standard_b64decode
print(standard_b64decode(b'bmhhbW1vbmQxMjlAZ21haWwuY29t'))

Languages

Best-known are C++, C, Python, and Wolfram Language. I peck at other languages all the time and don't have much trouble swapping around.


Tools:

Mathematica | git | bash | *nix | gdb | ... and so on


Footnotes

  1. Worked for Wolfram Research on the Algs. R&D team (C++ and WL development) Apr. 2020 - Nov. 2022

ch.py's People

Contributors

asl97 avatar belldandu avatar dani87 avatar donboricua avatar nhammond129 avatar piks avatar pystub avatar

Stargazers

 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  avatar  avatar  avatar

ch.py's Issues

(INVALID) Error in _rcmd_wl function

INVALID ISSUE

original post

Okay so I had a friend run the example bot with this ch.py and it gives and error in _rcmd_ function. I have the traceback and here it is:

Traceback (most recent call last):
File "C:\Users\name\Desktop\Python\BOTFOLDER\ch.py-master\example.py",
line 32, in <module> TestBot.easy_start(rooms, "name", "password")

File "C:\Users\name\Desktop\Python\BOTFOLDER\ch.py-master\ch.py",
line 2150, in easy_start self.main()

File "C:\Users\name\Desktop\Python\BOTFOLDER\ch.py-master\ch.py",
line 2115, in main con._feed(data)

File "C:\Users\name\Desktop\Python\BOTFOLDER\ch.py-master\ch.py",
line 480, in _feed self._process(food.decode(errors="replace").rstrip("\r\n"))

File "C:\Users\name\Desktop\Python\BOTFOLDER\ch.py-master\ch.py",
line 495, in _process getattr(self, func)(args)

File "C:\Users\name\Desktop\Python\BOTFOLDER\ch.py-master\ch.py",
line 526, in _rcmd_wl if not is_on == "on": self._status[user] = [int(last_on), False, 0]
ValueError: invalid literal for int() with base 10: 'None' 

>>>

unid alternative, the puid

the puid is what botteh and some other bots use for their whois

it doesn't need the bot to be mod to get the puid, which is why it so good for the whois cmd, the question is, should we add it in the ch, if we do, it would mean major change to the ch and the example bot, the before change and after it wouldn't be able to work with each other

ConnectionRefusedError on 746 not handled.

Hi again,

Just making sure this is an issue before I try and fix it. Currently when connecting to room on a server that's being restarted or updated etc (because often you get disconnected when that happens) you get a socket error of ConnectionRefusedError.

My thoughts are this needs to handled by an except (either specific to ConnectionRefusedError or not) either in _joinThread (1525) or init (738) to call the onConnectFail event. Unless there is a method recommended for fixing this in bot itself.

This could be considered medium as all it does is mean the person coding the bot has to be more advanced with their coding to check the bot joins a room etc. (ch.py just throws the exception, doesn't crash from what I can tell).

Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.4/threading.py", line 868, in run
    self._target(*self._args, **self._kwargs)
  File "/opt/bot/ch.py", line 1525, in _joinThread
    con = self._Room(room, mgr = self)
  File "/opt/bot/ch.py", line 738, in __init__
    if self._mgr: self._connect()
  File "/opt/bot/ch.py", line 746, in _connect
    self._sock.connect((self._server, self._port))
ConnectionRefusedError: [Errno 111] Connection refused

PUID, getMods

First Issue:

getMods doesn't exist, this is because it was updated to _getMods
Line 831
mods = self.getMods()
Should be:
mods = self._getMods()

PUID

This used to be in the older ch.py and was removed, it is handy for whois. To fix:
Lines 977 - 989

    msg = Message(
      time = mtime,
      user = User(name),
      body = msg,
      raw = rawmsg,
      ip = ip,
      nameColor = nameColor,
      fontColor = fontColor,
      fontFace = fontFace,
      fontSize = fontSize,
      unid = unid,
      room = self
    )

Replace with:

    msg = Message(
      time = mtime,
      user = User(name),
      body = msg,
      raw = rawmsg,
      ip = ip,
      nameColor = nameColor,
      fontColor = fontColor,
      fontFace = fontFace,
      fontSize = fontSize,
      unid = unid,
      room = self,
      uid = puid
    )

Lines 1026 - 1038

    msg = Message(
      time = mtime,
      user = User(name),
      body = msg,
      raw = rawmsg,
      ip = ip,
      nameColor = nameColor,
      fontColor = fontColor,
      fontFace = fontFace,
      fontSize = fontSize,
      unid = unid,
      room = self
    )

Replace with

    msg = Message(
      time = mtime,
      user = User(name),
      body = msg,
      raw = rawmsg,
      ip = ip,
      nameColor = nameColor,
      fontColor = fontColor,
      fontFace = fontFace,
      fontSize = fontSize,
      unid = unid,
      room = self,
      uid = puid
    )

Add
def _getUid(self): return self._uid

Under
def _getUnid(self): return self._unid

Add
uid = property(_getUid)

Under
unid = property(_getUnid)


This has been tested and is working. I make this change everytime you guys update ch.py on my own copy.

user online or offline

sending 'track' to the pm would return the status of the user

send: track:user
get: track:user:idle time in mins:status
if offline, the idle time would be zero

i not quite sure how to put it together or how to put together an api for this though

Adding the room.unbanlist to ch.py?

I think adding a unbanlist to the ch.py would be good for moderation bots. This way the bot owner can find who was unbanning certain users just like the banlist does.

Unbans Line 1152

Everytime the bot tries to unban someone, it errors out with no error message except

KeyError: <User: Botsusername> line 1152. 

Erroneous Line:

    del self._banlist[user]

I wrapped this in a basic exception handle

    try:
        del self._banlist[user]
    except Exception as e:
        print(e)

The error stopped crashing the bot, ofc. And unban still works just fine. I presume it goes to delete a user from the dictionary, then crashes because it can't find the user there. It still works on chatango however, the user was removed from the ban list, and added to the unbanned list.

Problem not joining the chat room/responding

I would really like to get this bot to work, sorry guys i am not really any good with python, though my friend owns a large chat room, and i thought that having bot like this would really help.

The problem i have is, bot doesn't join the chat room, yeah everything is fine when i launch it, no errors. Doesn't respond to pm commands, dunno if it should. When i pm the bot everything is fine, shows my level 99 at the python. But i can't get the bot to join chatroom, nor do any commands via pm.
I tried both 3.2 and 3.4 versions of python.

Thank you for taking the time to read this/help.

Room disconnection upon message delete

When using room.clearUser(user) the bot will suddenly room.disconnect() with no message deleted. If used in conjunction with room.banUser(user) the bot will ban and still room.disconnect() with no message deleted.

unable to connect to pm's on example.py using default library :3

Traceback (most recent call last):
File "example.py", line 32, in
TestBot.easy_start(["some place"],"killer04289","Wouldnt you like to know :3")
File "/home/pika/bot/chnew/ch.py", line 2154, in easy_start
self.main()
File "/home/pika/bot/chnew/ch.py", line 2119, in main
con._feed(data)
File "/home/pika/bot/chnew/ch.py", line 480, in _feed
self._process(food.decode(errors="replace").rstrip("\r\n"))
File "/home/pika/bot/chnew/ch.py", line 495, in _process
getattr(self, func)(args)
File "/home/pika/bot/chnew/ch.py", line 526, in _rcmd_wl
if not is_on == "on": self._status[user] = [int(last_on), False, 0]
ValueError: invalid literal for int() with base 10: 'None'

Adding the banned words section to the ch.py?

Well not sure if anyone wants the banned words section in this ch.py besides me. I have the code for it so if anyone wants it added to the nullspeaker ch.py just comment and I'll make a pull request.

split up ch.py?

Should ch.py be split up into a few files?

It'd be easier for people to clone into their projects, because they could just have their ch.py folder they can tortoisegit updates into, and it'd be easier for development as we know which files to look into for changes.

It'dn't change the topology of it a whole lot, though I can't quite remember at the moment how Python handles multifile libraries.
IIRC, importing would be just as easy if we put a (blank) init.py in ./ch.py/. I know my psyfrbot does something like that. It had a lot of weird hacky importing.

Problem with delete/ban

I'm not too sure what's going on here but every time I call to ban a user / delete a message it just doesn't do so.

I call room.delete(message) and room.banUser(user)

Also tried to do both just raw and still no results.

Any idea?

Unicode Error and PM support

Apology for bad English.
The bot doesn't seem to support letters or signs that aren't ASC II. It crashes when for example this face ( ͡° ͜ʖ ͡°) is posted and raises a Unicode Error.
Another issue is that the PM support does not seem to work. The only function that works is onPMPing, but that's not really suprising. Maybe it's just me though, so it would be nice if you could try it and tell me if it works normally for you, or if it really doesn't work.

Colons in Old Messages

As found when using cursango, (which probably needs a serious facelift on its own) messages that were sent before rejoining are prefixed with a colon. Never caused any actual issues -- but since it looks ch.py related, (messages are originally prefixed with a colon) I figure someone might be bored enough to check into this.

Windows users looking to inspect this will need the python curses addon based on pdcurses: http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses

Add working uids?

I noticed that this ch.py does not have uids like sone other ch.py's do. Like when I eval

message.uid

or

room.getLastMessage(ch.User(name)).uid

You get a attribute error. Should uids be in this one as well?

ch.py missing function docstring and the doc for ch.py

there is already an doc on the ch.py, it's in the ch.py xD

but there a lot of function missing their docstring

open a python shell and type

import ch
help(ch)

to see what i mean

once that done, we could put an online copy of it and the doc would finally be done

bot unable to join some rooms

i think your fix broke it nullspeaker...

the min(lnv,1000)

it was if lnv is smaller than 1000:

if(lnv <= 1000):
    lnv = 1000

so i think it should be max(lnv,1000)

No more Python 2

This library has been Python 2 compatible for eons, it would be a good to clarify (in the README changelog) that Python 2 is no longer supported for good.

Protocol update?

Between theholder's dropping and my new repo's creation, Chatango changed up the protocol.
What I know is that incoming messages have an additional colon at beginning, and that outgoing messages are crashing the client because we're lacking some delimiter or something. Could someone please notify me what is needed for those outgoing messages?
I already fixed the first issue, but I want to get that second one before I commit, since the first takes less than 10 keystrokes anyway.

hard to reproduce error when disconnecting

When disconnecting, the room._userlist get clear(1).
However it doesn't stop the feed from processing whatever it has left (3),
If there is an user leave participant in the feed (2), it would error due to the user not existing in the list.

Easiest way to reproduce it is by using a busy room, not filtering out anon in the Participant and disconnecting the room as soon as g_participants is receive (onRaw).

  1. https://github.com/Nullspeaker/ch.py/blob/aa73521774b299603eda7bb99928d718896e3e53/ch.py#L777
  2. https://github.com/Nullspeaker/ch.py/blob/aa73521774b299603eda7bb99928d718896e3e53/ch.py#L1067
  3. https://github.com/Nullspeaker/ch.py/blob/aa73521774b299603eda7bb99928d718896e3e53/ch.py#L870

[WIN] Line 2118 - OSError: [WinError 10022] An invalid argument was supplied

Notes: Been running ch.py while playing around with python to create a bot on Linux. Everything works well. Friend wanted to run a bot, so I set up a version for them to play with. Had errors on line 2118, tried with a fresh 3.4.1 install and had the same issues on windows, tried 2.7.8 same deal. Tried example.py, same issues again.

Python Versions Tried: 2.7.8, 3.4.1 (both fresh)
Source: example.py, ch.py latest

Traceback:

Room names separated by semicolons: exampleroom
User name: exampleuser
User password: examplepass
Traceback (most recent call last):
  File "example.py", line 33, in <module>
    TestBot.easy_start()
  File "ch.py", line 2159, in easy_start
    self.main()
  File "ch.py", line 2118, in main
    rd, wr, sp = select.select(socks, wsocks, [], self._TimerResolution)
OSError: [WinError 10022] An invalid argument was supplied

Line 2270 def _getRoomNames

def _getRoomNames(self): return [room.name for room in self.getRooms()]

self.getRooms() is suppose to be self._getRooms()

Like this:

def _getRoomNames(self): return [room.name for room in self._getRooms()]

Archived messages option

It would be good to have possibility to read archived messages at the time of entry into a room. Now we can see these archived messages only when we enter same Chatango room in http version. So if it is possible to implement it in program it would be good idea to be able to set this option.

include current maintainers into ch?

Lumirayz no longer recommend the ch.py let alone update it,

if we include current maintainers and change author into original author, the chance someone might email him would be lesser if she is still using that email,

i hear stuff about how she insult people who use it so changing it might be better for the users

not able to join some rooms

this is a MAJOR bug, chatango updated again and broke the ch, i got no idea how to fix it cause it doesn't throw any error

Joining rooms mistake

I made a mistake in my previous suggestion to make the bot join one room at a time.
If someone enters an invalid room name (if they typo the name or if the room doesn't exist anymore), the bot will not join any more rooms, because the events onStartJoin / onConnect will not be called.
Soo... I guess it has to be added to onConnectFail and possibly to onLoginFail, but I'm not sure about the latter.

Unknown Data

[Printed in console]
unknown data: ['time', '1460136198.55']
unknown data: ['seller_name', 'botnamet', '7725338125882817']
[keeps on repeating]
unknown data: ['']
unknown data: ['']
unknown data: ['']
unknown data: ['']
unknown data: ['']
unknown data: ['']
unknown data: ['']
unknown data: ['']
Also crashes if any user joins or refresh their browser
(C:\Users\i\Desktop\chatango bot 123\New folder\ch.py:1381) onLeave() takes 3 positional arguments but 4 were given

invalid literal for int() in _rcmd_wloffline

Traceback (most recent call last):
File "C:\Python32\Astarte\bot.py", line 1113, in
Alebaster.easy_start(rooms = rooms, name = "Astarte", password = "pls my pass is secret")
File "C:\Python32\Astarte\ch.py", line 2154, in easy_start
self.main()
File "C:\Python32\Astarte\ch.py", line 2119, in main
con._feed(data)
File "C:\Python32\Astarte\ch.py", line 480, in _feed
self._process(food.decode(errors="replace").rstrip("\r\n"))
File "C:\Python32\Astarte\ch.py", line 495, in _process
getattr(self, func)(args)
File "C:\Python32\Astarte\ch.py", line 584, in _rcmd_wloffline
last_on = int(args[1])
ValueError: invalid literal for int() with base 10: '1404708662.68'

keeps crashing when the bot's contacts go offline.

Login as anon

Is it possible to join some room as Anon instead of register user?

annoying error in ch.py says invalid arguement

[INF]Setting status to online...
[INF]Loading Definitions...
[INF]Loading Supermasters...
[INF]Loading Masters...
[INF]Loading Half Masters....
[INF]Loading Whitelists...
[INF]Loading Rooms...
Room names separated by semicolons: mf648animes
[INF] Disconnected to mf648animes
[ERR] Fatal error.
(\ch.py:1709) (10022, 'An invalid argument was supplied')
[SAV] Saving Definitions..
[SAV] Saving SuperMasters..
[SAV] Saving Masters..
[SAV] Saving HalfMasters..
[SAV] Saving Whitelist..
[SAV] Saving Rooms..
[INF] Setting status offline...
Waiting 10 seconds for you to read the error..
[INF] Shutting down..

heres the arguement

Main

def main(self):
self.onInit()
self._running = True
while self._running:
conns = self.getConnections()
socks = [x._sock for x in conns]
wsocks = [x._sock for x in conns if x._wbuf != b""]


  rd, wr, sp = select.select(socks, wsocks, [], self._TimerResolution)   

This is the issue right here ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


  for sock in rd:
    con = [c for c in conns if c._sock == sock][0]
    try:
      data = sock.recv(1024)
      if(len(data) > 0):
        con._feed(data)
      else:
        con.disconnect()
    except socket.error:
      pass
  for sock in wr:
    con = [c for c in conns if c._sock == sock][0]
    try:
      size = sock.send(con._wbuf)
      con._wbuf = con._wbuf[size:]
    except socket.error:
      pass
  self._tick()

Would the maintainers and contributors forgive me?

@AcePokeMaster
today, someone by the name of creator-kami has make me realize that i was wrong, wrong about a lot of things.

i was a stubborn idiot, it was wrong of me to argue like that, i could have easily edited the patch myself and there would be no issue.

would you ever forgive me?

http://angsoonli.deviantart.com/journal/I-am-asking-for-forgiveness-519471988

@Nullspeaker @piks @dani87 @pystub @donboricua @KamijouTouma @domzy
it would be wrong of me to just come back and start editing again
i want to earn my place again, not as the BDFL, but as someone who like python and the ch.py

even though i am still a contributor with write access, i am still going to asking for permission cause it would be the right thing to do.

however, i am going offline for a while, i need some time alone after my emotional break down.

Joining several rooms

I'm kind of too lazy to make a commit, buuut under def easy_start, you set a timeout for each room which the bot should join. You do this:

if len(rooms) > 5:
      # slow down connection to stop fail connection
      t = 1
      for room in rooms:
        self.setTimeout(int(t),self.joinRoom,room)
        if len(rooms) > 10:
          t = t + 1
        else:
          t = t + 0.5
    else:
      for room in rooms:
        self.joinRoom(room)

What I reckon might be better is making a list and joining one room at a time.

if not rooms: rooms = str(input("Room names separated by semicolons: ")).split(";")
if len(rooms) == 1 and rooms[0] == "": rooms = []
if not name: name = str(input("User name: "))
if name == "": name = None
if not password: password = str(input("User password: "))
if password == "": password = None
self = cl(name, password, pm = pm)

rooms_copy=rooms
if len(rooms_copy)>0:
  self.joinRoom(rooms_copy.pop())

and then that'd have to be called again under onConnect(self, room)..
It's probably easier to do this in the bot file. If certain people have a long list with rooms to join, they'll probably think of something to make it more stable themselves. I doubt they want to be restricted by a timeout. So I wonder if that should be removed from ch.py
It could be included in the example.py though.

http://pastebin.com/iSTxHjjX
This is a possibility.. this isn't meant to use easy_start, but it should still work with it.

Unable to PM as anon

Bot is unable to PM as anon.

Problem:

  • Not all accounts allow anons to PM them anyway, how do we find out whether they allow it?

Hangup in socket.py

Not sure if this is a specific issue for ch.py or if it's a wider issue, but the bot just started to hang up after a while and i had to interrupt it.

Trace:

Traceback (most recent call last):
  File "fvbot.py", line 220, in <module>
    FVBot.easy_start(["fv-se"], fvbotauth.FVBOT_USER, fvbotauth.FVBOT_PASS, True)
  File "C:\Users\Joe\Documents\GitHub\FVBot\ch.py", line 2182, in easy_start
    self.main()
  File "C:\Users\Joe\Documents\GitHub\FVBot\ch.py", line 2140, in main
    rd, wr, sp = select.select(socks, wsocks, [], self._TimerResolution)
  File "C:\Python27\lib\socket.py", line 223, in meth
    def meth(name,self,*args):
KeyboardInterrupt

Unicode support

I was messing around with stuff and noticed that it doesn't handle unicode all that well. I changed a couple of lines and managed to get it to receive and send characters outside of the ascii range, but i don't know if this would be enough or if there is another subtle reason why only ascii was being used.

Line changes:
Line 870
self._process(food.decode("utf-8", errors="replace").rstrip("\r\n"))

Line 1442
self._write(":".join(args).encode("utf-8") + terminator)

There is 2 other '_sendCommand' functions that only have encode(), so if this is acceptable then i imagine those would need to be changed. Any reason why unicode cant be support through this change?

Ch.py PMs contacts adding/removing

So I tried

self.pm._sendCommand("wladd", "name")

But when I check the PM contacts through the bot the dict was empty(bot didn't have contacts yet when testing)

Note: I did not test the pm blocking/unblocking so I don't know if that will work as well.

todo list before release of 1.3.5

  • rename internal functions
  • add proper docstrings for public functions
  • finish issue #28
  • make an official release and a new branch for 1.3.5
  • using efficient threading for non-blocking joining #30 (might be backward incomparable)

other lib already using threading but i am worry about the performance of thread,
it really sucks when there more thread than core so i ain't going to do what chlib.py do,
but one extra thread shouldn't be so bad, at best, maybe a 10% for first extra thread
and 1% for each other thread lost of performance in exchange of a perfect,
non-blocking joining

but most computer nowadays all have at least a duo core, but i think it wouldn't work so well with my psp and other single core device, so i be recommending 1.3.5 once it's out for those single core.

in any case, this is a todo list.

proper way for joining multiple room

currently the workaround does work fine but someone is nit-picking on the workaround so i guess now would be a good time to redo the whole room class to support joining of multiple room

the reason the workaround work is cause the joining of rooms doesn't block the bot from doing anything else since it only join the next room after it successfully or fail to join the current room, so it is able to send stuff like ping between joining so that it doesn't timeout

so to have a proper fix for this, the joining of rooms will have to take place on another thread or done through some non-blocking way (maybe calling a function to check if there any room that need joining every few second) so that it is able to continue sending pings

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.