Skip to content

Commit

Permalink
Merge pull request #1 from machengim/dev
Browse files Browse the repository at this point in the history
Release v0.1.1
  • Loading branch information
machengim authored Oct 27, 2021
2 parents 0bfc453 + fe8698b commit d18bf0c
Show file tree
Hide file tree
Showing 20 changed files with 303 additions and 262 deletions.
61 changes: 32 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,60 @@

[中文 README](https://github.com/machengim/oasis/blob/main/README_cn.md)

Minimalized file hosting and sharing app.
Minimalized self-hosted file server.

![](https://github.com/machengim/oasis/blob/dev/doc/Oasis_demo.jpg?raw=true)

### Install

1. Download from the release page
1. Download from the [release](https://github.com/machengim/oasis/releases) page
2. Uncompress
3. Run `oasis` or `oasis.exe`
4. Visit the server's IP address in your favorite browser

### Features

+ User authentication
+ File preview
+ Play list
+ Mobile compatibility
+ Temporary sharing link
+ Multiple platform support
+ I18n (English, Chinese)
- User authentication
- File preview
- File download
- Play list
- Mobile compatibility
- Temporary sharing link
- External media player support via sharing link
- Multiple platform support
- I18n (English, Chinese)

### File format support

+ Text
+ Image (browser support)
+ Audio (browser support)
+ Video (browser support)
+ Subtitle (srt / vtt format, supported in Chrome, Firefox and Edge by now)
+ PDF (supported by pdf.js)
- Text
- Image (browser support)
- Audio (browser support)
- Video (browser support)
- Subtitle (srt / vtt format, supported in Chrome, Firefox and Edge by now)
- PDF (supported by pdf.js)

### Roadmap

+ [ ] Custom media player
+ [ ] Download files
+ [ ] Multiple users management
+ [ ] HTTPS
+ [ ] More file format support
- [ ] Custom media player
- [ ] Multiple users management
- [ ] HTTPS
- [ ] More file format support

### Tech stack

+ [Svelte](https://svelte.dev)
+ [Rocket](https://rocket.rs)
+ [Tailwind](https://tailwindcss.com)
+ [Pdf.js](https://mozilla.github.io/pdf.js)
+ [Plyr](https://plyr.io)
- [Svelte](https://svelte.dev)
- [Rocket](https://rocket.rs)
- [Tailwind](https://tailwindcss.com)
- [Pdf.js](https://mozilla.github.io/pdf.js)
- [Plyr](https://plyr.io)

### Build process

+ Node 14.17
+ Rust 1.54
+ Python3
- Node 14.17+
- Rust 1.54+
- Python3

```
cd path/to/oasis
python3 build.py
```
```
63 changes: 33 additions & 30 deletions README_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,60 @@

[English README](https://github.com/machengim/oasis/blob/main/README.md)

极简文件服务和共享应用。
极简自建文件服务器。

![](https://github.com/machengim/oasis/blob/dev/doc/Oasis_demo.jpg?raw=true)

### 安装

1. 从release页面下载
1. [release](https://github.com/machengim/oasis/releases) 页面下载
2. 解压缩
3. 运行 `oasis``oasis.exe`
4. 从浏览器访问服务器的IP地址
4. 从浏览器访问服务器的 IP 地址

### 功能

+ 用户验证
+ 文件预览
+ 播放列表
+ 移动端适配
+ 临时共享链接
+ 多平台支持
+ I18n (英语, 中文)
- 用户验证
- 文件预览
- 文件下载
- 播放列表
- 移动端适配
- 临时分享链接
- 外部媒体播放器支持(通过分享链接)
- 多平台支持
- I18n (英语, 中文)

### 文件格式支持

+ 文本
+ 图片 (浏览器支持)
+ 音频 (浏览器支持)
+ 视频 (浏览器支持)
+ 字幕 (srt / vtt 格式, 支持 Chrome, Firefox 和 Edge 浏览器)
+ PDF (由 pdf.js 支持)
- 文本
- 图片 (浏览器支持)
- 音频 (浏览器支持)
- 视频 (浏览器支持)
- 字幕 (srt / vtt 格式, 支持 Chrome, Firefox 和 Edge 浏览器)
- PDF (由 pdf.js 支持)

### 规划

+ [ ] 定制媒体播放器
+ [ ] 下载文件
+ [ ] 多用户管理
+ [ ] HTTPS
+ [ ] 更多文件格式支持
- [ ] 定制媒体播放器
- [ ] 多用户管理
- [ ] HTTPS
- [ ] 更多文件格式支持

### 技术栈

+ [Svelte](https://svelte.dev)
+ [Rocket](https://rocket.rs)
+ [Tailwind](https://tailwindcss.com)
+ [Pdf.js](https://mozilla.github.io/pdf.js)
+ [Plyr](https://plyr.io)
- [Svelte](https://svelte.dev)
- [Rocket](https://rocket.rs)
- [Tailwind](https://tailwindcss.com)
- [Pdf.js](https://mozilla.github.io/pdf.js)
- [Plyr](https://plyr.io)

### 构建

+ Node 14.17
+ Rust 1.54
+ Python3
- Node 14.17
- Rust 1.54
- Python3

```
cd path/to/oasis
python3 build.py
```
```
28 changes: 14 additions & 14 deletions backend/src/api/files.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::entity::error::Error;
use crate::entity::file::{File, FileType};
use crate::entity::file::File;
use crate::entity::request::GenerateLinkRequest;
use crate::entity::response::FileResponse;
use crate::service::app_state::AppState;
use crate::service::auth::AuthUser;
use crate::service::range::RangedFile;
use crate::service::range::{Range, RangedFile};
use crate::service::track;
use crate::util::{self, file_system};
use crate::util;
use rocket::fs::NamedFile;
use rocket::serde::json::Json;
use rocket::tokio::fs;
Expand Down Expand Up @@ -55,6 +55,7 @@ async fn file_content(
path: &str,
_user: AuthUser,
state: &State<AppState>,
range_header: Range,
) -> Result<FileResponse, Error> {
let storage = state.get_site()?.storage.clone();
let target_path = PathBuf::from(&storage).join(&util::parse_encoded_url(path)?);
Expand All @@ -64,14 +65,12 @@ async fn file_content(
return Err(Error::BadRequest);
}

match FileType::get_file_type(&target_path) {
FileType::Code | FileType::Text => Ok(FileResponse::Text(
file_system::read_text_file(target_path).await?,
)),
FileType::Video | FileType::Music => {
Ok(FileResponse::Range(RangedFile { path: target_path }))
match range_header.range {
Some(range) => {
let ranged_file = RangedFile::new(range, target_path).await?;
Ok(FileResponse::Range(ranged_file))
}
_ => Ok(FileResponse::Binary(NamedFile::open(target_path).await?)),
None => Ok(FileResponse::Binary(NamedFile::open(target_path).await?)),
}
}

Expand Down Expand Up @@ -105,10 +104,10 @@ async fn generate_share_link(
) -> Result<String, Error> {
let secret = state.get_secret()?;
let path_encode = urlencoding::encode(&req_body.path);
let input = format!("path={}&expire={}", path_encode, req_body.expire);
let input = format!("expire={}&path={}", req_body.expire, path_encode);
let hash = util::sha256(&input, &secret);

Ok(format!("{}&hash={}", input, hash))
Ok(format!("hash={}&{}", hash, input))
}

#[get("/file/share?<path>&<expire>&<hash>")]
Expand All @@ -117,16 +116,17 @@ async fn get_share_link(
path: &str,
expire: i64,
hash: &str,
range_header: Range,
) -> Result<FileResponse, Error> {
let secret = state.get_secret()?;
let path_encode = urlencoding::encode(path);

let input = format!("path={}&expire={}", path_encode, expire);
let input = format!("expire={}&path={}", expire, path_encode);
if hash != util::sha256(&input, &secret) {
return Err(Error::BadRequest);
}

let user = AuthUser::default();

Ok(file_content(path, user, state).await?)
Ok(file_content(path, user, state, range_header).await?)
}
4 changes: 2 additions & 2 deletions backend/src/api/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::entity::user::User;
use crate::service::app_state::AppState;
use crate::service::auth::AuthAdmin;
use crate::service::token::AccessToken;
use crate::util::{self, constants::APP_VERSION_URL, file_system};
use crate::util::{self, file_system};
use rocket::serde::json::Json;
use rocket::{Either, Route, State};
use sqlx::Connection;
Expand Down Expand Up @@ -164,6 +164,6 @@ async fn check_need_update(
site.update(&mut tx).await?;
tx.commit().await?;

let url = APP_VERSION_URL.to_owned();
let url = util::get_verion_url();
Ok(Json(AppNeedUpdateResponse { need, url }))
}
1 change: 0 additions & 1 deletion backend/src/entity/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use super::site::Site;
pub enum FileResponse {
Range(RangedFile),
Binary(NamedFile),
Text(String),
}

#[derive(Serialize)]
Expand Down
2 changes: 2 additions & 0 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ async fn main() -> Result<(), anyhow::Error> {
init::init_app().await?;
let pool = init::get_db_pool().await?;
let mut conn = pool.acquire().await?;
init::check_update(&mut conn).await?;

let site_op = Site::read(&mut conn).await?;
let state = AppState::new(site_op, pool);
RocketEnv::new().setup();
Expand Down
25 changes: 8 additions & 17 deletions backend/src/service/fairings.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::util::constants;
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::uri::Path;
use rocket::http::{Method, Status};
use rocket::{Request, Response};

Expand All @@ -19,38 +20,28 @@ impl Fairing for StaticFileCache {
return;
}

if request.method() == Method::Get && allow_cache(request) {
let req_path = request.uri().path();
if request.method() == Method::Get && req_static(&req_path) {
let content = format!("private, max-age={}", constants::CACHE_MAX_AGE);
response.set_raw_header("Cache-Control", content);
response.set_raw_header("Accept-Ranges", "bytes");
}
}
}

// Do not cache development related files in debug mode.
#[cfg(debug_assertions)]
fn allow_cache<'r>(req: &'r Request<'_>) -> bool {
let req_path = req.uri().path();

if req_path.starts_with("/api/file/") {
return true;
}

false
fn req_static<'r>(req_path: &Path) -> bool {
req_path.starts_with("/api/file/")
}

#[cfg(not(debug_assertions))]
fn allow_cache<'r>(req: &'r Request<'_>) -> bool {
let req_path = req.uri().path();

if req_path.starts_with("/api/file/") {
return true;
}

fn req_static<'r>(req_path: &Path) -> bool {
for ext in constants::CACHE_FILE_EXTS.iter() {
if req_path.ends_with(ext) {
return true;
}
}

false
req_path.starts_with("/api/file/")
}
Loading

0 comments on commit d18bf0c

Please sign in to comment.