<commit_before>package viscel.server

import org.neo4j.tooling.GlobalGraphOperations
import rescala.propagation.Engines.default
import spray.can.server.Stats
import spray.http._
import upickle.Writer
import viscel.Deeds
import viscel.database.{Ntx, label}
import viscel.narration.Narrator
import viscel.shared.JsonCodecs.stringMapW
import viscel.store.{Collection, Config, User}

import scala.Predef.ArrowAssoc
import scala.collection.JavaConverters.iterableAsScalaIterableConverter
import scala.collection.immutable.Map
import scalatags.Text.attrs.{`type`, href, rel, src, title}
import scalatags.Text.implicits.{stringAttr, stringFrag}
import scalatags.Text.tags.{body, head, html, link, script}
import scalatags.Text.{RawFrag, Tag}


object ServerPages {
	val path_css: String = "/css"
	val path_js: String = "/js"

	val fullHtml: Tag =
		html(
			head(
				link(href := path_css, rel := "stylesheet", `type` := MediaTypes.`text/css`.toString()),
				title := "Viscel"),
			body("if nothing happens, your javascript does not work"),
			script(src := path_js),
			script(RawFrag(s"Viscel().main()")))

	val landing: HttpResponse = HttpResponse(entity = HttpEntity(
		ContentType(MediaTypes.`text/html`, HttpCharsets.`UTF-8`),
		"<!DOCTYPE html>" + fullHtml.render))

	def jsonResponse[T: Writer](value: T): HttpResponse = HttpResponse(entity = HttpEntity(
		ContentType(MediaTypes.`application/json`, HttpCharsets.`UTF-8`),
		upickle.write(value)))

	def bookmarks(user: User): HttpResponse = jsonResponse(user.bookmarks)

	def collections(implicit ntx: Ntx): HttpResponse = {

		val allCollections = GlobalGraphOperations.at(ntx.db).getAllNodesWithLabel(label.Collection).asScala.map { Collection.apply } ++
			Narrator.availableCores.map(Collection.findAndUpdate)
		jsonResponse(allCollections.map { _.narration(deep = false) })
	}


	def collection(collection: Collection)(implicit ntx: Ntx) = { jsonResponse(collection.narration(deep = true)) }

	def stats(stats: Stats)(implicit ntx: Ntx): HttpResponse = jsonResponse {
		val cn = Config.get()
		Map[String, String](
			"Downloaded" -> cn.downloaded.toString,
			"Downloads" -> cn.downloads.toString,
			"Compressed downloads" -> cn.downloadsCompressed.toString,
			"Failed downloads" -> cn.downloadsFailed.toString,
			"Narrations" -> ntx.nodes(label.Collection).size.toString,
			"Chapters" -> ntx.nodes(label.Chapter).size.toString,
			"Assets" -> ntx.nodes(label.Asset).size.toString,
			"Uptime" -> stats.uptime.toString,
			"Total requests" -> stats.totalRequests.toString,
			"Open requests" -> stats.openRequests.toString,
			"Max open requests" -> stats.maxOpenRequests.toString,
			"Total connections" -> stats.totalConnections.toString,
			"Open connections" -> stats.openConnections.toString,
			"Max open connections" -> stats.maxOpenConnections.toString,
			"Requests timed out" -> stats.requestTimeouts.toString,
			"Session ui requests" -> Deeds.sessionUiRequests.now.toString)<commit_msg>stats now return numbers, not strings<commit_after>package viscel.server

import org.neo4j.tooling.GlobalGraphOperations
import rescala.propagation.Engines.default
import spray.can.server.Stats
import spray.http._
import upickle.Writer
import viscel.Deeds
import viscel.database.{Ntx, label}
import viscel.narration.Narrator
import viscel.shared.JsonCodecs.stringMapW
import viscel.store.{Collection, Config, User}

import scala.Predef.ArrowAssoc
import scala.collection.JavaConverters.iterableAsScalaIterableConverter
import scala.collection.immutable.Map
import scalatags.Text.attrs.{`type`, href, rel, src, title}
import scalatags.Text.implicits.{stringAttr, stringFrag}
import scalatags.Text.tags.{body, head, html, link, script}
import scalatags.Text.{RawFrag, Tag}


object ServerPages {
	val path_css: String = "/css"
	val path_js: String = "/js"

	val fullHtml: Tag =
		html(
			head(
				link(href := path_css, rel := "stylesheet", `type` := MediaTypes.`text/css`.toString()),
				title := "Viscel"),
			body("if nothing happens, your javascript does not work"),
			script(src := path_js),
			script(RawFrag(s"Viscel().main()")))

	val landing: HttpResponse = HttpResponse(entity = HttpEntity(
		ContentType(MediaTypes.`text/html`, HttpCharsets.`UTF-8`),
		"<!DOCTYPE html>" + fullHtml.render))

	def jsonResponse[T: Writer](value: T): HttpResponse = HttpResponse(entity = HttpEntity(
		ContentType(MediaTypes.`application/json`, HttpCharsets.`UTF-8`),
		upickle.write(value)))

	def bookmarks(user: User): HttpResponse = jsonResponse(user.bookmarks)

	def collections(implicit ntx: Ntx): HttpResponse = {

		val allCollections = GlobalGraphOperations.at(ntx.db).getAllNodesWithLabel(label.Collection).asScala.map { Collection.apply } ++
			Narrator.availableCores.map(Collection.findAndUpdate)
		jsonResponse(allCollections.map { _.narration(deep = false) })
	}


	def collection(collection: Collection)(implicit ntx: Ntx) = { jsonResponse(collection.narration(deep = true)) }

	def stats(stats: Stats)(implicit ntx: Ntx): HttpResponse = jsonResponse {
		val cn = Config.get()
		Map[String, Long](
			"Downloaded" -> cn.downloaded,
			"Downloads" -> cn.downloads,
			"Compressed downloads" -> cn.downloadsCompressed,
			"Failed downloads" -> cn.downloadsFailed,
			"Narrations" -> ntx.nodes(label.Collection).size,
			"Chapters" -> ntx.nodes(label.Chapter).size,
			"Assets" -> ntx.nodes(label.Asset).size,
			"Uptime" -> stats.uptime.toSeconds,
			"Total requests" -> stats.totalRequests,
			"Open requests" -> stats.openRequests,
			"Max open requests" -> stats.maxOpenRequests,
			"Total connections" -> stats.totalConnections,
			"Open connections" -> stats.openConnections,
			"Max open connections" -> stats.maxOpenConnections,
			"Requests timed out" -> stats.requestTimeouts,
			"Session ui requests" -> Deeds.sessionUiRequests.now)
{'fraction_non_alphanumeric': 0.13317274604267035, 'fraction_numerical': 0.0010323468685478321, 'mean_word_length': 5.20384204909285, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5135785', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1858, 'n_words': 376}