Show positive/negative karma separately
This commit is contained in:
parent
f59f29bc1e
commit
40e213b75a
2 changed files with 72 additions and 27 deletions
|
@ -130,7 +130,8 @@ class KarmaBot(Plugin):
|
||||||
await evt.reply("You don't have any karma :(")
|
await evt.reply("You don't have any karma :(")
|
||||||
return
|
return
|
||||||
index = self.karma_cache.find_index_from_top(evt.sender)
|
index = self.karma_cache.find_index_from_top(evt.sender)
|
||||||
await evt.reply(f"You have {karma} karma and are #{index} on the top list.")
|
await evt.reply(f"You have {karma.total} karma (+{karma.positive}/-{karma.negative})"
|
||||||
|
f" and are #{index} on the top list.")
|
||||||
|
|
||||||
async def view_karma_list(self, evt: MessageEvent) -> None:
|
async def view_karma_list(self, evt: MessageEvent) -> None:
|
||||||
list_type = evt.content.command.arguments[ARG_LIST]
|
list_type = evt.content.command.arguments[ARG_LIST]
|
||||||
|
@ -145,6 +146,7 @@ class KarmaBot(Plugin):
|
||||||
message = "#### Lowest karma\n\n"
|
message = "#### Lowest karma\n\n"
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
message += "\n".join(f"{index + 1}. [{mxid}](https://matrix.to/#/{mxid}): {karma}"
|
message += "\n".join(f"{index + 1}. [{karma.user_id}](https://matrix.to/#/{karma.user_id}):"
|
||||||
for index, (mxid, karma) in enumerate(karma_list))
|
f" {karma.total} (+{karma.positive}/-{karma.negative})"
|
||||||
|
for index, karma in enumerate(karma_list))
|
||||||
await evt.reply(message)
|
await evt.reply(message)
|
||||||
|
|
91
karma/db.py
91
karma/db.py
|
@ -32,14 +32,19 @@ class KarmaCache:
|
||||||
Karma: Type['Karma'] = None
|
Karma: Type['Karma'] = None
|
||||||
|
|
||||||
user_id: UserID = Column(String(255), primary_key=True)
|
user_id: UserID = Column(String(255), primary_key=True)
|
||||||
karma: int = Column(Integer)
|
total: int = Column(Integer)
|
||||||
|
positive: int = Column(Integer)
|
||||||
|
negative: int = Column(Integer)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_karma(cls, user_id: UserID) -> Optional[int]:
|
def get_karma(cls, user_id: UserID, conn: Optional[Connection] = None
|
||||||
rows = cls.db.execute(select([cls.c.karma]).where(cls.c.user_id == user_id))
|
) -> Optional['KarmaCache']:
|
||||||
|
if not conn:
|
||||||
|
conn = cls.db
|
||||||
|
rows = conn.execute(cls.t.select().where(cls.c.user_id == user_id))
|
||||||
try:
|
try:
|
||||||
row = next(rows)
|
user_id, total, positive, negative = next(rows)
|
||||||
return row[0]
|
return cls(user_id=user_id, total=total, positive=positive, negative=negative)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -57,17 +62,21 @@ class KarmaCache:
|
||||||
cls._set_karma(user_id, karma, conn)
|
cls._set_karma(user_id, karma, conn)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_high(cls, limit: int = 10) -> List[Tuple[UserID, int]]:
|
def get_high(cls, limit: int = 10) -> List['KarmaCache']:
|
||||||
return list(cls.db.execute(cls.t.select().order_by(cls.c.karma.desc()).limit(limit)))
|
return [cls(user_id=user_id, total=total, positive=positive, negative=negative)
|
||||||
|
for (user_id, total, positive, negative)
|
||||||
|
in cls.db.execute(cls.t.select().order_by(cls.c.total.desc()).limit(limit))]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_low(cls, limit: int = 10) -> List[Tuple[UserID, int]]:
|
def get_low(cls, limit: int = 10) -> List['KarmaCache']:
|
||||||
return list(cls.db.execute(cls.t.select().order_by(cls.c.karma.asc()).limit(limit)))
|
return [cls(user_id=user_id, total=total, positive=positive, negative=negative)
|
||||||
|
for (user_id, total, positive, negative)
|
||||||
|
in cls.db.execute(cls.t.select().order_by(cls.c.total.asc()).limit(limit))]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def find_index_from_top(cls, user_id: UserID) -> int:
|
def find_index_from_top(cls, user_id: UserID) -> int:
|
||||||
i = 0
|
i = 0
|
||||||
for (found,) in cls.db.execute(select([cls.c.user_id]).order_by(cls.c.karma.desc())):
|
for (found,) in cls.db.execute(select([cls.c.user_id]).order_by(cls.c.total.desc())):
|
||||||
i += 1
|
i += 1
|
||||||
if found == user_id:
|
if found == user_id:
|
||||||
return i
|
return i
|
||||||
|
@ -78,19 +87,33 @@ class KarmaCache:
|
||||||
with cls.db.begin() as txn:
|
with cls.db.begin() as txn:
|
||||||
cls.set_karma(user_id, sum(entry.value for entry in cls.Karma.all(user_id)), txn)
|
cls.set_karma(user_id, sum(entry.value for entry in cls.Karma.all(user_id)), txn)
|
||||||
|
|
||||||
|
def update(self, conn: Optional[Connection]) -> None:
|
||||||
|
if not conn:
|
||||||
|
conn = self.db
|
||||||
|
conn.execute(self.t.update()
|
||||||
|
.where(self.c.user_id == self.user_id)
|
||||||
|
.values(total=self.total, positive=self.positive, negative=self.negative))
|
||||||
|
|
||||||
|
def insert(self, conn: Optional[Connection] = None) -> None:
|
||||||
|
if not conn:
|
||||||
|
conn = self.db
|
||||||
|
conn.execute(self.t.insert().values(user_id=self.user_id, total=self.total,
|
||||||
|
positive=self.positive, negative=self.negative))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update(cls, user_id: UserID, value_diff: int, conn: Optional[Connection],
|
def update_direct(cls, user_id: UserID, total_diff: int, positive_diff: int, negative_diff: int,
|
||||||
ignore_if_not_exist: bool = False) -> None:
|
conn: Optional[Connection] = None, ignore_if_not_exist: bool = False) -> None:
|
||||||
if not conn:
|
if not conn:
|
||||||
conn = cls.db
|
conn = cls.db
|
||||||
existing = conn.execute(select([cls.c.karma]).where(cls.c.user_id == user_id))
|
existing = cls.get_karma(user_id, conn)
|
||||||
try:
|
if existing:
|
||||||
karma = next(existing)[0] + value_diff
|
existing.total += total_diff
|
||||||
conn.execute(cls.t.update().where(cls.c.user_id == user_id).values(karma=karma))
|
existing.positive += positive_diff
|
||||||
except StopIteration:
|
existing.negative += negative_diff
|
||||||
if ignore_if_not_exist:
|
existing.update(conn)
|
||||||
return
|
elif not ignore_if_not_exist:
|
||||||
conn.execute(cls.t.insert().values(user_id=user_id, karma=value_diff))
|
cls(user_id=user_id, total=total_diff, positive=positive_diff,
|
||||||
|
negative=negative_diff).insert(conn)
|
||||||
|
|
||||||
|
|
||||||
class Karma:
|
class Karma:
|
||||||
|
@ -136,7 +159,10 @@ class Karma:
|
||||||
txn.execute(self.t.delete().where(and_(
|
txn.execute(self.t.delete().where(and_(
|
||||||
self.c.given_to == self.given_to, self.c.given_by == self.given_by,
|
self.c.given_to == self.given_to, self.c.given_by == self.given_by,
|
||||||
self.c.given_in == self.given_in, self.c.given_for == self.given_for)))
|
self.c.given_in == self.given_in, self.c.given_for == self.given_for)))
|
||||||
self.KarmaCache.update(self.given_to, self.value, txn, ignore_if_not_exist=True)
|
self.KarmaCache.update_direct(self.given_to, total_diff=-self.value,
|
||||||
|
positive_diff=-self.value if self.value > 0 else 0,
|
||||||
|
negative_diff=self.value if self.value < 0 else 0,
|
||||||
|
conn=txn, ignore_if_not_exist=True)
|
||||||
|
|
||||||
def insert(self) -> None:
|
def insert(self) -> None:
|
||||||
self.given_at = int(time() * 1000)
|
self.given_at = int(time() * 1000)
|
||||||
|
@ -145,18 +171,35 @@ class Karma:
|
||||||
given_in=self.given_in, given_for=self.given_for,
|
given_in=self.given_in, given_for=self.given_for,
|
||||||
given_from=self.given_from, value=self.value,
|
given_from=self.given_from, value=self.value,
|
||||||
given_at=self.given_at, content=self.content))
|
given_at=self.given_at, content=self.content))
|
||||||
self.KarmaCache.update(self.given_to, self.value, txn)
|
self.KarmaCache.update_direct(self.given_to, total_diff=self.value,
|
||||||
|
positive_diff=self.value if self.value > 0 else 0,
|
||||||
|
negative_diff=-self.value if self.value < 0 else 0,
|
||||||
|
conn=txn)
|
||||||
|
|
||||||
def update(self, new_value: int) -> None:
|
def update(self, new_value: int) -> None:
|
||||||
self.given_at = int(time() * 1000)
|
self.given_at = int(time() * 1000)
|
||||||
value_diff = new_value - self.value
|
old_value = self.value
|
||||||
self.value = new_value
|
self.value = new_value
|
||||||
with self.db.begin() as txn:
|
with self.db.begin() as txn:
|
||||||
txn.execute(self.t.update().where(and_(
|
txn.execute(self.t.update().where(and_(
|
||||||
self.c.given_to == self.given_to, self.c.given_by == self.given_by,
|
self.c.given_to == self.given_to, self.c.given_by == self.given_by,
|
||||||
self.c.given_in == self.given_in, self.c.given_for == self.given_for
|
self.c.given_in == self.given_in, self.c.given_for == self.given_for
|
||||||
)).values(given_from=self.given_from, value=self.value, given_at=self.given_at))
|
)).values(given_from=self.given_from, value=self.value, given_at=self.given_at))
|
||||||
self.KarmaCache.update(self.given_to, value_diff, txn)
|
total_diff = new_value - old_value
|
||||||
|
positive_diff = 0
|
||||||
|
negative_diff = 0
|
||||||
|
if old_value > 0:
|
||||||
|
positive_diff -= old_value
|
||||||
|
elif old_value < 0:
|
||||||
|
negative_diff += old_value
|
||||||
|
if new_value > 0:
|
||||||
|
positive_diff += new_value
|
||||||
|
elif new_value < 0:
|
||||||
|
negative_diff -= new_value
|
||||||
|
self.KarmaCache.update_direct(self.given_to, total_diff=total_diff,
|
||||||
|
positive_diff=positive_diff,
|
||||||
|
negative_diff=negative_diff,
|
||||||
|
conn=txn)
|
||||||
|
|
||||||
|
|
||||||
class Version:
|
class Version:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue