Skip to content

Commit

Permalink
Merge a338e5a into eb36b4a
Browse files Browse the repository at this point in the history
  • Loading branch information
gregorbg committed Aug 1, 2022
2 parents eb36b4a + a338e5a commit bf32b2c
Show file tree
Hide file tree
Showing 74 changed files with 2,905 additions and 1,696 deletions.
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ ktor = "2.0.3"
kotless = "0.1.6"
junit-jupiter = "5.9.0"
batik = "1.14"
itext7 = "7.2.3"

nodejs = "16.15.1"

[libraries]
markdownj-core = { module = "org.markdownj:markdownj-core", version = "0.4" }
zip4j = { module = "net.lingala.zip4j:zip4j", version = "2.11.1" }
itextpdf = { module = "com.itextpdf:itextpdf", version = "5.5.13.3" }
itext7 = { module = "com.itextpdf:itext7-core", version.ref = "itext7" }
batik-transcoder = { module = "org.apache.xmlgraphics:batik-transcoder", version.ref = "batik" }
batik-codec = { module = "org.apache.xmlgraphics:batik-codec", version.ref = "batik" }
snakeyaml = { module = "org.yaml:snakeyaml", version = "1.30" }
Expand All @@ -21,6 +23,7 @@ junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", vers
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.3.3" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.6.4" }
kotlinx-atomicfu-gradle = { module = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version = "0.18.3" }
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
ktor-server-servlet = { module = "io.ktor:ktor-server-servlet", version.ref = "ktor" }
ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" }
Expand Down
6 changes: 3 additions & 3 deletions tnoodle-server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ plugins {
}

