Merging the scala-emailer to default branch as things seem to work OK.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 29 Nov 2009 19:36:02 +0100
changeset 1590d90e4cb9175
parent 156 e3d6e326eac1
parent 158 0e8b21fcaeb0
child 160 9e862a62de85
Merging the scala-emailer to default branch as things seem to work OK.
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/emailer/all-zip.xml	Sun Nov 29 19:36:02 2009 +0100
     1.3 @@ -0,0 +1,19 @@
     1.4 +<?xml version="1.0" encoding="UTF-8"?>
     1.5 +<assembly>
     1.6 + <id>all</id>
     1.7 +  <formats>
     1.8 +    <format>zip</format>
     1.9 +  </formats>
    1.10 +  <dependencySets>
    1.11 +    <dependencySet>
    1.12 +        <useProjectArtifact>false</useProjectArtifact>
    1.13 +        <outputDirectory>lib</outputDirectory>
    1.14 +    </dependencySet>
    1.15 +  </dependencySets>
    1.16 +  <files>
    1.17 +    <file>
    1.18 +      <source>target/emailer-${version}.jar</source>
    1.19 +      <outputDirectory>/</outputDirectory>
    1.20 +    </file>
    1.21 +  </files>
    1.22 +</assembly>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/emailer/pom.xml	Sun Nov 29 19:36:02 2009 +0100
     2.3 @@ -0,0 +1,128 @@
     2.4 +<?xml version="1.0" encoding="UTF-8"?>
     2.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
     2.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     2.7 +  <modelVersion>4.0.0</modelVersion>
     2.8 +  <parent>
     2.9 +    <artifactId>all-quoridor</artifactId>
    2.10 +    <groupId>org.apidesign</groupId>
    2.11 +    <version>1.0</version>
    2.12 +  </parent>
    2.13 +  <groupId>org.apidesign</groupId>
    2.14 +  <artifactId>emailer</artifactId>
    2.15 +  <version>1.0</version>
    2.16 +  <inceptionYear>2008</inceptionYear>
    2.17 +  <build>
    2.18 +    <sourceDirectory>src/main/scala</sourceDirectory>
    2.19 +    <testSourceDirectory>src/test/scala</testSourceDirectory>
    2.20 +    <plugins>
    2.21 +      <plugin>
    2.22 +        <groupId>org.scala-tools</groupId>
    2.23 +        <artifactId>maven-scala-plugin</artifactId>
    2.24 +        <executions>
    2.25 +          <execution>
    2.26 +            <goals>
    2.27 +              <goal>compile</goal>
    2.28 +              <goal>testCompile</goal>
    2.29 +            </goals>
    2.30 +          </execution>
    2.31 +        </executions>
    2.32 +        <configuration>
    2.33 +          <scalaVersion>${scala.version}</scalaVersion>
    2.34 +          <args>
    2.35 +            <arg>-target:jvm-1.5</arg>
    2.36 +          </args>
    2.37 +        </configuration>
    2.38 +      </plugin>
    2.39 +      <plugin>
    2.40 +          <artifactId>maven-assembly-plugin</artifactId>
    2.41 +          <version>2.2-beta-2</version>
    2.42 +          <executions>
    2.43 +              <execution>
    2.44 +                  <id>create-executable-jar</id>
    2.45 +                  <phase>package</phase>
    2.46 +                  <goals>
    2.47 +                      <goal>single</goal>
    2.48 +                  </goals>
    2.49 +                  <configuration>
    2.50 +                      <descriptors>
    2.51 +                          <descriptor>all-zip.xml</descriptor>
    2.52 +                      </descriptors>
    2.53 +                      <finalName>emailer-${version}</finalName>
    2.54 +                  </configuration>
    2.55 +              </execution>
    2.56 +          </executions>
    2.57 +      </plugin>
    2.58 +      <plugin>
    2.59 +          <groupId>org.apache.maven.plugins</groupId>
    2.60 +          <artifactId>maven-jar-plugin</artifactId>
    2.61 +          <configuration>
    2.62 +              <archive>
    2.63 +                  <manifest>
    2.64 +                      <addClasspath>true</addClasspath>
    2.65 +                      <classpathPrefix>lib/</classpathPrefix>
    2.66 +                      <mainClass>cz.xelfi.quoridor.emailer.Main</mainClass>
    2.67 +                  </manifest>
    2.68 +              </archive>
    2.69 +          </configuration>
    2.70 +      </plugin>
    2.71 +  </plugins>
    2.72 +  </build>
    2.73 +  <repositories>
    2.74 +    <repository>
    2.75 +      <id>scala-tools.org</id>
    2.76 +      <name>Scala-Tools Maven2 Repository</name>
    2.77 +      <url>http://scala-tools.org/repo-releases</url>
    2.78 +    </repository>
    2.79 +  </repositories>
    2.80 +  <pluginRepositories>
    2.81 +    <pluginRepository>
    2.82 +      <id>scala-tools.org</id>
    2.83 +      <name>Scala-Tools Maven2 Repository</name>
    2.84 +      <url>http://scala-tools.org/repo-releases</url>
    2.85 +    </pluginRepository>
    2.86 +  </pluginRepositories>
    2.87 +  <dependencies>
    2.88 +    <dependency>
    2.89 +      <groupId>org.scala-lang</groupId>
    2.90 +      <artifactId>scala-library</artifactId>
    2.91 +      <version>${scala.version}</version>
    2.92 +    </dependency>
    2.93 +    <dependency>
    2.94 +      <groupId>junit</groupId>
    2.95 +      <artifactId>junit</artifactId>
    2.96 +      <version>4.4</version>
    2.97 +      <scope>test</scope>
    2.98 +    </dependency>
    2.99 +    <dependency>
   2.100 +      <groupId>org.specs</groupId>
   2.101 +      <artifactId>specs</artifactId>
   2.102 +      <version>1.2.5</version>
   2.103 +      <scope>test</scope>
   2.104 +    </dependency>
   2.105 +    <dependency>
   2.106 +      <groupId>javax.mail</groupId>
   2.107 +      <artifactId>mail</artifactId>
   2.108 +      <version>1.4.1</version>
   2.109 +    </dependency>
   2.110 +  </dependencies>
   2.111 +  <reporting>
   2.112 +    <plugins>
   2.113 +      <plugin>
   2.114 +        <groupId>org.scala-tools</groupId>
   2.115 +        <artifactId>maven-scala-plugin</artifactId>
   2.116 +        <configuration>
   2.117 +          <scalaVersion>${scala.version}</scalaVersion>
   2.118 +        </configuration>
   2.119 +      </plugin>
   2.120 +    </plugins>
   2.121 +  </reporting>
   2.122 +  <properties>
   2.123 +    <scala.version>2.7.0</scala.version>
   2.124 +  </properties>
   2.125 +    <name>Emails lazy players</name>
   2.126 +    <packaging>jar</packaging>
   2.127 +    <description>Obtains list of players without any activity for a while and sends them an email.</description>
   2.128 +</project>
   2.129 +
   2.130 +
   2.131 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/emailer/src/main/scala/cz/xelfi/quoridor/emailer/Main.scala	Sun Nov 29 19:36:02 2009 +0100
     3.3 @@ -0,0 +1,133 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * The contents of this file are subject to the terms of either the GNU
     3.8 + * General Public License Version 2 only ("GPL") or the Common
     3.9 + * Development and Distribution License("CDDL") (collectively, the
    3.10 + * "License"). You may not use this file except in compliance with the
    3.11 + * License. You can obtain a copy of the License at
    3.12 + * http://www.netbeans.org/cddl-gplv2.html
    3.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.14 + * specific language governing permissions and limitations under the
    3.15 + * License.  When distributing the software, include this License Header
    3.16 + * Notice in each file and include the License file at
    3.17 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    3.18 + * particular file as subject to the "Classpath" exception as provided
    3.19 + * by Sun in the GPL Version 2 section of the License file that
    3.20 + * accompanied this code. If applicable, add the following below the
    3.21 + * License Header, with the fields enclosed by brackets [] replaced by
    3.22 + * your own identifying information:
    3.23 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.24 + *
    3.25 + * Contributor(s):
    3.26 + *
    3.27 + * Portions Copyrighted 2009 Jaroslav Tulach
    3.28 + */
    3.29 +
    3.30 +package cz.xelfi.quoridor.emailer
    3.31 +
    3.32 +import scala.xml._
    3.33 +import java.net.URL
    3.34 +import scala.io._
    3.35 +import scala.collection.Map
    3.36 +import scala.collection.mutable.HashMap
    3.37 +import javax.mail.internet._
    3.38 +import javax.mail.Message
    3.39 +import javax.mail.Transport
    3.40 +
    3.41 +object Main {
    3.42 +  def main(args: Array[String]) {
    3.43 +    if (args == null || args.size != 4) {
    3.44 +      Console.println("Usage: emailer.jar <quoridor API URL> <login name> <password> <smtp server IP>")
    3.45 +      return
    3.46 +    }
    3.47 +
    3.48 +    val api = new URL(args(0));
    3.49 +
    3.50 +    val id = login(api, args(1), args(2))
    3.51 +    
    3.52 +    val ret = allPlayers(
    3.53 +      api,
    3.54 +      3600 * 1000 * 24
    3.55 +    )
    3.56 +
    3.57 +    val props = java.lang.System.getProperties
    3.58 +    props.put("mail.smtp.host", args(3));
    3.59 +
    3.60 +    val session = javax.mail.Session.getDefaultInstance(props, null)
    3.61 +
    3.62 +
    3.63 +    for (val address <- emails(api, id, ret.keySet)) {
    3.64 +        Console.println("Sending message to " + address)
    3.65 +
    3.66 +        val message = new MimeMessage(session)
    3.67 +        message.setFrom(new InternetAddress("quoridor@xelfi.cz"))
    3.68 +        message.addRecipient(Message.RecipientType.TO, new InternetAddress(address))
    3.69 +        message.setSubject("Play Quoridor!")
    3.70 +        message.setText("Visit http://quoridor.xelfi.cz")
    3.71 +
    3.72 +        Transport.send(message)
    3.73 +    }
    3.74 +  }
    3.75 +
    3.76 +  def login(url : URL, name : String, password : String) : String = {
    3.77 +    val u = new URL(url, "login?name=" + name + "&password=" + password);
    3.78 +    val conn = u.openConnection.asInstanceOf[java.net.HttpURLConnection]
    3.79 +    conn.setRequestMethod("PUT")
    3.80 +    conn.setDoInput(true)
    3.81 +    conn.connect
    3.82 +    val reply = Source.fromInputStream(conn.getInputStream)
    3.83 +    return reply.mkString("")
    3.84 +  }
    3.85 +
    3.86 +  def allPlayers(url : URL, okDelay : Long): Map[String,List[Node]] = {
    3.87 +    val u = new URL(url, "games");
    3.88 +    val conn = u.openConnection
    3.89 +    conn.setRequestProperty("Accept", "text/xml")
    3.90 +
    3.91 +    val ret = new HashMap[String,List[Node]]
    3.92 +
    3.93 +    val before = System.currentTimeMillis - okDelay
    3.94 +    val games = XML.load(conn.getInputStream)
    3.95 +    for (val g : Node <- games \\ "gameId") {
    3.96 +      val modified = (g \\ "@modified").text.toLong
    3.97 +      if (modified < before) {
    3.98 +        val status = (g \\ "@status").text;
    3.99 +        val name =
   3.100 +          if (status == "blackMove") {
   3.101 +            (g \\ "@black").text
   3.102 +          } else if (status == "whiteMove") {
   3.103 +            (g \\ "@white").text
   3.104 +          } else {
   3.105 +            null
   3.106 +          }
   3.107 +        if (name != null) {
   3.108 +          val prev = ret.getOrElse(name, Nil)
   3.109 +          val next = g :: prev
   3.110 +          ret.put(name, next);
   3.111 +        }
   3.112 +      }
   3.113 +    }
   3.114 +    return ret;
   3.115 +  }
   3.116 +
   3.117 +  def emails(url : URL, loginID : String, ids : Collection[String]): List[String] = {
   3.118 +    var ret : List[String] = Nil;
   3.119 +    for (val p <- ids) {
   3.120 +      val u = new URL(url, "users/" + p + "?loginID=" + loginID)
   3.121 +      val conn = u.openConnection
   3.122 +      conn.setRequestProperty("Accept", "text/xml")
   3.123 +      val xml = XML.load(conn.getInputStream)
   3.124 +      val res = (xml \\ "property").filter({
   3.125 +          n => n.attribute("name") match {
   3.126 +            case Some(attr) => attr.text == "email"
   3.127 +            case _ => false
   3.128 +          }
   3.129 +      })
   3.130 +      if (!res.isEmpty) {
   3.131 +        ret = res(0).text :: ret;
   3.132 +      }
   3.133 +    }
   3.134 +    return ret
   3.135 +  }
   3.136 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/emailer/src/test/scala/cz/xelfi/quoridor/emailer/MainTest.scala	Sun Nov 29 19:36:02 2009 +0100
     4.3 @@ -0,0 +1,41 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * The contents of this file are subject to the terms of either the GNU
     4.8 + * General Public License Version 2 only ("GPL") or the Common
     4.9 + * Development and Distribution License("CDDL") (collectively, the
    4.10 + * "License"). You may not use this file except in compliance with the
    4.11 + * License. You can obtain a copy of the License at
    4.12 + * http://www.netbeans.org/cddl-gplv2.html
    4.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.14 + * specific language governing permissions and limitations under the
    4.15 + * License.  When distributing the software, include this License Header
    4.16 + * Notice in each file and include the License file at
    4.17 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    4.18 + * particular file as subject to the "Classpath" exception as provided
    4.19 + * by Sun in the GPL Version 2 section of the License file that
    4.20 + * accompanied this code. If applicable, add the following below the
    4.21 + * License Header, with the fields enclosed by brackets [] replaced by
    4.22 + * your own identifying information:
    4.23 + * "Portions Copyrighted [year] [name of copyright owner]"
    4.24 + *
    4.25 + * Contributor(s):
    4.26 + *
    4.27 + * Portions Copyrighted 2009 Jaroslav Tulach
    4.28 + */
    4.29 +
    4.30 +package cz.xelfi.quoridor.emailer
    4.31 +
    4.32 +import org.junit._
    4.33 +import Assert._
    4.34 +
    4.35 +@Test
    4.36 +class MainTest {
    4.37 +
    4.38 +    @Test
    4.39 +    def testCheckLazyPlayers() = {
    4.40 +      Main.main(null)
    4.41 +    }
    4.42 +}
    4.43 +
    4.44 +
     5.1 --- a/pom.xml	Sun Nov 29 09:12:55 2009 +0100
     5.2 +++ b/pom.xml	Sun Nov 29 19:36:02 2009 +0100
     5.3 @@ -38,6 +38,7 @@
     5.4      <module>visidor</module>
     5.5      <module>webidor</module>
     5.6      <module>freemarkerdor</module>
     5.7 +    <module>emailer</module>
     5.8    </modules>
     5.9      <name>Quoridor related projects</name>
    5.10      <description>Master project that agregates all quoridor related functionality.