Skip to content

Commit

Permalink
LilSholex 4.9
Browse files Browse the repository at this point in the history
- Updated Django and other packages
- LilSholex image is based on Python 3.9.6 now !
- Using MySQL 8.0.26 as database
- Added Voice Review feature for admins
- Fixed bugs and issues
  • Loading branch information
RealNitroZeus committed Aug 14, 2021
1 parent 9f0c550 commit 542beba
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 100 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.9.5
FROM python:3.9.6
# Addding requirements
COPY requirements.txt requirements.txt
RUN pip install -U pip && pip install -r requirements.txt --no-cache-dir
Expand Down
10 changes: 4 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.8"
services:
db:
image: mysql:8.0.25
image: mysql:8.0.26
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD_FILE: "/run/secrets/db_password"
Expand Down Expand Up @@ -92,12 +92,10 @@ services:
- ssl_key
- dhparam
ports:
- 443:443/tcp
- 80:80/tcp
- "443:443/tcp"
- "80:80/tcp"
gunicorn:
image: ghcr.io/sholex-team/lilsholex/lilsholex:4.6
command: "gunicorn --workers=1 --threads=2 --bind=0.0.0.0:8080 \
--access-logfile /dev/null --error-logfile /dev/stderr LilSholex.wsgi"
image: ghcr.io/sholex-team/lilsholex/lilsholex:4.9
networks:
- db_django
- nginx_lilsholex
Expand Down
12 changes: 7 additions & 5 deletions persianmeme/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,18 +184,20 @@ def add_fake_deny_votes(self, request, queryset):
add_fake_deny_votes.allowed_permissions = change_permission
date_hierarchy = 'date'
list_display = (
'id', 'name', 'sender', 'votes', 'status', 'usage_count',count_deny_votes, count_accept_votes, count_tags
'id', 'name', 'sender', 'votes', 'status', 'usage_count', count_deny_votes, count_accept_votes, count_tags
)
list_filter = ('status', 'voice_type')
list_filter = ('status', 'voice_type', 'reviewed')
search_fields = ('name', 'sender__chat_id', 'file_id', 'file_unique_id', 'id', 'sender__user_id')
actions = (export_json, accept_vote, deny_vote, add_fake_deny_votes)
list_per_page = 15
readonly_fields = ('id', 'date')
raw_id_fields = ('sender', 'voters', 'accept_vote', 'deny_vote', 'tags')
raw_id_fields = ('sender', 'voters', 'accept_vote', 'deny_vote', 'tags', 'assigned_admin')
fieldsets = (
('Information', {'fields': ('id', 'file_id', 'name', 'file_unique_id', 'date', 'sender', 'tags')}),
('Information', {'fields': (
'id', 'file_id', 'name', 'file_unique_id', 'date', 'sender', 'tags', 'assigned_admin'
)}),
('Status', {'fields': (
'status', 'votes', 'voice_type', 'voters', 'accept_vote', 'deny_vote', 'usage_count'
'status', 'votes', 'voice_type', 'voters', 'accept_vote', 'deny_vote', 'usage_count', 'reviewed'
)})
)

Expand Down
54 changes: 40 additions & 14 deletions persianmeme/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
en_back,
owner,
user as user_keyboard,
manage_suggestions
manage_suggestions,
voice_review
)
from .types import InvalidVoiceTag, LongVoiceTag, TooManyVoiceTags
from string import punctuation
from itertools import combinations
from django.db.models import Q, Case, When, BooleanField
from .types import ObjectType
from requests import Session
from .tasks import revoke_review


class User(Base):
Expand Down Expand Up @@ -61,17 +63,16 @@ def get_user(self):
self.__ads = models.Ad.objects.exclude(seen=user)
return user

def delete_semi_active(self, file_unique_id: str):
if (result := models.Voice.objects.filter(
file_unique_id=file_unique_id, status=models.Voice.Status.SEMI_ACTIVE
)).exists():
result.first().delete(admin=self.database)
return True
return False
def delete_current_voice(self):
if self.database.current_voice:
self.database.current_voice.delete(admin=self.database)
self.send_message(translations.admin_messages['deleted'])
else:
self.send_message(translations.admin_messages['deleted_before'])

def delete_voice(self, file_unique_id):
if (result := models.Voice.objects.filter(
file_unique_id=file_unique_id, voice_type=models.Voice.Type.NORMAL, status__in=models.PUBLIC_STATUS
file_unique_id=file_unique_id, voice_type=models.Voice.Type.NORMAL, status=models.Voice.Status.ACTIVE
)).exists():
result.first().delete(admin=self.database)

