Commits

Guido Draheim committed 53cef84

welcome form for infos

  • Participants
  • Parent commits 9d4f631
  • Branches trunk

Comments (0)

Files changed (4)

File src/setup.py

     'UserscriptServerNotes.init = usernotes.init',
     'UserscriptServerNotes.settings = usernotes.settings',
     'UserscriptServerNotes.notes_mail = usernotes.notes_mail',
+    'UserscriptServerNotes.notes_info = usernotes.notes_info',
     'UserscriptServerNotes.web_nav = usernotes.web_nav',
     'UserscriptServerNotes.web_ui = usernotes.web_ui',
   ]},

File src/usernotes/db/model.py

-import usernotes.db.db1 as _db
+import usernotes.db.db2 as _db
 
 NotesMail = _db.NotesMail
+NotesInfo = _db.NotesInfo
+NotesFields = _db.NotesFields

File src/usernotes/notes_info.py

+import re, sys
+import datetime, string
+import collections
+
+from trac.core import Component, implements, ExtensionPoint
+from trac.util import Markup #, format_datetime
+
+from trac.web import IRequestHandler
+from trac.perm import IPermissionRequestor
+from trac.web.chrome import INavigationContributor, ITemplateProvider
+from trac.config import Option, ListOption, PathOption, BoolOption
+from trac.web.chrome import add_stylesheet, add_script
+from trac.util.presentation import Paginator
+from trac.util import Markup, format_datetime
+from trac.util.datefmt import localtz
+
+from trac.util.translation import domain_functions
+_, tag_, N_, ngettext, add_domain = domain_functions('usernotes',
+    '_', 'tag_', 'N_', 'ngettext', 'add_domain')
+
+import cgi
+import logging
+import string
+from time import strftime, localtime
+import os.path
+
+from sqlalchemy import Column, Integer, String
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy import create_engine
+from sqlalchemy.orm import create_session
+from sqlalchemy.sql import desc
+import sqlalchemy.sql.functions as by
+
+from db.session import context
+from db.model import NotesMail
+
+import web_nav
+
+PACKAGE = "usernotes"
+TITLE = "Userscript ServerNotes Info"
+
+import os.path
+
+def strU(text):
+    try:
+        return unicode(text)
+    except:
+        return unicode(str(text), "utf-8")
+def str8_(text):
+    if isinstance(text, unicode):
+        return text.encode("utf-8")
+    else:
+        return str(text)
+def str8(text):
+    return str(text)
+
+def esc(text):
+    if not text: return u""
+    return cgi.escape(strU(text))
+
+class UserNotesInfo(Component):
+    """ allows to store extra fields for a user on a remote site """
+    
+    implements(IRequestHandler)
+
+    domainlist = ListOption(PACKAGE, "domain_list", "domain1, domain2",
+          doc="The domains that you want to create databases for")
+    
+    def __init__(self):
+        locale_dir = os.path.join(os.path.dirname(__file__), "locale")
+        add_domain(self.env.path, locale_dir)
+        
+    
+    """
+      Determines if request should be handled by this plugin.
+    """
+    def match_request(self, req):
+        m = re.match(r"/%s\b/%s\b(/.*)?" % (web_nav.URL, web_nav.INFO), req.path_info)
+        if not m:
+            return False
+        domainpage = m.group(1)
+        if not domainpage: domainpage = ""
+        req.args["domainpage"] = domainpage
+        return True
+
+    """
+      Handles display, append and delete requests on this plugin.
+    """
+    def process_request(self, req):
+        req.perm.assert_permission(web_nav.VIEW)
+        self.locale_dir = os.path.join(os.path.dirname(__file__), "locale")
+        domainpage = req.args["domainpage"]
+        if domainpage:
+            return self.do_info(req, domainpage)
+        return self.do_default(req, message="[%s]" % domainpage)
+
+    def do_default(self, req, message=""):
+        data = {}
+        data["title"] = TITLE
+        data["domains"] = self._domains(req)
+        data["message"] = message
+        data["ngettext"] = ngettext
+        data["_"] = _
+        add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+        add_script(req, 'common/js/trac.js')
+        add_script(req, 'common/js/wikitoolbar.js')
+        return ('usernotes_default.html', data, None)
+
+    def home_url(self, req, domain): 
+        return Markup(u'<div><a href="%s">[welcome]</a></div>' % self.base_url(req, domain))
+    def base_url(self, req, domain):
+        return req.href(web_nav.URL + "/" + web_nav.MAIL + "/" + domain)
+    def do_info(self, req, path):
+        username = req.authname
+        m = re.match("^/([^/]+)(/.*)?", path)
+        if m and username:
+            add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+            add_script(req, 'common/js/trac.js')
+            domain = m.group(1)
+            render = m.group(2)
+            base_url = self.base_url(req, domain)
+            op = req.args.get("op", "")
+            if not op: op = render
+            # xx._scripts = _scripts
+            if op == "showall":
+                return self.do_showall(req, domain)
+            elif op == "userlist":
+                return self.do_userlist(req, domain)
+            elif op == "search":
+                return self.do_search(req, domain)
+            elif op == "insert":
+                return self.do_insert(req, domain)
+            else:
+                return self.do_welcome(req, domain)
+        else:
+            return self.do_default(req, path)
+        
+    def do_welcome(self, req, domain):
+        data = {}
+        data["domain"] = domain
+        data["username"] = req.authname
+        data["title"] = TITLE
+        data["domains"] = self._domains(req)
+        data["message"] = None
+        data["ngettext"] = ngettext
+        data["_"] = _
+        add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+        add_script(req, 'common/js/trac.js')
+        add_script(req, 'common/js/wikitoolbar.js')
+        return "notes_info_index.html", data, None
+        
+    def _domains(self, req):
+        return self.domainlist
+    def do_import(self, req, sell):
+        created = 0
+        current_time = datetime.datetime.now()
+        domain = sell._domain
+        all2 = sell.all()
+        session = context(self.env)
+        try:
+            for old in all2:
+                item = NotesMail()
+                item.created_by = req.authname
+                item.created_on = current_time
+                item.mail_domain = sell._domain 
+                item.mail_from = self.to_unicode(old.mail_from)
+                item.mail_user = self.to_unicode(old.mail_user)
+                item.mail_date = self.to_datetime(old.mail_date)
+                item.mail_date = item.mail_date + datetime.timedelta(milliseconds = created)
+                item.mail_call = self.to_unicode(old.mail_call)
+                item.mail_text = self.to_unicode(old.mail_text)
+                item.mail_info = self.to_unicode(old.mail_info)
+                item.mimetype = old.mimetype
+                item.encrypted = old.encrypted
+                session.add(item)
+                created += 1
+            session.flush()
+            return self.do_default(req, "imported %s entries from %s" % (created, sell.database_name())) 
+        except Exception, e:
+            session.rollback()
+            return self.do_default(req, "ERROR: %s" % e)
+    def to_datetime(self, old):
+        if not old or len(old) < 12 or old.startswith("("):
+            now = datetime.datetime(2000,1,1,0,0, tzinfo = localtz) 
+            return now 
+        if old.startswith("1000"): 
+            now = datetime.datetime(2000,1,1,0,0, tzinfo = localtz) 
+            return now 
+        if old[8] not in string.digits:
+            old = old[0:8] + "0000"
+        self.log.warning("OLD '%s'", old)
+        _ = long(old)
+        return datetime.datetime(int(old[0:4]),
+                                     int(old[4:6]),
+                                     int(old[6:8]),
+                                     int(old[8:10]),
+                                     int(old[10:12]), 
+                                     tzinfo = localtz)
+    def color_mail_user(self, mail_user):
+        return u"#" + (((u"222" + strU(hash(mail_user)))[-3:]).replace(u"0", u"A").replace(u"1", u"B"))
+    def do_userlist(self, req, domain):
+        Item = collections.namedtuple("Item", ["mail_user", "mail_date"])
+        session = context(self.env)
+        q = session.query(NotesMail.mail_user, by.max(NotesMail.mail_date))
+        q = q.group_by(NotesMail.mail_user).order_by(desc(NotesMail.mail_date))
+        datalist = []
+        for item in q.all():
+            datalist.append(Item(*item))
+        message = "found %s entries" % len(datalist)
+        base_url = req.href(web_nav.URL + "/" + web_nav.MAIL + "/" + domain)
+        data = {}
+        data["base_url"] = base_url
+        data["color_mail_user"] = self.color_mail_user
+        data["localtz"] = localtz
+        data["datalist"] = datalist
+        data["domains"] = self._domains(req)
+        data["title"] = TITLE
+        data["domains"] = self._domains(req)
+        data["message"] = message
+        data["ngettext"] = ngettext
+        data["_"] = _
+        add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+        add_script(req, 'common/js/trac.js')
+        add_script(req, 'common/js/wikitoolbar.js')
+        return ('notes_mail_userlist.html', data, None)
+    def do_search(self, req, domain):
+        mail_user = req.args.get("user", "")
+        if not mail_user:
+            self.log.info("no 'user' on search")
+            req.send_response(400)
+            return self.do_default(req, "no 'user' on search")
+        data = {}
+        data["home_url"] = self.home_url(req, domain)
+        data["mail_user"] = mail_user
+        session = context(self.env)
+        q = session.query(NotesMail.mail_from, NotesMail.mail_user, NotesMail.mail_date,
+                                NotesMail.mail_call, NotesMail.mail_text, NotesMail.mail_info,
+                                NotesMail.mimetype, NotesMail.encrypted)
+        q = q.filter_by(mail_user=mail_user)
+        q = q.order_by(desc(NotesMail.mail_date))
+        datalist = []
+        for item in q.all():
+            datalist.append(item)
+        message = len(datalist)
+        data["datalist"] = datalist
+        data["markup_mail_info"] = self.markup_mail_info
+        data["markup_mail_text"] = self.markup_mail_text
+        data["domains"] = self._domains(req)
+        data["title"] = TITLE
+        data["domains"] = self._domains(req)
+        data["message"] = message
+        data["ngettext"] = ngettext
+        data["_"] = _
+        add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+        add_script(req, 'common/js/trac.js')
+        add_script(req, 'common/js/wikitoolbar.js')
+        return ('notes_mail_textlist.html', data, None)
+    def do_showall(self, req, domain):
+        data = {}
+        data["home_url"] = self.home_url(req, domain)
+        data["mail_user"] = "ALL"
+        session = context(self.env)
+        q = session.query(NotesMail.mail_from, NotesMail.mail_user, NotesMail.mail_date,
+                                NotesMail.mail_call, NotesMail.mail_text, NotesMail.mail_info,
+                                NotesMail.mimetype, NotesMail.encrypted)
+        q = q.order_by(desc(NotesMail.mail_date))
+        datalist = []
+        for item in q.all():
+            datalist.append(item)
+        message = len(datalist)
+        data["datalist"] = datalist
+        data["markup_mail_info"] = self.markup_mail_info
+        data["markup_mail_text"] = self.markup_mail_text
+        data["domains"] = self._domains(req)
+        data["title"] = TITLE
+        data["domains"] = self._domains(req)
+        data["message"] = message
+        data["ngettext"] = ngettext
+        data["_"] = _
+        add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+        add_script(req, 'common/js/trac.js')
+        add_script(req, 'common/js/wikitoolbar.js')
+        return ('notes_mail_textlist.html', data, None)
+    def markup_mail_info(self, mail_info):
+        return Markup(self.span_mail_info(mail_info))
+    def span_mail_info(self, mail_info):
+        if not mail_info:
+            return ""
+        info = mail_info.strip()
+        if info.startswith("w "):
+            return u'<span style="color: red">%s</span>' % esc(info).replace(u"w ", u"w&nbsp;")
+        elif info.startswith(u"m "):
+            return u'<span style="color: blue">%s</span>' % esc(info).replace(u"m ", u"m&nbsp;")
+        elif info.startswith("undefined"):
+            return u'<span style="color: #DDD; font-size: xx-small">%s</span>' % esc(info)
+        else:
+            return '<span style="font-size: xx-small">%s</span>' % esc(info)
+    def markup_mail_text(self, mail_text):
+        return Markup(self.span_mail_text(mail_text))
+    def span_mail_text(self, mail_text):
+        if not mail_text:
+            return ""
+        return u"<p>" + esc(mail_text).strip().replace(u"\n\n", u"</p><p>").replace(u"\n", u"<br />") + u"</p>"
+    def do_insert(self, req, domain):
+        mail_from = req.args.get("from", "")
+        mail_user = req.args.get("user", "")
+        import parsedate
+        mail_date = parsedate.parse_datetime(req.args.get("date", ""))
+        mail_call = req.args.get("call", "")
+        mail_text = req.args.get("text", "")
+        mail_info = req.args.get("info", "")
+        mail_body = req.args.get("body", "")
+        mimetype = req.args.get("mimetype", "")
+        encrypted = req.args.get("encrypted", "")
+        if mail_body:
+            mimetype = "text/html"
+            mail_text = mail_body            
+        if not mail_date:
+            req.send_response(400)
+            message = u"datetime %s text not understood" % (req.args.get("date", ""))
+            self.log.info(message)
+            return self.do_default(req, message)
+        if not mail_user:
+            req.send_response(400)
+            message = u"no 'user' on insert %s " % mail_date
+            self.log.info(message)
+            return self.do_default(req, message)
+        session = context(self.env)
+        status = ""
+        try:
+            self.log.info("going to insert %s", mail_user)
+            q = session.query(NotesMail)
+            q = q.filter_by(mail_from=mail_from, mail_user=mail_user, mail_date=mail_date)
+            result = q.count()
+            if result > 0:
+                self.log.info(u"entry does already exist for %s", strU(mail_user))
+                status = u'<div class="status"><span class="statushead">OOPS EXISTS</span>: entry does already exist %s</div>' % esc(result)
+            else:
+                self.log.info("running sql for %s", mail_user)
+                mail = NotesMail(mail_from=mail_from, mail_user=mail_user, mail_date=mail_date,
+                                 mail_call=mail_call, mail_text=mail_text, mail_info=mail_info,
+                                 mimetype=mimetype, encrypted=encrypted,
+                                 mail_domain = domain, 
+                                 created_by = req.authname,
+                                 created_on = datetime.datetime.now())
+                session.add(mail)
+                status = u'<div class="status"><span class="statushead">OK SAVED</span>: entry was saved just fine</div>'
+            session.flush()
+            data = {}
+            data["title"] = TITLE
+            data["domains"] = self._domains(req)
+            data["message"] = Markup(status)
+            data["body"] = self.markup_mail_text(mail_text)
+            data["ngettext"] = ngettext
+            data["_"] = _
+            add_stylesheet(req, PACKAGE + '/css/userscriptservernotes.css')
+            add_script(req, 'common/js/trac.js')
+            add_script(req, 'common/js/wikitoolbar.js')
+            return ('notes_mail_insert.html', data, None)
+        except Exception, e:
+            import traceback
+            message = u"FAIL:(12) " + strU(e) + " @ " + traceback.format_exc()
+            self.log.error(u"OOPS " + strU(e) + " @ " + traceback.format_exc())
+            return self.do_default(req, message)
+

