Add conditionals_use_lists(default:true) setting for replace_metadata & Include/Exclude metadata conditionals. Might change existing behavior for some users.

This commit is contained in:
Jim Miller 2018-12-29 13:32:16 -06:00
parent 047eb9c37e
commit 0387bd9e7e
4 changed files with 46 additions and 15 deletions

View file

@ -232,6 +232,14 @@ connect_timeout:60.0
## page:
## https://github.com/JimmXinu/FanFicFare/wiki/InExcludeMetadataFeature
## When set true, conditionals for both replace_metadata and
## Include/Exclude metadata will check against each list value rather
## than the entire list as a string which was the case prior to this
## change (~Dec 2018). replace_metadata conditionals (after &&) can
## also now use ==, !=, =~ and !~. => is the same as =~ .)
## Set false to get the old behavior. You can also compare the list
## as string by using <entry>_LIST, such as category_LIST
conditionals_use_lists:true
## You can exclude chapters from a story by listing their chapter URLs
## in ignore_chapter_url_list. Chapter URLs will be normalized before

View file

@ -210,6 +210,7 @@ def get_valid_set_options():
'use_ssl_unverified_context':(None,None,boollist),
'continue_on_chapter_error':(None,None,boollist),
'conditionals_use_lists':(None,None,boollist),
'add_chapter_numbers':(None,None,boollist+['toconly']),
@ -435,6 +436,7 @@ def get_valid_keywords():
'use_meta_keywords',
'chapter_categories_use_all',
'clean_chapter_titles',
'conditionals_use_lists',
'description_in_chapter',
'inject_chapter_title',
'titlepage_end',

View file

@ -288,6 +288,14 @@ connect_timeout:60.0
## page:
## https://github.com/JimmXinu/FanFicFare/wiki/InExcludeMetadataFeature
## When set true, conditionals for both replace_metadata and
## Include/Exclude metadata will check against each list value rather
## than the entire list as a string which was the case prior to this
## change (~Dec 2018). replace_metadata conditionals (after &&) can
## also now use ==, !=, =~ and !~. => is the same as =~ .)
## Set false to get the old behavior. You can also compare the list
## as string by using <entry>_LIST, such as category_LIST
conditionals_use_lists:true
## You can exclude chapters from a story by listing their chapter URLs
## in ignore_chapter_url_list. Chapter URLs will be normalized before

View file

@ -353,15 +353,19 @@ class InExMatch:
def in_keys(self,key):
return key in self.keys
def is_match(self,value):
def is_match(self,param):
if not isinstance(param,list):
param = [param]
retval = False
if self.regex:
if self.regex.search(value):
retval = True
#print(">>>>>>>>>>>>>%s=~%s r: %s,%s=%s"%(self.match,value,self.negate,retval,self.negate != retval))
else:
retval = self.match == value
#print(">>>>>>>>>>>>>%s==%s r: %s,%s=%s"%(self.match,value,self.negate,retval, self.negate != retval))
# print(param)
for value in param:
if self.regex:
if self.regex.search(value):
retval |= True
#print(">>>>>>>>>>>>>%s=~%s r: %s,%s=%s"%(self.match,value,self.negate,retval,self.negate != retval))
else:
retval |= self.match == value
#print(">>>>>>>>>>>>>%s==%s r: %s,%s=%s"%(self.match,value,self.negate,retval, self.negate != retval))
return self.negate != retval
@ -530,28 +534,36 @@ class Story(Configurable):
# is_lightweight()
self.replacements_prepped = False
def getMetadataForConditional(self,key,seen_list={}):
if self.getConfig("conditionals_use_lists",True) and not key.endswith("_LIST"):
condval = self.getList(key,seen_list=seen_list)
else:
condval = self.getMetadata(key.replace("_LIST",""),seen_list=seen_list)
return condval
def do_in_ex_clude(self,which,value,key,seen_list):
if value and which in self.in_ex_cludes:
include = 'include' in which
keyfound = False
found = False
for (line,match,condmatch) in self.in_ex_cludes[which]:
for (line,match,cond_match) in self.in_ex_cludes[which]:
keyfndnow = False
if match.in_keys(key):
if line in seen_list:
logger.info("Skipping %s key(%s) value(%s) line(%s) to prevent infinite recursion."%(which,key,value,line))
continue
# key in keys and either no conditional, or conditional matched
if condmatch == None or condmatch.is_key(key):
if cond_match == None or cond_match.is_key(key):
keyfndnow = True
else:
new_seen_list = dict(seen_list)
new_seen_list[line]=True
condval = self.getMetadata(condmatch.key(),seen_list=new_seen_list)
keyfndnow = condmatch.is_match(condval)
# print(cond_match)
condval = self.getMetadataForConditional(cond_match.key(),seen_list=new_seen_list)
keyfndnow = cond_match.is_match(condval)
# print("match:%s %s\ncond_match:%s %s\n\tkeyfound:%s\n\tfound:%s"%(
# match,value,cond_match,condval,keyfound,found))
keyfound |= keyfndnow
# print("match:%s %s\ncondmatch:%s %s\n\tkeyfound:%s\n\tfound:%s"%(
# match,value,condmatch,condval,keyfound,found))
if keyfndnow:
found = isinstance(value,basestring) and match.is_match(value)
if found:
@ -590,7 +602,8 @@ class Story(Configurable):
if cond_match and cond_match.key() != key: # prevent infinite recursion.
new_seen_list = dict(seen_list)
new_seen_list[repl_line]=True
condval = self.getMetadata(cond_match.key(),seen_list=new_seen_list)
# print(cond_match)
condval = self.getMetadataForConditional(cond_match.key(),seen_list=new_seen_list)
doreplace = condval != None and cond_match.is_match(condval)
if doreplace: