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