Preparing for more testable 'business' logic - splitting the for cycles and REST queries.
1.1 --- a/emailer/src/main/scala/cz/xelfi/quoridor/emailer/Main.scala Mon Feb 15 23:34:53 2010 +0100
1.2 +++ b/emailer/src/main/scala/cz/xelfi/quoridor/emailer/Main.scala Tue Feb 16 01:22:36 2010 +0100
1.3 @@ -44,30 +44,78 @@
1.4
1.5 val api = new URL(args(0));
1.6
1.7 - val id = login(api, args(1), args(2))
1.8 -
1.9 - val ret = allPlayers(
1.10 - api,
1.11 - 3600 * 1000 * 24
1.12 - )
1.13 + val loginID = login(api, args(1), args(2))
1.14
1.15 + val okDelay = 3600 * 1000 * 24
1.16 val props = java.lang.System.getProperties
1.17 props.put("mail.smtp.host", args(3));
1.18
1.19 val session = javax.mail.Session.getDefaultInstance(props, null)
1.20
1.21 + val notify = new Notify() {
1.22 + protected def allPlayers(): Map[String,List[Node]] = {
1.23 + val u = new URL(api, "games");
1.24 + val conn = u.openConnection
1.25 + conn.setRequestProperty("Accept", "text/xml")
1.26
1.27 - for (val address <- emails(api, id, ret.keySet)) {
1.28 - Console.println("Sending message to " + address)
1.29 + val ret = new HashMap[String,List[Node]]
1.30
1.31 + val before = System.currentTimeMillis - okDelay
1.32 + val games = XML.load(conn.getInputStream)
1.33 + for (val g : Node <- games \\ "gameId") {
1.34 + val modified = (g \\ "@modified").text.toLong
1.35 + if (modified < before) {
1.36 + val status = (g \\ "@status").text;
1.37 + val name =
1.38 + if (status == "blackMove") {
1.39 + (g \\ "@black").text
1.40 + } else if (status == "whiteMove") {
1.41 + (g \\ "@white").text
1.42 + } else {
1.43 + null
1.44 + }
1.45 + if (name != null) {
1.46 + val prev = ret.getOrElse(name, Nil)
1.47 + val next = g :: prev
1.48 + ret.put(name, next);
1.49 + }
1.50 + }
1.51 + }
1.52 + return ret;
1.53 + }
1.54 +
1.55 + protected def emails(ids : Collection[String]): List[String] = {
1.56 + var ret : List[String] = Nil;
1.57 + for (val p <- ids) {
1.58 + val u = new URL(api, "users/" + p + "?loginID=" + loginID)
1.59 + val conn = u.openConnection
1.60 + conn.setRequestProperty("Accept", "text/xml")
1.61 + val xml = XML.load(conn.getInputStream)
1.62 + val res = (xml \\ "property").filter({
1.63 + n => n.attribute("name") match {
1.64 + case Some(attr) => attr.text == "email"
1.65 + case _ => false
1.66 + }
1.67 + })
1.68 + if (!res.isEmpty) {
1.69 + ret = res(0).text :: ret;
1.70 + }
1.71 + }
1.72 + return ret
1.73 + }
1.74 +
1.75 + protected def sendEmail(address : String, subject : String, text : String) : Unit = {
1.76 val message = new MimeMessage(session)
1.77 message.setFrom(new InternetAddress("quoridor@xelfi.cz"))
1.78 message.addRecipient(Message.RecipientType.TO, new InternetAddress(address))
1.79 - message.setSubject("Play Quoridor!")
1.80 - message.setText("Visit http://quoridor.xelfi.cz")
1.81 + message.setSubject(subject)
1.82 + message.setText(text)
1.83
1.84 Transport.send(message)
1.85 + }
1.86 }
1.87 +
1.88 + notify.process()
1.89 }
1.90
1.91 def login(url : URL, name : String, password : String) : String = {
1.92 @@ -79,55 +127,4 @@
1.93 val reply = Source.fromInputStream(conn.getInputStream)
1.94 return reply.mkString("")
1.95 }
1.96 -
1.97 - def allPlayers(url : URL, okDelay : Long): Map[String,List[Node]] = {
1.98 - val u = new URL(url, "games");
1.99 - val conn = u.openConnection
1.100 - conn.setRequestProperty("Accept", "text/xml")
1.101 -
1.102 - val ret = new HashMap[String,List[Node]]
1.103 -
1.104 - val before = System.currentTimeMillis - okDelay
1.105 - val games = XML.load(conn.getInputStream)
1.106 - for (val g : Node <- games \\ "gameId") {
1.107 - val modified = (g \\ "@modified").text.toLong
1.108 - if (modified < before) {
1.109 - val status = (g \\ "@status").text;
1.110 - val name =
1.111 - if (status == "blackMove") {
1.112 - (g \\ "@black").text
1.113 - } else if (status == "whiteMove") {
1.114 - (g \\ "@white").text
1.115 - } else {
1.116 - null
1.117 - }
1.118 - if (name != null) {
1.119 - val prev = ret.getOrElse(name, Nil)
1.120 - val next = g :: prev
1.121 - ret.put(name, next);
1.122 - }
1.123 - }
1.124 - }
1.125 - return ret;
1.126 - }
1.127 -
1.128 - def emails(url : URL, loginID : String, ids : Collection[String]): List[String] = {
1.129 - var ret : List[String] = Nil;
1.130 - for (val p <- ids) {
1.131 - val u = new URL(url, "users/" + p + "?loginID=" + loginID)
1.132 - val conn = u.openConnection
1.133 - conn.setRequestProperty("Accept", "text/xml")
1.134 - val xml = XML.load(conn.getInputStream)
1.135 - val res = (xml \\ "property").filter({
1.136 - n => n.attribute("name") match {
1.137 - case Some(attr) => attr.text == "email"
1.138 - case _ => false
1.139 - }
1.140 - })
1.141 - if (!res.isEmpty) {
1.142 - ret = res(0).text :: ret;
1.143 - }
1.144 - }
1.145 - return ret
1.146 - }
1.147 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/emailer/src/main/scala/cz/xelfi/quoridor/emailer/Notify.scala Tue Feb 16 01:22:36 2010 +0100
2.3 @@ -0,0 +1,56 @@
2.4 +/*
2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2.6 + *
2.7 + * The contents of this file are subject to the terms of either the GNU
2.8 + * General Public License Version 2 only ("GPL") or the Common
2.9 + * Development and Distribution License("CDDL") (collectively, the
2.10 + * "License"). You may not use this file except in compliance with the
2.11 + * License. You can obtain a copy of the License at
2.12 + * http://www.netbeans.org/cddl-gplv2.html
2.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
2.14 + * specific language governing permissions and limitations under the
2.15 + * License. When distributing the software, include this License Header
2.16 + * Notice in each file and include the License file at
2.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
2.18 + * particular file as subject to the "Classpath" exception as provided
2.19 + * by Sun in the GPL Version 2 section of the License file that
2.20 + * accompanied this code. If applicable, add the following below the
2.21 + * License Header, with the fields enclosed by brackets [] replaced by
2.22 + * your own identifying information:
2.23 + * "Portions Copyrighted [year] [name of copyright owner]"
2.24 + *
2.25 + * Contributor(s):
2.26 + *
2.27 + * Portions Copyrighted 2009 Jaroslav Tulach
2.28 + */
2.29 +
2.30 +package cz.xelfi.quoridor.emailer
2.31 +
2.32 +import scala.xml._
2.33 +import java.net.URL
2.34 +import scala.io._
2.35 +import scala.collection.Map
2.36 +import scala.collection.mutable.HashMap
2.37 +import javax.mail.internet._
2.38 +import javax.mail.Message
2.39 +import javax.mail.Transport
2.40 +
2.41 +abstract class Notify {
2.42 + protected def allPlayers(): Map[String,List[Node]]
2.43 + protected def emails(ids : Collection[String]): List[String]
2.44 + protected def sendEmail(address : String, subject : String, text : String) : Unit
2.45 +
2.46 + def process() {
2.47 + val ret = allPlayers()
2.48 +
2.49 + for (val address <- emails(ret.keySet)) {
2.50 + Console.println("Sending message to " + address)
2.51 +
2.52 + sendEmail(
2.53 + "quoridor@xelfi.cz",
2.54 + "Play Quoridor!",
2.55 + "Visit http://quoridor.xelfi.cz"
2.56 + )
2.57 + }
2.58 + }
2.59 +}