2012-11-06 12:56:30 -08:00
|
|
|
"""
|
|
|
|
Functions for parsing comic info from filename
|
|
|
|
|
|
|
|
This should probably be re-written, but, well, it mostly works!
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
"""
|
|
|
|
Copyright 2012 Anthony Beville
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
"""
|
2012-11-02 13:54:17 -07:00
|
|
|
|
2012-11-02 20:56:01 -07:00
|
|
|
|
|
|
|
# Some portions of this code were modified from pyComicMetaThis project
|
|
|
|
# http://code.google.com/p/pycomicmetathis/
|
2012-11-02 13:54:17 -07:00
|
|
|
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
from urllib import unquote
|
|
|
|
|
|
|
|
class FileNameParser:
|
2013-02-13 21:37:00 -08:00
|
|
|
def fixSpaces( self, string, remove_dashes=True ):
|
|
|
|
if remove_dashes:
|
|
|
|
placeholders = ['[-_]',' +']
|
|
|
|
else:
|
|
|
|
placeholders = ['[_]',' +']
|
2012-11-02 13:54:17 -07:00
|
|
|
for ph in placeholders:
|
|
|
|
string = re.sub(ph, ' ', string )
|
|
|
|
return string.strip()
|
|
|
|
|
|
|
|
# check for silly .1 or .5 style issue strings
|
|
|
|
# allow up to 5 chars total
|
|
|
|
def isPointIssue( self, word ):
|
|
|
|
ret = False
|
|
|
|
try:
|
|
|
|
float(word)
|
|
|
|
if (len(word) < 5 and not word.isdigit()):
|
|
|
|
ret = True
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
return ret
|
2012-11-18 21:15:16 -08:00
|
|
|
|
|
|
|
|
|
|
|
def getIssueCount( self,filename ):
|
|
|
|
|
|
|
|
count = ""
|
|
|
|
# replace any name seperators with spaces
|
|
|
|
tmpstr = self.fixSpaces(filename)
|
|
|
|
found = False
|
|
|
|
|
|
|
|
match = re.search('(?<=\sof\s)\d+(?=\s)', tmpstr, re.IGNORECASE)
|
|
|
|
if match:
|
|
|
|
count = match.group()
|
|
|
|
found = True
|
|
|
|
|
|
|
|
if not found:
|
|
|
|
match = re.search('(?<=\(of\s)\d+(?=\))', tmpstr, re.IGNORECASE)
|
|
|
|
if match:
|
|
|
|
count = match.group()
|
|
|
|
found = True
|
|
|
|
|
|
|
|
|
|
|
|
count = count.lstrip("0")
|
|
|
|
|
|
|
|
return count
|
|
|
|
|
2012-11-02 13:54:17 -07:00
|
|
|
|
2012-11-19 11:57:16 -08:00
|
|
|
def getIssueNumber( self, filename ):
|
2012-11-02 13:54:17 -07:00
|
|
|
|
|
|
|
found = False
|
|
|
|
issue = ''
|
2012-11-18 21:15:16 -08:00
|
|
|
|
|
|
|
# first, look for multiple "--", this mean's it's formatted differently from most:
|
|
|
|
if "--" in filename:
|
2012-12-21 17:18:18 -08:00
|
|
|
# the pattern seems to be that anything to left of the first "--" is the series name followed by issue
|
2012-11-18 21:15:16 -08:00
|
|
|
filename = filename.split("--")[0]
|
2012-12-21 17:18:18 -08:00
|
|
|
elif "___" in filename:
|
|
|
|
# the pattern seems to be that anything to left of the first "__" is the series name followed by issue
|
|
|
|
filename = filename.split("__")[0]
|
2013-01-30 10:39:13 -08:00
|
|
|
|
|
|
|
filename = filename.replace("+", " ")
|
2012-11-18 21:15:16 -08:00
|
|
|
|
2013-01-30 10:39:13 -08:00
|
|
|
# remove parenthetical phrases
|
|
|
|
filename = re.sub( "\(.*\)", "", filename)
|
|
|
|
filename = re.sub( "\[.*\]", "", filename)
|
|
|
|
|
2012-11-02 13:54:17 -07:00
|
|
|
# guess based on position
|
|
|
|
|
|
|
|
# replace any name seperators with spaces
|
|
|
|
tmpstr = self.fixSpaces(filename)
|
|
|
|
word_list = tmpstr.split(' ')
|
|
|
|
|
2012-12-03 21:28:06 -08:00
|
|
|
#before we search, remove any kind of likely "of X" phrase
|
|
|
|
for i in range(0, len(word_list)-2):
|
|
|
|
if ( word_list[i].isdigit() and
|
|
|
|
word_list[i+1] == "of" and
|
|
|
|
word_list[i+2].isdigit() ):
|
|
|
|
word_list[i+1] ="XXX"
|
|
|
|
word_list[i+2] ="XXX"
|
|
|
|
|
|
|
|
|
2013-01-30 17:05:16 -08:00
|
|
|
# first look for the last "#" followed by a digit in the filename. this is almost certainly the issue number
|
|
|
|
#issnum = re.search('#\d+', filename)
|
2013-03-11 16:18:07 -07:00
|
|
|
matchlist = re.findall("#[-+]?([0-9]*\.[0-9]+|[0-9]+)", filename)
|
2013-01-30 17:05:16 -08:00
|
|
|
if len(matchlist) > 0:
|
|
|
|
#get the last item
|
|
|
|
issue = matchlist[ len(matchlist) - 1]
|
|
|
|
found = True
|
|
|
|
|
2012-11-02 13:54:17 -07:00
|
|
|
# assume the last number in the filename that is under 4 digits is the issue number
|
2013-01-30 17:05:16 -08:00
|
|
|
if not found:
|
|
|
|
for word in reversed(word_list):
|
|
|
|
if len(word) > 0 and word[0] == "#":
|
|
|
|
word = word[1:]
|
|
|
|
if (
|
|
|
|
(word.isdigit() and len(word) < 4) or
|
|
|
|
(self.isPointIssue(word))
|
|
|
|
):
|
|
|
|
issue = word
|
|
|
|
found = True
|
|
|
|
#print 'Assuming issue number is ' + str(issue) + ' based on the position.'
|
|
|
|
break
|
2012-11-02 13:54:17 -07:00
|
|
|
|
|
|
|
if not found:
|
|
|
|
# try a regex
|
|
|
|
issnum = re.search('(?<=[_#\s-])(\d+[a-zA-Z]|\d+\.\d|\d+)', filename)
|
|
|
|
if issnum:
|
|
|
|
issue = issnum.group()
|
|
|
|
found = True
|
|
|
|
#print 'Got the issue using regex. Issue is ' + issue
|
|
|
|
|
|
|
|
return issue.strip()
|
|
|
|
|
|
|
|
def getSeriesName(self, filename, issue ):
|
|
|
|
|
|
|
|
# use the issue number string to split the filename string
|
|
|
|
# assume first element of list is the series name, plus cruft
|
|
|
|
#!!! this could fail in the case of small numerics in the series name!!!
|
2012-11-17 16:32:01 -08:00
|
|
|
|
|
|
|
# TODO: we really should pass in the *INDEX* of the issue, that makes
|
|
|
|
# finding it easier
|
|
|
|
|
2013-01-30 10:39:13 -08:00
|
|
|
filename = filename.replace("+", " ")
|
2013-02-13 21:37:00 -08:00
|
|
|
tmpstr = self.fixSpaces(filename, remove_dashes=False)
|
2012-11-17 16:32:01 -08:00
|
|
|
|
|
|
|
#remove pound signs. this might mess up the series name if there is a# in it.
|
|
|
|
tmpstr = tmpstr.replace("#", " ")
|
|
|
|
|
|
|
|
if issue != "":
|
2012-12-29 21:06:12 -08:00
|
|
|
# assume that issue substr has at least one space before it
|
2012-11-17 16:32:01 -08:00
|
|
|
issue_str = " " + str(issue)
|
|
|
|
series = tmpstr.split(issue_str)[0]
|
2012-11-02 13:54:17 -07:00
|
|
|
else:
|
|
|
|
# no issue to work off of
|
|
|
|
#!!! TODO we should look for the year, and split from that
|
2012-12-03 20:02:53 -08:00
|
|
|
# and if that doesn't exist, remove parenthetical phrases
|
2012-11-02 13:54:17 -07:00
|
|
|
series = tmpstr
|
2012-12-03 20:02:53 -08:00
|
|
|
series = re.sub( "\(.*\)", "", tmpstr)
|
2012-11-02 13:54:17 -07:00
|
|
|
|
|
|
|
volume = ""
|
|
|
|
|
|
|
|
series = series.rstrip("#")
|
|
|
|
|
2013-01-24 22:13:09 -08:00
|
|
|
# search for volume number
|
|
|
|
match = re.search('(.+)([vV]|[Vv][oO][Ll]\.?\s?)(\d+)\s*$', series)
|
2012-11-02 13:54:17 -07:00
|
|
|
if match:
|
2013-01-24 22:13:09 -08:00
|
|
|
series = match.group(1)
|
|
|
|
volume = match.group(3)
|
2012-11-02 13:54:17 -07:00
|
|
|
|
|
|
|
return series.strip(), volume.strip()
|
|
|
|
|
|
|
|
def getYear( self,filename):
|
|
|
|
|
|
|
|
year = ""
|
|
|
|
# look for four digit number with "(" ")" or "--" around it
|
|
|
|
match = re.search('(\(\d\d\d\d\))|(--\d\d\d\d--)', filename)
|
|
|
|
if match:
|
|
|
|
year = match.group()
|
|
|
|
# remove non-numerics
|
|
|
|
year = re.sub("[^0-9]", "", year)
|
|
|
|
return year
|
|
|
|
|
|
|
|
def parseFilename( self, filename ):
|
2012-12-29 21:06:12 -08:00
|
|
|
|
2012-11-02 13:54:17 -07:00
|
|
|
# remove the path
|
|
|
|
filename = os.path.basename(filename)
|
|
|
|
|
|
|
|
# remove the extension
|
|
|
|
filename = os.path.splitext(filename)[0]
|
2012-11-09 13:02:59 -08:00
|
|
|
|
|
|
|
#url decode, just in case
|
2012-11-02 13:54:17 -07:00
|
|
|
filename = unquote(filename)
|
2012-11-09 13:02:59 -08:00
|
|
|
|
2012-12-03 18:50:25 -08:00
|
|
|
# sometimes archives get messed up names from too many decodings
|
|
|
|
# often url encodings will break and leave "_28" and "_29" in place
|
|
|
|
# of "(" and ")" see if there are a number of these, and replace them
|
|
|
|
if filename.count("_28") > 1 and filename.count("_29") > 1:
|
|
|
|
filename = filename.replace("_28", "(")
|
|
|
|
filename = filename.replace("_29", ")")
|
|
|
|
|
2012-11-09 13:02:59 -08:00
|
|
|
# ----HACK
|
|
|
|
# remove the first word that word is a 3 digit number.
|
|
|
|
# some story arcs collection packs do this, but it's ugly
|
|
|
|
# this will probably break something, i.e. "100 bullets"
|
2013-01-30 10:39:13 -08:00
|
|
|
#word = filename.split(' ')[0]
|
|
|
|
#if len(word) == 3 and word[0] =='0' and word.isdigit():
|
|
|
|
# filename = filename[4:]
|
2012-11-09 13:02:59 -08:00
|
|
|
# ----HACK -
|
|
|
|
|
2012-11-02 13:54:17 -07:00
|
|
|
self.issue = self.getIssueNumber(filename)
|
|
|
|
self.series, self.volume = self.getSeriesName(filename, self.issue)
|
|
|
|
self.year = self.getYear(filename)
|
2012-11-18 21:15:16 -08:00
|
|
|
self.issue_count = self.getIssueCount(filename)
|
2012-11-02 13:54:17 -07:00
|
|
|
|
|
|
|
if self.issue != "":
|
|
|
|
# strip off leading zeros
|
|
|
|
self.issue = self.issue.lstrip("0")
|
|
|
|
if self.issue == "":
|
|
|
|
self.issue = "0"
|
2013-01-22 17:25:17 -08:00
|
|
|
if self.issue[0] == ".":
|
|
|
|
self.issue = "0" + self.issue
|
|
|
|
|