Allow templates to get objects instead of json
This commit is contained in:
		
							parent
							
								
									232f8231e0
								
							
						
					
					
						commit
						d5bc65c8f2
					
				
					 7 changed files with 81 additions and 64 deletions
				
			
		
							
								
								
									
										20
									
								
								etiquette.py
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								etiquette.py
									
									
									
									
									
								
							|  | @ -244,10 +244,6 @@ def favicon(): | ||||||
| 
 | 
 | ||||||
| def get_album_core(albumid): | def get_album_core(albumid): | ||||||
|     album = P_album(albumid) |     album = P_album(albumid) | ||||||
|     album = jsonify.album(album) |  | ||||||
|     album['sub_albums'] = [P_album(x) for x in album['sub_albums']] |  | ||||||
|     album['sub_albums'].sort(key=lambda x: (x.title or x.id).lower()) |  | ||||||
|     album['sub_albums'] = [jsonify.album(x, minimal=True) for x in album['sub_albums']] |  | ||||||
|     return album |     return album | ||||||
| 
 | 
 | ||||||
| @site.route('/album/<albumid>') | @site.route('/album/<albumid>') | ||||||
|  | @ -258,7 +254,6 @@ def get_album_html(albumid): | ||||||
|     response = flask.render_template( |     response = flask.render_template( | ||||||
|         'album.html', |         'album.html', | ||||||
|         album=album, |         album=album, | ||||||
|         photos=album['photos'], |  | ||||||
|         session=session, |         session=session, | ||||||
|         view=request.args.get('view', 'grid'), |         view=request.args.get('view', 'grid'), | ||||||
|     ) |     ) | ||||||
|  | @ -268,6 +263,10 @@ def get_album_html(albumid): | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| def get_album_json(albumid): | def get_album_json(albumid): | ||||||
|     album = get_album_core(albumid) |     album = get_album_core(albumid) | ||||||
|  |     album = jsonify.album(album) | ||||||
|  |     album['sub_albums'] = [P_album(x) for x in album['sub_albums']] | ||||||
|  |     album['sub_albums'].sort(key=lambda x: (x.title or x.id).lower()) | ||||||
|  |     album['sub_albums'] = [jsonify.album(x, minimal=True) for x in album['sub_albums']] | ||||||
|     return jsonify.make_json_response(album) |     return jsonify.make_json_response(album) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -285,7 +284,6 @@ def get_album_tar(albumid): | ||||||
| def get_albums_core(): | def get_albums_core(): | ||||||
|     albums = P.get_albums() |     albums = P.get_albums() | ||||||
|     albums = [a for a in albums if a.parent() is None] |     albums = [a for a in albums if a.parent() is None] | ||||||
|     albums = [jsonify.album(album, minimal=True) for album in albums] |  | ||||||
|     return albums |     return albums | ||||||
| 
 | 
 | ||||||
| @site.route('/albums') | @site.route('/albums') | ||||||
|  | @ -299,6 +297,7 @@ def get_albums_html(): | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| def get_albums_json(): | def get_albums_json(): | ||||||
|     albums = get_albums_core() |     albums = get_albums_core() | ||||||
|  |     albums = [jsonify.album(album, minimal=True) for album in albums] | ||||||
|     return jsonify.make_json_response(albums) |     return jsonify.make_json_response(albums) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -338,14 +337,12 @@ def get_file(photoid): | ||||||
| 
 | 
 | ||||||
| def get_photo_core(photoid): | def get_photo_core(photoid): | ||||||
|     photo = P_photo(photoid) |     photo = P_photo(photoid) | ||||||
|     photo = jsonify.photo(photo) |  | ||||||
|     return photo |     return photo | ||||||
| 
 | 
 | ||||||
