[svn] r3137 - in trunk/tools/pydar2: . perlpackages php pydar sql

packagers at lists.rpmforge.net packagers at lists.rpmforge.net
Mon Apr 18 22:36:19 CEST 2005


Author: dries
Date: 2005-04-18 22:36:17 +0200 (Mon, 18 Apr 2005)
New Revision: 3137

Added:
   trunk/tools/pydar2/classdiagram.xmi
   trunk/tools/pydar2/log4py.conf
   trunk/tools/pydar2/pydar-master-update.py
   trunk/tools/pydar2/pydar/cvsbasedspecrepository.py
   trunk/tools/pydar2/pydar/filesbasedspecrepository.py
   trunk/tools/pydar2/pydar/memorystorage.py
   trunk/tools/pydar2/pydar/postgresqlstorage.py
   trunk/tools/pydar2/pydar/pydarclient.py
   trunk/tools/pydar2/pydar/specrepository.py
   trunk/tools/pydar2/pydar/specrepositoryfactory.py
   trunk/tools/pydar2/pydar/specrepositorylist.py
   trunk/tools/pydar2/pydar/specrepositoryspecfile.py
   trunk/tools/pydar2/pydar/storage.py
   trunk/tools/pydar2/pydar/storagefactory.py
   trunk/tools/pydar2/pydar/svnbasedspecrepository.py
Modified:
   trunk/tools/pydar2/perlpackages/check.pl
   trunk/tools/pydar2/perlpackages/perltemplate.spec
   trunk/tools/pydar2/php/el4x86driestodo.php
   trunk/tools/pydar2/php/navigation.php
   trunk/tools/pydar2/pydar-buildserver-master.py
   trunk/tools/pydar2/pydar-buildserver-slave.py
   trunk/tools/pydar2/pydar/buildroot.py
   trunk/tools/pydar2/pydar/buildrootresult.py
   trunk/tools/pydar2/pydar/config.py
   trunk/tools/pydar2/pydar/yumbasedbuildroot.py
   trunk/tools/pydar2/sql/svncheck.sql
Log:
update, but far from working

