migration prep
This commit is contained in:
parent
640a274146
commit
c220b5b590
45
changelog.md
Normal file
45
changelog.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Changelog for Version 2.0
|
||||
|
||||
## TL;DR
|
||||
- Poll creation now interactive
|
||||
- New prefix: **pm!** (can be customized)
|
||||
- All commands and roles have been changed, check **pm!help**
|
||||
|
||||
## Complete Overhaul
|
||||
- Voting is no longer done per text, but by using reactions
|
||||
- Poll creation has been streamlined and is now interactive
|
||||
- An exhaustive pm!help function
|
||||
|
||||
## New features
|
||||
- Prepare polls in advance and schedule them or activate them on demand
|
||||
- A quick poll function with default settings
|
||||
- Multiple Choice as new settings (allow more than one answer)
|
||||
|
||||
## Full Private Message and Multi Server Support
|
||||
- **Every command can be used in private messages with pollmaster**
|
||||
- This works even if you are in many servers with the bot
|
||||
- Context sensitive detection of which server(s) are affected
|
||||
- Promt the user for a server if still ambiguous
|
||||
|
||||
## New Look
|
||||
- Complete visual overhaul for every aspect
|
||||
- New custom icons
|
||||
|
||||
## New Database
|
||||
- Changed the way all the polls are stored
|
||||
- Added server specific configurations
|
||||
|
||||
## New Prefix
|
||||
- **pm!** is the new default prefix
|
||||
- Prefix can be customized for each server
|
||||
|
||||
## New roles and permissions
|
||||
- Users with "Manage Server" permissions can now use all functions regardless of pollmaster specific permissions
|
||||
- Two new type of roles: *polladmin* and *polluser*
|
||||
- They can be set with *!polladmin role* and *!polluser role*
|
||||
- More infos pm!help -> configuration
|
||||
- The *pollmaster* role is deprecated
|
||||
|
||||
## Compability
|
||||
- Most databases will be preserved and converted to the new format
|
||||
- If your server lost data, please join the support server or contact the developer
|
||||
18
cogs/poll.py
18
cogs/poll.py
@ -705,10 +705,18 @@ class Poll:
|
||||
|
||||
|
||||
async def to_dict(self):
|
||||
if self.channel is None:
|
||||
cid = 0
|
||||
else:
|
||||
cid = self.channel.id
|
||||
if self.author is None:
|
||||
aid = 0
|
||||
else:
|
||||
aid = self.author.id
|
||||
return {
|
||||
'server_id': str(self.server.id),
|
||||
'channel_id': str(self.channel.id),
|
||||
'author': str(self.author.id),
|
||||
'channel_id': str(cid),
|
||||
'author': str(aid),
|
||||
'name': self.name,
|
||||
'short': self.short,
|
||||
'anonymous': self.anonymous,
|
||||
@ -827,9 +835,9 @@ class Poll:
|
||||
return None
|
||||
|
||||
async def from_dict(self, d):
|
||||
self.server = self.bot.get_server(d['server_id'])
|
||||
self.channel = self.bot.get_channel(d['channel_id'])
|
||||
self.author = await self.bot.get_user_info(d['author'])
|
||||
self.server = self.bot.get_server(str(d['server_id']))
|
||||
self.channel = self.bot.get_channel(str(d['channel_id']))
|
||||
self.author = await self.bot.get_user_info(str(d['author']))
|
||||
self.name = d['name']
|
||||
self.short = d['short']
|
||||
self.anonymous = d['anonymous']
|
||||
|
||||
@ -215,7 +215,8 @@ class PollControls:
|
||||
query = self.bot.db.polls.find({'server_id': str(server.id), 'active': False})
|
||||
|
||||
if query is not None:
|
||||
polls = [poll async for poll in query]
|
||||
# sort by newest first
|
||||
polls = [poll async for poll in query.sort('_id', -1)]
|
||||
else:
|
||||
return
|
||||
|
||||
@ -228,9 +229,9 @@ class PollControls:
|
||||
# await self.bot.say(embed=await self.embed_list_paginated(polls, item_fct, embed))
|
||||
# msg = await self.embed_list_paginated(ctx, polls, item_fct, embed, per_page=8)
|
||||
pre = await get_server_pre(self.bot, server)
|
||||
footer_text = '' # f'type {pre}show <label> to display a poll.
|
||||
footer_text = f'type {pre}show <label> to display a poll. '
|
||||
msg = await embed_list_paginated(self.bot, pre, polls, item_fct, embed, footer_prefix=footer_text,
|
||||
per_page=8)
|
||||
per_page=10)
|
||||
else:
|
||||
p = await Poll.load_from_db(self.bot, str(server.id), short)
|
||||
if p is not None:
|
||||
@ -347,10 +348,10 @@ class PollControls:
|
||||
async def on_reaction_add(self, reaction, user):
|
||||
if user != self.bot.user:
|
||||
try:
|
||||
if reaction.emoji.startswith(('⏪', '⏩')):
|
||||
if isinstance(reaction.emoji, str) and reaction.emoji.startswith(('⏪', '⏩')):
|
||||
return
|
||||
except:
|
||||
print("fail emoji",reaction.emoji)
|
||||
logger.warning("fail emoji "+str(reaction.emoji))
|
||||
|
||||
# only look at our polls
|
||||
try:
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
import datetime
|
||||
import os
|
||||
import traceback
|
||||
import logging
|
||||
import aiohttp
|
||||
import discord
|
||||
|
||||
|
||||
from discord.ext import commands
|
||||
from motor.motor_asyncio import AsyncIOMotorClient
|
||||
|
||||
from essentials.multi_server import get_pre
|
||||
from essentials.settings import SETTINGS
|
||||
|
||||
from utils.import_old_database import import_old_database
|
||||
|
||||
bot_config = {
|
||||
'command_prefix': get_pre,
|
||||
@ -60,12 +59,29 @@ async def on_ready():
|
||||
db_server_ids = [entry['_id'] async for entry in bot.db.config.find({}, {})]
|
||||
for server in bot.servers:
|
||||
if server.id not in db_server_ids:
|
||||
|
||||
# create new config entry
|
||||
await bot.db.config.update_one(
|
||||
{'_id': str(server.id)},
|
||||
{'$set': {'prefix': 'pm!', 'admin_role': 'polladmin', 'user_role': 'polluser'}},
|
||||
upsert=True
|
||||
)
|
||||
|
||||
#await import_old_database(bot, server)
|
||||
# text = 'Test Update Notice. Please Ignore.'
|
||||
text = "Dear Server Admin!\n" \
|
||||
"After more than a year in the field, today Pollmaster received it's first big update and I am excited to present you the new Version!\n" \
|
||||
"**TL;DR** A massive overhaul of every function. The new (now customizable) prefix is pm! and you can find the rest of commands with pm!help\n\n" \
|
||||
"Here are some more highlights:\n" \
|
||||
"🔹 Voting is no longer done per text, but by using reactions\n" \
|
||||
"🔹 Creating new polls is now an interactive process instead of command lines\n" \
|
||||
"🔹 There is now a settings for multiple choice polls\n" \
|
||||
"🔹 You can use all the commands in a private message with Pollmaster to reduce spam in your channels\n\n" \
|
||||
"For the full changelog, please visit: "
|
||||
# embed = discord.Embed(title="Pollmaster updated to version 2!", description=text, color=SETTINGS.color)
|
||||
# await bot.send_message(server.owner, embed= embed)
|
||||
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_command_error(e, ctx):
|
||||
@ -87,6 +103,7 @@ async def on_command_error(e, ctx):
|
||||
|
||||
# log error
|
||||
logger.error(f'{type(e).__name__}: {e}\n{"".join(traceback.format_tb(e.__traceback__))}')
|
||||
# raise(e)
|
||||
|
||||
if SETTINGS.msg_errors:
|
||||
# send discord message for unexpected errors
|
||||
|
||||
79
utils/import_old_database.py
Normal file
79
utils/import_old_database.py
Normal file
@ -0,0 +1,79 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
|
||||
import pytz
|
||||
|
||||
|
||||
async def import_old_database(bot, server):
|
||||
"""try to import the old database"""
|
||||
try:
|
||||
clean_server = str(server).replace("/", "")
|
||||
while clean_server.startswith("."):
|
||||
clean_server = clean_server[1:]
|
||||
fn = 'backup/' + clean_server + '.json'
|
||||
with open(fn, 'r') as infile:
|
||||
polls = json.load(infile)
|
||||
for p in polls:
|
||||
#print(polls[p]['short'])
|
||||
wr = []
|
||||
wn = []
|
||||
for r, n in polls[p]['weights'].items():
|
||||
wr.append(r)
|
||||
try:
|
||||
if n.is_integer():
|
||||
n = int(n)
|
||||
except:
|
||||
pass
|
||||
wn.append(n)
|
||||
created = datetime.datetime.strptime(polls[p]['datestarted'], '%d-%m-%Y %H:%M').replace(tzinfo=pytz.utc)
|
||||
if polls[p]['duration'] == 0:
|
||||
duration = 0
|
||||
else:
|
||||
duration = created + datetime.timedelta(hours=float(polls[p]['duration']))
|
||||
votes = {}
|
||||
for u,o in polls[p]['votes'].items():
|
||||
# get weight
|
||||
user = server.get_member(u)
|
||||
weight = 1
|
||||
if wr.__len__() > 0:
|
||||
valid_weights = [wn[wr.index(r)] for r in
|
||||
list(set([n.name for n in user.roles]).intersection(set(wr)))]
|
||||
if valid_weights.__len__() > 0:
|
||||
#print(wr, wn)
|
||||
weight = max(valid_weights)
|
||||
choices = []
|
||||
if o in polls[p]['options']:
|
||||
choices = [polls[p]['options'].index(o)]
|
||||
votes[u] = {'weight': weight, 'choices': choices}
|
||||
|
||||
new_format = {
|
||||
'server_id': str(server.id),
|
||||
'channel_id': str(polls[p]['channel']),
|
||||
'author': str(polls[p]['author']),
|
||||
'name': polls[p]['name'],
|
||||
'short': polls[p]['short'],
|
||||
'anonymous': polls[p]['anonymous'],
|
||||
'reaction': True,
|
||||
'multiple_choice': False,
|
||||
'options_reaction': polls[p]['options'],
|
||||
'reaction_default': False,
|
||||
'roles': polls[p]['roles'],
|
||||
'weights_roles': wr,
|
||||
'weights_numbers': wn,
|
||||
'duration': duration,
|
||||
'duration_tz': 'UTC',
|
||||
'time_created': created,
|
||||
'open': polls[p]['open'],
|
||||
'active': True,
|
||||
'activation': 0,
|
||||
'activation_tz': 'UTC',
|
||||
'votes': votes
|
||||
}
|
||||
await bot.db.polls.update_one({'server_id': str(server.id), 'short': polls[p]['short']},
|
||||
{'$set': new_format}, upsert=True)
|
||||
#os.remove(fn)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(e)
|
||||
@ -39,6 +39,6 @@ async def embed_list_paginated(bot, pre, items, item_fct, base_embed, footer_pre
|
||||
if res is None:
|
||||
return
|
||||
elif res.reaction.emoji == '⏪' and start > 0:
|
||||
await embed_list_paginated(bot, pre, items, item_fct, base_embed, msg=msg, start=start-per_page, per_page=per_page)
|
||||
await embed_list_paginated(bot, pre, items, item_fct, base_embed, footer_prefix=footer_prefix, msg=msg, start=start-per_page, per_page=per_page)
|
||||
elif res.reaction.emoji == '⏩' and items.__len__() > start+per_page:
|
||||
await embed_list_paginated(bot, pre, items, item_fct, base_embed, msg=msg, start=start+per_page, per_page=per_page)
|
||||
await embed_list_paginated(bot, pre, items, item_fct, base_embed, footer_prefix=footer_prefix, msg=msg, start=start+per_page, per_page=per_page)
|
||||
Loading…
Reference in New Issue
Block a user