| @site.route('/photo/<photoid>', methods=['GET']) | @site.route('/photo/<photoid>', methods=['GET']) | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| def get_photo_html(photoid): | def get_photo_html(photoid): | ||||||
|     photo = get_photo_core(photoid) |     photo = get_photo_core(photoid) | ||||||
|     photo['tags'].sort(key=lambda x: x['qualified_name']) |  | ||||||
|     session = session_manager.get(request) |     session = session_manager.get(request) | ||||||
|     return flask.render_template('photo.html', photo=photo, session=session) |     return flask.render_template('photo.html', photo=photo, session=session) | ||||||
| 
 | 
 | ||||||
|  | @ -353,6 +350,7 @@ def get_photo_html(photoid): | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| def get_photo_json(photoid): | def get_photo_json(photoid): | ||||||
|     photo = get_photo_core(photoid) |     photo = get_photo_core(photoid) | ||||||
|  |     photo = jsonify.photo(photo) | ||||||
|     photo = jsonify.make_json_response(photo) |     photo = jsonify.make_json_response(photo) | ||||||
|     return photo |     return photo | ||||||
| 
 | 
 | ||||||
|  | @ -449,15 +447,14 @@ def get_search_core(): | ||||||
|     #print(search_kwargs) |     #print(search_kwargs) | ||||||
|     with warnings.catch_warnings(record=True) as catcher: |     with warnings.catch_warnings(record=True) as catcher: | ||||||
|         photos = list(P.search(**search_kwargs)) |         photos = list(P.search(**search_kwargs)) | ||||||
|         photos = [jsonify.photo(photo, include_albums=False) for photo in photos] |  | ||||||
|         warns = [str(warning.message) for warning in catcher] |         warns = [str(warning.message) for warning in catcher] | ||||||
|     #print(warns) |     #print(warns) | ||||||
| 
 | 
 | ||||||
|     # TAGS ON THIS PAGE |     # TAGS ON THIS PAGE | ||||||
|     total_tags = set() |     total_tags = set() | ||||||
|     for photo in photos: |     for photo in photos: | ||||||
|         for tag in photo['tags']: |         for tag in photo.tags(): | ||||||
|             total_tags.add(tag['qualified_name']) |             total_tags.add(tag.qualified_name()) | ||||||
|     total_tags = sorted(total_tags) |     total_tags = sorted(total_tags) | ||||||
| 
 | 
 | ||||||
|     # PREV-NEXT PAGE URLS |     # PREV-NEXT PAGE URLS | ||||||
|  | @ -515,6 +512,7 @@ def get_search_html(): | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| def get_search_json(): | def get_search_json(): | ||||||
|     search_results = get_search_core() |     search_results = get_search_core() | ||||||
|  |     search_results['photos'] = [jsonify.photo(photo, include_albums=False) for photo in search_results['photos']] | ||||||
|     #search_kwargs = search_results['search_kwargs'] |     #search_kwargs = search_results['search_kwargs'] | ||||||
|     #qualname_map = search_results['qualname_map'] |     #qualname_map = search_results['qualname_map'] | ||||||
|     include_qualname_map = request.args.get('include_map', False) |     include_qualname_map = request.args.get('include_map', False) | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ def photo(p, include_albums=True, include_tags=True): | ||||||
|         'ratio': p.ratio, |         'ratio': p.ratio, | ||||||
|         'area': p.area, |         'area': p.area, | ||||||
|         'bytes': p.bytes, |         'bytes': p.bytes, | ||||||
|         'duration_str': helpers.seconds_to_hms(p.duration) if p.duration is not None else None, |         'duration_str': p.duration_string(), | ||||||
|         'duration': p.duration, |         'duration': p.duration, | ||||||
|         'bytes_str': p.bytestring(), |         'bytes_str': p.bytestring(), | ||||||
|         'has_thumbnail': bool(p.thumbnail), |         'has_thumbnail': bool(p.thumbnail), | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								objects.py
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								objects.py
									
									
									
									
									
								
							|  | @ -367,6 +367,11 @@ class Photo(ObjectBase): | ||||||
|             self.photodb.log.debug('Committing - delete photo') |             self.photodb.log.debug('Committing - delete photo') | ||||||
|             self.photodb.commit() |             self.photodb.commit() | ||||||
| 
 | 
 | ||||||
