Skip to content

Commit

Permalink
egit-github => jcabi-github; fixes #98
Browse files Browse the repository at this point in the history
  • Loading branch information
cvrebert committed May 16, 2015
1 parent f5c8ea3 commit 647e9de
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 23 deletions.
5 changes: 1 addition & 4 deletions build.sbt
Expand Up @@ -19,10 +19,7 @@ libraryDependencies += "nu.validator" % "validator" % "15.4.12" excludeAll(
ExclusionRule(organization = "commons-httpclient")
)

libraryDependencies += "org.eclipse.mylyn.github" % "org.eclipse.egit.github.core" % "4.0.0.201503231230-m1"

// egit-github needs Gson, but doesn't explicitly require it
libraryDependencies += "com.google.code.gson" % "gson" % "2.3.1"
libraryDependencies += "com.jcabi" % "jcabi-github" % "0.23"

libraryDependencies += "com.twitter" % "twitter-text" % "1.11.1"

Expand Down
@@ -0,0 +1,9 @@
package com.chrisrebert.lmvtfy.github

import com.jcabi.github.{Github, RtGithub}
import com.chrisrebert.lmvtfy.http.{UserAgent, SuperWire}

case class Credentials(username: String, password: String) {
private def basicGithub: Github = new RtGithub(username, password)
def github(threshold: Int)(implicit userAgent: UserAgent): Github = new RtGithub(basicGithub.entry.through(classOf[SuperWire], userAgent, new Integer(threshold)))
}
@@ -1,24 +1,20 @@
package com.chrisrebert.lmvtfy.github

import scala.util.{Try,Failure,Success}
import org.eclipse.egit.github.core.client.GitHubClient
import org.eclipse.egit.github.core.service.IssueService
import org.eclipse.egit.github.core.RepositoryId
import com.jcabi.github.Coordinates.{Simple=>RepoId}
import com.chrisrebert.lmvtfy.{MarkdownAboutHtml, MarkdownAboutBootstrap, Markdown, ValidationResult}
import com.chrisrebert.lmvtfy.live_examples.{LiveExampleMention, LiveExample}
import com.chrisrebert.lmvtfy.github.implicits._
import com.chrisrebert.lmvtfy.server.{ActorWithLogging, Settings}


class GitHubIssueCommenter extends ActorWithLogging {
val settings = Settings(context.system)

private val client = new GitHubClient()
client.setUserAgent(settings.UserAgent)
client.setCredentials(settings.BotUsername, settings.BotPassword)
private val client = settings.github()

private def tryToCommentOn(repo: RepositoryId, issue: IssueNumber, commentMarkdown: String) = {
val issueService = new IssueService(client)
Try { issueService.createComment(repo, issue.number, commentMarkdown) }
private def tryToCommentOn(repo: RepoId, issue: IssueNumber, commentMarkdown: String) = {
Try { client.repos.get(repo).issues.get(issue.number).comments.post(commentMarkdown) }
}

private def introFor(markdown: Markdown): String = {
Expand All @@ -45,7 +41,7 @@ class GitHubIssueCommenter extends ActorWithLogging {
""".stripMargin

tryToCommentOn(repo.id, issue, commentMarkdown) match {
case Success(comment) => log.info(s"Successfully posted comment ${comment.getUrl} for ${mention}")
case Success(comment) => log.info(s"Successfully posted comment ${comment.smart.url} for ${mention}")
case Failure(exc) => log.error(exc, s"Error posting comment for ${mention}")
}
}
Expand Down
@@ -1,12 +1,12 @@
package com.chrisrebert.lmvtfy.github

import spray.json._
import org.eclipse.egit.github.core.RepositoryId
import com.jcabi.github.Coordinates.{Simple=>RepoId}

case class GitHubRepository(val fullName: String) extends AnyVal {
def id: RepositoryId = RepositoryId.createFromId(fullName)
case class GitHubRepository(fullName: String) extends AnyVal {
def id: RepoId = new RepoId(fullName)
}
case class GitHubUser(val username: String) extends AnyVal
case class GitHubUser(username: String) extends AnyVal
case class IssueOrComment(
number: Option[Int], // issue number
body: String,
Expand Down
@@ -0,0 +1,10 @@
package com.chrisrebert.lmvtfy.github

import com.jcabi.github.Comment
import com.jcabi.github.Comment.{Smart=>SmartComment}

package object implicits {
implicit class RichComment(comment: Comment) {
def smart: SmartComment = new SmartComment(comment)
}
}
20 changes: 20 additions & 0 deletions src/main/scala/com/chrisrebert/lmvtfy/http/SuperWire.scala
@@ -0,0 +1,20 @@
package com.chrisrebert.lmvtfy.http

import java.util.{Collection=>JavaCollection}
import java.util.Map.{Entry=>MapEntry}
import java.io.InputStream
import com.jcabi.github.wire.RetryCarefulWire
import com.jcabi.http.{Wire,Request,Response}

case class SuperWire(private val wire: Wire, userAgent: UserAgent, threshold: Int) extends Wire {
private val wrappedWire = UserAgentWire(wire = new RetryCarefulWire(wire, threshold), userAgent = userAgent)

@Override
def send(
request: Request,
home: String,
method: String,
headers: JavaCollection[MapEntry[String, String]],
content: InputStream
): Response = wrappedWire.send(request, home, method, headers, content)
}
3 changes: 3 additions & 0 deletions src/main/scala/com/chrisrebert/lmvtfy/http/UserAgent.scala
@@ -0,0 +1,3 @@
package com.chrisrebert.lmvtfy.http

case class UserAgent(userAgent: String)
25 changes: 25 additions & 0 deletions src/main/scala/com/chrisrebert/lmvtfy/http/UserAgentWire.scala
@@ -0,0 +1,25 @@
package com.chrisrebert.lmvtfy.http

import java.util.{Collection=>JavaCollection}
import java.util.Map.{Entry=>MapEntry}
import java.io.InputStream
import scala.collection.JavaConverters._
import com.jcabi.http._

object UserAgentWire {
private val userAgentHeader = "User-Agent"
}
case class UserAgentWire(private val wire: Wire, userAgent: UserAgent) extends Wire {
@Override
def send(
request: Request,
home: String,
method: String,
headers: JavaCollection[MapEntry[String, String]],
content: InputStream
): Response = {
val header = new ImmutableHeader(UserAgentWire.userAgentHeader, userAgent.userAgent)
val newHeaders = header +: headers.asScala.filter{ _.getKey != UserAgentWire.userAgentHeader}.toSeq
wire.send(request, home, method, newHeaders.asJava, content)
}
}
Expand Up @@ -15,7 +15,7 @@ class IssueCommentEventHandler(fetcher: ActorRef) extends ActorWithLogging {

override def receive = {
case event: IssueOrCommentEvent => {
if (settings.RepoFullNames contains event.repository.fullName) {
if (settings.RepoIds contains event.repository.id) {
event.gitHubIssue.map { issue =>
event.message.map { message =>
if (message.user.username == settings.BotUsername) {
Expand Down
Expand Up @@ -29,7 +29,6 @@ class LmvtfyActor(protected val issueCommentEventHandler: ActorRef) extends Acto
event.message match {
case Some(_) => {
issueCommentEventHandler ! event
// FIXME: do throttling
// FIXME: ignore examples already posted in previous comments
complete(StatusCodes.OK)
}
Expand Down
13 changes: 10 additions & 3 deletions src/main/scala/com/chrisrebert/lmvtfy/server/Settings.scala
Expand Up @@ -8,14 +8,21 @@ import akka.actor.ExtensionId
import akka.actor.ExtensionIdProvider
import akka.actor.ExtendedActorSystem
import akka.util.ByteString
import com.jcabi.github.Github
import com.jcabi.github.Coordinates.{Simple=>RepoId}
import com.chrisrebert.lmvtfy.github.Credentials
import com.chrisrebert.lmvtfy.http.{UserAgent=>UA}
import com.chrisrebert.lmvtfy.util.Utf8String

class SettingsImpl(config: Config) extends Extension {
val RepoFullNames: Set[String] = config.getStringList("lmvtfy.github-repos-to-watch").toSet
val RepoIds: Set[RepoId] = config.getStringList("lmvtfy.github-repos-to-watch").toSet[String].map{ new RepoId(_) }
val BotUsername: String = config.getString("lmvtfy.username")
val BotPassword: String = config.getString("lmvtfy.password")
private val botPassword: String = config.getString("lmvtfy.password")
private val botCredentials: Credentials = Credentials(username = BotUsername, password = botPassword)
private val githubRateLimitThreshold: Int = config.getInt("lmvtfy.github-rate-limit-threshold")
def github(): Github = botCredentials.github(githubRateLimitThreshold)(UserAgent)
val WebHookSecretKey: ByteString = ByteString(config.getString("lmvtfy.web-hook-secret-key").utf8Bytes)
val UserAgent: String = config.getString("spray.can.client.user-agent-header")
val UserAgent: UA = UA(config.getString("spray.can.client.user-agent-header"))
val DefaultPort: Int = config.getInt("lmvtfy.default-port")
val SquelchInvalidHttpLogging: Boolean = config.getBoolean("lmvtfy.squelch-invalid-http-logging")
val DebugHtml: Boolean = config.getBoolean("lmvtfy.debug-html")
Expand Down

0 comments on commit 647e9de

Please sign in to comment.