ghickman / tvrenamr Goto Github PK
View Code? Open in Web Editor NEWUtility to rename tv shows into a cleaner format
Home Page: http://tvrenamr.info
License: MIT License
Utility to rename tv shows into a cleaner format
Home Page: http://tvrenamr.info
License: MIT License
Example:
"Castle - 2009" could not be found on The Tv DB
'Castle' could not be found on Tv Rage
No libraries left to fall back to. Exiting...
Looks like the changes in 3.1 or 3.2 might have caused this. Seems the year is being used as the episode number again.
Most likely the config override isn't working.
Calls to the TvDB appear to be happening with a leading zero in the season.
TvDB doesn't accept seasons in this format.
For example on it can't find American Dad because on thetvdb it's American Dad! but I don't want the files to have the ! in it, so maybe an option to change the searching show but not the one that is used to name the file? Although suppose you could do this with the output option?
I normally place all tv I haven't watched in an un-watched folder. Rename that and then move them after I've watched them. This means I run the renamer when there is quite often properly named shows in it.
Is there any way the application can detect a correctly named show and say so / ignore it, as opposed to saying "cannot find show bla bla bla"?
We should escape it, or add slash to the invalid files check (it's invalid on windows so the latter is prob better), however, we need to alter the clean_names method to allow lists of replacement characters and not just one.
Example filenames:
Arrested.Development.S04E12.720p.WEBRip.AAC2.0.x264-PublicHD.mkv
Venture.Bros.s02e11_viva_los_muertos.mkv
Error:
Traceback (most recent call last):
File "/usr/local/bin/tvr", line 9, in <module>
load_entry_point('tvrenamr==3.4.2', 'console_scripts', 'tvr')()
File "/Library/Python/2.7/site-packages/tvrenamr/frontend.py", line 168, in run
frontend.run()
File "/Library/Python/2.7/site-packages/tvrenamr/frontend.py", line 137, in run
self.rename(*details)
File "/Library/Python/2.7/site-packages/tvrenamr/frontend.py", line 92, in rename
canonical=options.canonical)
File "/Library/Python/2.7/site-packages/tvrenamr/main.py", line 185, in retrieve_episode_title
self.lookup = lib(*args) # assign to self for use in format_show_name
File "/Library/Python/2.7/site-packages/tvrenamr/libraries.py", line 25, in __init__
self.set_episode_title(self.build_episode_url())
File "/Library/Python/2.7/site-packages/tvrenamr/libraries.py", line 88, in set_episode_title
self.log.debug('Retrieved episode title: {0}'.format(self.title))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 2: ordinal not in range(128)
Python ships with ConfigParser and nothing in the config files should actually require Yaml yet it requires a hard dependency with optional C extensions.
Not shipping with this would be much nicer.
The Documentation at http://tvrenamr.readthedocs.org/en/latest/output-formats.html and http://tvrenamr.readthedocs.org/en/latest/custom-regexs.html#custom-regexs suggests that an output format of "$n S%s{2}E%e{2} %t%x" should result in Showname S01E01 EpTitle.avi, actual result is Showname S1{2}E01{2} Eptitle.avi
When missing a defaults section in the user's config the Config class should fall back on a set of pre-defined defaults.
Two ways to do this spring to mind:
First time using this tool (which looks great!), but I'm getting the following error:
tvr -l debug How.I.Met.Your.Mother.S09E04.720p.HDTV.x264-2HD.mkv
2013-10-09 22:32 DEBUG Config Config loaded
2013-10-09 22:32 DEBUG Config Defaults retrieved
2013-10-09 22:32 MINIMAL Core Renaming: How.I.Met.Your.Mother.S09E04.HDTV.x264-2HD.mkv
2013-10-09 22:32 DEBUG Core Renaming using: (?P<show_name>[\w\s.',_-]+)\.[Ss]?(?P<season>\d{1,2})[XxEe]?(?P<episode>\d{2}).E?(?P<episode2>\d{2})*
2013-10-09 22:32 DEBUG Core Filename yielded: season: 9, show_name: How I Met Your Mother, episodes: ['4'], extension: .mkv
2013-10-09 22:32 DEBUG Config No canonical defined, returning: How I Met Your Mother
2013-10-09 22:32 DEBUG Core Show Name: How I Met Your Mother
2013-10-09 22:32 DEBUG Core Using TheTvDb
2013-10-09 22:32 INFO The Tv DB Searching: How I Met Your Mother
2013-10-09 22:32 DEBUG The Tv DB Retrieving series id for How I Met Your Mother
2013-10-09 22:32 DEBUG The Tv DB Series url: http://www.thetvdb.com/api/GetSeries.php?seriesname=How%20I%20Met%20Your%20Mother
2013-10-09 22:32 INFO requests.packages.urllib3.connectionpool Starting new HTTP connection (1): www.thetvdb.com
2013-10-09 22:32 DEBUG requests.packages.urllib3.connectionpool Setting read timeout to None
2013-10-09 22:32 DEBUG requests.packages.urllib3.connectionpool "GET /api/GetSeries.php?seriesname=How%20I%20Met%20Your%20Mother HTTP/1.1" 200 None
2013-10-09 22:32 DEBUG The Tv DB XML: Attempting to parse
2013-10-09 22:32 DEBUG The Tv DB XML: Parsed
2013-10-09 22:32 DEBUG The Tv DB Series chosen: How I Met Your Mother
2013-10-09 22:32 DEBUG The Tv DB Retrieved show id: 75760
2013-10-09 22:32 DEBUG The Tv DB Retrieved canonical show name: How I Met Your Mother
2013-10-09 22:32 DEBUG The Tv DB Episode URL: http://www.thetvdb.com/api/C4C424B4E9137AFD/series/75760/default/9/4/en.xml
2013-10-09 22:32 DEBUG The Tv DB Attempting to retrieve episode title
2013-10-09 22:32 INFO requests.packages.urllib3.connectionpool Starting new HTTP connection (1): www.thetvdb.com
2013-10-09 22:32 DEBUG requests.packages.urllib3.connectionpool Setting read timeout to None
2013-10-09 22:32 DEBUG requests.packages.urllib3.connectionpool "GET /api/C4C424B4E9137AFD/series/75760/default/9/4/en.xml HTTP/1.1" 200 None
2013-10-09 22:32 DEBUG The Tv DB XML: Retreived
2013-10-09 22:32 DEBUG The Tv DB XML: Attempting to parse
2013-10-09 22:32 DEBUG The Tv DB XML: Episode document retrived for How I Met Your Mother - 904
2013-10-09 22:32 DEBUG The Tv DB XML: Attempting to find the episode title
2013-10-09 22:32 DEBUG The Tv DB Retrieved episode title: The Broken Code
2013-10-09 22:32 INFO Core Episode: The Broken Code
2013-10-09 22:32 DEBUG Error "How I Met Your Mother" is not in the Config. Falling back on name extracted from the filename
2013-10-09 22:32 DEBUG Core Using the formatted show name retrieved by the library: How I Met Your Mother
2013-10-09 22:32 DEBUG Core Final show name: How I Met Your Mother
2013-10-09 22:32 MINIMAL Core Directory:
2013-10-09 22:32 CRITICAL FrontEnd 'bool' object has no attribute 'replace'
2013-10-09 22:32 INFO FrontEnd
Make tvrenamr.init the entry_point and put all code from frontend.run() and frontend's main invocation into there along with option parsing.
Refactor FrontEnd so options are passed to it from whomever is using it. This way the daemonising code can invoke FrontEnd more easily.
I'm getting this error when trying to rename anything:
tvr: critical error: [Errno 18] Invalid cross-device link
Here's the log: https://gist.github.com/4abd825e566f8ad9c630
Any help appreciated.
Here's the gist link: git://gist.github.com/4056842.git
I'll give that a try then. What's the easiest way to uninstall the version I currently have installed? Or can I just run pip with the version number and it will overwrite it?
Cache the necessary XML files in the tests folder and change the mocked requests function to only ever return that.
One test seems to fail on Travis only.
The tests pass in a fresh checkout on OS X but need running on a Linux machine to check before Travis testing.
Travis have kindly offered to help me with a debug VM too.
Using the --regex
option requires the name
, season
and episode
parts in the string.
Any filename that doesn't use all three of these can be renamed with difficulty, if at all.
Example:
S2 - E01 - Title.avi
Making the different parts optional so they can be provided with options, e.g.:
tvr S2\ -\ E01\ -\ Some\ Title.avi --regex "" --name "Chuck" --season 2 --episode 3
As an addition to this the --canonical
option should still work as before, i.e.:
--canonical
or --name
: Search the library for this name and use it to rename the file.--canonical
and --name
: Search the library using the --canonical
name and use --name
for the show name in the filename.Need a place to put defaults so they're not spread around the code base.
#19 describes the need for this with regard to output format and the list of libraries is in need of it unless I go down the introspection route.
When trying to run the daemon script in daemon mode (instead of loop) it cannot write stdout.txt to the file system and throws OSError: [Errno 13] Permission denied: 'stdout.txt'
Looks like 720p episode support got broken recently. Most likely when multiple episodes got introduced.
Example: show.name.S03E01.720.something.mkv
Tests!
The Show IDs from each library are very unlikely to change so we should cache those. It would make sense for that to be in a database. This should really be a sqlite database stored in the same location as config. This feature needs to be optional given that it requires a non-python dependency.
The location of the database should be configurable with a switch and in the config.
Flushing the show or the full database should be doable from the front end.
tvr --flush-show-id
should flush the show id for the show of the file being renamed.
Also, the link to tests results to Travis is wrong.
It should include target
as well: :target: https://travis-ci.org/ghickman/tvrenamr
Pseudo format: SxxExx
Output Format: %n.S%sE%e%x
Expected Format: S01E20
Actual Output: S1E0120
Need to check if using {n}
format in the output sections and it looks like the episode is outputting the season too.
Update use of urllib2 to requests
The field on the Episode
object is called show_name
, as defined here: https://github.com/ghickman/tvrenamr/blob/master/tvrenamr/episode.py#L6
However, main.py
tries to access the field as episode.show
: https://github.com/ghickman/tvrenamr/blob/master/tvrenamr/main.py#L113
Furthermore, this bug causes an infinite recursion on the Episode
object's __getattr__
implementation because it erroneously calls __getitem__
. Episodes are not containers, so you probably just want something like this:
if item is 'episode_2':
return '0%s' % self.episode
else:
raise AttributeError
The globing code needs to expand each item it gets from the command line and present a list to the TvRenamr class.
Currently have noticed the following issue:
! in titles (Such as American Dad)
: in titles (Such as Spartacus: Blood and Sand)
2010 in title (New versions of original series, although 2010 is included in the torrent name, it cannot find , such as Human Target (2010)
Example:
tvr foo.1.bar --regex "text.%e.text" -s 1
This should work but the season number hasn't been passed down to the File object by the look of it.
Traceback (most recent call last):
File "/usr/local/bin/tvr", line 9, in <module>
load_entry_point('tvrenamr==3.4.1', 'console_scripts', 'tvr')()
File "/Library/Python/2.7/site-packages/tvrenamr-3.4.1-py2.7.egg/tvrenamr/frontend.py", line 168, in run
frontend.run()
File "/Library/Python/2.7/site-packages/tvrenamr-3.4.1-py2.7.egg/tvrenamr/frontend.py", line 137, in run
self.rename(*details)
File "/Library/Python/2.7/site-packages/tvrenamr-3.4.1-py2.7.egg/tvrenamr/frontend.py", line 92, in rename
canonical=options.canonical)
File "/Library/Python/2.7/site-packages/tvrenamr-3.4.1-py2.7.egg/tvrenamr/main.py", line 185, in retrieve_episode_title
self.lookup = lib(*args) # assign to self for use in format_show_name
File "/Library/Python/2.7/site-packages/tvrenamr-3.4.1-py2.7.egg/tvrenamr/libraries.py", line 25, in __init__
self.set_episode_title(self.build_episode_url())
File "/Library/Python/2.7/site-packages/tvrenamr-3.4.1-py2.7.egg/tvrenamr/libraries.py", line 128, in build_episode_url
season = str(int(self.season))
ValueError: invalid literal for int() with base 10: ''
When requesting the XML from TVDb's API (TvRage may be similar) we're given a document with the series id in, which we're currently requesting for every single episode.
Cache the XML file locally and refer to it if it passes a sanity check. Age should factor into this, since both libraries' DB's do get updated.
The TVDb locks seasons so only an admin can change them, usually if they are old. If we can get that data then caching a show forever would be sensible.
Add a switch to override this.
Allow the config to override it at both the global and show level.
Tv Rage returns all episodes of a season in one file. For shows that aren't likely to change this would make sense to cache. Look at the air date of the latest episode and if it has been a year since this occurred cache the whole lot into oblivion. It's probably safe (ish) to assume that the data won't change any time soon.
Copy the example at http://crate.io/packages/tvrenamr/ in a big font to show to install/upgrade.
Update for Python 3 support!
Example filename: Arrow.S01E10.Burned.1080p.WEB-DL.DD5.1.H.264-TB.mkv
Using the --library switch does select the chosen library.
This is mostly likely due to some doofus not coding the option to work....oh wait.
Deluge functionality has fallen behind core significantly and doesn't really make sense in core anymore.
It either needs splitting out into it's own lib (as a wrapper) or simply removing.
The TVDb treats special episodes as Season 0 but usually it's nicer to name that folder "Special".
Add the naming of this as an option to the global config and the command line. It should be overridable using the specific show options too.
Taking a leaf from Django's CBV book use a base class and implementation child classes for the libraries.
They're currently about 70% duplicated code as it is.
Having a config in the tests muddies the waters with what is and isn't required for testing various sections and has been the cause of a few other issues by accident, namely #50
Currently overwriting them with each file renamed.
I name files with periods in the filename (as I use unix, its not a naming issue), It would be perfect if this tool had the option to replace spaces with dots..
:)
If the user doesn't have a "defaults" dict in config.yaml
, the defaults
field on the Config
object is None because this method returns None implicitly: https://github.com/ghickman/tvrenamr/blob/master/tvrenamr/config.py#L96
Then, later, when a config value is looked up, defaults
is assumed to exist: https://github.com/ghickman/tvrenamr/blob/master/tvrenamr/config.py#L27
This raises a "TypeError: 'NoneType' object is not subscriptable" error, which is not handled. You probably want this somewhere in there:
if not self.defaults:
return False
It looks like thetvdb.com is sending gzip-compressed HTTP responses even though tvrenamr is not requesting it by sending the associated "Accept-Encoding" header. Just running:
>>> import urllib2
>>> urllib2.urlopen('http://www.thetvdb.com/api/C4C424B4E9137AFD/series/79488/default/5/22/en.xml').read()
gives a compressed response. This means that all requests to this backend result in an XML parse error.
Here's an example of using the built-in gzip module to decode this kind of thing: this function and this check
My apologies for such rapid-fire issue filing; I don't mean to be demanding about an open-source project. Feel free to just ignore me. :)
Create a higher level configuration handler that deals with the config file and the command line in a single point.
This would allow the code to check one place and have the handler work out the highest priority option.
Unless the organise option is set as yes, files are not renamed
So it seems that the renamr breaks on the terms that have a date in it after the name.
Example matching would be
The.Colbert.Report.2013.02.12.Roger.Hodge.720p.HDTV.mkv
The.Daily.Show.2013.01.22.Jennifer.Lopez.720p.HDTV.mkv
Trying to figure out a regex that would match dates (forwards and backwards for those across the pond :) )
Looking at tvrage it maps by name but also provides the address as a match point:
http://www.tvrage.com/The_Colbert_Report/episode_list
Haven't tested what you gave me but putting it here as reference:
tvr --regex "%n.2013.02.12.%t" -s 9 -e 22 --partial <filename>
tvr --history
will parse the logs and return a list of files that have been renamed, passing the list to the default system pager.
Pager can also be set with shell variable or the config file.
Format: Show.Name.US.S01E04.HDTV.XviD-2HD.avi
Throws this error: cannot concatenate 'str' and 'NoneType' objects
Fine with the -n 'Show name' switch.
Catch keyboard interrupts and exit with a clean message. The stack trace is a waste of console real estate.
Core XML is probably fine, but considered bad practice now.
I previously had this running on my ReadyNAS Duo v2, I have now moved to a HP Proliant N40L running FreeNAS which uses FreeBSD.
I installed the package using python setup.py install, I tried to reinstall it because of the error.
I try to run it on a single file but I always get the same error, I tried just a dry run and it's the same thing:
tvr: critical error: 'NoneType' object is not subscriptable
Here is a gist of my config, my tvrenamr.log and the output from the reinstall: https://gist.github.com/4046147
Any help would be much appreciated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.