package org.meshbay.client.phonesync import java.io.File import java.text.SimpleDateFormat import java.util.Date import java.util.Locale import java.util.TimeZone /** One file a run sends, and what is recorded once the node has it. */ data class Export( val file: File, val name: String, val mime: String, /** Recorded only when the node took the file: what the next export starts from. */ val marker: String, /** Contacts or messages in it, for the page to say. */ val count: Int, /** A folder under the kind's own, such as the year, or empty. */ val subdir: String = "", ) /** * One kind of the phone's data (the contacts, the messages) written out as * a file of what is new since `marker`, the value the last file sent left. */ interface DocSource { /** The runtime permissions it reads with. */ val permissions: Array /** Where its files go, under the chosen folder: `-`. */ val suffix: String /** A file of what is new since `marker` in `dir`, or null when nothing is. */ fun export(marker: String?, dir: File, now: Long, zone: TimeZone): Export? } /** The names a run gives what it sends. Pure, so the JVM tests hold them. */ object DocPlan { /** A run is due once a day, counted from the last one that finished. */ const val DAY_MS = 24L * 3600 * 1000 /** A username as the hub allows it; it names a folder on the node. */ val SAFE_ACCOUNT = Regex("^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$") /** `/-`: everything of one kind, from one account, in one place. */ fun dirFor(destination: Destination, suffix: String): String = "${destination.folder}/${destination.account}-$suffix" /** * `-YYYY-MM-DD-HHmm.`, in the phone's time: a run never replaces * an earlier file, and the name says when it was taken. */ fun yearOf(now: Long, zone: TimeZone): String = SimpleDateFormat("yyyy", Locale.ROOT).apply { timeZone = zone }.format(Date(now)) fun nameFor(stem: String, ext: String, now: Long, zone: TimeZone): String = "$stem-" + SimpleDateFormat("yyyy-MM-dd-HHmm", Locale.ROOT).apply { timeZone = zone }.format(Date(now)) + ".$ext" }