File src/usernotes/templates/notes_info_index.html

+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:py="http://genshi.edgewall.org/"
+	xmlns:xi="http://www.w3.org/2001/XInclude">
+<xi:include href="layout.html" />
+<xi:include href="macros.html" />
+<head>
+<title>${title}</title>
+</head>
+<body>
+	<div id="ctxtnav" class="nav"></div>
+	<xi:include href="usernotes_domains_nav.html" />
+
+	<div id="content">
+		<h2>${title}</h2>
+
+		<py:if test="message">
+			<div class="error">${message}</div>
+		</py:if>
+
+		<h3>INFO</h3>
+		<table>
+			<tr>
+				<td>
+					<form>
+						<input type="hidden" name="op" value="search" />
+						<label for="user">USER:</label>
+						<input type="text" name="user" value="" />
+						<input type="submit" value="SEARCH" />
+					</form>
+				</td>
+				<td class="listbox">
+					<div class="button">
+						<a href="?op=userlist">user list</a>
+					</div>
+				</td>
+				<td class="listbox">
+					<div class="button">
+						<a href="?op=showall">show all</a>
+					</div>
+				</td>
+				<td>&nbsp;</td>
+			</tr>
+		</table>
+		<div style="background-color: #DDD; padding: 1em">
+			<b>Neuer Eintrag:</b>
+			<form>
+				<input type="hidden" name="op" value="insert" />
+				<div>
+					<label for="from">FROM:</label> <input type="text" name="from"
+						value="${username}" /> <label for="info">INFO:</label> <input
+						type="text" name="info" value="" />
+				</div>
+				<div>
+					<label for="user">USER:</label> <input type="text" name="user"
+						value="" /> <label for="date">DATE:</label> <input type="text"
+						name="date" value="${format_datetime(None,'%Y-%m-%d %H:%M')}" />
+				</div>
+				<div>
+					<label for="call">TEXT:</label> <input type="text" name="text"
+						value="" size="55" />
+				</div>
+				<input type="submit" value="SAVE NOTE" />
+			</form>
+		</div>
+	</div>
+</body>
+</html>
+
+