示例#1
0
def prepare_user_message(user, msg_score, is_media):
    if user.isInCooldown():
        return rp.Reply(rp.types.ERR_COOLDOWN, until=user.cooldownUntil)
    if is_media and user.rank < RANKS.mod and media_limit_period is not None:
        if (datetime.now() - user.joined) < media_limit_period:
            return rp.Reply(rp.types.ERR_MEDIA_LIMIT)
    ok = spam_scores.increaseSpamScore(user.id, msg_score)
    if not ok:
        return rp.Reply(rp.types.ERR_SPAMMY)
    return ch.assignMessageId(CachedMessage(user.id))
示例#2
0
def cmd_warn(ev, delete=False):
	c_user = UserContainer(ev.from_user)

	if ev.reply_to_message is None:
		return send_answer(ev, rp.Reply(rp.types.ERR_NO_REPLY), True)

	reply_msid = ch.lookupMapping(ev.from_user.id, data=ev.reply_to_message.message_id)
	if reply_msid is None:
		return send_answer(ev, rp.Reply(rp.types.ERR_NOT_IN_CACHE), True)
	send_answer(ev, core.warn_user(c_user, reply_msid, delete), True)
示例#3
0
def cmd_blacklist(ev, arg):
    c_user = UserContainer(ev.from_user)
    if ev.reply_to_message is None:
        return send_answer(ev, rp.Reply(rp.types.ERR_NO_REPLY), True)

    reply_msid = ch.lookupMapping(ev.from_user.id,
                                  data=ev.reply_to_message.message_id)
    if reply_msid is None:
        return send_answer(ev, rp.Reply(rp.types.ERR_NOT_IN_CACHE), True)
    return send_answer(ev, core.blacklist_user(c_user, reply_msid, arg), True)
示例#4
0
def cmd_plusone(ev):
    c_user = UserContainer(ev.from_user)
    if ev.reply_to_message is None:
        return send_answer(ev, rp.Reply(rp.types.ERR_NO_REPLY), True)

    reply_msid = ch.lookupMapping(ev.from_user.id,
                                  data=ev.reply_to_message.message_id)
    if reply_msid is None:
        return send_answer(ev, rp.Reply(rp.types.ERR_NOT_IN_CACHE), True)
    return send_answer(ev, core.give_karma(c_user, reply_msid), True)
示例#5
0
def remove(user, msid, reason):
    cm = ch.getMessage(msid)
    if cm is None or cm.user_id is None:
        return rp.Reply(rp.types.ERR_NOT_IN_CACHE)

    user2 = db.getUser(id=cm.user_id)
    _push_system_message(rp.Reply(rp.types.MESSAGE_REMOVED, reason=reason),
                         who=user2,
                         reply_to=msid)
    Sender.delete(msid)
    logging.info("%s had a message removed by %s for: %s", user2, user, reason)
    return rp.Reply(rp.types.SUCCESS)
示例#6
0
def get_info_mod(user, msid):
    cm = ch.getMessage(msid)
    if cm is None or cm.user_id is None:
        return rp.Reply(rp.types.ERR_NOT_IN_CACHE)

    user2 = db.getUser(id=cm.user_id)
    params = {
        "id": user2.getObfuscatedId(),
        "karma": user2.getObfuscatedKarma(),
        "cooldown": user2.cooldownUntil if user2.isInCooldown() else None,
    }
    return rp.Reply(rp.types.USER_INFO_MOD, **params)
示例#7
0
def delete_message(user, msid):
	if not allow_remove_command:
		return rp.Reply(rp.types.ERR_COMMAND_DISABLED)

	cm = ch.getMessage(msid)
	if cm is None or cm.user_id is None:
		return rp.Reply(rp.types.ERR_NOT_IN_CACHE)

	user2 = db.getUser(id=cm.user_id)
	_push_system_message(rp.Reply(rp.types.MESSAGE_DELETED), who=user2, reply_to=msid)
	Sender.delete(msid)
	logging.info("%s deleted a message from [%s]", user, user2.getObfuscatedId())
	return rp.Reply(rp.types.SUCCESS)
