PageRenderTime 43ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/src/main/scala/g8.scala

http://github.com/softprops/ls-server
Scala | 143 lines | 126 code | 16 blank | 1 comment | 1 complexity | 42494a63c9ac35a2ea5f3bf2c3540bf6 MD5 | raw file
  1. package ls
  2. object G8Conversions extends Logged {
  3. import com.mongodb.casbah.commons.Imports.ObjectId
  4. import com.mongodb.casbah.commons.{MongoDBObject => Obj, MongoDBList => ObjList}
  5. import com.mongodb.casbah.{MongoCollection, MongoCursor}
  6. import com.mongodb.{BasicDBList, DBObject}
  7. import com.mongodb.casbah.Implicits._
  8. private def dbObjectToTemplate(m:Obj) = try {
  9. G8.Template(
  10. m.getAs[String]("username").get,
  11. m.getAs[String]("name").get,
  12. m.getAs[String]("description").get
  13. )
  14. } catch {
  15. case e =>
  16. log.error("failed to parse %s" format m)
  17. throw e
  18. }
  19. implicit val mit: Iterator[DBObject] => Iterable[G8.Template] =
  20. (m) => (for(t <- m) yield dbObjectToTemplate(t)).toSeq
  21. }
  22. object G8 extends Logged {
  23. import Mongo._
  24. import com.mongodb.casbah.commons.Imports.ObjectId
  25. import com.mongodb.casbah.commons.{ MongoDBObject => Obj, MongoDBList => ObjList }
  26. import com.mongodb.casbah.{ MongoCollection }
  27. import com.mongodb.{ BasicDBList, DBObject }
  28. import com.mongodb.casbah.Implicits._
  29. case class Template(username: String, name: String, description: String)
  30. implicit val templateToDbObject: Template => DBObject =
  31. (t: Template) =>
  32. Obj(
  33. "username" -> t.username, // deprecated
  34. "name" -> t.name,
  35. "description" -> t.description
  36. )
  37. def DefaultLimit = 200
  38. private def templates[T](f: MongoCollection => T) =
  39. Store.collection("g8")(f)
  40. /** @return paginated set of all templates */
  41. def all[C, T](page: Int = 1, limit: Int = DefaultLimit)(f: Iterable[C] => T)(implicit cct: CanConvertListTo[C]) =
  42. templates { c =>
  43. log.info("getting templates (page: %s, limit: %s)" format(page, limit))
  44. f(cct(paginate(c.find(), page, limit).sort(
  45. Obj("username" -> 1, "name"-> 1))))
  46. }
  47. def apply[T, C](
  48. username: Option[String],
  49. name: Option[String],
  50. page: Int = 1, limit: Int = DefaultLimit)
  51. (f: Iterable[C] => T)(implicit cct: CanConvertListTo[C]) =
  52. templates { c =>
  53. log.info("getting templates for username: %s, name: %s" format(
  54. username, name
  55. ))
  56. ((username, name) match {
  57. case (Some(user), Some(tmp)) =>
  58. Some(Obj("username" -> anycase(user), "name" -> anycase(tmp)))
  59. case (Some(user), _) =>
  60. Some(Obj("username" -> anycase(user)))
  61. case (_, Some(tmp)) =>
  62. Some(Obj("name" -> anycase(tmp)))
  63. case _ =>
  64. None
  65. }) match {
  66. case Some(q) =>
  67. log.info("query: %s" format q)
  68. f(cct(
  69. paginate(c.find(q), page, limit).sort(
  70. Obj("username" -> 1, "name"-> 1))
  71. ))
  72. case _ => all(page, limit)(f)(cct)
  73. }
  74. }
  75. def save(tmpls: Seq[Template]) = templates { col =>
  76. log.info("saving or updating %d templates" format tmpls.size)
  77. tmpls.map { t =>
  78. val query = Obj(
  79. "username" -> t.username,
  80. "name" -> t.name
  81. )
  82. log.info("create or update selection query %s" format query)
  83. col.findAndModify(
  84. query, // query
  85. Obj(), // fields
  86. Obj(), // sort
  87. false, // rm
  88. templateToDbObject(t),// update
  89. true, // returned new
  90. true // create or update
  91. )
  92. }
  93. }
  94. def mainly(args: Array[String]) {
  95. import dispatch._
  96. import dispatch.liftjson.Js._
  97. import net.liftweb.json.JsonAST._
  98. def http = new Http
  99. def search = :/("github.com") / "api" / "v2"/ "json" / "repos" / "search"
  100. val RepoNamed = """(\S+)\.g8""".r
  101. @annotation.tailrec
  102. def fetch(tmpls: List[Template], page: Int): List[Template] = {
  103. (for {
  104. repos <- http(search / "g8" <<? Map("start_page" -> page.toString) ># ('repositories ? ary))
  105. JObject(fields) <- repos
  106. JField("name", JString(repo)) <- fields
  107. JField("username", JString(user_name)) <- fields
  108. JField("description", JString(desc)) <- fields
  109. repo_name <- RepoNamed.findFirstMatchIn(repo)
  110. } yield Template(user_name, repo_name.group(1), desc)) match {
  111. case Nil =>
  112. println("exhausted g8 search on page %s" format page)
  113. tmpls
  114. case more => fetch(more ::: tmpls, page + 1)
  115. }
  116. }
  117. try {
  118. val tmpls = fetch(List.empty[Template], 1)
  119. for(t <- tmpls) println(t)
  120. println("resolved %d g8 templates" format tmpls.size)
  121. G8.save(tmpls)
  122. } catch {
  123. case StatusCode(404, _) =>
  124. println("Unable to find github repositories like g8")
  125. }
  126. }
  127. }