Added: trunk/tools/pydar2/classdiagram.xmi
===================================================================
--- trunk/tools/pydar2/classdiagram.xmi	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/classdiagram.xmi	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2005-04-10T22:36:21" xmi.version="1.2" >
+ <XMI.header>
+  <XMI.documentation>
+   <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
+   <XMI.exporterVersion>1.4</XMI.exporterVersion>
+   <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
+  </XMI.documentation>
+  <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
+ </XMI.header>
+ <XMI.content>
+  <UML:Model isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" >
+   <UML:Namespace.ownedElement>
+    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" xmi.id="20" isRoot="false" isAbstract="false" name="interface" />
+    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" xmi.id="23" isRoot="false" isAbstract="false" name="datatype" />
+    <UML:DataType stereotype="23" isSpecification="false" isLeaf="false" visibility="public" xmi.id="22" isRoot="false" isAbstract="false" name="void" />
+    <UML:Interface stereotype="20" isSpecification="false" isLeaf="false" visibility="public" xmi.id="19" isRoot="false" isAbstract="true" name="BuildRoot" >
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="21" isRoot="false" isAbstract="false" name="__init__" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="24" isRoot="false" isAbstract="false" name="cleanRoot" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="25" isRoot="false" isAbstract="false" name="prepareRoot" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="26" isRoot="false" isAbstract="false" name="installRpms" >
+       <UML:BehavioralFeature.parameter>
+        <UML:Parameter isSpecification="false" isLeaf="false" visibility="private" xmi.id="28" isRoot="false" value="" type="22" isAbstract="false" name="rpms" />
+       </UML:BehavioralFeature.parameter>
+      </UML:Operation>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="29" isRoot="false" isAbstract="false" name="buildRpm" >
+       <UML:BehavioralFeature.parameter>
+        <UML:Parameter isSpecification="false" isLeaf="false" visibility="private" xmi.id="30" isRoot="false" value="" type="22" isAbstract="false" name="spec" />
+       </UML:BehavioralFeature.parameter>
+      </UML:Operation>
+     </UML:Classifier.feature>
+    </UML:Interface>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="27" isRoot="false" isAbstract="false" name="int" />
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="31" isRoot="false" isAbstract="false" name="YumBasedBuildRoot" >
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="35" isRoot="false" isAbstract="false" name="__init__" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="36" isRoot="false" isAbstract="false" name="cleanRoot" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="protected" xmi.id="37" isRoot="false" isAbstract="false" name="setVars" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="38" isRoot="false" isAbstract="false" name="installRpms" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="39" isRoot="false" isAbstract="false" name="prepareRoot" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="protected" xmi.id="40" isRoot="false" isAbstract="false" name="logCommands" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="protected" xmi.id="41" isRoot="false" isAbstract="false" name="logCommand" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="protected" xmi.id="42" isRoot="false" isAbstract="false" name="logCommandWithoutErrors" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="protected" xmi.id="43" isRoot="false" isAbstract="false" name="createScript" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="protected" xmi.id="44" isRoot="false" isAbstract="false" name="callBuildScript" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="45" isRoot="false" isAbstract="false" name="BuildRootResult" >
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="46" isRoot="false" isAbstract="false" name="__init__" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="47" isRoot="false" isAbstract="false" name="logErrorLine" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="48" isRoot="false" isAbstract="false" name="logDebugLine" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="49" isRoot="false" isAbstract="false" name="Command" >
+     <UML:Classifier.feature>
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="50" isRoot="false" initialValue="" type="22" isAbstract="false" name="commandName" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="51" isRoot="false" initialValue="" type="22" isAbstract="false" name="userId" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="52" isRoot="false" initialValue="" type="22" isAbstract="false" name="specName" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="53" isRoot="false" initialValue="" type="22" isAbstract="false" name="toEmail" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="54" isRoot="false" initialValue="" type="22" isAbstract="false" name="releaseTag" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="55" isRoot="false" initialValue="" type="22" isAbstract="false" name="machRoot" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="56" isRoot="false" initialValue="" type="22" isAbstract="false" name="priority" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="57" isRoot="false" isAbstract="false" name="Config" >
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="102" isRoot="false" isAbstract="false" name="getSpecRepositoryByName" />
+     </UML:Classifier.feature>
+     <UML:Namespace.ownedElement>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="75" isRoot="false" isAbstract="false" name="SpecRepository" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="87" isRoot="false" isAbstract="false" name="getUpdateCommand" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="95" isRoot="false" isAbstract="false" name="getType" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="96" isRoot="false" isAbstract="false" name="getName" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="97" isRoot="false" isAbstract="false" name="getRootDirectory" />
+       </UML:Classifier.feature>
+      </UML:Class>
+     </UML:Namespace.ownedElement>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="58" isRoot="false" isAbstract="false" name="TagsFile" >
+     <UML:Classifier.feature>
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="60" isRoot="false" initialValue="" type="22" isAbstract="false" name="rpmforgetags" />
+      <UML:Attribute isSpecification="false" isLeaf="false" visibility="private" xmi.id="61" isRoot="false" initialValue="" type="27" isAbstract="false" name="standardtags" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="59" isRoot="false" isAbstract="false" name="getStandardTags" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="62" isRoot="false" isAbstract="false" name="SpecFile" >
+     <UML:GeneralizableElement.generalization>
+      <UML:Generalization xmi.idref="63" />
+     </UML:GeneralizableElement.generalization>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="66" isRoot="false" isAbstract="false" name="RpmFile" >
+     <UML:GeneralizableElement.generalization>
+      <UML:Generalization xmi.idref="67" />
+     </UML:GeneralizableElement.generalization>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="70" isRoot="false" isAbstract="false" name="SvnWrapper" >
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="71" isRoot="false" isAbstract="false" name="startTransaction" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="72" isRoot="false" isAbstract="false" name="stopTransaction" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="73" isRoot="false" isAbstract="false" name="updateLocalCopy" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="74" isRoot="false" isAbstract="false" name="getLastCommitRev" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="76" isRoot="false" isAbstract="false" name="SvnBasedSpecRepository" >
+     <UML:GeneralizableElement.generalization>
+      <UML:Generalization xmi.idref="78" />
+     </UML:GeneralizableElement.generalization>
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="88" isRoot="false" isAbstract="false" name="getUpdateCommand" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="77" isRoot="false" isAbstract="false" name="CvsBasedSpecRepository" >
+     <UML:GeneralizableElement.generalization>
+      <UML:Generalization xmi.idref="81" />
+     </UML:GeneralizableElement.generalization>
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="89" isRoot="false" isAbstract="false" name="getUpdateCommand" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="90" isRoot="false" isAbstract="false" name="FilesBasedSpecRepository" >
+     <UML:GeneralizableElement.generalization>
+      <UML:Generalization xmi.idref="91" />
+     </UML:GeneralizableElement.generalization>
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="94" isRoot="false" isAbstract="false" name="getUpdateCommand" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Class isSpecification="false" isLeaf="false" visibility="public" xmi.id="103" isRoot="false" isAbstract="false" name="SpecRepositoryFactory" >
+     <UML:Classifier.feature>
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="104" isRoot="false" isAbstract="false" name="getInstance" />
+      <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="105" isRoot="false" isAbstract="false" name="createSpecRepository" />
+     </UML:Classifier.feature>
+    </UML:Class>
+    <UML:Generalization isSpecification="false" child="31" visibility="public" xmi.id="32" parent="19" discriminator="" name="" />
+    <UML:Generalization isSpecification="false" child="62" visibility="public" xmi.id="63" parent="58" discriminator="" name="" />
+    <UML:Generalization isSpecification="false" child="66" visibility="public" xmi.id="67" parent="58" discriminator="" name="" />
+    <UML:Generalization isSpecification="false" child="76" visibility="public" xmi.id="78" parent="75" discriminator="" name="" />
+    <UML:Generalization isSpecification="false" child="77" visibility="public" xmi.id="81" parent="75" discriminator="" name="" />
+    <UML:Generalization isSpecification="false" child="31" visibility="public" xmi.id="84" parent="19" discriminator="" name="" />
+    <UML:Generalization isSpecification="false" child="90" visibility="public" xmi.id="91" parent="75" discriminator="" name="" />
+   </UML:Namespace.ownedElement>
+  </UML:Model>
+ </XMI.content>
+ <XMI.extensions xmi.extender="umbrello" >
+  <docsettings viewid="18" documentation="" uniqueid="107" />
+  <diagrams>
+   <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="976" snapy="10" showatts="1" xmi.id="18" documentation="" type="402" showops="1" showpackage="0" name="class diagram" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans,8,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="1019" >
+    <widgets>
+     <interfacewidget usesdiagramfillcolour="1" width="150" usesdiagramusefillcolour="1" x="471" linecolour="none" y="206" drawascircle="0" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="105" usefillcolor="1" isinstance="0" xmi.id="19" showoperations="1" showpackage="0" showscope="1" font="Sans,8,-1,5,75,1,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="173" showattsigs="601" usesdiagramusefillcolour="1" x="705" linecolour="none" y="352" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="172" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="31" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="102" showattsigs="601" usesdiagramusefillcolour="1" x="185" linecolour="none" y="224" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="67" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="45" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="123" showattsigs="601" usesdiagramusefillcolour="1" x="321" linecolour="none" y="63" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="127" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="49" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="172" showattsigs="601" usesdiagramusefillcolour="1" x="211" linecolour="none" y="371" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="37" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="57" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="118" showattsigs="601" usesdiagramusefillcolour="1" x="651" linecolour="none" y="589" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="60" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="58" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="55" showattsigs="601" usesdiagramusefillcolour="1" x="581" linecolour="none" y="711" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="29" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="62" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="53" showattsigs="601" usesdiagramusefillcolour="1" x="785" linecolour="none" y="719" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="29" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="66" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="129" showattsigs="601" usesdiagramusefillcolour="1" x="819" linecolour="none" y="133" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="82" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="70" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="137" showattsigs="601" usesdiagramusefillcolour="1" x="231" linecolour="none" y="621" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="82" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="75" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="147" showattsigs="601" usesdiagramusefillcolour="1" x="225" linecolour="none" y="802" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="37" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="76" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="147" showattsigs="601" usesdiagramusefillcolour="1" x="401" linecolour="none" y="800" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="37" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="77" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="1" width="151" showattsigs="601" usesdiagramusefillcolour="1" x="47" linecolour="none" y="800" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="37" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="90" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <classwidget usesdiagramfillcolour="0" width="143" showattsigs="601" usesdiagramusefillcolour="0" x="385" linecolour="#ff0000" y="620" showopsigs="601" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="0" fillcolour="#ffffc0" height="52" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="103" showoperations="1" showpackage="0" showscope="1" showstereotype="0" font="Sans,8,-1,5,75,0,0,0,0,0" />
+     <notewidget usesdiagramfillcolour="1" width="100" usesdiagramusefillcolour="1" x="479" linecolour="none" y="498" linewidth="none" usesdiagramlinewidth="1" usesdiagramlinecolour="1" fillcolour="none" height="80" usefillcolor="1" isinstance="0" xmi.id="107" text="SpecRepositoryFactory is a singleton which creates SpecRepository objects" font="Sans,8,-1,5,50,0,0,0,0,0" />
+    </widgets>
+    <messages/>
+    <associations>
+     <assocwidget totalcounta="2" indexa="1" totalcountb="3" indexb="1" widgetbid="58" widgetaid="62" xmi.id="63" >
+      <linepath>
+       <startpoint startx="608" starty="711" />
+       <endpoint endx="690" endy="649" />
+      </linepath>
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" totalcountb="3" indexb="2" widgetbid="58" widgetaid="66" xmi.id="67" >
+      <linepath>
+       <startpoint startx="811" starty="719" />
+       <endpoint endx="729" endy="649" />
+      </linepath>
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" totalcountb="4" indexb="2" widgetbid="75" widgetaid="76" xmi.id="78" >
+      <linepath>
+       <startpoint startx="298" starty="802" />
+       <endpoint endx="299" endy="703" />
+      </linepath>
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" totalcountb="4" indexb="3" widgetbid="75" widgetaid="77" xmi.id="81" >
+      <linepath>
+       <startpoint startx="474" starty="800" />
+       <endpoint endx="333" endy="703" />
+      </linepath>
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" widgetbid="19" widgetaid="31" xmi.id="84" >
+      <linepath>
+       <startpoint startx="705" starty="438" />
+       <endpoint endx="546" endy="311" />
+      </linepath>
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" totalcountb="4" indexb="1" widgetbid="75" widgetaid="90" xmi.id="91" >
+      <linepath>
+       <startpoint startx="122" starty="800" />
+       <endpoint endx="265" endy="703" />
+      </linepath>
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" widgetbid="75" widgetaid="57" roleBdoc="" documentation="" roleAdoc="" type="509" changeabilityA="900" changeabilityB="900" visibilityA="200" >
+      <linepath>
+       <startpoint startx="297" starty="408" />
+       <endpoint endx="299" endy="621" />
+      </linepath>
+      <floatingtext usesdiagramfillcolour="1" width="14" usesdiagramusefillcolour="1" x="281" linecolour="none" y="410" linewidth="none" usesdiagramlinewidth="1" posttext="" usesdiagramlinecolour="1" role="701" fillcolour="none" height="19" usefillcolor="1" pretext="" isinstance="0" xmi.id="99" text="1" font="Sans,8,-1,5,50,0,0,0,0,0" />
+      <floatingtext usesdiagramfillcolour="1" width="12" usesdiagramusefillcolour="1" x="301" linecolour="none" y="600" linewidth="none" usesdiagramlinewidth="1" posttext="" usesdiagramlinecolour="1" role="702" fillcolour="none" height="19" usefillcolor="1" pretext="" isinstance="0" xmi.id="101" text="*" font="Sans,8,-1,5,50,0,0,0,0,0" />
+     </assocwidget>
+     <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" widgetbid="103" widgetaid="107" roleBdoc="" documentation="" roleAdoc="" type="513" changeabilityA="900" changeabilityB="900" visibilityA="200" >
+      <linepath>
+       <startpoint startx="529" starty="578" />
+       <endpoint endx="456" endy="620" />
+      </linepath>
+     </assocwidget>
+    </associations>
+   </diagram>
+  </diagrams>
+  <listview>
+   <listitem open="1" type="800" label="Views" >
+    <listitem open="1" type="801" label="Logical View" >
+     <listitem open="1" type="813" id="45" >
+      <listitem open="0" type="815" id="46" />
+      <listitem open="0" type="815" id="47" />
+      <listitem open="0" type="815" id="48" />
+     </listitem>
+     <listitem open="1" type="813" id="49" >
+      <listitem open="0" type="814" id="50" />
+      <listitem open="0" type="814" id="51" />
+      <listitem open="0" type="814" id="52" />
+      <listitem open="0" type="814" id="53" />
+      <listitem open="0" type="814" id="54" />
+      <listitem open="0" type="814" id="55" />
+      <listitem open="0" type="814" id="56" />
+     </listitem>
+     <listitem open="1" type="813" id="57" >
+      <listitem open="1" type="813" id="75" >
+       <listitem open="0" type="815" id="87" />
+       <listitem open="0" type="815" id="95" />
+       <listitem open="0" type="815" id="96" />
+       <listitem open="0" type="815" id="97" />
+      </listitem>
+      <listitem open="0" type="815" id="102" />
+     </listitem>
+     <listitem open="1" type="813" id="77" >
+      <listitem open="0" type="815" id="89" />
+     </listitem>
+     <listitem open="1" type="813" id="90" >
+      <listitem open="0" type="815" id="94" />
+     </listitem>
+     <listitem open="1" type="813" id="66" />
+     <listitem open="1" type="813" id="62" />
+     <listitem open="1" type="813" id="103" >
+      <listitem open="0" type="815" id="104" />
+      <listitem open="0" type="815" id="105" />
+     </listitem>
+     <listitem open="1" type="813" id="76" >
+      <listitem open="0" type="815" id="88" />
+     </listitem>
+     <listitem open="1" type="813" id="70" >
+      <listitem open="0" type="815" id="71" />
+      <listitem open="0" type="815" id="72" />
+      <listitem open="0" type="815" id="73" />
+      <listitem open="0" type="815" id="74" />
+     </listitem>
+     <listitem open="1" type="813" id="58" >
+      <listitem open="0" type="814" id="60" />
+      <listitem open="0" type="814" id="61" />
+      <listitem open="0" type="815" id="59" />
+     </listitem>
+     <listitem open="1" type="813" id="31" >
+      <listitem open="0" type="815" id="35" />
+      <listitem open="0" type="815" id="36" />
+      <listitem open="0" type="815" id="37" />
+      <listitem open="0" type="815" id="38" />
+      <listitem open="0" type="815" id="39" />
+      <listitem open="0" type="815" id="40" />
+      <listitem open="0" type="815" id="41" />
+      <listitem open="0" type="815" id="42" />
+      <listitem open="0" type="815" id="43" />
+      <listitem open="0" type="815" id="44" />
+     </listitem>
+     <listitem open="1" type="813" id="27" />
+     <listitem open="1" type="817" id="19" >
+      <listitem open="0" type="815" id="21" />
+      <listitem open="0" type="815" id="24" />
+      <listitem open="0" type="815" id="25" />
+      <listitem open="0" type="815" id="26" />
+      <listitem open="0" type="815" id="29" />
+     </listitem>
+     <listitem open="1" type="830" label="Datatypes" >
+      <listitem open="1" type="829" id="22" />
+     </listitem>
+    </listitem>
+    <listitem open="1" type="802" label="Use Case View" />
+    <listitem open="1" type="821" label="Component View" />
+    <listitem open="1" type="827" label="Deployment View" />
+    <listitem open="1" type="836" label="Entity Relationship Model" />
+   </listitem>
+  </listview>
+  <codegeneration>
+   <codegenerator language="Python" />
+  </codegeneration>
+ </XMI.extensions>
+</XMI>