示例#8
0
def set_tripcode(user, text):
	if not enable_signing:
		return rp.Reply(rp.types.ERR_COMMAND_DISABLED)

	if not (0 < text.find("#") < len(text) - 1):
		return rp.Reply(rp.types.ERR_INVALID_TRIP_FORMAT)
	if "\n" in text or len(text) > 30:
		return rp.Reply(rp.types.ERR_INVALID_TRIP_FORMAT)

	with db.modifyUser(id=user.id) as user:
		user.tripcode = text
	tripname, tripcode = genTripcode(user.tripcode)
	return rp.Reply(rp.types.TRIPCODE_SET, tripname=tripname, tripcode=tripcode)
示例#9
0
def blacklist_user(user, msid, reason):
	cm = ch.getMessage(msid)
	if cm is None or cm.user_id is None:
		return rp.Reply(rp.types.ERR_NOT_IN_CACHE)

	with db.modifyUser(id=cm.user_id) as user2:
		if user2.rank >= user.rank: return
		user2.setBlacklisted(reason)
	Sender.stop_invoked(user2) # do this before queueing new messages below
	_push_system_message(rp.Reply(rp.types.ERR_BLACKLISTED, reason=reason, contact=blacklist_contact), who=user2, reply_to=msid)
	Sender.delete(msid)
	logging.info("%s was blacklisted by %s for: %s", user2, user, reason)
	return rp.Reply(rp.types.SUCCESS)
示例#10
0
def promote_user(user, username2, rank):
    user2 = getUserByName(username2)
    if user2 is None:
        return rp.Reply(rp.types.ERR_NO_USER)

    if user2.rank >= rank: return
    with db.modifyUser(id=user2.id) as user2:
        user2.rank = rank
    if rank >= RANKS.admin:
        _push_system_message(rp.Reply(rp.types.PROMOTED_ADMIN), who=user2)
    elif rank >= RANKS.mod:
        _push_system_message(rp.Reply(rp.types.PROMOTED_MOD), who=user2)
    logging.info("%s was promoted by %s to: %d", user2, user, rank)
    return rp.Reply(rp.types.SUCCESS)
示例#11
0
def get_users(user):
	if user.rank < RANKS.mod:
		n = sum(1 for user in db.iterateUsers() if user.isJoined())
		return rp.Reply(rp.types.USERS_INFO, count=n)
	active, inactive, black = 0, 0, 0
	for user in db.iterateUsers():
		if user.isBlacklisted():
			black += 1
		elif not user.isJoined():
			inactive += 1
		else:
			active += 1
	return rp.Reply(rp.types.USERS_INFO_EXTENDED,
		active=active, inactive=inactive, blacklisted=black,
		total=active + inactive + black)
示例#12
0
def toggle_debug(user):
    with db.modifyUser(id=user.id) as user:
        user.debugEnabled = not user.debugEnabled
        new = user.debugEnabled
    return rp.Reply(rp.types.BOOLEAN_CONFIG,
                    description="Debug mode",
                    enabled=new)
示例#13
0
def give_karma(user, msid):
	cm = ch.getMessage(msid)
	if cm is None or cm.user_id is None:
		return rp.Reply(rp.types.ERR_NOT_IN_CACHE)

	if cm.hasUpvoted(user):
		return rp.Reply(rp.types.ERR_ALREADY_UPVOTED)
	elif user.id == cm.user_id:
		return rp.Reply(rp.types.ERR_UPVOTE_OWN_MESSAGE)
	cm.addUpvote(user)
	user2 = db.getUser(id=cm.user_id)
	with db.modifyUser(id=cm.user_id) as user2:
		user2.karma += KARMA_PLUS_ONE
	if not user2.hideKarma:
		_push_system_message(rp.Reply(rp.types.KARMA_NOTIFICATION), who=user2, reply_to=msid)
	return rp.Reply(rp.types.KARMA_THANK_YOU)
