mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-11-04 03:27:00 -05:00 
			
		
		
		
	Fix #8378 (bad author sort when diacritic is used). Fix generation of teplate-functions.json
This commit is contained in:
		
						commit
						627445c0ee
					
				
							
								
								
									
										28
									
								
								resources/template-functions.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								resources/template-functions.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "contains": "def evaluate(self, formatter, kwargs, mi, locals,\n             val, test, value_if_present, value_if_not):\n    if re.search(test, val):\n        return value_if_present\n    else:\n        return value_if_not\n", 
 | 
				
			||||||
 | 
					    "divide": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x else 0)\n    y = float(y if y else 0)\n    return unicode(x / y)\n", 
 | 
				
			||||||
 | 
					    "uppercase": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return val.upper()\n", 
 | 
				
			||||||
 | 
					    "strcat": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    i = 0\n    res = ''\n    for i in range(0, len(args)):\n        res += args[i]\n    return res\n", 
 | 
				
			||||||
 | 
					    "substr": "def evaluate(self, formatter, kwargs, mi, locals, str_, start_, end_):\n    return str_[int(start_): len(str_) if int(end_) == 0 else int(end_)]\n", 
 | 
				
			||||||
 | 
					    "ifempty": "def evaluate(self, formatter, kwargs, mi, locals, val, value_if_empty):\n    if val:\n        return val\n    else:\n        return value_if_empty\n", 
 | 
				
			||||||
 | 
					    "field": "def evaluate(self, formatter, kwargs, mi, locals, name):\n    return formatter.get_value(name, [], kwargs)\n", 
 | 
				
			||||||
 | 
					    "capitalize": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return capitalize(val)\n", 
 | 
				
			||||||
 | 
					    "list_item": "def evaluate(self, formatter, kwargs, mi, locals, val, index, sep):\n    if not val:\n        return ''\n    index = int(index)\n    val = val.split(sep)\n    try:\n        return val[index]\n    except:\n        return ''\n", 
 | 
				
			||||||
 | 
					    "shorten": "def evaluate(self, formatter, kwargs, mi, locals,\n             val, leading, center_string, trailing):\n    l = max(0, int(leading))\n    t = max(0, int(trailing))\n    if len(val) > l + len(center_string) + t:\n        return val[0:l] + center_string + ('' if t == 0 else val[-t:])\n    else:\n        return val\n", 
 | 
				
			||||||
 | 
					    "re": "def evaluate(self, formatter, kwargs, mi, locals, val, pattern, replacement):\n    return re.sub(pattern, replacement, val)\n", 
 | 
				
			||||||
 | 
					    "add": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x else 0)\n    y = float(y if y else 0)\n    return unicode(x + y)\n", 
 | 
				
			||||||
 | 
					    "lookup": "def evaluate(self, formatter, kwargs, mi, locals, val, *args):\n    if len(args) == 2: # here for backwards compatibility\n        if val:\n            return formatter.vformat('{'+args[0].strip()+'}', [], kwargs)\n        else:\n            return formatter.vformat('{'+args[1].strip()+'}', [], kwargs)\n    if (len(args) % 2) != 1:\n        raise ValueError(_('lookup requires either 2 or an odd number of arguments'))\n    i = 0\n    while i < len(args):\n        if i + 1 >= len(args):\n            return formatter.vformat('{' + args[i].strip() + '}', [], kwargs)\n        if re.search(args[i], val):\n            return formatter.vformat('{'+args[i+1].strip() + '}', [], kwargs)\n        i += 2\n", 
 | 
				
			||||||
 | 
					    "template": "def evaluate(self, formatter, kwargs, mi, locals, template):\n    template = template.replace('[[', '{').replace(']]', '}')\n    return formatter.safe_format(template, kwargs, 'TEMPLATE', mi)\n", 
 | 
				
			||||||
 | 
					    "print": "def evaluate(self, formatter, kwargs, mi, locals, *args):\n    print args\n    return None\n", 
 | 
				
			||||||
 | 
					    "titlecase": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return titlecase(val)\n", 
 | 
				
			||||||
 | 
					    "test": "def evaluate(self, formatter, kwargs, mi, locals, val, value_if_set, value_not_set):\n    if val:\n        return value_if_set\n    else:\n        return value_not_set\n", 
 | 
				
			||||||
 | 
					    "eval": "def evaluate(self, formatter, kwargs, mi, locals, template):\n    from formatter import eval_formatter\n    template = template.replace('[[', '{').replace(']]', '}')\n    return eval_formatter.safe_format(template, locals, 'EVAL', None)\n", 
 | 
				
			||||||
 | 
					    "multiply": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x else 0)\n    y = float(y if y else 0)\n    return unicode(x * y)\n", 
 | 
				
			||||||
 | 
					    "subtract": "def evaluate(self, formatter, kwargs, mi, locals, x, y):\n    x = float(x if x else 0)\n    y = float(y if y else 0)\n    return unicode(x - y)\n", 
 | 
				
			||||||
 | 
					    "count": "def evaluate(self, formatter, kwargs, mi, locals, val, sep):\n    return unicode(len(val.split(sep)))\n", 
 | 
				
			||||||
 | 
					    "lowercase": "def evaluate(self, formatter, kwargs, mi, locals, val):\n    return val.lower()\n", 
 | 
				
			||||||
 | 
					    "assign": "def evaluate(self, formatter, kwargs, mi, locals, target, value):\n    locals[target] = value\n    return value\n", 
 | 
				
			||||||
 | 
					    "switch": "def evaluate(self, formatter, kwargs, mi, locals, val, *args):\n    if (len(args) % 2) != 1:\n        raise ValueError(_('switch requires an odd number of arguments'))\n    i = 0\n    while i < len(args):\n        if i + 1 >= len(args):\n            return args[i]\n        if re.search(args[i], val):\n            return args[i+1]\n        i += 2\n", 
 | 
				
			||||||
 | 
					    "strcmp": "def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):\n    v = strcmp(x, y)\n    if v < 0:\n        return lt\n    if v == 0:\n        return eq\n    return gt\n", 
 | 
				
			||||||
 | 
					    "cmp": "def evaluate(self, formatter, kwargs, mi, locals, x, y, lt, eq, gt):\n    x = float(x if x else 0)\n    y = float(y if y else 0)\n    if x < y:\n        return lt\n    if x == y:\n        return eq\n    return gt\n"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -86,9 +86,20 @@ class Resources(Command):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.info('\tCreating template-functions.json')
 | 
					        self.info('\tCreating template-functions.json')
 | 
				
			||||||
        dest = self.j(self.RESOURCES, 'template-functions.json')
 | 
					        dest = self.j(self.RESOURCES, 'template-functions.json')
 | 
				
			||||||
        function_dict = {'test': 'def test(*args): return test'}
 | 
					        function_dict = {}
 | 
				
			||||||
 | 
					        import inspect
 | 
				
			||||||
 | 
					        from calibre.utils.formatter_functions import all_builtin_functions
 | 
				
			||||||
 | 
					        for obj in all_builtin_functions:
 | 
				
			||||||
 | 
					            eval_func = inspect.getmembers(obj,
 | 
				
			||||||
 | 
					                    lambda x: inspect.ismethod(x) and x.__name__ == 'evaluate')
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                lines = [l[4:] for l in inspect.getsourcelines(eval_func[0][1])[0]]
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            lines = ''.join(lines)
 | 
				
			||||||
 | 
					            function_dict[obj.name] = lines
 | 
				
			||||||
        import json
 | 
					        import json
 | 
				
			||||||
        json.dump(function_dict, open(dest, 'wb'))
 | 
					        json.dump(function_dict, open(dest, 'wb'), indent=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean(self):
 | 
					    def clean(self):
 | 
				
			||||||
        for x in ('scripts', 'recipes', 'ebook-convert-complete'):
 | 
					        for x in ('scripts', 'recipes', 'ebook-convert-complete'):
 | 
				
			||||||
 | 
				
			|||||||
@ -730,7 +730,7 @@ class TagsModel(QAbstractItemModel): # {{{
 | 
				
			|||||||
            else:
 | 
					            else:
 | 
				
			||||||
                collapse_model = 'partition'
 | 
					                collapse_model = 'partition'
 | 
				
			||||||
                collapse_template = tweaks['categories_collapsed_popularity_template']
 | 
					                collapse_template = tweaks['categories_collapsed_popularity_template']
 | 
				
			||||||
        collapse_letter = None
 | 
					        collapse_letter = collapse_letter_sk = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i, r in enumerate(self.row_map):
 | 
					        for i, r in enumerate(self.row_map):
 | 
				
			||||||
            if self.hidden_categories and self.categories[i] in self.hidden_categories:
 | 
					            if self.hidden_categories and self.categories[i] in self.hidden_categories:
 | 
				
			||||||
@ -782,8 +782,17 @@ class TagsModel(QAbstractItemModel): # {{{
 | 
				
			|||||||
                        ts = tag.sort
 | 
					                        ts = tag.sort
 | 
				
			||||||
                        if not ts:
 | 
					                        if not ts:
 | 
				
			||||||
                            ts = ' '
 | 
					                            ts = ' '
 | 
				
			||||||
                        if upper(ts[0]) != collapse_letter:
 | 
					                        try:
 | 
				
			||||||
 | 
					                            sk = sort_key(ts)[0]
 | 
				
			||||||
 | 
					                        except:
 | 
				
			||||||
 | 
					                            sk = ts[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if sk != collapse_letter_sk:
 | 
				
			||||||
                            collapse_letter = upper(ts[0])
 | 
					                            collapse_letter = upper(ts[0])
 | 
				
			||||||
 | 
					                            try:
 | 
				
			||||||
 | 
					                                collapse_letter_sk = sort_key(collapse_letter)[0]
 | 
				
			||||||
 | 
					                            except:
 | 
				
			||||||
 | 
					                                collapse_letter_sk = collapse_letter
 | 
				
			||||||
                            sub_cat = TagTreeItem(parent=category,
 | 
					                            sub_cat = TagTreeItem(parent=category,
 | 
				
			||||||
                                     data = collapse_letter,
 | 
					                                     data = collapse_letter,
 | 
				
			||||||
                                     category_icon = category_node.icon,
 | 
					                                     category_icon = category_node.icon,
 | 
				
			||||||
 | 
				
			|||||||
@ -77,7 +77,7 @@ class FormatterFunction(object):
 | 
				
			|||||||
                                        exc_traceback)[-2:]).replace('\n', '')
 | 
					                                        exc_traceback)[-2:]).replace('\n', '')
 | 
				
			||||||
            return _('Exception ' + info)
 | 
					            return _('Exception ' + info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all_builtin_functions = []
 | 
				
			||||||
class BuiltinFormatterFunction(FormatterFunction):
 | 
					class BuiltinFormatterFunction(FormatterFunction):
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        formatter_functions.register_builtin(self)
 | 
					        formatter_functions.register_builtin(self)
 | 
				
			||||||
@ -88,6 +88,7 @@ class BuiltinFormatterFunction(FormatterFunction):
 | 
				
			|||||||
        except:
 | 
					        except:
 | 
				
			||||||
            lines = []
 | 
					            lines = []
 | 
				
			||||||
        self.program_text = ''.join(lines)
 | 
					        self.program_text = ''.join(lines)
 | 
				
			||||||
 | 
					        all_builtin_functions.append(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BuiltinStrcmp(BuiltinFormatterFunction):
 | 
					class BuiltinStrcmp(BuiltinFormatterFunction):
 | 
				
			||||||
    name = 'strcmp'
 | 
					    name = 'strcmp'
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user