/
frontend.py
178 lines (148 loc) · 6.07 KB
/
frontend.py
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/python
import logging
import os
import sys
from __init__ import __version__
from config import Config
from episode import Episode
from errors import *
from logs import start_logging
from main import TvRenamr
from options import OptionParser
log = logging.getLogger('Core')
parser = OptionParser(usage='tvr [options] <file/folder>',
version='Tv Renamr {0}'.format(__version__))
options, args = parser.parse_args()
class FrontEnd():
def __init__(self, path):
# start logging
if options.debug:
options.log_level = 10
start_logging(options.log_file, options.log_level, options.quiet)
self.config = self._get_config()
# no path was passed in so assuming current directory.
if not path:
if options.debug:
log.debug('No file or directory specified, using '
'current directory')
path = [os.getcwd()]
# determine type
try:
file_list = self._build_file_list(path, options.recursive,
options.ignore_filelist)
except OSError:
parser.error('\'%s\' is not a file or directory. Ruh Roe!' % path)
if options.dry or options.debug:
self._start_dry_run()
# kick off a rename for each file in the list
for details in file_list:
self.rename(details)
# if we're not doing a dry run add a blank line for clarity
if options.debug is False and options.dry is False:
log.info('')
if options.dry or options.debug:
self._stop_dry_run()
def _build_file_list(self, path, recursive=False, ignore_filelist=None):
"""
Determines which files need to be processed for renaming.
:param path: The input file or directory.
:param recursive: Do a recursive search for files if 'path' is a
directory. Default is False.
:param ignore_filelist: Optional set of files to ignore from renaming.
Often used by filtering
methods such as Deluge.
:returns: A list of files to be renamed.
:rtype: A list of dictionaries, with the keys directory and filename.
"""
filelist = []
if len(path) > 1:
# must have used wildcards
for fn in path:
filelist.append(os.path.split(fn))
return filelist
else:
if os.path.isdir(path[0]):
for root, dirs, files in os.walk(path[0]):
for fname in files:
# If we have a file we should be ignoring and skipping.
if ignore_filelist is not None and \
(os.path.join(root, fname) in ignore_filelist):
continue
filelist.append((root, fname))
# Don't want a recursive walk?
if not recursive:
break
return filelist
elif os.path.isfile(path[0]):
return [os.path.split(path[0])]
else:
raise OSError
def _get_config(self):
possible_config = (
options.config,
os.path.expanduser('~/.tvrenamr/config.yml'),
os.path.join(sys.path[0], 'config.yml')
)
# get the first viable config from the list of possibles
_config = None
for config in possible_config:
if config is not None and os.path.exists(config):
_config = Config(config)
break
if _config is None:
raise ConfigNotFoundException
return _config
def rename(self, details):
working, filename = details
try:
tv = TvRenamr(working, self.config, options.debug, options.dry)
episode = Episode(**tv.extract_details_from_file(filename,
user_regex=options.regex))
if options.show_name:
episode.show_name = options.show_name
if options.season:
episode.season = options.season
if options.episode:
episode.episode = options.episode
episode.title = tv.retrieve_episode_name(episode, library=options.library,
canonical=options.canonical)
episode.show_name = tv.format_show_name(episode.show_name, the=options.the,
override=options.show_override)
path = tv.build_path(episode, rename_dir=options.rename_dir,
organise=options.organise, format=options.output_format)
tv.rename(filename, path)
except (ConfigNotFoundException,
NoMoreLibrariesException,
NoNetworkConnectionException):
if options.dry or options.debug:
self._stop_dry_run()
sys.exit(1)
except (AttributeError,
EmptyEpisodeNameException,
EpisodeAlreadyExistsInDirectoryException,
EpisodeNotFoundException,
IncorrectCustomRegularExpressionSyntaxException,
InvalidXMLException,
OutputFormatMissingSyntaxException,
ShowNotFoundException,
UnexpectedFormatException) as e:
if e.args:
log.critical(e)
pass
except Exception as err:
if options.debug:
# In debug mode, show the full traceback.
raise
log.critical('tvr: critical error: %s' % str(err))
sys.exit(1)
def _start_dry_run(self):
log.log(26, 'Dry Run beginning.')
log.log(26, '-' * 70)
log.log(26, '')
def _stop_dry_run(self):
log.log(26, '')
log.log(26, '-' * 70)
log.log(26, 'Dry Run complete. No files were harmed in the process.')
log.log(26, '')
if __name__ == "__main__":
frontend = FrontEnd(args)