|  |     def duration_string(self): | ||||||
|  |         if self.duration is None: | ||||||
|  |             return None | ||||||
|  |         return helpers.seconds_to_hms(self.duration) | ||||||
|  | 
 | ||||||
|     @decorators.time_me |     @decorators.time_me | ||||||
|     def generate_thumbnail(self, *, commit=True, **special): |     def generate_thumbnail(self, *, commit=True, **special): | ||||||
|         ''' |         ''' | ||||||
|  | @ -606,6 +611,11 @@ class Photo(ObjectBase): | ||||||
| 
 | 
 | ||||||
|         self.__reinit__() |         self.__reinit__() | ||||||
| 
 | 
 | ||||||
|  |     def sorted_tags(self): | ||||||
|  |         tags = self.tags() | ||||||
|  |         tags.sort(key=lambda x: x.qualified_name()) | ||||||
|  |         return tags | ||||||
|  | 
 | ||||||
|     def tags(self): |     def tags(self): | ||||||
|         ''' |         ''' | ||||||
|         Return the tags assigned to this Photo. |         Return the tags assigned to this Photo. | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| <head> | <head> | ||||||
|     {% import "photo_card.html" as photo_card %} |     {% import "photo_card.html" as photo_card %} | ||||||
|     {% import "header.html" as header %} |     {% import "header.html" as header %} | ||||||
|     <title>Album {{album["title"]}}</title> |     <title>Album {{album.title}}</title> | ||||||
|     <meta charset="UTF-8"> |     <meta charset="UTF-8"> | ||||||
|     <link rel="stylesheet" href="/static/common.css"> |     <link rel="stylesheet" href="/static/common.css"> | ||||||
| 
 | 
 | ||||||
