Skip to content

Commit

Permalink
feat(services): add seafile support (#3771)
Browse files Browse the repository at this point in the history
  • Loading branch information
hoslo authored Dec 18, 2023
1 parent 1783caf commit e518d5b
Show file tree
Hide file tree
Showing 20 changed files with 1,312 additions and 14 deletions.
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,9 @@ OPENDAL_HUGGINGFACE_REPO_TYPE=dataset
OPENDAL_HUGGINGFACE_REPO_ID=opendal/huggingface-testdata
OPENDAL_HUGGINGFACE_REVISION=main
OPENDAL_HUGGINGFACE_ROOT=/testdata/
# seafile
OPENDAL_SEAFILE_ROOT=/path/to/dir
OPENDAL_SEAFILE_ENDPOINT=<endpoint>
OPENDAL_SEAFILE_USERNAME=<usernmae>
OPENDAL_SEAFILE_PASSWORD=<password>
OPENDAL_SEAFILE_REPO_NAME=<repo_name>
45 changes: 45 additions & 0 deletions .github/services/seafile/seafile/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: seafile
description: "Behavior test for Seafile"

runs:
using: "composite"
steps:
- name: Setup Seafile service
shell: bash
working-directory: fixtures/seafile
run: |
docker compose -f docker-compose-seafile.yml up -d --wait
- name: Create test token and setup test library
shell: bash
run: |
token=$(curl --location --request POST -d "[email protected]&password=asecret" http://127.0.0.1:80/api2/auth-token/ | awk -F '"' '/token/{print $4}')
curl --location --request POST -d 'name=test' -H "Authorization: Token $token" http://127.0.0.1:80/api2/repos/
- name: Set environment variables
shell: bash
run: |
cat << EOF >> $GITHUB_ENV
OPENDAL_SEAFILE_ENDPOINT=http://127.0.0.1:80
[email protected]
OPENDAL_SEAFILE_PASSWORD=asecret
OPENDAL_SEAFILE_REPO_NAME=test
OPENDAL_SEAFILE_ROOT=/
EOF
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ jobs:
# TODO: we need to find ways to using pre-install rocksdb library
# services-rocksdb
services-s3
services-seafile
# TODO: sftp is known to not work on windows, waiting for https://github.com/apache/incubator-opendal/issues/2963
# services-sftp
services-sled
Expand Down
2 changes: 2 additions & 0 deletions bindings/java/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ services-all = [
"services-swift",
"services-alluxio",
"services-b2",
"services-seafile",
]

# Default services provided by opendal.
Expand Down Expand Up @@ -137,6 +138,7 @@ services-redis = ["opendal/services-redis"]
services-rocksdb = ["opendal/services-rocksdb"]
services-sftp = ["opendal/services-sftp"]
services-sled = ["opendal/services-sled"]
services-seafile = ["opendal/services-seafile"]
services-sqlite = ["opendal/services-sqlite"]
services-supabase = ["opendal/services-supabase"]
services-swift = ["opendal/services-swift"]
Expand Down
2 changes: 2 additions & 0 deletions bindings/nodejs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ services-all = [
"services-libsql",
"services-alluxio",
"services-b2",
"services-seafile",
]

# Default services provided by opendal.
Expand Down Expand Up @@ -133,6 +134,7 @@ services-rocksdb = ["opendal/services-rocksdb"]
services-sftp = ["opendal/services-sftp"]
services-sled = ["opendal/services-sled"]
services-sqlite = ["opendal/services-sqlite"]
services-seafile = ["opendal/services-seafile"]
services-supabase = ["opendal/services-supabase"]
services-swift = ["opendal/services-swift"]
services-tikv = ["opendal/services-tikv"]
Expand Down
2 changes: 2 additions & 0 deletions bindings/python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ services-all = [
"services-libsql",
"services-alluxio",
"services-b2",
"services-seafile",
]

# Default services provided by opendal.
Expand Down Expand Up @@ -132,6 +133,7 @@ services-rocksdb = ["opendal/services-rocksdb"]
services-sftp = ["opendal/services-sftp"]
services-sled = ["opendal/services-sled"]
services-sqlite = ["opendal/services-sqlite"]
services-seafile = ["opendal/services-seafile"]
services-supabase = ["opendal/services-supabase"]
services-swift = ["opendal/services-swift"]
services-tikv = ["opendal/services-tikv"]
Expand Down
1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ services-azdls = [
]
services-azfile = []
services-b2 = []
services-seafile = []
services-cacache = ["dep:cacache"]
services-cloudflare-kv = []
services-cos = [
Expand Down
9 changes: 9 additions & 0 deletions core/src/raw/chrono_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,12 @@ pub fn parse_datetime_from_from_timestamp_millis(s: i64) -> Result<DateTime<Utc>

Ok(st.into())
}

/// parse datetime from given timestamp
pub fn parse_datetime_from_from_timestamp(s: i64) -> Result<DateTime<Utc>> {
let st = UNIX_EPOCH
.checked_add(Duration::from_secs(s as u64))
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "input timestamp overflow"))?;

Ok(st.into())
}
40 changes: 26 additions & 14 deletions core/src/raw/http_util/multipart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,19 @@ impl Part for FormDataPart {

// Building pre-content.
for (k, v) in self.headers.iter() {
bs.extend_from_slice(k.as_str().as_bytes());
// Trick!
//
// Seafile could not recognize header names like `content-disposition`
// and requires to use `Content-Disposition`. So we hardcode the part
// headers name here.
match k.as_str() {
"content-disposition" => {
bs.extend_from_slice("Content-Disposition".as_bytes());
}
_ => {
bs.extend_from_slice(k.as_str().as_bytes());
}
}
bs.extend_from_slice(b": ");
bs.extend_from_slice(v.as_bytes());
bs.extend_from_slice(b"\r\n");
Expand Down Expand Up @@ -728,11 +740,11 @@ mod tests {
assert_eq!(size, bs.len() as u64);

let expected = "--lalala\r\n\
content-disposition: form-data; name=\"foo\"\r\n\
Content-Disposition: form-data; name=\"foo\"\r\n\
\r\n\
bar\r\n\
--lalala\r\n\
content-disposition: form-data; name=\"hello\"\r\n\
Content-Disposition: form-data; name=\"hello\"\r\n\
\r\n\
world\r\n\
--lalala--\r\n";
Expand Down Expand Up @@ -764,48 +776,48 @@ mod tests {
assert_eq!(size, bs.len() as u64);

let expected = r#"--9431149156168
content-disposition: form-data; name="key"
Content-Disposition: form-data; name="key"
user/eric/MyPicture.jpg
--9431149156168
content-disposition: form-data; name="acl"
Content-Disposition: form-data; name="acl"
public-read
--9431149156168
content-disposition: form-data; name="success_action_redirect"
Content-Disposition: form-data; name="success_action_redirect"
https://awsexamplebucket1.s3.us-west-1.amazonaws.com/successful_upload.html
--9431149156168
content-disposition: form-data; name="content-type"
Content-Disposition: form-data; name="content-type"
image/jpeg
--9431149156168
content-disposition: form-data; name="x-amz-meta-uuid"
Content-Disposition: form-data; name="x-amz-meta-uuid"
14365123651274
--9431149156168
content-disposition: form-data; name="x-amz-meta-tag"
Content-Disposition: form-data; name="x-amz-meta-tag"
Some,Tag,For,Picture
--9431149156168
content-disposition: form-data; name="AWSAccessKeyId"
Content-Disposition: form-data; name="AWSAccessKeyId"
AKIAIOSFODNN7EXAMPLE
--9431149156168
content-disposition: form-data; name="Policy"
Content-Disposition: form-data; name="Policy"
eyAiZXhwaXJhdGlvbiI6ICIyMDA3LTEyLTAxVDEyOjAwOjAwLjAwMFoiLAogICJjb25kaXRpb25zIjogWwogICAgeyJidWNrZXQiOiAiam9obnNtaXRoIn0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci9lcmljLyJdLAogICAgeyJhY2wiOiAicHVibGljLXJlYWQifSwKICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL2pvaG5zbWl0aC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwKICAgIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS8iXSwKICAgIHsieC1hbXotbWV0YS11dWlkIjogIjE0MzY1MTIzNjUxMjc0In0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiR4LWFtei1tZXRhLXRhZyIsICIiXQogIF0KfQo=
--9431149156168
content-disposition: form-data; name="Signature"
Content-Disposition: form-data; name="Signature"
0RavWzkygo6QX9caELEqKi9kDbU=
--9431149156168
content-disposition: form-data; name="file"
Content-Disposition: form-data; name="file"
content-type: image/jpeg
...file content...
--9431149156168
content-disposition: form-data; name="submit"
Content-Disposition: form-data; name="submit"
Upload to Amazon S3
--9431149156168--
Expand Down
7 changes: 7 additions & 0 deletions core/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,10 @@ mod b2;
pub use b2::B2Config;
#[cfg(feature = "services-b2")]
pub use b2::B2;

#[cfg(feature = "services-seafile")]
mod seafile;
#[cfg(feature = "services-seafile")]
pub use seafile::Seafile;
#[cfg(feature = "services-seafile")]
pub use seafile::SeafileConfig;
Loading

0 comments on commit e518d5b

Please sign in to comment.