-
Notifications
You must be signed in to change notification settings - Fork 0
/
assoc.py.bak
109 lines (88 loc) · 2.96 KB
/
assoc.py.bak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import toml
import filetype
import subprocess
import timeit
import re
import functools
import collections
import os
""" assoc.py
assoc.py handles the mapping of handler programs to mime types.
We use our own TOML "database" here, but it's trivial to implement
a database class for the XDG standard.
"""
class NoAssociationException(Exception):
pass
class AssocDB():
""" AssocDB is a reference implementation of an Associations Database.
It uses a TOML file for the database and supports globbing. """
def __init__(self, dbfile):
with open(dbfile, "r") as file:
tomldata = toml.load(file, _dict = collections.OrderedDict)
self.assocs = tomldata["associations"]
# Precompile all the regular expressions to save on lookup time.
for assoc in self.assocs:
try:
re.compile(assoc)
except:
pass
@functools.lru_cache(maxsize = 4096)
def Lookup(self, mimetype):
# While this /can/ be handled by regular expressions, It's better not to.
# Dictonary lookups are a lot quicker than compiling a bunch of regexs
# in a loop.
try:
return self.assocs[mimetype]
except KeyError:
pass
# Perform globbing for subtype.
for assoc in self.assocs:
regex = re.compile(assoc)
if regex.match(mimetype):
return self.assocs[assoc]
# There are no entrys,
# the only thing we can do now is raise an exception.
raise NoAssociationException()
@functools.lru_cache(maxsize = 4096)
def LookupFromFile(self, file):
type = filetype.guess(file)
if not type:
raise NoAssociationException()
print(type.mime)
assoc = self.Lookup(type.mime)
return assoc
class Runner():
__slots__ = ["assocdb"]
def __init__(self, assocdb):
self.assocdb = assocdb
def Run(self, file, foreground = False):
assoc = self.assocdb.LookupFromFile(file)
# Format the assoc.
assoc = assoc.format(
file = file
)
print(f"Running {file} with {assoc}")
proc = subprocess.Popen(assoc, shell = True)
if foreground:
proc.wait()
def test():
try:
print(db.Lookup.cache_info())
db.Lookup("audio/x-flac")
except NoAssociationException:
pass
if __name__ == "__main__":
# Load the database.
db = AssocDB("assoc.toml")
# Load the Runner.
r = Runner(db)
# Guess mimetype.
# r.Run("test.flac", foreground = True)
for dirpath, dirnames, filenames in os.walk("/home/jordyn/code"):
for filename in filenames:
print(f"Lookup: {db.Lookup.cache_info()}")
print(f"LookupFromFile: {db.LookupFromFile.cache_info()}")
try:
db.LookupFromFile(f"{dirpath}/{filename}")
except NoAssociationException:
pass