Add prettyness.

This commit is contained in:
Daniel 2023-02-28 23:52:38 -05:00
parent ce51c184a5
commit 7ec53f3806
7 changed files with 69 additions and 2 deletions

7
Cargo.lock generated
View file

@ -1399,6 +1399,7 @@ dependencies = [
"ring", "ring",
"serde", "serde",
"serde_regex", "serde_regex",
"text-template",
"url", "url",
] ]
@ -1563,6 +1564,12 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "text-template"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51bcc3e9514cba67c087126b18600010c7c29b0cb51a6f6bc75e5058c2369bba"
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.17" version = "0.3.17"

View file

@ -34,6 +34,7 @@ humantime-serde = "1.1.1"
glob = "0.3.1" glob = "0.3.1"
ring = "0.16.20" ring = "0.16.20"
hotwatch = "0.4.5" hotwatch = "0.4.5"
text-template = "0.1.0"
[dependencies.config] [dependencies.config]
version = "0.13.3" version = "0.13.3"

View file

@ -1,6 +1,8 @@
<a href="https://github.com/orhun/rustypaste"><img src="img/rustypaste_logo.png" width="500"></a> <a href="https://github.com/orhun/rustypaste"><img src="img/rustypaste_logo.png" width="500"></a>
**Rustypaste** is a minimal file upload/pastebin service. **Rustypaste-pretty** is a minimal file upload/pastebin service with client side highlighting provided by highlight.js.
Just add `?pretty` to the end of a link to highlight!
```sh ```sh
$ echo "some text" > awesome.txt $ echo "some text" > awesome.txt

View file

@ -2,12 +2,13 @@
refresh_rate="1s" refresh_rate="1s"
[server] [server]
address="127.0.0.1:8000" address="127.0.0.1:8020"
#workers=4 #workers=4
max_content_length="10MB" max_content_length="10MB"
upload_path="./upload" upload_path="./upload"
timeout="30s" timeout="30s"
expose_version=false expose_version=false
style="monokai"
landing_page="""Submit files via HTTP POST here: landing_page="""Submit files via HTTP POST here:
curl -F 'file=@example.txt' <server>" curl -F 'file=@example.txt' <server>"
This will return the finished URL. This will return the finished URL.
@ -42,5 +43,10 @@ mime_blacklist = [
"application/java-archive", "application/java-archive",
"application/java-vm" "application/java-vm"
] ]
duplicate_files = true duplicate_files = true
delete_expired_files = { enabled = true, interval = "1h" } delete_expired_files = { enabled = true, interval = "1h" }
[paste.highlight_override]
# For example, to force markdown rather than using highlight.js's autodetection
#"text/markdown" = "markdown"

View file

@ -2,6 +2,7 @@ use crate::mime::MimeMatcher;
use crate::random::RandomURLConfig; use crate::random::RandomURLConfig;
use byte_unit::Byte; use byte_unit::Byte;
use config::{self, ConfigError}; use config::{self, ConfigError};
use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::Duration; use std::time::Duration;
@ -45,6 +46,8 @@ pub struct ServerConfig {
pub landing_page: Option<String>, pub landing_page: Option<String>,
/// Expose version. /// Expose version.
pub expose_version: Option<bool>, pub expose_version: Option<bool>,
/// Highlight.js style
pub style: Option<String>,
} }
/// Paste configuration. /// Paste configuration.
@ -64,6 +67,9 @@ pub struct PasteConfig {
pub duplicate_files: Option<bool>, pub duplicate_files: Option<bool>,
/// Delete expired files. /// Delete expired files.
pub delete_expired_files: Option<CleanupConfig>, pub delete_expired_files: Option<CleanupConfig>,
/// Highlight override.
#[serde(default)]
pub highlight_override: HashMap<String, String>,
} }
/// Cleanup configuration. /// Cleanup configuration.
@ -80,6 +86,7 @@ impl Config {
/// Parses the config file and returns the values. /// Parses the config file and returns the values.
pub fn parse(path: &Path) -> Result<Config, ConfigError> { pub fn parse(path: &Path) -> Result<Config, ConfigError> {
config::Config::builder() config::Config::builder()
.set_default("style", "default").unwrap()
.add_source(config::File::from(path)) .add_source(config::File::from(path))
.add_source(config::Environment::default().separator("__")) .add_source(config::Environment::default().separator("__"))
.build()? .build()?

23
src/pretty.html Normal file
View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>${file}</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/${style}.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<script>
var xhr= new XMLHttpRequest();
xhr.open('GET', '${file}', true);
xhr.onreadystatechange= function() {
if (this.readyState!==4) return;
if (this.status!==200) return; // or whatever error handling you want
document.getElementById('h').innerHTML= this.responseText;
hljs.highlightAll();
};
xhr.send();
</script>
</head>
<body>
<pre><code id="h" class="${type}">
</code></pre>
</body>
</html>

View file

@ -6,6 +6,7 @@ use crate::mime as mime_util;
use crate::paste::{Paste, PasteType}; use crate::paste::{Paste, PasteType};
use crate::util; use crate::util;
use crate::AUTH_TOKEN_ENV; use crate::AUTH_TOKEN_ENV;
use text_template::*;
use actix_files::NamedFile; use actix_files::NamedFile;
use actix_multipart::Multipart; use actix_multipart::Multipart;
use actix_web::{error, get, post, web, Error, HttpRequest, HttpResponse}; use actix_web::{error, get, post, web, Error, HttpRequest, HttpResponse};
@ -16,7 +17,9 @@ use serde::Deserialize;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::env; use std::env;
use std::fs; use std::fs;
use std::str;
use std::sync::RwLock; use std::sync::RwLock;
use std::collections::HashMap;
/// Shows the landing page. /// Shows the landing page.
#[get("/")] #[get("/")]
@ -51,6 +54,7 @@ async fn serve(
let config = config let config = config
.read() .read()
.map_err(|_| error::ErrorInternalServerError("cannot acquire config"))?; .map_err(|_| error::ErrorInternalServerError("cannot acquire config"))?;
let path = config.server.upload_path.join(&*file); let path = config.server.upload_path.join(&*file);
let mut path = util::glob_match_file(path)?; let mut path = util::glob_match_file(path)?;
let mut paste_type = PasteType::File; let mut paste_type = PasteType::File;
@ -78,6 +82,23 @@ async fn serve(
mime_util::get_mime_type(&config.paste.mime_override, file.to_string()) mime_util::get_mime_type(&config.paste.mime_override, file.to_string())
.map_err(error::ErrorInternalServerError)? .map_err(error::ErrorInternalServerError)?
}; };
if request.query_string() == "pretty" {
let mut values = HashMap::new();
let tmpl_bytes = str::from_utf8(include_bytes!("pretty.html")).unwrap();
let tmpl = Template::from(tmpl_bytes);
values.insert("file", file.as_str());
values.insert("style", match &config.server.style {
Some(style) => style.as_str(),
None => "default",
});
let mime_str = mime_type.to_string();
let overrides = &config.paste.highlight_override;
values.insert("type", if overrides.contains_key(&mime_str) { overrides[&mime_str].as_str() } else { "" });
let rendered = tmpl.fill_in(&values);
return Ok(HttpResponse::Ok().body(rendered.to_string()))
}
let response = NamedFile::open(&path)? let response = NamedFile::open(&path)?
.disable_content_disposition() .disable_content_disposition()
.set_content_type(mime_type) .set_content_type(mime_type)