1#!/usr/bin/env python
2#
3# A library that provides a Python interface to the Telegram Bot API
4# Copyright (C) 2015-2020
5# Leandro Toledo de Souza <devs@python-telegram-bot.org>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Lesser Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU Lesser Public License for more details.
16#
17# You should have received a copy of the GNU Lesser Public License
18# along with this program.  If not, see [http://www.gnu.org/licenses/].
19"""This module contains an object that represents a Encrypted PassportFile."""
20
21from typing import TYPE_CHECKING, Any, List, Optional
22
23from telegram import TelegramObject
24from telegram.utils.types import JSONDict
25
26if TYPE_CHECKING:
27    from telegram import Bot, File, FileCredentials
28
29
30class PassportFile(TelegramObject):
31    """
32    This object represents a file uploaded to Telegram Passport. Currently all Telegram Passport
33    files are in JPEG format when decrypted and don't exceed 10MB.
34
35    Objects of this class are comparable in terms of equality. Two objects of this class are
36    considered equal, if their :attr:`file_unique_id` is equal.
37
38    Attributes:
39        file_id (:obj:`str`): Identifier for this file.
40        file_unique_id (:obj:`str`): Unique identifier for this file, which
41            is supposed to be the same over time and for different bots.
42            Can't be used to download or reuse the file.
43        file_size (:obj:`int`): File size.
44        file_date (:obj:`int`): Unix time when the file was uploaded.
45        bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
46
47    Args:
48        file_id (:obj:`str`): Identifier for this file, which can be used to download
49            or reuse the file.
50        file_unique_id (:obj:`str`): Unique identifier for this file, which
51            is supposed to be the same over time and for different bots.
52            Can't be used to download or reuse the file.
53        file_size (:obj:`int`): File size.
54        file_date (:obj:`int`): Unix time when the file was uploaded.
55        bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
56        **kwargs (:obj:`dict`): Arbitrary keyword arguments.
57
58    """
59
60    def __init__(
61        self,
62        file_id: str,
63        file_unique_id: str,
64        file_date: int,
65        file_size: int = None,
66        bot: 'Bot' = None,
67        credentials: 'FileCredentials' = None,
68        **_kwargs: Any,
69    ):
70        # Required
71        self.file_id = file_id
72        self.file_unique_id = file_unique_id
73        self.file_size = file_size
74        self.file_date = file_date
75        # Optionals
76        self.bot = bot
77        self._credentials = credentials
78
79        self._id_attrs = (self.file_unique_id,)
80
81    @classmethod
82    def de_json_decrypted(
83        cls, data: Optional[JSONDict], bot: 'Bot', credentials: 'FileCredentials'
84    ) -> Optional['PassportFile']:
85        data = cls.parse_data(data)
86
87        if not data:
88            return None
89
90        data['credentials'] = credentials
91
92        return cls(bot=bot, **data)
93
94    @classmethod
95    def de_list_decrypted(
96        cls, data: Optional[List[JSONDict]], bot: 'Bot', credentials: List['FileCredentials']
97    ) -> List[Optional['PassportFile']]:
98        if not data:
99            return []
100
101        return [
102            cls.de_json_decrypted(passport_file, bot, credentials[i])
103            for i, passport_file in enumerate(data)
104        ]
105
106    def get_file(self, timeout: int = None, api_kwargs: JSONDict = None) -> 'File':
107        """
108        Wrapper over :attr:`telegram.Bot.get_file`. Will automatically assign the correct
109        credentials to the returned :class:`telegram.File` if originating from
110        :obj:`telegram.PassportData.decrypted_data`.
111
112        Args:
113            timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
114                the read timeout from the server (instead of the one specified during creation of
115                the connection pool).
116            api_kwargs (:obj:`dict`, optional): Arbitrary keyword arguments to be passed to the
117                Telegram API.
118
119        Returns:
120            :class:`telegram.File`
121
122        Raises:
123            :class:`telegram.TelegramError`
124
125        """
126        file = self.bot.get_file(self.file_id, timeout=timeout, api_kwargs=api_kwargs)
127        file.set_credentials(self._credentials)
128        return file
129