Bloodsucker

This commit is contained in:
Geoffrey Frogeye 2020-08-08 11:19:48 +02:00
parent 6cdd924613
commit f03d13f7db
8 changed files with 140 additions and 811 deletions

View file

@ -7,11 +7,17 @@ echo RELOADAGENT | gpg-connect-agent
dm-tool lock
if [ $? -ne 0 ]; then
if [ -d ~/.cache/lockpatterns ]
then
pattern=$(find ~/.cache/lockpatterns/ | sort -R | head -1)
else
pattern=$HOME/.config/i3/lock.png
fi
revert() {
xset dpms 0 0 0
}
trap revert SIGHUP SIGINT SIGTERM
xset dpms 5 5 5
i3lock --nofork --color 648901 --image=$HOME/.config/i3/lock.png --tiling --ignore-empty-password
i3lock --nofork --color 648901 --image=$pattern --tiling --ignore-empty-password
revert
fi

View file

@ -277,6 +277,12 @@ class NetworkProviderSection(StatefulSection, Updater):
self.ssid = p.stdout.strip().decode()
elif self.iface.startswith('tun') or self.iface.startswith('tap'):
self.icon = ''
elif self.iface.startswith('docker'):
self.icon = ''
elif self.iface.startswith('veth'):
self.icon = ''
elif self.iface.startswith('vboxnet'):
self.icon = ''
else:
self.icon = '?'

View file

@ -1,34 +1,8 @@
# Autogenerated config.py
# Documentation:
# qute://help/configuring.html
# qute://help/settings.html
import os
# TODO Autoconfig + theme might be all the things we need
# Value to send in the `Accept-Language` header. Note that the value
# read from JavaScript is always the global value.
# Type: String
c.content.headers.accept_language = 'fr,fr-FR,en-US,en'
# Enable JavaScript.
# Type: Bool
config.set('content.javascript.enabled', True, 'file://*')
# Enable JavaScript.
# Type: Bool
config.set('content.javascript.enabled', True, 'chrome://*/*')
# Enable JavaScript.
# Type: Bool
config.set('content.javascript.enabled', True, 'qute://*/*')
# Proxy to use. In addition to the listed values, you can use a
# `socks://...` or `http://...` URL.
# Type: Proxy
# Valid values:
# - system: Use the system wide proxy.
# - none: Don't use any proxy
c.content.proxy = 'system'
# Public static configuration for qutebrowser
# Note that private stuff (permissions, per-site rules)
# are in autoconfig in gdotfiles
# Prompt the user for the download location. If set to false,
# `downloads.location.directory` will be used.
@ -42,17 +16,12 @@ c.downloads.location.prompt = False
# - never: Always hide the tab bar.
# - multiple: Hide the tab bar if only one tab is open.
# - switching: Show the tab bar when switching tabs.
c.tabs.show = 'never'
c.tabs.show = "never"
# Open a new window for every tab.
# Type: Bool
c.tabs.tabs_are_windows = True
# Page to open if :open -t/-b/-w is used without URL. Use `about:blank`
# for a blank page.
# Type: FuzzyUrl
c.url.default_page = 'https://geoffrey.frogeye.fr/blank.html'
# Open base URL of the searchengine if a searchengine shortcut is
# invoked without parameters.
# Type: Bool
@ -67,24 +36,41 @@ c.url.open_base_url = True
# used by prepending the search engine name to the search term, e.g.
# `:open google qutebrowser`.
# Type: Dict
c.url.searchengines = {'DEFAULT': 'https://www.qwant.com/?t=web&q={}', 'arch': 'https://wiki.archlinux.org/?search={}', 'archp': 'https://www.archlinux.org/packages/?q={}', 'aur': 'https://aur.archlinux.org/packages/?K={}', 'aw': 'http://www.amp-what.com/unicode/search/{}', 'dockerhub': 'https://hub.docker.com/search/?isAutomated=0&isOfficial=0&page=1&pullCount=0&q={}&starCount=0', 'g': 'https://www.google.fr/search?q={}', 'gfr': 'https://www.google.fr/search?hl=fr&q={}', 'gi': 'http://images.google.com/search?q={}', 'gif': 'https://giphy.com/search/{}', 'github': 'https://github.com/search?q={}', 'npm': 'https://www.npmjs.com/search?q={}', 'wa': 'https://www.wolframalpha.com/input/?i={}', 'yt': 'https://www.youtube.com/results?search_query={}'}
c.url.searchengines = {
"DEFAULT": "https://duckduckgo.com/?q={}&ia=web",
"aw": "http://www.amp-what.com/unicode/search/{}",
"ddg": "https://duckduckgo.com/?q={}&ia=web",
"duckduckgo": "https://duckduckgo.com/?q={}&ia=web",
"github": "https://github.com/search?q={}",
"google": "https://www.google.fr/search?q={}",
"npm": "https://www.npmjs.com/search?q={}",
"q": "https://www.qwant.com/?t=web&q={}",
"qwant": "https://www.qwant.com/?t=web&q={}",
"wolfram": "https://www.wolframalpha.com/input/?i={}",
"youtube": "https://www.youtube.com/results?search_query={}",
}
# Only allow first party cookies
config.set("content.cookies.accept", "no-3rdparty", "chrome://*/*")
# Page(s) to open at the start.
# Type: List of FuzzyUrl, or FuzzyUrl
c.url.start_pages = 'https://geoffrey.frogeye.fr/blank.html'
c.url.start_pages = "https://geoffrey.frogeye.fr/blank.html"
# Bindings for normal mode
config.bind('H', 'tab-prev')
config.bind('J', 'back')
config.bind('K', 'forward')
config.bind('L', 'tab-next')
config.unbind('T')
config.bind("H", "tab-prev")
config.bind("J", "back")
config.bind("K", "forward")
config.bind("L", "tab-next")
config.unbind("T")
config.bind("af", "spawn --userscript freshrss")
config.bind("as", "spawn --userscript shaarli")
import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'theme.py')
with open(filename) as file:
exec(file.read())
filename = os.path.join(dirname, "theme.py")
if os.path.exists(filename):
with open(filename) as file:
exec(file.read())
# Uncomment this to still load settings configured via autoconfig.yml
config.load_autoconfig()