Expand Down Expand Up @@ -164,7 +165,7 @@ def get_voices(self, query: str, offset: str):
Q(id=target_voice_id) & ((
Q(voice_type=models.Voice.Type.PRIVATE) &
Q(sender=self.database)
) | Q(voice_type=models.Voice.Type.NORMAL)) & Q(status__in=models.PUBLIC_STATUS)
) | Q(voice_type=models.Voice.Type.NORMAL)) & Q(status=models.Voice.Status.ACTIVE)
))], str())
except models.Voice.DoesNotExist:
return list(), str()
Expand Down Expand Up @@ -196,10 +197,10 @@ def get_voices(self, query: str, offset: str):
queries & Q(sender=self.database) & Q(voice_type=models.Voice.Type.PRIVATE)
).annotate(is_name=is_name).order_by('-is_name', self.database.voice_order).distinct(),
lambda: self.database.favorite_voices.values_list('id', 'file_id', 'name').filter(
queries & Q(status__in=models.PUBLIC_STATUS)
queries & Q(status=models.Voice.Status.ACTIVE)
).annotate(is_name=is_name).order_by('-is_name', self.database.voice_order).distinct(),
lambda: models.Voice.objects.values_list('id', 'file_id', 'name').filter(
queries & Q(status__in=models.PUBLIC_STATUS) & Q(voice_type=models.Voice.Type.NORMAL)
queries & Q(status=models.Voice.Status.ACTIVE) & Q(voice_type=models.Voice.Type.NORMAL)
).annotate(is_name=is_name).order_by('-is_name', self.database.voice_order).distinct()
)
if len(splinted_offset := offset.split(':')) != len(result_sets):
Expand Down Expand Up @@ -274,7 +275,7 @@ def get_favorite_voice(self, voice_id: str):

def get_suggested_voice(self, voice_id: str):
return models.Voice.objects.get(
id=voice_id, status__in=models.PUBLIC_STATUS, voice_type=models.Voice.Type.NORMAL, sender=self.database
id=voice_id, status=models.Voice.Status.ACTIVE, voice_type=models.Voice.Type.NORMAL, sender=self.database
)

def delete_private_voice(self):
Expand Down Expand Up @@ -553,7 +554,7 @@ def add_recent_voice(self, voice: models.Voice):

def send_ordered_voice_list(self, ordering: models.User.VoiceOrder):
ordered_voices = models.Voice.objects.filter(
status__in=models.PUBLIC_STATUS, voice_type='n'
status=models.Voice.Status.ACTIVE, voice_type='n'
).order_by(ordering)[:12]
return self.send_message(
make_list_string(ObjectType.PLAYLIST_VOICE, ordered_voices), make_voice_list(ordered_voices)
Expand Down Expand Up @@ -593,3 +594,28 @@ def check_current_voice(self):
self.go_back()
return False
return True

def assign_voice(self):
if (assigned_voice := models.Voice.objects.filter(
assigned_admin=self.database, reviewed=False, voice_type=models.Voice.Type.NORMAL
)).exists():
self.database.current_voice = assigned_voice.first()
elif (new_voice := models.Voice.objects.filter(
assigned_admin=None,
reviewed=False,
status=models.Voice.Status.ACTIVE,
voice_type=models.Voice.Type.NORMAL
)).exists():
self.database.current_voice = new_voice.first()
self.database.current_voice.assigned_admin = self.database
self.database.current_voice.save()
revoke_review(self.database.current_voice.id)
else:
self.send_message(translations.admin_messages['no_voice_to_review'])
return False
self.send_message(
translations.admin_messages['review_the_voice'],
voice_review,
self.database.current_voice.send_voice(self.database.chat_id, False, self._session)
)
return True
4 changes: 2 additions & 2 deletions persianmeme/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def get_vote(file_unique_id):
def get_voice(file_unique_id: str, voice_type=models.Voice.Type.NORMAL):
if (target_voice := models.Voice.objects.filter(
file_unique_id=file_unique_id,
status__in=models.PUBLIC_STATUS,
status=models.Voice.Status.ACTIVE,
voice_type=voice_type
)).exists():
return target_voice.first()
Expand All @@ -38,7 +38,7 @@ def get_admin_voice(voice_id: int):


def count_voices():
voices_count = models.Voice.objects.filter(status__in=models.PUBLIC_STATUS).count()
voices_count = models.Voice.objects.filter(status=models.Voice.Status.ACTIVE).count()
return f'All voices count : {voices_count}'


Expand Down
9 changes: 6 additions & 3 deletions persianmeme/keyboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
['Get Voice', 'Get User'],
['Add Ad', 'Delete Ad', 'Edit Ad'],
['Accept Voice', 'Ban Vote', 'Deny Voice'],
['Edit Voice', 'File ID'],
['Messages', 'Accepted', 'Delete Requests']
['Edit Voice', 'File ID', 'Voice Review'],
['Messages', 'Delete Requests']
], 'resize_keyboard': True}
user = {'keyboard': [
['راهنما 🔰'],
Expand Down Expand Up @@ -50,7 +50,10 @@
['بازگشت 🔙']
], 'resize_keyboard': True}
manage_voice = {'keyboard': [['حذف ویس ❌', 'گوش دادن به ویس 🎧'], ['بازگشت 🔙']], 'resize_keyboard': True}
edit_voice = {'keyboard': [['Edit Name', 'Edit Tags'], ['Back 🔙']], 'resize_keyboard': True}
edit_voice = {'keyboard': [['Edit Name', 'Edit Tags'], ['Done ✔'], ['Back 🔙']], 'resize_keyboard': True}
voice_review = {'keyboard': [
['Edit Name', 'Edit Tags'], ['Delete 🗑', 'Check the Voice'], ['Done ✔', 'Done and Next ⏭'], ['Back 🔙']
], 'resize_keyboard': True}


