[prev in list] [next in list] [prev in thread] [next in thread] 

List:       calendarserver-changes
Subject:    [CalendarServer-changes] [7376]
From:       source_changes () macosforge ! org
Date:       2011-04-27 20:10:50
Message-ID: 20110427201051.32F66196E47F () lists ! macosforge ! org
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Revision: 7376
          http://trac.macosforge.org/projects/calendarserver/changeset/7376
Author:   sagen@apple.com
Date:     2011-04-27 13:10:49 -0700 (Wed, 27 Apr 2011)
Log Message:
-----------
Adds the ability to generate "names" within "repeated" users in accounts.xml \
(9339200).

Putting in ~<number> within the name, first-name, last-name, and email-address XML \
elements will substitute that with the first <number> characters from the hash of the \
repeat counter.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml
    CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py
    CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py

Modified: CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml	2011-04-27 \
                18:52:55 UTC (rev 7375)
+++ CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml	2011-04-27 \
20:10:49 UTC (rev 7376) @@ -107,7 +107,10 @@
     <uid>user%02d</uid>
     <guid>user%02d</guid>
     <password>%02duser</password>
-    <name>User %02d</name>
+    <name>~35 User %02d</name>
+    <first-name>~5</first-name>
+    <last-name>~9 User %02d</last-name>
+    <email-address>~10@example.com</email-address>
   </user>
   <group>
     <uid>managers</uid>

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2011-04-27 \
                18:52:55 UTC (rev 7375)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2011-04-27 \
20:10:49 UTC (rev 7376) @@ -39,8 +39,8 @@
         "lecroy"     : { "password": "yorcel",     "guid": \
"8B4288F6-CC82-491D-8EF9-642EF4F3E7D0", "addresses": ("mailto:lecroy@example.com",)   \
                },
         "dreid"      : { "password": "dierd",      "guid": \
"5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1", "addresses": ("mailto:dreid@example.com",)    \
                },
         "nocalendar" : { "password": "radnelacon", "guid": \
                "543D28BA-F74F-4D5F-9243-B3E3A61171E5", "addresses": () },
-        "user01"     : { "password": "01user",     "guid": None                      \
                , "addresses": () },
