Author: xor
Date: 2008-11-10 03:58:08 +0000 (Mon, 10 Nov 2008)
New Revision: 23466

Modified:
   trunk/plugins/WoT/introduction/IntroductionPuzzle.java
   trunk/plugins/WoT/introduction/IntroductionServer.java
Log:
Implement some more of the identity introduction stuff.

Modified: trunk/plugins/WoT/introduction/IntroductionPuzzle.java
===================================================================
--- trunk/plugins/WoT/introduction/IntroductionPuzzle.java      2008-11-10 
03:22:59 UTC (rev 23465)
+++ trunk/plugins/WoT/introduction/IntroductionPuzzle.java      2008-11-10 
03:58:08 UTC (rev 23466)
@@ -5,6 +5,10 @@
  */
 package plugins.WoT.introduction;

+import com.db4o.ObjectContainer;
+import com.db4o.ObjectSet;
+import com.db4o.query.Query;
+
 import plugins.WoT.Identity;

 public class IntroductionPuzzle {
@@ -16,22 +20,39 @@

        private final PuzzleType mType;

+       private final String mMimeType;
+       
+       private final String mFilename;
+       
        private final byte[] mData;

        private final String mSolution;

        private final Identity mInserter;

+       private final long mValidUntilTime;
+       
+       /* FIXME: wire this in */
        /**
+        * Get a list of fields which the database should create an index on.
+        */
+       public static String[] getIndexedFields() {
+               return new String[] {"mInserter"};
+       }
+       
+       /**
         * For construction from a received puzzle.
         * @param newType
         * @param newData
         */
-       public IntroductionPuzzle(Identity newInserter, PuzzleType newType, 
byte[] newData) {
+       public IntroductionPuzzle(Identity newInserter, PuzzleType newType, 
String newMimeType, String newFilename, byte[] newData, long newValidUntilTime) 
{
                mInserter = newInserter;
                mType = newType;
+               mMimeType = newMimeType;
+               mFilename = newFilename;
                mData = newData;
-               mSolution = null; 
+               mSolution = null;
+               mValidUntilTime = newValidUntilTime;
        }

        /**
@@ -39,17 +60,29 @@
         * @param newType
         * @param newData
         */
-       public IntroductionPuzzle(Identity newInserter, PuzzleType newType, 
byte[] newData, String newSolution) {
+       public IntroductionPuzzle(Identity newInserter, PuzzleType newType, 
String newMimeType, String newFilename, byte[] newData, String newSolution) {
                mInserter = newInserter;
                mType = newType;
+               mMimeType = newMimeType;
+               mFilename = newFilename;
                mData = newData;
-               mSolution = newSolution; 
+               mSolution = newSolution;
+               mValidUntilTime = System.currentTimeMillis() + 
IntroductionServer.PUZZLE_INVALID_AFTER_DAYS * 24 * 60 * 60 * 1000;
        }

        public PuzzleType getPuzzleType() {
                return mType;
        }

+       public String getMimeType() {
+               return mMimeType;
+       }
+       
+       public String getFilename() {
+               /* FIXME: include date etc. */
+               return mFilename;
+       }
+       
        public byte[] getPuzzle() {
                return mData;
        }
@@ -65,4 +98,26 @@
        public Identity getInserter() {
                return mInserter;
        }
+       
+       public long getValidUntilTime() {
+               return mValidUntilTime;
+       }
+       
+       
+       public void store(ObjectContainer db) {
+               db.store(this);
+               db.commit();
+       }
+       
+       public static void deleteOldPuzzles(ObjectContainer db) {
+               Query q = db.query();
+               q.constrain(IntroductionPuzzle.class);
+               
q.descend("mValidUntilTime").constrain(System.currentTimeMillis()).smaller();
+               ObjectSet<IntroductionPuzzle> result = q.execute();
+               
+               for(IntroductionPuzzle p : result)
+                       db.delete(p);
+               
+               db.commit();
+       }
 }

Modified: trunk/plugins/WoT/introduction/IntroductionServer.java
===================================================================
--- trunk/plugins/WoT/introduction/IntroductionServer.java      2008-11-10 
03:22:59 UTC (rev 23465)
+++ trunk/plugins/WoT/introduction/IntroductionServer.java      2008-11-10 
03:58:08 UTC (rev 23466)
@@ -5,15 +5,31 @@
  */
 package plugins.WoT.introduction;

+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
 import java.util.Date;

+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
 import com.db4o.ObjectContainer;
 import com.db4o.ObjectSet;
+import com.db4o.ext.DatabaseClosedException;
+import com.db4o.ext.Db4oIOException;
+import com.db4o.query.Query;

+import freenet.client.ClientMetadata;
 import freenet.client.HighLevelSimpleClient;
+import freenet.client.InsertBlock;
+import freenet.client.InsertException;
+import freenet.keys.FreenetURI;
 import freenet.support.Logger;
+import freenet.support.api.Bucket;
 import freenet.support.io.TempBucketFactory;
 import plugins.WoT.OwnIdentity;
+import plugins.WoT.exceptions.InvalidParameterException;

 /**
  * This class provides identity announcement for new identities; It uploads 
puzzles in certain time intervals and checks whether they were solved.
@@ -22,22 +38,27 @@
  */
 public class IntroductionServer implements Runnable {

-       private static long THREAD_PERIOD = 30 * 60 * 1000;
-       private static short PUZZLES_PER_DAY = 1; 
-       private static long PUZZLE_INVALID_AFTER_DAYS = 3;
+       private static final long THREAD_PERIOD = 30 * 60 * 1000;
+       private static final short PUZZLES_COUNT = 5; 
+       public static final long PUZZLE_INVALID_AFTER_DAYS = 3;
+       private static final String INTRODUCTION_CONTEXT = "introduction";

+       private Thread mThread;
+       
+       /** Used to tell the introduction server thread if it should stop */
+       private boolean isRunning;
+       
        /** A reference to the database */
-       ObjectContainer db;
+       private ObjectContainer db;

        /** A reference the HighLevelSimpleClient used to perform inserts */
-       HighLevelSimpleClient client;
+       private HighLevelSimpleClient mClient;

        /** The TempBucketFactory used to create buckets from puzzles before 
insert */
-       final TempBucketFactory tBF;
-       
-       /** Used to tell the introduction server thread if it should stop */
-       boolean isRunning;
+       private final TempBucketFactory mTBF;

+       private final IntroductionPuzzleFactory[] mPuzzleFactories = new 
IntroductionPuzzleFactory[] { new CaptchaFactory1() };
+
        /**
         * Creates an IntroductionServer
         * 
@@ -49,33 +70,32 @@
         * @param tbf
         *            Needed to create buckets from Identities before insert
         */
-       public IntroductionServer(ObjectContainer db, HighLevelSimpleClient 
client, TempBucketFactory tbf) {
-               this.db = db;
-               this.client = client;
+       public IntroductionServer(ObjectContainer myDB, HighLevelSimpleClient 
myClient, TempBucketFactory myTBF) {
                isRunning = true;
-               tBF = tbf;
+               db = myDB;
+               mClient = myClient;
+               mTBF = myTBF;
        }

        public void run() {
+               mThread = Thread.currentThread();
                try {
-                       Thread.sleep((long) (3*60*1000 * (0.5f + 
Math.random()))); // Let the node start up
+                       Thread.sleep((long) (1*60*1000 * (0.5f + 
Math.random()))); // Let the node start up
                }
                catch (InterruptedException e) {}

                while(isRunning) {
                        ObjectSet<OwnIdentity> identities = 
OwnIdentity.getAllOwnIdentities(db);

+                       IntroductionPuzzle.deleteOldPuzzles(db);
+                       
                        while(identities.hasNext()) {
                                OwnIdentity identity = identities.next();
-                               synchronized(identity) {
-                                       if(identity.hasContext("introduction")) 
{
-                                               try {
-                                                       insertPuzzles(identity);
-                                                       // 
identity.setLastInsert(new Date()); 
-                                                       // db.store(identity);
-                                               } catch (Exception e) {
-                                                       Logger.error(this, 
"Puzzle insert failed: " + e.getMessage(), e);
-                                               }
+                               if(identity.hasContext("introduction")) {
+                                       try {
+                                               managePuzzles(identity);
+                                       } catch (Exception e) {
+                                               Logger.error(this, "Puzzle 
insert failed: " + e.getMessage(), e);
                                        }
                                }
                        }
@@ -84,13 +104,61 @@
                        try {
                                Thread.sleep((long) (THREAD_PERIOD * (0.5f + 
Math.random())));
                        }
-                       catch (InterruptedException e){}
+                       catch (InterruptedException e)
+                       {
+                               mThread.interrupt();
+                       }
                }

        }

-       private void insertPuzzles(OwnIdentity identity) {
+       public void terminate() {
+               Logger.debug(this, "Stopping the introduction server...");
+               isRunning = false;
+               mThread.interrupt();
+               try {
+                       mThread.join();
+               }
+               catch(InterruptedException e)
+               {
+                       Thread.currentThread().interrupt();
+               }
+               Logger.debug(this, "Stopped the introduction server.");
+       }
+       
+       private void managePuzzles(OwnIdentity identity) {
+               Query q = db.query();
+               q.constrain(IntroductionPuzzle.class);
+               q.descend("mInserter").constrain(identity);
+               ObjectSet<IntroductionPuzzle> puzzles = q.execute();

        }
+       
+       private void insertNewPuzzle(OwnIdentity identity) throws IOException, 
InsertException {
+               Bucket tempB = mTBF.makeBucket(10 * 1024);
+               OutputStream os = tempB.getOutputStream();
+               
+               try {
+                       IntroductionPuzzle p = 
mPuzzleFactories[(int)(Math.random() * 100) % 
mPuzzleFactories.length].generatePuzzle();
+                       os.write(p.getPuzzle());
+                       os.close();
+                       tempB.setReadOnly();
+               
+                       ClientMetadata cmd = new 
ClientMetadata(p.getMimeType());
+                       FreenetURI uri = new FreenetURI("KSK", p.getFilename());
+                       InsertBlock ib = new InsertBlock(tempB, cmd, uri);

+                       Logger.debug(this, "Started insert puzzle from '" + 
identity.getNickName() + "'");
+
+                       /* FIXME: use nonblocking insert */
+                       mClient.insert(ib, true, p.getFilename());
+
+                       db.store(p);
+                       db.commit();
+               } finally {
+                       tempB.free();
+               }
+
+               Logger.debug(this, "Successful insert of puzzle for '" + 
identity.getNickName() + "'");
+       }
 }


Reply via email to