def voice(accept_count: int = 0, deny_count: int = 0):
Expand Down
32 changes: 17 additions & 15 deletions persianmeme/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
from urllib.parse import urlencode
import requests
from django.conf import settings
from django.db import models
Expand Down Expand Up @@ -68,6 +67,7 @@ class Menu(models.IntegerChoices):
ADMIN_EDIT_VOICE_NAME = 46, 'Admin Edit Voice Name',
ADMIN_EDIT_VOICE_TAGS = 47, 'Admin Edit Voice Tags',
ADMIN_FILE_ID = 48, 'Admin File ID'
ADMIN_VOICE_REVIEW = 54, 'Admin Voice Review'
USER_MAIN = 19, 'User Main'
USER_CONTACT_ADMIN = 20, 'User Contact Admin'
USER_SUGGEST_VOICE_NAME = 21, 'User Suggest Voice Name'
Expand Down Expand Up @@ -146,7 +146,6 @@ class Voice(models.Model):
class Status(models.TextChoices):
ACTIVE = 'a', 'Active'
PENDING = 'p', 'Pending'
SEMI_ACTIVE = 's', 'Semi Active'

class Type(models.TextChoices):
NORMAL = 'n', 'Normal'
Expand Down Expand Up @@ -177,7 +176,7 @@ def delete(self, *args, **kwargs):
file_id = models.CharField(max_length=200, verbose_name='Voice File ID')
file_unique_id = models.CharField(max_length=100, verbose_name='Voice Unique ID')
name = models.CharField(max_length=200)
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='senders')
sender = models.ForeignKey(User, models.CASCADE, related_name='senders')
voters = models.ManyToManyField(User, related_name='voters', blank=True)
votes = models.IntegerField(default=0, verbose_name='Up Votes')
status = models.CharField(max_length=1, choices=Status.choices)
Expand All @@ -187,6 +186,10 @@ def delete(self, *args, **kwargs):
deny_vote = models.ManyToManyField(User, 'deny_vote_users', blank=True, verbose_name='Deny Votes')
tags = models.ManyToManyField(VoiceTag, 'voice_tags', blank=True)
usage_count = models.PositiveIntegerField('Usage Count', default=0)
assigned_admin = models.ForeignKey(
User, models.SET_NULL, 'voice_admin', verbose_name='Assigned Admin', null=True, blank=True
)
reviewed = models.BooleanField('Is Reviewed', default=False)

class Meta:
db_table = 'persianmeme_voices'
Expand All @@ -196,7 +199,7 @@ def __str__(self):
return f'{self.name}:{self.file_id}'

def user_accept(self):
self.status = self.Status.SEMI_ACTIVE
self.status = self.Status.ACTIVE
self.save()
self.accept_vote.clear()
self.deny_vote.clear()
Expand All @@ -209,13 +212,13 @@ def user_deny(self):

def accept(self):
from .functions import send_message
self.status = self.Status.SEMI_ACTIVE
self.status = self.Status.ACTIVE
self.save()
self.accept_vote.clear()
self.deny_vote.clear()
send_message(self.sender.chat_id, translations.user_messages['voice_accepted'])
for admin in User.objects.filter(rank=User.Rank.ADMIN):
send_message(admin.chat_id, translations.admin_messages['new_voice_accepted'])
send_message(admin.chat_id, translations.admin_messages['review_required'])

def deny(self):
from .functions import send_message
Expand All @@ -236,19 +239,19 @@ def edit_vote_count(self):
break

