1 | # Copyright (C) 2014-2018, Stefan Schwarzer <sschwarzer@sschwarzer.net> |
---|
2 | # and ftputil contributors (see `doc/contributors.txt`) |
---|
3 | # See the file LICENSE for licensing terms. |
---|
4 | |
---|
5 | """ |
---|
6 | Session factory factory (the two "factory" are intential :-) ) |
---|
7 | for ftputil. |
---|
8 | """ |
---|
9 | |
---|
10 | import ftplib |
---|
11 | |
---|
12 | |
---|
13 | __all__ = ["session_factory"] |
---|
14 | |
---|
15 | |
---|
16 | # In a way, it would be appropriate to call this function |
---|
17 | # `session_factory_factory`, but that's cumbersome to use. Think of |
---|
18 | # the function returning a session factory and the shorter name should |
---|
19 | # be fine. |
---|
20 | def session_factory(base_class=ftplib.FTP, port=21, use_passive_mode=None, |
---|
21 | encrypt_data_channel=True, debug_level=None): |
---|
22 | """ |
---|
23 | Create and return a session factory according to the keyword |
---|
24 | arguments. |
---|
25 | |
---|
26 | base_class: Base class to use for the session class (e. g. |
---|
27 | `ftplib.FTP_TLS` or `M2Crypto.ftpslib.FTP_TLS`, default is |
---|
28 | `ftplib.FTP`). |
---|
29 | |
---|
30 | port: Port number (integer) for the command channel (default 21). |
---|
31 | If you don't know what "command channel" means, use the default or |
---|
32 | use what the provider gave you as "the FTP port". |
---|
33 | |
---|
34 | use_passive_mode: If `True`, explicitly use passive mode. If |
---|
35 | `False`, explicitly don't use passive mode. If `None` (default), |
---|
36 | let the `base_class` decide whether it wants to use active or |
---|
37 | passive mode. |
---|
38 | |
---|
39 | encrypt_data_channel: If `True` (the default), call the `prot_p` |
---|
40 | method of the base class if it has the method. If `False` or |
---|
41 | `None` (`None` is the default), don't call the method. |
---|
42 | |
---|
43 | debug_level: Debug level (integer) to be set on a session |
---|
44 | instance. The default is `None`, meaning no debugging output. |
---|
45 | |
---|
46 | This function should work for the base classes `ftplib.FTP`, |
---|
47 | `ftplib.FTP_TLS`. Other base classes should work if they use the |
---|
48 | same API as `ftplib.FTP`. |
---|
49 | |
---|
50 | Usage example: |
---|
51 | |
---|
52 | my_session_factory = session_factory( |
---|
53 | base_class=ftplib.FTP_TLS, |
---|
54 | use_passive_mode=True, |
---|
55 | encrypt_data_channel=True) |
---|
56 | with ftputil.FTPHost(host, user, password, |
---|
57 | session_factory=my_session_factory) as host: |
---|
58 | ... |
---|
59 | """ |
---|
60 | class Session(base_class): |
---|
61 | """Session factory class created by `session_factory`.""" |
---|
62 | |
---|
63 | def __init__(self, host, user, password): |
---|
64 | super().__init__() |
---|
65 | self.connect(host, port) |
---|
66 | if debug_level is not None: |
---|
67 | self.set_debuglevel(debug_level) |
---|
68 | self.login(user, password) |
---|
69 | # `set_pasv` can be called with `True` (causing passive |
---|
70 | # mode) or `False` (causing active mode). |
---|
71 | if use_passive_mode is not None: |
---|
72 | self.set_pasv(use_passive_mode) |
---|
73 | if encrypt_data_channel and hasattr(base_class, "prot_p"): |
---|
74 | self.prot_p() |
---|
75 | |
---|
76 | return Session |
---|