PageRenderTime 182ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/scala/Libraries.scala

http://github.com/softprops/ls-server
Scala | 196 lines | 171 code | 12 blank | 13 comment | 5 complexity | 2267cec90715387ffa3cd2ce714252eb MD5 | raw file
  1. package ls
  2. import com.mongodb.casbah.Imports._
  3. // for reference http://www.mongodb.org/display/DOCS/Advanced+Queries
  4. object Libraries extends Logged {
  5. import Conversions._
  6. import Mongo._
  7. import com.mongodb.casbah.commons.Imports.ObjectId
  8. import com.mongodb.casbah.commons.{ MongoDBObject => Obj, MongoDBList => ObjList }
  9. import com.mongodb.casbah.{ MongoCollection }
  10. import com.mongodb.{ BasicDBList, DBObject }
  11. import com.mongodb.casbah.Implicits._
  12. val DefaultLimit = 20
  13. private def libraries[T](f: MongoCollection => T) =
  14. Store.collection("libraries")(f)
  15. /** searches for librarues by author/contributors */
  16. def author[T, C](ghuser: String)(f: Iterable[C] => T)
  17. (implicit cct: CanConvertListTo[C]) =
  18. libraries { c =>
  19. log.info("getting libraries for author %s" format ghuser)
  20. f(cct(c.find(
  21. $or("ghuser" -> anycase(ghuser), "contributors.login" -> anycase(ghuser))
  22. )))
  23. }
  24. /** search by any search terms */
  25. def any[T, C](terms: Seq[String])
  26. (page: Int = 1, lim: Int = DefaultLimit)(f: Iterable[C] => T)
  27. (implicit cct: CanConvertListTo[C]) =
  28. libraries { c =>
  29. log.info("getting libraries for terms %s" format terms.mkString(", "))
  30. val possiblies = (MongoDBObject().empty /: terms)(
  31. (a, e) => a += ("name" -> anycase(e))
  32. )
  33. val parts = (possiblies ++ ("_keywords" $in terms)).toMap
  34. val query = $or(parts.toSeq:_*)
  35. log.info("any query: %s" format query)
  36. f(cct( paginate(c.find(query), page, lim).sort(Obj("updated" -> -1)) ))
  37. }
  38. /** get a pagingates list of all libraries */
  39. def all[T, C](page: Int = 1, lim: Int = DefaultLimit)(f: Iterable[C] => T)
  40. (implicit cct: CanConvertListTo[C])=
  41. libraries { c =>
  42. log.info("getting libraries (page: %s, lim: %s)" format(page, lim))
  43. f(cct( paginate(c.find(), page, lim).sort(Obj("updated" -> -1)) ))
  44. }
  45. /** For project-based queries */
  46. def projects[T, C](user: String, repo: Option[String] = None)(
  47. f: Iterable[C] => T)(implicit cct: CanConvertListTo[C]) =
  48. libraries { c =>
  49. log.info(
  50. "getting libraries for user: %s, repo: %s" format(
  51. user, repo)
  52. )
  53. val query =
  54. Obj("ghuser" -> anycase(user)) opt repo.map(r => Obj("ghrepo" -> anycase(r)))
  55. log.info("query: %s" format query)
  56. f(cct(
  57. c.find(query)
  58. ))
  59. }
  60. def latest[T, C](
  61. name: String, user: Option[String] = None,
  62. repo: Option[String] = None)
  63. (f: Iterable[C] => T)(implicit cct: CanConvertListTo[C]) =
  64. libraries { c =>
  65. log.info("geting latest version of %s (%s/%s)" format(name, user, repo))
  66. val query = Obj("name" -> narrowAnycase(name)) opt user.map(u =>
  67. Obj("ghuser" -> narrowAnycase(u))
  68. ) opt repo.map(r =>
  69. Obj("ghrepo" -> narrowAnycase(r))
  70. )
  71. f(cct(c.find(
  72. query,
  73. Obj("_id" -> 0, "versions.version" -> 1)
  74. )))
  75. }
  76. /** Find by name + version and optionally user and repo */
  77. def apply[T, C](
  78. name: String,
  79. version: Option[String] = None,
  80. user: Option[String] = None,
  81. repo: Option[String] = None)
  82. (f: Iterable[C] => T)(implicit cct: CanConvertListTo[C]) =
  83. libraries { c =>
  84. log.info("getting libraries for name: %s, user: %s, repo: %s" format(
  85. name, user, repo
  86. ))
  87. val query =
  88. Obj("name" -> narrowAnycase(name)) opt user.map(u =>
  89. Obj("ghuser" -> narrowAnycase(u))
  90. ) opt repo.map(r =>
  91. Obj("ghrepo" -> narrowAnycase(r))
  92. ) opt version.map(v =>
  93. Obj("versions.version" -> version)
  94. )
  95. log.info("query: %s" format query)
  96. f(cct(
  97. c.find(query)
  98. ))
  99. }
  100. // merge/update before simply appending to collection
  101. // potential hammersmith candiate
  102. def save(libs: Seq[Library]) = libraries { col =>
  103. log.info("saving or updating %d libraries" format libs.size)
  104. libs.map { l =>
  105. val query = Obj(
  106. "name" -> l.name,
  107. "ghuser" -> l.ghuser,
  108. "ghrepo" -> l.ghrepo
  109. )
  110. log.info("create or update selection query %s" format query)
  111. apply(l.name, user = l.ghuser, repo = l.ghrepo){ (currentVersions: Iterable[LibraryVersions]) =>
  112. log.info("found %s libraries by the name %s under %s/%s" format(currentVersions, l.name, l.ghuser, l.ghrepo))
  113. if(currentVersions.isEmpty) try {
  114. col.findAndModify(
  115. query, // query
  116. Obj(), // fields
  117. Obj(), // sort
  118. false, // rm
  119. libraryToDbObject(l),// update
  120. true, // returned new
  121. true // create or update
  122. )
  123. } catch {
  124. case e => e.printStackTrace
  125. } else {
  126. // this could get ugly!
  127. val current: LibraryVersions = currentVersions.head.copy(
  128. description = l.description,
  129. // for now, always update this to the provided org (assume it's the latest)
  130. // this field for all intents an purposes should be considered deprecated
  131. organization = l.organization,
  132. site = l.site,
  133. tags = l.tags,
  134. sbt = l.sbt,
  135. contributors = l.contributors
  136. )
  137. val versions = current.versions.toSeq
  138. val (contained, notcontained) = versions.partition(_.version == l.version)
  139. if(contained.isEmpty) {
  140. val appended = (Version(
  141. l.version, l.docs,
  142. l.resolvers, l.dependencies,
  143. l.scalas,
  144. l.licenses,
  145. l.organization
  146. ) +: versions).sorted
  147. val updating = libraryVersionsToDbObject(current.copy(
  148. versions = appended
  149. ))
  150. // append version
  151. col.findAndModify(
  152. query,
  153. Obj(),
  154. Obj(),
  155. false,
  156. updating,
  157. true,
  158. true
  159. )
  160. } else {
  161. // update version
  162. val merged = (contained(0).copy(
  163. version = l.version, organization = l.organization, docs = l.docs,
  164. resolvers = l.resolvers, dependencies = l.dependencies,
  165. scalas = l.scalas
  166. ) +: notcontained).sorted
  167. val updated = libraryVersionsToDbObject(current.copy(
  168. versions = merged
  169. ))
  170. col.findAndModify(
  171. query,
  172. Obj(),
  173. Obj(),
  174. false,
  175. updated,
  176. true,
  177. true
  178. )
  179. }
  180. }
  181. }
  182. }
  183. }
  184. }