Package coprs :: Module filters
[hide private]
[frames] | no frames]

Source Code for Module coprs.filters

  1  import datetime 
  2  from six.moves.urllib.parse import urlparse 
  3  import pytz 
  4  import time 
  5   
  6  try: 
  7      import commonmark 
  8  except: 
  9      # needed for Fedora <= 29 
 10      import CommonMark as commonmark 
 11   
 12  from pygments import highlight 
 13  from pygments.lexers import get_lexer_by_name, guess_lexer 
 14  from pygments.lexers.special import TextLexer 
 15  from pygments.util import ClassNotFound 
 16  from pygments.formatters import HtmlFormatter 
 17   
 18  import humanize 
 19  import os 
 20  import re 
 21   
 22  from flask import Markup, url_for 
 23   
 24  from copr_common.enums import ModuleStatusEnum, StatusEnum 
 25  from coprs import app 
 26  from coprs import helpers 
27 28 -class CoprHtmlRenderer(commonmark.HtmlRenderer):
29 - def code_block(self, node, entering):
30 info_words = node.info.split() if node.info else [] 31 attrs = self.attrs(node) 32 lexer = None 33 34 if len(info_words) > 0 and len(info_words[0]) > 0: 35 attrs.append(['class', 'language-' + 36 commonmark.common.escape_xml(info_words[0], True)]) 37 try: 38 lexer = get_lexer_by_name(info_words[0]) 39 except ClassNotFound: 40 pass 41 42 if lexer is None: 43 try: 44 lexer = guess_lexer(node.literal) 45 except ClassNotFound: 46 lexer = TextLexer 47 48 self.cr() 49 self.tag('pre') 50 self.tag('code', attrs) 51 code = highlight(node.literal, lexer, HtmlFormatter()) 52 code = re.sub('<pre>', '', code) 53 code = re.sub('</pre>', '', code) 54 self.lit(code) 55 self.tag('/code') 56 self.tag('/pre') 57 self.cr()
58
59 60 @app.template_filter("remove_anchor") 61 -def remove_anchor(data):
62 if data: 63 data = re.sub("<.*?>", "", data) 64 data = re.sub("</a>", "", data) 65 return data 66 return None
67
68 @app.template_filter("date_from_secs") 69 -def date_from_secs(secs):
70 if secs: 71 return time.strftime("%Y-%m-%d %H:%M:%S %Z", time.gmtime(secs)) 72 73 return None
74
75 76 @app.template_filter("perm_type_from_num") 77 -def perm_type_from_num(num):
78 return helpers.PermissionEnum(num)
79
80 81 @app.template_filter("state_from_num") 82 -def state_from_num(num):
83 if num is None: 84 return "unknown" 85 return StatusEnum(num)
86
87 88 @app.template_filter("module_state_from_num") 89 -def module_state_from_num(num):
90 if num is None: 91 return "unknown" 92 return ModuleStatusEnum(num)
93
94 95 @app.template_filter("os_name_short") 96 -def os_name_short(os_name, os_version):
97 # TODO: make it models.MockChroot method or not? 98 if os_version: 99 if os_version == "rawhide": 100 return os_version 101 if os_name == "fedora": 102 return "fc.{0}".format(os_version) 103 elif os_name == "epel": 104 return "el{0}".format(os_version) 105 return os_name
106
107 108 @app.template_filter('localized_time') 109 -def localized_time(time_in, timezone):
110 """ return time shifted into timezone (and printed in ISO format) 111 112 Input is in EPOCH (seconds since epoch). 113 """ 114 if not time_in: 115 return "Not yet" 116 format_tz = "%Y-%m-%d %H:%M %Z" 117 utc_tz = pytz.timezone('UTC') 118 if timezone: 119 user_tz = pytz.timezone(timezone) 120 else: 121 user_tz = utc_tz 122 dt_aware = datetime.datetime.fromtimestamp(time_in).replace(tzinfo=utc_tz) 123 dt_my_tz = dt_aware.astimezone(user_tz) 124 return dt_my_tz.strftime(format_tz)
125
126 127 @app.template_filter('timestamp_diff') 128 -def timestamp_diff(time_in, until=None):
129 """ returns string with difference between two timestamps 130 131 Input is in EPOCH (seconds since epoch). 132 """ 133 if time_in is None: 134 return " - " 135 if until is not None: 136 now = datetime.datetime.fromtimestamp(until) 137 else: 138 now = datetime.datetime.now() 139 diff = now - datetime.datetime.fromtimestamp(time_in) 140 return str(int(diff.total_seconds()))
141
142 143 @app.template_filter('time_ago') 144 -def time_ago(time_in, until=None):
145 """ returns string saying how long ago the time on input was 146 147 Input is in EPOCH (seconds since epoch). 148 """ 149 if time_in is None: 150 return " - " 151 if until is not None: 152 now = datetime.datetime.fromtimestamp(until) 153 else: 154 now = datetime.datetime.now() 155 diff = now - datetime.datetime.fromtimestamp(time_in) 156 return humanize.naturaldelta(diff)
157
158 159 @app.template_filter("markdown") 160 -def markdown_filter(data):
161 if not data: 162 return '' 163 164 parser = commonmark.Parser() 165 renderer = CoprHtmlRenderer() 166 167 return Markup(renderer.render(parser.parse(data)))
168
169 170 @app.template_filter("pkg_name") 171 -def parse_package_name(pkg):
172 if pkg is not None: 173 return helpers.parse_package_name(os.path.basename(pkg)) 174 return pkg
175
176 177 @app.template_filter("basename") 178 -def parse_basename(pkg):
179 if pkg is not None: 180 return os.path.basename(pkg) 181 return pkg
182
183 184 @app.template_filter("build_state_description") 185 -def build_state_decoration(state):
186 187 description_map = { 188 "failed": "Build failed. See logs for more details.", 189 "succeeded": "Successfully built.", 190 "canceled": "The build has been cancelled manually.", 191 "running": "Build in progress.", 192 "pending": "Your build is waiting for a builder.", 193 "skipped": "This package has already been built previously.", 194 "starting": "Trying to acquire and configure builder for task.", 195 "importing": "Package content is being imported into DistGit.", 196 "waiting": "Task is waiting for something else to finish.", 197 "imported": "Package was successfully imported into DistGit.", 198 "forked": "Build has been forked from another build.", 199 } 200 201 return description_map.get(state, "")
202
203 204 @app.template_filter("build_source_description") 205 -def build_source_description(state):
206 description_map = { 207 "unset": "No default source", 208 "link": "External link to .spec or SRPM", 209 "upload": "SRPM or .spec file upload", 210 "scm": "Build from an SCM repository", 211 "pypi": "Build from PyPI", 212 "rubygems": "Build from RubyGems", 213 "custom": "Custom build method", 214 } 215 216 return description_map.get(state, "")
217
218 219 @app.template_filter("fix_url_https_backend") 220 -def fix_url_https_backend(url):
221 if app.config.get('REPO_NO_SSL', False): 222 return url.replace('https://', 'http://') 223 return helpers.fix_protocol_for_backend(url)
224
225 226 @app.template_filter("fix_url_https_frontend") 227 -def fix_url_https_frontend(url):
228 return helpers.fix_protocol_for_frontend(url)
229
230 @app.template_filter("repo_url") 231 -def repo_url(url):
232 """ 233 render copr://<user>/<prj> or copr://g/<group>/<prj> 234 to be rendered as copr projects pages 235 """ 236 parsed = urlparse(url) 237 if parsed.scheme == "copr": 238 owner = parsed.netloc 239 prj = parsed.path.split("/")[1] 240 if owner[0] == '@': 241 url = url_for("coprs_ns.copr_detail", group_name=owner[1:], coprname=prj) 242 else: 243 url = url_for("coprs_ns.copr_detail", username=owner, coprname=prj) 244 245 return helpers.fix_protocol_for_frontend(url)
246
247 @app.template_filter("mailto") 248 -def mailto(url):
249 return url if urlparse(url).scheme else "mailto:{}".format(url)
250