You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

notifications.rs 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * meli - ui crate.
  3. *
  4. * Copyright 2017-2018 Manos Pitsidianakis
  5. *
  6. * This file is part of meli.
  7. *
  8. * meli is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * meli is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with meli. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /*!
  22. Notification handling components.
  23. */
  24. use notify_rust::Notification as notify_Notification;
  25. use std::process::{Command, Stdio};
  26. use super::*;
  27. /// Passes notifications to the OS using the XDG specifications.
  28. #[derive(Debug)]
  29. pub struct XDGNotifications {}
  30. impl fmt::Display for XDGNotifications {
  31. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  32. // TODO display subject/info
  33. write!(f, "")
  34. }
  35. }
  36. impl Component for XDGNotifications {
  37. fn draw(&mut self, _grid: &mut CellBuffer, _area: Area, _context: &mut Context) {}
  38. fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
  39. if let UIEventType::Notification(ref title, ref body) = event.event_type {
  40. notify_Notification::new()
  41. .appname("meli")
  42. .icon("mail-message-new")
  43. .summary(title.as_ref().map(|v| v.as_str()).unwrap_or("Event"))
  44. .body(&escape_str(body))
  45. .icon("dialog-information")
  46. .show()
  47. .unwrap();
  48. }
  49. false
  50. }
  51. fn set_dirty(&mut self) {}
  52. }
  53. fn escape_str(s: &str) -> String {
  54. let mut ret: String = String::with_capacity(s.len());
  55. for c in s.chars() {
  56. match c {
  57. '&' => ret.push_str("&amp;"),
  58. '<' => ret.push_str("&lt;"),
  59. '>' => ret.push_str("&gt;"),
  60. '\'' => ret.push_str("&apos;"),
  61. '"' => ret.push_str("&quot;"),
  62. _ => {
  63. let i = c as u32;
  64. if (0x1 <= i && i <= 0x8)
  65. || (0xb <= i && i <= 0xc)
  66. || (0xe <= i && i <= 0x1f)
  67. || (0x7f <= i && i <= 0x84)
  68. || (0x86 <= i && i <= 0x9f)
  69. {
  70. ret.push_str(&format!("&#{:x}%{:x};", i, i));
  71. } else {
  72. ret.push(c);
  73. }
  74. }
  75. }
  76. }
  77. ret
  78. }
  79. #[cfg(test)]
  80. mod tests {
  81. use super::*;
  82. #[test]
  83. fn test_escape_str() {
  84. let title: &str = "& > Title τίτλος";
  85. let body: &str = "& > Body σώμα";
  86. notify_Notification::new()
  87. .appname("meli")
  88. .icon("mail-message-new")
  89. .summary(title)
  90. .body(&escape_str(body))
  91. .icon("dialog-information")
  92. .show()
  93. .unwrap();
  94. }
  95. }
  96. /// Passes notifications to the OS using the XDG specifications.
  97. #[derive(Debug)]
  98. pub struct NotificationFilter {}
  99. impl fmt::Display for NotificationFilter {
  100. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  101. // TODO display subject/info
  102. write!(f, "")
  103. }
  104. }
  105. impl Component for NotificationFilter {
  106. fn draw(&mut self, _grid: &mut CellBuffer, _area: Area, _context: &mut Context) {}
  107. fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
  108. if let UIEventType::Notification(ref title, ref body) = event.event_type {
  109. if let Some(ref bin) = context.runtime_settings.notifications.script {
  110. if let Err(v) = Command::new(bin)
  111. .arg(title.as_ref().map(|v| v.as_str()).unwrap_or("Event"))
  112. .arg(body)
  113. .stdin(Stdio::piped())
  114. .stdout(Stdio::piped())
  115. .spawn()
  116. {
  117. eprintln!("{:?}", v);
  118. }
  119. }
  120. }
  121. false
  122. }
  123. fn set_dirty(&mut self) {}
  124. }