示例#14
0
def toggle_karma(user):
    with db.modifyUser(id=user.id) as user:
        user.hideKarma = not user.hideKarma
        new = user.hideKarma
    return rp.Reply(rp.types.BOOLEAN_CONFIG,
                    description="Karma notifications",
                    enabled=not new)
示例#15
0
def toggle_tripcode(user):
    with db.modifyUser(id=user.id) as user:
        user.tripcodeToggle = not user.tripcodeToggle
        new = user.tripcodeToggle
    return rp.Reply(rp.types.BOOLEAN_CONFIG,
                    description="Username (tripcode)",
                    enabled=new)
示例#16
0
def calc_spam_score(ev):
    if not allow_message_text(ev.text) or not allow_message_text(ev.caption):
        return 999
    c_user = UserContainer(ev.from_user)
    user_rank = RANKS[core.get_info(c_user).kwargs["rank"]]
    if ev.content_type in ("photo", "video", "gif", "sticker", "video/mp4",
                           "document") and user_rank <= 0:
        if (datetime.now() - core.get_info(c_user).kwargs["joined"]).days <= 1:
            return 999
        else:
            with db.modifyUser(
                    id=core.get_info(c_user).kwargs["real_id"]) as user:
                user.rank = RANKS.user_with_images
                core._push_system_message(rp.Reply(rp.types.IMAGES_ALLOWED),
                                          who=user)

    s = SCORE_BASE_MESSAGE
    if (ev.forward_from is not None or ev.forward_from_chat is not None
            or ev.json.get("forward_sender_name") is not None):
        s = SCORE_BASE_FORWARD

    if ev.content_type == "sticker":
        return SCORE_STICKER
    elif ev.content_type == "text":
        pass
    else:
        return s
    s += len(ev.text) * SCORE_TEXT_CHARACTER + ev.text.count(
        "\n") * SCORE_TEXT_LINEBREAK
    return s
示例#17
0
def send_signed_user_message(user, msg_score, text, reply_msid=None, tripcode=False):
	if not enable_signing:
		return rp.Reply(rp.types.ERR_COMMAND_DISABLED)
	if user.isInCooldown():
		return rp.Reply(rp.types.ERR_COOLDOWN, until=user.cooldownUntil)

	ok = spam_scores.increaseSpamScore(user.id, msg_score)
	if not ok:
		return rp.Reply(rp.types.ERR_SPAMMY)
	if not tripcode and sign_interval.total_seconds() > 1:
		last_used = sign_last_used.get(user.id, None)
		if last_used and (datetime.now() - last_used) < sign_interval:
			return rp.Reply(rp.types.ERR_SPAMMY_SIGN)
		sign_last_used[user.id] = datetime.now()

	if tripcode:
		if user.tripcode is None:
			return rp.Reply(rp.types.ERR_NO_TRIPCODE)
		tripname, tripcode = genTripcode(user.tripcode)
		m = rp.Reply(rp.types.TSIGNED_MSG, text=text, user_id=user.id, tripname=tripname, tripcode=tripcode)
	else:
		m = rp.Reply(rp.types.SIGNED_MSG, text=text, user_id=user.id, user_text=user.getFormattedName())

	msid = ch.assignMessageId(CachedMessage(user.id))
	Sender.reply(m, msid, None, user, reply_msid)
	return msid
示例#18
0
 def wrapper(c_user, *args, **kwargs):
     # fetch user from db
     try:
         user = db.getUser(id=c_user.id)
     except KeyError as e:
         return rp.Reply(rp.types.USER_NOT_IN_CHAT)
     # check for blacklist or absence
     if user.isBlacklisted():
         return rp.Reply(rp.types.ERR_BLACKLISTED,
                         reason=user.blacklistReason,
                         contact=blacklist_contact)
     elif not user.isJoined():
         return rp.Reply(rp.types.USER_NOT_IN_CHAT)
     # keep db entry up to date
     with db.modifyUser(id=user.id) as user:
         updateUserFromEvent(user, c_user)
     # call original function
     return func(user, *args, **kwargs)