View file

@ -1,701 +0,0 @@
# vim: ft=conf
#
# In this config file, qutebrowser's key bindings are configured.
# The format looks like this:
#
# [keymode]
#
# command
# keychain
# keychain2
# ...
#
# All blank lines and lines starting with '#' are ignored.
# Inline-comments are not permitted.
#
# keymode is a comma separated list of modes in which the key binding should be
# active. If keymode starts with !, the key binding is active in all modes
# except the listed modes.
#
# For special keys (can't be part of a keychain), enclose them in `<`...`>`.
# For modifiers, you can use either `-` or `+` as delimiters, and these names:
#
# * Control: `Control`, `Ctrl`
# * Meta: `Meta`, `Windows`, `Mod4`
# * Alt: `Alt`, `Mod1`
# * Shift: `Shift`
#
# For simple keys (no `<>`-signs), a capital letter means the key is pressed
# with Shift. For special keys (with `<>`-signs), you need to explicitly add
# `Shift-` to match a key pressed with shift.
#
# Note that default keybindings are always bound, and need to be explicitly
# unbound if you wish to remove them:
#
# <unbound>
# keychain
# keychain2
# ...
[!normal]
leave-mode
<escape>
<ctrl-[>
[normal]
# Keybindings for normal mode.
clear-keychain ;; search ;; fullscreen --leave
<escape>
set-cmd-text -s :open
o
set-cmd-text :open {url:pretty}
go
set-cmd-text -s :open -t
O
set-cmd-text :open -t -i {url:pretty}
gO
set-cmd-text -s :open -b
xo
set-cmd-text :open -b -i {url:pretty}
xO
set-cmd-text -s :open -w
wo
set-cmd-text :open -w {url:pretty}
wO
set-cmd-text /
/
set-cmd-text ?
?
set-cmd-text :
:
open -t
ga
<ctrl-t>
open -w
<ctrl-n>
tab-close
d
<ctrl-w>
tab-close -o
D
tab-only
co
tab-focus
T
tab-move
gm
tab-move -
gl
tab-move +
gr
tab-next
L
<ctrl-pgdown>
tab-prev
H
<ctrl-pgup>
tab-clone
gC
reload
r
<f5>
reload -f
R
<ctrl-f5>
back
J
<back>
back -t
tj
back -w
wj
forward
K
<forward>
forward -t
tk
forward -w
wk
fullscreen
<f11>
hint
f
hint all tab
F
hint all window
wf
hint all tab-bg
;b
hint all tab-fg
;f
hint all hover
;h
hint images
;i
hint images tab
;I
hint links fill :open {hint-url}
;o
hint links fill :open -t -i {hint-url}
;O
hint links yank
;y
hint links yank-primary
;Y
hint --rapid links tab-bg
;r
hint --rapid links window
;R
hint links download
;d
hint inputs
;t
scroll left
h
scroll down
j
scroll up
k
scroll right
l
undo
u
<ctrl-shift-t>
scroll-perc 0
gg
scroll-perc
G
search-next
n
search-prev
N
enter-mode insert
i
enter-mode caret
v
enter-mode set_mark
`
enter-mode jump_mark
'
yank
yy
yank -s
yY
yank title
yt
yank title -s
yT
yank domain
yd
yank domain -s
yD
yank pretty-url
yp
yank pretty-url -s
yP
open -- {clipboard}
pp
open -- {primary}
pP
open -t -- {clipboard}
Pp
open -t -- {primary}
PP
open -w -- {clipboard}
wp
open -w -- {primary}
wP
quickmark-save
m
set-cmd-text -s :quickmark-load
b
set-cmd-text -s :quickmark-load -t
B
set-cmd-text -s :quickmark-load -w
wb
bookmark-add
M
set-cmd-text -s :bookmark-load
gb
set-cmd-text -s :bookmark-load -t
gB
set-cmd-text -s :bookmark-load -w
wB
save
sf
set-cmd-text -s :set
ss
set-cmd-text -s :set -t
sl
set-cmd-text -s :bind
sk
zoom-out
-
zoom-in
+
zoom
=
navigate prev
[[
navigate next
]]
navigate prev -t
{{
navigate next -t
}}
navigate up
gu
navigate up -t
gU
navigate increment
<ctrl-a>
navigate decrement
<ctrl-x>
inspector
wi
download
gd
download-cancel
ad
download-clear
cd
view-source
gf
set-cmd-text -s :buffer
gt
tab-focus last
<ctrl-tab>
enter-mode passthrough
<ctrl-v>
quit
<ctrl-q>
scroll-page 0 1
<ctrl-f>
scroll-page 0 -1
<ctrl-b>
scroll-page 0 0.5
<ctrl-d>
scroll-page 0 -0.5
<ctrl-u>
tab-focus 1
<alt-1>
tab-focus 2
<alt-2>
tab-focus 3
<alt-3>
tab-focus 4
<alt-4>
tab-focus 5
<alt-5>
tab-focus 6
<alt-6>
tab-focus 7
<alt-7>
tab-focus 8
<alt-8>
tab-focus 9
<alt-9>
home
<ctrl-h>
stop
<ctrl-s>
print
<ctrl-alt-p>
open qute:settings
Ss
follow-selected
<return>
<ctrl-m>
<ctrl-j>
<shift-return>
<enter>
<shift-enter>
follow-selected -t
<ctrl-return>
<ctrl-enter>
repeat-command
.
record-macro
q
run-macro
@
wq
ZZ
tab-focus -1
g$
tab-pin
<ctrl-p>
[insert]
# Keybindings for insert mode.
# Since normal keypresses are passed through, only special keys are
# supported in this mode.
# Useful hidden commands to map in this section:
# * `open-editor`: Open a texteditor with the focused field.
# * `paste-primary`: Paste primary selection at cursor position.
open-editor
<ctrl-e>
insert-text {primary}
<shift-ins>
[hint]
# Keybindings for hint mode.
# Since normal keypresses are passed through, only special keys are
# supported in this mode.
# Useful hidden commands to map in this section:
# * `follow-hint`: Follow the currently selected hint.
follow-hint
<return>
<ctrl-m>
<ctrl-j>
<shift-return>
<enter>
<shift-enter>
hint --rapid links tab-bg
<ctrl-r>
hint links
<ctrl-f>
hint all tab-bg
<ctrl-b>
[command]
# Keybindings for command mode.
# Since normal keypresses are passed through, only special keys are
# supported in this mode.
# Useful hidden commands to map in this section:
# * `command-history-prev`: Switch to previous command in history.
# * `command-history-next`: Switch to next command in history.
# * `completion-item-focus`: Select another item in completion.
# * `command-accept`: Execute the command currently in the commandline.
command-history-prev
<ctrl-p>
command-history-next
<ctrl-n>
completion-item-focus prev
<shift-tab>
<up>
completion-item-focus next
<tab>
<down>
completion-item-focus next-category
<ctrl-tab>
completion-item-focus prev-category
<ctrl-shift-tab>
completion-item-del
<ctrl-d>
command-accept
<return>
<ctrl-m>
<ctrl-j>
<shift-return>
<enter>
<shift-enter>
[prompt]
# Keybindings for prompts in the status line.
# You can bind normal keys in this mode, but they will be only active
# when a yes/no-prompt is asked. For other prompt modes, you can only
# bind special keys.
# Useful hidden commands to map in this section:
# * `prompt-accept`: Confirm the entered value.
# * `prompt-accept yes`: Answer yes to a yes/no question.
# * `prompt-accept no`: Answer no to a yes/no question.
prompt-accept
<return>
<ctrl-m>
<ctrl-j>
<shift-return>
<enter>
<shift-enter>
prompt-accept yes
y
prompt-accept no
n
prompt-open-download
<ctrl-x>
prompt-item-focus prev
<shift-tab>
<up>
prompt-item-focus next
<tab>
<down>
[command,prompt]
rl-backward-char
<ctrl-b>
rl-forward-char
<ctrl-f>
rl-backward-word
<alt-b>
rl-forward-word
<alt-f>
rl-beginning-of-line
<ctrl-a>
rl-end-of-line
<ctrl-e>
rl-unix-line-discard
<ctrl-u>
rl-kill-line
<ctrl-k>
rl-kill-word
<alt-d>
rl-unix-word-rubout
<ctrl-w>
rl-backward-kill-word
<alt-backspace>
rl-yank
<ctrl-y>
rl-delete-char
<ctrl-?>
rl-backward-delete-char
<ctrl-h>
[caret]
toggle-selection
v
<space>
drop-selection
<ctrl-space>
enter-mode normal
c
move-to-next-line
j
move-to-prev-line
k
move-to-next-char
l
move-to-prev-char
h
move-to-end-of-word
e
move-to-next-word
w
move-to-prev-word
b
move-to-start-of-next-block
]
move-to-start-of-prev-block
[
move-to-end-of-next-block
}
move-to-end-of-prev-block
{
move-to-start-of-line
0
move-to-end-of-line
$
move-to-start-of-document
gg
move-to-end-of-document
G
yank selection -s
Y
yank selection
y
<return>
<ctrl-m>
<ctrl-j>
<shift-return>
<enter>
<shift-enter>
scroll left
H
scroll down
J
scroll up
K
scroll right
L

View file

@ -25,7 +25,7 @@ then
if [ -f "$page_stmp_svg" ]
then
echo "Processing $page_orig_path (applying stamp)"
inkscape "$page_stmp_svg" --export-pdf "$page_stmp_pdf"
inkscape "$page_stmp_svg" --export-filename "$page_stmp_pdf"
pdftk "$page_orig_path" stamp "$page_stmp_pdf" output "$page_fin_pdf"
else
echo "Processing $page_orig_path (copying)"
@ -51,7 +51,7 @@ then
do
page_stmp_svg="$(echo "$page_orig_path" | sed 's|_og\.pdf$|_fg\.svg|')"
echo "Processing $page_orig_path"
inkscape "$page_orig_path" --export-plain-svg "$page_stmp_svg"
inkscape "$page_orig_path" --export-plain-svg --export-filename "$page_stmp_svg"
done
echo "Done. Make sure to edit in a a new layer in Inkscape and hide the original one."
else

View file

@ -29,7 +29,9 @@ if __name__ == "__main__":
"-o", "--subject", default=f"Test message {now.strftime('%H:%M:%S')}"
)
parser.add_argument("-m", "--me", default="Geoffrey")
parser.add_argument("-g", "--gtube", action="store_true")
parser.add_argument("-d", "--debug", action="store_true")
parser.add_argument("-b", "--body", default="")
args = parser.parse_args()
@ -37,6 +39,17 @@ if __name__ == "__main__":
if args.debug:
command = print
gtube = ""
if args.gtube:
gtube = """
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X"""
body = ""
if args.body:
body = f"\n\n{args.body}"
text = f"""Date: {now_email}
From: {args.sender}
Subject: {args.subject}
@ -45,7 +58,7 @@ To: {args.receiver}
Hello there,
This is a test message, generated from a template.
If you didn't expect to see this message, please contact {args.me}.
If you didn't expect to see this message, please contact {args.me}.{gtube}{body}
Greetings,
@ -57,11 +70,11 @@ Input arguments:
."""
if not args.debug:
for i in range(5, 0, -1):
for i in range(3, 0, -1):
print(f"Typing mail in {i}…")
time.sleep(1)
command(f"HELO {args.helo}")
command(f"EHLO {args.helo}")
command(f"MAIL FROM: <{args.sender}>")
command(f"RCPT TO: <{args.receiver}>")
command("DATA")

View file

@ -11,9 +11,11 @@ import enum
# TODO Able to ignore extensions everywhere
class ArchiveType():
suffix: str = ''
dest_suffix: str = ''
class ArchiveType:
suffix: str = ""
fullname: str = ""
dest_suffix: str = ""
mime: typing.Optional[str] = None
header: typing.Optional[bytes] = None
extract_cmd: typing.Optional[typing.List[str]] = None
@ -24,7 +26,7 @@ class ArchiveType():
self.log = logging.getLogger(self.__class__.__name__)
def dest_name(self, archive: str) -> str:
return archive[:-len(self.suffix)] + self.dest_suffix
return archive + self.dest_suffix
def fits(self, name_lower: str, mime: str, header: bytes) -> bool:
if not name_lower.endswith(self.suffix):
@ -55,81 +57,87 @@ class ArchiveType():
r.check_returncode()
if self.single_file:
assert os.path.isfile(dest)
os.unlink(archive)
extract_fun: typing.Optional[typing.Callable[[str, str], None]] = None
class ArchiveZip(ArchiveType):
suffix = '.zip'
mime = 'application/zip'
extract_cmd = ['unzip']
suffix = ".zip"
mime = "application/zip"
extract_cmd = ["unzip"]
class Archive7z(ArchiveType):
suffix = '.7z'
mime = 'application/x-7z-compressed'
extract_cmd = ['7z', 'x']
suffix = ".7z"
mime = "application/x-7z-compressed"
extract_cmd = ["7z", "x"]
class ArchiveRar(ArchiveType):
suffix = '.rar'
mime = 'application/x-rar'
extract_cmd = ['unrar', 'x']
suffix = ".rar"
mime = "application/x-rar"
extract_cmd = ["unrar", "x"]
class ArchiveTar(ArchiveType):
suffix = '.tar'
mime = 'application/x-tar'
extract_cmd = ['tar', '--extract', '--file']
suffix = ".tar"
mime = "application/x-tar"
extract_cmd = ["tar", "--extract", "--file"]
class ArchiveTarGz(ArchiveType):
suffix = '.tar.gz'
mime = 'application/gzip'
extract_cmd = ['tar', '--extract', '--gzip', '--file']
suffix = ".tar.gz"
mime = "application/gzip"
extract_cmd = ["tar", "--extract", "--gzip", "--file"]
class ArchiveTarXz(ArchiveType):
suffix = '.tar.xz'
mime = 'application/x-xz'
extract_cmd = ['tar', '--extract', '--xz', '--file']
suffix = ".tar.xz"
mime = "application/x-xz"
extract_cmd = ["tar", "--extract", "--xz", "--file"]
class ArchiveGzip(ArchiveType):
suffix = '.gz'
mime = 'application/gzip'
suffix = ".gz"
mime = "application/gzip"
single_file = True
extract_cmd = ['gunzip']
extract_cmd = ["gunzip"]
class TreeExtractor():
class TreeExtractor:
ARCHIVE_TYPES: typing.List[ArchiveType] = [
ArchiveZip(),
Archive7z(),
ArchiveRar(),
ArchiveTar(),
ArchiveTarGz(),
ArchiveTarXz(),
ArchiveGzip(),
ArchiveZip(),
Archive7z(),
ArchiveRar(),
ArchiveTar(),
ArchiveTarGz(),
ArchiveTarXz(),
ArchiveGzip(),
]
def __init__(self) -> None:
self.log = logging.getLogger('TreeExtractor')
self.extensions = set()
self.log = logging.getLogger("TreeExtractor")
self.suffixes = set()
for archive_type in self.ARCHIVE_TYPES:
suffixes = archive_type.suffix.split('.')
self.extensions.add('.' + suffixes[-1])
self.suffixes.add(archive_type.suffix)
def extract_tree(self, directory: str = '.') -> None:
def extract_tree(self, directory: str = ".") -> None:
for root, dirs, files in os.walk(directory):
real_root = os.path.realpath(root)
for name in files:
self.log.debug("Handling '%s' '%s'", real_root, name)
# Initial filtering with extensions
extension = os.path.splitext(name)[1].lower()
if extension not in self.extensions:
self.log.debug("Extension not matched: %s", name)
# Initial filtering with suffix
name_lower = name.lower()
for suffix in self.suffixes:
if name_lower.endswith(suffix):
break
else:
self.log.debug("Suffix not matched: %s", name)
continue
name_lower = name.lower()
filepath = os.path.join(real_root, name)
with open(filepath, 'rb') as filedesc:
with open(filepath, "rb") as filedesc:
header = filedesc.read(1024)
mime = magic.from_buffer(header, mime=True)
@ -144,19 +152,24 @@ class TreeExtractor():
dest_name = archive_type.dest_name(name)
dest = os.path.join(real_root, dest_name)
dest_tmp = dest + ".tmp"
try:
archive_type.extract(filepath, dest)
archive_type.extract(filepath, dest_tmp)
except BaseException as e:
# TODO Parameters stop on error
self.log.error(e, exc_info=True)
else:
os.unlink(filepath)
os.rename(dest_tmp, dest)
if os.path.isdir(dest):
self.extract_tree(dest)
def main(self) -> None:
directory = sys.argv[1] if len(sys.argv) > 1 else '.'
directory = sys.argv[1] if len(sys.argv) > 1 else "."
self.extract_tree(directory)
if __name__ == '__main__':
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
if __name__ == "__main__":
coloredlogs.install(level="DEBUG", fmt="%(levelname)s %(message)s")
TreeExtractor().main()

View file

@ -15,7 +15,7 @@ log = logging.getLogger()
# Constants
SOURCE_FOLDER = os.path.join(os.path.expanduser("~"), "Musiques")
OUTPUT_FOLDER = os.path.join(os.path.expanduser("~"), ".musicCompressed")
OUTPUT_FOLDER = os.path.join(os.path.expanduser("~"), ".MusiqueCompressed")
CONVERSIONS = {"flac": "opus"}
FORBIDDEN_EXTENSIONS = ["jpg", "png", "pdf", "ffs_db"]
FORGIVEN_FILENAMES = ["cover.jpg", "front.jpg", "folder.jpg",
@ -24,6 +24,7 @@ IGNORED_EMPTY_FOLDER = [".stfolder"]
RESTRICT_CHARACTERS = '[\0\\/:*"<>|]' # FAT32, NTFS
# RESTRICT_CHARACTERS = '[:/]' # HFS, HFS+
# RESTRICT_CHARACTERS = '[\0/]' # ext2-4, linux-based?
act = True
# TODO FEAT Make the directory structure the same as the base one and
# remove IGNORED_EMPTY_FOLDER variable
@ -96,13 +97,14 @@ for sourceFile in remainingConversions:
# Creating folder if it doesn't exists
fullOutputFile = os.path.join(OUTPUT_FOLDER, outputFile)
fullOutputDir = os.path.dirname(fullOutputFile)
os.makedirs(fullOutputDir, exist_ok=True)
if act:
os.makedirs(fullOutputDir, exist_ok=True)
# Converting
fullSourceFile = os.path.join(SOURCE_FOLDER, sourceFile)
if sourceFile == outputFile:
log.debug('%s → %s', fullSourceFile, fullOutputFile)
if os.path.isfile(fullOutputFile):
if act and os.path.isfile(fullOutputFile):
os.remove(fullOutputFile)
os.link(fullSourceFile, fullOutputFile)
else:
@ -112,7 +114,8 @@ log.info("Removing extra files")
for extraFile in extraFiles:
fullExtraFile = os.path.join(OUTPUT_FOLDER, extraFile)
log.debug('× %s', fullExtraFile)
os.remove(fullExtraFile)
if act:
os.remove(fullExtraFile)
log.info("Listing files that will be converted")
for fullSourceFile, fullOutputFile in conversions:
@ -123,11 +126,14 @@ for fullSourceFile, fullOutputFile in progressbar.progressbar(conversions):
cmd = ["ffmpeg", "-y", "-i", fullSourceFile, "-c:a", "libopus",
"-movflags", "+faststart", "-b:a", "128k", "-vbr", "on",
"-compression_level", "10", fullOutputFile]
subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if act:
subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
print(cmd)
# Removing empty dirs
for root, dirs, files in os.walk(OUTPUT_FOLDER):
if not dirs and not files:
dirBasename = os.path.basename(root)
if dirBasename not in IGNORED_EMPTY_FOLDER:
if act and dirBasename not in IGNORED_EMPTY_FOLDER:
os.rmdir(root)