def to_url(self, value): if isinstance(value, str) and value in Brother.__members__: return url_quote(value) elif isinstance(value, enum.Enum) and value in Brother: return url_quote(value.name) else: return url_quote('oso')
def to_url(self, value): if isinstance(value, str) and value in NormalCouple.__members__: return url_quote(value) elif isinstance(value, enum.Enum) and value in NormalCouple: return url_quote(value.name) else: return url_quote('chyoukei')
def to_url(self, value): if isinstance(value, str) and value in Nickname.subdomains(): return url_quote(value) elif isinstance(value, enum.Enum) and value in Nickname: return url_quote(value.subdomain) else: return url_quote('lesser.oso')
def test_quoting(self): assert urls.url_quote(u'\xf6\xe4\xfc') == '%C3%B6%C3%A4%C3%BC' assert urls.url_unquote(urls.url_quote(u'#%="\xf6')) == u'#%="\xf6' assert urls.url_quote_plus('foo bar') == 'foo+bar' assert urls.url_unquote_plus('foo+bar') == 'foo bar' assert urls.url_encode({'a': None, 'b': 'foo bar'}) == 'b=foo+bar' assert urls.url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)') == \ 'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
def test_quoting(self): self.assert_strict_equal(urls.url_quote(u'\xf6\xe4\xfc'), '%C3%B6%C3%A4%C3%BC') self.assert_strict_equal(urls.url_unquote(urls.url_quote(u'#%="\xf6')), u'#%="\xf6') self.assert_strict_equal(urls.url_quote_plus('foo bar'), 'foo+bar') self.assert_strict_equal(urls.url_unquote_plus('foo+bar'), u'foo bar') self.assert_strict_equal(urls.url_encode({b'a': None, b'b': b'foo bar'}), 'b=foo+bar') self.assert_strict_equal(urls.url_encode({u'a': None, u'b': u'foo bar'}), 'b=foo+bar') self.assert_strict_equal(urls.url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)'), 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)')
def match(self, path_info = None, method = None, return_rule = False): self.map.update() if path_info is None: path_info = self.path_info if not isinstance(path_info, unicode): path_info = path_info.decode(self.map.charset, 'ignore') method = (method or self.default_method).upper() path = u'%s|/%s' % (self.subdomain, path_info.lstrip('/')) have_match_for = set() for rule in self.map._rules: try: rv = rule.match(path) except RequestSlash: raise RequestRedirect(str('%s://%s%s%s/%s/' % (self.url_scheme, self.subdomain and self.subdomain + '.' or '', self.server_name, self.script_name[:-1], url_quote(path_info.lstrip('/'), self.map.charset)))) if rv is None: continue if rule.methods is not None and method not in rule.methods: have_match_for.update(rule.methods) continue if self.map.redirect_defaults: for r in self.map._rules_by_endpoint[rule.endpoint]: if r.provides_defaults_for(rule) and r.suitable_for(rv, method): rv.update(r.defaults) subdomain, path = r.build(rv) raise RequestRedirect(str('%s://%s%s%s/%s' % (self.url_scheme, subdomain and subdomain + '.' or '', self.server_name, self.script_name[:-1], url_quote(path.lstrip('/'), self.map.charset)))) if rule.redirect_to is not None: if isinstance(rule.redirect_to, basestring): def _handle_match(match): value = rv[match.group(1)] return rule._converters[match.group(1)].to_url(value) redirect_url = _simple_rule_re.sub(_handle_match, rule.redirect_to) else: redirect_url = rule.redirect_to(self, **rv) raise RequestRedirect(str(urljoin('%s://%s%s%s' % (self.url_scheme, self.subdomain and self.subdomain + '.' or '', self.server_name, self.script_name), redirect_url))) if return_rule: return (rule, rv) return (rule.endpoint, rv) if have_match_for: raise MethodNotAllowed(valid_methods=list(have_match_for)) raise NotFound()
def test_quoting(self): assert urls.url_quote(u"\xf6\xe4\xfc") == "%C3%B6%C3%A4%C3%BC" assert urls.url_unquote(urls.url_quote(u'#%="\xf6')) == u'#%="\xf6' assert urls.url_quote_plus("foo bar") == "foo+bar" assert urls.url_unquote_plus("foo+bar") == "foo bar" assert urls.url_encode({"a": None, "b": "foo bar"}) == "b=foo+bar" assert ( urls.url_fix(u"http://de.wikipedia.org/wiki/Elf (Begriffsklärung)") == "http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29" )
def get_current_url(environ, root_only=False, strip_querystring=False, host_only=False, trusted_hosts=None): """A handy helper function that recreates the full URL for the current request or parts of it. Here an example: >>> from werkzeug.test import create_environ >>> env = create_environ("/?param=foo", "http://localhost/script") >>> get_current_url(env) 'http://localhost/script/?param=foo' >>> get_current_url(env, root_only=True) 'http://localhost/script/' >>> get_current_url(env, host_only=True) 'http://localhost/' >>> get_current_url(env, strip_querystring=True) 'http://localhost/script/' This optionally it verifies that the host is in a list of trusted hosts. If the host is not in there it will raise a :exc:`~werkzeug.exceptions.SecurityError`. :param environ: the WSGI environment to get the current URL from. :param root_only: set `True` if you only want the root URL. :param strip_querystring: set to `True` if you don't want the querystring. :param host_only: set to `True` if the host URL should be returned. :param trusted_hosts: a list of trusted hosts, see :func:`host_is_trusted` for more information. """ from werkzeug.urls import uri_to_iri tmp = [environ['wsgi.url_scheme'], '://', get_host(environ, trusted_hosts)] cat = tmp.append if host_only: return uri_to_iri(''.join(tmp) + '/') cat(urls.url_quote(environ.get('SCRIPT_NAME', '').rstrip('/'))) if root_only: cat('/') else: cat(urls.url_quote('/' + environ.get('PATH_INFO', '').lstrip('/'))) if not strip_querystring: qs = environ.get('QUERY_STRING') if qs: # QUERY_STRING really should be ascii safe but some browsers # will send us some unicode stuff (I am looking at you IE). # In that case we want to urllib quote it badly. try: if hasattr(qs, 'decode'): qs.decode('ascii') else: qs.encode('ascii') except UnicodeError: qs = ''.join(x > 127 and '%%%02X' % x or c for x, c in ((ord(x), x) for x in qs)) cat('?' + qs) return uri_to_iri(''.join(tmp))
def test_quoting(): strict_eq(urls.url_quote(u'\xf6\xe4\xfc'), '%C3%B6%C3%A4%C3%BC') strict_eq(urls.url_unquote(urls.url_quote(u'#%="\xf6')), u'#%="\xf6') strict_eq(urls.url_quote_plus('foo bar'), 'foo+bar') strict_eq(urls.url_unquote_plus('foo+bar'), u'foo bar') strict_eq(urls.url_quote_plus('foo+bar'), 'foo%2Bbar') strict_eq(urls.url_unquote_plus('foo%2Bbar'), u'foo+bar') strict_eq(urls.url_encode({b'a': None, b'b': b'foo bar'}), 'b=foo+bar') strict_eq(urls.url_encode({u'a': None, u'b': u'foo bar'}), 'b=foo+bar') strict_eq(urls.url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)'), 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)') strict_eq(urls.url_quote_plus(42), '42') strict_eq(urls.url_quote(b'\xff'), '%FF')
def get_current_url(environ, root_only=False, strip_querystring=False, host_only=False, trusted_hosts=None): """A handy helper function that recreates the full URL as IRI for the current request or parts of it. Here an example: >>> from werkzeug.test import create_environ >>> env = create_environ("/?param=foo", "http://localhost/script") >>> get_current_url(env) 'http://localhost/script/?param=foo' >>> get_current_url(env, root_only=True) 'http://localhost/script/' >>> get_current_url(env, host_only=True) 'http://localhost/' >>> get_current_url(env, strip_querystring=True) 'http://localhost/script/' This optionally it verifies that the host is in a list of trusted hosts. If the host is not in there it will raise a :exc:`~werkzeug.exceptions.SecurityError`. Note that the string returned might contain unicode characters as the representation is an IRI not an URI. If you need an ASCII only representation you can use the :func:`~werkzeug.urls.iri_to_uri` function: >>> from werkzeug.urls import iri_to_uri >>> iri_to_uri(get_current_url(env)) 'http://localhost/script/?param=foo' :param environ: the WSGI environment to get the current URL from. :param root_only: set `True` if you only want the root URL. :param strip_querystring: set to `True` if you don't want the querystring. :param host_only: set to `True` if the host URL should be returned. :param trusted_hosts: a list of trusted hosts, see :func:`host_is_trusted` for more information. """ tmp = [environ['wsgi.url_scheme'], '://', get_host(environ, trusted_hosts)] cat = tmp.append if host_only: return uri_to_iri(''.join(tmp) + '/') cat(url_quote(wsgi_get_bytes(environ.get('SCRIPT_NAME', ''))).rstrip('/')) cat('/') if not root_only: cat(url_quote(wsgi_get_bytes(environ.get('PATH_INFO', '')).lstrip(b'/'))) if not strip_querystring: qs = get_query_string(environ) if qs: cat('?' + qs) return uri_to_iri(''.join(tmp))
def test_quoting(): strict_eq(urls.url_quote(u"\xf6\xe4\xfc"), "%C3%B6%C3%A4%C3%BC") strict_eq(urls.url_unquote(urls.url_quote(u'#%="\xf6')), u'#%="\xf6') strict_eq(urls.url_quote_plus("foo bar"), "foo+bar") strict_eq(urls.url_unquote_plus("foo+bar"), u"foo bar") strict_eq(urls.url_quote_plus("foo+bar"), "foo%2Bbar") strict_eq(urls.url_unquote_plus("foo%2Bbar"), u"foo+bar") strict_eq(urls.url_encode({b"a": None, b"b": b"foo bar"}), "b=foo+bar") strict_eq(urls.url_encode({u"a": None, u"b": u"foo bar"}), "b=foo+bar") strict_eq( urls.url_fix(u"http://de.wikipedia.org/wiki/Elf (Begriffsklärung)"), "http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)", ) strict_eq(urls.url_quote_plus(42), "42") strict_eq(urls.url_quote(b"\xff"), "%FF")
def url_for(endpoint, **args): """Get the URL to an endpoint. The keyword arguments provided are used as URL values. Unknown URL values are used as keyword argument. Additionally there are some special keyword arguments: `_anchor` This string is used as URL anchor. `_external` If set to `True` the URL will be generated with the full server name and `http://` prefix. """ if hasattr(endpoint, 'get_url_values'): rv = endpoint.get_url_values() if rv is not None: if isinstance(rv, basestring): return make_external_url(rv) endpoint, updated_args = rv args.update(updated_args) anchor = args.pop('_anchor', None) external = args.pop('_external', False) rv = get_application().url_adapter.build(endpoint, args, force_external=external) if anchor is not None: rv += '#' + url_quote(anchor) return rv
def url_for(self, endpoint, use_partyline=True, **values): """Build a URL, asking other applications if BuildError occurs locally. This implementation is a fork of :func:`~flask.helpers.url_for`, where the implementation you see here works around Flask's context-locals to provide URL routing specific to ``self``. Then it implements the wsgi_party url_for requests across Flask applications loaded into the partyline. """ # Some values are popped; keep an original copy for re-requesting URL. copy_values = copy.deepcopy(values) blueprint_name = request.blueprint if endpoint[:1] == '.': if blueprint_name is not None: endpoint = blueprint_name + endpoint else: endpoint = endpoint[1:] external = values.pop('_external', False) anchor = values.pop('_anchor', None) method = values.pop('_method', None) self.inject_url_defaults(endpoint, values) url_adapter = self.create_url_adapter(request) try: rv = url_adapter.build(endpoint, values, method=method, force_external=external) except BuildError: # We do not have this URL, ask the partyline. if not use_partyline: raise for url in self.partyline.ask_around('url', (endpoint, copy_values)): # First response wins. return url if anchor is not None: rv += '#' + url_quote(anchor) return rv
def _get_pts_link(self): """ returns an URL for the package in the Debian Package Tracking System """ pts_link = PTS_PREFIX + self.package pts_link = url_quote(pts_link) # for '+' symbol in package names return pts_link
def fb_request(self, original_url): conf_ = conf['fb'] original_url = oauth_base + conf_['callback_base'] + url_quote(original_url) uri = conf_['token_url'] + '?' + url_encode({'client_id': conf_['consumer_key'], 'redirect_uri': original_url}) self.redirect(uri)
def url_for(endpoint, anchor=None, method=None, external=False, **values): """Generates a URL to the given endpoint with the method provided. endpoint : The endpoint of the URL (name of the function). anchor : If provided this is added as anchor to the URL. method : If provided this explicitly specifies an HTTP method. external : Set to `True`, to generate an absolute URL. values : The variable arguments of the URL rule """ try: urls = local.urls except AttributeError: raise RuntimeError("You must call this function only from" " inside a view or a template") try: url = urls.build(endpoint, values, method=method, force_external=external) except BuildError: url = '' if anchor is not None: url += '#' + url_quote(anchor) return url
def test_settings_avatar(self): response = self.client.get('/user/settings/avatar') self.assertRedirects(response, location='/login?next=%s' % url_quote('/user/settings/avatar', safe='')) self._login() self._test_get_request('/user/settings/avatar', 'settings/avatar.html')
def test_profile(self): endpoint = '/settings/profile' response = self.client.get(endpoint) self.assertRedirects(response, location='/login?next=%s' % url_quote(endpoint, safe='')) user = self._login() response = self.client.get('/settings/profile') self.assert200(response) self.assertTemplateUsed("settings/profile.html") data = { 'name': 'demo1', 'email': '*****@*****.**', 'role_id': ADMIN, 'status_id': NEW, 'real_name': user.user_detail.real_name, 'age': user.user_detail.age, 'url': user.user_detail.url, 'location': user.user_detail.location, 'bio': user.user_detail.bio, } response = self.client.post(endpoint, data=data) print response.data assert "help-block error" not in response.data self.assert200(response) self.assertTemplateUsed("settings/profile.html") new_user = User.query.filter_by(name=data.get('name')).first() assert new_user is not None assert new_user.email == data.get('email') assert new_user.getRole() == USER_ROLE.get(ADMIN) assert new_user.getStatus() == USER_STATUS.get(NEW)
def twitter_request(self, original_url): conf_ = conf['twitter'] original_url = oauth_base + conf_['callback_base'] + url_quote(original_url) consumer = oauth2.Consumer(conf_['consumer_key'], conf_['consumer_secret']) client = oauth2.Client(consumer) q, content = client.request(conf_['token_url'], "POST", body = url_encode({'oauth_callback':original_url})) if q['status'] != "200": stderr.write("Login error twitter auth:\n %s\n" % q.content) return self.redirect('/?msg=2') del q oauth_data = url_decode(content) oauth_token = oauth_data['oauth_token'] oauth_token_secret = oauth_data['oauth_token_secret'] del content del oauth_data f = open(oauth_secrets_path_prefix + oauth_token, 'w') f.write(oauth_token_secret) f.close() self.redirect(conf_['authenticate'] + "?oauth_token=" + oauth_token)
def test_home(self): response = self.client.get('/user/') self.assertRedirects(response, location='/login?next=%s' % url_quote('/user/', safe='')) self.login('demo', '123456') self._test_get_request('/user/', 'user/index.html')
def member_is_pending(username): rv = github_api_request('GET', 'teams/%s/memberships/%s' % ( app.config['MEMBER_TEAM_ID'], url_quote(username), )) if rv.status_code == 404: return False return rv.json().get('state') == 'pending'
def run_dev_server(application): app_pkg = tmpdir.mkdir("testsuite_app") appfile = app_pkg.join("__init__.py") port = next(port_generator) appfile.write( "\n\n".join( ( "kwargs = {{'hostname': 'localhost', 'port': {port:d}}}".format( port=port ), textwrap.dedent(application), ) ) ) monkeypatch.delitem(sys.modules, "testsuite_app", raising=False) monkeypatch.syspath_prepend(str(tmpdir)) import testsuite_app hostname = testsuite_app.kwargs["hostname"] port = testsuite_app.kwargs["port"] addr = "{}:{}".format(hostname, port) if hostname.startswith("unix://"): addr = hostname.split("unix://", 1)[1] requests_url = "http+unix://" + url_quote(addr, safe="") elif testsuite_app.kwargs.get("ssl_context", None): requests_url = "https://localhost:{0}".format(port) else: requests_url = "http://localhost:{0}".format(port) info = _ServerInfo(xprocess, addr, requests_url, port) from xprocess import ProcessStarter class Starter(ProcessStarter): args = [sys.executable, __file__, str(tmpdir)] @property def pattern(self): return "pid=%s" % info.request_pid() xprocess.ensure("dev_server", Starter, restart=True) @request.addfinalizer def teardown(): # Killing the process group that runs the server, not just the # parent process attached. xprocess is confused about Werkzeug's # reloader and won't help here. pid = info.request_pid() if not pid: return if platform.system() == "Windows": subprocess.call(["taskkill", "/F", "/T", "/PID", str(pid)]) else: os.killpg(os.getpgid(pid), signal.SIGTERM) return info
def fb_callback(request, original_url): if "code" not in request.args: return redirect("/?msg=2") code = request.args["code"] callback_uri = request.host_url + "login/callback/fb/" + url_quote(original_url) q = requests.get( "https://graph.facebook.com/oauth/access_token?" + url_encode( { "client_id": FB["consumer_key"], "redirect_uri": url_quote(callback_uri), "client_secret": FB["consumer_secret"], "code": code, } ) ) if q.status_code != 200: return redirect("/?msg=2") content = url_decode(q.content) access_token = content["access_token"] q = requests.get("https://graph.facebook.com/me?access_token=" + access_token) if q.status_code != 200: return redirect("/?msg=2") userdata = loads(q.content) profile_id = userdata["id"] email = userdata.get("email") fullname = userdata["name"] img_url = None try: q = requests.get("https://graph.facebook.com/%s/picture?redirect=0" % profile_id) if q.status_code == 200: userdata = loads(q.content)["data"] img_url = userdata["url"] except Exception, exc: stderr.write("fb profile pic fetch error: " + str(exc))
def external_url_handler(error, endpoint, values): method = values.pop('_method', None) anchor = values.pop('_anchor', None) values.pop('_external', None) rv = ext_adapter.build(endpoint, values, method=method, force_external=True) if anchor is not None: rv += '#' + url_quote(anchor) return rv
def index(): idform = GetIdForm(prefix="get") if idform.validate_on_submit(): return redirect(url_for('component_page', identifier=url_quote(idform.identifier.data, safe=''))) sform = SearchForm(prefix="search") if sform.validate_on_submit(): return redirect(url_for('component_search', search_str=url_quote(sform.text.data, safe=''))) itemform = SearchItemsForm(prefix="search-item") if itemform.validate_on_submit(): return redirect(url_for('find_feature', kind=itemform.kind.data, value=url_quote(itemform.text.data, safe=''))) return render_template('index.html', title = 'Home', idform = idform, sform = sform, itemform = itemform)
def test_profile(self): endpoint = '/settings/profile' response = self.client.get(endpoint) self.assertRedirects(response, location='/login?next=%s' % url_quote(endpoint, safe='')) self.login('demo', '123456') response = self.client.get('/settings/profile') self.assert200(response) self.assertTemplateUsed("settings/profile.html")
def send_file_inline(filename): """Send a file inline, including the original filename. Ref: http://test.greenbytes.de/tech/tc2231/. """ response = send_file(filename) basename = os.path.basename(filename) cont_disp = "inline; filename*=UTF-8''{}".format(url_quote(basename)) response.headers['Content-Disposition'] = cont_disp return response
def href(*args, **kw): """ Simple function for URL generation. Position arguments are used for the URL path and keyword arguments are used for the url parameters. """ result = [(request and request.script_root or '') + '/'] for idx, arg in enumerate(args): result.append((idx and '/' or '') + url_quote(arg)) if kw: result.append('?' + url_encode(kw)) return ''.join(result)
def href(*args, **kw): """ Simple function for URL generation. Position arguments are used for the URL path and keyword arguments are used for the url parameters. """ result = [(request.script_root if request else "") + "/"] for idx, arg in enumerate(args): result.append(("/" if idx else "") + url_quote(arg)) if kw: result.append("?" + url_encode(kw)) return "".join(result)
def get_current_url(environ, root_only=False, strip_querystring=False, host_only=False, trusted_hosts=None): """A handy helper function that recreates the full URL for the current request or parts of it. Here an example: >>> from werkzeug.test import create_environ >>> env = create_environ("/?param=foo", "http://localhost/script") >>> get_current_url(env) 'http://localhost/script/?param=foo' >>> get_current_url(env, root_only=True) 'http://localhost/script/' >>> get_current_url(env, host_only=True) 'http://localhost/' >>> get_current_url(env, strip_querystring=True) 'http://localhost/script/' This optionally it verifies that the host is in a list of trusted hosts. If the host is not in there it will raise a :exc:`~werkzeug.exceptions.SecurityError`. :param environ: the WSGI environment to get the current URL from. :param root_only: set `True` if you only want the root URL. :param strip_querystring: set to `True` if you don't want the querystring. :param host_only: set to `True` if the host URL should be returned. :param trusted_hosts: a list of trusted hosts, see :func:`host_is_trusted` for more information. """ tmp = [environ["wsgi.url_scheme"], "://", get_host(environ, trusted_hosts)] cat = tmp.append if host_only: return uri_to_iri("".join(tmp) + "/") cat(url_quote(wsgi_get_bytes(environ.get("SCRIPT_NAME", ""))).rstrip("/")) cat("/") if not root_only: cat(url_quote(wsgi_get_bytes(environ.get("PATH_INFO", "")).lstrip(b"/"))) if not strip_querystring: qs = get_query_string(environ) if qs: cat("?" + qs) return uri_to_iri("".join(tmp))
def to_url(self, value): return url_quote(value, self.map.charset)
def pypi_url(self): pypi_name = self.pypi if pypi_name is not None: return 'https://pypi.python.org/pypi/%s/' % url_quote(pypi_name)
def application(environ, start_response): headers = list(EnvironHeaders(environ).items()) headers[:] = [(k, v) for k, v in headers if not is_hop_by_hop_header(k) and k.lower() not in ( 'content-length', 'host')] headers.append(('Connection', 'close')) if opts['host'] == '<auto>': headers.append(('Host', target.ascii_host)) elif opts['host'] is None: headers.append(('Host', environ['HTTP_HOST'])) else: headers.append(('Host', opts['host'])) headers.extend(opts['headers'].items()) remote_path = path if opts['remove_prefix']: remote_path = '%s/%s' % (target.path.rstrip('/'), remote_path[len(prefix):].lstrip('/')) content_length = environ.get('CONTENT_LENGTH') chunked = False if content_length not in ('', None): headers.append(('Content-Length', content_length)) elif content_length is not None: headers.append(('Transfer-Encoding', 'chunked')) chunked = True try: if target.scheme == 'http': con = httplib.HTTPConnection(target.ascii_host, target.port or 80, timeout=self.timeout) elif target.scheme == 'https': con = httplib.HTTPSConnection(target.ascii_host, target.port or 443, timeout=self.timeout, context=opts['ssl_context']) con.connect() remote_url = url_quote(remote_path) querystring = environ['QUERY_STRING'] if querystring: remote_url = remote_url + '?' + querystring con.putrequest(environ['REQUEST_METHOD'], remote_url, skip_host=True) for k, v in headers: if k.lower() == 'connection': v = 'close' con.putheader(k, v) con.endheaders() stream = get_input_stream(environ) while 1: data = stream.read(self.chunk_size) if not data: break if chunked: con.send(b'%x\r\n%s\r\n' % (len(data), data)) else: con.send(data) resp = con.getresponse() except socket.error: from werkzeug.exceptions import BadGateway return BadGateway()(environ, start_response) start_response( '%d %s' % (resp.status, resp.reason), [(k.title(), v) for k, v in resp.getheaders() if not is_hop_by_hop_header(k)]) def read(): while 1: try: data = resp.read(self.chunk_size) except socket.error: break if not data: break yield data return read()
def results_csv(group_id): if current_user.is_admin: group = Group.query.get_or_404(group_id) def generate(): group = Group.query.get_or_404(group_id) group_name_with_subject = group.name + ' (' + group.subject + ')' header = (gettext('Grupa:'), group_name_with_subject) yield ",".join(header) + '\n' header = ( gettext("Sekcja"), gettext("Tytuł projektu"), # gettext("Suma wszystkich punktów"), gettext("Punkty z oceniania sposobem 1"), gettext("Punkty z oceniania sposobem 2"), gettext("Punkty z oceniania sposobem 3"), gettext("Punkty od nauczyciela"), gettext("Punkty od nauczyciela (poprawa)"), gettext("Wyróżnienia (studenci)"), gettext("Wyróżnienie (nauczyciel)")) yield ",".join(header) + '\n' group_points_per_project = gettext( f'(od 1 do {str(group.points_per_project)})') row = '', '', '', '', group_points_per_project, group_points_per_project, group_points_per_project yield ",".join(row) + '\n' # Count numbers of evaluators section_keys = [section.login for section in group.users] points_pool_evaluators = User.query.filter_by( did_rate=True, rating_type='points_pool').join( Group, Group.id == User.group_id).filter( Group.name.in_(section_keys)).count() points_pool_shuffled_evaluators = User.query.filter_by( did_rate=True, rating_type='points_pool_shuffled').join( Group, Group.id == User.group_id).filter( Group.name.in_(section_keys)).count() pool_per_project_evaluators = User.query.filter_by( did_rate=True, rating_type='pool_per_project').join( Group, Group.id == User.group_id).filter( Group.name.in_(section_keys)).count() # numbers needed to calculate score for 3 method group_projects = Project.query.join(User).filter( User.group == group).order_by(User.section_number.asc()).all() raters_pool_per_project_nums = dict() for project in group_projects: raters_num_temp = User.query.filter_by( did_rate=True, rating_type='pool_per_project').join( Group, Group.id == User.group_id).filter( Group.name.in_(section_keys), Group.name != project.author.login).count() if raters_num_temp == 0: raters_num_temp = 1 raters_pool_per_project_nums[project] = raters_num_temp for section in group.users: section_name = '\n' + gettext('Sekcja ') + str( section.section_number) if section.project: if section.project.upload_file_improvement and ( group.rating_status == 'disabled_improvement' or group.rating_status == 'enabled_improvement' or group.rating_status == 'ended_improvement'): section_project_title = section.project.title_improvement else: section_project_title = section.project.title # section_points_sum = (str(section.project.score_points_pool + section.project.score_points_pool_shuffled)) section_score_points_pool = (str( section.project.score_points_pool)) section_score_points_pool_shuffled = (str( section.project.score_points_pool_shuffled)) section_score_pool_per_project = (str( round( section.project.score_pool_per_project / (raters_pool_per_project_nums.get( section.project)), 2))) section_score_admin = (str(section.project.score_admin)) section_score_admin_improvement = (str( section.project.score_admin_improvement)) section_user_distinctions = (str( section.project.user_distinctions)) section_admin_distinction = gettext( "tak" ) if section.project.admin_distinction else gettext("nie") else: section_project_title = '---' # section_points_sum = '---' section_score_points_pool = '---' section_score_points_pool_shuffled = '---' section_score_pool_per_project = '---' section_score_admin = '---' section_score_admin_improvement = '---' section_user_distinctions = '---' section_admin_distinction = '---' row = (section_name, section_project_title, section_score_points_pool, section_score_points_pool_shuffled, section_score_pool_per_project, section_score_admin, section_score_admin_improvement, section_user_distinctions, section_admin_distinction) yield ','.join(row) row = gettext('\n\n' + 'Oceniający sposobem 1:'), str( points_pool_evaluators) yield ','.join(row) row = gettext('\n' + 'Oceniający sposobem 2:'), str( points_pool_shuffled_evaluators) yield ','.join(row) row = gettext('\n' + 'Oceniający sposobem 3:'), str( pool_per_project_evaluators) yield ','.join(row) else: flash( gettext( 'Musisz mieć uprawnienia administratora, aby uzyskać dostęp do tej strony' ), 'warning') return redirect(url_for('main.home')) filename = group.subject + '-' + group.name.replace( " ", "_") + gettext('-wyniki') + ".csv" filename = filename.encode('utf-8') filename = url_quote(filename) return Response( generate(), mimetype='text/csv', headers={"Content-Disposition": "attachment;filename=" + filename})
def to_url(self, value): return url_quote(self.v2k.get(value, value), self.map.charset)
def urlquote(value, charset='utf-8'): """ Url Quote. """ return url_quote(value, charset)
def test_bytes_unquoting(): strict_eq( urls.url_unquote(urls.url_quote(u'#%="\xf6', charset="latin1"), charset=None), b'#%="\xf6', )
def download(): """ Download the zip file. """ # Deny new downloads if "Stop After First Download" is checked and there is # currently a download deny_download = (self.web.settings.get("share", "autostop_sharing") and self.download_in_progress) if deny_download: r = make_response(render_template("denied.html")) return self.web.add_security_headers(r) # Prepare some variables to use inside generate() function below # which is outside of the request context shutdown_func = request.environ.get("werkzeug.server.shutdown") path = request.path # If this is a zipped file, then serve as-is. If it's not zipped, then, # if the http client supports gzip compression, gzip the file first # and serve that use_gzip = self.should_use_gzip() if use_gzip: file_to_download = self.gzip_filename self.filesize = self.gzip_filesize else: file_to_download = self.download_filename self.filesize = self.download_filesize # Tell GUI the download started history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request(self.web.REQUEST_STARTED, path, { "id": history_id, "use_gzip": use_gzip }) basename = os.path.basename(self.download_filename) def generate(): # Starting a new download if self.web.settings.get("share", "autostop_sharing"): self.download_in_progress = True chunk_size = 102400 # 100kb fp = open(file_to_download, "rb") self.web.done = False canceled = False while not self.web.done: # The user has canceled the download, so stop serving the file if not self.web.stop_q.empty(): self.web.add_request(self.web.REQUEST_CANCELED, path, {"id": history_id}) break chunk = fp.read(chunk_size) if chunk == b"": self.web.done = True else: try: yield chunk # tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / self.filesize) * 100 # only output to stdout if running onionshare in CLI mode, or if using Linux (#203, #304) if (not self.web.is_gui or self.common.platform == "Linux" or self.common.platform == "BSD"): sys.stdout.write( "\r{0:s}, {1:.2f}% ".format( self.common.human_readable_filesize( downloaded_bytes), percent, )) sys.stdout.flush() self.web.add_request( self.web.REQUEST_PROGRESS, path, { "id": history_id, "bytes": downloaded_bytes }, ) self.web.done = False except: # looks like the download was canceled self.web.done = True canceled = True # tell the GUI the download has canceled self.web.add_request(self.web.REQUEST_CANCELED, path, {"id": history_id}) fp.close() if self.common.platform != "Darwin": sys.stdout.write("\n") # Download is finished if self.web.settings.get("share", "autostop_sharing"): self.download_in_progress = False # Close the server, if necessary if self.web.settings.get("share", "autostop_sharing") and not canceled: print("Stopped because transfer is complete") self.web.running = False try: if shutdown_func is None: raise RuntimeError( "Not running with the Werkzeug Server") shutdown_func() except: pass r = Response(generate()) if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", self.filesize) filename_dict = { 'filename': unidecode(basename), 'filename*': "UTF-8''%s" % url_quote(basename) } r.headers.set("Content-Disposition", "inline", **filename_dict) r = self.web.add_security_headers(r) # guess content type (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: r.headers.set("Content-Type", content_type) return r
def get_tweets(username): """Returns the tweets of a given user""" resp = urllib2.urlopen('http://twitter.com/statuses/user_timeline/' + url_quote(username) + '.json') return json.load(resp)
def url_for(endpoint, **values): """Generates a URL to the given endpoint with the method provided. Variable arguments that are unknown to the target endpoint are appended to the generated URL as query arguments. If the value of a query argument is ``None``, the whole pair is skipped. In case blueprints are active you can shortcut references to the same blueprint by prefixing the local endpoint with a dot (``.``). This will reference the index function local to the current blueprint:: url_for('.index') For more information, head over to the :ref:`Quickstart <url-building>`. Configuration values ``APPLICATION_ROOT`` and ``SERVER_NAME`` are only used when generating URLs outside of a request context. To integrate applications, :class:`Flask` has a hook to intercept URL build errors through :attr:`Flask.url_build_error_handlers`. The `url_for` function results in a :exc:`~werkzeug.routing.BuildError` when the current app does not have a URL for the given endpoint and values. When it does, the :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if it is not ``None``, which can return a string to use as the result of `url_for` (instead of `url_for`'s default to raise the :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. An example:: def external_url_handler(error, endpoint, values): "Looks up an external URL when `url_for` cannot build a URL." # This is an example of hooking the build_error_handler. # Here, lookup_url is some utility function you've built # which looks up the endpoint in some external URL registry. url = lookup_url(endpoint, **values) if url is None: # External lookup did not have a URL. # Re-raise the BuildError, in context of original traceback. exc_type, exc_value, tb = sys.exc_info() if exc_value is error: raise exc_type, exc_value, tb else: raise error # url_for will use this result, instead of raising BuildError. return url app.url_build_error_handlers.append(external_url_handler) Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and `endpoint` and `values` are the arguments passed into `url_for`. Note that this is for building URLs outside the current application, and not for handling 404 NotFound errors. .. versionadded:: 0.10 The `_scheme` parameter was added. .. versionadded:: 0.9 The `_anchor` and `_method` parameters were added. .. versionadded:: 0.9 Calls :meth:`Flask.handle_build_error` on :exc:`~werkzeug.routing.BuildError`. :param endpoint: the endpoint of the URL (name of the function) :param values: the variable arguments of the URL rule :param _external: if set to ``True``, an absolute URL is generated. Server address can be changed via ``SERVER_NAME`` configuration variable which falls back to the `Host` header, then to the IP and port of the request. :param _scheme: a string specifying the desired URL scheme. The `_external` parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default behavior uses the same scheme as the current request, or ``PREFERRED_URL_SCHEME`` from the :ref:`app configuration <config>` if no request context is available. As of Werkzeug 0.10, this also can be set to an empty string to build protocol-relative URLs. :param _anchor: if provided this is added as anchor to the URL. :param _method: if provided this explicitly specifies an HTTP method. """ appctx = _app_ctx_stack.top reqctx = _request_ctx_stack.top if appctx is None: raise RuntimeError( "Attempted to generate a URL without the application context being" " pushed. This has to be executed when application context is" " available." ) # If request specific information is available we have some extra # features that support "relative" URLs. if reqctx is not None: url_adapter = reqctx.url_adapter blueprint_name = request.blueprint if endpoint[:1] == ".": if blueprint_name is not None: endpoint = blueprint_name + endpoint else: endpoint = endpoint[1:] external = values.pop("_external", False) # Otherwise go with the url adapter from the appctx and make # the URLs external by default. else: url_adapter = appctx.url_adapter if url_adapter is None: raise RuntimeError( "Application was not able to create a URL adapter for request" " independent URL generation. You might be able to fix this by" " setting the SERVER_NAME config variable." ) external = values.pop("_external", True) anchor = values.pop("_anchor", None) method = values.pop("_method", None) scheme = values.pop("_scheme", None) appctx.app.inject_url_defaults(endpoint, values) # This is not the best way to deal with this but currently the # underlying Werkzeug router does not support overriding the scheme on # a per build call basis. old_scheme = None if scheme is not None: if not external: raise ValueError("When specifying _scheme, _external must be True") old_scheme = url_adapter.url_scheme url_adapter.url_scheme = scheme try: try: rv = url_adapter.build( endpoint, values, method=method, force_external=external ) finally: if old_scheme is not None: url_adapter.url_scheme = old_scheme except BuildError as error: # We need to inject the values again so that the app callback can # deal with that sort of stuff. values["_external"] = external values["_anchor"] = anchor values["_method"] = method values["_scheme"] = scheme return appctx.app.handle_url_build_error(error, endpoint, values) if anchor is not None: rv += "#" + url_quote(anchor) return rv
def create_an_event(self, event): """ Create a new event in google calendar from the given event in Harpiya. :param event : record of calendar.event to export to google calendar """ data = self.generate_data(event, isCreating=True) url = "/calendar/v3/calendars/%s/events?fields=%s&access_token=%s" % ('primary', urls.url_quote('id,updated'), self.get_token()) headers = {'Content-type': 'application/json', 'Accept': 'text/plain'} data_json = json.dumps(data) return self.env['google.service']._do_request(url, data_json, headers, type='POST')
def send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=None, conditional=False, last_modified=None): """Sends the contents of a file to the client. This will use the most efficient method available and configured. By default it will try to use the WSGI server's file_wrapper support. Alternatively you can set the application's :attr:`~Flask.use_x_sendfile` attribute to ``True`` to directly emit an ``X-Sendfile`` header. This however requires support of the underlying webserver for ``X-Sendfile``. By default it will try to guess the mimetype for you, but you can also explicitly provide one. For extra security you probably want to send certain files as attachment (HTML for instance). The mimetype guessing requires a `filename` or an `attachment_filename` to be provided. ETags will also be attached automatically if a `filename` is provided. You can turn this off by setting `add_etags=False`. If `conditional=True` and `filename` is provided, this method will try to upgrade the response stream to support range requests. This will allow the request to be answered with partial content response. Please never pass filenames to this function from user sources; you should use :func:`send_from_directory` instead. .. versionadded:: 0.2 .. versionadded:: 0.5 The `add_etags`, `cache_timeout` and `conditional` parameters were added. The default behavior is now to attach etags. .. versionchanged:: 0.7 mimetype guessing and etag support for file objects was deprecated because it was unreliable. Pass a filename if you are able to, otherwise attach an etag yourself. This functionality will be removed in Flask 1.0 .. versionchanged:: 0.9 cache_timeout pulls its default from application config, when None. .. versionchanged:: 0.12 The filename is no longer automatically inferred from file objects. If you want to use automatic mimetype and etag support, pass a filepath via `filename_or_fp` or `attachment_filename`. .. versionchanged:: 0.12 The `attachment_filename` is preferred over `filename` for MIME-type detection. .. versionchanged:: 0.13 UTF-8 filenames, as specified in `RFC 2231`_, are supported. .. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4 :param filename_or_fp: the filename of the file to send. This is relative to the :attr:`~Flask.root_path` if a relative path is specified. Alternatively a file object might be provided in which case ``X-Sendfile`` might not work and fall back to the traditional method. Make sure that the file pointer is positioned at the start of data to send before calling :func:`send_file`. :param mimetype: the mimetype of the file if provided. If a file path is given, auto detection happens as fallback, otherwise an error will be raised. :param as_attachment: set to ``True`` if you want to send this file with a ``Content-Disposition: attachment`` header. :param attachment_filename: the filename for the attachment if it differs from the file's filename. :param add_etags: set to ``False`` to disable attaching of etags. :param conditional: set to ``True`` to enable conditional responses. :param cache_timeout: the timeout in seconds for the headers. When ``None`` (default), this value is set by :meth:`~Flask.get_send_file_max_age` of :data:`~flask.current_app`. :param last_modified: set the ``Last-Modified`` header to this value, a :class:`~datetime.datetime` or timestamp. If a file was passed, this overrides its mtime. """ mtime = None fsize = None if isinstance(filename_or_fp, string_types): filename = filename_or_fp if not os.path.isabs(filename): filename = os.path.join(current_app.root_path, filename) file = None if attachment_filename is None: attachment_filename = os.path.basename(filename) else: file = filename_or_fp filename = None if mimetype is None: if attachment_filename is not None: mimetype = mimetypes.guess_type(attachment_filename)[0] \ or 'application/octet-stream' if mimetype is None: raise ValueError( 'Unable to infer MIME-type because no filename is available. ' 'Please set either `attachment_filename`, pass a filepath to ' '`filename_or_fp` or set your own MIME-type via `mimetype`.' ) headers = Headers() if as_attachment: if attachment_filename is None: raise TypeError('filename unavailable, required for ' 'sending as attachment') try: attachment_filename = attachment_filename.encode('latin-1') except UnicodeEncodeError: filenames = { 'filename': unicodedata.normalize( 'NFKD', attachment_filename).encode('latin-1', 'ignore'), 'filename*': "UTF-8''%s" % url_quote(attachment_filename), } else: filenames = {'filename': attachment_filename} headers.add('Content-Disposition', 'attachment', **filenames) if current_app.use_x_sendfile and filename: if file is not None: file.close() headers['X-Sendfile'] = filename fsize = os.path.getsize(filename) headers['Content-Length'] = fsize data = None else: if file is None: file = open(filename, 'rb') mtime = os.path.getmtime(filename) fsize = os.path.getsize(filename) headers['Content-Length'] = fsize data = wrap_file(request.environ, file) rv = current_app.response_class(data, mimetype=mimetype, headers=headers, direct_passthrough=True) if last_modified is not None: rv.last_modified = last_modified elif mtime is not None: rv.last_modified = mtime rv.cache_control.public = True if cache_timeout is None: cache_timeout = current_app.get_send_file_max_age(filename) if cache_timeout is not None: rv.cache_control.max_age = cache_timeout rv.expires = int(time() + cache_timeout) if add_etags and filename is not None: from warnings import warn try: rv.set_etag('%s-%s-%s' % ( os.path.getmtime(filename), os.path.getsize(filename), adler32( filename.encode('utf-8') if isinstance(filename, text_type) else filename ) & 0xffffffff )) except OSError: warn('Access %s failed, maybe it does not exist, so ignore etags in ' 'headers' % filename, stacklevel=2) if conditional: try: rv = rv.make_conditional(request, accept_ranges=True, complete_length=fsize) except RequestedRangeNotSatisfiable: if file is not None: file.close() raise # make sure we don't send x-sendfile for servers that # ignore the 304 status code for x-sendfile. if rv.status_code == 304: rv.headers.pop('x-sendfile', None) return rv
def url_for(endpoint, **values): """Generates a URL to the given endpoint with the method provided. Variable arguments that are unknown to the target endpoint are appended to the generated URL as query arguments. If the value of a query argument is `None`, the whole pair is skipped. In case blueprints are active you can shortcut references to the same blueprint by prefixing the local endpoint with a dot (``.``). This will reference the index function local to the current blueprint:: url_for('.index') For more information, head over to the :ref:`Quickstart <url-building>`. To integrate applications, :class:`Flask` has a hook to intercept URL build errors through :attr:`Flask.build_error_handler`. The `url_for` function results in a :exc:`~werkzeug.routing.BuildError` when the current app does not have a URL for the given endpoint and values. When it does, the :data:`~flask.current_app` calls its :attr:`~Flask.build_error_handler` if it is not `None`, which can return a string to use as the result of `url_for` (instead of `url_for`'s default to raise the :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. An example:: def external_url_handler(error, endpoint, **values): "Looks up an external URL when `url_for` cannot build a URL." # This is an example of hooking the build_error_handler. # Here, lookup_url is some utility function you've built # which looks up the endpoint in some external URL registry. url = lookup_url(endpoint, **values) if url is None: # External lookup did not have a URL. # Re-raise the BuildError, in context of original traceback. exc_type, exc_value, tb = sys.exc_info() if exc_value is error: raise exc_type, exc_value, tb else: raise error # url_for will use this result, instead of raising BuildError. return url app.build_error_handler = external_url_handler Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and `endpoint` and `**values` are the arguments passed into `url_for`. Note that this is for building URLs outside the current application, and not for handling 404 NotFound errors. .. versionadded:: 0.10 The `_scheme` parameter was added. .. versionadded:: 0.9 The `_anchor` and `_method` parameters were added. .. versionadded:: 0.9 Calls :meth:`Flask.handle_build_error` on :exc:`~werkzeug.routing.BuildError`. :param endpoint: the endpoint of the URL (name of the function) :param values: the variable arguments of the URL rule :param _external: if set to `True`, an absolute URL is generated. Server address can be changed via `SERVER_NAME` configuration variable which defaults to `localhost`. :param _scheme: a string specifying the desired URL scheme. The `_external` parameter must be set to `True` or a `ValueError` is raised. :param _anchor: if provided this is added as anchor to the URL. :param _method: if provided this explicitly specifies an HTTP method. """ appctx = _app_ctx_stack.top reqctx = _request_ctx_stack.top if appctx is None: raise RuntimeError('Attempted to generate a URL without the ' 'application context being pushed. This has to be ' 'executed when application context is available.') # If request specific information is available we have some extra # features that support "relative" urls. if reqctx is not None: url_adapter = reqctx.url_adapter blueprint_name = request.blueprint if not reqctx.request._is_old_module: if endpoint[:1] == '.': if blueprint_name is not None: endpoint = blueprint_name + endpoint else: endpoint = endpoint[1:] else: # TODO: get rid of this deprecated functionality in 1.0 if '.' not in endpoint: if blueprint_name is not None: endpoint = blueprint_name + '.' + endpoint elif endpoint.startswith('.'): endpoint = endpoint[1:] external = values.pop('_external', False) # Otherwise go with the url adapter from the appctx and make # the urls external by default. else: url_adapter = appctx.url_adapter if url_adapter is None: raise RuntimeError('Application was not able to create a URL ' 'adapter for request independent URL generation. ' 'You might be able to fix this by setting ' 'the SERVER_NAME config variable.') external = values.pop('_external', True) anchor = values.pop('_anchor', None) method = values.pop('_method', None) scheme = values.pop('_scheme', None) appctx.app.inject_url_defaults(endpoint, values) if scheme is not None: if not external: raise ValueError('When specifying _scheme, _external must be True') url_adapter.url_scheme = scheme try: rv = url_adapter.build(endpoint, values, method=method, force_external=external) except BuildError as error: # We need to inject the values again so that the app callback can # deal with that sort of stuff. values['_external'] = external values['_anchor'] = anchor values['_method'] = method return appctx.app.handle_url_build_error(error, endpoint, values) if anchor is not None: rv += '#' + url_quote(anchor) return rv
def _notify_members(self, message): """Send the given message to all members of the mail group (except the author).""" self.ensure_one() if message.mail_group_id != self: raise UserError(_('The group of the message do not match.')) if not message.mail_message_id.reply_to: _logger.error('The alias or the catchall domain is missing, group might not work properly.') base_url = self.get_base_url() body = self.env['mail.render.mixin']._replace_local_links(message.body) access_token = self._generate_group_access_token() mail_values = [] # Email added in a dict to be sure to send only once the email to each address member_emails = { email_normalize(member.email): member.email for member in self.member_ids } for batch_email_member in tools.split_every(GROUP_SEND_BATCH_SIZE, member_emails.items()): for email_member_normalized, email_member in batch_email_member: if email_member_normalized == message.email_from_normalized: # Do not send the email to his author continue # SMTP headers related to the subscription email_url_encoded = urls.url_quote(email_member) headers = { ** self._notify_email_header_dict(), 'List-Archive': f'<{base_url}/groups/{slug(self)}>', 'List-Subscribe': f'<{base_url}/groups?email={email_url_encoded}>', 'List-Unsubscribe': f'<{base_url}/groups?unsubscribe&email={email_url_encoded}>', 'Precedence': 'list', 'X-Auto-Response-Suppress': 'OOF', # avoid out-of-office replies from MS Exchange } if self.alias_name and self.alias_domain: headers.update({ 'List-Id': f'<{self.alias_name}.{self.alias_domain}>', 'List-Post': f'<mailto:{self.alias_name}@{self.alias_domain}>', 'X-Forge-To': f'"{self.name}" <{self.alias_name}@{self.alias_domain}>', }) if message.mail_message_id.parent_id: headers['In-Reply-To'] = message.mail_message_id.parent_id.message_id # Add the footer (member specific) in the body template_values = { 'mailto': f'{self.alias_name}@{self.alias_domain}', 'group_url': f'{base_url}/groups/{slug(self)}', 'unsub_label': f'{base_url}/groups?unsubscribe', 'unsub_url': f'{base_url}/groups?unsubscribe&group_id={self.id}&token={access_token}&email={email_url_encoded}', } template = self.env.ref('mail_group.mail_group_footer') footer = template._render(template_values, engine='ir.qweb', minimal_qcontext=True) member_body = tools.append_content_to_html(body, footer, plaintext=False) mail_values.append({ 'auto_delete': True, 'attachment_ids': message.attachment_ids.ids, 'body_html': member_body, 'email_from': message.email_from, 'email_to': email_member, 'headers': json.dumps(headers), 'mail_message_id': message.mail_message_id.id, 'message_id': message.mail_message_id.message_id, 'model': 'mail.group', 'reply_to': message.mail_message_id.reply_to, 'res_id': self.id, 'subject': message.subject, }) if mail_values: self.env['mail.mail'].sudo().create(mail_values)
def download(): """ Download the zip file. """ # Deny new downloads if "Stop After First Download" is checked and there is # currently a download deny_download = (self.web.settings.get("share", "autostop_sharing") and self.download_in_progress) if deny_download: return render_template("denied.html") # Prepare some variables to use inside generate() function below # which is outside of the request context shutdown_func = request.environ.get("werkzeug.server.shutdown") request_path = request.path # If this is a zipped file, then serve as-is. If it's not zipped, then, # if the http client supports gzip compression, gzip the file first # and serve that use_gzip = self.should_use_gzip() if use_gzip: file_to_download = self.gzip_filename self.filesize = self.gzip_filesize etag = self.gzip_etag else: file_to_download = self.download_filename self.filesize = self.download_filesize etag = self.download_etag # for range requests range_, status_code = self.get_range_and_status_code( self.filesize, etag, self.last_modified) # Tell GUI the download started history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request( self.web.REQUEST_STARTED, request_path, { "id": history_id, "use_gzip": use_gzip }, ) basename = os.path.basename(self.download_filename) if status_code == 304: r = Response() else: r = Response( self.generate( shutdown_func, range_, file_to_download, request_path, history_id, self.filesize, )) if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", range_[1] - range_[0] + 1) filename_dict = { "filename": unidecode(basename), "filename*": "UTF-8''%s" % url_quote(basename), } r.headers.set("Content-Disposition", "attachment", **filename_dict) # guess content type (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: r.headers.set("Content-Type", content_type) r.headers.set("Accept-Ranges", "bytes") r.headers.set("ETag", etag) r.headers.set("Last-Modified", http_date(self.last_modified)) # we need to set this for range requests r.headers.set("Vary", "Accept-Encoding") if status_code == 206: r.headers.set( "Content-Range", "bytes {}-{}/{}".format(range_[0], range_[1], self.filesize), ) r.status_code = status_code return r
def send_stream(stream, filename, size, mtime, mimetype=None, restricted=True, as_attachment=False, etag=None, content_md5=None, chunk_size=None, conditional=True, trusted=False): """Send the contents of a file to the client. .. warning:: It is very easy to be exposed to Cross-Site Scripting (XSS) attacks if you serve user uploaded files. Here are some recommendations: 1. Serve user uploaded files from a separate domain (not a subdomain). This way a malicious file can only attack other user uploaded files. 2. Prevent the browser from rendering and executing HTML files (by setting ``trusted=False``). 3. Force the browser to download the file as an attachment (``as_attachment=True``). :param stream: The file stream to send. :param filename: The file name. :param size: The file size. :param mtime: A Unix timestamp that represents last modified time (UTC). :param mimetype: The file mimetype. If ``None``, the module will try to guess. (Default: ``None``) :param restricted: If the file is not restricted, the module will set the cache-control. (Default: ``True``) :param as_attachment: If the file is an attachment. (Default: ``False``) :param etag: If defined, it will be set as HTTP E-Tag. :param content_md5: If defined, a HTTP Content-MD5 header will be set. :param chunk_size: The chunk size. :param conditional: Make the response conditional to the request. (Default: ``True``) :param trusted: Do not enable this option unless you know what you are doing. By default this function will send HTTP headers and MIME types that prevents your browser from rendering e.g. a HTML file which could contain a malicious script tag. (Default: ``False``) :returns: A Flask response instance. """ chunk_size = chunk_size_or_default(chunk_size) # Guess mimetype from filename if not provided. if mimetype is None and filename: mimetype = mimetypes.guess_type(filename)[0] if mimetype is None: mimetype = 'application/octet-stream' # Construct headers headers = Headers() headers['Content-Length'] = size if content_md5: headers['Content-MD5'] = content_md5 if not trusted: # Sanitize MIME type mimetype = sanitize_mimetype(mimetype, filename=filename) # See https://www.owasp.org/index.php/OWASP_Secure_Headers_Project # Prevent JavaScript execution headers['Content-Security-Policy'] = "default-src 'none';" # Prevent MIME type sniffing for browser. headers['X-Content-Type-Options'] = 'nosniff' # Prevent opening of downloaded file by IE headers['X-Download-Options'] = 'noopen' # Prevent cross domain requests from Flash/Acrobat. headers['X-Permitted-Cross-Domain-Policies'] = 'none' # Prevent files from being embedded in frame, iframe and object tags. headers['X-Frame-Options'] = 'deny' # Enable XSS protection (IE, Chrome, Safari) headers['X-XSS-Protection'] = '1; mode=block' # Force Content-Disposition for application/octet-stream to prevent # Content-Type sniffing. if as_attachment or mimetype == 'application/octet-stream': # See https://github.com/pallets/flask/commit/0049922f2e690a6d try: filenames = {'filename': filename.encode('latin-1')} except UnicodeEncodeError: filenames = {'filename*': "UTF-8''%s" % url_quote(filename)} encoded_filename = (unicodedata.normalize('NFKD', filename) .encode('latin-1', 'ignore')) if encoded_filename: filenames['filename'] = encoded_filename headers.add('Content-Disposition', 'attachment', **filenames) else: headers.add('Content-Disposition', 'inline') # Construct response object. rv = current_app.response_class( FileWrapper(stream, buffer_size=chunk_size), mimetype=mimetype, headers=headers, direct_passthrough=True, ) # Set etag if defined if etag: rv.set_etag(etag) # Set last modified time if mtime is not None: rv.last_modified = int(mtime) # Set cache-control if not restricted: rv.cache_control.public = True cache_timeout = current_app.get_send_file_max_age(filename) if cache_timeout is not None: rv.cache_control.max_age = cache_timeout rv.expires = int(time() + cache_timeout) if conditional: rv = rv.make_conditional(request) return rv
def remove_member(username): github_api_request( 'DELETE', 'teams/%s/members/%s' % ( app.config['MEMBER_TEAM_ID'], url_quote(username), )).raise_for_status()
def redirect_stream(url, filename, size, mtime, mimetype=None, restricted=True, as_attachment=False, etag=None, content_md5=None, chunk_size=None, conditional=True, trusted=False): """Redirect to URL to serve the file directly from there. :param url: redirection URL :return: Flaks response. """ chunk_size = chunk_size_or_default(chunk_size) # Guess mimetype from filename if not provided. if mimetype is None and filename: mimetype = mimetypes.guess_type(filename)[0] if mimetype is None: mimetype = 'application/octet-stream' # Construct headers headers = Headers() headers['Content-Length'] = size if content_md5: headers['Content-MD5'] = content_md5 # Add redirect url as localtion headers['Location'] = url if not trusted: # Sanitize MIME type mimetype = sanitize_mimetype(mimetype, filename=filename) # See https://www.owasp.org/index.php/OWASP_Secure_Headers_Project # Prevent JavaScript execution headers['Content-Security-Policy'] = "default-src 'none';" # Prevent MIME type sniffing for browser. headers['X-Content-Type-Options'] = 'nosniff' # Prevent opening of downloaded file by IE headers['X-Download-Options'] = 'noopen' # Prevent cross domain requests from Flash/Acrobat. headers['X-Permitted-Cross-Domain-Policies'] = 'none' # Prevent files from being embedded in frame, iframe and object tags. headers['X-Frame-Options'] = 'deny' # Enable XSS protection (IE, Chrome, Safari) headers['X-XSS-Protection'] = '1; mode=block' # Force Content-Disposition for application/octet-stream to prevent # Content-Type sniffing. if as_attachment or mimetype == 'application/octet-stream': # See https://github.com/pallets/flask/commit/0049922f2e690a6d try: filenames = {'filename': filename.encode('latin-1')} except UnicodeEncodeError: filenames = {'filename*': "UTF-8''%s" % url_quote(filename)} encoded_filename = (unicodedata.normalize('NFKD', filename).encode( 'latin-1', 'ignore')) if encoded_filename: filenames['filename'] = encoded_filename headers.add('Content-Disposition', 'attachment', **filenames) else: headers.add('Content-Disposition', 'inline') # Construct response object. rv = current_app.response_class( url, status=302, mimetype=mimetype, headers=headers, direct_passthrough=True, ) # Set etag if defined if etag: rv.set_etag(etag) # Set last modified time if mtime is not None: rv.last_modified = int(mtime) # Set cache-control if not restricted: rv.cache_control.public = True cache_timeout = current_app.get_send_file_max_age(filename) if cache_timeout is not None: rv.cache_control.max_age = cache_timeout rv.expires = int(time() + cache_timeout) if conditional: rv = rv.make_conditional(request) return rv
def add_member(username): github_api_request( 'PUT', 'teams/%s/memberships/%s' % ( app.config['MEMBER_TEAM_ID'], url_quote(username), )).raise_for_status()
def application(environ, start_response): headers = list(EnvironHeaders(environ).items()) headers[:] = [(k, v) for k, v in headers if not is_hop_by_hop_header(k) and k.lower() not in ( "content-length", "host")] headers.append(("Connection", "close")) if opts["host"] == "<auto>": headers.append(("Host", target.ascii_host)) elif opts["host"] is None: headers.append(("Host", environ["HTTP_HOST"])) else: headers.append(("Host", opts["host"])) headers.extend(opts["headers"].items()) remote_path = path if opts["remove_prefix"]: remote_path = "%s/%s" % ( target.path.rstrip("/"), remote_path[len(prefix):].lstrip("/"), ) content_length = environ.get("CONTENT_LENGTH") chunked = False if content_length not in ("", None): headers.append(("Content-Length", content_length)) elif content_length is not None: headers.append(("Transfer-Encoding", "chunked")) chunked = True try: if target.scheme == "http": con = httplib.HTTPConnection(target.ascii_host, target.port or 80, timeout=self.timeout) elif target.scheme == "https": con = httplib.HTTPSConnection( target.ascii_host, target.port or 443, timeout=self.timeout, context=opts["ssl_context"], ) con.connect() con.putrequest(environ["REQUEST_METHOD"], url_quote(remote_path), skip_host=True) for k, v in headers: if k.lower() == "connection": v = "close" con.putheader(k, v) con.endheaders() stream = get_input_stream(environ) while 1: data = stream.read(self.chunk_size) if not data: break if chunked: con.send(b"%x\r\n%s\r\n" % (len(data), data)) else: con.send(data) resp = con.getresponse() except socket.error: from werkzeug.exceptions import BadGateway return BadGateway()(environ, start_response) start_response( "%d %s" % (resp.status, resp.reason), [(k.title(), v) for k, v in resp.getheaders() if not is_hop_by_hop_header(k)], ) def read(): while 1: try: data = resp.read(self.chunk_size) except socket.error: break if not data: break yield data return read()
def to_url(self, value): parts = itertools.chain.from_iterable(value) quoted_parts = (urls.url_quote(p, charset=self.map.charset, safe='') for p in parts) return ''.join(p + '/' for p in quoted_parts)
values, method=method, force_external=external) except BuildError, error: values['_external'] = external values['_anchor'] = anchor values['_method'] = method return appctx.app.handleBuildError(error, endpoint, **values) rv = urlAdapter.build(endpoint, values, method=method, force_external=external) if anchor is not None: rv += '#' + url_quote(anchor) return rv def findPackage(importName): rootModName = importName.split('.')[0] loader = pkgutil.get_loader(rootModName) if loader is None or importName == '__main__': pkgPath = os.getcwd() else: if hasattr(loader, 'get_filename'): filename = loader.get_filename(rootModName) elif hasattr(loader, 'active'): filename = loader.active else: __import__(importName)
def url_for_item(item_name, wiki_name='', field='', namespace='', rev=CURRENT, endpoint='frontend.show_item', _external=False, regex=''): """ Compute URL for some local or remote/interwiki item. For local items: give <rev> to get the url of some specific revision. give the <endpoint> to get the url of some specific view, give _external=True to compute fully specified URLs. For remote/interwiki items: If you just give <item_name> and <wiki_name>, a generic interwiki URL will be built. If you also give <rev> and/or <endpoint>, it is assumed that remote wiki URLs are built in the same way as local URLs. Computed URLs are always fully specified. """ if field == NAME_EXACT: field = '' if is_local_wiki(wiki_name): item_name = get_fqname(item_name, field, namespace) if rev is None or rev == CURRENT: url = url_for(endpoint, item_name=item_name, _external=_external) else: url = url_for(endpoint, item_name=item_name, rev=rev, _external=_external) else: try: wiki_base_url = app.cfg.interwiki_map[wiki_name] except KeyError as err: logging.warning( "no interwiki_map entry for {0!r}".format(wiki_name)) item_name = get_fqname(item_name, field, namespace) if wiki_name: url = '{0}/{1}'.format(wiki_name, item_name) else: url = item_name url = '/{0}'.format(url) else: if (rev is None or rev == CURRENT) and endpoint == 'frontend.show_item': # we just want to show latest revision (no special revision given) - # this is the generic interwiki url support, should work for any remote wiki url = join_wiki(wiki_base_url, item_name, field, namespace) else: # rev and/or endpoint was given, assume same URL building as for local wiki. # we need this for moin wiki farms, e.g. to link from search results to # some specific item/revision in another farm wiki. item_name = get_fqname(item_name, field, namespace) local_url = url_for(endpoint, item_name=item_name, rev=rev, _external=False) # we know that everything left of the + belongs to script url, but we # just want e.g. +show/42/FooBar to append it to the other wiki's # base URL. i = local_url.index('/+') path = local_url[i + 1:] url = wiki_base_url + path if regex: url += '?regex={0}'.format(url_quote(regex, charset=CHARSET)) return url
def send_file( filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=None, conditional=False, last_modified=None, ): """Sends the contents of a file to the client. This will use the most efficient method available and configured. By default it will try to use the WSGI server's file_wrapper support. Alternatively you can set the application's :attr:`~Flask.use_x_sendfile` attribute to ``True`` to directly emit an ``X-Sendfile`` header. This however requires support of the underlying webserver for ``X-Sendfile``. By default it will try to guess the mimetype for you, but you can also explicitly provide one. For extra security you probably want to send certain files as attachment (HTML for instance). The mimetype guessing requires a `filename` or an `attachment_filename` to be provided. When passing a file-like object instead of a filename, only binary mode is supported (``open(filename, "rb")``, :class:`~io.BytesIO`, etc.). Text mode files and :class:`~io.StringIO` will raise a :exc:`ValueError`. ETags will also be attached automatically if a `filename` is provided. You can turn this off by setting `add_etags=False`. If `conditional=True` and `filename` is provided, this method will try to upgrade the response stream to support range requests. This will allow the request to be answered with partial content response. Please never pass filenames to this function from user sources; you should use :func:`send_from_directory` instead. .. versionchanged:: 2.0 Passing a file-like object that inherits from :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather than sending an empty file. .. versionchanged:: 1.1 ``filename`` may be a :class:`~os.PathLike` object. .. versionchanged:: 1.1 Passing a :class:`~io.BytesIO` object supports range requests. .. versionchanged:: 1.0.3 Filenames are encoded with ASCII instead of Latin-1 for broader compatibility with WSGI servers. .. versionchanged:: 1.0 UTF-8 filenames, as specified in `RFC 2231`_, are supported. .. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4 .. versionchanged:: 0.12 The filename is no longer automatically inferred from file objects. If you want to use automatic MIME and etag support, pass a filename via ``filename_or_fp`` or ``attachment_filename``. .. versionchanged:: 0.12 ``attachment_filename`` is preferred over ``filename`` for MIME detection. .. versionchanged:: 0.9 ``cache_timeout`` defaults to :meth:`Flask.get_send_file_max_age`. .. versionchanged:: 0.7 MIME guessing and etag support for file-like objects was deprecated because it was unreliable. Pass a filename if you are able to, otherwise attach an etag yourself. This functionality will be removed in Flask 1.0. .. versionadded:: 0.5 The ``add_etags``, ``cache_timeout`` and ``conditional`` parameters were added. The default behavior is to add etags. .. versionadded:: 0.2 :param filename_or_fp: The filename of the file to send, relative to :attr:`~Flask.root_path` if a relative path is specified. Alternatively, a file-like object opened in binary mode. Make sure the file pointer is seeked to the start of the data. ``X-Sendfile`` will only be used with filenames. :param mimetype: the mimetype of the file if provided. If a file path is given, auto detection happens as fallback, otherwise an error will be raised. :param as_attachment: set to ``True`` if you want to send this file with a ``Content-Disposition: attachment`` header. :param attachment_filename: the filename for the attachment if it differs from the file's filename. :param add_etags: set to ``False`` to disable attaching of etags. :param conditional: set to ``True`` to enable conditional responses. :param cache_timeout: the timeout in seconds for the headers. When ``None`` (default), this value is set by :meth:`~Flask.get_send_file_max_age` of :data:`~flask.current_app`. :param last_modified: set the ``Last-Modified`` header to this value, a :class:`~datetime.datetime` or timestamp. If a file was passed, this overrides its mtime. """ mtime = None fsize = None if hasattr(filename_or_fp, "__fspath__"): filename_or_fp = os.fspath(filename_or_fp) if isinstance(filename_or_fp, str): filename = filename_or_fp if not os.path.isabs(filename): filename = os.path.join(current_app.root_path, filename) file = None if attachment_filename is None: attachment_filename = os.path.basename(filename) else: file = filename_or_fp filename = None if mimetype is None: if attachment_filename is not None: mimetype = (mimetypes.guess_type(attachment_filename)[0] or "application/octet-stream") if mimetype is None: raise ValueError( "Unable to infer MIME-type because no filename is available. " "Please set either `attachment_filename`, pass a filepath to " "`filename_or_fp` or set your own MIME-type via `mimetype`.") headers = Headers() if as_attachment: if attachment_filename is None: raise TypeError( "filename unavailable, required for sending as attachment") if not isinstance(attachment_filename, str): attachment_filename = attachment_filename.decode("utf-8") try: attachment_filename = attachment_filename.encode("ascii") except UnicodeEncodeError: quoted = url_quote(attachment_filename, safe="") filenames = { "filename": unicodedata.normalize("NFKD", attachment_filename).encode( "ascii", "ignore"), "filename*": f"UTF-8''{quoted}", } else: filenames = {"filename": attachment_filename} headers.add("Content-Disposition", "attachment", **filenames) if current_app.use_x_sendfile and filename: if file is not None: file.close() headers["X-Sendfile"] = filename fsize = os.path.getsize(filename) data = None else: if file is None: file = open(filename, "rb") mtime = os.path.getmtime(filename) fsize = os.path.getsize(filename) elif isinstance(file, io.BytesIO): fsize = file.getbuffer().nbytes elif isinstance(file, io.TextIOBase): raise ValueError( "Files must be opened in binary mode or use BytesIO.") data = wrap_file(request.environ, file) if fsize is not None: headers["Content-Length"] = fsize rv = current_app.response_class(data, mimetype=mimetype, headers=headers, direct_passthrough=True) if last_modified is not None: rv.last_modified = last_modified elif mtime is not None: rv.last_modified = mtime rv.cache_control.public = True if cache_timeout is None: cache_timeout = current_app.get_send_file_max_age(filename) if cache_timeout is not None: rv.cache_control.max_age = cache_timeout rv.expires = int(time() + cache_timeout) if add_etags and filename is not None: from warnings import warn try: check = (adler32( filename.encode("utf-8") if isinstance(filename, str ) else filename) & 0xFFFFFFFF) rv.set_etag( f"{os.path.getmtime(filename)}-{os.path.getsize(filename)}-{check}" ) except OSError: warn( f"Access {filename} failed, maybe it does not exist, so" " ignore etags in headers", stacklevel=2, ) if conditional: try: rv = rv.make_conditional(request, accept_ranges=True, complete_length=fsize) except RequestedRangeNotSatisfiable: if file is not None: file.close() raise # make sure we don't send x-sendfile for servers that # ignore the 304 status code for x-sendfile. if rv.status_code == 304: rv.headers.pop("x-sendfile", None) return rv
def wsd_upload_file(self, upload, alt='File', filename=None, is_image=False, **post_data): Attachments = request.env['ir.attachment'].sudo() attachment_data = { 'name': alt, # TODO: How to use file type checking for case 'upload'? 'datas_fname': filename or 'upload', 'public': False, } if post_data.get('request_id'): try: attachment_data['res_id'] = int(post_data.get('request_id')) except (ValueError, TypeError): _logger.debug("Cannon convert request_id %r", post_data.get('request_id'), exc_info=True) else: attachment_data['res_model'] = 'request.request' # Check max filesize and return error if file is too big upload.seek(0, os.SEEK_END) file_size = upload.tell() max_size = self._get_max_upload_size() if max_size and file_size > max_size: _logger.warning("File size is too big: %s > %s", file_size, max_size) return json.dumps({ 'status': 'FAIL', 'success': False, 'message': _("File size is too big!"), }) upload.seek(0, os.SEEK_SET) try: data = upload.read() if is_image: data = self._optimize_image(data, disable_optimization=False) attachment = Attachments.create( dict( attachment_data, datas=base64.b64encode(data), )) except Exception as e: _logger.exception("Failed to upload file to attachment") message = ustr(e) return json.dumps({ 'status': 'FAIL', 'success': False, 'message': message, }) attachment.generate_access_token() if is_image: attachment_url = "%s?access_token=%s" % ( url_quote("/web/image/%d/%s" % (attachment.id, attachment.datas_fname)), attachment.sudo().access_token, ) else: attachment_url = "%s?access_token=%s&download" % ( url_quote("/web/content/%d/%s" % (attachment.id, attachment.datas_fname)), attachment.sudo().access_token, ) return json.dumps({ 'status': 'OK', 'success': True, 'attachment_url': attachment_url, })
def test_bytes_unquoting(self): self.assert_strict_equal( urls.url_unquote(urls.url_quote(u'#%="\xf6', charset='latin1'), charset=None), b'#%="\xf6')
def quote(self, value): if self.has_slug: return self.model.slug.slugify(value) else: return url_quote(value)
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." if options.get('qweb_img_raw_data', False): return super(Image, self).record_to_html(record, field_name, options) aclasses = ['img', 'img-fluid'] if options.get('qweb_img_responsive', True) else ['img'] aclasses += options.get('class', '').split() classes = ' '.join(map(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get( 'max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1( str(getattr(record, '__last_update')).encode('utf-8')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size if options.get('filename-field') and getattr( record, options['filename-field'], None): filename = record[options['filename-field']] elif options.get('filename'): filename = options['filename'] else: filename = record.display_name filename = filename.replace('/', '-').replace('\\', '-') src = '/web/image/%s/%s/%s%s/%s?unique=%s' % ( record._name, record.id, options.get('preview_image', field_name), max_size, url_quote(filename), sha) if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] else: alt = escape(record.display_name) src_zoom = None if options.get('zoom') and getattr(record, options['zoom'], None): src_zoom = '/web/image/%s/%s/%s%s/%s?unique=%s' % ( record._name, record.id, options['zoom'], max_size, url_quote(filename), sha) elif options.get('zoom'): src_zoom = options['zoom'] itemprop = None if options.get('itemprop'): itemprop = options['itemprop'] atts = OrderedDict() atts["src"] = src atts["itemprop"] = itemprop atts["class"] = classes atts["style"] = options.get('style') atts["alt"] = alt atts["data-zoom"] = src_zoom and u'1' or None atts["data-zoom-image"] = src_zoom atts["data-no-post-process"] = options.get('data-no-post-process') atts = self.env['ir.qweb']._post_processing_att( 'img', atts, options.get('template_options')) img = ['<img'] for name, value in atts.items(): if value: img.append(' ') img.append(escape(pycompat.to_text(name))) img.append('="') img.append(escape(pycompat.to_text(value))) img.append('"') img.append('/>') return u''.join(img)
def _encode(self, key): """ we need to get rid of slashes in revids because we put them into URLs and it would confuse the URL routing. """ return url_quote(key, safe='')
def stream_individual_file(self, filesystem_path): """ Return a flask response that's streaming the download of an individual file, and gzip compressing it if the browser supports it. """ use_gzip = self.should_use_gzip() # gzip compress the individual file, if it hasn't already been compressed if use_gzip: if filesystem_path not in self.gzip_individual_files: self.gzip_files.append( tempfile.NamedTemporaryFile( "wb+", dir=self.common.build_tmp_dir())) gzip_file = self.gzip_files[-1] self._gzip_compress(filesystem_path, gzip_file.name, 6, None) self.gzip_individual_files[filesystem_path] = gzip_file.name # Cleanup this temp file self.web.cleanup_tempfiles.append(gzip_file) file_to_download = self.gzip_individual_files[filesystem_path] filesize = os.path.getsize( self.gzip_individual_files[filesystem_path]) else: file_to_download = filesystem_path filesize = os.path.getsize(filesystem_path) path = request.path # Tell GUI the individual file started history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_STARTED, path, { "id": history_id, "filesize": filesize }, ) def generate(): chunk_size = 102400 # 100kb fp = open(file_to_download, "rb") done = False while not done: chunk = fp.read(chunk_size) if chunk == b"": done = True else: try: yield chunk # Tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / filesize) * 100 if (not self.web.is_gui or self.common.platform == "Linux" or self.common.platform == "BSD"): sys.stdout.write( "\r{0:s}, {1:.2f}% ".format( self.common.human_readable_filesize( downloaded_bytes), percent, )) sys.stdout.flush() self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_PROGRESS, path, { "id": history_id, "bytes": downloaded_bytes, "filesize": filesize, }, ) done = False except Exception: # Looks like the download was canceled done = True # Tell the GUI the individual file was canceled self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_CANCELED, path, {"id": history_id}, ) fp.close() if self.common.platform != "Darwin": sys.stdout.write("\n") basename = os.path.basename(filesystem_path) r = Response(generate()) if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", filesize) filename_dict = { "filename": unidecode(basename), "filename*": "UTF-8''%s" % url_quote(basename), } r.headers.set("Content-Disposition", "inline", **filename_dict) (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: r.headers.set("Content-Type", content_type) return r