Fix Windows compatibility + bugs
This commit is contained in:
parent
7d04cfcce9
commit
cf9cf79da2
12
README.md
12
README.md
|
@ -9,7 +9,7 @@ pip install fsub
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
```
|
```
|
||||||
usage: fsub [-h] [-c] [-s MS] [-n] [-f FILE] file [file ...]
|
usage: fsub.py [-h] [-c] [-s MS] [-n] [-f FILE] file [file ...]
|
||||||
|
|
||||||
Fix, edit and clean SubRip (.srt) files.
|
Fix, edit and clean SubRip (.srt) files.
|
||||||
|
|
||||||
|
@ -18,20 +18,20 @@ positional arguments:
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
-c, --clean remove subtitles matching regular expressions listed in
|
-c, --clean remove subtitles matching regular expressions listed in the config
|
||||||
~/.config/fsubrc (this is the default behavior if no other flag is
|
file (this is the default behavior if no other flag is passed)
|
||||||
passed)
|
|
||||||
-s MS, --shift MS shift all subtitles by MS milliseconds, which may be positive or
|
-s MS, --shift MS shift all subtitles by MS milliseconds, which may be positive or
|
||||||
negative
|
negative
|
||||||
-n, --no-html strip HTML tags from subtitles content
|
-n, --no-html strip HTML tags from subtitles content
|
||||||
-f FILE, --config-file FILE
|
-f FILE, --config-file FILE
|
||||||
overwrite the default config file (~/.config/fsubrc)
|
overwrite the default config file (Unix: $HOME/.config/fsubrc,
|
||||||
|
Windows: %APPDATA%\fsubrc)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
- Fixes subtitle numbering
|
- Fixes subtitle numbering
|
||||||
- Converts files to UTF-8 encoding
|
- Converts files to UTF-8 encoding
|
||||||
- Validates file structure
|
- Validates file structure
|
||||||
- May remove subtitles containing lines that match any regular expression listed in the config file (by default `~/.config/fsubrc`)
|
- May remove subtitles containing lines that match any regular expression listed in the config file (by default on Unix: `$HOME/.config/fsubrc`; on Windows: `%APPDATA%\fsubrc`)
|
||||||
- May shift the time of all subtitles
|
- May shift the time of all subtitles
|
||||||
- May strip HTML
|
- May strip HTML
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = fsub
|
name = fsub
|
||||||
version = 0.0.5
|
version = 0.1.0
|
||||||
author = Augusto Lenz Gunsch
|
author = Augusto Lenz Gunsch
|
||||||
author_email = augustogunsch@tutanota.com
|
author_email = augustogunsch@tutanota.com
|
||||||
description = CLI SubRip editor
|
description = CLI SubRip editor
|
||||||
|
|
|
@ -26,6 +26,7 @@ import argparse
|
||||||
import re
|
import re
|
||||||
import chardet
|
import chardet
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
|
||||||
class Time:
|
class Time:
|
||||||
|
@ -91,24 +92,17 @@ class Subtitle:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '{}{}{} --> {}{}{}'.format(
|
return '{}\n{} --> {}\n{}'.format(
|
||||||
self.number, os.linesep,
|
self.number,
|
||||||
self.time_start, self.time_end,
|
self.time_start, self.time_end,
|
||||||
os.linesep, os.linesep.join(self.content)
|
'\n'.join(self.content)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def clean(subs, cfg):
|
def clean(subs, expressions):
|
||||||
# Read expressions in ~/.config/fsubrc
|
|
||||||
if not cfg:
|
|
||||||
cfg = open(os.getenv('HOME') + '/.config/fsubrc', 'r')
|
|
||||||
lines = re.split(r'\r?\n', cfg.read().strip())
|
|
||||||
expressions = list(map(re.compile, lines))
|
|
||||||
cfg.close()
|
|
||||||
|
|
||||||
# Cancel if no expression
|
# Cancel if no expression
|
||||||
if len(expressions) == 0:
|
if len(expressions) == 0:
|
||||||
return
|
return subs
|
||||||
|
|
||||||
# Remove lines matching any expression
|
# Remove lines matching any expression
|
||||||
for regexp in expressions:
|
for regexp in expressions:
|
||||||
|
@ -126,10 +120,10 @@ def shift(subs, ms):
|
||||||
def strip_html(subs):
|
def strip_html(subs):
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
for i in range(0, len(sub.content)):
|
for i in range(0, len(sub.content)):
|
||||||
sub.content[i] = re.sub('<.+>', '', sub.content[i])
|
sub.content[i] = re.sub('<.+?>', '', sub.content[i])
|
||||||
|
|
||||||
|
|
||||||
def process_file(args, file):
|
def process_file(args, file, expressions):
|
||||||
# Read the input file
|
# Read the input file
|
||||||
contents = file.read()
|
contents = file.read()
|
||||||
file.close()
|
file.close()
|
||||||
|
@ -163,7 +157,7 @@ def process_file(args, file):
|
||||||
|
|
||||||
# Clean if --clean is passed
|
# Clean if --clean is passed
|
||||||
if args.clean:
|
if args.clean:
|
||||||
subs_objs = clean(subs_objs, args.config_file)
|
subs_objs = clean(subs_objs, expressions)
|
||||||
|
|
||||||
# Shift if --shift is passed
|
# Shift if --shift is passed
|
||||||
if args.shift:
|
if args.shift:
|
||||||
|
@ -180,15 +174,41 @@ def process_file(args, file):
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Join Subtitle objects back to a string
|
# Join Subtitle objects back to a string
|
||||||
contents = (os.linesep + os.linesep).join(map(repr, subs_objs))
|
contents = '\n\n'.join(map(repr, subs_objs))
|
||||||
|
|
||||||
# Write output
|
# Write output
|
||||||
output = open(file.name, 'w', encoding='utf-8')
|
output = open(file.name, 'w', encoding='utf-8')
|
||||||
output.write(contents)
|
output.write(contents)
|
||||||
output.write(os.linesep)
|
output.write('\n')
|
||||||
output.close()
|
output.close()
|
||||||
|
|
||||||
|
|
||||||
|
def read_expressions(args):
|
||||||
|
if args.clean:
|
||||||
|
cfg = args.config_file
|
||||||
|
|
||||||
|
# Open default config file if not specified
|
||||||
|
if not args.config_file:
|
||||||
|
home = pathlib.Path.home()
|
||||||
|
try:
|
||||||
|
if type(home) is pathlib.PosixPath:
|
||||||
|
cfg = open(str(home) + '/.config/fsubrc', 'r')
|
||||||
|
elif type(home) is pathlib.WindowsPath:
|
||||||
|
cfg = open(os.getenv('APPDATA') + r'\fsubrc', 'r')
|
||||||
|
else:
|
||||||
|
print('Unsupported operating system', file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
except FileNotFoundError:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Read expressions
|
||||||
|
lines = re.split(r'\r?\n', cfg.read().strip())
|
||||||
|
expressions = list(map(re.compile, lines))
|
||||||
|
cfg.close()
|
||||||
|
return expressions
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Fix, edit and clean SubRip (.srt) files.',
|
description='Fix, edit and clean SubRip (.srt) files.',
|
||||||
|
@ -198,7 +218,7 @@ def main():
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-c', '--clean',
|
'-c', '--clean',
|
||||||
help='remove subtitles matching regular expressions ' +
|
help='remove subtitles matching regular expressions ' +
|
||||||
'listed in ~/.config/fsubrc (this is the default ' +
|
'listed in the config file (this is the default ' +
|
||||||
'behavior if no other flag is passed)',
|
'behavior if no other flag is passed)',
|
||||||
action='store_true'
|
action='store_true'
|
||||||
)
|
)
|
||||||
|
@ -220,7 +240,8 @@ def main():
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-f', '--config-file',
|
'-f', '--config-file',
|
||||||
help='overwrite the default config file (~/.config/fsubrc)',
|
help='overwrite the default config file (Unix: $HOME/.config/fsubrc,' +
|
||||||
|
r' Windows: %%APPDATA%%\fsubrc)',
|
||||||
metavar='FILE',
|
metavar='FILE',
|
||||||
action='store',
|
action='store',
|
||||||
type=argparse.FileType('r')
|
type=argparse.FileType('r')
|
||||||
|
@ -252,8 +273,10 @@ def main():
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
expressions = read_expressions(args)
|
||||||
|
|
||||||
for file in args.files:
|
for file in args.files:
|
||||||
process_file(args, file)
|
process_file(args, file, expressions)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue