From: Michael Tremer Date: Sat, 8 Jan 2011 09:53:58 +0000 (+0100) Subject: fireinfo: Add new image. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=abc3bb319823e11d0477b7a7a48a081cf155343a;p=ipfire.org.git fireinfo: Add new image. --- diff --git a/www/templates/i-use/fonts/DejaVuSans-Bold.ttf b/www/templates/i-use/fonts/DejaVuSans-Bold.ttf new file mode 100644 index 00000000..badc808e Binary files /dev/null and b/www/templates/i-use/fonts/DejaVuSans-Bold.ttf differ diff --git a/www/templates/i-use/fonts/DejaVuSans.ttf b/www/templates/i-use/fonts/DejaVuSans.ttf new file mode 100644 index 00000000..e820f025 Binary files /dev/null and b/www/templates/i-use/fonts/DejaVuSans.ttf differ diff --git a/www/templates/i-use/i-use-1.png b/www/templates/i-use/i-use-1.png new file mode 100644 index 00000000..0e591a36 Binary files /dev/null and b/www/templates/i-use/i-use-1.png differ diff --git a/www/templates/i-use/i-use-1.xcf b/www/templates/i-use/i-use-1.xcf new file mode 100644 index 00000000..8f68a885 Binary files /dev/null and b/www/templates/i-use/i-use-1.xcf differ diff --git a/www/translations/de_DE.csv b/www/translations/de_DE.csv index d20a2dbf..64247b6d 100644 --- a/www/translations/de_DE.csv +++ b/www/translations/de_DE.csv @@ -183,3 +183,10 @@ "Bugtracker","Bugtracker" "Development for IPFire 2.x","Entwicklung von IPFire 2.x" "Development for IPFire 3.x","Entwicklung von IPFire 3.x" +"green","grün" +"blue","blau" +"red","rot" +"orange","orange" +"Networks: %s","Netzwerke: %s" +"Mem: %s","RAM: %s" +"Disk: %s","HDD: %s" diff --git a/www/webapp/backend/iuse.py b/www/webapp/backend/iuse.py index 5acefd03..9be180a8 100644 --- a/www/webapp/backend/iuse.py +++ b/www/webapp/backend/iuse.py @@ -3,8 +3,10 @@ from __future__ import division import StringIO +import logging +import os.path -from PIL import Image, ImageDraw, PngImagePlugin +from PIL import Image, ImageDraw, ImageFont, PngImagePlugin from misc import Singleton @@ -28,16 +30,26 @@ class ImageObject(object): default_mode = "RGBA" default_size = 100, 100 - def __init__(self, profile): + _filename = None + _font = "DejaVuSans.ttf" + _font_size = 10 + + def __init__(self, request, profile): + self.request = request self.profile = profile # Create new image - self._image = Image.new(self.default_mode, self.default_size) + if self.filename and os.path.exists(self.filename): + self.open(self.filename) + else: + self._image = Image.new(self.default_mode, self.default_size) self.draw() def open(self, filename): - image = Image.open(filename, self.default_mode) + logging.debug("Opening image as a template: %s" % filename) + + image = Image.open(filename) self._image = image.convert(self.default_mode) def save(self, filename): @@ -60,35 +72,115 @@ class ImageObject(object): def draw(self): raise NotImplementedError + @property + def font(self): + if not hasattr(self, "__font"): + fontfile = os.path.join( + self.request.application.settings.get("template_path", ""), + "i-use", "fonts", self._font + ) + + self.__font = ImageFont.truetype(fontfile, self._font_size, encoding="unic") + + return self.__font + + def draw_text(self, pos, text, **kwargs): + if not kwargs.has_key("font"): + kwargs["font"] = self.font + + return self.paint.text(pos, text, **kwargs) + + @property + def filename(self): + if not self._filename: + return + + return os.path.join( + self.request.application.settings.get("template_path", ""), + "i-use", self._filename + ) + + @property + def locale(self): + return self.request.locale + + +#class Image1(ImageObject): +# id = 0 +# +# default_size = 500, 50 +# +# def draw(self): +# # Background +# self.paint.rectangle(((0, 0), self.default_size), fill="#000000") +# +# # Release information +# self.paint.text((10, 10), "%s" % self.profile.release) +# +# # Hardware information +# hw = [ +# self.profile.cpu.model_string, +# "Mem: %.1fG" % (self.profile.memory / 1024**2), +# ] +# +# if self.profile.virtual: +# virt = "V-%s" % self.profile.hypervisor.vendor +# if self.profile.hypervisor.type == "para": +# virt = "%s-PV" % virt +# hw.append(virt) +# +# if self.profile.cpu.capable_64bit: +# hw.append("64") +# +# self.paint.text((10, 30), "%s" % " | ".join(hw)) +# +# +#IUse().add_imagetype(Image1) + class Image1(ImageObject): id = 0 default_size = 500, 50 - def draw(self): - # Background - self.paint.rectangle(((0, 0), self.default_size), fill="#000000") + _filename = "i-use-1.png" + _font = "DejaVuSans-Bold.ttf" + _font_size = 9 - # Release information - self.paint.text((10, 10), "%s" % self.profile.release) + def draw(self): + _ = self.locale.translate - # Hardware information - hw = [ - self.profile.cpu.model_string, - "Mem: %.1fG" % (self.profile.memory / 1024**2), - ] + line1 = [self.profile.release,] if self.profile.virtual: virt = "V-%s" % self.profile.hypervisor.vendor if self.profile.hypervisor.type == "para": virt = "%s-PV" % virt - hw.append(virt) + line1.append(virt) + + self.draw_text((225, 8), " | ".join(line1)) + + line2 = [] + line2.append(self.profile.cpu.friendly_string) + line2.append(_("Mem: %s") % self.profile.friendly_memory) + + if self.profile.root_size: + line2.append(_("Disk: %s") % self.profile.friendly_root_size) + + line3 = [] + + if self.profile.network: + zones = [] + + for zone in ("green", "red", "blue", "orange"): + if self.profile.network.has_zone(zone): + zones.append(_(zone)) - if self.profile.cpu.capable_64bit: - hw.append("64") + if zones: + line3.append(_("Networks: %s") % " | ".join(zones)) - self.paint.text((10, 30), "%s" % " | ".join(hw)) + self.draw_text((225, 20), "%s" % " - ".join(line2)) + self.draw_text((225, 32), "%s" % " - ".join(line3)) IUse().add_imagetype(Image1) diff --git a/www/webapp/backend/stasy.py b/www/webapp/backend/stasy.py index 9375cf7c..c2f46bbd 100644 --- a/www/webapp/backend/stasy.py +++ b/www/webapp/backend/stasy.py @@ -5,6 +5,7 @@ from __future__ import division import hwdata import logging import pymongo +import re from misc import Singleton @@ -14,6 +15,33 @@ DATABASE_NAME = "stasy" CPU_SPEED_CONSTRAINTS = (0, 500, 1000, 1500, 2000, 2500, 3000, 3500) MEMORY_CONSTRAINTS = (0, 128, 256, 512, 1024, 2048, 4096, 8128, 16384) +CPU_STRINGS = ( + # AMD + (r"(AMD Athlon).*(XP).*", r"\1 \2"), + (r"(AMD Phenom).* ([0-9]+) .*", r"\1 \2"), + (r"(AMD Phenom).*", r"\1"), + (r"(AMD Sempron).*", r"\1"), + (r"AMD Athlon.* II X2 ([a-z0-9]+).*", r"AMD Athlon X2 \1"), + (r"(Geode).*", r"\1"), + + # Intel + (r"Intel.*(Atom|Celeron).*CPU\s*([A-Z0-9]+) .*", r"Intel \1 \2"), + (r"(Intel).*(Celeron).*", r"\1 \2"), + (r"Intel.* Core.*2 Duo CPU .* ([A-Z0-9]+) .*", r"Intel C2D \1"), + (r"Intel.* Core.*2 CPU .* ([A-Z0-9]+) .*", r"Intel C2 \1"), + (r"Intel.* Core.*2 Quad CPU .* ([A-Z0-9]+) .*", r"Intel C2Q \1"), + (r"Intel.* Xeon.* CPU .* ([A-Z0-9]+) .*", r"Intel Xeon \1"), + (r"(Intel).*(Xeon).*", r"\1 \2"), + (r"Intel.* Pentium.* (D|4) .*", r"Intel Pentium \1"), + (r"Intel.* Pentium.* Dual .* ([A-Z0-9]+) .*", r"Intel Pentium Dual \1"), + (r"Pentium.* Dual-Core .* ([A-Z0-9]+) .*", r"Intel Pentium Dual \1"), + (r"(Pentium I{2,3}).*", r"Intel \1"), + (r"(Celeron \(Coppermine\))", r"Intel Celeron"), + + # VIA + (r"(VIA \w*).*", r"\1"), +) + class ProfileDict(object): def __init__(self, data): self._data = data @@ -32,6 +60,13 @@ class ProfileCPU(ProfileDict): def speed(self): return self._data.get("speed") + @property + def friendly_speed(self): + if self.speed < 1000: + return "%dMHz" % self.speed + + return "%.1fGHz" % round(self.speed / 1000, 1) + @property def bogomips(self): return self._data.get("bogomips") @@ -64,6 +99,20 @@ class ProfileCPU(ProfileDict): def capable_virt(self): return "vmx" in self.flags or "svm" in self.flags + @property + def friendly_vendor(self): + s = self.model_string + for pattern, repl in CPU_STRINGS: + if re.match(pattern, s) is None: + continue + return re.sub(pattern, repl, s) + + return s + + @property + def friendly_string(self): + return "%s @ %s" % (self.friendly_vendor, self.friendly_speed) + class ProfileHypervisor(ProfileDict): def __repr__(self): @@ -256,10 +305,37 @@ class Profile(ProfileDict): def memory(self): return self.system.get("memory") + @property + def friendly_memory(self): + units = ("k", "M", "G", "T") + + mem = self.memory + i = 0 + while mem >= 1024: + mem /= 1024 + i += 1 + + return "%d%s" % (round(mem, 0), units[i]) + @property def root_size(self): return self.system.get("root_size") or 0 + @property + def friendly_root_size(self): + units = ("k", "M", "G", "T") + + size = self.root_size + if not size: + return + + i = 0 + while size >= 1024: + size /= 1024 + i += 1 + + return "%d%s" % (round(size, 0), units[i]) + @property def vendor(self): return self.system.get("vendor") @@ -645,34 +721,3 @@ class Stasy(object): if __name__ == "__main__": s = Stasy() - print s.get_profile("0" * 40) - print s.cpu_vendors - for id in s.secret_ids: - print "\t", id - - #for p in s._db.profiles.find(): - # print p - - print s.cpu_map - print s.memory_map - print s.memory_average - print s.hypervisor_vendors - print s.hypervisor_models - print s.languages - print s.language_maps - print s.vendors - print s.vendor_map - print s.models - print s.cpus - print s.cpu_map - print s.arches - print s.arch_map - print s.kernels - print s.kernel_map - print s.releases - print s.release_map - - p = s.get_profile("0b5f4fe2162fdfbfa29b632610e317078fa70d34") - print p._data -# print p.hypervisor - diff --git a/www/webapp/handlers_iuse.py b/www/webapp/handlers_iuse.py index 62e0eb37..e0b003a6 100644 --- a/www/webapp/handlers_iuse.py +++ b/www/webapp/handlers_iuse.py @@ -1,5 +1,6 @@ #!/usr/bin/python +import logging import tornado.web from handlers_base import * @@ -15,12 +16,20 @@ class IUseImage(BaseHandler): return backend.Stasy() def get(self, profile_id, image_id): + image = None # Try to get the image from memcache. If we have a cache miss we # build a new one. - mem_id = "iuse-%s-%s" % (profile_id, image_id) - image = self.memcached.get(mem_id) + mem_id = "iuse-%s-%s-%s" % (profile_id, image_id, self.locale.code) + + cache = self.get_argument("cache", "true") + if cache == "true": + image = self.memcached.get(mem_id) + + if image: + logging.debug("Got image from cache for profile: %s" % profile_id) + else: + logging.info("Rendering new image for profile: %s" % profile_id) - if not image: image_cls = self.iuse.get_imagetype(image_id) if not image_cls: raise tornado.web.HTTPError(404, "Image class is unknown: %s" % image_id) @@ -30,7 +39,7 @@ class IUseImage(BaseHandler): raise tornado.web.HTTPError(404, "Profile '%s' was not found." % profile_id) # Render the image - image = image_cls(profile).to_string() + image = image_cls(self, profile).to_string() # Save the image to the memcache for 15 minutes self.memcached.set(mem_id, image, 15*60)