Hex Artifact Content
Logged in as anonymous

Artifact 1de828453bb1c6dbd1818ee350337d573e3b1a5b5a42e7b31a19a96ec735a08f:


0000: 2f 2f 21 20 53 69 6d 70 6c 65 20 53 4d 54 50 2d  //! Simple SMTP-
0010: 74 6f 2d 54 65 6c 65 67 72 61 6d 20 67 61 74 65  to-Telegram gate
0020: 77 61 79 2e 20 43 61 6e 20 70 61 72 73 65 20 65  way. Can parse e
0030: 6d 61 69 6c 20 61 6e 64 20 73 65 6e 64 20 74 68  mail and send th
0040: 65 6d 20 61 73 20 74 65 6c 65 67 72 61 6d 0a 2f  em as telegram./
0050: 2f 21 20 6d 65 73 73 61 67 65 73 20 74 6f 20 73  /! messages to s
0060: 70 65 63 69 66 69 65 64 20 63 68 61 74 73 2c 20  pecified chats, 
0070: 67 65 6e 65 72 61 6c 6c 79 20 79 6f 75 20 73 70  generally you sp
0080: 65 63 69 66 79 20 77 68 69 63 68 20 65 6d 61 69  ecify which emai
0090: 6c 20 61 64 64 72 65 73 73 20 69 73 0a 2f 2f 21  l address is.//!
00a0: 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 63 6f   available in co
00b0: 6e 66 69 67 75 72 61 74 69 6f 6e 2c 20 65 76 65  nfiguration, eve
00c0: 72 79 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20  rything else is 
00d0: 73 65 6e 74 20 74 6f 20 64 65 66 61 75 6c 74 20  sent to default 
00e0: 61 64 64 72 65 73 73 2e 0a 0a 75 73 65 20 61 6e  address...use an
00f0: 79 68 6f 77 3a 3a 52 65 73 75 6c 74 3b 0a 75 73  yhow::Result;.us
0100: 65 20 61 73 79 6e 63 5f 73 74 64 3a 3a 7b 0a 09  e async_std::{..
0110: 66 73 3a 3a 6d 65 74 61 64 61 74 61 2c 0a 09 69  fs::metadata,..i
0120: 6f 3a 3a 45 72 72 6f 72 2c 0a 09 74 61 73 6b 2c  o::Error,..task,
0130: 0a 7d 3b 0a 75 73 65 20 6a 75 73 74 5f 67 65 74  .};.use just_get
0140: 6f 70 74 3a 3a 7b 0a 09 4f 70 74 46 6c 61 67 73  opt::{..OptFlags
0150: 2c 0a 09 4f 70 74 53 70 65 63 73 2c 0a 09 4f 70  ,..OptSpecs,..Op
0160: 74 56 61 6c 75 65 2c 0a 7d 3b 0a 75 73 65 20 6c  tValue,.};.use l
0170: 61 7a 79 5f 73 74 61 74 69 63 3a 3a 6c 61 7a 79  azy_static::lazy
0180: 5f 73 74 61 74 69 63 3b 0a 75 73 65 20 6d 61 69  _static;.use mai
0190: 6c 69 6e 5f 65 6d 62 65 64 64 65 64 3a 3a 7b 0a  lin_embedded::{.
01a0: 09 52 65 73 70 6f 6e 73 65 2c 0a 09 72 65 73 70  .Response,..resp
01b0: 6f 6e 73 65 3a 3a 2a 2c 0a 7d 3b 0a 75 73 65 20  onse::*,.};.use 
01c0: 72 65 67 65 78 3a 3a 52 65 67 65 78 3b 0a 75 73  regex::Regex;.us
01d0: 65 20 74 65 6c 6f 78 69 64 65 3a 3a 7b 0a 09 42  e teloxide::{..B
01e0: 6f 74 2c 0a 09 70 72 65 6c 75 64 65 3a 3a 7b 0a  ot,..prelude::{.
01f0: 09 09 52 65 71 75 65 73 74 65 72 2c 0a 09 09 52  ..Requester,...R
0200: 65 71 75 65 73 74 65 72 45 78 74 2c 0a 09 7d 2c  equesterExt,..},
0210: 0a 09 74 79 70 65 73 3a 3a 7b 0a 09 09 43 68 61  ..types::{...Cha
0220: 74 49 64 2c 0a 09 09 49 6e 70 75 74 4d 65 64 69  tId,...InputMedi
0230: 61 2c 0a 09 09 4d 65 73 73 61 67 65 2c 0a 09 09  a,...Message,...
0240: 50 61 72 73 65 4d 6f 64 65 3a 3a 4d 61 72 6b 64  ParseMode::Markd
0250: 6f 77 6e 56 32 2c 0a 09 7d 2c 0a 7d 3b 0a 75 73  ownV2,..},.};.us
0260: 65 20 74 68 69 73 65 72 72 6f 72 3a 3a 45 72 72  e thiserror::Err
0270: 6f 72 3b 0a 0a 75 73 65 20 73 74 64 3a 3a 7b 0a  or;..use std::{.
0280: 09 62 6f 72 72 6f 77 3a 3a 43 6f 77 2c 0a 09 63  .borrow::Cow,..c
0290: 6f 6c 6c 65 63 74 69 6f 6e 73 3a 3a 7b 0a 09 09  ollections::{...
02a0: 48 61 73 68 4d 61 70 2c 0a 09 09 48 61 73 68 53  HashMap,...HashS
02b0: 65 74 2c 0a 09 7d 2c 0a 09 6f 73 3a 3a 75 6e 69  et,..},..os::uni
02c0: 78 3a 3a 66 73 3a 3a 50 65 72 6d 69 73 73 69 6f  x::fs::Permissio
02d0: 6e 73 45 78 74 2c 0a 09 70 61 74 68 3a 3a 50 61  nsExt,..path::Pa
02e0: 74 68 2c 0a 09 76 65 63 3a 3a 56 65 63 2c 0a 7d  th,..vec::Vec,.}
02f0: 3b 0a 0a 23 5b 64 65 72 69 76 65 28 45 72 72 6f  ;..#[derive(Erro
0300: 72 2c 20 44 65 62 75 67 29 5d 0a 70 75 62 20 65  r, Debug)].pub e
0310: 6e 75 6d 20 4d 79 45 72 72 6f 72 20 7b 0a 09 23  num MyError {..#
0320: 5b 65 72 72 6f 72 28 22 46 61 69 6c 65 64 20 74  [error("Failed t
0330: 6f 20 70 61 72 73 65 20 6d 61 69 6c 22 29 5d 0a  o parse mail")].
0340: 09 42 61 64 4d 61 69 6c 2c 0a 09 23 5b 65 72 72  .BadMail,..#[err
0350: 6f 72 28 22 4d 69 73 73 69 6e 67 20 64 65 66 61  or("Missing defa
0360: 75 6c 74 20 61 64 64 72 65 73 73 20 69 6e 20 72  ult address in r
0370: 65 63 69 70 69 65 6e 74 20 74 61 62 6c 65 22 29  ecipient table")
0380: 5d 0a 09 4e 6f 44 65 66 61 75 6c 74 2c 0a 09 23  ]..NoDefault,..#
0390: 5b 65 72 72 6f 72 28 22 4e 6f 20 68 65 61 64 65  [error("No heade
03a0: 72 73 20 66 6f 75 6e 64 22 29 5d 0a 09 4e 6f 48  rs found")]..NoH
03b0: 65 61 64 65 72 73 2c 0a 09 23 5b 65 72 72 6f 72  eaders,..#[error
03c0: 28 22 4e 6f 20 72 65 63 69 70 69 65 6e 74 20 61  ("No recipient a
03d0: 64 64 72 65 73 73 65 73 22 29 5d 0a 09 4e 6f 52  ddresses")]..NoR
03e0: 65 63 69 70 69 65 6e 74 2c 0a 09 23 5b 65 72 72  ecipient,..#[err
03f0: 6f 72 28 22 46 61 69 6c 65 64 20 74 6f 20 65 78  or("Failed to ex
0400: 74 72 61 63 74 20 74 65 78 74 20 66 72 6f 6d 20  tract text from 
0410: 6d 65 73 73 61 67 65 22 29 5d 0a 09 4e 6f 54 65  message")]..NoTe
0420: 78 74 2c 0a 09 23 5b 65 72 72 6f 72 28 74 72 61  xt,..#[error(tra
0430: 6e 73 70 61 72 65 6e 74 29 5d 0a 09 52 65 71 75  nsparent)]..Requ
0440: 65 73 74 45 72 72 6f 72 28 23 5b 66 72 6f 6d 5d  estError(#[from]
0450: 20 74 65 6c 6f 78 69 64 65 3a 3a 52 65 71 75 65   teloxide::Reque
0460: 73 74 45 72 72 6f 72 29 2c 0a 09 23 5b 65 72 72  stError),..#[err
0470: 6f 72 28 74 72 61 6e 73 70 61 72 65 6e 74 29 5d  or(transparent)]
0480: 0a 09 54 72 79 46 72 6f 6d 49 6e 74 45 72 72 6f  ..TryFromIntErro
0490: 72 28 23 5b 66 72 6f 6d 5d 20 73 74 64 3a 3a 6e  r(#[from] std::n
04a0: 75 6d 3a 3a 54 72 79 46 72 6f 6d 49 6e 74 45 72  um::TryFromIntEr
04b0: 72 6f 72 29 2c 0a 7d 0a 0a 2f 2f 2f 20 60 53 6f  ror),.}../// `So
04c0: 6d 65 48 65 61 64 65 72 73 60 20 6f 62 6a 65 63  meHeaders` objec
04d0: 74 20 74 6f 20 73 74 6f 72 65 20 64 61 74 61 20  t to store data 
04e0: 74 68 72 6f 75 67 68 20 53 4d 54 50 20 73 65 73  through SMTP ses
04f0: 73 69 6f 6e 0a 23 5b 64 65 72 69 76 65 28 43 6c  sion.#[derive(Cl
0500: 6f 6e 65 2c 20 44 65 62 75 67 29 5d 0a 73 74 72  one, Debug)].str
0510: 75 63 74 20 53 6f 6d 65 48 65 61 64 65 72 73 20  uct SomeHeaders 
0520: 7b 0a 09 66 72 6f 6d 3a 20 53 74 72 69 6e 67 2c  {..from: String,
0530: 0a 09 74 6f 3a 20 56 65 63 3c 53 74 72 69 6e 67  ..to: Vec<String
0540: 3e 2c 0a 7d 0a 0a 2f 2f 2f 20 60 54 65 6c 65 67  >,.}../// `Teleg
0550: 72 61 6d 54 72 61 6e 73 70 6f 72 74 60 20 43 65  ramTransport` Ce
0560: 6e 74 72 61 6c 20 6f 62 6a 65 63 74 20 77 69 74  ntral object wit
0570: 68 20 54 47 20 61 70 69 20 61 6e 64 20 63 6f 6e  h TG api and con
0580: 66 69 67 75 72 61 74 69 6f 6e 0a 23 5b 64 65 72  figuration.#[der
0590: 69 76 65 28 43 6c 6f 6e 65 29 5d 0a 73 74 72 75  ive(Clone)].stru
05a0: 63 74 20 54 65 6c 65 67 72 61 6d 54 72 61 6e 73  ct TelegramTrans
05b0: 70 6f 72 74 20 7b 0a 09 64 61 74 61 3a 20 56 65  port {..data: Ve
05c0: 63 3c 75 38 3e 2c 0a 09 68 65 61 64 65 72 73 3a  c<u8>,..headers:
05d0: 20 4f 70 74 69 6f 6e 3c 53 6f 6d 65 48 65 61 64   Option<SomeHead
05e0: 65 72 73 3e 2c 0a 09 72 65 63 69 70 69 65 6e 74  ers>,..recipient
05f0: 73 3a 20 48 61 73 68 4d 61 70 3c 53 74 72 69 6e  s: HashMap<Strin
0600: 67 2c 20 43 68 61 74 49 64 3e 2c 0a 09 72 65 6c  g, ChatId>,..rel
0610: 61 79 3a 20 62 6f 6f 6c 2c 0a 09 74 67 3a 20 74  ay: bool,..tg: t
0620: 65 6c 6f 78 69 64 65 3a 3a 61 64 61 70 74 6f 72  eloxide::adaptor
0630: 73 3a 3a 44 65 66 61 75 6c 74 50 61 72 73 65 4d  s::DefaultParseM
0640: 6f 64 65 3c 74 65 6c 6f 78 69 64 65 3a 3a 61 64  ode<teloxide::ad
0650: 61 70 74 6f 72 73 3a 3a 54 68 72 6f 74 74 6c 65  aptors::Throttle
0660: 3c 42 6f 74 3e 3e 2c 0a 09 66 69 65 6c 64 73 3a  <Bot>>,..fields:
0670: 20 48 61 73 68 53 65 74 3c 53 74 72 69 6e 67 3e   HashSet<String>
0680: 2c 0a 7d 0a 0a 6c 61 7a 79 5f 73 74 61 74 69 63  ,.}..lazy_static
0690: 21 20 7b 0a 09 73 74 61 74 69 63 20 72 65 66 20  ! {..static ref 
06a0: 52 45 5f 53 50 45 43 49 41 4c 3a 20 52 65 67 65  RE_SPECIAL: Rege
06b0: 78 20 3d 20 52 65 67 65 78 3a 3a 6e 65 77 28 72  x = Regex::new(r
06c0: 22 28 5b 5c 2d 5f 2a 5c 5b 5c 5d 28 29 7e 60 3e  "([\-_*\[\]()~`>
06d0: 23 2b 7c 7b 7d 5c 2e 21 5d 29 22 29 2e 75 6e 77  #+|{}\.!])").unw
06e0: 72 61 70 28 29 3b 0a 7d 0a 0a 2f 2f 2f 20 45 6e  rap();.}../// En
06f0: 63 6f 64 65 73 20 73 70 65 63 69 61 6c 20 48 54  codes special HT
0700: 4d 4c 20 65 6e 74 69 74 69 65 73 20 74 6f 20 70  ML entities to p
0710: 72 65 76 65 6e 74 20 74 68 65 6d 20 69 6e 74 65  revent them inte
0720: 72 66 65 72 69 6e 67 20 77 69 74 68 20 54 65 6c  rfering with Tel
0730: 65 67 72 61 6d 20 48 54 4d 4c 0a 66 6e 20 65 6e  egram HTML.fn en
0740: 63 6f 64 65 20 28 74 65 78 74 3a 20 26 73 74 72  code (text: &str
0750: 29 20 2d 3e 20 43 6f 77 3c 27 5f 2c 20 73 74 72  ) -> Cow<'_, str
0760: 3e 20 7b 0a 09 52 45 5f 53 50 45 43 49 41 4c 2e  > {..RE_SPECIAL.
0770: 72 65 70 6c 61 63 65 5f 61 6c 6c 28 74 65 78 74  replace_all(text
0780: 2c 20 22 5c 5c 24 31 22 29 0a 7d 0a 0a 23 5b 63  , "\\$1").}..#[c
0790: 66 67 28 74 65 73 74 29 5d 0a 6d 6f 64 20 74 65  fg(test)].mod te
07a0: 73 74 73 20 7b 0a 09 75 73 65 20 63 72 61 74 65  sts {..use crate
07b0: 3a 3a 65 6e 63 6f 64 65 3b 0a 0a 09 23 5b 74 65  ::encode;...#[te
07c0: 73 74 5d 0a 09 66 6e 20 63 68 65 63 6b 5f 72 65  st]..fn check_re
07d0: 67 65 78 20 28 29 20 7b 0a 09 09 6c 65 74 20 72  gex () {...let r
07e0: 65 73 20 3d 20 65 6e 63 6f 64 65 28 22 2d 5f 2a  es = encode("-_*
07f0: 5b 5d 28 29 7e 60 3e 23 2b 7c 7b 7d 2e 21 22 29  []()~`>#+|{}.!")
0800: 3b 0a 09 09 61 73 73 65 72 74 5f 65 71 21 28 72  ;...assert_eq!(r
0810: 65 73 2c 20 22 5c 5c 2d 5c 5c 5f 5c 5c 2a 5c 5c  es, "\\-\\_\\*\\
0820: 5b 5c 5c 5d 5c 5c 28 5c 5c 29 5c 5c 7e 5c 5c 60  [\\]\\(\\)\\~\\`
0830: 5c 5c 3e 5c 5c 23 5c 5c 2b 5c 5c 7c 5c 5c 7b 5c  \\>\\#\\+\\|\\{\
0840: 5c 7d 5c 5c 2e 5c 5c 21 22 29 3b 0a 09 7d 0a 7d  \}\\.\\!");..}.}
0850: 0a 0a 69 6d 70 6c 20 54 65 6c 65 67 72 61 6d 54  ..impl TelegramT
0860: 72 61 6e 73 70 6f 72 74 20 7b 0a 09 2f 2f 2f 20  ransport {../// 
0870: 49 6e 69 74 69 61 6c 69 7a 65 20 41 50 49 20 61  Initialize API a
0880: 6e 64 20 72 65 61 64 20 63 6f 6e 66 69 67 75 72  nd read configur
0890: 61 74 69 6f 6e 0a 09 66 6e 20 6e 65 77 28 73 65  ation..fn new(se
08a0: 74 74 69 6e 67 73 3a 20 63 6f 6e 66 69 67 3a 3a  ttings: config::
08b0: 43 6f 6e 66 69 67 29 20 2d 3e 20 54 65 6c 65 67  Config) -> Teleg
08c0: 72 61 6d 54 72 61 6e 73 70 6f 72 74 20 7b 0a 09  ramTransport {..
08d0: 09 6c 65 74 20 74 67 20 3d 20 42 6f 74 3a 3a 6e  .let tg = Bot::n
08e0: 65 77 28 73 65 74 74 69 6e 67 73 2e 67 65 74 5f  ew(settings.get_
08f0: 73 74 72 69 6e 67 28 22 61 70 69 5f 6b 65 79 22  string("api_key"
0900: 29 0a 09 09 09 2e 65 78 70 65 63 74 28 22 5b 73  ).....expect("[s
0910: 6d 74 70 32 74 67 2e 74 6f 6d 6c 5d 20 6d 69 73  mtp2tg.toml] mis
0920: 73 69 6e 67 20 5c 22 61 70 69 5f 6b 65 79 5c 22  sing \"api_key\"
0930: 20 70 61 72 61 6d 65 74 65 72 2e 5c 6e 22 29 29   parameter.\n"))
0940: 0a 09 09 09 2e 74 68 72 6f 74 74 6c 65 28 74 65  .....throttle(te
0950: 6c 6f 78 69 64 65 3a 3a 61 64 61 70 74 6f 72 73  loxide::adaptors
0960: 3a 3a 74 68 72 6f 74 74 6c 65 3a 3a 4c 69 6d 69  ::throttle::Limi
0970: 74 73 3a 3a 64 65 66 61 75 6c 74 28 29 29 0a 09  ts::default())..
0980: 09 09 2e 70 61 72 73 65 5f 6d 6f 64 65 28 4d 61  ...parse_mode(Ma
0990: 72 6b 64 6f 77 6e 56 32 29 3b 0a 09 09 6c 65 74  rkdownV2);...let
09a0: 20 72 65 63 69 70 69 65 6e 74 73 3a 20 48 61 73   recipients: Has
09b0: 68 4d 61 70 3c 53 74 72 69 6e 67 2c 20 43 68 61  hMap<String, Cha
09c0: 74 49 64 3e 20 3d 20 73 65 74 74 69 6e 67 73 2e  tId> = settings.
09d0: 67 65 74 5f 74 61 62 6c 65 28 22 72 65 63 69 70  get_table("recip
09e0: 69 65 6e 74 73 22 29 0a 09 09 09 2e 65 78 70 65  ients").....expe
09f0: 63 74 28 22 5b 73 6d 74 70 32 74 67 2e 74 6f 6d  ct("[smtp2tg.tom
0a00: 6c 5d 20 6d 69 73 73 69 6e 67 20 74 61 62 6c 65  l] missing table
0a10: 20 5c 22 72 65 63 69 70 69 65 6e 74 73 5c 22 2e   \"recipients\".
0a20: 5c 6e 22 29 0a 09 09 09 2e 69 6e 74 6f 5f 69 74  \n").....into_it
0a30: 65 72 28 29 2e 6d 61 70 28 7c 28 61 2c 20 62 29  er().map(|(a, b)
0a40: 7c 20 28 61 2c 20 43 68 61 74 49 64 20 28 62 2e  | (a, ChatId (b.
0a50: 69 6e 74 6f 5f 69 6e 74 28 29 0a 09 09 09 09 2e  into_int()......
0a60: 65 78 70 65 63 74 28 22 5b 73 6d 74 70 32 74 67  expect("[smtp2tg
0a70: 2e 74 6f 6d 6c 5d 20 5c 22 72 65 63 69 70 69 65  .toml] \"recipie
0a80: 6e 74 5c 22 20 74 61 62 6c 65 20 76 61 6c 75 65  nt\" table value
0a90: 73 20 73 68 6f 75 6c 64 20 62 65 20 69 6e 74 65  s should be inte
0aa0: 67 65 72 73 2e 5c 6e 22 29 0a 09 09 09 09 29 29  gers.\n").....))
0ab0: 29 2e 63 6f 6c 6c 65 63 74 28 29 3b 0a 09 09 69  ).collect();...i
0ac0: 66 20 21 72 65 63 69 70 69 65 6e 74 73 2e 63 6f  f !recipients.co
0ad0: 6e 74 61 69 6e 73 5f 6b 65 79 28 22 5f 22 29 20  ntains_key("_") 
0ae0: 7b 0a 09 09 09 65 70 72 69 6e 74 6c 6e 21 28 22  {....eprintln!("
0af0: 5b 73 6d 74 70 32 74 67 2e 74 6f 6d 6c 5d 20 5c  [smtp2tg.toml] \
0b00: 22 72 65 63 69 70 69 65 6e 74 5c 22 20 74 61 62  "recipient\" tab
0b10: 6c 65 20 6d 69 73 73 65 73 20 5c 22 64 65 66 61  le misses \"defa
0b20: 75 6c 74 5f 72 65 63 69 70 69 65 6e 74 5c 22 2e  ult_recipient\".
0b30: 5c 6e 22 29 3b 0a 09 09 09 70 61 6e 69 63 21 28  \n");....panic!(
0b40: 22 6e 6f 20 64 65 66 61 75 6c 74 20 72 65 63 69  "no default reci
0b50: 70 69 65 6e 74 22 29 3b 0a 09 09 7d 0a 09 09 6c  pient");...}...l
0b60: 65 74 20 66 69 65 6c 64 73 20 3d 20 48 61 73 68  et fields = Hash
0b70: 53 65 74 3a 3a 3c 53 74 72 69 6e 67 3e 3a 3a 66  Set::<String>::f
0b80: 72 6f 6d 5f 69 74 65 72 28 73 65 74 74 69 6e 67  rom_iter(setting
0b90: 73 2e 67 65 74 5f 61 72 72 61 79 28 22 66 69 65  s.get_array("fie
0ba0: 6c 64 73 22 29 0a 09 09 09 2e 65 78 70 65 63 74  lds").....expect
0bb0: 28 22 5b 73 6d 74 70 32 74 67 2e 74 6f 6d 6c 5d  ("[smtp2tg.toml]
0bc0: 20 5c 22 66 69 65 6c 64 73 5c 22 20 73 68 6f 75   \"fields\" shou
0bd0: 6c 64 20 62 65 20 61 6e 20 61 72 72 61 79 22 29  ld be an array")
0be0: 0a 09 09 09 2e 69 74 65 72 28 29 2e 6d 61 70 28  .....iter().map(
0bf0: 7c 78 7c 20 78 2e 63 6c 6f 6e 65 28 29 2e 69 6e  |x| x.clone().in
0c00: 74 6f 5f 73 74 72 69 6e 67 28 29 2e 65 78 70 65  to_string().expe
0c10: 63 74 28 22 73 68 6f 75 6c 64 20 62 65 20 73 74  ct("should be st
0c20: 72 69 6e 67 73 22 29 29 29 3b 0a 09 09 6c 65 74  rings")));...let
0c30: 20 76 61 6c 75 65 20 3d 20 73 65 74 74 69 6e 67   value = setting
0c40: 73 2e 67 65 74 5f 73 74 72 69 6e 67 28 22 75 6e  s.get_string("un
0c50: 6b 6e 6f 77 6e 22 29 3b 0a 09 09 6c 65 74 20 72  known");...let r
0c60: 65 6c 61 79 20 3d 20 6d 61 74 63 68 20 76 61 6c  elay = match val
0c70: 75 65 20 7b 0a 09 09 09 4f 6b 28 76 61 6c 75 65  ue {....Ok(value
0c80: 29 20 3d 3e 20 7b 0a 09 09 09 09 6d 61 74 63 68  ) => {.....match
0c90: 20 76 61 6c 75 65 2e 61 73 5f 73 74 72 28 29 20   value.as_str() 
0ca0: 7b 0a 09 09 09 09 09 22 72 65 6c 61 79 22 20 3d  {......"relay" =
0cb0: 3e 20 74 72 75 65 2c 0a 09 09 09 09 09 22 64 65  > true,......"de
0cc0: 6e 79 22 20 3d 3e 20 66 61 6c 73 65 2c 0a 09 09  ny" => false,...
0cd0: 09 09 09 5f 20 3d 3e 20 7b 0a 09 09 09 09 09 09  ..._ => {.......
0ce0: 65 70 72 69 6e 74 6c 6e 21 28 22 5b 73 6d 74 70  eprintln!("[smtp
0cf0: 32 74 67 2e 74 6f 6d 6c 5d 20 5c 22 75 6e 6b 6e  2tg.toml] \"unkn
0d00: 6f 77 6e 5c 22 20 73 68 6f 75 6c 64 20 62 65 20  own\" should be 
0d10: 65 69 74 68 65 72 20 5c 22 72 65 6c 61 79 5c 22  either \"relay\"
0d20: 20 6f 72 20 5c 22 64 65 6e 79 5c 22 2e 5c 6e 22   or \"deny\".\n"
0d30: 29 3b 0a 09 09 09 09 09 09 70 61 6e 69 63 21 28  );.......panic!(
0d40: 22 62 61 64 20 73 65 74 74 69 6e 67 22 29 3b 0a  "bad setting");.
0d50: 09 09 09 09 09 7d 2c 0a 09 09 09 09 7d 0a 09 09  .....},.....}...
0d60: 09 7d 2c 0a 09 09 09 45 72 72 28 65 72 72 29 20  .},....Err(err) 
0d70: 3d 3e 20 7b 0a 09 09 09 09 65 70 72 69 6e 74 6c  => {.....eprintl
0d80: 6e 21 28 22 5b 73 6d 74 70 32 74 67 2e 74 6f 6d  n!("[smtp2tg.tom
0d90: 6c 5d 20 63 61 6e 27 74 20 67 65 74 20 5c 22 75  l] can't get \"u
0da0: 6e 6b 6e 6f 77 6e 5c 22 3a 5c 6e 20 7b 65 72 72  nknown\":\n {err
0db0: 3a 3f 7d 5c 6e 22 29 3b 0a 09 09 09 09 70 61 6e  :?}\n");.....pan
0dc0: 69 63 21 28 22 62 61 64 20 73 65 74 74 69 6e 67  ic!("bad setting
0dd0: 22 29 3b 0a 09 09 09 7d 2c 0a 09 09 7d 3b 0a 0a  ");....},...};..
0de0: 09 09 54 65 6c 65 67 72 61 6d 54 72 61 6e 73 70  ..TelegramTransp
0df0: 6f 72 74 20 7b 0a 09 09 09 64 61 74 61 3a 20 76  ort {....data: v
0e00: 65 63 21 28 29 2c 0a 09 09 09 68 65 61 64 65 72  ec!(),....header
0e10: 73 3a 20 4e 6f 6e 65 2c 0a 09 09 09 72 65 63 69  s: None,....reci
0e20: 70 69 65 6e 74 73 2c 0a 09 09 09 72 65 6c 61 79  pients,....relay
0e30: 2c 0a 09 09 09 74 67 2c 0a 09 09 09 66 69 65 6c  ,....tg,....fiel
0e40: 64 73 2c 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2f 2f  ds,...}..}...///
0e50: 20 53 65 6e 64 20 6d 65 73 73 61 67 65 20 74 6f   Send message to
0e60: 20 64 65 66 61 75 6c 74 20 75 73 65 72 2c 20 75   default user, u
0e70: 73 65 64 20 66 6f 72 20 64 65 62 75 67 2f 6c 6f  sed for debug/lo
0e80: 67 2f 69 6e 66 6f 20 70 75 72 70 6f 73 65 73 0a  g/info purposes.
0e90: 09 61 73 79 6e 63 20 66 6e 20 64 65 62 75 67 20  .async fn debug 
0ea0: 28 26 73 65 6c 66 2c 20 6d 73 67 3a 20 26 73 74  (&self, msg: &st
0eb0: 72 29 20 2d 3e 20 52 65 73 75 6c 74 3c 4d 65 73  r) -> Result<Mes
0ec0: 73 61 67 65 2c 20 4d 79 45 72 72 6f 72 3e 20 7b  sage, MyError> {
0ed0: 0a 09 09 4f 6b 28 73 65 6c 66 2e 74 67 2e 73 65  ...Ok(self.tg.se
0ee0: 6e 64 5f 6d 65 73 73 61 67 65 28 2a 73 65 6c 66  nd_message(*self
0ef0: 2e 72 65 63 69 70 69 65 6e 74 73 2e 67 65 74 28  .recipients.get(
0f00: 22 5f 22 29 2e 6f 6b 5f 6f 72 28 4d 79 45 72 72  "_").ok_or(MyErr
0f10: 6f 72 3a 3a 4e 6f 44 65 66 61 75 6c 74 29 3f 2c  or::NoDefault)?,
0f20: 20 65 6e 63 6f 64 65 28 6d 73 67 29 29 2e 61 77   encode(msg)).aw
0f30: 61 69 74 3f 29 0a 09 7d 0a 0a 09 2f 2f 2f 20 53  ait?)..}.../// S
0f40: 65 6e 64 20 6d 65 73 73 61 67 65 20 74 6f 20 73  end message to s
0f50: 70 65 63 69 66 69 65 64 20 75 73 65 72 0a 09 61  pecified user..a
0f60: 73 79 6e 63 20 66 6e 20 73 65 6e 64 20 3c 53 3e  sync fn send <S>
0f70: 20 28 26 73 65 6c 66 2c 20 74 6f 3a 20 26 43 68   (&self, to: &Ch
0f80: 61 74 49 64 2c 20 6d 73 67 3a 20 53 29 20 2d 3e  atId, msg: S) ->
0f90: 20 52 65 73 75 6c 74 3c 4d 65 73 73 61 67 65 2c   Result<Message,
0fa0: 20 4d 79 45 72 72 6f 72 3e 0a 09 77 68 65 72 65   MyError>..where
0fb0: 20 53 3a 20 49 6e 74 6f 3c 53 74 72 69 6e 67 3e   S: Into<String>
0fc0: 20 7b 0a 09 09 4f 6b 28 73 65 6c 66 2e 74 67 2e   {...Ok(self.tg.
0fd0: 73 65 6e 64 5f 6d 65 73 73 61 67 65 28 2a 74 6f  send_message(*to
0fe0: 2c 20 6d 73 67 29 2e 61 77 61 69 74 3f 29 0a 09  , msg).await?)..
0ff0: 7d 0a 0a 09 2f 2f 2f 20 41 74 74 65 6d 70 74 20  }.../// Attempt 
1000: 74 6f 20 64 65 6c 69 76 65 72 20 6f 6e 65 20 6d  to deliver one m
1010: 65 73 73 61 67 65 0a 09 61 73 79 6e 63 20 66 6e  essage..async fn
1020: 20 72 65 6c 61 79 5f 6d 61 69 6c 20 28 26 73 65   relay_mail (&se
1030: 6c 66 29 20 2d 3e 20 52 65 73 75 6c 74 3c 28 29  lf) -> Result<()
1040: 2c 20 4d 79 45 72 72 6f 72 3e 20 7b 0a 09 09 69  , MyError> {...i
1050: 66 20 6c 65 74 20 53 6f 6d 65 28 68 65 61 64 65  f let Some(heade
1060: 72 73 29 20 3d 20 26 73 65 6c 66 2e 68 65 61 64  rs) = &self.head
1070: 65 72 73 20 7b 0a 09 09 09 6c 65 74 20 6d 61 69  ers {....let mai
1080: 6c 20 3d 20 6d 61 69 6c 5f 70 61 72 73 65 72 3a  l = mail_parser:
1090: 3a 4d 65 73 73 61 67 65 50 61 72 73 65 72 3a 3a  :MessageParser::
10a0: 6e 65 77 28 29 2e 70 61 72 73 65 28 26 73 65 6c  new().parse(&sel
10b0: 66 2e 64 61 74 61 29 0a 09 09 09 09 2e 6f 6b 5f  f.data)......ok_
10c0: 6f 72 28 4d 79 45 72 72 6f 72 3a 3a 42 61 64 4d  or(MyError::BadM
10d0: 61 69 6c 29 3f 3b 0a 0a 09 09 09 2f 2f 20 41 64  ail)?;.....// Ad
10e0: 64 69 6e 67 20 61 6c 6c 20 6b 6e 6f 77 6e 20 61  ding all known a
10f0: 64 64 72 65 73 73 65 73 20 74 6f 20 72 65 63 69  ddresses to reci
1100: 70 69 65 6e 74 20 6c 69 73 74 2c 20 66 6f 72 20  pient list, for 
1110: 61 6e 79 6f 6e 65 20 65 6c 73 65 20 61 64 64 69  anyone else addi
1120: 6e 67 20 64 65 66 61 75 6c 74 0a 09 09 09 2f 2f  ng default....//
1130: 20 41 6c 73 6f 20 69 66 20 6c 69 73 74 20 69 73   Also if list is
1140: 20 65 6d 70 74 79 20 61 6c 73 6f 20 61 64 64 69   empty also addi
1150: 6e 67 20 64 65 66 61 75 6c 74 0a 09 09 09 6c 65  ng default....le
1160: 74 20 6d 75 74 20 72 63 70 74 3a 20 48 61 73 68  t mut rcpt: Hash
1170: 53 65 74 3c 26 43 68 61 74 49 64 3e 20 3d 20 48  Set<&ChatId> = H
1180: 61 73 68 53 65 74 3a 3a 6e 65 77 28 29 3b 0a 09  ashSet::new();..
1190: 09 09 69 66 20 68 65 61 64 65 72 73 2e 74 6f 2e  ..if headers.to.
11a0: 69 73 5f 65 6d 70 74 79 28 29 20 7b 0a 09 09 09  is_empty() {....
11b0: 09 72 65 74 75 72 6e 20 45 72 72 28 4d 79 45 72  .return Err(MyEr
11c0: 72 6f 72 3a 3a 4e 6f 52 65 63 69 70 69 65 6e 74  ror::NoRecipient
11d0: 29 3b 0a 09 09 09 7d 0a 09 09 09 66 6f 72 20 69  );....}....for i
11e0: 74 65 6d 20 69 6e 20 26 68 65 61 64 65 72 73 2e  tem in &headers.
11f0: 74 6f 20 7b 0a 09 09 09 09 6d 61 74 63 68 20 73  to {.....match s
1200: 65 6c 66 2e 72 65 63 69 70 69 65 6e 74 73 2e 67  elf.recipients.g
1210: 65 74 28 69 74 65 6d 29 20 7b 0a 09 09 09 09 09  et(item) {......
1220: 53 6f 6d 65 28 61 64 64 72 29 20 3d 3e 20 72 63  Some(addr) => rc
1230: 70 74 2e 69 6e 73 65 72 74 28 61 64 64 72 29 2c  pt.insert(addr),
1240: 0a 09 09 09 09 09 4e 6f 6e 65 20 3d 3e 20 7b 0a  ......None => {.
1250: 09 09 09 09 09 09 73 65 6c 66 2e 64 65 62 75 67  ......self.debug
1260: 28 26 66 6f 72 6d 61 74 21 28 22 52 65 63 69 70  (&format!("Recip
1270: 69 65 6e 74 20 5b 7b 69 74 65 6d 7d 5d 20 6e 6f  ient [{item}] no
1280: 74 20 66 6f 75 6e 64 2e 22 29 29 2e 61 77 61 69  t found.")).awai
1290: 74 3f 3b 0a 09 09 09 09 09 09 72 63 70 74 2e 69  t?;.......rcpt.i
12a0: 6e 73 65 72 74 28 73 65 6c 66 2e 72 65 63 69 70  nsert(self.recip
12b0: 69 65 6e 74 73 2e 67 65 74 28 22 5f 22 29 0a 09  ients.get("_")..
12c0: 09 09 09 09 09 09 2e 6f 6b 5f 6f 72 28 4d 79 45  .......ok_or(MyE
12d0: 72 72 6f 72 3a 3a 4e 6f 44 65 66 61 75 6c 74 29  rror::NoDefault)
12e0: 3f 29 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 3b  ?)......}.....};
12f0: 0a 09 09 09 7d 3b 0a 09 09 09 69 66 20 72 63 70  ....};....if rcp
1300: 74 2e 69 73 5f 65 6d 70 74 79 28 29 20 7b 0a 09  t.is_empty() {..
1310: 09 09 09 73 65 6c 66 2e 64 65 62 75 67 28 22 4e  ...self.debug("N
1320: 6f 20 72 65 63 69 70 69 65 6e 74 20 6f 72 20 65  o recipient or e
1330: 6e 76 65 6c 6f 70 65 20 61 64 64 72 65 73 73 2e  nvelope address.
1340: 22 29 2e 61 77 61 69 74 3f 3b 0a 09 09 09 09 72  ").await?;.....r
1350: 63 70 74 2e 69 6e 73 65 72 74 28 73 65 6c 66 2e  cpt.insert(self.
1360: 72 65 63 69 70 69 65 6e 74 73 2e 67 65 74 28 22  recipients.get("
1370: 5f 22 29 0a 09 09 09 09 09 2e 6f 6b 5f 6f 72 28  _").......ok_or(
1380: 4d 79 45 72 72 6f 72 3a 3a 4e 6f 44 65 66 61 75  MyError::NoDefau
1390: 6c 74 29 3f 29 3b 0a 09 09 09 7d 3b 0a 0a 09 09  lt)?);....};....
13a0: 09 2f 2f 20 70 72 65 70 61 74 69 6e 67 20 6d 65  .// prepating me
13b0: 73 73 61 67 65 20 68 65 61 64 65 72 0a 09 09 09  ssage header....
13c0: 6c 65 74 20 6d 75 74 20 72 65 70 6c 79 3a 20 56  let mut reply: V
13d0: 65 63 3c 53 74 72 69 6e 67 3e 20 3d 20 76 65 63  ec<String> = vec
13e0: 21 5b 5d 3b 0a 09 09 09 69 66 20 73 65 6c 66 2e  ![];....if self.
13f0: 66 69 65 6c 64 73 2e 63 6f 6e 74 61 69 6e 73 28  fields.contains(
1400: 22 73 75 62 6a 65 63 74 22 29 20 7b 0a 09 09 09  "subject") {....
1410: 09 69 66 20 6c 65 74 20 53 6f 6d 65 28 73 75 62  .if let Some(sub
1420: 6a 65 63 74 29 20 3d 20 6d 61 69 6c 2e 73 75 62  ject) = mail.sub
1430: 6a 65 63 74 28 29 20 7b 0a 09 09 09 09 09 72 65  ject() {......re
1440: 70 6c 79 2e 70 75 73 68 28 66 6f 72 6d 61 74 21  ply.push(format!
1450: 28 22 5f 5f 2a 53 75 62 6a 65 63 74 3a 2a 5f 5f  ("__*Subject:*__
1460: e2 80 87 60 7b 7d 60 22 2c 20 65 6e 63 6f 64 65   `{}`", encode
1470: 28 73 75 62 6a 65 63 74 29 29 29 3b 0a 09 09 09  (subject)));....
1480: 09 7d 20 65 6c 73 65 20 69 66 20 6c 65 74 20 53  .} else if let S
1490: 6f 6d 65 28 74 68 72 65 61 64 29 20 3d 20 6d 61  ome(thread) = ma
14a0: 69 6c 2e 74 68 72 65 61 64 5f 6e 61 6d 65 28 29  il.thread_name()
14b0: 20 7b 0a 09 09 09 09 09 72 65 70 6c 79 2e 70 75   {......reply.pu
14c0: 73 68 28 66 6f 72 6d 61 74 21 28 22 5f 5f 2a 54  sh(format!("__*T
14d0: 68 72 65 61 64 3a 2a 5f 5f e2 80 87 60 7b 7d 60  hread:*__ `{}`
14e0: 22 2c 20 65 6e 63 6f 64 65 28 74 68 72 65 61 64  ", encode(thread
14f0: 29 29 29 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a  )));.....}....}.
1500: 09 09 09 6c 65 74 20 6d 75 74 20 73 68 6f 72 74  ...let mut short
1510: 5f 68 65 61 64 65 72 73 3a 20 56 65 63 3c 53 74  _headers: Vec<St
1520: 72 69 6e 67 3e 20 3d 20 76 65 63 21 5b 5d 3b 0a  ring> = vec![];.
1530: 09 09 09 2f 2f 20 64 6f 20 77 65 20 6e 65 65 64  ...// do we need
1540: 20 74 6f 20 72 65 70 6c 61 63 65 20 73 70 61 63   to replace spac
1550: 65 73 20 68 65 72 65 3f 0a 09 09 09 69 66 20 73  es here?....if s
1560: 65 6c 66 2e 66 69 65 6c 64 73 2e 63 6f 6e 74 61  elf.fields.conta
1570: 69 6e 73 28 22 66 72 6f 6d 22 29 20 7b 0a 09 09  ins("from") {...
1580: 09 09 73 68 6f 72 74 5f 68 65 61 64 65 72 73 2e  ..short_headers.
1590: 70 75 73 68 28 66 6f 72 6d 61 74 21 28 22 5f 5f  push(format!("__
15a0: 2a 46 72 6f 6d 3a 2a 5f 5f e2 80 87 60 7b 7d 60  *From:*__ `{}`
15b0: 22 2c 20 65 6e 63 6f 64 65 28 26 68 65 61 64 65  ", encode(&heade
15c0: 72 73 2e 66 72 6f 6d 29 29 29 3b 0a 09 09 09 7d  rs.from)));....}
15d0: 0a 09 09 09 69 66 20 73 65 6c 66 2e 66 69 65 6c  ....if self.fiel
15e0: 64 73 2e 63 6f 6e 74 61 69 6e 73 28 22 64 61 74  ds.contains("dat
15f0: 65 22 29 20 7b 0a 09 09 09 09 69 66 20 6c 65 74  e") {.....if let
1600: 20 53 6f 6d 65 28 64 61 74 65 29 20 3d 20 6d 61   Some(date) = ma
1610: 69 6c 2e 64 61 74 65 28 29 20 7b 0a 09 09 09 09  il.date() {.....
1620: 09 73 68 6f 72 74 5f 68 65 61 64 65 72 73 2e 70  .short_headers.p
1630: 75 73 68 28 66 6f 72 6d 61 74 21 28 22 5f 5f 2a  ush(format!("__*
1640: 44 61 74 65 3a 2a 5f 5f e2 80 87 60 7b 64 61 74  Date:*__ `{dat
1650: 65 7d 60 22 29 29 3b 0a 09 09 09 09 7d 0a 09 09  e}`"));.....}...
1660: 09 7d 0a 09 09 09 72 65 70 6c 79 2e 70 75 73 68  .}....reply.push
1670: 28 73 68 6f 72 74 5f 68 65 61 64 65 72 73 2e 6a  (short_headers.j
1680: 6f 69 6e 28 22 20 22 29 29 3b 0a 09 09 09 6c 65  oin(" "));....le
1690: 74 20 68 65 61 64 65 72 5f 73 69 7a 65 20 3d 20  t header_size = 
16a0: 72 65 70 6c 79 2e 6a 6f 69 6e 28 22 20 22 29 2e  reply.join(" ").
16b0: 6c 65 6e 28 29 20 2b 20 31 3b 0a 0a 09 09 09 6c  len() + 1;.....l
16c0: 65 74 20 68 74 6d 6c 5f 70 61 72 74 73 20 3d 20  et html_parts = 
16d0: 6d 61 69 6c 2e 68 74 6d 6c 5f 62 6f 64 79 5f 63  mail.html_body_c
16e0: 6f 75 6e 74 28 29 3b 0a 09 09 09 6c 65 74 20 74  ount();....let t
16f0: 65 78 74 5f 70 61 72 74 73 20 3d 20 6d 61 69 6c  ext_parts = mail
1700: 2e 74 65 78 74 5f 62 6f 64 79 5f 63 6f 75 6e 74  .text_body_count
1710: 28 29 3b 0a 09 09 09 6c 65 74 20 61 74 74 61 63  ();....let attac
1720: 68 6d 65 6e 74 73 20 3d 20 6d 61 69 6c 2e 61 74  hments = mail.at
1730: 74 61 63 68 6d 65 6e 74 5f 63 6f 75 6e 74 28 29  tachment_count()
1740: 3b 0a 09 09 09 69 66 20 68 74 6d 6c 5f 70 61 72  ;....if html_par
1750: 74 73 20 21 3d 20 74 65 78 74 5f 70 61 72 74 73  ts != text_parts
1760: 20 7b 0a 09 09 09 09 73 65 6c 66 2e 64 65 62 75   {.....self.debu
1770: 67 28 26 66 6f 72 6d 61 74 21 28 22 48 6d 2c 20  g(&format!("Hm, 
1780: 77 65 20 68 61 76 65 20 7b 68 74 6d 6c 5f 70 61  we have {html_pa
1790: 72 74 73 7d 20 48 54 4d 4c 20 70 61 72 74 73 20  rts} HTML parts 
17a0: 61 6e 64 20 7b 74 65 78 74 5f 70 61 72 74 73 7d  and {text_parts}
17b0: 20 74 65 78 74 20 70 61 72 74 73 2e 22 29 29 2e   text parts.")).
17c0: 61 77 61 69 74 3f 3b 0a 09 09 09 7d 0a 09 09 09  await?;....}....
17d0: 2f 2f 6c 65 74 20 6d 75 74 20 68 74 6d 6c 5f 6e  //let mut html_n
17e0: 75 6d 20 3d 20 30 3b 0a 09 09 09 6c 65 74 20 6d  um = 0;....let m
17f0: 75 74 20 74 65 78 74 5f 6e 75 6d 20 3d 20 30 3b  ut text_num = 0;
1800: 0a 09 09 09 6c 65 74 20 6d 75 74 20 66 69 6c 65  ....let mut file
1810: 5f 6e 75 6d 20 3d 20 30 3b 0a 09 09 09 2f 2f 20  _num = 0;....// 
1820: 6c 65 74 27 73 20 64 69 73 70 6c 61 79 20 66 69  let's display fi
1830: 72 73 74 20 68 74 6d 6c 20 6f 72 20 74 65 78 74  rst html or text
1840: 20 70 61 72 74 20 61 73 20 62 6f 64 79 0a 09 09   part as body...
1850: 09 6c 65 74 20 6d 75 74 20 62 6f 64 79 3a 20 43  .let mut body: C
1860: 6f 77 3c 27 5f 2c 20 73 74 72 3e 20 3d 20 22 22  ow<'_, str> = ""
1870: 2e 69 6e 74 6f 28 29 3b 0a 09 09 09 2f 2a 0a 09  .into();..../*..
1880: 09 09 20 2a 20 61 63 74 75 61 6c 6c 79 20 49 20  .. * actually I 
1890: 64 6f 6e 27 74 20 77 61 6e 6e 61 20 70 61 72 73  don't wanna pars
18a0: 65 20 74 68 61 74 20 68 74 6d 6c 20 73 74 75 66  e that html stuf
18b0: 66 0a 09 09 09 69 66 20 68 74 6d 6c 5f 70 61 72  f....if html_par
18c0: 74 73 20 3e 20 30 20 7b 0a 09 09 09 09 6c 65 74  ts > 0 {.....let
18d0: 20 74 65 78 74 20 3d 20 6d 61 69 6c 2e 62 6f 64   text = mail.bod
18e0: 79 5f 68 74 6d 6c 28 30 29 2e 75 6e 77 72 61 70  y_html(0).unwrap
18f0: 28 29 3b 0a 09 09 09 09 69 66 20 74 65 78 74 2e  ();.....if text.
1900: 6c 65 6e 28 29 20 3c 20 34 30 39 36 20 2d 20 68  len() < 4096 - h
1910: 65 61 64 65 72 5f 73 69 7a 65 20 7b 0a 09 09 09  eader_size {....
1920: 09 09 62 6f 64 79 20 3d 20 74 65 78 74 3b 0a 09  ..body = text;..
1930: 09 09 09 09 68 74 6d 6c 5f 6e 75 6d 20 3d 20 31  ....html_num = 1
1940: 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 3b 0a 09 09  ;.....}....};...
1950: 09 2a 2f 0a 09 09 09 69 66 20 62 6f 64 79 2e 69  .*/....if body.i
1960: 73 5f 65 6d 70 74 79 28 29 20 26 26 20 74 65 78  s_empty() && tex
1970: 74 5f 70 61 72 74 73 20 3e 20 30 20 7b 0a 09 09  t_parts > 0 {...
1980: 09 09 6c 65 74 20 74 65 78 74 20 3d 20 6d 61 69  ..let text = mai
1990: 6c 2e 62 6f 64 79 5f 74 65 78 74 28 30 29 0a 09  l.body_text(0)..
19a0: 09 09 09 09 2e 6f 6b 5f 6f 72 28 4d 79 45 72 72  .....ok_or(MyErr
19b0: 6f 72 3a 3a 4e 6f 54 65 78 74 29 3f 3b 0a 09 09  or::NoText)?;...
19c0: 09 09 69 66 20 74 65 78 74 2e 6c 65 6e 28 29 20  ..if text.len() 
19d0: 3c 20 34 30 39 36 20 2d 20 68 65 61 64 65 72 5f  < 4096 - header_
19e0: 73 69 7a 65 20 7b 0a 09 09 09 09 09 62 6f 64 79  size {......body
19f0: 20 3d 20 74 65 78 74 3b 0a 09 09 09 09 09 74 65   = text;......te
1a00: 78 74 5f 6e 75 6d 20 3d 20 31 3b 0a 09 09 09 09  xt_num = 1;.....
1a10: 7d 0a 09 09 09 7d 3b 0a 09 09 09 72 65 70 6c 79  }....};....reply
1a20: 2e 70 75 73 68 28 22 60 60 60 22 2e 69 6e 74 6f  .push("```".into
1a30: 28 29 29 3b 0a 09 09 09 72 65 70 6c 79 2e 65 78  ());....reply.ex
1a40: 74 65 6e 64 28 62 6f 64 79 2e 6c 69 6e 65 73 28  tend(body.lines(
1a50: 29 2e 6d 61 70 28 7c 78 7c 20 78 2e 69 6e 74 6f  ).map(|x| x.into
1a60: 28 29 29 29 3b 0a 09 09 09 72 65 70 6c 79 2e 70  ()));....reply.p
1a70: 75 73 68 28 22 60 60 60 22 2e 69 6e 74 6f 28 29  ush("```".into()
1a80: 29 3b 0a 0a 09 09 09 2f 2f 20 61 6e 64 20 6c 65  );.....// and le
1a90: 74 27 73 20 63 6f 6c 6c 65 63 74 20 61 6c 6c 20  t's collect all 
1aa0: 6f 74 68 65 72 20 61 74 74 61 63 68 6d 65 6e 74  other attachment
1ab0: 20 70 61 72 74 73 0a 09 09 09 6c 65 74 20 6d 75   parts....let mu
1ac0: 74 20 66 69 6c 65 73 5f 74 6f 5f 73 65 6e 64 20  t files_to_send 
1ad0: 3d 20 76 65 63 21 5b 5d 3b 0a 09 09 09 2f 2a 0a  = vec![];..../*.
1ae0: 09 09 09 20 2a 20 6c 65 74 27 73 20 6a 75 73 74  ... * let's just
1af0: 20 73 6b 69 70 20 68 74 6d 6c 20 70 61 72 74 73   skip html parts
1b00: 20 66 6f 72 20 6e 6f 77 2c 20 74 68 65 79 20 6a   for now, they j
1b10: 75 73 74 20 64 75 70 6c 69 63 61 74 65 20 74 65  ust duplicate te
1b20: 78 74 3f 0a 09 09 09 77 68 69 6c 65 20 68 74 6d  xt?....while htm
1b30: 6c 5f 6e 75 6d 20 3c 20 68 74 6d 6c 5f 70 61 72  l_num < html_par
1b40: 74 73 20 7b 0a 09 09 09 09 66 69 6c 65 73 5f 74  ts {.....files_t
1b50: 6f 5f 73 65 6e 64 2e 70 75 73 68 28 6d 61 69 6c  o_send.push(mail
1b60: 2e 68 74 6d 6c 5f 70 61 72 74 28 68 74 6d 6c 5f  .html_part(html_
1b70: 6e 75 6d 29 2e 75 6e 77 72 61 70 28 29 29 3b 0a  num).unwrap());.
1b80: 09 09 09 09 68 74 6d 6c 5f 6e 75 6d 20 2b 3d 20  ....html_num += 
1b90: 31 3b 0a 09 09 09 7d 0a 09 09 09 2a 2f 0a 09 09  1;....}....*/...
1ba0: 09 77 68 69 6c 65 20 74 65 78 74 5f 6e 75 6d 20  .while text_num 
1bb0: 3c 20 74 65 78 74 5f 70 61 72 74 73 20 7b 0a 09  < text_parts {..
1bc0: 09 09 09 66 69 6c 65 73 5f 74 6f 5f 73 65 6e 64  ...files_to_send
1bd0: 2e 70 75 73 68 28 6d 61 69 6c 2e 74 65 78 74 5f  .push(mail.text_
1be0: 70 61 72 74 28 74 65 78 74 5f 6e 75 6d 2e 74 72  part(text_num.tr
1bf0: 79 5f 69 6e 74 6f 28 29 3f 29 0a 09 09 09 09 09  y_into()?)......
1c00: 2e 6f 6b 5f 6f 72 28 4d 79 45 72 72 6f 72 3a 3a  .ok_or(MyError::
1c10: 4e 6f 54 65 78 74 29 3f 29 3b 0a 09 09 09 09 74  NoText)?);.....t
1c20: 65 78 74 5f 6e 75 6d 20 2b 3d 20 31 3b 0a 09 09  ext_num += 1;...
1c30: 09 7d 0a 09 09 09 77 68 69 6c 65 20 66 69 6c 65  .}....while file
1c40: 5f 6e 75 6d 20 3c 20 61 74 74 61 63 68 6d 65 6e  _num < attachmen
1c50: 74 73 20 7b 0a 09 09 09 09 66 69 6c 65 73 5f 74  ts {.....files_t
1c60: 6f 5f 73 65 6e 64 2e 70 75 73 68 28 6d 61 69 6c  o_send.push(mail
1c70: 2e 61 74 74 61 63 68 6d 65 6e 74 28 66 69 6c 65  .attachment(file
1c80: 5f 6e 75 6d 2e 74 72 79 5f 69 6e 74 6f 28 29 3f  _num.try_into()?
1c90: 29 0a 09 09 09 09 09 2e 6f 6b 5f 6f 72 28 4d 79  ).......ok_or(My
1ca0: 45 72 72 6f 72 3a 3a 4e 6f 54 65 78 74 29 3f 29  Error::NoText)?)
1cb0: 3b 0a 09 09 09 09 66 69 6c 65 5f 6e 75 6d 20 2b  ;.....file_num +
1cc0: 3d 20 31 3b 0a 09 09 09 7d 0a 0a 09 09 09 6c 65  = 1;....}.....le
1cd0: 74 20 6d 73 67 20 3d 20 72 65 70 6c 79 2e 6a 6f  t msg = reply.jo
1ce0: 69 6e 28 22 5c 6e 22 29 3b 0a 09 09 09 66 6f 72  in("\n");....for
1cf0: 20 63 68 61 74 20 69 6e 20 72 63 70 74 20 7b 0a   chat in rcpt {.
1d00: 09 09 09 09 69 66 20 21 66 69 6c 65 73 5f 74 6f  ....if !files_to
1d10: 5f 73 65 6e 64 2e 69 73 5f 65 6d 70 74 79 28 29  _send.is_empty()
1d20: 20 7b 0a 09 09 09 09 09 6c 65 74 20 6d 75 74 20   {......let mut 
1d30: 66 69 6c 65 73 20 3d 20 76 65 63 21 5b 5d 3b 0a  files = vec![];.
1d40: 09 09 09 09 09 6c 65 74 20 6d 75 74 20 66 69 72  .....let mut fir
1d50: 73 74 5f 6f 6e 65 20 3d 20 74 72 75 65 3b 0a 09  st_one = true;..
1d60: 09 09 09 09 66 6f 72 20 63 68 75 6e 6b 20 69 6e  ....for chunk in
1d70: 20 26 66 69 6c 65 73 5f 74 6f 5f 73 65 6e 64 20   &files_to_send 
1d80: 7b 0a 09 09 09 09 09 09 6c 65 74 20 64 61 74 61  {.......let data
1d90: 20 3d 20 63 68 75 6e 6b 2e 63 6f 6e 74 65 6e 74   = chunk.content
1da0: 73 28 29 3b 0a 09 09 09 09 09 09 6c 65 74 20 6d  s();.......let m
1db0: 75 74 20 66 69 6c 65 6e 61 6d 65 3a 20 4f 70 74  ut filename: Opt
1dc0: 69 6f 6e 3c 53 74 72 69 6e 67 3e 20 3d 20 4e 6f  ion<String> = No
1dd0: 6e 65 3b 0a 09 09 09 09 09 09 66 6f 72 20 68 65  ne;.......for he
1de0: 61 64 65 72 20 69 6e 20 63 68 75 6e 6b 2e 68 65  ader in chunk.he
1df0: 61 64 65 72 73 28 29 20 7b 0a 09 09 09 09 09 09  aders() {.......
1e00: 09 69 66 20 68 65 61 64 65 72 2e 6e 61 6d 65 28  .if header.name(
1e10: 29 20 3d 3d 20 22 43 6f 6e 74 65 6e 74 2d 54 79  ) == "Content-Ty
1e20: 70 65 22 20 7b 0a 09 09 09 09 09 09 09 09 6d 61  pe" {.........ma
1e30: 74 63 68 20 68 65 61 64 65 72 2e 76 61 6c 75 65  tch header.value
1e40: 28 29 20 7b 0a 09 09 09 09 09 09 09 09 09 6d 61  () {..........ma
1e50: 69 6c 5f 70 61 72 73 65 72 3a 3a 48 65 61 64 65  il_parser::Heade
1e60: 72 56 61 6c 75 65 3a 3a 43 6f 6e 74 65 6e 74 54  rValue::ContentT
1e70: 79 70 65 28 63 6f 6e 74 65 6e 74 74 79 70 65 29  ype(contenttype)
1e80: 20 3d 3e 20 7b 0a 09 09 09 09 09 09 09 09 09 09   => {...........
1e90: 69 66 20 6c 65 74 20 53 6f 6d 65 28 66 6e 61 6d  if let Some(fnam
1ea0: 65 29 20 3d 20 63 6f 6e 74 65 6e 74 74 79 70 65  e) = contenttype
1eb0: 2e 61 74 74 72 69 62 75 74 65 28 22 6e 61 6d 65  .attribute("name
1ec0: 22 29 20 7b 0a 09 09 09 09 09 09 09 09 09 09 09  ") {............
1ed0: 66 69 6c 65 6e 61 6d 65 20 3d 20 53 6f 6d 65 28  filename = Some(
1ee0: 66 6e 61 6d 65 2e 74 6f 5f 6f 77 6e 65 64 28 29  fname.to_owned()
1ef0: 29 3b 0a 09 09 09 09 09 09 09 09 09 09 7d 0a 09  );...........}..
1f00: 09 09 09 09 09 09 09 09 7d 2c 0a 09 09 09 09 09  ........},......
1f10: 09 09 09 09 5f 20 3d 3e 20 7b 0a 09 09 09 09 09  ...._ => {......
1f20: 09 09 09 09 09 73 65 6c 66 2e 64 65 62 75 67 28  .....self.debug(
1f30: 22 41 74 74 61 63 68 6d 65 6e 74 20 68 61 73 20  "Attachment has 
1f40: 62 61 64 20 43 6f 6e 74 65 6e 74 54 79 70 65 20  bad ContentType 
1f50: 68 65 61 64 65 72 2e 22 29 2e 61 77 61 69 74 3f  header.").await?
1f60: 3b 0a 09 09 09 09 09 09 09 09 09 7d 2c 0a 09 09  ;..........},...
1f70: 09 09 09 09 09 09 7d 3b 0a 09 09 09 09 09 09 09  ......};........
1f80: 7d 3b 0a 09 09 09 09 09 09 7d 3b 0a 09 09 09 09  };.......};.....
1f90: 09 09 6c 65 74 20 66 69 6c 65 6e 61 6d 65 20 3d  ..let filename =
1fa0: 20 69 66 20 6c 65 74 20 53 6f 6d 65 28 66 6e 61   if let Some(fna
1fb0: 6d 65 29 20 3d 20 66 69 6c 65 6e 61 6d 65 20 7b  me) = filename {
1fc0: 0a 09 09 09 09 09 09 09 66 6e 61 6d 65 0a 09 09  ........fname...
1fd0: 09 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ....} else {....
1fe0: 09 09 09 09 22 41 74 74 61 63 68 6d 65 6e 74 2e  ...."Attachment.
1ff0: 74 78 74 22 2e 69 6e 74 6f 28 29 0a 09 09 09 09  txt".into().....
2000: 09 09 7d 3b 0a 09 09 09 09 09 09 6c 65 74 20 69  ..};.......let i
2010: 74 65 6d 20 3d 20 74 65 6c 6f 78 69 64 65 3a 3a  tem = teloxide::
2020: 74 79 70 65 73 3a 3a 49 6e 70 75 74 4d 65 64 69  types::InputMedi
2030: 61 44 6f 63 75 6d 65 6e 74 3a 3a 6e 65 77 28 0a  aDocument::new(.
2040: 09 09 09 09 09 09 09 74 65 6c 6f 78 69 64 65 3a  .......teloxide:
2050: 3a 74 79 70 65 73 3a 3a 49 6e 70 75 74 46 69 6c  :types::InputFil
2060: 65 3a 3a 6d 65 6d 6f 72 79 28 64 61 74 61 2e 74  e::memory(data.t
2070: 6f 5f 76 65 63 28 29 29 0a 09 09 09 09 09 09 09  o_vec())........
2080: 2e 66 69 6c 65 5f 6e 61 6d 65 28 66 69 6c 65 6e  .file_name(filen
2090: 61 6d 65 29 29 3b 0a 09 09 09 09 09 09 6c 65 74  ame));.......let
20a0: 20 69 74 65 6d 20 3d 20 69 66 20 66 69 72 73 74   item = if first
20b0: 5f 6f 6e 65 20 7b 0a 09 09 09 09 09 09 09 66 69  _one {........fi
20c0: 72 73 74 5f 6f 6e 65 20 3d 20 66 61 6c 73 65 3b  rst_one = false;
20d0: 0a 09 09 09 09 09 09 09 69 74 65 6d 2e 63 61 70  ........item.cap
20e0: 74 69 6f 6e 28 26 6d 73 67 29 0a 09 09 09 09 09  tion(&msg)......
20f0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09  .} else {.......
2100: 09 69 74 65 6d 0a 09 09 09 09 09 09 7d 3b 0a 09  .item.......};..
2110: 09 09 09 09 09 66 69 6c 65 73 2e 70 75 73 68 28  .....files.push(
2120: 49 6e 70 75 74 4d 65 64 69 61 3a 3a 44 6f 63 75  InputMedia::Docu
2130: 6d 65 6e 74 28 69 74 65 6d 29 29 3b 0a 09 09 09  ment(item));....
2140: 09 09 7d 0a 09 09 09 09 09 73 65 6c 66 2e 73 65  ..}......self.se
2150: 6e 64 67 72 6f 75 70 28 63 68 61 74 2c 20 66 69  ndgroup(chat, fi
2160: 6c 65 73 29 2e 61 77 61 69 74 3f 3b 0a 09 09 09  les).await?;....
2170: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 73  .} else {......s
2180: 65 6c 66 2e 73 65 6e 64 28 63 68 61 74 2c 20 26  elf.send(chat, &
2190: 6d 73 67 29 2e 61 77 61 69 74 3f 3b 0a 09 09 09  msg).await?;....
21a0: 09 7d 0a 09 09 09 7d 0a 09 09 7d 20 65 6c 73 65  .}....}...} else
21b0: 20 7b 0a 09 09 09 72 65 74 75 72 6e 20 45 72 72   {....return Err
21c0: 28 4d 79 45 72 72 6f 72 3a 3a 4e 6f 48 65 61 64  (MyError::NoHead
21d0: 65 72 73 29 3b 0a 09 09 7d 0a 09 09 4f 6b 28 28  ers);...}...Ok((
21e0: 29 29 0a 09 7d 0a 0a 09 2f 2f 2f 20 53 65 6e 64  ))..}.../// Send
21f0: 20 6d 65 64 69 61 20 74 6f 20 73 70 65 63 69 66   media to specif
2200: 69 65 64 20 75 73 65 72 0a 09 70 75 62 20 61 73  ied user..pub as
2210: 79 6e 63 20 66 6e 20 73 65 6e 64 67 72 6f 75 70  ync fn sendgroup
2220: 20 3c 4d 3e 20 28 26 73 65 6c 66 2c 20 74 6f 3a   <M> (&self, to:
2230: 20 26 43 68 61 74 49 64 2c 20 6d 65 64 69 61 3a   &ChatId, media:
2240: 20 4d 29 20 2d 3e 20 52 65 73 75 6c 74 3c 56 65   M) -> Result<Ve
2250: 63 3c 4d 65 73 73 61 67 65 3e 2c 20 4d 79 45 72  c<Message>, MyEr
2260: 72 6f 72 3e 0a 09 77 68 65 72 65 20 4d 3a 20 49  ror>..where M: I
2270: 6e 74 6f 49 74 65 72 61 74 6f 72 3c 49 74 65 6d  ntoIterator<Item
2280: 20 3d 20 49 6e 70 75 74 4d 65 64 69 61 3e 20 7b   = InputMedia> {
2290: 0a 09 09 4f 6b 28 73 65 6c 66 2e 74 67 2e 73 65  ...Ok(self.tg.se
22a0: 6e 64 5f 6d 65 64 69 61 5f 67 72 6f 75 70 28 2a  nd_media_group(*
22b0: 74 6f 2c 20 6d 65 64 69 61 29 2e 61 77 61 69 74  to, media).await
22c0: 3f 29 0a 09 7d 0a 7d 0a 0a 69 6d 70 6c 20 6d 61  ?)..}.}..impl ma
22d0: 69 6c 69 6e 5f 65 6d 62 65 64 64 65 64 3a 3a 48  ilin_embedded::H
22e0: 61 6e 64 6c 65 72 20 66 6f 72 20 54 65 6c 65 67  andler for Teleg
22f0: 72 61 6d 54 72 61 6e 73 70 6f 72 74 20 7b 0a 09  ramTransport {..
2300: 2f 2f 2f 20 4a 75 73 74 20 64 65 6e 79 20 6c 6f  /// Just deny lo
2310: 67 69 6e 20 61 75 74 68 0a 09 66 6e 20 61 75 74  gin auth..fn aut
2320: 68 5f 6c 6f 67 69 6e 20 28 26 6d 75 74 20 73 65  h_login (&mut se
2330: 6c 66 2c 20 5f 75 73 65 72 6e 61 6d 65 3a 20 26  lf, _username: &
2340: 73 74 72 2c 20 5f 70 61 73 73 77 6f 72 64 3a 20  str, _password: 
2350: 26 73 74 72 29 20 2d 3e 20 52 65 73 70 6f 6e 73  &str) -> Respons
2360: 65 20 7b 0a 09 09 49 4e 56 41 4c 49 44 5f 43 52  e {...INVALID_CR
2370: 45 44 45 4e 54 49 41 4c 53 0a 09 7d 0a 0a 09 2f  EDENTIALS..}.../
2380: 2f 2f 20 4a 75 73 74 20 64 65 6e 79 20 70 6c 61  // Just deny pla
2390: 69 6e 20 61 75 74 68 0a 09 66 6e 20 61 75 74 68  in auth..fn auth
23a0: 5f 70 6c 61 69 6e 20 28 26 6d 75 74 20 73 65 6c  _plain (&mut sel
23b0: 66 2c 20 5f 61 75 74 68 6f 72 69 7a 61 74 69 6f  f, _authorizatio
23c0: 6e 5f 69 64 3a 20 26 73 74 72 2c 20 5f 61 75 74  n_id: &str, _aut
23d0: 68 65 6e 74 69 63 61 74 69 6f 6e 5f 69 64 3a 20  hentication_id: 
23e0: 26 73 74 72 2c 20 5f 70 61 73 73 77 6f 72 64 3a  &str, _password:
23f0: 20 26 73 74 72 29 20 2d 3e 20 52 65 73 70 6f 6e   &str) -> Respon
2400: 73 65 20 7b 0a 09 09 49 4e 56 41 4c 49 44 5f 43  se {...INVALID_C
2410: 52 45 44 45 4e 54 49 41 4c 53 0a 09 7d 0a 0a 09  REDENTIALS..}...
2420: 2f 2f 2f 20 56 65 72 69 66 79 20 77 68 65 74 68  /// Verify wheth
2430: 65 72 20 61 64 64 72 65 73 73 20 69 73 20 64 65  er address is de
2440: 6c 69 76 65 72 61 62 6c 65 0a 09 66 6e 20 72 63  liverable..fn rc
2450: 70 74 20 28 26 6d 75 74 20 73 65 6c 66 2c 20 74  pt (&mut self, t
2460: 6f 3a 20 26 73 74 72 29 20 2d 3e 20 52 65 73 70  o: &str) -> Resp
2470: 6f 6e 73 65 20 7b 0a 09 09 69 66 20 73 65 6c 66  onse {...if self
2480: 2e 72 65 6c 61 79 20 7b 0a 09 09 09 4f 4b 0a 09  .relay {....OK..
2490: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 6d 61 74  .} else {....mat
24a0: 63 68 20 73 65 6c 66 2e 72 65 63 69 70 69 65 6e  ch self.recipien
24b0: 74 73 2e 67 65 74 28 74 6f 29 20 7b 0a 09 09 09  ts.get(to) {....
24c0: 09 53 6f 6d 65 28 5f 29 20 3d 3e 20 4f 4b 2c 0a  .Some(_) => OK,.
24d0: 09 09 09 09 4e 6f 6e 65 20 3d 3e 20 7b 0a 09 09  ....None => {...
24e0: 09 09 09 69 66 20 73 65 6c 66 2e 72 65 6c 61 79  ...if self.relay
24f0: 20 7b 0a 09 09 09 09 09 09 4f 4b 0a 09 09 09 09   {.......OK.....
2500: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09  .} else {.......
2510: 4e 4f 5f 4d 41 49 4c 42 4f 58 0a 09 09 09 09 09  NO_MAILBOX......
2520: 7d 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 7d  }.....}....}...}
2530: 0a 09 7d 0a 0a 09 2f 2f 2f 20 53 61 76 65 20 68  ..}.../// Save h
2540: 65 61 64 65 72 73 20 77 65 20 6e 65 65 64 0a 09  eaders we need..
2550: 66 6e 20 64 61 74 61 5f 73 74 61 72 74 20 28 26  fn data_start (&
2560: 6d 75 74 20 73 65 6c 66 2c 20 5f 64 6f 6d 61 69  mut self, _domai
2570: 6e 3a 20 26 73 74 72 2c 20 66 72 6f 6d 3a 20 26  n: &str, from: &
2580: 73 74 72 2c 20 5f 69 73 38 62 69 74 3a 20 62 6f  str, _is8bit: bo
2590: 6f 6c 2c 20 74 6f 3a 20 26 5b 53 74 72 69 6e 67  ol, to: &[String
25a0: 5d 29 20 2d 3e 20 52 65 73 70 6f 6e 73 65 20 7b  ]) -> Response {
25b0: 0a 09 09 73 65 6c 66 2e 68 65 61 64 65 72 73 20  ...self.headers 
25c0: 3d 20 53 6f 6d 65 28 53 6f 6d 65 48 65 61 64 65  = Some(SomeHeade
25d0: 72 73 7b 0a 09 09 09 66 72 6f 6d 3a 20 66 72 6f  rs{....from: fro
25e0: 6d 2e 74 6f 5f 73 74 72 69 6e 67 28 29 2c 0a 09  m.to_string(),..
25f0: 09 09 74 6f 3a 20 74 6f 2e 74 6f 5f 76 65 63 28  ..to: to.to_vec(
2600: 29 2c 0a 09 09 7d 29 3b 0a 09 09 4f 4b 0a 09 7d  ),...});...OK..}
2610: 0a 0a 09 2f 2f 2f 20 53 61 76 65 20 63 68 75 6e  .../// Save chun
2620: 6b 28 3f 29 20 6f 66 20 64 61 74 61 0a 09 66 6e  k(?) of data..fn
2630: 20 64 61 74 61 20 28 26 6d 75 74 20 73 65 6c 66   data (&mut self
2640: 2c 20 62 75 66 3a 20 26 5b 75 38 5d 29 20 2d 3e  , buf: &[u8]) ->
2650: 20 52 65 73 75 6c 74 3c 28 29 2c 20 45 72 72 6f   Result<(), Erro
2660: 72 3e 20 7b 0a 09 09 73 65 6c 66 2e 64 61 74 61  r> {...self.data
2670: 2e 61 70 70 65 6e 64 28 62 75 66 2e 74 6f 5f 76  .append(buf.to_v
2680: 65 63 28 29 2e 61 73 5f 6d 75 74 28 29 29 3b 0a  ec().as_mut());.
2690: 09 09 4f 6b 28 28 29 29 0a 09 7d 0a 0a 09 2f 2f  ..Ok(())..}...//
26a0: 2f 20 41 74 74 65 6d 70 74 20 74 6f 20 73 65 6e  / Attempt to sen
26b0: 64 20 65 6d 61 69 6c 2c 20 72 65 74 75 72 6e 20  d email, return 
26c0: 74 65 6d 70 6f 72 61 72 79 20 65 72 72 6f 72 20  temporary error 
26d0: 69 66 20 74 68 61 74 20 66 61 69 6c 73 0a 09 66  if that fails..f
26e0: 6e 20 64 61 74 61 5f 65 6e 64 20 28 26 6d 75 74  n data_end (&mut
26f0: 20 73 65 6c 66 29 20 2d 3e 20 52 65 73 70 6f 6e   self) -> Respon
2700: 73 65 20 7b 0a 09 09 6c 65 74 20 6d 75 74 20 72  se {...let mut r
2710: 65 73 75 6c 74 20 3d 20 4f 4b 3b 0a 09 09 74 61  esult = OK;...ta
2720: 73 6b 3a 3a 62 6c 6f 63 6b 5f 6f 6e 28 61 73 79  sk::block_on(asy
2730: 6e 63 20 7b 0a 09 09 09 2f 2f 20 72 65 6c 61 79  nc {....// relay
2740: 20 6d 61 69 6c 0a 09 09 09 69 66 20 6c 65 74 20   mail....if let 
2750: 45 72 72 28 65 72 72 29 20 3d 20 73 65 6c 66 2e  Err(err) = self.
2760: 72 65 6c 61 79 5f 6d 61 69 6c 28 29 2e 61 77 61  relay_mail().awa
2770: 69 74 20 7b 0a 09 09 09 09 72 65 73 75 6c 74 20  it {.....result 
2780: 3d 20 49 4e 54 45 52 4e 41 4c 5f 45 52 52 4f 52  = INTERNAL_ERROR
2790: 3b 0a 09 09 09 09 2f 2f 20 69 6e 20 63 61 73 65  ;.....// in case
27a0: 20 74 68 61 74 20 66 61 69 6c 73 20 2d 20 69 6e   that fails - in
27b0: 66 6f 72 6d 20 64 65 66 61 75 6c 74 20 72 65 63  form default rec
27c0: 69 70 69 65 6e 74 0a 09 09 09 09 69 66 20 6c 65  ipient.....if le
27d0: 74 20 45 72 72 28 65 72 72 29 20 3d 20 73 65 6c  t Err(err) = sel
27e0: 66 2e 64 65 62 75 67 28 26 66 6f 72 6d 61 74 21  f.debug(&format!
27f0: 28 22 53 65 6e 64 69 6e 67 20 65 6d 61 69 6c 73  ("Sending emails
2800: 20 66 61 69 6c 65 64 3a 5c 6e 7b 65 72 72 3a 3f   failed:\n{err:?
2810: 7d 22 29 29 2e 61 77 61 69 74 20 7b 0a 09 09 09  }")).await {....
2820: 09 09 2f 2f 20 69 6e 20 63 61 73 65 20 74 68 61  ..// in case tha
2830: 74 20 61 6c 73 6f 20 66 61 69 6c 73 20 2d 20 77  t also fails - w
2840: 72 69 74 65 20 73 6f 6d 65 20 6c 6f 67 73 20 61  rite some logs a
2850: 6e 64 20 62 61 69 6c 0a 09 09 09 09 09 65 70 72  nd bail......epr
2860: 69 6e 74 6c 6e 21 28 22 7b 65 72 72 3a 3f 7d 22  intln!("{err:?}"
2870: 29 3b 0a 09 09 09 09 7d 3b 0a 09 09 09 7d 3b 0a  );.....};....};.
2880: 09 09 7d 29 3b 0a 09 09 2f 2f 20 63 6c 65 61 72  ..});...// clear
2890: 20 2d 20 6a 75 73 74 20 69 6e 20 63 61 73 65 0a   - just in case.
28a0: 09 09 73 65 6c 66 2e 64 61 74 61 20 3d 20 76 65  ..self.data = ve
28b0: 63 21 5b 5d 3b 0a 09 09 73 65 6c 66 2e 68 65 61  c![];...self.hea
28c0: 64 65 72 73 20 3d 20 4e 6f 6e 65 3b 0a 09 09 72  ders = None;...r
28d0: 65 73 75 6c 74 0a 09 7d 0a 7d 0a 0a 23 5b 61 73  esult..}.}..#[as
28e0: 79 6e 63 5f 73 74 64 3a 3a 6d 61 69 6e 5d 0a 61  ync_std::main].a
28f0: 73 79 6e 63 20 66 6e 20 6d 61 69 6e 20 28 29 20  sync fn main () 
2900: 2d 3e 20 52 65 73 75 6c 74 3c 28 29 3e 20 7b 0a  -> Result<()> {.
2910: 09 6c 65 74 20 73 70 65 63 73 20 3d 20 4f 70 74  .let specs = Opt
2920: 53 70 65 63 73 3a 3a 6e 65 77 28 29 0a 09 09 2e  Specs::new()....
2930: 6f 70 74 69 6f 6e 28 22 68 65 6c 70 22 2c 20 22  option("help", "
2940: 68 22 2c 20 4f 70 74 56 61 6c 75 65 3a 3a 4e 6f  h", OptValue::No
2950: 6e 65 29 0a 09 09 2e 6f 70 74 69 6f 6e 28 22 68  ne)....option("h
2960: 65 6c 70 22 2c 20 22 68 65 6c 70 22 2c 20 4f 70  elp", "help", Op
2970: 74 56 61 6c 75 65 3a 3a 4e 6f 6e 65 29 0a 09 09  tValue::None)...
2980: 2e 6f 70 74 69 6f 6e 28 22 63 6f 6e 66 69 67 22  .option("config"
2990: 2c 20 22 63 22 2c 20 4f 70 74 56 61 6c 75 65 3a  , "c", OptValue:
29a0: 3a 52 65 71 75 69 72 65 64 29 0a 09 09 2e 6f 70  :Required)....op
29b0: 74 69 6f 6e 28 22 63 6f 6e 66 69 67 22 2c 20 22  tion("config", "
29c0: 63 6f 6e 66 69 67 22 2c 20 4f 70 74 56 61 6c 75  config", OptValu
29d0: 65 3a 3a 52 65 71 75 69 72 65 64 29 0a 09 09 2e  e::Required)....
29e0: 66 6c 61 67 28 4f 70 74 46 6c 61 67 73 3a 3a 4f  flag(OptFlags::O
29f0: 70 74 69 6f 6e 73 45 76 65 72 79 77 68 65 72 65  ptionsEverywhere
2a00: 29 3b 0a 09 6c 65 74 20 6d 75 74 20 61 72 67 73  );..let mut args
2a10: 20 3d 20 73 74 64 3a 3a 65 6e 76 3a 3a 61 72 67   = std::env::arg
2a20: 73 28 29 3b 0a 09 61 72 67 73 2e 6e 65 78 74 28  s();..args.next(
2a30: 29 3b 0a 09 6c 65 74 20 70 61 72 73 65 64 20 3d  );..let parsed =
2a40: 20 73 70 65 63 73 2e 67 65 74 6f 70 74 28 61 72   specs.getopt(ar
2a50: 67 73 29 3b 0a 09 66 6f 72 20 75 20 69 6e 20 26  gs);..for u in &
2a60: 70 61 72 73 65 64 2e 75 6e 6b 6e 6f 77 6e 20 7b  parsed.unknown {
2a70: 0a 09 09 70 72 69 6e 74 6c 6e 21 28 22 55 6e 6b  ...println!("Unk
2a80: 6e 6f 77 6e 20 6f 70 74 69 6f 6e 3a 20 7b 75 7d  nown option: {u}
2a90: 22 29 3b 0a 09 7d 0a 09 69 66 20 21 28 70 61 72  ");..}..if !(par
2aa0: 73 65 64 2e 75 6e 6b 6e 6f 77 6e 2e 69 73 5f 65  sed.unknown.is_e
2ab0: 6d 70 74 79 28 29 29 20 7c 7c 20 70 61 72 73 65  mpty()) || parse
2ac0: 64 2e 6f 70 74 69 6f 6e 73 5f 66 69 72 73 74 28  d.options_first(
2ad0: 22 68 65 6c 70 22 29 2e 69 73 5f 73 6f 6d 65 28  "help").is_some(
2ae0: 29 20 7b 0a 09 09 70 72 69 6e 74 6c 6e 21 28 22  ) {...println!("
2af0: 53 4d 54 50 32 54 47 20 76 7b 7d 2c 20 28 43 29  SMTP2TG v{}, (C)
2b00: 20 32 30 32 34 20 2d 20 32 30 32 35 5c 6e 5c 6e   2024 - 2025\n\n
2b10: 5c 0a 09 09 09 5c 74 2d 68 7c 2d 2d 68 65 6c 70  \....\t-h|--help
2b20: 5c 74 44 69 73 70 6c 61 79 20 74 68 69 73 20 68  \tDisplay this h
2b30: 65 6c 70 5c 6e 5c 0a 09 09 09 5c 74 2d 63 7c 2d  elp\n\....\t-c|-
2b40: 63 6f 6e 66 69 67 20 e2 80 a6 5c 74 53 65 74 20  config …\tSet 
2b50: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 66 69  configuration fi
2b60: 6c 65 20 6c 6f 63 61 74 69 6f 6e 2e 22 2c 0a 09  le location.",..
2b70: 09 09 65 6e 76 21 28 22 43 41 52 47 4f 5f 50 4b  ..env!("CARGO_PK
2b80: 47 5f 56 45 52 53 49 4f 4e 22 29 29 3b 0a 09 09  G_VERSION"));...
2b90: 72 65 74 75 72 6e 20 4f 6b 28 28 29 29 3b 0a 09  return Ok(());..
2ba0: 7d 3b 0a 09 6c 65 74 20 63 6f 6e 66 69 67 5f 66  };..let config_f
2bb0: 69 6c 65 20 3d 20 50 61 74 68 3a 3a 6e 65 77 28  ile = Path::new(
2bc0: 69 66 20 6c 65 74 20 53 6f 6d 65 28 70 61 74 68  if let Some(path
2bd0: 29 20 3d 20 70 61 72 73 65 64 2e 6f 70 74 69 6f  ) = parsed.optio
2be0: 6e 73 5f 76 61 6c 75 65 5f 6c 61 73 74 28 22 63  ns_value_last("c
2bf0: 6f 6e 66 69 67 22 29 20 7b 0a 09 09 26 70 61 74  onfig") {...&pat
2c00: 68 5b 2e 2e 5d 0a 09 7d 20 65 6c 73 65 20 7b 0a  h[..]..} else {.
2c10: 09 09 22 73 6d 74 70 32 74 67 2e 74 6f 6d 6c 22  .."smtp2tg.toml"
2c20: 0a 09 7d 29 3b 0a 09 69 66 20 21 63 6f 6e 66 69  ..});..if !confi
2c30: 67 5f 66 69 6c 65 2e 65 78 69 73 74 73 28 29 20  g_file.exists() 
2c40: 7b 0a 09 09 65 70 72 69 6e 74 6c 6e 21 28 22 45  {...eprintln!("E
2c50: 72 72 6f 72 3a 20 63 61 6e 27 74 20 72 65 61 64  rror: can't read
2c60: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 66   configuration f
2c70: 72 6f 6d 20 7b 63 6f 6e 66 69 67 5f 66 69 6c 65  rom {config_file
2c80: 3a 3f 7d 22 29 3b 0a 09 09 73 74 64 3a 3a 70 72  :?}");...std::pr
2c90: 6f 63 65 73 73 3a 3a 65 78 69 74 28 31 29 3b 0a  ocess::exit(1);.
2ca0: 09 7d 3b 0a 09 7b 0a 09 09 6c 65 74 20 6d 65 74  .};..{...let met
2cb0: 61 20 3d 20 6d 65 74 61 64 61 74 61 28 63 6f 6e  a = metadata(con
2cc0: 66 69 67 5f 66 69 6c 65 29 2e 61 77 61 69 74 3f  fig_file).await?
2cd0: 3b 0a 09 09 69 66 20 28 21 30 6f 31 30 30 36 30  ;...if (!0o10060
2ce0: 30 20 26 20 6d 65 74 61 2e 70 65 72 6d 69 73 73  0 & meta.permiss
2cf0: 69 6f 6e 73 28 29 2e 6d 6f 64 65 28 29 29 20 3e  ions().mode()) >
2d00: 20 30 20 7b 0a 09 09 09 65 70 72 69 6e 74 6c 6e   0 {....eprintln
2d10: 21 28 22 45 72 72 6f 72 3a 20 6f 74 68 65 72 20  !("Error: other 
2d20: 75 73 65 72 73 20 63 61 6e 20 72 65 61 64 20 6f  users can read o
2d30: 72 20 77 72 69 74 65 20 63 6f 6e 66 69 67 20 66  r write config f
2d40: 69 6c 65 20 7b 63 6f 6e 66 69 67 5f 66 69 6c 65  ile {config_file
2d50: 3a 3f 7d 5c 6e 5c 0a 09 09 09 09 46 69 6c 65 20  :?}\n\.....File 
2d60: 70 65 72 6d 69 73 73 69 6f 6e 73 3a 20 7b 3a 6f  permissions: {:o
2d70: 7d 22 2c 20 6d 65 74 61 2e 70 65 72 6d 69 73 73  }", meta.permiss
2d80: 69 6f 6e 73 28 29 2e 6d 6f 64 65 28 29 29 3b 0a  ions().mode());.
2d90: 09 09 09 73 74 64 3a 3a 70 72 6f 63 65 73 73 3a  ...std::process:
2da0: 3a 65 78 69 74 28 31 29 3b 0a 09 09 7d 0a 09 7d  :exit(1);...}..}
2db0: 0a 09 6c 65 74 20 73 65 74 74 69 6e 67 73 3a 20  ..let settings: 
2dc0: 63 6f 6e 66 69 67 3a 3a 43 6f 6e 66 69 67 20 3d  config::Config =
2dd0: 20 63 6f 6e 66 69 67 3a 3a 43 6f 6e 66 69 67 3a   config::Config:
2de0: 3a 62 75 69 6c 64 65 72 28 29 0a 09 09 2e 73 65  :builder()....se
2df0: 74 5f 64 65 66 61 75 6c 74 28 22 66 69 65 6c 64  t_default("field
2e00: 73 22 2c 20 76 65 63 21 5b 22 64 61 74 65 22 2c  s", vec!["date",
2e10: 20 22 66 72 6f 6d 22 2c 20 22 73 75 62 6a 65 63   "from", "subjec
2e20: 74 22 5d 29 2e 75 6e 77 72 61 70 28 29 0a 09 09  t"]).unwrap()...
2e30: 2e 73 65 74 5f 64 65 66 61 75 6c 74 28 22 68 6f  .set_default("ho
2e40: 73 74 6e 61 6d 65 22 2c 20 22 73 6d 74 70 2e 32  stname", "smtp.2
2e50: 2e 74 67 22 29 2e 75 6e 77 72 61 70 28 29 0a 09  .tg").unwrap()..
2e60: 09 2e 73 65 74 5f 64 65 66 61 75 6c 74 28 22 6c  ..set_default("l
2e70: 69 73 74 65 6e 5f 6f 6e 22 2c 20 22 30 2e 30 2e  isten_on", "0.0.
2e80: 30 2e 30 3a 31 30 32 35 22 29 2e 75 6e 77 72 61  0.0:1025").unwra
2e90: 70 28 29 0a 09 09 2e 73 65 74 5f 64 65 66 61 75  p()....set_defau
2ea0: 6c 74 28 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22 72  lt("unknown", "r
2eb0: 65 6c 61 79 22 29 2e 75 6e 77 72 61 70 28 29 0a  elay").unwrap().
2ec0: 09 09 2e 61 64 64 5f 73 6f 75 72 63 65 28 63 6f  ...add_source(co
2ed0: 6e 66 69 67 3a 3a 46 69 6c 65 3a 3a 66 72 6f 6d  nfig::File::from
2ee0: 28 63 6f 6e 66 69 67 5f 66 69 6c 65 29 29 0a 09  (config_file))..
2ef0: 09 2e 62 75 69 6c 64 28 29 0a 09 09 2e 75 6e 77  ..build()....unw
2f00: 72 61 70 5f 6f 72 5f 65 6c 73 65 28 7c 5f 7c 20  rap_or_else(|_| 
2f10: 70 61 6e 69 63 21 28 22 5b 7b 63 6f 6e 66 69 67  panic!("[{config
2f20: 5f 66 69 6c 65 3a 3f 7d 5d 20 74 68 65 72 65 20  _file:?}] there 
2f30: 77 61 73 20 61 6e 20 65 72 72 6f 72 20 72 65 61  was an error rea
2f40: 64 69 6e 67 20 63 6f 6e 66 69 67 5c 6e 5c 0a 09  ding config\n\..
2f50: 09 09 5c 74 70 6c 65 61 73 65 20 63 6f 6e 73 75  ..\tplease consu
2f60: 6c 74 20 5c 22 73 6d 74 70 32 74 67 2e 74 6f 6d  lt \"smtp2tg.tom
2f70: 6c 2e 65 78 61 6d 70 6c 65 5c 22 20 66 6f 72 20  l.example\" for 
2f80: 64 65 74 61 69 6c 73 22 29 29 3b 0a 0a 09 6c 65  details"));...le
2f90: 74 20 6c 69 73 74 65 6e 5f 6f 6e 20 3d 20 73 65  t listen_on = se
2fa0: 74 74 69 6e 67 73 2e 67 65 74 5f 73 74 72 69 6e  ttings.get_strin
2fb0: 67 28 22 6c 69 73 74 65 6e 5f 6f 6e 22 29 3f 3b  g("listen_on")?;
2fc0: 0a 09 6c 65 74 20 73 65 72 76 65 72 5f 6e 61 6d  ..let server_nam
2fd0: 65 20 3d 20 73 65 74 74 69 6e 67 73 2e 67 65 74  e = settings.get
2fe0: 5f 73 74 72 69 6e 67 28 22 68 6f 73 74 6e 61 6d  _string("hostnam
2ff0: 65 22 29 3f 3b 0a 09 6c 65 74 20 63 6f 72 65 20  e")?;..let core 
3000: 3d 20 54 65 6c 65 67 72 61 6d 54 72 61 6e 73 70  = TelegramTransp
3010: 6f 72 74 3a 3a 6e 65 77 28 73 65 74 74 69 6e 67  ort::new(setting
3020: 73 29 3b 0a 09 6c 65 74 20 6d 75 74 20 73 65 72  s);..let mut ser
3030: 76 65 72 20 3d 20 6d 61 69 6c 69 6e 5f 65 6d 62  ver = mailin_emb
3040: 65 64 64 65 64 3a 3a 53 65 72 76 65 72 3a 3a 6e  edded::Server::n
3050: 65 77 28 63 6f 72 65 29 3b 0a 0a 09 73 65 72 76  ew(core);...serv
3060: 65 72 2e 77 69 74 68 5f 6e 61 6d 65 28 73 65 72  er.with_name(ser
3070: 76 65 72 5f 6e 61 6d 65 29 0a 09 09 2e 77 69 74  ver_name)....wit
3080: 68 5f 73 73 6c 28 6d 61 69 6c 69 6e 5f 65 6d 62  h_ssl(mailin_emb
3090: 65 64 64 65 64 3a 3a 53 73 6c 43 6f 6e 66 69 67  edded::SslConfig
30a0: 3a 3a 4e 6f 6e 65 29 2e 75 6e 77 72 61 70 28 29  ::None).unwrap()
30b0: 0a 09 09 2e 77 69 74 68 5f 61 64 64 72 28 6c 69  ....with_addr(li
30c0: 73 74 65 6e 5f 6f 6e 29 2e 75 6e 77 72 61 70 28  sten_on).unwrap(
30d0: 29 3b 0a 09 73 65 72 76 65 72 2e 73 65 72 76 65  );..server.serve
30e0: 28 29 2e 75 6e 77 72 61 70 28 29 3b 0a 0a 09 4f  ().unwrap();...O
30f0: 6b 28 28 29 29 0a 7d 0a                          k(()).}.