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.

125 lines
3.9KB

  1. use std::env;
  2. use std::error::Error as StdError;
  3. use std::io::Write;
  4. use std::time::Instant;
  5. use atty;
  6. use chrono::Duration;
  7. use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
  8. use errors::Error;
  9. use site::Site;
  10. lazy_static! {
  11. /// Termcolor color choice.
  12. /// We do not rely on ColorChoice::Auto behavior
  13. /// as the check is already performed by has_color.
  14. static ref COLOR_CHOICE: ColorChoice =
  15. if has_color() {
  16. ColorChoice::Always
  17. } else {
  18. ColorChoice::Never
  19. };
  20. }
  21. pub fn info(message: &str) {
  22. colorize(message, ColorSpec::new().set_bold(true));
  23. }
  24. pub fn warn(message: &str) {
  25. colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Yellow)));
  26. }
  27. pub fn success(message: &str) {
  28. colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Green)));
  29. }
  30. pub fn error(message: &str) {
  31. colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Red)));
  32. }
  33. /// Print a colorized message to stdout
  34. fn colorize(message: &str, color: &ColorSpec) {
  35. let mut stdout = StandardStream::stdout(*COLOR_CHOICE);
  36. stdout.set_color(color).unwrap();
  37. writeln!(&mut stdout, "{}", message).unwrap();
  38. stdout.set_color(&ColorSpec::new()).unwrap();
  39. }
  40. /// Display in the console the number of pages/sections in the site, and number of images to process
  41. pub fn notify_site_size(site: &Site) {
  42. let library = site.library.read().unwrap();
  43. println!(
  44. "-> Creating {} pages ({} orphan), {} sections, and processing {} images",
  45. library.pages().len(),
  46. site.get_number_orphan_pages(),
  47. library.sections().len() - 1, // -1 since we do not count the index as a section there
  48. site.num_img_ops(),
  49. );
  50. }
  51. /// Display in the console only the number of pages/sections in the site
  52. pub fn notify_site_size_simple(site: &Site) {
  53. let library = site.library.read().unwrap();
  54. println!(
  55. "-> {} pages ({} orphan), {} sections",
  56. library.pages().len(),
  57. site.get_number_orphan_pages(),
  58. library.sections().len() - 1, // -1 since we do not count the index as a section there
  59. );
  60. }
  61. /// Display a warning in the console if there are ignored pages in the site
  62. pub fn warn_about_ignored_pages(site: &Site) {
  63. let library = site.library.read().unwrap();
  64. let ignored_pages: Vec<_> = library
  65. .sections_values()
  66. .iter()
  67. .flat_map(|s| s.ignored_pages.iter().map(|k| library.get_page_by_key(*k).file.path.clone()))
  68. .collect();
  69. if !ignored_pages.is_empty() {
  70. warn(&format!(
  71. "{} page(s) ignored (missing date or weight in a sorted section):",
  72. ignored_pages.len()
  73. ));
  74. for path in ignored_pages {
  75. warn(&format!("- {}", path.display()));
  76. }
  77. }
  78. }
  79. /// Print the time elapsed rounded to 1 decimal
  80. pub fn report_elapsed_time(instant: Instant) {
  81. let duration_ms = Duration::from_std(instant.elapsed()).unwrap().num_milliseconds() as f64;
  82. if duration_ms < 1000.0 {
  83. success(&format!("Done in {}ms.\n", duration_ms));
  84. } else {
  85. let duration_sec = duration_ms / 1000.0;
  86. success(&format!("Done in {:.1}s.\n", ((duration_sec * 10.0).round() / 10.0)));
  87. }
  88. }
  89. /// Display an error message and the actual error(s)
  90. pub fn unravel_errors(message: &str, error: &Error) {
  91. if !message.is_empty() {
  92. self::error(message);
  93. }
  94. self::error(&format!("Error: {}", error));
  95. let mut cause = error.source();
  96. while let Some(e) = cause {
  97. self::error(&format!("Reason: {}", e));
  98. cause = e.source();
  99. }
  100. }
  101. /// Check whether to output colors
  102. fn has_color() -> bool {
  103. let use_colors = env::var("CLICOLOR").unwrap_or_else(|_| "1".to_string()) != "0"
  104. && env::var("NO_COLOR").is_err();
  105. let force_colors = env::var("CLICOLOR_FORCE").unwrap_or_else(|_| "0".to_string()) != "0";
  106. force_colors || use_colors && atty::is(atty::Stream::Stdout)
  107. }