Move export functions to their own module.
This commit is contained in:
		
							parent
							
								
									4f03815a30
								
							
						
					
					
						commit
						821a5f3371
					
				
					 6 changed files with 105 additions and 89 deletions
				
			
		|  | @ -20,7 +20,6 @@ Documentation is still a work in progress. In general, I use: | ||||||
| - Debate whether the `UserMixin.login` method should accept usernames or I should standardize the usage of IDs only internally. | - Debate whether the `UserMixin.login` method should accept usernames or I should standardize the usage of IDs only internally. | ||||||
| - Ability to access user page and user photos by user's ID, not just username. | - Ability to access user page and user photos by user's ID, not just username. | ||||||
| - Should album size be cached on disk? | - Should album size be cached on disk? | ||||||
| - Organize the tag exporter functions better. |  | ||||||
| - Replace columns like area, ratio, bitrate by using expression indices or views (`width * height` etc). | - Replace columns like area, ratio, bitrate by using expression indices or views (`width * height` etc). | ||||||
| - Add some way to support large image albums without flooding the search results. Considering a "hidden" property so that a handful of representative images can appear in the search results, and the rest can be found on the actual Album page. | - Add some way to support large image albums without flooding the search results. Considering a "hidden" property so that a handful of representative images can appear in the search results, and the rest can be found on the actual Album page. | ||||||
| - Add a `Photo.merge` to combine duplicate entries. | - Add a `Photo.merge` to combine duplicate entries. | ||||||
|  |  | ||||||
|  | @ -6,3 +6,4 @@ from . import jsonify | ||||||
| from . import objects | from . import objects | ||||||
| from . import photodb | from . import photodb | ||||||
| from . import searchhelpers | from . import searchhelpers | ||||||
|  | from . import tag_export | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ from . import exceptions | ||||||
| from . import helpers | from . import helpers | ||||||
| from . import objects | from . import objects | ||||||
| from . import searchhelpers | from . import searchhelpers | ||||||
|  | from . import tag_export | ||||||
| 
 | 
 | ||||||
