mirror of
https://github.com/tealdeer-rs/tealdeer.git
synced 2026-08-23 08:34:18 +02:00
Download and decompress tldr pages
This commit is contained in:
parent
c90e3499e5
commit
e7e3211cd5
5 changed files with 327 additions and 0 deletions
210
Cargo.lock
generated
210
Cargo.lock
generated
|
|
@ -3,8 +3,21 @@ name = "tldr"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tar 0.3.2 (git+https://github.com/dbrgn/tar-rs?branch=pax_header)",
|
||||
"tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "advapi32-sys"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -20,6 +33,30 @@ name = "ansi_term"
|
|||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "curl"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"curl-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.3.2"
|
||||
|
|
@ -29,11 +66,74 @@ dependencies = [
|
|||
"regex 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdi32-sys"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libressl-pnacl-sys"
|
||||
version = "2.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.4"
|
||||
|
|
@ -42,6 +142,11 @@ dependencies = [
|
|||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.7"
|
||||
|
|
@ -50,6 +155,50 @@ dependencies = [
|
|||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz-sys"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pnacl-build-helper"
|
||||
version = "1.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.44"
|
||||
|
|
@ -65,3 +214,64 @@ name = "regex-syntax"
|
|||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.3.2"
|
||||
source = "git+https://github.com/dbrgn/tar-rs?branch=pax_header#b573100243c34347fbeba6345bfbba5a47b16dd0"
|
||||
dependencies = [
|
||||
"filetime 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "0.2.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "user32-sys"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,4 +9,8 @@ logging = ["env_logger"]
|
|||
[dependencies]
|
||||
ansi_term = "^0.7"
|
||||
log = "^0.3"
|
||||
tar = { git = "https://github.com/dbrgn/tar-rs", branch = "pax_header" }
|
||||
flate2 = "^0.2"
|
||||
tempdir = "^0.3"
|
||||
curl = "^0.2"
|
||||
env_logger = { version = "^0.3", optional = true }
|
||||
|
|
|
|||
14
src/error.rs
Normal file
14
src/error.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use curl::ErrCode;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TldrError {
|
||||
UpdateError(String)
|
||||
}
|
||||
|
||||
|
||||
impl From<ErrCode> for TldrError {
|
||||
fn from(err: ErrCode) -> TldrError {
|
||||
TldrError::UpdateError(err.to_string())
|
||||
}
|
||||
}
|
||||
16
src/main.rs
16
src/main.rs
|
|
@ -3,6 +3,10 @@
|
|||
#[macro_use] extern crate log;
|
||||
#[cfg(feature = "logging")]extern crate env_logger;
|
||||
extern crate ansi_term;
|
||||
extern crate flate2;
|
||||
extern crate tar;
|
||||
extern crate tempdir;
|
||||
extern crate curl;
|
||||
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::fs::File;
|
||||
|
|
@ -12,9 +16,13 @@ use ansi_term::Colour;
|
|||
|
||||
mod types;
|
||||
mod tokenizer;
|
||||
mod updater;
|
||||
mod error;
|
||||
|
||||
use types::LineType;
|
||||
use tokenizer::Tokenizer;
|
||||
use updater::Updater;
|
||||
use error::TldrError;
|
||||
|
||||
|
||||
/// Open file, return a `BufRead` instance
|
||||
|
|
@ -76,6 +84,14 @@ fn main() {
|
|||
print_lines(&mut tokenizer);
|
||||
println!("");
|
||||
|
||||
let dl = Updater::new("https://github.com/tldr-pages/tldr/archive/master.tar.gz".into());
|
||||
dl.update().unwrap_or_else(|e| {
|
||||
match e {
|
||||
TldrError::UpdateError(msg) => println!("Could not update cache: {}", msg),
|
||||
};
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
83
src/updater.rs
Normal file
83
src/updater.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
use std::io::Read;
|
||||
use std::io::Result as IoResult;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
use flate2::read::GzDecoder;
|
||||
use tar::Archive;
|
||||
use curl::http;
|
||||
use tempdir::TempDir;
|
||||
|
||||
use error::TldrError::{self, UpdateError};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Updater {
|
||||
url: String,
|
||||
}
|
||||
|
||||
impl Updater {
|
||||
|
||||
pub fn new(url: String) -> Updater {
|
||||
Updater {
|
||||
url: url,
|
||||
}
|
||||
}
|
||||
|
||||
/// Download the archive
|
||||
fn download(&self) -> Result<http::Response, TldrError> {
|
||||
let resp = try!(
|
||||
http::handle()
|
||||
.follow_location(1)
|
||||
.get(&self.url[..])
|
||||
.exec()
|
||||
);
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
/// Decompress and open the archive
|
||||
fn decompress<R: Read>(&self, reader: R) -> Result<Archive<GzDecoder<R>>, TldrError> {
|
||||
let decoder = try!(GzDecoder::new(reader).map_err(|_| UpdateError("Could not decode gzip data".into())));
|
||||
Ok(Archive::new(decoder))
|
||||
}
|
||||
|
||||
/// Extract archive, return pages and license
|
||||
fn extract<R: Read>(&self, archive: &mut Archive<R>, path: &Path) -> Result<(PathBuf, PathBuf), TldrError> {
|
||||
try!(archive.unpack(path).map_err(|e| {
|
||||
UpdateError(format!("Could not unpack compressed data: {}", e))
|
||||
}));
|
||||
let repodir = path.join("tldr-master");
|
||||
Ok((repodir.join("pages"), repodir.join("LICENSE.md")))
|
||||
}
|
||||
|
||||
fn get_pages(&self, path: &Path) -> Vec<PathBuf> {
|
||||
}
|
||||
|
||||
/// Update the pages cache.
|
||||
pub fn update(&self) -> Result<(), TldrError> {
|
||||
// First, download the compressed data
|
||||
let response = try!(self.download());
|
||||
|
||||
// Decompress the response body into an `Archive`
|
||||
let mut archive = try!(self.decompress(response.get_body()));
|
||||
|
||||
// Create temporary directory
|
||||
let dir = try!(TempDir::new("tldr").map_err(|e| {
|
||||
UpdateError(format!("Could not create temporary directory: {}", e))
|
||||
}));
|
||||
|
||||
// Get paths to pages and license
|
||||
let (pages_path, license_path) = try!(self.extract(&mut archive, dir.path()));
|
||||
|
||||
// Copy files
|
||||
let home_dir = try!(env::home_dir().ok_or(UpdateError("Could not determine home directory".into())));
|
||||
let cache_dir = home_dir.join(".tldr").join("cache");
|
||||
try!(fs::copy(license_path, cache_dir.join("LICENSE.md")).map_err(|e| {
|
||||
UpdateError(format!("Could not extract license file: {}", e))
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue