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

Source Code for Module coprs.helpers

  1  import math 
  2  import random 
  3  import string 
  4  import urlparse 
  5  import flask 
  6   
  7  from coprs import constants 
  8   
  9  from rpmUtils.miscutils import splitFilename 
10 11 12 -def generate_api_token(size=30):
13 """ Generate a random string used as token to access the API 14 remotely. 15 16 :kwarg: size, the size of the token to generate, defaults to 30 17 chars. 18 :return: a string, the API token for the user. 19 """ 20 return ''.join(random.choice(string.ascii_lowercase) for x in range(size))
21
22 23 -class EnumType(type):
24
25 - def __call__(self, attr):
26 if isinstance(attr, int): 27 for k, v in self.vals.items(): 28 if v == attr: 29 return k 30 raise KeyError("num {0} is not mapped".format(attr)) 31 else: 32 return self.vals[attr]
33
34 35 -class PermissionEnum(object):
36 __metaclass__ = EnumType 37 vals = {"nothing": 0, "request": 1, "approved": 2} 38 39 @classmethod
40 - def choices_list(cls, without=-1):
41 return [(n, k) for k, n in cls.vals.items() if n != without]
42
43 44 -class ActionTypeEnum(object):
45 __metaclass__ = EnumType 46 vals = {"delete": 0, "rename": 1, "legal-flag": 2}
47
48 49 -class BackendResultEnum(object):
50 __metaclass__ = EnumType 51 vals = {"waiting": 0, "success": 1, "failure": 2}
52
53 54 -class RoleEnum(object):
55 __metaclass__ = EnumType 56 vals = {"user": 0, "admin": 1}
57
58 59 -class StatusEnum(object):
60 __metaclass__ = EnumType 61 vals = {"failed": 0, 62 "succeeded": 1, 63 "canceled": 2, 64 "running": 3, 65 "pending": 4, 66 "skipped": 5, # if there was this package built already 67 "starting": 6} # build picked by worker but no VM initialized
68
69 70 -class Paginator(object):
71
72 - def __init__(self, query, total_count, page=1, 73 per_page_override=None, urls_count_override=None):
74 75 self.query = query 76 self.total_count = total_count 77 self.page = page 78 self.per_page = per_page_override or constants.ITEMS_PER_PAGE 79 self.urls_count = urls_count_override or constants.PAGES_URLS_COUNT 80 self._sliced_query = None
81
82 - def page_slice(self, page):
83 return (self.per_page * (page - 1), 84 self.per_page * page)
85 86 @property
87 - def sliced_query(self):
88 if not self._sliced_query: 89 self._sliced_query = self.query[slice(*self.page_slice(self.page))] 90 return self._sliced_query
91 92 @property
93 - def pages(self):
94 return int(math.ceil(self.total_count / float(self.per_page)))
95
96 - def border_url(self, request, start):
97 if start: 98 if self.page - 1 > self.urls_count / 2: 99 return (self.url_for_other_page(request, 1), 1) 100 else: 101 if self.page < self.pages - self.urls_count / 2: 102 return (self.url_for_other_page(request, self.pages), 103 self.pages) 104 105 return None
106
107 - def get_urls(self, request):
108 left_border = self.page - self.urls_count / 2 109 left_border = 1 if left_border < 1 else left_border 110 right_border = self.page + self.urls_count / 2 111 right_border = self.pages if right_border > self.pages else right_border 112 113 return [(self.url_for_other_page(request, i), i) 114 for i in range(left_border, right_border + 1)]
115
116 - def url_for_other_page(self, request, page):
117 args = request.view_args.copy() 118 args["page"] = page 119 return flask.url_for(request.endpoint, **args)
120
121 122 -def parse_package_name(pkg):
123 """ 124 Parse package name from possibly incomplete nvra string. 125 """ 126 127 if pkg.count(".") >= 3 and pkg.count("-") >= 2: 128 return splitFilename(pkg)[0] 129 130 # doesn"t seem like valid pkg string, try to guess package name 131 result = "" 132 pkg = pkg.replace(".rpm", "").replace(".src", "") 133 134 for delim in ["-", "."]: 135 if delim in pkg: 136 parts = pkg.split(delim) 137 for part in parts: 138 if any(map(lambda x: x.isdigit(), part)): 139 return result[:-1] 140 141 result += part + "-" 142 143 return result[:-1] 144 145 return pkg
146
147 148 -def render_repo(copr, mock_chroot, url):
149 """ Render .repo file. No checks if copr or mock_chroot exists. """ 150 if mock_chroot.os_release == "fedora": 151 if mock_chroot.os_version != "rawhide": 152 mock_chroot.os_version = "$releasever" 153 154 url = urlparse.urljoin( 155 url, "{0}-{1}-{2}/".format(mock_chroot.os_release, 156 mock_chroot.os_version, "$basearch")) 157 158 #url = url.replace("http://", "https://") 159 return flask.render_template("coprs/copr.repo", copr=copr, url=url)
160
161 162 -class Serializer(object):
163
164 - def to_dict(self, options=None):
165 """ 166 Usage: 167 168 SQLAlchObject.to_dict() => returns a flat dict of the object 169 SQLAlchObject.to_dict({"foo": {}}) => returns a dict of the object 170 and will include a flat dict of object foo inside of that 171 SQLAlchObject.to_dict({"foo": {"bar": {}}, "spam": {}}) => returns 172 a dict of the object, which will include dict of foo 173 (which will include dict of bar) and dict of spam. 174 175 Options can also contain two special values: __columns_only__ 176 and __columns_except__ 177 178 If present, the first makes only specified fiels appear, 179 the second removes specified fields. Both of these fields 180 must be either strings (only works for one field) or lists 181 (for one and more fields). 182 183 SQLAlchObject.to_dict({"foo": {"__columns_except__": ["id"]}, 184 "__columns_only__": "name"}) => 185 186 The SQLAlchObject will only put its "name" into the resulting dict, 187 while "foo" all of its fields except "id". 188 189 Options can also specify whether to include foo_id when displaying 190 related foo object (__included_ids__, defaults to True). 191 This doesn"t apply when __columns_only__ is specified. 192 """ 193 194 result = {} 195 if options is None: 196 options = {} 197 columns = self.serializable_attributes 198 199 if "__columns_only__" in options: 200 columns = options["__columns_only__"] 201 else: 202 columns = set(columns) 203 if "__columns_except__" in options: 204 columns_except = options["__columns_except__"] 205 if not isinstance(options["__columns_except__"], list): 206 columns_except = [options["__columns_except__"]] 207 208 columns -= set(columns_except) 209 210 if ("__included_ids__" in options and 211 options["__included_ids__"] is False): 212 213 related_objs_ids = [ 214 r + "_id" for r, _ in options.items() 215 if not r.startswith("__")] 216 217 columns -= set(related_objs_ids) 218 219 columns = list(columns) 220 221 for column in columns: 222 result[column] = getattr(self, column) 223 224 for related, values in options.items(): 225 if hasattr(self, related): 226 result[related] = getattr(self, related).to_dict(values) 227 return result
228 229 @property
230 - def serializable_attributes(self):
231 return map(lambda x: x.name, self.__table__.columns)
232