@sync_fix
def send_voice(self, session: requests.Session) -> int:
def send_voice(self, chat_id: int, send_voice_keyboard, session: requests.Session) -> int:
tags_string = str()
for tag in self.tags.all():
tags_string += f'\n<code>{tag.tag}</code>'
encoded = urlencode({
voice_dict = {
'caption': f'<b>Voice Name</b>: {self.name}\n\n<b>Voice Tags 👇</b>{tags_string}',
'parse_mode': 'Html',
'reply_markup': json.dumps(voice_keyboard())
})
with session.get(
f'https://api.telegram.org/bot{settings.MEME}/sendVoice?chat_id={settings.MEME_CHANNEL}&'
f'voice={self.file_id}&{encoded}'
) as response:
'voice': self.file_id,
'chat_id': chat_id
}
if send_voice_keyboard:
voice_dict['reply_markup'] = json.dumps(voice_keyboard())
with session.get(f'https://api.telegram.org/bot{settings.MEME}/sendVoice', params=voice_dict) as response:
response = response.json()
if response['ok']:
return response['result']['message_id']
Expand Down Expand Up @@ -343,5 +346,4 @@ class Meta:
db_table = 'persianmeme_user_recent_voices'


PUBLIC_STATUS = (Voice.Status.ACTIVE, Voice.Status.SEMI_ACTIVE)
BOT_ADMINS = (User.Rank.ADMIN, User.Rank.OWNER)
7 changes: 7 additions & 0 deletions persianmeme/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
'keyboard': keyboards.edit_voice,
'before': 'send_edit_voice',
'callback': 'clear_temp_voice_tags'
},
'voice_review': {
'menu': User.Menu.ADMIN_VOICE_REVIEW,
'message': translations.admin_messages['review_the_voice'],
'keyboard': keyboards.voice_review,
'before': 'main',
'callback': 'clear_current_voice'
}
}
user_steps = {
Expand Down
10 changes: 10 additions & 0 deletions persianmeme/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
from background_task.models import CompletedTask


@background(schedule=21600)
def revoke_review(voice_id: int):
try:
target_voice = Voice.objects.get(id=voice_id, reviewed=False)
except Voice.DoesNotExist:
return
target_voice.assigned_admin = None
target_voice.save()


@background(schedule=21600)
def check_voice(voice_id: int):
CompletedTask.objects.all().delete()
Expand Down
17 changes: 10 additions & 7 deletions persianmeme/translations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@
'banned': 'User {0} has been banned !',
'reply': 'Please send the text which you want to be replied !',
'replying': 'Replying 🔴',
'accepted': 'Voice has been accepted ✅',
'deleted': 'Voice has been deleted 🗑',
'deleted_before': 'Voice is already deleted ⚠',
'denied': 'Delete Request has been denied ☑',
'welcome': 'Welcome to Admin Panel !',
'member_count': 'Bot users total count : {0}',
'voice': 'Please send the voice.',
'accepted_voices': 'Accepted voices 👆',
'no_accepted': 'There isn\'t any accepted voice !',
'send_ad': 'Please send the ad message.',
'send_ad_id': 'Please send the ad ID.',
'delete_requests': 'Here are delete requests 👆',
'messages': 'Here are messages 👆',
'no_message': 'There is no message !',
'no_delete_requests': 'There is no more delete requests !',
'no_message': 'There is no new message !',
'no_delete_requests': 'There is no more delete requests !',
'broadcast': 'Please sent the message you want to broadcast.',
'voice_info': 'Voice Name : {0}\n\nYou can use it by typing\n\n '
'@Persian_Meme_Bot {0}\n\nin a chat 😁',
Expand All @@ -38,12 +37,12 @@
'broadcast_start': 'Broadcasting is going to start soon ...',
'replace_ad': 'Send the new message to replace the ad.',
'ad_edited': 'Ad has been edited ✔️',
'voice_edited': 'Voice editing is done ✔',
'send_a_voice': 'Please send a voice ⚠️',
'deleted_by_admins': 'Voice has been deleted{0} !\nName : {1}\nFile ID : {2}',
'new_voice_accepted': 'A new voice accepted ⚠️',
'review_required': 'A new voice is ready for reviewing ⚠',
'admin_panel': 'Admin panel activated 🔛',
'ban_voted': 'Voice has been deleted and user got banned !',
'processed_before': 'Voice has been processed before !',
'admin_voice_denied': 'Voice has been denied !',
'admin_voice_accepted': 'Voice has been accepted !',
'send_voice_id': 'Please send a voice ID to receive the voice file.',
Expand Down Expand Up @@ -78,7 +77,11 @@
'joined_playlist': 'You have joined {0} playlist !',
'already_joined_playlist': 'You have already joined this playlist !',
'invalid_playlist': 'Playlist is invalid ⚠',
'user_is_admin': 'User is an admin ⚠'
'user_is_admin': 'User is an admin ⚠',
'review_the_voice': 'Please review the voice and submit it using these options 👇',
'no_voice_to_review': 'There isn\'t any voice requiring a review !',
'reviewed': 'Voice has been reviewed ✅',
'voice_not_accessible': 'Requested voice is not accessible anymore !'
}
user_messages = {
'back': 'شما به منوی اصلی بازگشتید 🔙',
Expand Down
Loading

0 comments on commit 542beba

Please sign in to comment.