]> git.ipfire.org Git - people/shoehn/ipfire.org.git/commitdiff
Some changes on the admin interface of the planet.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 2 Jan 2011 12:15:48 +0000 (13:15 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 2 Jan 2011 12:15:48 +0000 (13:15 +0100)
www/templates/admin-planet-compose.html
www/templates/downloads.html
www/templates/index.html
www/templates/planet-main.html
www/translations/de_DE.csv
www/webapp/__init__.py
www/webapp/backend/__init__.py
www/webapp/backend/accounts.py
www/webapp/backend/planet.py
www/webapp/handlers_admin.py

index ee9295057a0a4e7d1ca83254ab8854f4a91db867..edf5d3020e2f77dae5746fe7f8381b2aceebf220 100644 (file)
@@ -5,7 +5,9 @@
                <h3>{{ _("Compose new entry") }}</h3>
                <form name="entry" method="post">
                        {{ xsrf_form_html() }}
-                       <input type="hidden" name="id" value="{{ entry.id }}">
+                       {% if entry.id %}
+                               <input type="hidden" name="id" value="{{ entry.id }}">
+                       {% end %}
 
                        <table>
                                <tr>
index 647f18c77861248ca8cc913e6468e91a73d647ff..7164e337b5442c7beea126429ae665976d5dd00b 100644 (file)
        {% if lang == "de" %}
                <p>
                        Auf dieser Seite können Sie <strong>kostenlos</strong> die neueste
-                       Version von IPFire herunterladen. Ältere Versionen oder
-                       andere Downloadoptionen finden Sie weiter unten auf der Seite.
+                       Version von IPFire herunterladen.
                </p>
-
                <p>
-                       IPFire ist innerhalb von 15 bis 20 Minuten eingerichtet.
-                       Eine <a href="http://wiki.ipfire.org/{{ lang }}/installation/start"
-                       target="_blank">Installationsanleitung</a>
-                       ist in unserem Wiki zu finden.
+                       Ältere Versionen oder andere Downloadoptionen finden Sie im
+                       <a href="http://downloads.ipfire.org/">Download Center</a>.
                </p>
        {% else %}
                <p>
                        On this page one can download the latest version of IPFire
-                       <strong>for free</strong>. Older versions and other downloads
-                       can be retrieved on the linked pages below.
+                       <strong>for free</strong>.
                </p>
-
-               <!-- <p>
-                       IPFire can be installed within 15 to 20 minutes. An
-                       <a href="http://wiki.ipfire.org/{{ lang }}/installation/start"
-                       target="_blank">installation guide</a> can be found on our wiki.
-               </p> -->
-
                <p>
-                       Some other things you might be interested in as well:
+                       Older versions and other downloads can be found in the
+                       <a href="http://downloads.ipfire.org/">Download Center</a>.
                </p>
-               <ul>
-                       <li>
-                               <a href="http://wiki.ipfire.org/{{ lang }}/installation/start">{{ _("Installation guide") }}</a>
-                       </li>
-               </ul>
        {% end %}
-       
-       <p>
-               Older downloads can be found in the
-               <a href="http://downloads.ipfire.org/">Download Center</a>.
-       </p>
 
        <br class="clear" />
 
        <br class="clear" />
 
        <h3>{{ _("Donation") }}</h3>
-       <p>
-               If you like IPFire, there is the opportunity to donate a small amount
-               of money to the project. This will help the people that are running
-               this project very much.
-       </p>
-       <p>
-               <div align="center">
-                       <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
-                               <input type="hidden" name="cmd" value="_s-xclick">
-                               <input type="hidden" name="hosted_button_id" value="10781833">
-                               <input type="image" src="https://www.paypal.com/de_DE/DE/i/btn/btn_donateCC_LG.gif"
-                                       border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
-                               <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
-                       </form>
-               </div>
+       {% if lang == "de" %}
+               <p>
+                       Wenn Ihnen IPFire gefällt, gibt es die Möglichkeit mit einer kleinen
+                       Menge Geld das Projekt zu unetrstützen. Diese Unterstützung bedeutet
+                       sehr viel, denn sie hilft das Projekt fortzuführen.
+               </p>
                <br class="clear" />
-       </p>
-       <p>
-               If you want to know more about how you can help the IPFire project
-               read <a href="/donation">this</a>.
-       </p>
+               <p>
+                       <div align="center">
+                               <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+                                       <input type="hidden" name="cmd" value="_s-xclick">
+                                       <input type="hidden" name="hosted_button_id" value="10781833">
+                                       <input type="image" src="https://www.paypal.com/de_DE/DE/i/btn/btn_donateCC_LG.gif"
+                                               border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
+                                       <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
+                               </form>
+                       </div>
+               </p>
+               <br class="clear" />
+               <p>
+                       Um mehr darüber zu erfahren, wie Sie das Projekt unterstützen können,
+                       klicken Sie <a href="/donation">hier</a>.
+               </p>
+       {% else %}
+               <p>
+                       If you like IPFire, there is the opportunity to donate a small amount
+                       of money to the project. This will help the people that are running
+                       this project very much.
+               </p>
+               <br class="clear" />
+               <p>
+                       <div align="center">
+                               <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+                                       <input type="hidden" name="cmd" value="_s-xclick">
+                                       <input type="hidden" name="hosted_button_id" value="10781833">
+                                       <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif"
+                                               border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
+                                       <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
+                               </form>
+                       </div>
+               </p>
+               <br class="clear" />
+               <p>
+                       If you want to know more about how you can help the IPFire project
+                       read <a href="/donation">this</a>.
+               </p>
+       {% end %}
 {% end block %}
 
 {% block sidebar %}
index 6da50a9ebab321e138b04bda81902c9e1f12ba9c..16c096051f5a89b082fa772f2bc26780ca3ab9c1 100644 (file)
@@ -15,7 +15,7 @@
                        in mittleren bis kleinen Unternehmensnetzwerken und Heimnetzwerken.
                </p>
                <p>
-                       Obwohl das System extrem schlank gehalten und gehärtet wurde und können
+                       Obwohl das System extrem schlank gehalten und gehärtet wurde, können
                        Addons mit nur einem Klick installiert werden. Diese Eigenschaft unterscheidet
                        IPFire von anderen Distributionen: IPFire ist einfach zu administrieren
                        aber hat genug Leistung allen Anforderungen gewachsen zu sein.
@@ -36,9 +36,9 @@
 
        <br class="clear" />
 
-       <p>
+       <h4>
                {{ _("See what makes IPFire so great:") }}
-       </p>
+       </h4>
 
        <table class="blocks">
                <tr>
                                {% if lang == "de" %}
                                        <p>
                                                Die oberste Priorität ist die Sicherheit des Systems.
-                                               So werden zum Beispiel Sicherheitsupdates zügig zur
-                                               Verfügung gestellt.
+                                               Zum Beispiel werden Sicherheits- updates regelmäßig und
+                                               zügig verteilt.
                                        </p>
                                {% else %}
                                        <p>
                                                As the most important issue: Security updates
-                                               are deployed regularly and in a timely manner.
+                                               are deployed regularly and promptly.
                                        </p>
                                {% end %}
                                <a href="/about#security">{{ _("Learn more.") }}</a>
@@ -66,7 +66,7 @@
                                <span>{{ _("Flexibility") }}</span>
                                {% if lang == "de" %}
                                        <p>
-                                               Heutzutage ist nichts wichtiger als flexibel zu sein
+                                               Heutzutage ist es auch wichtig flexibel zu sein
                                                und sich der Welt anzupassen. Genau wie IPFire...
                                        </p>
                                {% else %}
@@ -91,7 +91,7 @@
                                {% else %}
                                        <p>
                                                The success of IPFire is based on the community that
-                                               is working on the code an spreading IPFire to the world.
+                                               is working on the code and spreading IPFire to the world.
                                        </p>
                                {% end %}
                                <p>
        <p class="links">
                {{ _("Quick links") }} &bull;
                <a href="/about">{{ _("About IPFire") }}</a>
-               &bull;
-               <a href="/screenshots">{{ _("Screenshots") }}</a>
+               <!-- &bull;
+               <a href="/about">{{ _("Screenshots") }}</a> -->
        </p>
 
-       <br class="clear" />
+       <div class="line"></div>
 
        {% for item in latest_news %}
                {{ modules.NewsItem(item) }}
index bd392bdfb21fefd8cc3e6921614fd7d7ab400380..af9d02b02b30f45d50a4a5c7ff4aac027faa3335 100644 (file)
@@ -40,7 +40,9 @@
                </p>
                -->
        </div>
-       
+
+       <div class="line"></div>
+
        {% for entry in entries %}
                {{ modules.PlanetEntry(entry, short=True) }}
        {% end %}
@@ -56,7 +58,7 @@
 
 {% block sidebar %}
                <h4>{{ _("People on the planet") }}</h4>
-               <ul>
+               <ul class="list">
                        {% for author in authors %}
                                <li>
                                        <a href="/user/{{ author.uid }}">{{ author.cn }}</a>
index 0bc9a8ec262accead24a56fc04fecb3370bd6ae9..1f69ada384e6045960fb336dc44df67cf737a0dd 100644 (file)
 "Virtualization","Virtualisierung"
 "It's free","IPFire ist frei"
 "Packet management","Paketmanagement"
+"Really important guides are:","Empfehlenswerte Artikel sind:"
+"Installation guide","Installationsanleitung"
+"Learn how to start.","Wie fängt man an?"
+"Server","Server"
+"Channel","Channel"
+"Getting support","Support"
+"Concept of the system","Konzept"
+"Hardware section on the wiki","Hardware-Sektion im Wiki"
+"Hardware compatibility list","Hardwarekompatibilitätsliste"
+"networking","Netzwerk"
+
index 8b40a68dbaa387452e0ed7d246b5912847830be4..903cbac377b38842cafb742c118f2c3d637a45d3 100644 (file)
@@ -113,7 +113,7 @@ class Application(tornado.web.Application):
                self.add_handlers(r"planet\.ipfire\.org", [
                        (r"/", PlanetMainHandler),
                        (r"/post/([A-Za-z0-9_-]+)", PlanetPostingHandler),
-                       (r"/user/([a-z0-9]+)", PlanetUserHandler),
+                       (r"/user/([a-z0-9_-]+)", PlanetUserHandler),
                ] + static_handlers)
 
                # stasy.ipfire.org
index 83ecfec134aa795d94ec2c7eea8ba33a191c08f3..288daf63f083f88ee82a80b7523e8e5297e065ea 100644 (file)
@@ -9,7 +9,7 @@ from menu               import Menu
 from mirrors   import Mirrors
 from netboot   import NetBoot
 from news              import News
-from planet            import Planet
+from planet            import Planet, PlanetEntry
 from releases  import Releases
 from settings  import Settings as Config
 from stasy             import Stasy
index a0c072677eb28e7f3ffcfe7ca0ea6946f1fb2507..a0ad046ada2ca5d08d43727146e904b641e45fb6 100644 (file)
@@ -2,6 +2,7 @@
 
 import hashlib
 import ldap
+import logging
 import urllib
 
 from misc import Singleton
@@ -10,6 +11,10 @@ from settings import Settings
 class Accounts(object):
        __metaclass__ = Singleton
 
+       @property
+       def settings(self):
+               return Settings()
+
        def __init__(self):
                self.__db = None
 
@@ -22,13 +27,14 @@ class Accounts(object):
        @property
        def db(self):
                if not self.__db:
-                       ldap_uri = Settings().get("ldap_uri")
+                       ldap_uri = self.settings.get("ldap_uri")
 
                        self.__db = ldap.initialize(ldap_uri)
                        
-                       bind_dn = Settings().get("ldap_bind_dn")
+                       bind_dn = self.settings.get("ldap_bind_dn")
+
                        if bind_dn:
-                               bind_pw = Settings().get("ldap_bind_pw")
+                               bind_pw = self.settings.get("ldap_bind_pw")
 
                                self.__db.simple_bind(bind_dn, bind_pw)
 
index 8323aae1dd2b3140e03e20cd23d861d365fa30ae..3967c228dc94c11df1694961be635e6956038e4c 100644 (file)
@@ -1,6 +1,9 @@
 #!/usr/bin/python
 
+import re
 import textile
+import tornado.database
+import unicodedata
 
 from accounts import Accounts
 from databases import Databases
@@ -8,8 +11,22 @@ from databases import Databases
 from misc import Singleton
 
 class PlanetEntry(object):
-       def __init__(self, entry):
-               self.__entry = entry
+       def __init__(self, entry=None):
+               if entry:
+                       self.__entry = entry
+               else:
+                       self.__entry = tornado.database.Row({
+                               "id" : None,
+                               "title" : "",
+                               "markdown" : "",
+                       })
+
+       def set(self, key, val):
+               self.__entry[key] = val
+
+       @property
+       def planet(self):
+               return Planet()
 
        @property
        def id(self):
@@ -40,9 +57,7 @@ class PlanetEntry(object):
                return self.render(self.markdown, 400)
 
        def render(self, text, limit=0):
-               if limit and len(text) >= limit:
-                       text = text[:limit] + "..."
-               return textile.textile(text)
+               return self.planet.render(text, limit)
 
        @property
        def text(self):
@@ -67,13 +82,18 @@ class Planet(object):
                        if author:
                                authors.append(author)
 
-               return authors
+               return sorted(authors)
 
        def get_entry_by_slug(self, slug):
                entry = self.db.get("SELECT * FROM planet WHERE slug = %s", slug)
                if entry:
                        return PlanetEntry(entry)
 
+       def get_entry_by_id(self, id):
+               entry = self.db.get("SELECT * FROM planet WHERE id = %s", id)
+               if entry:
+                       return PlanetEntry(entry)
+
        def _limit_and_offset_query(self, limit=None, offset=None):
                query = " "
 
@@ -104,7 +124,39 @@ class Planet(object):
                # Respect limit and offset              
                query += self._limit_and_offset_query(limit=limit, offset=offset)
 
-
                entries = self.db.query(query)
 
                return [PlanetEntry(e) for e in entries]
+
+       def render(self, text, limit=0):
+               if limit and len(text) >= limit:
+                       text = text[:limit] + "..."
+               return textile.textile(text)
+
+       def _generate_slug(self, title):
+               slug = unicodedata.normalize("NFKD", title).encode("ascii", "ignore")
+               slug = re.sub(r"[^\w]+", " ", slug)
+               slug = "-".join(slug.lower().strip().split())
+
+               if not slug:
+                       slug = "entry"
+
+               while True:
+                       e = self.db.get("SELECT * FROM planet WHERE slug = %s", slug)
+                       if not e:
+                               break
+                       slug += "-"
+
+               return slug
+
+       def update_entry(self, entry):
+               self.db.execute("UPDATE planet SET title = %s, markdown = %s WHERE id = %s",
+                       entry.title, entry.markdown, entry.id)
+
+       def save_entry(self, entry):
+               slug = self._generate_slug(entry.title)
+
+               self.db.execute("INSERT INTO planet(author_id, title, slug, markdown, published) "
+                       "VALUES(%s, %s, %s, %s, UTC_TIMESTAMP())", entry.author.uid, entry.title,
+                       slug, entry.markdown)
+
index 410be01ef39aea00c17bab28038e55b5300f372b..4096800c9a92a213383be6bf62a7d9f2309adc4e 100644 (file)
@@ -6,8 +6,17 @@ import tornado.web
 
 from handlers_base import *
 
+import backend
 
 class AdminBaseHandler(BaseHandler):
+       @property
+       def accounts(self):
+               return backend.Accounts()
+
+       @property
+       def planet(self):
+               return backend.Planet()
+
        def get_current_user(self):
                return self.get_secure_cookie("account")
 
@@ -47,17 +56,14 @@ class AdminApiPlanetRenderMarkupHandler(AdminBaseHandler):
                text = self.get_argument("text", "")
 
                # Render markup
-               self.write(markdown2.markdown(text))
+               self.write(self.planet.render(text))
                self.finish()
 
 
 class AdminPlanetHandler(AdminBaseHandler):
        @tornado.web.authenticated
        def get(self):
-               entries = self.backend.db.planet.query("SELECT * FROM planet ORDER BY published DESC")
-
-               for entry in entries:
-                       entry.author = self.backend.accounts.search(entry.author_id)
+               entries = self.planet.get_entries(limit=100)
 
                self.render("admin-planet.html", entries=entries)
 
@@ -65,46 +71,30 @@ class AdminPlanetHandler(AdminBaseHandler):
 class AdminPlanetComposeHandler(AdminBaseHandler):
        @tornado.web.authenticated
        def get(self, id=None):
+               entry = backend.PlanetEntry()
+
                if id:
-                       entry = self.backend.db.planet.get("SELECT * FROM planet WHERE id = '%s'", int(id))
-               else:
-                       entry = tornado.database.Row(id="", title="", markdown="")
+                       entry = self.planet.get_entry_by_id(id)
 
                self.render("admin-planet-compose.html", entry=entry)
 
        @tornado.web.authenticated
        def post(self, id=None):
                id = self.get_argument("id", id)
-               title = self.get_argument("title")
-               markdown = self.get_argument("markdown")
-               author = self.backend.accounts.search(self.current_user)
 
-               if id:
-                       entry = self.backend.db.planet.get("SELECT * FROM planet WHERE id = %s", id)
-                       if not entry:
-                               raise tornado.web.HTTPError(404)
+               entry = backend.PlanetEntry()
 
-                       self.backend.db.planet.execute("UPDATE planet SET title = %s, markdown = %s "
-                               "WHERE id = %s", title, markdown, id)
+               if id:
+                       entry = self.planet.get_entry_by_id(id)
 
-                       slug = entry.slug
+               entry.set("title", self.get_argument("title"))
+               entry.set("markdown", self.get_argument("markdown"))
+               entry.set("author_id", self.current_user)
 
+               if id:
+                       self.planet.update_entry(entry)
                else:
-                       slug = unicodedata.normalize("NFKD", title).encode("ascii", "ignore")
-                       slug = re.sub(r"[^\w]+", " ", slug)
-                       slug = "-".join(slug.lower().strip().split())
-
-                       if not slug:
-                               slug = "entry"
-
-                       while True:
-                               e = self.backend.db.planet.get("SELECT * FROM planet WHERE slug = %s", slug)
-                               if not e:
-                                       break
-                               slug += "-"
-
-                       self.backend.db.planet.execute("INSERT INTO planet(author_id, title, slug, markdown, published) "
-                               "VALUES(%s, %s, %s, %s, UTC_TIMESTAMP())", author.uid, title, slug, markdown)
+                       self.planet.save_entry(entry)
 
                self.redirect("/planet")
 
@@ -114,15 +104,13 @@ class AdminPlanetEditHandler(AdminPlanetComposeHandler):
 
 
 class AdminAccountsBaseHandler(AdminBaseHandler):
-       @property
-       def accounts(self):
-               return self.backend.accounts
+       pass
 
 
 class AdminAccountsHandler(AdminAccountsBaseHandler):
        @tornado.web.authenticated
        def get(self):
-               accounts = self.backend.accounts.list()
+               accounts = self.accounts.list()
                self.render("admin-accounts.html", accounts=accounts)
 
 
@@ -148,13 +136,9 @@ class AdminAccountsDeleteHandler(AdminAccountsBaseHandler):
 
 
 class AdminMirrorsBaseHandler(AdminBaseHandler):
-       @property
-       def db(self):
-               return self.backend.db.mirrors
-
        @property
        def mirrors(self):
-               return self.backend.mirrors
+               return backend.Mirrors()
 
 
 class AdminMirrorsHandler(AdminMirrorsBaseHandler):