示例#19
0
def user_join(c_user):
    try:
        user = db.getUser(id=c_user.id)
    except KeyError as e:
        user = None

    if user is not None:
        # check if user can't rejoin
        err = None
        if user.isBlacklisted():
            err = rp.Reply(rp.types.ERR_BLACKLISTED,
                           reason=user.blacklistReason,
                           contact=blacklist_contact)
        elif user.isJoined():
            err = rp.Reply(rp.types.USER_IN_CHAT)
        if err is not None:
            with db.modifyUser(id=user.id) as user:
                updateUserFromEvent(user, c_user)
            return err
        # user rejoins
        with db.modifyUser(id=user.id) as user:
            updateUserFromEvent(user, c_user)
            user.setLeft(False)
        logging.info("%s rejoined chat", user)
        return rp.Reply(rp.types.CHAT_JOIN)

    # create new user
    user = User()
    user.defaults()
    user.id = c_user.id
    updateUserFromEvent(user, c_user)
    if not any(db.iterateUserIds()):
        user.rank = RANKS.admin

    logging.info("%s joined chat", user)
    db.addUser(user)
    ret = [rp.Reply(rp.types.CHAT_JOIN)]

    motd = db.getSystemConfig().motd
    if motd != "":
        ret.append(rp.Reply(rp.types.CUSTOM, text=motd))

    return ret
示例#20
0
def warn_user(user, msid, delete=False):
	cm = ch.getMessage(msid)
	if cm is None or cm.user_id is None:
		return rp.Reply(rp.types.ERR_NOT_IN_CACHE)

	if not cm.warned:
		with db.modifyUser(id=cm.user_id) as user2:
			d = user2.addWarning()
			user2.karma -= KARMA_WARN_PENALTY
		_push_system_message(rp.Reply(rp.types.GIVEN_COOLDOWN, duration=d, deleted=delete), who=user2, reply_to=msid)
		cm.warned = True
	else:
		user2 = db.getUser(id=cm.user_id)
		if not delete: # allow deleting already warned messages
			return rp.Reply(rp.types.ERR_ALREADY_WARNED)
	if delete:
		Sender.delete(msid)
	logging.info("%s warned [%s]%s", user, user2.getObfuscatedId(), delete and " (message deleted)" or "")
	return rp.Reply(rp.types.SUCCESS)
示例#21
0
def uncooldown_user(user, oid2=None, username2=None):
	if oid2 is not None:
		user2 = getUserByOid(oid2)
		if user2 is None:
			return rp.Reply(rp.types.ERR_NO_USER_BY_ID)
	elif username2 is not None:
		user2 = getUserByName(username2)
		if user2 is None:
			return rp.Reply(rp.types.ERR_NO_USER)
	else:
		raise ValueError()

	if not user2.isInCooldown():
		return rp.Reply(rp.types.ERR_NOT_IN_COOLDOWN)
	with db.modifyUser(id=user2.id) as user2:
		user2.removeWarning()
		was_until = user2.cooldownUntil
		user2.cooldownUntil = None
	logging.info("%s removed cooldown from %s (was until %s)", user, user2, format_datetime(was_until))
	return rp.Reply(rp.types.SUCCESS)
示例#22
0
def get_info(user):
    params = {
        "id": user.getObfuscatedId(),
        "username": user.getFormattedName(),
        "rank_i": user.rank,
        "rank": RANKS.reverse[user.rank],
        "karma": user.karma,
        "warnings": user.warnings,
        "warnExpiry": user.warnExpiry,
        "cooldown": user.cooldownUntil if user.isInCooldown() else None,
    }
    return rp.Reply(rp.types.USER_INFO, **params)