-        "user02"     : { "password": "02user",     "guid": None                      \
, "addresses": () }, +        "user01"     : { "password": "01user",     "guid": None \
, "addresses": ("mailto:c4ca4238a0@example.com",) }, +        "user02"     : { \
"password": "02user",     "guid": None                                  , \
"addresses": ("mailto:c81e728d9d@example.com",) },  }
 
     groups = {
@@ -297,6 +297,15 @@
         self.assertNotEquals(None, \
service._lookupInIndex(service.recordType_locations, service.INDEX_TYPE_SHORTNAME, \
                "orion"))
         self.assertEquals(None, service._lookupInIndex(service.recordType_users, \
service.INDEX_TYPE_CUA, "mailto:nobody@example.com"))  
+    def test_repeat(self):
+        service = self.service()
+        record = service.recordWithShortName(
+            DirectoryService.recordType_users, "user01")
+        self.assertEquals(record.fullName, "c4ca4238a0b923820dcc509a6f75849bc4c User \
01") +        self.assertEquals(record.firstName, "c4ca4")
+        self.assertEquals(record.lastName, "c4ca4238a User 01")
+        self.assertEquals(record.emailAddresses, set(['c4ca4238a0@example.com']))
+
 class XMLFileSubset (XMLFileBase, TestCase):
     """
     Test the recordTypes subset feature of XMLFile service.

Modified: CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py	2011-04-27 \
                18:52:55 UTC (rev 7375)
+++ CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py	2011-04-27 \
20:10:49 UTC (rev 7376) @@ -31,6 +31,9 @@
 
 from twistedcaldav.directory.directory import DirectoryService
 
+import re
+import hashlib
+
 log = Logger()
 
 ELEMENT_ACCOUNTS          = "accounts"
@@ -165,6 +168,36 @@
         done on them with the numeric value provided.
         @param ctr: an integer to substitute into text.
         """
+
+        # Regular expression which matches ~ followed by a number
+        matchNumber = re.compile(r"(~\d+)")
+
+        def expand(text, ctr):
+            """
+            Returns a string where ~<number> is replaced by the first <number>
+            characters from the md5 hexdigest of str(ctr), e.g.:
+
+                expand("~9 foo", 1)
+
+            returns:
+
+                "c4ca4238a foo"
+
+            ...since "c4ca4238a" is the first 9 characters of:
+
+                hashlib.md5(str(1)).hexdigest()
+
+            If <number> is larger than 32, the hash will repeat as needed.
+            """
+            if text:
+                m = matchNumber.search(text)
+                if m:
+                    length = int(m.group(0)[1:])
+                    hash = hashlib.md5(str(ctr)).hexdigest()
+                    string = (hash*((length/32)+1))[:-(32-(length%32))]
+                    return text.replace(m.group(0), string)
+            return text
+
         shortNames = []
         for shortName in self.shortNames:
             if shortName.find("%") != -1:
@@ -183,16 +216,20 @@
             fullName = self.fullName % ctr
         else:
             fullName = self.fullName
+        fullName = expand(fullName, ctr)
         if self.firstName and self.firstName.find("%") != -1:
             firstName = self.firstName % ctr
         else:
             firstName = self.firstName
+        firstName = expand(firstName, ctr)
         if self.lastName and self.lastName.find("%") != -1:
             lastName = self.lastName % ctr
         else:
             lastName = self.lastName
+        lastName = expand(lastName, ctr)
         emailAddresses = set()
         for emailAddr in self.emailAddresses:
+            emailAddr = expand(emailAddr, ctr)
             if emailAddr.find("%") != -1:
                 emailAddresses.add(emailAddr % ctr)
             else:


[Attachment #5 (text/html)]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[7376] CalendarServer/trunk/twistedcaldav/directory</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: \
verdana,arial,helvetica,sans-serif; font-size: 10pt;  } #msg dl a { font-weight: \
bold} #msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: \
bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: \
6px; } #logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em \
0; } #logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg \
h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; } \
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; \
} #logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: \
-1.5em; padding-left: 1.5em; } #logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em \
1em 0 1em; background: white;} #logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid \
#fa0; border-bottom: 1px solid #fa0; background: #fff; } #logmsg table th { \
text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted \
#fa0; } #logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: \
0.2em 0.5em; } #logmsg table thead th { text-align: center; border-bottom: 1px solid \
#fa0; } #logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: \
6px; } #patch { width: 100%; }
#patch h4 {font-family: \
verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
 #patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, \
#patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins \
{background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del \
{background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, \
                .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a \
href="http://trac.macosforge.org/projects/calendarserver/changeset/7376">7376</a></dd>
 <dt>Author</dt> <dd>sagen@apple.com</dd>
<dt>Date</dt> <dd>2011-04-27 13:10:49 -0700 (Wed, 27 Apr 2011)</dd>
</dl>

<h3>Log Message</h3>
<pre>Adds the ability to generate &quot;names&quot; within &quot;repeated&quot; users \
in accounts.xml (9339200).

Putting in ~&lt;number&gt; within the name, first-name, last-name, and email-address \
XML elements will substitute that with the first &lt;number&gt; characters from the \
hash of the repeat counter.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunktwistedcaldavdirectorytestaccountsxml">CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml</a></li>
 <li><a href="#CalendarServertrunktwistedcaldavdirectorytesttest_xmlfilepy">CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py</a></li>
 <li><a href="#CalendarServertrunktwistedcaldavdirectoryxmlaccountsparserpy">CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py</a></li>
 </ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunktwistedcaldavdirectorytestaccountsxml"></a>
<div class="modfile"><h4>Modified: \
CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml (7375 => 7376)</h4> \
<pre class="diff"><span> <span class="info">--- \
CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml	2011-04-27 18:52:55 \
                UTC (rev 7375)
+++ CalendarServer/trunk/twistedcaldav/directory/test/accounts.xml	2011-04-27 \
20:10:49 UTC (rev 7376) </span><span class="lines">@@ -107,7 +107,10 @@
</span><span class="cx">     &lt;uid&gt;user%02d&lt;/uid&gt;
</span><span class="cx">     &lt;guid&gt;user%02d&lt;/guid&gt;
</span><span class="cx">     &lt;password&gt;%02duser&lt;/password&gt;
</span><del>-    &lt;name&gt;User %02d&lt;/name&gt;
</del><ins>+    &lt;name&gt;~35 User %02d&lt;/name&gt;
+    &lt;first-name&gt;~5&lt;/first-name&gt;
+    &lt;last-name&gt;~9 User %02d&lt;/last-name&gt;
+    &lt;email-address&gt;~10@example.com&lt;/email-address&gt;
</ins><span class="cx">   &lt;/user&gt;
</span><span class="cx">   &lt;group&gt;
</span><span class="cx">     &lt;uid&gt;managers&lt;/uid&gt;
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectorytesttest_xmlfilepy"></a>
<div class="modfile"><h4>Modified: \
CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py (7375 => 7376)</h4> \
<pre class="diff"><span> <span class="info">--- \
CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2011-04-27 18:52:55 \
                UTC (rev 7375)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2011-04-27 \
20:10:49 UTC (rev 7376) </span><span class="lines">@@ -39,8 +39,8 @@
</span><span class="cx">         &quot;lecroy&quot;     : { &quot;password&quot;: \
&quot;yorcel&quot;,     &quot;guid&quot;: \
&quot;8B4288F6-CC82-491D-8EF9-642EF4F3E7D0&quot;, &quot;addresses&quot;: \
(&quot;mailto:lecroy@example.com&quot;,)   }, </span><span class="cx">         \
&quot;dreid&quot;      : { &quot;password&quot;: &quot;dierd&quot;,      \
&quot;guid&quot;: &quot;5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1&quot;, \
&quot;addresses&quot;: (&quot;mailto:dreid@example.com&quot;,)    }, </span><span \
class="cx">         &quot;nocalendar&quot; : { &quot;password&quot;: \
&quot;radnelacon&quot;, &quot;guid&quot;: \
&quot;543D28BA-F74F-4D5F-9243-B3E3A61171E5&quot;, &quot;addresses&quot;: () }, \
</span><del>-        &quot;user01&quot;     : { &quot;password&quot;: \
&quot;01user&quot;,     &quot;guid&quot;: None                                  , \
                &quot;addresses&quot;: () },
-        &quot;user02&quot;     : { &quot;password&quot;: &quot;02user&quot;,     \
&quot;guid&quot;: None                                  , &quot;addresses&quot;: () \
}, </del><ins>+        &quot;user01&quot;     : { &quot;password&quot;: \
&quot;01user&quot;,     &quot;guid&quot;: None                                  , \
&quot;addresses&quot;: (&quot;mailto:c4ca4238a0@example.com&quot;,) }, +        \
&quot;user02&quot;     : { &quot;password&quot;: &quot;02user&quot;,     \
&quot;guid&quot;: None                                  , &quot;addresses&quot;: \
(&quot;mailto:c81e728d9d@example.com&quot;,) }, </ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     groups = {
</span><span class="lines">@@ -297,6 +297,15 @@
</span><span class="cx">         self.assertNotEquals(None, \
service._lookupInIndex(service.recordType_locations, service.INDEX_TYPE_SHORTNAME, \
&quot;orion&quot;)) </span><span class="cx">         self.assertEquals(None, \
service._lookupInIndex(service.recordType_users, service.INDEX_TYPE_CUA, \
&quot;mailto:nobody@example.com&quot;)) </span><span class="cx"> 
</span><ins>+    def test_repeat(self):
+        service = self.service()
+        record = service.recordWithShortName(
+            DirectoryService.recordType_users, &quot;user01&quot;)
+        self.assertEquals(record.fullName, &quot;c4ca4238a0b923820dcc509a6f75849bc4c \
User 01&quot;) +        self.assertEquals(record.firstName, &quot;c4ca4&quot;)
+        self.assertEquals(record.lastName, &quot;c4ca4238a User 01&quot;)
+        self.assertEquals(record.emailAddresses, set(['c4ca4238a0@example.com']))
+
</ins><span class="cx"> class XMLFileSubset (XMLFileBase, TestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Test the recordTypes subset feature of XMLFile service.
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryxmlaccountsparserpy"></a>
<div class="modfile"><h4>Modified: \
CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py (7375 => 7376)</h4> \
<pre class="diff"><span> <span class="info">--- \
CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py	2011-04-27 18:52:55 \
                UTC (rev 7375)
+++ CalendarServer/trunk/twistedcaldav/directory/xmlaccountsparser.py	2011-04-27 \
20:10:49 UTC (rev 7376) </span><span class="lines">@@ -31,6 +31,9 @@
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.directory.directory import \
DirectoryService </span><span class="cx"> 
</span><ins>+import re
+import hashlib
+
</ins><span class="cx"> log = Logger()
</span><span class="cx"> 
</span><span class="cx"> ELEMENT_ACCOUNTS          = &quot;accounts&quot;
</span><span class="lines">@@ -165,6 +168,36 @@
</span><span class="cx">         done on them with the numeric value provided.
</span><span class="cx">         @param ctr: an integer to substitute into text.
</span><span class="cx">         &quot;&quot;&quot;
</span><ins>+
+        # Regular expression which matches ~ followed by a number
+        matchNumber = re.compile(r&quot;(~\d+)&quot;)
+
+        def expand(text, ctr):
+            &quot;&quot;&quot;
+            Returns a string where ~&lt;number&gt; is replaced by the first \
&lt;number&gt; +            characters from the md5 hexdigest of str(ctr), e.g.:
+
+                expand(&quot;~9 foo&quot;, 1)
+
+            returns:
+
+                &quot;c4ca4238a foo&quot;
+
+            ...since &quot;c4ca4238a&quot; is the first 9 characters of:
+
+                hashlib.md5(str(1)).hexdigest()
+
+            If &lt;number&gt; is larger than 32, the hash will repeat as needed.
+            &quot;&quot;&quot;
+            if text:
+                m = matchNumber.search(text)
+                if m:
+                    length = int(m.group(0)[1:])
+                    hash = hashlib.md5(str(ctr)).hexdigest()
+                    string = (hash*((length/32)+1))[:-(32-(length%32))]
+                    return text.replace(m.group(0), string)
+            return text
+
</ins><span class="cx">         shortNames = []
</span><span class="cx">         for shortName in self.shortNames:
</span><span class="cx">             if shortName.find(&quot;%&quot;) != -1:
</span><span class="lines">@@ -183,16 +216,20 @@
</span><span class="cx">             fullName = self.fullName % ctr
</span><span class="cx">         else:
</span><span class="cx">             fullName = self.fullName
</span><ins>+        fullName = expand(fullName, ctr)
</ins><span class="cx">         if self.firstName and \
self.firstName.find(&quot;%&quot;) != -1: </span><span class="cx">             \
firstName = self.firstName % ctr </span><span class="cx">         else:
</span><span class="cx">             firstName = self.firstName
</span><ins>+        firstName = expand(firstName, ctr)
</ins><span class="cx">         if self.lastName and \
self.lastName.find(&quot;%&quot;) != -1: </span><span class="cx">             \
lastName = self.lastName % ctr </span><span class="cx">         else:
</span><span class="cx">             lastName = self.lastName
</span><ins>+        lastName = expand(lastName, ctr)
</ins><span class="cx">         emailAddresses = set()
</span><span class="cx">         for emailAddr in self.emailAddresses:
</span><ins>+            emailAddr = expand(emailAddr, ctr)
</ins><span class="cx">             if emailAddr.find(&quot;%&quot;) != -1:
</span><span class="cx">                 emailAddresses.add(emailAddr % ctr)
</span><span class="cx">             else:
</span></span></pre>
</div>
</div>

</body>
</html>



_______________________________________________
calendarserver-changes mailing list
calendarserver-changes@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/calendarserver-changes


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic