Basic logic finished
This commit is contained in:
parent
b5558d2027
commit
2e014f141d
4
README
Normal file
4
README
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Link tool
|
||||||
|
|
||||||
|
This tools is used to quickly (re-)create hard link. which is useful
|
||||||
|
when creating link for jellyfin from qbittorrent.
|
106
link-tool.py
Normal file
106
link-tool.py
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import dataclasses
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from typing import List, Tuple, Union
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@dataclasses.dataclass(repr=True)
|
||||||
|
class Link:
|
||||||
|
src: str
|
||||||
|
dst: str
|
||||||
|
|
||||||
|
@dataclasses.dataclass(repr=True)
|
||||||
|
class Conf:
|
||||||
|
cwd: Union[str, None]
|
||||||
|
|
||||||
|
def assign(self, var_name, var_value):
|
||||||
|
if hasattr(self, var_name):
|
||||||
|
logger.debug('assign config: {} = {}'.format(var_name, var_value))
|
||||||
|
setattr(self, var_name, var_value)
|
||||||
|
else:
|
||||||
|
raise Exception('Unknown config: {}'.format(var_name))
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
missing_fields = []
|
||||||
|
if self.cwd is None:
|
||||||
|
missing_fields.append('cwd')
|
||||||
|
if len(missing_fields) > 0:
|
||||||
|
logger.error('there are missing field: {}'.format(missing_fields))
|
||||||
|
return len(missing_fields) == 0
|
||||||
|
|
||||||
|
def load_config(conf_path: str) -> Tuple[Conf, List[Link]]:
|
||||||
|
with open(conf_path, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
lines = [ line.strip() for line in lines ]
|
||||||
|
lines = [ line for line in lines if len(line) > 0 ]
|
||||||
|
lines = [ line for line in lines if not line.startswith('#') ]
|
||||||
|
|
||||||
|
links = []
|
||||||
|
conf = Conf(cwd=None)
|
||||||
|
for line in lines:
|
||||||
|
if '=' in line:
|
||||||
|
line_fields = line.split('=')
|
||||||
|
logger.debug('[config ] line fields: {}'.format(line_fields))
|
||||||
|
var_name = line_fields[0].strip()
|
||||||
|
var_value = line_fields[1].strip()
|
||||||
|
|
||||||
|
conf.assign(var_name, var_value)
|
||||||
|
|
||||||
|
elif '->' in line:
|
||||||
|
line_fields = line.split('->')
|
||||||
|
logger.debug('[link-rule] line fields: {}'.format(line_fields))
|
||||||
|
src = line_fields[0].strip()
|
||||||
|
dst = line_fields[1].strip()
|
||||||
|
|
||||||
|
links.append(Link(src, dst))
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Unknown config line: {}'.format(line))
|
||||||
|
|
||||||
|
return conf, links
|
||||||
|
|
||||||
|
def make_link(links: List[Link]):
|
||||||
|
for link in links:
|
||||||
|
if os.path.exists(link.dst):
|
||||||
|
logger.warning('dst exists, removing: {}'.format(link.dst))
|
||||||
|
os.remove(link.dst)
|
||||||
|
|
||||||
|
dst_dir = os.path.dirname(link.dst)
|
||||||
|
if not os.path.exists(dst_dir):
|
||||||
|
logger.info('dst directory not exists, creating: {}'.format(dst_dir))
|
||||||
|
os.makedirs(dst_dir)
|
||||||
|
|
||||||
|
os.link(link.src, link.dst)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-c', '--config', required=True, help='configuration file')
|
||||||
|
parser.add_argument('-v', '--verbose', action='store_true' ,help='more verbose log')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
config_path = args.config
|
||||||
|
verbose = args.verbose
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG if verbose else logging.INFO)
|
||||||
|
|
||||||
|
config, links = load_config(config_path)
|
||||||
|
|
||||||
|
if not config.validate():
|
||||||
|
logger.error('invalid configuration, exiting...')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
for link in links:
|
||||||
|
logger.info('loaded link: {}'.format(link))
|
||||||
|
|
||||||
|
make_link(links)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
0
test/src/file1.txt
Normal file
0
test/src/file1.txt
Normal file
7
test/src/link1.conf
Normal file
7
test/src/link1.conf
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# cwd is used for the pwd of src and dst defined below.
|
||||||
|
# the cwd is relative to the its config file, such as this file
|
||||||
|
cwd = '.'
|
||||||
|
|
||||||
|
# this is comment
|
||||||
|
test/src/file1.txt -> test/dst/file1.txt
|
||||||
|
|
Loading…
Reference in a new issue