Added: trunk/tools/pydar2/log4py.conf
===================================================================
--- trunk/tools/pydar2/log4py.conf	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/log4py.conf	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,96 @@
+# Log4Py configuration file
+#
+# The "Default" Sections contains default settings which can be overwritten
+# by settings for different instances (see bottom of file)
+
+[Default]
+
+# Format is the output format of the lines.
+#
+# Possible parameters are:
+#
+#    %C ..... class-name
+#    %D ..... program duration
+#    %d ..... duration for the last step (last output)
+#    %F ..... function name
+#    %L ..... logtype (Error, Warning, ...)
+#    %M ..... message
+#    %N ..... Line-number
+#    %T ..... current time
+#
+# Example formats are:
+#
+#    Short:           %M
+#    Medium:          [ %C.%F ] %D: %M
+#    Long (default):  %T %L %C [%F] - %M
+#    Debug:           %T [%D (%d)] %L %C [%F (%N)] - %M
+
+Format: %T %L %C [%F:%N] - %M
+
+# Target controls the output medium of the logging
+#
+# Possible values are:
+#
+#    stdout (default): Standard output stream
+#    stderr:           Error stream
+#    <filename>        Any other filename
+#
+# Multiple targets can be specified as comma seperated list
+
+Target: stdout
+
+# Use ansi colors. Possible values are True or False (default)
+
+Ansi: False
+
+# TimeFormat is the format of the date and time as used by the
+# Python strftime() function
+
+# TimeFormat: %d.%m.%Y %H:%M:%S
+
+# LogLevel controls the level of what you want to see
+#
+# Possible values are:
+#
+#    None:             No output (silent mode)
+#    Normal (default): Information- and Errormessages
+#    Verbose:          Information-, Error- and Warningmessages
+#    Debug:            Information-, Error-, Warning- and Debugmessages
+
+LogLevel: Debug
+
+# This is a section for the Log4PyTest class.
+
+[Log4PyTest]
+SpecFile: Debug
+foo: Debug
+SvnCheck: Debug
+Store: Debug
+SpecRepository: Debug
+Config: Debug
+Storage: Debug
+PostgresqlStorage: Debug
+SpecRepositoryFactory: Debug
+BuildRoot: Debug
+BuildRootResult: Debug
+Command: Debug
+Config: Debug
+CvsBasedSpecRepository: Debug
+FilesBasedSpecRepository:: Debug
+MemoryStorage:: Debug
+PostgresqlStorage:: Debug
+PydarClient: Debug
+RpmFile: Debug
+RpmsCheck: Debug
+SpecFile: Debug
+SpecRepositoryFactory: Debug
+SpecRepositoryList: Debug
+SpecRepository: Debug
+SpecRepositorySpecFile: Debug
+StorageFactory: Debug
+Storage: Debug
+SvnBasedSpecRepository:  Debug
+SvnCheck: Debug
+SvnWrapper: Debug
+TagsFile: Debug
+YumBasedBuildRoot: Debug

Modified: trunk/tools/pydar2/perlpackages/check.pl
===================================================================
--- trunk/tools/pydar2/perlpackages/check.pl	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/perlpackages/check.pl	2005-04-18 20:36:17 UTC (rev 3137)
@@ -15,6 +15,9 @@
 # This list can be generated with packageslist.sh from 
 # the spec files
 
+
+my $currentperlpackage = "";
+
 sub geturl {
 	my $url = pop(@_);
 	my $u = URI::URL->new($url, "");
@@ -77,7 +80,7 @@
 	} else {
 		print "first href not found";
 	}
-	die "could not get the name + email";
+	die $currentperlpackage . ": could not get the name + email";
 }
 
 sub createspec {
@@ -99,12 +102,25 @@
 		$sourceurlpart = "http://search.cpan.org" . $1;
 		$speccontents =~ s|Source: |Source: $sourceurlpart|g;
 	}
-
+	$readmecontents = "";
+        if ($urlcontents =~ /<a href="(\/src\/.*?\/README)">README<\/a><br>/) {
+                $readmeurl = "http://search.cpan.org" . $1;
+                $readmecontents = geturl($readmeurl);
+                
+        }
+	
 	#print $speccontents;
-	mkdir("../../../rpms/perl-$packagename");
-	open (TMP, ">" . $specfilename . ".autocreate") or die "could not write to " . $specfilename . ".autocreate";
+	mkdir("../../../rpms/newperlpackages/perl-$packagename");
+	open (TMP, ">" . $specfilename) or die "could not write to " . $specfilename;
 	print TMP  $speccontents;
 	close(TMP);
+	open (TMP, ">" . "../../../rpms/newperlpackages/perl-$packagename/perlpage.html") or die "perlpage.html";
+	print TMP $urlcontents;
+	close (TMP);
+	open (TMP, ">" . "../../../rpms/newperlpackages/perl-$packagename/README") or die "README";
+	print TMP $readmecontents;
+	close (TMP);
+	
 	print "cd perl-$packagename; mv perl-$packagename.spec.autocreate perl-$packagename.spec; spectool perl-$packagename.spec;\n";
 
 }
@@ -118,7 +134,7 @@
 	if ($urlcontents =~ /<td class=cell>$packagename-(.*?)<\/td>/) {
 		$latestversion = $1;
 	}
