A library for writing host-specific, single-binary configuration management and deployment tools
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.

106 lines
4.9 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. use regex::Regex;
  2. use std::cmp::max;
  3. use std::error::Error;
  4. use std::fmt;
  5. use std::fs::File as FsFile;
  6. use std::io;
  7. use std::io::Read;
  8. use std::ops::Deref;
  9. use std::path::Path;
  10. use command_runner::CommandRunner;
  11. use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
  12. use resources::Resource;
  13. pub struct WordpressTranslation<'a, C, D, R> where C: Deref<Target=str> + fmt::Display, D: AsRef<str> + fmt::Display, R: 'a + CommandRunner {
  14. path: D,
  15. language: C,
  16. command_runner: &'a R
  17. }
  18. impl<'a, C, R> WordpressTranslation<'a, C, String, R> where C: Deref<Target=str> + fmt::Display, R: CommandRunner {
  19. pub fn new<D: AsRef<str> + fmt::Display>(path: D, language: C, command_runner: &'a R) -> Self {
  20. WordpressTranslation {
  21. path: Path::new(path.as_ref()).join("wp-content/languages").to_string_lossy().to_string(),
  22. language: language,
  23. command_runner: command_runner
  24. }
  25. }
  26. }
  27. /*
  28. https://translate.wordpress.org/projects/wp/4.7.x/de/default/export-translations?format=po > /home/de_adrianheine_blog/WordPress/wp-content/languages/de_DE.po
  29. https://translate.wordpress.org/projects/wp/4.7.x/de/default/export-translations?format=mo > /home/de_adrianheine_blog/WordPress/wp-content/languages/de_DE.mo
  30. https://translate.wordpress.org/projects/wp/4.7.x/cc/de/default/export-translations?format=po > /home/de_adrianheine_blog/WordPress/wp-content/languages/continents-cities-de_DE.po
  31. https://translate.wordpress.org/projects/wp/4.7.x/cc/de/default/export-translations?format=mo > /home/de_adrianheine_blog/WordPress/wp-content/languages/continents-cities-de_DE.mo
  32. https://translate.wordpress.org/projects/wp/4.7.x/admin/de/default/export-translations?format=po > /home/de_adrianheine_blog/WordPress/wp-content/languages/admin-de_DE.po
  33. https://translate.wordpress.org/projects/wp/4.7.x/admin/de/default/export-translations?format=mo > /home/de_adrianheine_blog/WordPress/wp-content/languages/admin-de_DE.mo
  34. https://translate.wordpress.org/projects/wp/4.7.x/admin/network/de/default/export-translations?format=po > /home/de_adrianheine_blog/WordPress/wp-content/languages/admin-network-de_DE.po
  35. https://translate.wordpress.org/projects/wp/4.7.x/admin/network/de/default/export-translations?format=mo > /home/de_adrianheine_blog/WordPress/wp-content/languages/admin-network-de_DE.mo
  36. */
  37. impl<'a, C, D, R> WordpressTranslation<'a, C, D, R> where C: Deref<Target=str> + fmt::Display, D: AsRef<str> + fmt::Display, R: CommandRunner {
  38. fn get_pairs(&self) -> Vec<(String, String)> {
  39. let mut res = vec![];
  40. for &(in_slug, out_slug) in [("", ""), ("cc/", "continents-cities-"), ("admin/", "admin-"), ("admin/network/", "admin-network-")].into_iter() {
  41. for format in ["po", "mo"].into_iter() {
  42. res.push((format!("https://translate.wordpress.org/projects/wp/4.7.x/{}{}/default/export-translations?format={}", in_slug, self.language, format), format!("{}/{}de_DE.{}", self.path, out_slug, format)))
  43. }
  44. }
  45. res
  46. }
  47. }
  48. impl<'a, C, D, R> Symbol for WordpressTranslation<'a, C, D, R> where C: Deref<Target=str> + fmt::Display, D: AsRef<str> + fmt::Display, R: CommandRunner {
  49. fn target_reached(&self) -> Result<bool, Box<Error>> {
  50. let mut newest = String::new();
  51. let match_date = Regex::new("(?m)^\"PO-Revision-Date: (.+)\\+0000\\\\n\"$").unwrap();
  52. for (_, target) in self.get_pairs() {
  53. let file = FsFile::open(target.clone());
  54. // Check if file exists
  55. if let Err(e) = file {
  56. return if e.kind() == io::ErrorKind::NotFound {
  57. Ok(false)
  58. } else {
  59. Err(Box::new(e))
  60. };
  61. }
  62. if target.ends_with(".po") {
  63. let mut content = String::new();
  64. try!(file.unwrap().read_to_string(&mut content));
  65. let file_date = &match_date.captures(&content).unwrap()[1];
  66. newest = max(newest, file_date.to_string());
  67. }
  68. }
  69. let upstream = try!(self.command_runner.get_output("curl", &["https://api.wordpress.org/core/version-check/1.7/?version=4.7.8&locale=de_DE"]));
  70. Ok(try!(String::from_utf8(upstream)).contains(&format!(r###"language":"de_DE","version":"4.7.8","updated":"{}"###, newest)))
  71. }
  72. fn execute(&self) -> Result<(), Box<Error>> {
  73. for (source, target) in self.get_pairs() {
  74. try!(self.command_runner.run_successfully("curl", &["--compressed", "-o", &target, &source]));
  75. }
  76. Ok(())
  77. }
  78. fn get_prerequisites(&self) -> Vec<Resource> {
  79. vec![ Resource::new("dir", self.path.as_ref()) ]
  80. }
  81. fn as_action<'b>(&'b self, runner: &'b SymbolRunner) -> Box<Action + 'b> {
  82. Box::new(SymbolAction::new(runner, self))
  83. }
  84. fn into_action<'b>(self: Box<Self>, runner: &'b SymbolRunner) -> Box<Action + 'b> where Self: 'b {
  85. Box::new(OwnedSymbolAction::new(runner, *self))
  86. }
  87. }
  88. impl<'a, C, D, R> fmt::Display for WordpressTranslation<'a, C, D, R> where C: Deref<Target=str> + fmt::Display, D: AsRef<str> + fmt::Display, R: CommandRunner {
  89. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
  90. write!(f, "WordpressTranslation {}", self.path)
  91. }
  92. }