| from voussoirkit import cacheclass | from voussoirkit import cacheclass | ||||||
| from voussoirkit import expressionmatch | from voussoirkit import expressionmatch | ||||||
|  | @ -176,76 +177,6 @@ def searchfilter_must_may_forbid(photo_tags, tag_musts, tag_mays, tag_forbids, f | ||||||
| 
 | 
 | ||||||
|     return True |     return True | ||||||
| 
 | 
 | ||||||
| def tag_export_easybake(tags, depth=0): |  | ||||||
|     lines = [] |  | ||||||
|     for tag in tags: |  | ||||||
|         if not hasattr(tag, 'string'): |  | ||||||
|             tag.string = tag.name |  | ||||||
|         children = tag.children() |  | ||||||
|         synonyms = tag.synonyms() |  | ||||||
|         lines.append(tag.string) |  | ||||||
| 
 |  | ||||||
|         for synonym in synonyms: |  | ||||||
|             synonym = tag.string + '+' + synonym |  | ||||||
|             lines.append(synonym) |  | ||||||
| 
 |  | ||||||
|         for child in children: |  | ||||||
|             child.string = tag.string + '.' + child.name |  | ||||||
|         child_bake = tag_export_easybake(children, depth=depth+1) |  | ||||||
|         if child_bake != '': |  | ||||||
|             lines.append(child_bake) |  | ||||||
| 
 |  | ||||||
|     lines = '\n'.join(lines) |  | ||||||
|     return lines |  | ||||||
| 
 |  | ||||||
| def tag_export_json(tags): |  | ||||||
|     def fill(tag): |  | ||||||
|         children = {child.name:fill(child) for child in tag.children()} |  | ||||||
|         return children |  | ||||||
|     result = {} |  | ||||||
|     for tag in tags: |  | ||||||
|         result[tag.name] = fill(tag) |  | ||||||
|     return result |  | ||||||
| 
 |  | ||||||
| def tag_export_qualname_map(tags): |  | ||||||
|     lines = tag_export_easybake(tags) |  | ||||||
|     lines = lines.split('\n') |  | ||||||
|     lines = [line for line in lines if line] |  | ||||||
|     qualname_map = {} |  | ||||||
|     for line in lines: |  | ||||||
|         key = line.split('.')[-1].split('+')[-1] |  | ||||||
|         value = line.split('+')[0] |  | ||||||
|         qualname_map[key] = value |  | ||||||
|     return qualname_map |  | ||||||
| 
 |  | ||||||
| def tag_export_stdout(tags, depth=0): |  | ||||||
|     for tag in tags: |  | ||||||
|         children = tag.children() |  | ||||||
|         synonyms = tag.synonyms() |  | ||||||
| 
 |  | ||||||
|         pad = '    ' * depth |  | ||||||
|         synpad = '    ' * (depth + 1) |  | ||||||
|         print(pad + str(tag)) |  | ||||||
| 
 |  | ||||||
|         for synonym in synonyms: |  | ||||||
|             print(synpad + synonym) |  | ||||||
| 
 |  | ||||||
|         tag_export_stdout(children, depth=depth+1) |  | ||||||
| 
 |  | ||||||
|         if tag.parent() is None: |  | ||||||
|             print() |  | ||||||
| 
 |  | ||||||
| @decorators.time_me |  | ||||||
| def tag_export_totally_flat(tags): |  | ||||||
|     result = {} |  | ||||||
|     for tag in tags: |  | ||||||
|         for child in tag.walk_children(): |  | ||||||
|             children = list(child.walk_children()) |  | ||||||
|             result[child] = children |  | ||||||
|             for synonym in child.synonyms(): |  | ||||||
|                 result[synonym] = children |  | ||||||
|     return result |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| #################################################################################################### | #################################################################################################### | ||||||
| #################################################################################################### | #################################################################################################### | ||||||
|  | @ -725,7 +656,7 @@ class PDBPhotoMixin: | ||||||
|             if self._cached_frozen_children: |             if self._cached_frozen_children: | ||||||
|                 frozen_children = self._cached_frozen_children |                 frozen_children = self._cached_frozen_children | ||||||
|             else: |             else: | ||||||
|                 frozen_children = self.export_tags(tag_export_totally_flat) |                 frozen_children = tag_export.flat_dict(self.get_tags()) | ||||||
|                 self._cached_frozen_children = frozen_children |                 self._cached_frozen_children = frozen_children | ||||||
|         else: |         else: | ||||||
|             frozen_children = None |             frozen_children = None | ||||||
|  | @ -916,20 +847,6 @@ class PDBTagMixin: | ||||||
|         super().__init__() |         super().__init__() | ||||||
|         self._tag_cache = cacheclass.Cache() |         self._tag_cache = cacheclass.Cache() | ||||||
| 
 | 
 | ||||||
|     def export_tags(self, exporter=tag_export_stdout, specific_tag=None): |  | ||||||
|         ''' |  | ||||||
|         Send the top-level tags to function `exporter`. |  | ||||||
|         Strings 'start' and 'stop' are sent before and after the tags are sent. |  | ||||||
|         Recursion is to be handled by the exporter. |  | ||||||
|         ''' |  | ||||||
|         if specific_tag is None: |  | ||||||
|             items = list(self.get_tags()) |  | ||||||
|             items = [item for item in items if item.parent() is None] |  | ||||||
|             items.sort(key=lambda x: x.name) |  | ||||||
|         else: |  | ||||||
|             items = [self.get_tag(specific_tag)] |  | ||||||
|         return exporter(items) |  | ||||||
| 
 |  | ||||||
|     def get_tag(self, name=None, id=None): |     def get_tag(self, name=None, id=None): | ||||||
|         ''' |         ''' | ||||||
|         Redirect to get_tag_by_id or get_tag_by_name after xor-checking the parameters. |         Redirect to get_tag_by_id or get_tag_by_name after xor-checking the parameters. | ||||||
|  |  | ||||||
							
								
								
									
										98
									
								
								etiquette/tag_export.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								etiquette/tag_export.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,98 @@ | ||||||
|  | def easybake(tags): | ||||||
|  |     ''' | ||||||
|  |     A string where every line is the qualified name of a tag or its synonyms. | ||||||
|  | 
 | ||||||
|  |     people | ||||||
|  |     people.family | ||||||
|  |     people.family.mother | ||||||
|  |     people.family.mother+mom | ||||||
|  |     ''' | ||||||
|  |     lines = [] | ||||||
|  |     tags = list(tags) | ||||||
|  |     for tag in tags: | ||||||
|  |         qualname = tag.qualified_name() | ||||||
|  |         lines.append(qualname) | ||||||
|  |         lines.extend(qualname + '+' + syn for syn in tag.synonyms()) | ||||||
|  |     return '\n'.join(lines) | ||||||
|  | 
 | ||||||
|  | def flat_dict(tags): | ||||||
|  |     ''' | ||||||
|  |     A dictionary where every tag is its own key, and the value is a list | ||||||
|  |     containing itself all of its nested children. | ||||||
|  |     Synonyms not included. | ||||||
|  | 
 | ||||||
|  |     { | ||||||
|  |         people: [people, family, mother], | ||||||
|  |         family: [family, mother], | ||||||
|  |         mother: [mother], | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     The list contains itself so that you can quickly ask whether a user's | ||||||
|  |     requested tag exists in that tree without having to write separate checks | ||||||
|  |     for equaling the main tag versus existing in the rest of the subtree. | ||||||
|  |     ''' | ||||||
|  |     result = {} | ||||||
|  |     for tag in tags: | ||||||
|  |         for child in tag.walk_children(): | ||||||
|  |             children = list(child.walk_children()) | ||||||
|  |             result[child] = children | ||||||
|  |             for synonym in child.synonyms(): | ||||||
|  |                 result[synonym] = children | ||||||
|  |     return result | ||||||
|  | 
 | ||||||
|  | def nested_dict(tags): | ||||||
|  |     ''' | ||||||
|  |     A dictionary where keys are tags, values are recursive dictionaries | ||||||
|  |     of children. | ||||||
|  |     Synonyms not included. | ||||||
|  | 
 | ||||||
|  |     { | ||||||
|  |         people: { | ||||||
|  |             family: { | ||||||
|  |                 mother: {} | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     ''' | ||||||
|  |     result = {} | ||||||
|  |     for tag in tags: | ||||||
|  |         result[tag] = nested_dict(tag) | ||||||
|  | 
 | ||||||
|  |     return result | ||||||
|  | 
 | ||||||
|  | def qualified_names(tags): | ||||||
|  |     ''' | ||||||
|  |     A dictionary where keys are string names, values are qualified names. | ||||||
|  |     Synonyms included. | ||||||
|  | 
 | ||||||
|  |     { | ||||||
|  |         'people': 'people', | ||||||
|  |         'family': 'people.family', | ||||||
|  |         'mother': 'people.family.mother', | ||||||
|  |         'mom': 'people.family.mother', | ||||||
|  |     } | ||||||
|  |     ''' | ||||||
|  |     results = {} | ||||||
|  |     for tag in tags: | ||||||
|  |         qualname = tag.qualified_name() | ||||||
|  |         results[tag.name] = qualname | ||||||
|  |         for synonym in tag.synonyms(): | ||||||
|  |             results[synonym] = qualname | ||||||
|  |     return results | ||||||
|  | 
 | ||||||
|  | def stdout(tags, depth=0): | ||||||
|  |     for tag in tags: | ||||||
|  |         children = tag.children() | ||||||
|  |         synonyms = tag.synonyms() | ||||||
|  | 
 | ||||||
|  |         pad = '    ' * depth | ||||||
|  |         print(pad + tag.name) | ||||||
|  | 
 | ||||||
|  |         synpad = '    ' * (depth + 1) | ||||||
|  |         for synonym in synonyms: | ||||||
|  |             print(synpad + '+' + synonym) | ||||||
|  | 
 | ||||||
|  |         stdout(children, depth=depth+1) | ||||||
|  | 
 | ||||||
|  |         if tag.parent() is None: | ||||||
|  |             print() | ||||||
|  | @ -565,7 +565,7 @@ def get_search_core(): | ||||||
| def get_search_html(): | def get_search_html(): | ||||||
|     search_results = get_search_core() |     search_results = get_search_core() | ||||||
|     search_kwargs = search_results['search_kwargs'] |     search_kwargs = search_results['search_kwargs'] | ||||||
|     qualname_map = P.export_tags(exporter=etiquette.photodb.tag_export_qualname_map) |     qualname_map = etiquette.tag_export.qualified_names(P.get_tags()) | ||||||
|     session = session_manager.get(request) |     session = session_manager.get(request) | ||||||
|     response = flask.render_template( |     response = flask.render_template( | ||||||
|         'search.html', |         'search.html', | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| # Use with | # Use with | ||||||
| # py -i etiquette_easy.py | # py -i etiquette_easy.py | ||||||
| 
 | 
 | ||||||
| import etiquette.photodb | import etiquette | ||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
|  | 
 | ||||||
| P = etiquette.photodb.PhotoDB() | P = etiquette.photodb.PhotoDB() | ||||||
| import traceback | import traceback | ||||||
| 
 | 
 | ||||||
|  | @ -13,7 +14,7 @@ def easytagger(): | ||||||
|         if i.startswith('?'): |         if i.startswith('?'): | ||||||
|             i = i.split('?')[1] or None |             i = i.split('?')[1] or None | ||||||
|             try: |             try: | ||||||
|                 P.export_tags(specific_tag=i) |                 etiquette.tag_export.stdout([P.get_tag(i)]) | ||||||
|             except: |             except: | ||||||
|                 traceback.print_exc() |                 traceback.print_exc() | ||||||
|         else: |         else: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue