This is an ongoing effort to please GMail and the likes, so Benitlux emails are no longer sent to the spam folder. Which is vital to keep @R4PaSs happy, hydrated and productive.
This PR adds headers to the email to make it clear that it is a mailing list and to guide the assisted unsubscribe option. Specifying the street name will help differentiate between the emails from the two mailing lists. (One of which is not exposed on the website, it is available on request only.)
I've also added DKIM (to the existing SPF) as server identification, it should help a lot too.
Pull-Request: #1680
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Jean-Philippe Caissy <jpcaissy@piji.ca>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Christophe Gigax <christophe.gigax@viacesi.fr>
Julien Pagès <julien.projet@gmail.com>
+
+Mehdi Ait Younes <overpex@gmail.com>
+
+Hervé Matysiak <herve.matysiak@viacesi.fr>
var res = new Array[String]
for l in logins do
var u = get_and_check("https://api.github.com/users/{l}").json_as_map
- if not u.has_key("name") then
- print "No public name for user {l}"
+ if not u.has_key("name") or u["name"] == null or not u.has_key("email")or u["email"] == null then
+ print "No public name/email for user {l}"
continue
end
var r = "{u["name"].to_s} <{u["email"].to_s}>"
# Returns the config value at `key` or return `default` if no key was found.
private fun value_or_default(key: String, default: String): String do
- if not has_key(key) then return default
- return self[key]
+ return self[key] or else default
end
# Site name displayed.
# Returns `self` as a String of `length`.
fun to_s_with_length(length: Int): String is abstract
+
+ # Returns `self` as a String with `bytelen` and `length` set
+ #
+ # SEE: `abstract_text::Text` for more infos on the difference
+ # between `Text::bytelen` and `Text::length`
+ fun to_s_full(bytelen, unilen: Int): String is abstract
end
redef class NativeArray[E]
do
written = true
if bytelen == 0 then items = new NativeString(1)
- return new FlatString.with_infos(items, bytelen, 0, bytelen - 1)
+ return new FlatString.full(items, bytelen, 0, bytelen - 1, length)
end
redef fun to_cstring
redef fun times(repeats)
do
- var x = new FlatString.with_infos(items, bytelen, 0, bytelen - 1)
+ var x = new FlatString.full(items, bytelen, 0, bytelen - 1, length)
for i in [1 .. repeats[ do
append(x)
end
return str
end
+ redef fun to_s_full(bytelen, unilen) do
+ return new FlatString.full(self, bytelen, 0, bytelen - 1, unilen)
+ end
+
# Returns `self` as a new String.
redef fun to_s_with_copy: FlatString
do
var ns = new NativeString(nlen + 1)
mits.copy_to(ns, mlen, mifrom, 0)
sits.copy_to(ns, slen, sifrom, mlen)
- return ns.to_s_with_length(nlen)
+ return new FlatString.full(ns, nlen, 0, nlen - 1, length + s.length)
else if s isa Concat then
var sl = s.left
var sllen = sl.bytelen
# Get the config value for `key`
#
- # REQUIRE: `has_key(key)`
- #
# var config = new ConfigTree("config.ini")
# assert config["goo"] == "goo"
# assert config["foo.bar"] == "foobar"
# assert config["foo.baz"] == "foobaz"
- fun [](key: String): String do
- if not has_key(key) then
- print "error: config key `{key}` not found"
- abort
- end
- var node = get_node(key).as(not null)
- if node.value == null then
- print "error: config key `{key}` has no value"
- abort
- end
- return node.value.as(not null)
+ # assert config["fail.fail"] == null
+ fun [](key: String): nullable String do
+ var node = get_node(key)
+ if node == null then return null
+ return node.value
end
# Get the config values under `key`
#
- # REQUIRE: `has_key(key)`
- #
# var config = new ConfigTree("config.ini")
# var values = config.at("foo")
# assert values.has_key("bar")
# assert values.has_key("baz")
# assert not values.has_key("goo")
- fun at(key: String): Map[String, String] do
- if not has_key(key) then
- print "error: config key `{key}` not found"
- abort
- end
+ #
+ # Return null if the key does not exists.
+ #
+ # assert config.at("fail.fail") == null
+ fun at(key: String): nullable Map[String, String] do
+ var node = get_node(key)
+ if node == null then return null
var map = new HashMap[String, String]
- var node = get_node(key).as(not null)
for k, child in node.children do
if child.value == null then continue
map[k] = child.value.to_s
private fun get_node(key: String): nullable ConfigNode do
var parts = key.split(".").reversed
var node = get_root(parts.pop)
- while not parts.is_empty do
+ while node != null and not parts.is_empty do
node = node.get_child(parts.pop)
end
return node
var native_mtype = mmodule.native_string_type
var nat = self.new_var(native_mtype)
self.add("{nat} = \"{string.escape_to_c}\";")
- var length = self.int_instance(string.bytelen)
- self.add("{res} = {self.send(self.get_property("to_s_with_length", native_mtype), [nat, length]).as(not null)};")
+ var bytelen = self.int_instance(string.bytelen)
+ var unilen = self.int_instance(string.length)
+ self.add("{res} = {self.send(self.get_property("to_s_full", native_mtype), [nat, bytelen, unilen]).as(not null)};")
self.add("{name} = {res};")
self.add("\}")
return res
fun string_instance(txt: String): Instance
do
var nat = native_string_instance(txt)
- var res = self.send(self.force_get_primitive_method("to_s_with_length", nat.mtype), [nat, self.int_instance(txt.bytelen)])
+ var res = self.send(self.force_get_primitive_method("to_s_full", nat.mtype), [nat, self.int_instance(txt.bytelen), self.int_instance(txt.length)])
assert res != null
return res
end
var mgroup
if parent == null then
# no parent, thus new project
- var namekey = "project.name"
- if ini != null and ini.has_key(namekey) then pn = ini[namekey]
+ if ini != null then pn = ini["project.name"] or else pn
var mproject = new MProject(pn, model)
mgroup = new MGroup(pn, mproject, null) # same name for the root group
mproject.root = mgroup
do
var native = v.analysis.mainmodule.native_string_type
v.add_type(native)
- var prop = v.get_method(native, "to_s_with_length")
+ var prop = v.get_method(native, "to_s_full")
v.add_monomorphic_send(native, prop)
end
end
-alt/error_needed_method_alt3.nit:48,9--13: Fatal Error: `NativeString` must have a property named `to_s_with_length`.
+alt/error_needed_method_alt3.nit:48,9--13: Fatal Error: `NativeString` must have a property named `to_s_full`.
-alt/error_needed_method_alt4.nit:49,10--14: Fatal Error: `NativeString` must have a property named `to_s_with_length`.
+alt/error_needed_method_alt4.nit:49,10--14: Fatal Error: `NativeString` must have a property named `to_s_full`.