-	my $specfilename = "../../../rpms/perl-$packagename/perl-$packagename.spec";
+	my $specfilename = "../../../rpms/newperlpackages/perl-$packagename/perl-$packagename.spec";
 
 	if ( -e $specfilename ) {
 		updatespec($url,$urlcontents,$latestversion,$specfilename,$packagename);
@@ -131,6 +147,7 @@
 # read the list from stdin
 while ($packagename = <>) {
 	chomp $packagename;
-#	print "package: " . $packagename .  "\n";
+	print "package: " . $packagename .  "\n";
+	$currentperlpackage = $packagename;
 	checkspec ($packagename);
 }
\ No newline at end of file

Modified: trunk/tools/pydar2/perlpackages/perltemplate.spec
===================================================================
--- trunk/tools/pydar2/perlpackages/perltemplate.spec	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/perlpackages/perltemplate.spec	2005-04-18 20:36:17 UTC (rev 3137)
@@ -1,28 +1,24 @@
 # $Id$
-
 # Authority: dries
 # Upstream: UPSTREAMTAG
 
-%define real_name NNAAMMEE
 %define perl_vendorlib %(eval "`perl -V:installvendorlib`"; echo $installvendorlib)
 %define perl_vendorarch %(eval "`perl -V:installvendorarch`"; echo $installvendorarch)
-%define perl_archlib %(eval "`perl -V:archlib`"; echo $archlib)
-%define perl_privlib %(eval "`perl -V:privlib`"; echo $privlib)
 
+%define real_name NNAAMMEE
+
 Summary: 
 Name: perl-NNAAMMEE
 Version: 
 Release: 1
-License: Artistic
+License: Artistic/GPL
 Group: Applications/CPAN
 URL: http://search.cpan.org/dist/NNAAMMEE/
 
-Packager: Dries Verachtert <dries at ulyssis.org>
-Vendor: Dries Apt/Yum Repository http://dries.ulyssis.org/ayo/
-
 Source: NNAAMMEE-%{version}.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 
+#BuildArch: noarch
 BuildRequires: perl
 
 %description
@@ -31,19 +27,20 @@
 %setup -n %{real_name}-%{version}
 
 %build
-%{__perl} Makefile.PL INSTALLDIRS="vendor" destdir=%{buildroot}
+%{__perl} Makefile.PL INSTALLDIRS="vendor" PREFIX="%{buildroot}%{_prefix}"
 %{__make} %{?_smp_mflags}
 
 %install
 %{__rm} -rf %{buildroot}
 %makeinstall
+#%{__rm} -rf %{buildroot}%{perl_archlib} %{buildroot}%{perl_vendorarch}
 
 %clean
 %{__rm} -rf %{buildroot}
 
 %files
 %defattr(-, root, root, 0755)
-%doc README Changes
+%doc Changes README
 %doc %{_mandir}/man3/*
 #%{perl_vendorlib}/NAMEDIR.pm
 #%{perl_vendorlib}/NAMEDIR/*

Modified: trunk/tools/pydar2/php/el4x86driestodo.php
===================================================================
--- trunk/tools/pydar2/php/el4x86driestodo.php	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/php/el4x86driestodo.php	2005-04-18 20:36:17 UTC (rev 3137)
@@ -1,7 +1,7 @@
 <?php
     $fullname = "Red Hat Enterprise Linux 4 x86 (dries)";
     $buildscript = "./el4build";
-    $releasetag = ".1.el4.rf";
+    $releasetag = ".2.el4.rf";
     $authority = "dries";
     include("stats.php");
 ?>
\ No newline at end of file

Modified: trunk/tools/pydar2/php/navigation.php
===================================================================
--- trunk/tools/pydar2/php/navigation.php	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/php/navigation.php	2005-04-18 20:36:17 UTC (rev 3137)
@@ -8,6 +8,7 @@
     <div class="navitem"><a class="navitem" href="http://dries.ulyssis.org/ayo/fedora/fc2/i386/RPMS.dries">fc2 i386 rpms</a></div>
     <div class="navitem"><a class="navitem" href="http://dries.ulyssis.org/ayo/fedora/fc1/i386/RPMS.dries">fc1 i386 rpms</a></div>
     <div class="navitem"><a class="navitem" href="http://dries.ulyssis.org/ayo/redhat/el3/en/i386/RPMS.dries">el3 i386 rpms</a></div>
+    <div class="navitem"><a class="navitem" href="http://dries.ulyssis.org/ayo/redhat/el4/en/i386/RPMS.dries">el4 i386 rpms</a></div>
     <div class="navitem"><a class="navitem" href="http://dries.ulyssis.org/ayo/aurora/1.92/sparc/RPMS.dries">au 1.92 rpms</a></div>
     <div class="navitem"><a class="navitem" href="http://dries.ulyssis.org/ayo/aurora/1.91/sparc/RPMS.dries">au 1.91 rpms</a></div>
     <div class="navpart">Build system:</div>
@@ -20,6 +21,7 @@
     <div class="navitem"><a class="navitem" href="http://pydar2.vmhosting.org/auroratodo.php">Todo au1.92</a></div>
     <div class="navitem"><a class="navitem" href="http://pydar2.vmhosting.org/auroradriestodo.php">Todo au1.92/dries</a></div>
     <div class="navitem"><a class="navitem" href="http://pydar2.vmhosting.org/el3x86driestodo.php">Todo el3/x86/dries</a></div>
+    <div class="navitem"><a class="navitem" href="http://pydar2.vmhosting.org/el4x86driestodo.php">Todo el4/x86/dries</a></div>
     <div class="navpart">Other repo's:</div>
     <div class="navitem"><a class="navitem" href="http://dag.wieers.com/home-made/apt">DAG</a></div>
     <div class="navitem"><a class="navitem" href="http://freshrpms.net">Freshrpms</a></div>

Modified: trunk/tools/pydar2/pydar/buildroot.py
===================================================================
--- trunk/tools/pydar2/pydar/buildroot.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/buildroot.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -18,7 +18,7 @@
 
 # normally you don't use this class but a subclass which implements 
 # these functions
-# for example: YmBasedBuildRoot
+# for example: YumBasedBuildRoot
 
 # example usage:
 # fc3br = BlaBlaBuildRoot(cfg,'fedora-3-i386-core')

Modified: trunk/tools/pydar2/pydar/buildrootresult.py
===================================================================
--- trunk/tools/pydar2/pydar/buildrootresult.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/buildrootresult.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -20,23 +20,34 @@
 
 
 class BuildRootResult:
-    __init__(self,buildrootobj):
-        self.buildrootobj = buildrootobj
-        self.containsErrors = 0
-        self.containsWarnings = 0
-        self.logText = ""
-        self.srpm = ""
-        self.rpms = []
-        self.buildlog = ""
-        self.configlog = ""
+    def __init__(self,buildrootobj):
+        self.__buildrootobj = buildrootobj
+        self.__containsErrors = 0
+        self.__containsWarnings = 0
+        self.__logText = ""
+        self.__srpm = ""
+        self.__rpms = []
+        self.__buildlog = ""
+        self.__configlog = ""
         
     def logErrorLine(self,line):
-        self.logText = self.logText + "ERROR:" + line + "\n"
+        self.__logText = self.__logText + "ERROR:" + line + "\n"
         print "ERROR:" + line
-        self.containsErrors = 1
+        self.__containsErrors = 1
         
     def logDebugLine(self,line):
-        self.logText = self.logText + line + "\n"
+        self.__logText = self.__logText + line + "\n"
         print line
         
+    def getRpms(self):
+        return self.__rpms
+
+    def getSrpm(self):
+        return self.__srpm
+    
+    def getBuildLog(self):
+        return self.__buildlog
         
+    def getConfigLog(self):
+        return self.__configlog
+    

Modified: trunk/tools/pydar2/pydar/config.py
===================================================================
--- trunk/tools/pydar2/pydar/config.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/config.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -1,4 +1,3 @@
-
 #!/usr/bin/python
 
 """ Contains some settings for pydar """
@@ -18,11 +17,53 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 # Copyright 2004 Dries Verachtert
 
-import ConfigParser, os
+import ConfigParser, os, posixpath, sys
+sys.path.append("pydar")
+sys.path.append(".")
+from specrepository import SpecRepository
+from specrepositoryfactory import SpecRepositoryFactory
+from specrepositorylist import SpecRepositoryList
+from log4py import Logger
 
 class Config:
+    __myInstance = None
+    __fullInitDone = False
+    __withinFullInit = False
+    
     def __init__(self):
-               
+        if Config.__myInstance != None:
+            raise Exception("use Config.getInstance()")
+        Config.__myInstance = self
+        print "Config::__init__ __myInstance=" + str(self.__myInstance)
+    
+    def getInstance(cls):
+        if cls.__myInstance == None:
+            unused = Config()
+        print "Config::getInstance __myInstance=" + str(cls.__myInstance)
+        return cls.__myInstance
+    getInstance = classmethod(getInstance)
+    
+    def getSpecReposRootDir(self):
+        self.__fullInit()
+        return self.__specreposrootdir
+    
+    def getPostgresqlConnectString(self):
+        self.__fullInit()
+        # @todo
+        return self.__dbconnectstring
+        
+    
+    def __fullInit(self):
+        if Config.__fullInitDone or Config.__withinFullInit:
+            return
+        Config.__withinFullInit = True
+        self.__cat = Logger().get_instance(self)
+        self.__cat.debug("start")
+        
+        # the userid which is used by the pydar-master-update.py program
+        self.updateUserId = 0
+ 
+        # old stuff
         myParser = ConfigParser.ConfigParser()
         try:
             myParser.readfp(open('/usr/share/pydar/defaults.conf'))
@@ -44,7 +85,8 @@
         self.releaseTag = myParser.get('client','defaultreleasetag')
         self.machRoot = myParser.get('client','defaultmachroot')
         self.userid = myParser.get('client','userid')
-        self.dbconnectstring = myParser.get('master','dbconnectstring')
+        self.__dbconnectstring = myParser.get('master','dbconnectstring')
+        self.__cat.debug('dbconnectstring set to:' + self.__dbconnectstring)
         self.buildmachineid = myParser.get('slave','buildmachineid')
         self.dirtestbuilds = myParser.get('slave','dirtestbuilds')
 
@@ -53,4 +95,40 @@
         # get the supported machroots
         self.machroots = []
         for key in myParser.options('machroots'):
-            self.machroots.append(myParser.get('machroots',key))
\ No newline at end of file
+            self.machroots.append(myParser.get('machroots',key))
+        
+        
+        
+        
+        # todo: rewrite this stuff so everything is read from some nice configuration files
+        self.__specreposrootdir="/var/lib/pydar2/specrepos"
+        self.__specRepositoryList = SpecRepositoryList()
+        
+        # some default info, should be read from some files
+        #sr = SpecRepository("rpmforge",SpecRepository.TYPE_SVN,self.specreposrootdir + "/rpmforge/rpms")
+        srf = SpecRepositoryFactory.getInstance();
+        sr = srf.createSpecRepository("rpmforge",SpecRepository.TYPE_SVN,self.__specreposrootdir + "/rpmforge/rpms")
+        self.getSpecRepositoryList().add(sr)
+        #sr = SpecRepository("pld",SpecRepository.TYPE_CVS,self.specreposrootdir + "/pld/SPECS")
+        sr = srf.createSpecRepository("pld",SpecRepository.TYPE_CVS,self.__specreposrootdir + "/pld/SPECS")
+        self.getSpecRepositoryList().add(sr)
+        #sr = SpecRepository("fedoraextrasdevel",SpecRepository.TYPE_CVS,self.specreposrootdir + "/fedoraextrasdevel")
+        #self.specrepositories.append(sr)
+        #sr = SpecRepository("local",SpecRepositoryFactory.TYPE_FILES,self.specreposrootdir + "/local")
+        sr = srf.createSpecRepository("local",SpecRepository.TYPE_FILES,self.__specreposrootdir + "/local")
+        self.getSpecRepositoryList().add(sr)
+ 
+        __withinFullInit = False
+        __fullInitDone = True
+        self.__cat.debug('end')
+        
+
+    # must be able to respond to this function without a loaded Storage instance!
+    def getStorageType(self):
+        #self.__fullInit()
+        return 1;
+            
+    def getSpecRepositoryList(self):
+        self.__fullInit()
+        return self.__specRepositoryList
+        

Added: trunk/tools/pydar2/pydar/cvsbasedspecrepository.py
===================================================================
--- trunk/tools/pydar2/pydar/cvsbasedspecrepository.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/cvsbasedspecrepository.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+
+""" Contains the information about a cvs source of spec files """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+import ConfigParser, os, posixpath, sys
+sys.path.append("pydar")
+sys.path.append(".")
+from log4py import Logger
+from specrepository import SpecRepository
+#from specrepositoryfactory import SpecRepositoryFactory
+
+class CvsBasedSpecRepository(SpecRepository):
+    # name: ascii name, for example 'rpmforge'
+    # type: a constant, can be one of "SVN", "CVS", "FILES"
+    def __init__(self, name, rootdirectory):
+        SpecRepository.__init__(self, name, rootdirectory)
+        self.__cat = Logger().get_instance(self)
+        self._setType(SpecRepository.TYPE_CVS)
+        self.__cat.debug("initialized")
+        
+    def getUpdateCommand(self):
+        return "cd " + self.getRootDirectory() + "; cvs update"

Added: trunk/tools/pydar2/pydar/filesbasedspecrepository.py
===================================================================
--- trunk/tools/pydar2/pydar/filesbasedspecrepository.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/filesbasedspecrepository.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+
+""" Contains the information about a files source of spec files """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+import ConfigParser, os, posixpath, sys
+sys.path.append("pydar")
+sys.path.append(".")
+from log4py import Logger
+from specrepository import SpecRepository
+#from specrepositoryfactory import SpecRepositoryFactory
+
+class FilesBasedSpecRepository(SpecRepository):
+    # name: ascii name, for example 'rpmforge'
+    # type: a constant, can be one of "SVN", "CVS", "FILES"
+    def __init__(self, name, rootdirectory):
+        SpecRepository.__init__(self, name, rootdirectory)
+        self.__cat = Logger().get_instance(self)
+        self._setType(SpecRepository.TYPE_FILES)
+        self.__cat.debug("initialized")
+        
+    def getUpdateCommand(self):
+        return ""

Added: trunk/tools/pydar2/pydar/memorystorage.py
===================================================================
--- trunk/tools/pydar2/pydar/memorystorage.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/memorystorage.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,30 @@
+
+""" This class contains all the functions for storing stuff in memory """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+from command import Command
+from log4py import Logger
+import pgdb, posixpath, posix, string
+
+# needs to be rewritten so it uses only arrays/hashes
+
+class MemoryStorage(Storage):
+    def __init__(self,myconfig):
+        self.cat = Logger().get_instance(self)
+        self.config = myconfig
+        self.cat.debug("initialized")
+        raise Exception("MemoryStorage is not yet implemented")

Added: trunk/tools/pydar2/pydar/postgresqlstorage.py
===================================================================
--- trunk/tools/pydar2/pydar/postgresqlstorage.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/postgresqlstorage.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,253 @@
+
+""" This class contains all the functions for storing stuff in the database """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+# if you want to have a pydar which works without a database or with another type of database
+# then you have to write a new subclass of Storage
+
+import sys
+sys.path.append("pydar")
+sys.path.append(".")
+from command import Command
+from log4py import Logger
+import config
+from storage import Storage
+import pgdb, posixpath, posix, string
+
+class PostgresqlStorage(Storage):
+    def __init__(self):
+        self.cat = Logger().get_instance(self)
+        self.cat.debug("initialized")
+    
+    def getConfig():
+        raise Exception("todo getConfig")
+
+    def getSpecRepositoryFileListToIds(self,specRepo):
+        retval = {}
+        conn = self.__getConnection()
+        cursor = conn.cursor()
+        sql = "select subdir, filename, id from pydar2_specfile where specrepoid=" + str(specRepo.getId())
+        cursor.execute(sql)
+        if cursor.rowcount > 0:
+            arr = cursor.fetchall()
+            for row in arr:
+                subdir = row[0]
+                filename = row[1]
+                id = row[2]
+                retval[subdir + '/' + filename] = id
+        cursor.close()
+        self.__releaseConnection(conn)
+        return retval
+        
+        
+    def saveSpecRepositorySpecFile(self, specRepo, specRepoSpecFile):
+        conn = self.__getConnection()
+        cursor = conn.cursor()
+        if specRepoSpecFile.getId() != None and specRepoSpecFile.getId() >= 0:
+            # it should be in the database..
+            sql = "update pydar2_specfile set filename='" + str(specRepoSpecFile.getFileName()) + "', "
+            sql = sql + " subdir='" + str(specRepoSpecFile.getSubDir()) + "', "
+            sql = sql + " specrepoid=" + str(specRepo.getId()) + ", "
+            sql = sql + " checksum='" + str(specRepoSpecFile.getCheckSum()) + "', "
+            sql = sql + " where id=" + str(specRepoSpecFile.getId())
+            cursor.execute(sql)
+            conn.commit()
+        else:
+            # new spec file, insert it
+            sql = "insert into pydar2_specfile (specrepoid, filename, subdir, checksum) values ("
+            sql = sql + "" + str(specRepo.getId()) + ","
+            sql = sql + "'" + str(specRepoSpecFile.getFileName()) + "',"
+            sql = sql + "'" + str(specRepoSpecFile.getSubDir()) + "',"
+            sql = sql + "'" + str(specRepoSpecFile.getCheckSum()) + "')"
+            cursor.execute(sql)
+            conn.commit()
+        # now get the id so we can return it
+        cursor.execute("select id from pydar2_specfile where filename='" + str(specRepoSpecFile.getFileName()) + "' and subdir='" + str(specRepoSpecFile.getSubDir()) + "' and specrepoid=" + str(specRepo.getId()))
+        retval = None
+        if cursor.rowcount > 0:
+            arr = cursor.fetchall()
+            for row in arr:
+                retval = row[0]
+        cursor.close()
+        self.__releaseConnection(conn)
+        return retval
+    
+    def saveSpecRepository(self,specRepo):
+        conn = self.__getConnection()
+        cursor = conn.cursor()
+        cursor.execute("select * from pydar2_specrepo where name='" + str(specRepo.getName()) + "'")
+        if cursor.rowcount > 0:
+            # specrepo exists, update it
+            sql = "update pydar2_specrepo set rootdirectory='" + str(specRepo.getRootDirectory()) + "', type='"
+            sql = sql + str(specRepo.getType()) + "', deleted='0' where name='" + str(specRepo.getName()) + "'"
+            cursor.execute(sql)
+            conn.commit()
+        else:
+            # specrepo does not exist, add it
+            sql = "insert into pydar2_specrepo (name, rootdirectory, type) values ('" + str(specRepo.getName()) + "','" + str(specRepo.getRootDirectory()) + "','" + str(specRepo.getType()) + "')"
+            cursor.execute(sql)
+            conn.commit()
+        # now get the id again
+        cursor.execute("select id from pydar2_specrepo where name='" + str(specRepo.getName()) + "'")
+        retval = None
+        arr = cursor.fetchall()
+        for row in arr:
+            retval = row[0]
+        cursor.close()
+        self.__releaseConnection(conn)
+        return retval
+        
+    # @todo add some type of connection pooling 
+    def __getConnection(self):
+        conn = pgdb.connect(config.Config.getInstance().getPostgresqlConnectString())
+        return conn
+        
+    def __releaseConnection(self,conn):
+        conn.close()
+    
+    # returns a hash with ( __subDir + '/' + __fileName ) => ( checksum )
+    def getSpecRepositoryFileListToChecksum(self,specRepo):
+        retval = {}
+        conn = self.__getConnection()
+        cursor = conn.cursor()
+        sql = "select subdir, filename, checksum from pydar2_specfile where specrepoid "
+        sql = sql + "in (select id from pydar2_specrepo where name='" + specRepo.getName() + "')"
+        cursor.execute(sql)
+        if cursor.rowcount > 0:
+            arr = cursor.fetchall()
+            for row in arr:
+                subdir = row[0]
+                filename = row[1]
+                checksum = row[2]
+                retval[subdir + '/' + filename] = checksum
+        cursor.close()
+        self.__releaseConnection(conn)
+        return retval
+        
+    def createCommand(self,commandName,userId,specName,toEmail,releaseTag,machRoot,priority):
+        # spec name can also be the contents of a specfile...
+        self.cat.debug("start")
+        aCommand = Command(commandName,userId,specName,toEmail,releaseTag,machRoot,priority)
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("insert into pydar_commands (commandname,userid,specname,toemail,releasetag,machroot,priority) values ('"
+        + aCommand.commandName + "','"
+        + aCommand.userId + "','"
+        + aCommand.specName + "','"
+        + aCommand.toEmail + "','"
+        + aCommand.releaseTag + "','"
+        + aCommand.machRoot + "',"
+        + aCommand.priority + ")")
+        conn.commit()
+        cursor.close()
+        conn.close()
+
+    def checkIfValidUserId(self, userId):
+        self.cat.debug("start, userId=" + str(userId))
+        retval = 0
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("select * from pydar_users where id='" + str(userId) + "'")
+        if cursor.rowcount > 0:
+            retval = 1
+        cursor.close()
+        conn.close()
+        self.cat.debug("retval=" + str(retval))
+        return retval
+
+    def checkIfValidBuildMachineId(self, buildmachineid):
+        self.cat.debug("start, id=" + buildmachineid)
+        conn = pgdb.connect(self.config.dbconnectstring)
+        retval = 0
+        cursor = conn.cursor()
+        cursor.execute("select * from pydar_buildmachines where id='" + buildmachineid + "'")
+        if cursor.rowcount > 0:
+            retval = 1
+        cursor.close()
+        conn.close()
+        self.cat.debug("retval=" + str(retval))
+        return retval
+
+    def registerSlave(self, buildmachineid):
+        self.cat.debug("start, buildmachineid=" + buildmachineid)
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("insert into pydar_buildmachine_registrations (id) values ('" + buildmachineid + "')")
+        cursor.execute("delete from pydar_buildmachine_machroots where buildmachineid='" + buildmachineid + "'")
+        conn.commit()
+        cursor.close()
+        conn.close()
+
+    def addMachRoot(self, buildmachineid, machroot):
+        self.cat.debug("start, id=" + buildmachineid + ",machroot=" + machroot)
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("insert into pydar_buildmachine_machroots (buildmachineid,machroot) values ('" + buildmachineid + "','" + machroot + "')")
+        conn.commit()
+        cursor.close()
+        conn.close()
+
+    def addResultFileName(self,buildmachineid,commandId,fileName):
+        # no check on buildmachineid yet...
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("insert into pydar_actions_files (commandid,filename) values (" + str(commandId) + ",'" + fileName + "')")
+        conn.commit()
+        cursor.close()
+        conn.close()
+
+    def setBuildResult(self,buildmachineid,commandId,buildResult):
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("insert into pydar_actions (buildmachineid,commandid,statusid) values ('" + buildmachineid + "'," + str(commandId) + "," + str(buildResult+1) + ")")
+        cursor.execute("update pydar_commands set handled=true,inprogress=false where id=" + str(commandId))
+        conn.commit()
+        cursor.close()
+        conn.close()
+
+    # a seperate program updates the spec file repositories.
+    # result: the commands which have to be executed to update all the spec file repositories
+    # example:  "cd /a/b/c; svn update"
+    def getSpecRepositoriesUpdateCommands(self):
+        self.cat.debug("start")
+        retval = ""
+        for repo in self.config.specrepositories:
+            retval = retval + repo.getUpdateCommand() + "\n"
+        return retval
+    
+
+    def reserveCommand(self, buildmachineid):
+        self.cat.debug("start, buildmachineid=" + buildmachineid)
+        conn = pgdb.connect(self.config.dbconnectstring)
+        cursor = conn.cursor()
+        cursor.execute("select pc.id, pc.specname, pc.toemail, pc.releasetag, pc.machroot, pc.commandname from pydar_commands pc where (pc.commandname='BUILD' or pc.commandname='TESTBUILD') and not pc.handled and not pc.inprogress and pc.machroot in (select machroot from pydar_buildmachine_machroots where buildmachineid='" + buildmachineid + "')  order by pc.priority desc, pc.machroot desc, pc.id asc")
+        retval = ""
+        if cursor.rowcount > 0:
+            rs = cursor.fetchone()
+            self.cat.debug("command found for buildmachineid=" + buildmachineid + ",rs=" + str(rs))
+            aCommand = Command(rs[5],'-1',rs[1],rs[2],rs[3],rs[4])
+            aCommand.setCommandId(rs[0])
+            cursor.execute("update pydar_commands set inprogress=true where id=" + str(aCommand.commandId))
+            cursor.execute("insert into pydar_actions (commandid, statusid, buildmachineid) values (" + str(aCommand.commandId) + ",0,'" + buildmachineid + "')")
+            retval = aCommand
+        else:
+            self.cat.debug("nothing to do for buildmachineid=" + buildmachineid)
+            retval = ""
+        conn.commit()
+        cursor.close()
+        conn.close()
+        return retval

Added: trunk/tools/pydar2/pydar/pydarclient.py
===================================================================
--- trunk/tools/pydar2/pydar/pydarclient.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/pydarclient.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+
+""" helper class for calling functions on the master """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+
+import getopt, os, sys
+sys.path.append("/usr/share/pydar/pydar")
+sys.path.append("pydar")
+from xmlrpclib import Server
+from log4py import Logger
+
+class PydarClient:
+    def __init__(self,buildmasterurl):
+        self.cat = Logger().get_instance(self)
+        self.buildmasterurl = buildmasterurl
+        self.cat.debug("initialised, buildmasterurl=" + self.buildmasterurl)
+        
+    def getSpecRepositoriesUpdateCommands(self,userId):
+        myserverclient = Server(self.buildmasterurl)
+        retval = myserverclient.getSpecRepositoriesUpdateCommands(userId)
+        return retval
+
+    def updateAllSpecRepositoriesFileLists(self,userId):
+        myserverclient = Server(self.buildmasterurl)
+        retval = myserverclient.updateAllSpecRepositoriesFileLists(userId)
+        return retval


Property changes on: trunk/tools/pydar2/pydar/pydarclient.py
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/tools/pydar2/pydar/specrepository.py
===================================================================
--- trunk/tools/pydar2/pydar/specrepository.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/specrepository.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,143 @@
+#!/usr/bin/python
+
+""" Contains the information about 1 source of spec files """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+from log4py import Logger
+from storagefactory import StorageFactory
+from specrepositoryspecfile import SpecRepositorySpecFile
+import posixpath, posix, string
+
+# A specrepository has some attributes (a name, the root directory)
+# and a list of objects which represent 1 spec file within this specrepository
+# The StoreFactory is used to create a store object so this list of spec files can be saved 
+# within a database if you use the right type of store
+
+class SpecRepository:
+    TYPE_SVN = "SVN"
+    TYPE_CVS = "CVS"
+    TYPE_FILES = "FILES"
+    TYPE_UNKNOWN = "UNKNOWN"
+
+    # name: ascii name, for example 'rpmforge'
+    # type: a constant, can be one of "SVN", "CVS", "FILES"
+    def __init__(self, name, rootdirectory):
+        self.__cat = Logger().get_instance(self)
+        self.__name = name
+        self.__rootdirectory = rootdirectory
+        self._setType(SpecRepository.TYPE_UNKNOWN)
+        self.__cat.debug("initialized")
+        self.__specFiles = [];
+        self.__storage = StorageFactory.getStorage()
+        self.__id = None
+        
+    def getUpdateCommand(self):
+        return ""
+    
+    def getName(self):
+        return self.__name
+
+    def getRootDirectory(self):
+        return self.__rootdirectory
+    
+    def getType(self):
+        return self.__type
+    
+    def _setType(self,myType):
+        self.__type = myType
+        
+    # first get the list of files which have to be updated,
+    # then update every file which has been changed
+    def __updateFileListInStorage(self):
+        arr = self.__getListOfModifiedFiles()
+        for modFile in arr:
+            self.__updateFileInStorage(modFile)
+    
+    # the storage class assigns a unique id to each specrepository
+    def getId(self):
+        self.__cat.debug("returnval:" + str(self.__id))
+        return self.__id
+        
+    def setId(self,newId):
+        self.__cat.debug("id set to: " + str(newId))
+        self.__id = newId
+    
+    def __updateFileInStorage(self, specfile):
+        self.__cat.debug("start, specfile=" + specfile.getFileName())
+        specfile.setId(self.__storage.saveSpecRepositorySpecFile(self, specfile))
+    
+    # normally the checksums are also stored in storage,
+    # this function is only called at the end of updateFileList
+    # so we can compare the checksums of  __specFiles with 
+    # the contents of the store
+    def __getListOfModifiedFiles(self):
+        self.__cat.debug("start")
+        # we return an array of SpecRepositorySpecFile objects
+        retval = []
+        myFileNameToCheckSumHash = self.__storage.getSpecRepositoryFileListToChecksum(self)
+        for diskSpecFile in self.__specFiles:
+            if (diskSpecFile.getPathFromRoot() in myFileNameToCheckSumHash.keys()):
+                # this specrepositoryspecfile is already in the storage
+                if (diskSpecFile.getCheckSum() != myFileNameToCheckSumHash[diskSpecFile.getPathFromRoot()]):
+                    retval.append(diskSpecFile)
+            else:
+                # new file
+                retval.append(diskSpecFile)
+        return retval
+        
+    def updateFileList(self):
+        self.__cat.debug("start")
+        dirname = self.getRootDirectory()
+        # generate a list of all found spec files in this repository and store it in the database
+        # then the master can accept commands to build one of those spec files
+        self.__specFiles = self.__recursiveFindFiles(dirname, "")
+        self.__assignIdsFromStorage()
+        self.__updateFileListInStorage()
+        return len(self.__specFiles);
+    
+    # storage maybe has unique ids about the spec files: ask the storage for a hash subdir +/+filename => unique id so we can assign them
+    def __assignIdsFromStorage(self):
+        self.__cat.debug("start")
+        myFileNameToIdHash = self.__storage.getSpecRepositoryFileListToIds(self)
+        for diskSpecFile in self.__specFiles:
+            if (diskSpecFile.getPathFromRoot() in myFileNameToIdHash.keys()):
+                # this specrepositoryspecfile is already in the storage
+                pathFromRoot = diskSpecFile.getPathFromRoot()
+                id = myFileNameToIdHash[pathFromRoot]
+                diskSpecFile.setId(id)
+        
+    def __recursiveFindFiles(self,topDir,startDir):
+        #self.cat.debug("start, startDir=" + startDir)
+        arr = []
+        fullDir = posixpath.join(topDir,startDir)
+        topDirList = posix.listdir(fullDir)
+        for entryInDir in topDirList:
+            #self.cat.debug("entryInDir=" + entryInDir)
+            fullEntryInDir = posixpath.join(fullDir,entryInDir)
+            if posixpath.isdir(fullEntryInDir):
+                #self.cat.debug("it's a dir!")
+                # recurse
+                tmpArr = self.__recursiveFindFiles(topDir,posixpath.join(startDir,entryInDir))
+                arr = arr + tmpArr
+            else:
+                # it's not a dir
+                rindex = string.rfind(entryInDir,'.spec')
+                if rindex > 0 and rindex == len(entryInDir) - len('.spec'):
+                    #self.cat.debug("spec match, entryInDir=" + entryInDir)
+                    spf = SpecRepositorySpecFile(self,startDir,entryInDir)
+                    arr.append(spf)
+        return arr

Added: trunk/tools/pydar2/pydar/specrepositoryfactory.py
===================================================================
--- trunk/tools/pydar2/pydar/specrepositoryfactory.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/specrepositoryfactory.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+""" Creates types of spec repository objects """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+from log4py import Logger
+from svnbasedspecrepository import SvnBasedSpecRepository
+from cvsbasedspecrepository import CvsBasedSpecRepository
+from filesbasedspecrepository import FilesBasedSpecRepository
+from specrepository import SpecRepository
+
+## SINGLETON: so use the getInstance() method
+
+class SpecRepositoryFactory:
+    __myInstance = None
+    # TODO, make static
+    def __init__(self):
+        if SpecRepositoryFactory.__myInstance != None:
+            raise Exception("use getInstance() of SpecRepositoryFactory")
+        else:
+            SpecRepositoryFactory.__myInstance = self
+
+    #@classmethod
+    def getInstance(cls):
+        if cls.__myInstance == None:
+            unused = SpecRepositoryFactory()
+        return cls.__myInstance
+    getInstance = classmethod(getInstance)
+
+    def createSpecRepository(self,name, type, rootdirectory):
+        if type == SpecRepository.TYPE_SVN:
+            return SvnBasedSpecRepository(name, rootdirectory)
+        if type == SpecRepository.TYPE_CVS:
+            return CvsBasedSpecRepository(name, rootdirectory)
+        if type == SpecRepository.TYPE_FILES:
+            return FilesBasedSpecRepository(name, rootdirectory)
+        # oops, error
+        raise Exception, "unknown type " + str(type)

Added: trunk/tools/pydar2/pydar/specrepositorylist.py
===================================================================
--- trunk/tools/pydar2/pydar/specrepositorylist.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/specrepositorylist.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,72 @@
+#!/usr/bin/python
+
+""" Contains the specrepository objects """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+from log4py import Logger
+from storagefactory import StorageFactory
+
+class SpecRepositoryList:
+    def __init__(self):
+        self.__cat = Logger().get_instance(self)
+        # configuration about each source (source of spec files)
+        self.__specrepositories = []
+        # this array contains an array of SpecRepoFileList objects for each specrepo name
+        #self.__specRepoFileListBySpecRepoName = {};
+        self.__myStorage = StorageFactory.getStorage()
+    
+    def add(self,specRepo):
+        if specRepo != None:
+            self.__specrepositories.append(specRepo)
+        self.__storeSpecRepo(specRepo)
+    
+    def __storeSpecRepo(self, specRepo):
+        id = self.__myStorage.saveSpecRepository(specRepo)
+        specRepo.setId(id)
+        
+    
+    def getSpecRepositoryByName(self,name):
+        for sr in self.__specrepositories:
+            if sr.getName() == name:
+                return sr
+        self.cat.warn("no SpecRepository found with name: " + name)
+        raise Exception, "no SpecRepository " + str(type)
+
+    def getSpecRepoStats(self, sreponame):
+        repo = self.getSpecRepositoryByName(sreponame)
+        retval = repo.getName() + " (" + repo.getType() + "): " + str(len(self.specRepoFileListBySpecRepoName[sreponame])) + "\n"
+        return retval
+    
+    def getConfig(self):
+        retval = ""
+        cnt = 0
+        for srepo in self.__specrepositories:
+            retval = retval + "SpecRepository " + str(cnt)
+            retval = retval + ": name=" + srepo.getName() + ", type="
+            retval = retval + srepo.getType() + ", rootdirectory=" + srepo.getRootDirectory() + "\n"
+            rootdir = srepo.getRootDirectory()
+            if posixpath.isdir(rootdir):
+                retval = retval + "this rootdirectory exists\n"
+            else:
+                retval = retval + "this rootdir does not exist\n"
+            cnt = cnt + 1
+        return retval
+ 
+    def updateAllFileLists(self):
+        for i in self.__specrepositories:
+            i.updateFileList()
+ 

Added: trunk/tools/pydar2/pydar/specrepositoryspecfile.py
===================================================================
--- trunk/tools/pydar2/pydar/specrepositoryspecfile.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/specrepositoryspecfile.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,71 @@
+
+""" Represents one spec file within a SpecRepository """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+# a place holder for some values/information about 1 spec file in one of the SpecRepository objects
+# also calculates the SHA1 checksum so it is easy to check if a file is changed or not
+
+from log4py import Logger
+import sha
+
+class SpecRepositorySpecFile:
+    def __init__(self, specRepository,subDir,fileName):
+        self.__cat = Logger().get_instance(self)
+        self.__specRepository = specRepository
+        self.__subDir = subDir
+        self.__fileName = fileName
+        self.__checksum = self.__calculateCheckSum()
+        self.__id = None
+        #self.cat.debug("start, specRepositoryName=" + self.specRepositoryName + ",specRepositoryRootDir=" + self.specRepositoryRootDir + ",subDir=" + self.subDir + ",fileName=" + self.fileName)
+
+    def getCheckSum(self):
+        return self.__checksum
+        
+        
+    def __calculateCheckSum(self):
+        s = sha.new()
+        fullFileName = self.__specRepository.getRootDirectory() + "/" + self.__subDir + "/" + self.__fileName
+        f = open(fullFileName, 'r')
+        line = f.readline()
+        while line != '':
+            s.update(line)
+            line = f.readline()
+        f.close()
+        return s.hexdigest()
+    
+    def getSpecRepository(self):
+        return self.__specRepository
+        
+    def getSubDir(self):
+        return self.__subDir
+        
+    def getFileName(self):
+        return self.__fileName
+    
+    # the following should be unique within one specrepository!!
+    def getPathFromRoot(self):
+        return self.__subDir + '/' + self.__fileName
+
+    def setId(self, newId):
+        self.__id = newId
+        
+    def getId(self):
+        return self.__id
+    
+    def toString(self):
+        return "SpecRepositorySpecFile: subDir=" + str(self.getSubDir()) + ",fileName=" + str(self.getFileName()) + ",specRepository.name=" + str(self.getSpecRepository().getName())
+        

Added: trunk/tools/pydar2/pydar/storage.py
===================================================================
--- trunk/tools/pydar2/pydar/storage.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/storage.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,87 @@
+
+""" This class contains all the functions for storing stuff """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+# normally you dont use this class directly but a subclass
+# use getInstance() to get the correct type of subclass (defined by a config parameter)
+# PostgresqlStorage: store everything in a pgsql database
+# MemoryStorage: store everything in memory
+
+import posixpath, posix, string, sys, config
+sys.path.append("pydar")
+sys.path.append(".")
+from command import Command
+from log4py import Logger
+
+# SINGLETON, so use getInstance()
+
+
+class Storage:
+    __myInstance = None
+    
+    def __init__(self):
+        raise Exception("use getStorage() on StorageFactory")
+    
+    ## classmethod
+    #def getInstance(cls):
+    #    if cls.__myInstance == None:
+    #        unused = Storage()
+    #    return cls.__myInstance
+    #getInstance = classmethod(getInstance)
+    
+    def getSpecRepositoryFileListToIds(self,specRepo):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+    
+    def saveSpecRepositorySpecFile(self, specRepo, specRepoSpecFile):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+    
+    def saveSpecRepository(self,specRepo):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+      
+    def getSpecRepositoryFileListToChecksum(self,specRepo):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+        
+    def createCommand(self,commandName,userId,specName,toEmail,releaseTag,machRoot,priority):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+        
+    def checkIfValidUserId(self, userId):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+
+    def checkIfValidBuildMachineId(self, buildmachineid):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+
+    def registerSlave(self, buildmachineid):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+
+    def addMachRoot(self, buildmachineid, machroot):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+
+    def addResultFileName(self,buildmachineid,commandId,fileName):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+
+    def setBuildResult(self,buildmachineid,commandId,buildResult):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+
+    # a seperate program updates the spec file repositories.
+    # result: the commands which have to be executed to update all the spec file repositories
+    # example:  "cd /a/b/c; svn update"
+    def getSpecRepositoriesUpdateCommands(self):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")
+    
+
+    def reserveCommand(self, buildmachineid):
+        raise Exception("Dont use Storage but a subclass of Storage, use getInstance()")

Added: trunk/tools/pydar2/pydar/storagefactory.py
===================================================================
--- trunk/tools/pydar2/pydar/storagefactory.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/storagefactory.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+""" Creates types of storage objects """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+from log4py import Logger
+from postgresqlstorage import PostgresqlStorage
+
+## SINGLETON: so use the getInstance() or immediately the getStorage() method
+
+class StorageFactory:
+    __myInstance = None
+    __myStorageInstance = None
+    
+    def __init__(self):
+        if StorageFactory.__myInstance != None:
+            raise Exception("use getInstance() of StorageFactory")
+        else:
+            StorageFactory.__myInstance = self
+
+    #@classmethod
+    def getInstance(cls):
+        if cls.__myInstance == None:
+            unused = StorageFactory()
+        return cls.__myInstance
+    getInstance = classmethod(getInstance)
+
+    def getStorage(cls):
+        if cls.__myStorageInstance == None:
+            cls.__myStorageInstance = PostgresqlStorage()
+        return cls.__myStorageInstance
+    getStorage = classmethod(getStorage)
+    

Added: trunk/tools/pydar2/pydar/svnbasedspecrepository.py
===================================================================
--- trunk/tools/pydar2/pydar/svnbasedspecrepository.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/svnbasedspecrepository.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+
+""" Contains the information about a svn source of spec files """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+import ConfigParser, os, posixpath, sys
+sys.path.append("pydar")
+sys.path.append(".")
+from log4py import Logger
+from specrepository import SpecRepository
+#from specrepositoryfactory import SpecRepositoryFactory
+
+class SvnBasedSpecRepository(SpecRepository):
+    # name: ascii name, for example 'rpmforge'
+    # type: a constant, can be one of "SVN", "CVS", "FILES"
+    def __init__(self, name, rootdirectory):
+        SpecRepository.__init__(self, name, rootdirectory)
+        self.__cat = Logger().get_instance(self)
+        self._setType(SpecRepository.TYPE_SVN)
+        self.__cat.debug("initialized")
+        
+    def getUpdateCommand(self):
+        return "cd " + self.getRootDirectory() + "; svn update"

Modified: trunk/tools/pydar2/pydar/yumbasedbuildroot.py
===================================================================
--- trunk/tools/pydar2/pydar/yumbasedbuildroot.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar/yumbasedbuildroot.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -150,11 +150,11 @@
         # todo: the sources should be available in a certain dir
         self.cat.debug("start")
         
-    def copySpecFile(spec,brr)
+    def copySpecFile(spec,brr):
         # todo
         self.cat.debug("start")
         
-    def createScript(spec,brr)
+    def createScript(spec,brr):
         # todo
         self.cat.debug("start")
         script = "#!/bin/bash\n"
@@ -165,7 +165,7 @@
         script = script + "done\n"
 
         
-    def callBuildScript(brr)
+    def callBuildScript(brr):
         cmd = "sudo chroot " + self.rootdir + "/bin/bash /pydar2build.sh"
         self.logCommand(cmd,brr)
     
@@ -175,7 +175,7 @@
 myRoot.prepareRoot()
 spec = SpecFile('/home/dries/projects/rap-svn/svn/trunk/rpms/aldo/aldo.spec',' --define "fc3 1" ')
 myRoot.installRpms(spec.getBuildRequires())
-myRoot.
+#myRoot.
 print myRoot.logText
 
 

Modified: trunk/tools/pydar2/pydar-buildserver-master.py
===================================================================
--- trunk/tools/pydar2/pydar-buildserver-master.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar-buildserver-master.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -26,7 +26,8 @@
 from config import Config
 from thread import start_new_thread
 from command import Command
-from store import Store
+from storagefactory import StorageFactory
+from specrepositoryfactory import SpecRepositoryFactory
 import time
 
 
@@ -36,10 +37,10 @@
 # these functions must check if the caller has a valid ID
 
 class MasterRpc:
-    def __init__(self,myconfig,mystore):
+    def __init__(self):
         self.cat = Logger().get_instance(self)
-        self.config = myconfig
-        self.store = mystore
+        self.config = Config.getInstance()
+        self.store = StorageFactory.getStorage()
         self.cat.debug("initialized")
 
     # a slave wants to register itself (timestamp is saved)
@@ -111,15 +112,50 @@
             return "OK"
         else:
             return "UNKNOWN USERID"
+    
+    def getConfig(self,userId):
+        self.cat.debug("start, userId=" + userId)
+        if self.store.checkIfValidUserId(userId):
+            return self.config.getConfig()
+        else:
+            return "UNKNOWN USERID"
+    
+    def updateSpecRepositoriesFileList(self,userId,specRepoName):
+        self.cat.debug("start,userId=" + str(userId))
+        if self.store.checkIfValidUserId(userId):
+            return self.store.updateSpecRepositoriesFileList(specRepoName)
+        else:
+            return "UNKNOWN USERID"
+        
+    def updateAllSpecRepositoriesFileLists(self,userId):
+        self.cat.debug("start,userId=" + str(userId))
+        if self.store.checkIfValidUserId(userId):
+            retval = ""
+            for repo in self.config.specrepositories:
+                retval = retval + str(self.store.updateSpecRepositoriesFileList(repo.getName()))
+            return retval
+        else:
+            return "UNKNOWN USERID"
+    
+    def getSpecRepositoriesUpdateCommands(self,userId):
+        self.cat.debug("start,userId=" + str(userId))
+        if self.store.checkIfValidUserId(userId):
+            return self.store.getSpecRepositoriesUpdateCommands()
+        else:
+            return "UNKNOWN USERID"
 
 
 class Master:
     def __init__(self,myconfig):
         self.cat = Logger().get_instance(self)
         self.config = myconfig
-        # open a connection to the db
-        self.store = Store(self.config)
         self.cat.debug("initialized")
+        # update the list of known spec files
+        self.config.getSpecRepositoryList().updateAllFileLists()
+        self.cat.debug("file lists updated")
+        #for testing some stuff:
+        #tmp = MasterRpc(self.config,self.store)
+        #print tmp.getSpecRepositoriesUpdateCommands(self.config.updateUserId)
 
     def run(self):
         self.cat.debug("start")
@@ -129,15 +165,21 @@
         # open a listen socket and wait for commands from the master
         self.cat.debug("buildmasterhostname=" +self.config.buildmasterhostname + ",buildmasterport=" + str(self.config.buildmasterport))
         myslaveserver = SimpleXMLRPCServer((self.config.buildmasterhostname,self.config.buildmasterport))
-        myslaveserver.register_instance(MasterRpc(self.config,self.store))
+        myslaveserver.register_instance(MasterRpc())
         myslaveserver.serve_forever()
 
 
 def main():
-        myConfig = Config()
+        checkSingletons()
+        myConfig = Config.getInstance()
         myInstance = Master(myConfig)
         myInstance.run()
 
+def checkSingletons():
+    # call getInstance once for each of the singletons, so any following call of their constructors will failed
+    unused = Config.getInstance()
+    unused = StorageFactory.getInstance()
+    unused = SpecRepositoryFactory.getInstance()
 
 # code from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
 if __name__ == "__main__":

Modified: trunk/tools/pydar2/pydar-buildserver-slave.py
===================================================================
--- trunk/tools/pydar2/pydar-buildserver-slave.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar-buildserver-slave.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -101,10 +101,7 @@
 
     def doBuildSpec(self,command):
         # choose one implementation
-        doBuildSpecRsyncYumBased(self,command):
-        specFileName = command.specName
-        lastChangedSvnRevId = self.getLastChangedSvnRevId(self.dirMapping[specFileName], command.specName)
-        self.cat.debug("start, specFileName=" + specFileName)
+        self.doBuildSpecRsyncYumBased(command)
         
     
     def doBuildSpecRsyncYumBased(self,command):

Added: trunk/tools/pydar2/pydar-master-update.py
===================================================================
--- trunk/tools/pydar2/pydar-master-update.py	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/pydar-master-update.py	2005-04-18 20:36:17 UTC (rev 3137)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+""" update the spec file repositories """
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Copyright 2004 Dries Verachtert
+
+import ConfigParser, os, posixpath, sys, commands
+sys.path.append("pydar")
+sys.path.append(".")
+
+from pydarclient import PydarClient
+from config import Config
+
+# updates the spec file repositories on the master
+
+# - get the commands to execute from the master
+# - use those commands
+# - informs the master when the update is done -> rechecks spec files
+
+# get  the url of the master and a userId
+
+conf = Config()
+pc = PydarClient(conf.buildmasterurl)
+commandlines = pc.getSpecRepositoriesUpdateCommands(conf.updateUserId)
+lines = commandlines.split("\n")
+for line in lines:
+    print "line: " + line + "\n"
+    (status, output) = commands.getstatusoutput("/bin/bash -c \""+line+"\"")
+    print "status: " + str(status)
+    print "output: " + output
+    
+# now ask the master to update the lists about the spec files
+pc.updateAllSpecRepositoriesFileLists(conf.updateUserId)
+

Modified: trunk/tools/pydar2/sql/svncheck.sql
===================================================================
--- trunk/tools/pydar2/sql/svncheck.sql	2005-04-16 09:25:14 UTC (rev 3136)
+++ trunk/tools/pydar2/sql/svncheck.sql	2005-04-18 20:36:17 UTC (rev 3137)
@@ -1,4 +1,4 @@
-p
+
 drop sequence pydar2_specfile_idseq;
 drop sequence pydar2_distro_idseq;
 create sequence pydar2_specfile_idseq;
@@ -8,13 +8,29 @@
 drop table pydar2_specfile_tags;
 drop table pydar2_specfile;
 drop table pydar2_distro;
+drop table pydar2_specrepo;
 
+create table pydar2_specrepo (
+	id integer unique not null default nextval('pydar2_specrepo_idseq'),
+	name varchar(512) unique not null,
+	rootdirectory varchar(512) not null,
+	type varchar(32) not null,
+	addtimestamp timestamp not null default current_timestamp,
+	deleted bool not null default false
+);
+create sequence pydar2_specrepo_idseq;
+
+
 create table pydar2_specfile (
 	id	integer unique not null default nextval('pydar2_specfile_idseq'),
-	name	varchar(512) unique not null,
-	path	varchar(512) not null,
+	specrepoid integer not null,
+	filename varchar(512) not null,
+	subdir	varchar(512) not null,
+	checksum varchar(512) not null,
         addtimestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
 );
+create sequence pydar2_specfile_idseq;
+-- todo create constraint specfile_specrepoid 
 create index pydar2_specfile__id on pydar2_specfile(id);
 create index pydar2_specfile__name on pydar2_specfile(name);
 create index pydar2_specfile__both on pydar2_specfile(id,name);




More information about the commits mailing list