]> git.ipfire.org Git - people/shoehn/ipfire.org.git/commitdiff
fireinfo: Add new image.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 8 Jan 2011 09:53:58 +0000 (10:53 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 8 Jan 2011 09:54:24 +0000 (10:54 +0100)
www/templates/i-use/fonts/DejaVuSans-Bold.ttf [new file with mode: 0644]
www/templates/i-use/fonts/DejaVuSans.ttf [new file with mode: 0644]
www/templates/i-use/i-use-1.png [new file with mode: 0644]
www/templates/i-use/i-use-1.xcf [new file with mode: 0644]
www/translations/de_DE.csv
www/webapp/backend/iuse.py
www/webapp/backend/stasy.py
www/webapp/handlers_iuse.py

diff --git a/www/templates/i-use/fonts/DejaVuSans-Bold.ttf b/www/templates/i-use/fonts/DejaVuSans-Bold.ttf
new file mode 100644 (file)
index 0000000..badc808
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 (file)
index 0000000..e820f02
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 (file)
index 0000000..0e591a3
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 (file)
index 0000000..8f68a88
Binary files /dev/null and b/www/templates/i-use/i-use-1.xcf differ
index d20a2dbf9e693d09dfd2033c0c69fbf78a9309c4..64247b6d755ee46d071fe49ed5547626db057900 100644 (file)
 "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"
index 5acefd038573a489530cdd5ae77c928c0665255b..9be180a87229c472928e485efdbcc7025cf6f6d1 100644 (file)
@@ -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)
index 9375cf7c42d31950ec515a9284380ac489d99c48..c2f46bbd35cf2c0ee116501ce7419f4da18422c5 100644 (file)
@@ -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
-
index 62e0eb378346979517d1f345e66ab0721523945f..e0b003a69668ffaa523ad9d0804796838fbaf457 100644 (file)
@@ -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)