Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
N
nctool
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Analyze
Contributor analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Andri Joos
nctool
Commits
45345e73
Commit
45345e73
authored
1 year ago
by
Andri Joos
Browse files
Options
Downloads
Plain Diff
Merge branch 'download'
parents
90461684
03902b68
Loading
Loading
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
.vscode/launch.json
+20
-2
20 additions, 2 deletions
.vscode/launch.json
main.py
+89
-50
89 additions, 50 deletions
main.py
requirements.txt
+1
-0
1 addition, 0 deletions
requirements.txt
setup.py
+6
-0
6 additions, 0 deletions
setup.py
with
116 additions
and
52 deletions
.vscode/launch.json
+
20
−
2
View file @
45345e73
...
...
@@ -5,7 +5,7 @@
"version"
:
"0.2.0"
,
"configurations"
:
[
{
"name"
:
"Python:
Current File
"
,
"name"
:
"Python:
upload
"
,
"type"
:
"python"
,
"request"
:
"launch"
,
"program"
:
"main.py"
,
...
...
@@ -19,7 +19,25 @@
"--username"
,
"test"
,
"--password"
,
"test123"
"test123"
,
"up"
]
},
{
"name"
:
"Python: download"
,
"type"
:
"python"
,
"request"
:
"launch"
,
"program"
:
"main.py"
,
"console"
:
"integratedTerminal"
,
"justMyCode"
:
true
,
"args"
:
[
"--in"
,
"/"
,
"--out"
,
"/home/andri/tmp/test"
,
"-l"
,
"test"
,
"down"
]
}
]
...
...
This diff is collapsed.
Click to expand it.
main.py
+
89
−
50
View file @
45345e73
...
...
@@ -6,7 +6,7 @@ import humanize
chunk_size
=
50
*
1024
*
1024
# 50MB
def
exists_remote_path
(
path
:
str
)
->
bool
:
def
exists_remote_path
(
path
:
str
,
nc
:
Client
)
->
bool
:
try
:
nc
.
list
(
path
)
except
HTTPResponseError
as
e
:
...
...
@@ -17,7 +17,7 @@ def exists_remote_path(path: str) -> bool:
return
True
def
create_path_if_not_exists
(
path
:
str
):
def
create_
remote_
path_if_not_exists
(
path
:
str
,
nc
:
Client
):
path_splits
=
path
.
split
(
os
.
sep
)
current_path
=
"
/
"
...
...
@@ -28,52 +28,91 @@ def create_path_if_not_exists(path: str):
print
(
"
creating directory {}
"
.
format
(
current_path
))
nc
.
mkdir
(
current_path
)
parser
=
ArgumentParser
(
prog
=
"
NextcloudUpload
"
,
description
=
"
Upload folders to nextcloud (specifically created for big files)
"
)
parser
.
add_argument
(
"
--in
"
,
action
=
"
store
"
,
required
=
True
,
type
=
str
)
parser
.
add_argument
(
"
--out
"
,
action
=
"
store
"
,
required
=
True
,
type
=
str
)
parser
.
add_argument
(
"
--server-address
"
,
action
=
"
store
"
,
default
=
"
https://cloud.420joos.dev/
"
,
required
=
False
,
type
=
str
)
parser
.
add_argument
(
"
--username
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
)
parser
.
add_argument
(
"
--password
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
)
parser
.
add_argument
(
"
--public-link
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
)
args
=
vars
(
parser
.
parse_args
())
in_path
=
args
[
"
in
"
]
out_path
=
args
[
"
out
"
]
server_address
=
args
[
"
server_address
"
]
username
=
args
[
"
username
"
]
password
=
args
[
"
password
"
]
public_link
=
args
[
"
public_link
"
]
nc
:
Client
=
None
if
public_link
is
not
None
:
nc
=
Client
.
from_public_link
(
public_link
)
else
:
nc
=
Client
(
server_address
)
nc
.
login
(
username
,
password
)
files_and_directories
=
glob
.
glob
(
os
.
path
.
join
(
in_path
,
"
**/*
"
),
recursive
=
True
)
uploading_files
=
[
f
for
f
in
files_and_directories
if
os
.
path
.
isfile
(
f
)]
already_uploaded
=
[]
if
exists_remote_path
(
out_path
):
already_uploaded
=
nc
.
list
(
out_path
,
depth
=
"
infinity
"
)
already_uploaded_files
=
[
a
.
path
for
a
in
already_uploaded
if
not
a
.
is_dir
()]
# already_uploaded_filenames = [a.name for a in already_uploaded]
uploading_files
.
sort
()
for
file_path
in
uploading_files
:
file_name
=
os
.
path
.
basename
(
file_path
)
relative_file_path
=
os
.
path
.
relpath
(
file_path
,
in_path
)
remote_file_path
=
os
.
path
.
join
(
out_path
,
relative_file_path
)
if
remote_file_path
not
in
already_uploaded_files
:
remote_dir_path
=
os
.
path
.
dirname
(
remote_file_path
)
create_path_if_not_exists
(
remote_dir_path
)
file_stats
=
os
.
stat
(
file_path
)
file_size
=
humanize
.
naturalsize
(
file_stats
.
st_size
)
print
(
"
uploading {} from {} to {}
"
.
format
(
file_size
,
file_path
,
remote_file_path
))
nc
.
put_file
(
remote_file_path
,
file_path
,
chunk_size
=
chunk_size
)
def
create_client
(
server_address
:
str
=
None
,
username
:
str
=
None
,
password
:
str
=
None
,
public_link
:
str
=
None
)
->
Client
:
if
public_link
is
not
None
:
nc
=
Client
.
from_public_link
(
public_link
)
else
:
print
(
"
{} exists already at {}
"
.
format
(
file_path
,
remote_file_path
))
nc
=
Client
(
server_address
)
nc
.
login
(
username
,
password
)
return
nc
def
upload
(
_in
:
str
,
out
:
str
,
server_address
:
str
=
None
,
username
:
str
=
None
,
password
:
str
=
None
,
public_link
:
str
=
None
,
func
=
None
):
nc
=
create_client
(
server_address
,
username
,
password
,
public_link
)
files_and_directories
=
glob
.
glob
(
os
.
path
.
join
(
_in
,
"
**/*
"
),
recursive
=
True
)
uploading_files
=
[
f
for
f
in
files_and_directories
if
os
.
path
.
isfile
(
f
)]
already_uploaded
=
[]
if
exists_remote_path
(
out
):
already_uploaded
=
nc
.
list
(
out
,
depth
=
"
infinity
"
)
already_uploaded_files
=
[
a
.
path
for
a
in
already_uploaded
if
not
a
.
is_dir
()]
# already_uploaded_filenames = [a.name for a in already_uploaded]
uploading_files
.
sort
()
for
file_path
in
uploading_files
:
relative_file_path
=
os
.
path
.
relpath
(
file_path
,
_in
)
remote_file_path
=
os
.
path
.
join
(
out
,
relative_file_path
)
if
remote_file_path
not
in
already_uploaded_files
:
remote_dir_path
=
os
.
path
.
dirname
(
remote_file_path
)
create_remote_path_if_not_exists
(
remote_dir_path
)
file_stats
=
os
.
stat
(
file_path
)
file_size
=
humanize
.
naturalsize
(
file_stats
.
st_size
)
print
(
"
uploading {} from {} to {}
"
.
format
(
file_size
,
file_path
,
remote_file_path
))
nc
.
put_file
(
remote_file_path
,
file_path
,
chunk_size
=
chunk_size
)
else
:
print
(
"
{} exists already at {}
"
.
format
(
file_path
,
remote_file_path
))
def
download
(
_in
:
str
,
out
:
str
,
server_address
:
str
=
None
,
username
:
str
=
None
,
password
:
str
=
None
,
public_link
:
str
=
None
,
depth
:
str
=
None
,
func
=
None
):
nc
=
create_client
(
server_address
,
username
,
password
,
public_link
)
parsed_depth
:
int
|
str
=
None
try
:
parsed_depth
=
int
(
depth
)
except
ValueError
:
parsed_depth
=
depth
remote_listing
=
nc
.
list
(
_in
,
depth
=
parsed_depth
)
remote_files
=
[(
a
.
path
,
a
.
attributes
[
"
{DAV:}getcontentlength
"
])
for
a
in
remote_listing
if
not
a
.
is_dir
()]
already_downloaded_files
=
glob
.
glob
(
os
.
path
.
join
(
out
,
"
**/*
"
),
recursive
=
True
)
for
file_path
,
file_size
in
remote_files
:
relative_path
=
os
.
path
.
relpath
(
file_path
,
_in
)
local_path
=
os
.
path
.
join
(
out
,
relative_path
)
if
local_path
not
in
already_downloaded_files
:
local_dir
=
os
.
path
.
dirname
(
local_path
)
os
.
makedirs
(
local_dir
,
exist_ok
=
True
)
file_size_humanized
=
humanize
.
naturalsize
(
file_size
)
print
(
"
downloading {} from {} to {}
"
.
format
(
file_size_humanized
,
file_path
,
local_path
))
nc
.
get_file
(
file_path
,
local_path
)
else
:
print
(
"
{} exists already at {}
"
.
format
(
file_path
,
local_path
))
def
main
():
parser
=
ArgumentParser
(
prog
=
"
NextcloudTool
"
,
description
=
"
Upload/Download folders to nextcloud (specifically created for big files)
"
)
parser
.
add_argument
(
"
--in
"
,
"
-i
"
,
action
=
"
store
"
,
required
=
True
,
type
=
str
,
dest
=
"
_in
"
)
parser
.
add_argument
(
"
--out
"
,
"
-o
"
,
action
=
"
store
"
,
required
=
True
,
type
=
str
)
parser
.
add_argument
(
"
--server-address
"
,
"
-s
"
,
action
=
"
store
"
,
default
=
"
https://cloud.420joos.dev/
"
,
required
=
False
,
type
=
str
)
parser
.
add_argument
(
"
--username
"
,
"
-u
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
)
parser
.
add_argument
(
"
--password
"
,
"
-p
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
)
parser
.
add_argument
(
"
--public-link
"
,
"
-l
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
)
subparsers
=
parser
.
add_subparsers
(
title
=
"
action
"
)
up_parser
=
subparsers
.
add_parser
(
"
up
"
,
aliases
=
[
"
u
"
])
up_parser
.
set_defaults
(
func
=
upload
)
down_parser
=
subparsers
.
add_parser
(
"
down
"
,
aliases
=
[
"
d
"
])
down_parser
.
add_argument
(
"
--depth
"
,
"
-d
"
,
action
=
"
store
"
,
required
=
False
,
type
=
str
,
default
=
"
infinity
"
)
down_parser
.
set_defaults
(
func
=
download
)
parsed_args
=
parser
.
parse_args
()
args
=
vars
(
parsed_args
)
parsed_args
.
func
(
**
args
)
if
__name__
==
"
__main__
"
:
main
()
This diff is collapsed.
Click to expand it.
requirements.txt
+
1
−
0
View file @
45345e73
pyncclient
humanize
./
\ No newline at end of file
This diff is collapsed.
Click to expand it.
setup.py
0 → 100644
+
6
−
0
View file @
45345e73
from
setuptools
import
setup
,
find_packages
setup
(
name
=
'
nctool
'
,
version
=
'
1.0
'
,
packages
=
find_packages
(),
entry_points
=
{
"
console_scripts
"
:
[
"
nctool = main:main
"
]
})
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment