abuse log improvements
authorzapata <zapata>
Fri, 19 Sep 2003 23:34:14 +0000 (23:34 +0000)
committerzapata <zapata>
Fri, 19 Sep 2003 23:34:14 +0000 (23:34 +0000)
bundles/admin_en.properties
source/default.properties
source/mircoders/entity/EntityContent.java
source/mircoders/global/Abuse.java
source/mircoders/localizer/basic/MirBasicAdminInterfaceLocalizer.java
templates/admin/abuse.log.template
templates/admin/producerqueue.template
web/style/admin.css

index 0a631a4..cdff95a 100755 (executable)
@@ -1,6 +1,6 @@
 ########## admin ##########
 # language: english
-# $Id: admin_en.properties,v 1.48.2.12 2003/09/19 02:54:48 zapata Exp $
+# $Id: admin_en.properties,v 1.48.2.13 2003/09/19 23:34:14 zapata Exp $
 
 languagename=English
 
@@ -447,6 +447,8 @@ abuse.log.time=Time
 abuse.log.address=IP number
 abuse.log.object=Object
 abuse.log.browser=Browser
+abuse.log.filtertype=Filter type
+abuse.log.filterexpression=Expression
 
 abuse.filters = Filters
 abuse.filters.movedown = move down
index 31479e0..6474ab7 100755 (executable)
@@ -386,9 +386,7 @@ Mir.DefaultEncoding=UTF8
 Mir.DefaultHTMLCharset=UTF-8
 
 # Default timezone to display times in in admin, producers
-# 
-# Leave empty to use the system's default
-Mir.DefaultTimezone= 
+Mir.DefaultTimezone= UTC
 
 # Default date/time format
 Mir.DefaultDateTimeFormat = yyyy-MM-dd HH:mm
index 8f5a4ee..3fa7b38 100755 (executable)
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir 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.
- *
- * Mir 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-
-package mircoders.entity;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.Map;
-
-import mir.entity.Entity;
-import mir.entity.EntityList;
-import mir.log.LoggerWrapper;
-import mir.storage.StorageObject;
-import mir.storage.StorageObjectExc;
-import mir.storage.StorageObjectFailure;
-import mircoders.storage.DatabaseContent;
-import mircoders.storage.DatabaseContentToMedia;
-import mircoders.storage.DatabaseContentToTopics;
-
-/**
- * this class implements mapping of one line of the database table content
- * to a java object
- *
- * @version $Id: EntityContent.java,v 1.19.2.2 2003/09/03 17:49:39 zapata Exp $
- * @author mir-coders group
- *
- */
-
-
-public class EntityContent extends Entity
-{
-
-  String mirconf_extLinkName  = configuration.getString("Producer.ExtLinkName");
-  String mirconf_intLinkName  = configuration.getString("Producer.IntLinkName");
-  String mirconf_mailLinkName = configuration.getString("Producer.MailLinkName");
-  String mirconf_imageRoot    = configuration.getString("Producer.ImageRoot");
-
-  //this should always be transient i.e it can never be stored in the db
-  //or ObjectStore. (so the ObjectStore should only be caching what comes
-  //directly out of the DB. @todo confirm this with rk. -mh
-  Map _entCache = new HashMap();
-  Boolean _hasMedia = null;
-
-  // constructors
-
-  public EntityContent()
-  {
-    super();
-
-    logger = new LoggerWrapper("Entity.Content");
-  }
-
-  public EntityContent(StorageObject theStorage) {
-    this();
-
-    setStorage(theStorage);
-  }
-
-  //
-  // methods
-
-  /**
-   * set is_produced flag for the article
-   */
-
-  public void setProduced(boolean yesno) throws StorageObjectFailure
-  {
-    String value = (yesno) ? "1":"0";
-    if (value.equals( getValue("is_produced") )) return;
-
-    Connection con=null;Statement stmt=null;
-    String sql = "update content set is_produced='" + value + "' where id='" + getId()+"'";
-    try {
-      con = theStorageObject.getPooledCon();
-      /** @todo should be preparedStatement: faster!! */
-      stmt = con.createStatement();
-      theStorageObject.executeUpdate(stmt,sql);
-    }
-    catch (StorageObjectFailure e) {
-      throwStorageObjectFailure(e, "\n -- set produced failed");
-    }
-    catch (SQLException e) {
-      throwStorageObjectFailure(e, "\n -- set produced failed");
-    }
-    finally {
-      theStorageObject.freeConnection(con,stmt);
-    }
-  }
-
-  /**
-   * Deattaches media from an article
-   *
-   * @param anArticleId
-   * @param aMediaId
-   * @throws StorageObjectFailure
-   */
-  public void dettach(String anArticleId, String aMediaId) throws StorageObjectFailure
-  {
-    if (aMediaId!=null){
-      try{
-        DatabaseContentToMedia.getInstance().delete(anArticleId, aMediaId);
-      }
-      catch (Exception e){
-        throwStorageObjectFailure(e, "\n -- failed to get instance");
-      }
-
-      setProduced(false);
-    }
-  }
-
-  /**
-   * Attaches media to an article
-   *
-   * @param mid
-   * @throws StorageObjectFailure
-   */
-
-  public void attach(String aMediaId) throws StorageObjectFailure
-  {
-    if (aMediaId!=null) {
-      try{
-        DatabaseContentToMedia.getInstance().addMedia(getId(),aMediaId);
-      }
-      catch(StorageObjectFailure e){
-        throwStorageObjectFailure(e, "attach: could not get the instance");
-      }
-      setProduced(false);
-    }
-    else {
-      logger.error("EntityContent: attach without mid");
-    }
-  }
-
-  /**
-   * overridden method setValues to patch creator_main_url
-   */
-  public void setValues(Map theStringValues) {
-    if (theStringValues != null) {
-      if (theStringValues.containsKey("creator_main_url")){
-        if (((String)theStringValues.get("creator_main_url")).equalsIgnoreCase("http://")){
-          theStringValues.remove("creator_main_url");
-        }
-        else if (!((String)theStringValues.get("creator_main_url")).startsWith("http://")){
-          theStringValues.put("creator_main_url","http://"+((String)theStringValues.get("creator_main_url")));
-        }
-      }
-    }
-    super.setValues(theStringValues);
-  }
-
-  private boolean hasMedia() throws StorageObjectFailure
-  {
-    if (_hasMedia == null) {
-      try {
-        _hasMedia =
-            new Boolean(DatabaseContentToMedia.getInstance().hasMedia(this));
-      } catch (StorageObjectExc e) {
-        throw new StorageObjectFailure(e);
-      }
-    }
-    return _hasMedia.booleanValue();
-  }
-}
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+\r
+package mircoders.entity;\r
+\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.util.Map;\r
+\r
+import mir.entity.Entity;\r
+import mir.log.LoggerWrapper;\r
+import mir.storage.StorageObject;\r
+import mir.storage.StorageObjectFailure;\r
+import mir.util.StringRoutines;\r
+import mircoders.storage.DatabaseContentToMedia;\r
+\r
+/**\r
+ * this class implements mapping of one line of the database table content\r
+ * to a java object\r
+ *\r
+ * @version $Id: EntityContent.java,v 1.19.2.3 2003/09/19 23:34:20 zapata Exp $\r
+ * @author mir-coders group\r
+ *\r
+ */\r
+\r
+\r
+public class EntityContent extends Entity\r
+{\r
+  // constructors\r
+\r
+  public EntityContent()\r
+  {\r
+    super();\r
+\r
+    logger = new LoggerWrapper("Entity.Content");\r
+  }\r
+\r
+  public EntityContent(StorageObject theStorage) {\r
+    this();\r
+\r
+    setStorage(theStorage);\r
+  }\r
+\r
+  //\r
+  // methods\r
+\r
+  /**\r
+   * set is_produced flag for the article\r
+   */\r
+\r
+  public void setProduced(boolean yesno) throws StorageObjectFailure\r
+  {\r
+    String value = (yesno) ? "1":"0";\r
+    if (value.equals( getValue("is_produced") )) return;\r
+\r
+    Connection con=null;Statement stmt=null;\r
+    String sql = "update content set is_produced='" + value + "' where id='" + getId()+"'";\r
+    try {\r
+      con = theStorageObject.getPooledCon();\r
+      /** @todo should be preparedStatement: faster!! */\r
+      stmt = con.createStatement();\r
+      theStorageObject.executeUpdate(stmt,sql);\r
+    }\r
+    catch (StorageObjectFailure e) {\r
+      throwStorageObjectFailure(e, "\n -- set produced failed");\r
+    }\r
+    catch (SQLException e) {\r
+      throwStorageObjectFailure(e, "\n -- set produced failed");\r
+    }\r
+    finally {\r
+      theStorageObject.freeConnection(con,stmt);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Deattaches media from an article\r
+   *\r
+   * @param anArticleId\r
+   * @param aMediaId\r
+   * @throws StorageObjectFailure\r
+   */\r
+  public void dettach(String anArticleId, String aMediaId) throws StorageObjectFailure\r
+  {\r
+    if (aMediaId!=null){\r
+      try{\r
+        DatabaseContentToMedia.getInstance().delete(anArticleId, aMediaId);\r
+      }\r
+      catch (Exception e){\r
+        throwStorageObjectFailure(e, "\n -- failed to get instance");\r
+      }\r
+\r
+      setProduced(false);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Attaches media to an article\r
+   *\r
+   * @param mid\r
+   * @throws StorageObjectFailure\r
+   */\r
+\r
+  public void attach(String aMediaId) throws StorageObjectFailure\r
+  {\r
+    if (aMediaId!=null) {\r
+      try{\r
+        DatabaseContentToMedia.getInstance().addMedia(getId(),aMediaId);\r
+      }\r
+      catch(StorageObjectFailure e){\r
+        throwStorageObjectFailure(e, "attach: could not get the instance");\r
+      }\r
+      setProduced(false);\r
+    }\r
+    else {\r
+      logger.error("EntityContent: attach without mid");\r
+    }\r
+  }\r
+\r
+  /**\r
+   * overridden method setValues to patch creator_main_url\r
+   */\r
+  public void setValues(Map theStringValues) {\r
+    if (theStringValues != null) {\r
+      if (theStringValues.containsKey("creator_main_url")){\r
+        if (((String)theStringValues.get("creator_main_url")).equalsIgnoreCase("http://")){\r
+          theStringValues.remove("creator_main_url");\r
+        }\r
+        else if (!((String)theStringValues.get("creator_main_url")).startsWith("http://")){\r
+          theStringValues.put("creator_main_url","http://"+((String)theStringValues.get("creator_main_url")));\r
+        }\r
+      }\r
+    }\r
+    super.setValues(theStringValues);\r
+  }\r
+\r
+  public void appendToComments(String aLine) {\r
+    StringBuffer comment = new StringBuffer();\r
+    try {\r
+      comment.append(StringRoutines.interpretAsString(getValue("comment")));\r
+    }\r
+    catch (Throwable t) {\r
+    }\r
+    if (comment.length() > 0 && comment.charAt(comment.length() - 1) != '\n') {\r
+      comment.append('\n');\r
+    }\r
+\r
+    comment.append(aLine);\r
+    setValueForProperty("comment", comment.toString());\r
+  }\r
+\r
+\r
+\r
+}\r
index aed4347..c5cee47 100755 (executable)
@@ -50,11 +50,11 @@ import mir.config.MirPropertiesConfiguration;
 import mir.entity.Entity;\r
 import mir.log.LoggerWrapper;\r
 import mir.session.Request;\r
+import mir.util.DateTimeFunctions;\r
 import mir.util.GeneratorFormatAdapters;\r
 import mir.util.StringRoutines;\r
 import mircoders.entity.EntityComment;\r
 import mircoders.entity.EntityContent;\r
-import mircoders.entity.EntityUsers;\r
 import mircoders.localizer.MirAdminInterfaceLocalizer;\r
 import mircoders.localizer.MirAntiAbuseFilterType;\r
 \r
@@ -162,8 +162,6 @@ public class Abuse {
   }\r
 \r
   public void checkComment(EntityComment aComment, Request aRequest, HttpServletResponse aResponse) {\r
-    logComment(aComment, aRequest);\r
-\r
     try {\r
       long time = System.currentTimeMillis();\r
 \r
@@ -175,7 +173,11 @@ public class Abuse {
         MirGlobal.performCommentOperation(null, aComment, filterRule.getCommentAction());\r
         setCookie(aResponse);\r
         save();\r
+        logComment(aComment, aRequest, filterRule.getType(), filterRule.getExpression());\r
       }\r
+      else\r
+        logComment(aComment, aRequest);\r
+\r
 \r
       logger.info("checkComment: " + (System.currentTimeMillis() - time) + "ms");\r
     }\r
@@ -186,8 +188,6 @@ public class Abuse {
   }\r
 \r
   public void checkArticle(EntityContent anArticle, Request aRequest, HttpServletResponse aResponse) {\r
-    logArticle(anArticle, aRequest);\r
-\r
     try {\r
       long time = System.currentTimeMillis();\r
 \r
@@ -196,10 +196,27 @@ public class Abuse {
       if (filterRule != null) {\r
         logger.debug("Match for " + filterRule.getType() + " rule '" + filterRule.getExpression() + "'");\r
         filterRule.setLastHit(new GregorianCalendar().getTime());\r
+\r
+        StringBuffer line = new StringBuffer();\r
+\r
+        line.append(DateTimeFunctions.advancedDateFormat(\r
+            configuration.getString("Mir.DefaultDateTimeFormat"),\r
+            (new GregorianCalendar()).getTime(), configuration.getString("Mir.DefaultTimezone")));\r
+\r
+        line.append(" ");\r
+        line.append("filter");\r
+\r
+        line.append(" ");\r
+        line.append(filterRule.getType() +" ("+ filterRule.getExpression()+")");\r
+        anArticle.appendToComments(line.toString());\r
+\r
         MirGlobal.performArticleOperation(null, anArticle, filterRule.getArticleAction());\r
         setCookie(aResponse);\r
         save();\r
+        logArticle(anArticle, aRequest, filterRule.getType(), filterRule.getExpression());\r
       }\r
+      else\r
+        logArticle(anArticle, aRequest);\r
 \r
       logger.info("checkArticle: " + (System.currentTimeMillis() - time) + "ms");\r
     }\r
@@ -286,6 +303,8 @@ public class Abuse {
           else\r
             entry.put("type", "comment");\r
           entry.put("browser", logEntry.getBrowserString());\r
+          entry.put("hitfiltertype", logEntry.getHitFilterType());\r
+          entry.put("hitfilterexpression", logEntry.getHitFilterExpression());\r
 \r
           result.add(entry);\r
         }\r
@@ -299,27 +318,35 @@ public class Abuse {
   }\r
 \r
   public void logComment(Entity aComment, Request aRequest) {\r
+    logComment(aComment, aRequest, null, null);\r
+  }\r
+\r
+  public void logComment(Entity aComment, Request aRequest, String aHitFilterType, String aHitFilterExpression) {\r
     String ipAddress = aRequest.getHeader("ip");\r
     String id = aComment.getId();\r
     String browser = aRequest.getHeader("User-Agent");\r
 \r
-    logComment(ipAddress, id, new Date(), browser);\r
+    logComment(ipAddress, id, new Date(), browser, aHitFilterType, aHitFilterExpression);\r
   }\r
 \r
   public void logArticle(Entity anArticle, Request aRequest) {\r
+    logArticle(anArticle, aRequest, null, null);\r
+  }\r
+\r
+  public void logArticle(Entity anArticle, Request aRequest, String aHitFilterType, String aHitFilterExpression) {\r
     String ipAddress = aRequest.getHeader("ip");\r
     String id = anArticle.getId();\r
     String browser = aRequest.getHeader("User-Agent");\r
 \r
-    logArticle(ipAddress, id, new Date(), browser);\r
+    logArticle(ipAddress, id, new Date(), browser, aHitFilterType, aHitFilterExpression);\r
   }\r
 \r
-  public void logComment(String anIp, String anId, Date aTimeStamp, String aBrowser) {\r
-    appendLog(new LogEntry(aTimeStamp, anIp, aBrowser, anId, false));\r
+  public void logComment(String anIp, String anId, Date aTimeStamp, String aBrowser, String aHitFilterType, String aHitFilterExpression) {\r
+    appendLog(new LogEntry(aTimeStamp, anIp, aBrowser, anId, false, aHitFilterType, aHitFilterExpression));\r
   }\r
 \r
-  public void logArticle(String anIp, String anId, Date aTimeStamp, String aBrowser) {\r
-    appendLog(new LogEntry(aTimeStamp, anIp, aBrowser, anId, true));\r
+  public void logArticle(String anIp, String anId, Date aTimeStamp, String aBrowser, String aHitFilterType, String aHitFilterExpression) {\r
+    appendLog(new LogEntry(aTimeStamp, anIp, aBrowser, anId, true, aHitFilterType, aHitFilterExpression));\r
   }\r
 \r
   public void load() {\r
@@ -690,16 +717,14 @@ public class Abuse {
 \r
   private String escapeFilterPart(String aFilterPart) {\r
     return StringRoutines.replaceStringCharacters(aFilterPart,\r
-                                                  new char[] {'\\', ':', '\n', '\r', '\t', ' '}\r
-                                                  ,\r
-                                                  new String[] {"\\\\", "\\:", "\\n", "\\r", "\\t", "\\ "});\r
+        new char[] {'\\', ':', '\n', '\r', '\t', ' '},\r
+        new String[] {"\\\\", "\\:", "\\n", "\\r", "\\t", "\\ "});\r
   }\r
 \r
   private String deescapeFilterPart(String aFilterPart) {\r
     return StringRoutines.replaceEscapedStringCharacters(aFilterPart,\r
         '\\',\r
-        new char[] {'\\', ':', 'n', 'r', 't', ' '}\r
-        ,\r
+        new char[] {'\\', ':', 'n', 'r', 't', ' '},\r
         new String[] {"\\", ":", "\n", "\r", "\t", " "});\r
   }\r
 \r
@@ -774,13 +799,21 @@ public class Abuse {
     private String id;\r
     private Date timeStamp;\r
     private boolean isArticle;\r
+    private String hitFilterType;\r
+    private String hitFilterExpression;\r
 \r
-    public LogEntry(Date aTimeStamp, String anIpNumber, String aBrowserString, String anId, boolean anIsArticle) {\r
+    public LogEntry(Date aTimeStamp, String anIpNumber, String aBrowserString, String anId, boolean anIsArticle, String aHitFilterType, String aHitFilterExpression) {\r
       ipNumber = anIpNumber;\r
       browserString = aBrowserString;\r
       id = anId;\r
       isArticle = anIsArticle;\r
       timeStamp = aTimeStamp;\r
+      hitFilterType = aHitFilterType;\r
+      hitFilterExpression = aHitFilterExpression;\r
+    }\r
+\r
+    public LogEntry(Date aTimeStamp, String anIpNumber, String aBrowserString, String anId, boolean anIsArticle) {\r
+      this(aTimeStamp, anIpNumber, aBrowserString, anId, anIsArticle, null, null);\r
     }\r
 \r
     public String getIpNumber() {\r
@@ -795,6 +828,14 @@ public class Abuse {
       return id;\r
     }\r
 \r
+    public String getHitFilterType() {\r
+      return hitFilterType;\r
+    }\r
+\r
+    public String getHitFilterExpression() {\r
+      return hitFilterExpression;\r
+    }\r
+\r
     public Date getTimeStamp() {\r
       return timeStamp;\r
     }\r
index 4ed7d6a..bb606a8 100755 (executable)
 
 package mircoders.localizer.basic;
 
-import java.text.SimpleDateFormat;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.*;
-import java.util.Vector;
-
-import mir.entity.Entity;
-import mir.entity.adapter.EntityAdapter;
-import mir.misc.StringUtil;
-import mir.storage.StorageObjectFailure;
-import mir.util.StringRoutines;
-import mircoders.entity.EntityComment;
-import mircoders.entity.EntityContent;
-import mircoders.localizer.MirAdminInterfaceLocalizer;
-import mircoders.localizer.MirLocalizerExc;
-import mircoders.localizer.MirLocalizerFailure;
+import java.util.Arrays;\r
+import java.util.GregorianCalendar;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Vector;\r
+\r
+import mir.entity.Entity;\r
+import mir.entity.adapter.EntityAdapter;\r
+import mir.misc.StringUtil;\r
+import mir.storage.StorageObjectFailure;\r
+import mir.util.DateTimeFunctions;\r
+import mircoders.entity.EntityComment;\r
+import mircoders.entity.EntityContent;\r
+import mircoders.global.MirGlobal;\r
+import mircoders.localizer.MirAdminInterfaceLocalizer;\r
+import mircoders.localizer.MirAdminInterfaceLocalizer.MirSimpleEntityOperation;\r
+import mircoders.localizer.MirLocalizerExc;\r
+import mircoders.localizer.MirLocalizerFailure;\r
 import mircoders.storage.DatabaseContent;
 
 
@@ -55,7 +60,6 @@ public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocaliz
   private Vector simpleArticleOperations;
   private Map simpleCommentOperationsMap;
   private Map simpleArticleOperationsMap;
-  private static SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy HH:mm");
 
   public MirBasicAdminInterfaceLocalizer() throws MirLocalizerFailure, MirLocalizerExc {
     simpleCommentOperations = new Vector();
@@ -190,25 +194,21 @@ public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocaliz
       anEntity.setValueForProperty("is_produced", "0");
 
       if (logOperation) {
-        StringBuffer comment = new StringBuffer();
-        try {
-          comment.append(StringRoutines.interpretAsString(anEntity.getValue("comment")));
-        }
-        catch (Throwable t) {
-        }
-        if (comment.length()>0 && comment.charAt(comment.length()-1)!='\n') {
-          comment.append('\n');
-        }
-        comment.append(dateFormatter.format((new GregorianCalendar()).getTime()));
-        comment.append(" ");
-        try {
-          comment.append(StringRoutines.interpretAsString(aUser.get("login")));
-        }
-        catch (Throwable t) {
-        }
-        comment.append(" ");
-        comment.append(getName());
-        anEntity.setValueForProperty("comment", comment.toString());
+        StringBuffer line = new StringBuffer();
+
+        line.append(DateTimeFunctions.advancedDateFormat(
+            MirGlobal.config().getString("Mir.DefaultDateTimeFormat"),
+            (new GregorianCalendar()).getTime(),
+            MirGlobal.config().getString("Mir.DefaultTimezone")));
+        line.append(" ");
+        if (aUser!=null)
+          line.append(aUser.get("login"));
+        else
+          line.append("unknown");
+
+        line.append(" ");
+        line.append(getName());
+        ((EntityContent) anEntity).appendToComments(line.toString());
       }
     };
 
index 73882a5..ec52057 100755 (executable)
@@ -18,6 +18,8 @@
         <td class="table-head">${lang("abuse.log.address")}</td>
         <td class="table-head">${lang("abuse.log.object")}</td>
         <td class="table-head">${lang("abuse.log.browser")}</td>
+        <td class="table-head">${lang("abuse.log.filtertype")}</td>
+        <td class="table-head">${lang("abuse.log.filterexpression")}</td>
       </tr>
       
       <assign grey="0">      
             </if>
           </td>
           <td>${l.browser}</td>
+          <td><if l.hitfiltertype>${lang("abuse.filtertype."+l.hitfiltertype)}</if></td>
+          <td>${utility.encodeHTML(l.hitfilterexpression)}</td>
         </tr>
       </list>
     <tr>
-      <td colspan="4" class="table-foot">&nbsp;</td>
+      <td colspan="6" class="table-foot">&nbsp;</td>
     </tr>
     </table>
 
index 8e21fdc..9466eec 100755 (executable)
     <list p.verbs as v>
     <tr <if grey=="1">class="listrow2"<else>class="listrow2"</if>>
       <td width="25"></td>
-      <if v.name=="all">
-        <td class="small text-alert">${v.name} [!]</td>
-      <else>
-        <td class="small">${v.name}</td>
-      </if>
-      <td class="small">${v.description}</td>
-      <td class="small"><form method="post" action="${config.actionRoot}?module=Producer&do=enqueue&producer=${utility.encodeURI(p.name)}&verb=${utility.encodeURI(v.name)}"><input class="listbutton" type="submit" value="${lang("producer.verb.enqueue")}"></form></td>
-    </tr>
+      <td class="small">${v.name}</td>
+      <td class="small">${v.description}</td><td class="small"> <form method="post" action="${config.actionRoot}?module=Producer&do=enqueue&producer=${utility.encodeURI(p.name)}&verb=${utility.encodeURI(v.name)}"><input class="listbutton" type="submit" value="${lang("producer.verb.enqueue")}"> </form> </td></tr>
     <if grey=="1"><assign grey="0"><else><assign grey="1"></if>
     </list>
     
index e42fa0a..2d24349 100755 (executable)
@@ -204,8 +204,10 @@ a:hover            {
        color: #990000;
        font-size:0.9em;
        margin: 0px;
-       padding:1px;
+       padding:0px;
+/*     
        padding-left:2px;
        padding-right:2px;
+*/     
 }