dependencies {
api(libs.ktor.server.netty)
api(libs.ktor.server.content.negotiation)
api(libs.ktor.server.core)
api(libs.kotlinx.serialization.json)
api(libs.kotlinx.coroutines.core)
api(libs.tnoodle.scrambles)

implementation(libs.kotlinx.coroutines.core)
implementation(libs.ktor.server.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.server.host.common)
implementation(libs.ktor.server.default.headers)
Expand Down
2 changes: 2 additions & 0 deletions webscrambles/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ dependencies {
implementation(libs.zip4j)
implementation(libs.markdownj.core)
implementation(libs.itextpdf)
implementation(libs.itext7)
implementation(libs.batik.transcoder)
implementation(libs.snakeyaml)
implementation(libs.kotlin.argparser)
implementation(libs.system.tray)
implementation(libs.apache.commons.lang3)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.server.websockets)
implementation(libs.ktor.server.status.pages)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ object Translate {
val TRANSLATED_LOCALES
get() = TRANSLATIONS.keys

val LOCALES_BY_LANG_TAG = TRANSLATED_LOCALES.associateBy { it.toLanguageTag() }

private fun loadTranslationResources(): Map<Locale, Map<String, *>> {
val yaml = Yaml(Constructor(HashMap::class.java))
val locales = Locale.getAvailableLocales() + DEFAULT_LOCALE
Expand Down Expand Up @@ -56,7 +58,11 @@ object Translate {
?: TranslationException.error("${locale.toLanguageTag()} translation key $key is of type ${translation.javaClass}, but we were expecting String.")
}

private tailrec fun descendKeys(translationGroup: Map<*, *>, parts: List<String>, errorProvider: ((String) -> String)? = null): String? {
private tailrec fun descendKeys(
translationGroup: Map<*, *>,
parts: List<String>,
errorProvider: ((String) -> String)? = null
): String? {
if (parts.isEmpty()) {
return null
}
Expand Down Expand Up @@ -87,6 +93,9 @@ object Translate {
return interpolate(translation, substitutions)
}

operator fun invoke(key: String, locale: Locale, substitutions: Map<String, String> = mapOf()) =
translate(key, locale, substitutions)

// Interpolate translation keys in the same way Ruby on Rails does.
// See: http://guides.rubyonrails.org/i18n.html#passing-variables-to-translations
private fun interpolate(interpolateMe: String, substitutions: Map<String, String>): String {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.worldcubeassociation.tnoodle.server.webscrambles.pdf

import org.worldcubeassociation.tnoodle.server.webscrambles.Translate
import org.worldcubeassociation.tnoodle.server.webscrambles.wcif.model.*
import java.util.Locale

abstract class FewestMovesSheet(
val scramble: Scramble,
val totalAttemptsNum: Int,
override val scrambleSetId: Int,
competitionTitle: String,
activityCode: ActivityCode,
hasGroupId: Boolean,
locale: Locale,
watermark: String?
) : ScrambleSheet(competitionTitle, activityCode, hasGroupId, locale, watermark) {
override val scrambles: List<Scramble>
get() = listOfNotNull(scramble)

val currentAttemptNum: Int
get() = activityCode.attemptNumber?.plus(1) ?: 1

val localEventTitle: String
get() = Translate("fmc.event", locale)

val attemptDetails: String
get() = activityCode.copyParts(attemptNumber = null) // FMC is split per attempt so we count scrambleXofY instead
.compileTitleString(locale, includeEvent = false, includeGroupId = hasGroupId)

val activityTitle: String
get() = "$localEventTitle $attemptDetails".trim()

val scrambleXOfY
get(): String {
val substitutions = mapOf(
"scrambleIndex" to currentAttemptNum.toString(),
"scrambleCount" to totalAttemptsNum.toString()
)

return Translate("fmc.scrambleXofY", locale, substitutions)
}

companion object {
const val MOVE_BARS_PER_LINE = 10
const val MOVE_BAR_LINES = 8

const val WCA_MAX_MOVES_FMC = MOVE_BARS_PER_LINE * MOVE_BAR_LINES
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.worldcubeassociation.tnoodle.server.webscrambles.pdf

import org.worldcubeassociation.tnoodle.server.webscrambles.Translate
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.dsl.DocumentBuilder
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.dsl.PageBuilder
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.properties.Alignment
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.properties.Drawing
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.properties.Font
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.properties.Paper.inchesToPixel
import org.worldcubeassociation.tnoodle.server.webscrambles.pdf.model.properties.Paper.pixelsToInch
import org.worldcubeassociation.tnoodle.server.webscrambles.wcif.model.*
import java.util.*

class FmcCutoutSheet(
scramble: Scramble,
activityCode: ActivityCode,
scrambleSetId: Int,
locale: Locale,
totalAttemptsNum: Int,
competitionTitle: String,
hasGroupId: Boolean,
watermark: String? = null
) : FewestMovesSheet(scramble, totalAttemptsNum, scrambleSetId, competitionTitle, activityCode, hasGroupId, locale, watermark) {
override fun DocumentBuilder.writeContents() {
page {
setVerticalMargins(10)
setHorizontalMargins(20)

addFmcScrambleCutoutSheet()
}
}

private fun PageBuilder.addFmcScrambleCutoutSheet() {
val scrambleSuffix = scrambleXOfY
.takeIf { totalAttemptsNum > 1 }.orEmpty()

val title = "$activityTitle $scrambleSuffix".trim()

val baseFont = Font.fontForLocale(Translate.DEFAULT_LOCALE)
val localFont = Font.fontForLocale(locale)

val paddingHeightPenalty = SCRAMBLES_PER_SHEET * 2 * Drawing.Padding.DEFAULT

val actualWidthIn = size.widthIn - (marginLeft + marginRight).pixelsToInch
val actualHeightIn = size.heightIn - (marginTop + marginBottom).pixelsToInch -
paddingHeightPenalty.pixelsToInch

val scramblerPreferredSize = scramblingPuzzle.preferredSize
val scramblerWidthToHeight = scramblerPreferredSize.width.toFloat() / scramblerPreferredSize.height

table(2) {
// see GeneralScrambleSheet to figure out what this is about (:
val relativeHeight = actualHeightIn / actualWidthIn
val relHeightPerScramble = relativeHeight / SCRAMBLES_PER_SHEET

val scrambleWidth = relHeightPerScramble * scramblerWidthToHeight

// as we're always printing more than 1 scramble per sheet,
// naively assume that fullWidth < 1
val textWidth = 1 - scrambleWidth
relativeWidths = listOf(textWidth, scrambleWidth)

border = Drawing.Border.ROWS_ONLY
stroke = Drawing.Stroke.DASHED

repeat(SCRAMBLES_PER_SHEET) {
row {
verticalAlignment = Alignment.Vertical.MIDDLE

cell {
paragraph {
leading = 1f

// TODO this is a hack to prevent some margins overlapping
// TODO magic number factor
val scaledTextWidth = textWidth * 0.98f

line(competitionTitle) {
fontName = baseFont

val relHeightForCompName = relHeightPerScramble / 8
setOptimalOneLineFontSize(relHeightForCompName, scaledTextWidth, actualWidthIn)
}
line(title) {
fontName = localFont

val relHeightForTitle = relHeightPerScramble / 4
setOptimalOneLineFontSize(relHeightForTitle, scaledTextWidth, actualWidthIn)
}
line(scramble.scrambleString) {
fontName = baseFont

val relHeightForScrambleString = relHeightPerScramble / 2
setOptimalOneLineFontSize(relHeightForScrambleString, scaledTextWidth, actualWidthIn)
}
}
}

cell {
padding = 2 * Drawing.Padding.DEFAULT
horizontalAlignment = Alignment.Horizontal.CENTER

val scrambleWidthPx = (scrambleWidth * actualWidthIn).inchesToPixel
svgScrambleImage(scramble.scrambleString, scrambleWidthPx)
}
}
}
}
}

companion object {
val SCRAMBLES_PER_SHEET = 8
}
}

This file was deleted.

Loading

0 comments on commit bf32b2c

Please sign in to comment.