forked from Mahesh0253/Media-Search-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatabase.py
102 lines (78 loc) · 2.86 KB
/
database.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import re
import logging
from pymongo.errors import DuplicateKeyError
from umongo import Instance, Document, fields
from motor.motor_asyncio import AsyncIOMotorClient
from marshmallow.exceptions import ValidationError
from info import DATABASE_URI, DATABASE_NAME, COLLECTION_NAME, USE_CAPTION_FILTER
from .helpers import unpack_new_file_id
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
client = AsyncIOMotorClient(DATABASE_URI)
database = client[DATABASE_NAME]
instance = Instance.from_db(database)
@instance.register
class Media(Document):
file_id = fields.StrField(attribute='_id')
file_ref = fields.StrField(allow_none=True)
file_name = fields.StrField(required=True)
file_size = fields.IntField(required=True)
file_type = fields.StrField(allow_none=True)
mime_type = fields.StrField(allow_none=True)
caption = fields.StrField(allow_none=True)
class Meta:
indexes = ('$file_name', )
collection_name = COLLECTION_NAME
async def save_file(media):
"""Save file in database"""
file_id, file_ref = unpack_new_file_id(media.file_id)
try:
file = Media(
file_id=file_id,
file_ref=file_ref,
file_name=media.file_name,
file_size=media.file_size,
file_type=media.file_type,
mime_type=media.mime_type,
caption=media.caption.html if media.caption else None,
)
except ValidationError:
logger.exception('Error occurred while saving file in database')
else:
try:
await file.commit()
except DuplicateKeyError:
logger.warning(media.file_name + " is already saved in database")
else:
logger.info(media.file_name + " is saved in database")
async def get_search_results(query, file_type=None, max_results=10, offset=0):
"""For given query return (results, next_offset)"""
query = query.strip()
if not query:
raw_pattern = '.'
elif ' ' not in query:
raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
else:
raw_pattern = query.replace(' ', r'.*[\s\.\+\-_\(\)\[\]]')
try:
regex = re.compile(raw_pattern, flags=re.IGNORECASE)
except:
return [], ''
if USE_CAPTION_FILTER:
filter = {'$or': [{'file_name': regex}, {'caption': regex}]}
else:
filter = {'file_name': regex}
if file_type:
filter['file_type'] = file_type
total_results = await Media.count_documents(filter)
next_offset = offset + max_results
if next_offset > total_results:
next_offset = ''
cursor = Media.find(filter)
# Sort by recent
cursor.sort('$natural', -1)
# Slice files according to offset and max results
cursor.skip(offset).limit(max_results)
# Get list of files
files = await cursor.to_list(length=max_results)
return files, next_offset