示例#23
0
def send_signed_user_message(user,
                             msg_score,
                             text,
                             reply_msid=None,
                             tripcode=False):
    if not enable_signing:
        return rp.Reply(rp.types.ERR_COMMAND_DISABLED)
    if user.isInCooldown():
        return rp.Reply(rp.types.ERR_COOLDOWN, until=user.cooldownUntil)
    ok = spam_scores.increaseSpamScore(user.id, msg_score)
    if not ok:
        return rp.Reply(rp.types.ERR_SPAMMY)

    if tripcode:
        if user.tripcode is None:
            return rp.Reply(rp.types.ERR_NO_TRIPCODE)
        tripname, tripcode = genTripcode(user.tripcode)
        m = rp.Reply(rp.types.TSIGNED_MSG,
                     text=text,
                     user_id=user.id,
                     tripname=tripname,
                     tripcode=tripcode)
    else:
        m = rp.Reply(rp.types.SIGNED_MSG,
                     text=text,
                     user_id=user.id,
                     user_text=user.getFormattedName())

    msid = ch.assignMessageId(CachedMessage(user.id))
    Sender.reply(m, msid, None, user, reply_msid)
    return msid
示例#24
0
def prepare_user_message(user: User,
                         msg_score,
                         *,
                         is_media=False,
                         signed=False,
                         tripcode=False):
    # prerequisites
    if user.isInCooldown():
        return rp.Reply(rp.types.ERR_COOLDOWN, until=user.cooldownUntil)
    if (signed or tripcode) and not enable_signing:
        return rp.Reply(rp.types.ERR_COMMAND_DISABLED)
    if tripcode and user.tripcode is None:
        return rp.Reply(rp.types.ERR_NO_TRIPCODE)
    if is_media and user.rank < RANKS.mod and media_limit_period is not None:
        if (datetime.now() - user.joined) < media_limit_period:
            return rp.Reply(rp.types.ERR_MEDIA_LIMIT)

    ok = spam_scores.increaseSpamScore(user.id, msg_score)
    if not ok:
        return rp.Reply(rp.types.ERR_SPAMMY)

    # enforce signing cooldown
    if signed and sign_interval.total_seconds() > 1:
        last_used = sign_last_used.get(user.id, None)
        if last_used and (datetime.now() - last_used) < sign_interval:
            return rp.Reply(rp.types.ERR_SPAMMY_SIGN)
        sign_last_used[user.id] = datetime.now()

    return ch.assignMessageId(CachedMessage(user.id))
示例#25
0
def get_info(user):
    params = {
        "id": user.getObfuscatedId(),
        "username": user.getFormattedName(),
        "rank_i": user.rank,
        "rank": RANKS.reverse[user.rank],
        "karma": user.karma,
        "warnings": user.warnings,
        "warnExpiry": user.warnExpiry,
        "cooldown": user.cooldownUntil if user.isInCooldown() else None,
    }
    if enable_signing:
        params["tripcode"] = user.tripcode
    else:
        params['tripcode'] = "disabled"
    return rp.Reply(rp.types.USER_INFO, **params)
示例#26
0
def cmd_version(ev):
    send_answer(ev, rp.Reply(rp.types.PROGRAM_VERSION, version=VERSION), True)
示例#27
0
def cmd_adminhelp(ev):
    send_answer(ev, rp.Reply(rp.types.HELP_ADMIN), True)
示例#28
0
def cmd_modhelp(ev):
    send_answer(ev, rp.Reply(rp.types.HELP_MODERATOR), True)
示例#29
0
def send_admin_message(user, arg):
    text = arg + " ~<b>admins</b>"
    m = rp.Reply(rp.types.CUSTOM, text=text)
    _push_system_message(m)
    logging.info("%s sent admin message: %s", user, arg)
示例#30
0
def get_tripcode(user):
    if not enable_signing:
        return rp.Reply(rp.types.ERR_COMMAND_DISABLED)

    return rp.Reply(rp.types.TRIPCODE_INFO, tripcode=user.tripcode)