|  | @ -24,29 +24,31 @@ p | ||||||
| <body> | <body> | ||||||
| {{header.make_header(session=session)}} | {{header.make_header(session=session)}} | ||||||
| <div id="content_body"> | <div id="content_body"> | ||||||
|     <h2>{{album["title"]}}</h2> |     <h2>{{album.title}}</h2> | ||||||
|     <p>{{album["description"]}}</p> |     <p>{{album.description}}</p> | ||||||
|     {% set parent=album["parent"] %} |     {% set parent=album.parent() %} | ||||||
|     {% if parent %} |     {% if parent %} | ||||||
|     <h3>Parent: <a href="/album/{{parent["id"]}}">{{parent["id"] + " " + parent.title}}</a></h3> |     <h3>Parent: <a href="/album/{{parent.id}}">{{parent.id + " " + parent.title}}</a></h3> | ||||||
|     {% else %} |     {% else %} | ||||||
|     <h3>Parent: <a href="/albums">Albums</a></h3> |     <h3>Parent: <a href="/albums">Albums</a></h3> | ||||||
|     {% endif %} |     {% endif %} | ||||||
|     {% if album["sub_albums"] %} |     {% set sub_albums = album.children() %} | ||||||
|  |     {% if sub_albums %} | ||||||
|     <h3>Sub-albums</h3> |     <h3>Sub-albums</h3> | ||||||
|     <ul> |     <ul> | ||||||
|         {% for sub_album in album["sub_albums"] %} |         {% for sub_album in sub_albums %} | ||||||
|         <li><a href="/album/{{sub_album["id"]}}"> |         <li><a href="/album/{{sub_album.id}}"> | ||||||
|             {% if sub_album["title"] %} |             {% if sub_album.title %} | ||||||
|             {{sub_album["title"]}} |             {{sub_album.title}} | ||||||
|             {% else %} |             {% else %} | ||||||
|             {{sub_album["id"]}} |             {{sub_album.id}} | ||||||
|             {% endif %}</a> |             {% endif %}</a> | ||||||
|         </li> |         </li> | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
|     </ul> |     </ul> | ||||||
|     {% endif %} |     {% endif %} | ||||||
|     <span><a href="/album/{{album["id"]}}.tar">(download .tar)</a></span> |     <span><a href="/album/{{album.id}}.tar">(download .tar)</a></span> | ||||||
|  |     {% set photos = album.photos() %} | ||||||
|     {% if photos %} |     {% if photos %} | ||||||
|     <h3>Photos</h3> |     <h3>Photos</h3> | ||||||
|     <ul> |     <ul> | ||||||
|  | @ -62,7 +64,7 @@ p | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
| function submit_tag(callback) | function submit_tag(callback) | ||||||
| { | { | ||||||
|     add_photo_tag('{{album["id"]}}', add_tag_box.value, callback); |     add_photo_tag('{{album.id}}', add_tag_box.value, callback); | ||||||
|     add_tag_box.value = ""; |     add_tag_box.value = ""; | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -19,12 +19,12 @@ | ||||||
| {{header.make_header(session=session)}} | {{header.make_header(session=session)}} | ||||||
| <div id="content_body"> | <div id="content_body"> | ||||||
|     {% for album in albums %} |     {% for album in albums %} | ||||||
|     {% if album["title"] %} |     {% if album.title %} | ||||||
|     {% set title=album["id"] + " " + album["title"] %} |     {% set title=album.id + " " + album.title %} | ||||||
|     {% else %} |     {% else %} | ||||||
|     {% set title=album["id"] %} |     {% set title=album.id %} | ||||||
|     {% endif %} |     {% endif %} | ||||||
|     <div><a href="/album/{{album["id"]}}">{{album["id"] + " " + album["title"]}}</a></div> |     <div><a href="/album/{{album.id}}">{{album.id + " " + album.title}}</a></div> | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
| </div> | </div> | ||||||
| </body> | </body> | ||||||
|  |  | ||||||
|  | @ -6,9 +6,9 @@ | ||||||
|     <meta charset="UTF-8"> |     <meta charset="UTF-8"> | ||||||
|     <link rel="stylesheet" href="/static/common.css"> |     <link rel="stylesheet" href="/static/common.css"> | ||||||
|     <script src="/static/common.js"></script> |     <script src="/static/common.js"></script> | ||||||
|     {% set filename = photo["id"] + "." + photo["extension"] %} |     {% set filename = photo.id + "." + photo.extension %} | ||||||
|     {% set link = "/file/" + filename %} |     {% set link = "/file/" + filename %} | ||||||
|     {% set mimetype=photo["mimetype"] %} |     {% set mimetype=photo.mimetype() %} | ||||||
| 
 | 
 | ||||||
| <style> | <style> | ||||||
| #content_body | #content_body | ||||||
|  | @ -94,10 +94,11 @@ | ||||||
|         <!-- TAG INFO --> |         <!-- TAG INFO --> | ||||||
|         <h4>Tags</h4> |         <h4>Tags</h4> | ||||||
|         <ul id="this_tags"> |         <ul id="this_tags"> | ||||||
|             {% for tag in photo['tags'] %} |             {% set tags = photo.sorted_tags() %} | ||||||
|  |             {% for tag in tags %} | ||||||
|             <li> |             <li> | ||||||
|                 <a class="tag_object" href="/search?tag_musts={{tag["name"]}}">{{tag["qualified_name"]}}</a> |                 <a class="tag_object" href="/search?tag_musts={{tag.name}}">{{tag.qualified_name()}}</a> | ||||||
|                 <button class="remove_tag_button" onclick="remove_photo_tag('{{photo["id"]}}', '{{tag["name"]}}', receive_callback);"></button> |                 <button class="remove_tag_button" onclick="remove_photo_tag('{{photo.id}}', '{{tag.name}}', receive_callback);"></button> | ||||||
|             </li> |             </li> | ||||||
|             {% endfor %} |             {% endfor %} | ||||||
|             <li> |             <li> | ||||||
|  | @ -109,24 +110,29 @@ | ||||||
|         <!-- METADATA & DOWNLOAD --> |         <!-- METADATA & DOWNLOAD --> | ||||||
|         <h4>File info</h4> |         <h4>File info</h4> | ||||||
|         <ul id="metadata"> |         <ul id="metadata"> | ||||||
|         {% if photo["width"] %} |         {% if photo.author_id %} | ||||||
|             <li>Dimensions: {{photo["width"]}}x{{photo["height"]}} px</li> |             {% set author = photo.author() %} | ||||||
|             <li>Aspect ratio: {{photo["ratio"]}}</li> |             <li>Author: <a href="/user/{{author.username}}">{{author.username}}</a> | ||||||
|             <li>Size: {{photo["bytes_str"]}}</li> |  | ||||||
|         {% endif %} |         {% endif %} | ||||||
|         {% if photo["duration"] %} |         {% if photo.width %} | ||||||
|             <li>Duration: {{photo["duration_str"]}}</li> |             <li>Dimensions: {{photo.width}}x{{photo.height}} px</li> | ||||||
|  |             <li>Aspect ratio: {{photo.ratio}}</li> | ||||||
|  |             <li>Size: {{photo.bytestring()}}</li> | ||||||
|         {% endif %} |         {% endif %} | ||||||
|             <li><a href="/file/{{photo["id"]}}.{{photo["extension"]}}?download=1">Download as {{photo["id"]}}.{{photo["extension"]}}</a></li> |         {% if photo.duration %} | ||||||
|             <li><a href="/file/{{photo["id"]}}.{{photo["extension"]}}?download=1&original_filename=1">Download as "{{photo["filename"]}}"</a></li> |             <li>Duration: {{photo.duration_str}}</li> | ||||||
|  |         {% endif %} | ||||||
|  |             <li><a href="/file/{{photo.id}}.{{photo.extension}}?download=1">Download as {{photo.id}}.{{photo.extension}}</a></li> | ||||||
|  |             <li><a href="/file/{{photo.id}}.{{photo.extension}}?download=1&original_filename=1">Download as "{{photo.basename}}"</a></li> | ||||||
|         </ul> |         </ul> | ||||||
| 
 | 
 | ||||||
|         <!-- CONTAINING ALBUMS --> |         <!-- CONTAINING ALBUMS --> | ||||||
|         {% if photo["albums"] %} |         {% set albums = photo.albums() %} | ||||||
|  |         {% if albums %} | ||||||
|         <h4>Albums containing this photo</h4> |         <h4>Albums containing this photo</h4> | ||||||
|         <ul id="containing albums"> |         <ul id="containing albums"> | ||||||
|             {% for album in photo["albums"] %} |             {% for album in albums %} | ||||||
|             <li><a href="/album/{{album["id"]}}">{{album["title"]}}</a></li> |             <li><a href="/album/{{album.id}}">{{album.title}}</a></li> | ||||||
|             {% endfor %} |             {% endfor %} | ||||||
|         {% endif %} |         {% endif %} | ||||||
|         </ul> |         </ul> | ||||||
|  | @ -142,7 +148,7 @@ | ||||||
|         <div id="photo_img_holder"><img id="photo_img" src="{{link}}" onclick="toggle_hoverzoom()" onload="this.style.opacity=0.99"></div> |         <div id="photo_img_holder"><img id="photo_img" src="{{link}}" onclick="toggle_hoverzoom()" onload="this.style.opacity=0.99"></div> | ||||||
|         <!-- <img src="{{link}}"> --> |         <!-- <img src="{{link}}"> --> | ||||||
|         {% elif mimetype == "video" %} |         {% elif mimetype == "video" %} | ||||||
|         <video src="{{link}}" controls preload=none {%if photo["has_thumbnail"]%}poster="/thumbnail/{{photo["id"]}}.jpg"{%endif%}></video> |         <video src="{{link}}" controls preload=none {%if photo.thumbnail%}poster="/thumbnail/{{photo.id}}.jpg"{%endif%}></video> | ||||||
|         {% elif mimetype == "audio" %} |         {% elif mimetype == "audio" %} | ||||||
|         <audio src="{{link}}" controls></audio> |         <audio src="{{link}}" controls></audio> | ||||||
|         {% else %} |         {% else %} | ||||||
|  | @ -261,7 +267,7 @@ function receive_callback(response) | ||||||
| } | } | ||||||
| function submit_tag(callback) | function submit_tag(callback) | ||||||
| { | { | ||||||
|     add_photo_tag('{{photo["id"]}}', add_tag_box.value, callback); |     add_photo_tag('{{photo.id}}', add_tag_box.value, callback); | ||||||
|     add_tag_box.value = ""; |     add_tag_box.value = ""; | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -16,20 +16,20 @@ | ||||||
| 
 | 
 | ||||||
| {% if view == "list" %} | {% if view == "list" %} | ||||||
| <div class="photo_card_list"> | <div class="photo_card_list"> | ||||||
|     <a target="_blank" href="/photo/{{photo["id"]}}">{{photo["filename"]}}</a> |     <a target="_blank" href="/photo/{{photo.id}}">{{photo.basename}}</a> | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| {% else %} | {% else %} | ||||||
| <div class="photo_card_grid"> | <div class="photo_card_grid"> | ||||||
|     <div class="photo_card_grid_thumb"> |     <div class="photo_card_grid_thumb"> | ||||||
|         <a target="_blank" href="/photo/{{photo["id"]}}"> |         <a target="_blank" href="/photo/{{photo.id}}"> | ||||||
|             <img height="150" |             <img height="150" | ||||||
|             {% if photo["has_thumbnail"] %} |             {% if photo.thumbnail %} | ||||||
|                 src="/thumbnail/{{photo["id"]}}.jpg" |                 src="/thumbnail/{{photo.id}}.jpg" | ||||||
|             {% else %} |             {% else %} | ||||||
|                 {% set choice = |                 {% set choice = | ||||||
|                     thumbnails.get(photo["extension"], |                     thumbnails.get(photo.extension, | ||||||
|                     thumbnails.get(photo["mimetype"], |                     thumbnails.get(photo.mimetype, | ||||||
|                     'other')) |                     'other')) | ||||||
|                 %} |                 %} | ||||||
|                 src="/static/basic_thumbnails/{{choice}}.png" |                 src="/static/basic_thumbnails/{{choice}}.png" | ||||||
|  | @ -37,23 +37,24 @@ | ||||||
|         </a> |         </a> | ||||||
|     </div> |     </div> | ||||||
|     <div class="photo_card_grid_info"> |     <div class="photo_card_grid_info"> | ||||||
|         <a target="_blank" href="/photo/{{photo["id"]}}">{{photo["filename"]}}</a> |         <a target="_blank" href="/photo/{{photo.id}}">{{photo.basename}}</a> | ||||||
|         <span class="photo_card_grid_file_metadata"> |         <span class="photo_card_grid_file_metadata"> | ||||||
|         {% if photo["width"] %} |         {% if photo.width %} | ||||||
|             {{photo["width"]}}x{{photo["height"]}}, |             {{photo.width}}x{{photo.height}}, | ||||||
|         {% endif %} |         {% endif %} | ||||||
|         {% if photo["duration"] %} |         {% if photo.duration %} | ||||||
|             {{photo["duration_str"]}}, |             {{photo.duration_string()}}, | ||||||
|         {% endif %} |         {% endif %} | ||||||
|         {{photo["bytes_str"]}} |         {{photo.bytestring()}} | ||||||
|         </span> |         </span> | ||||||
|         <span class="photo_card_grid_tags"> |         <span class="photo_card_grid_tags"> | ||||||
|             {% if photo["tags"] %} |             {% set tags = photo.tags() %} | ||||||
|             {% set tags=[] %} |             {% set tag_names = [] %} | ||||||
|             {% for tag in photo["tags"] %} |             {% for tag in tags %} | ||||||
|             {% do tags.append(tag["name"]) %} |             {% do tag_names.append(tag.name) %} | ||||||
|             {% endfor %} |             {% endfor %} | ||||||
|             <span title="{{", ".join(tags)}}">T</span> |             {% if tags %} | ||||||
|  |                 <span title="{{", ".join(tag_names)}}">T</span> | ||||||
|             {% endif %} |             {% endif %} | ||||||
|         </span> |         </span> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue