Browse Source

Move cookies management code to separate file

master
Gwendal 6 years ago
parent
commit
cf4dd39417
2 changed files with 120 additions and 106 deletions
  1. +2
    -106
      src/main/kotlin/bandcampcollectiondownloader/BandcampCollectionDownloader.kt
  2. +118
    -0
      src/main/kotlin/bandcampcollectiondownloader/CookiesManagement.kt

+ 2
- 106
src/main/kotlin/bandcampcollectiondownloader/BandcampCollectionDownloader.kt View File

@ -1,29 +1,17 @@
package bandcampcollectiondownloader
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.google.gson.annotations.SerializedName
import org.ini4j.Ini
import org.jsoup.HttpStatusException
import org.jsoup.Jsoup
import org.zeroturnaround.zip.ZipUtil
import java.io.File
import retrieveCookiesFromFile
import retrieveFirefoxCookies
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.sql.Connection
import java.sql.DriverManager
import java.time.Instant
import java.util.*
import java.util.regex.Pattern
data class ParsedCookie(
@SerializedName("Name raw")
val nameRaw: String?,
@SerializedName("Content raw")
val contentRaw: String?
)
data class ParsedBandcampData(
@Suppress("ArrayInDataClass") val digital_items: Array<DigitalItem>
@ -42,19 +30,6 @@ data class ParsedStatDownload(
val download_url: String
)
fun parsedCookiesToMap(parsedCookies: Array<ParsedCookie>): Map<String, String> {
val result = HashMap<String, String>()
for (parsedCookie in parsedCookies) {
if (parsedCookie.contentRaw.isNullOrEmpty()) {
throw BandCampDownloaderError("Missing 'Content raw' field in cookie number ${parsedCookies.indexOf(parsedCookie) + 1}.")
}
if (parsedCookie.nameRaw.isNullOrEmpty()) {
throw BandCampDownloaderError("Missing 'Name raw' field in cookie number ${parsedCookies.indexOf(parsedCookie) + 1}.")
}
result[parsedCookie.nameRaw!!] = parsedCookie.contentRaw!!
}
return result
}
/**
@ -121,85 +96,6 @@ fun downloadAll(cookiesFile: Path?, bandcampUser: String, downloadFormat: String
}
private fun retrieveCookiesFromFile(cookiesFile: Path?, gson: Gson): Map<String, String> {
if (!Files.exists(cookiesFile)) {
throw BandCampDownloaderError("Cookies file '$cookiesFile' cannot be found.")
}
val jsonData = String(Files.readAllBytes(cookiesFile))
val parsedCookies =
try {
gson.fromJson(jsonData, Array<ParsedCookie>::class.java)
} catch (e: JsonSyntaxException) {
throw BandCampDownloaderError("Cookies file '$cookiesFile' is not well formed: ${e.message}")
}
return parsedCookiesToMap(parsedCookies)
}
private fun retrieveFirefoxCookies(): HashMap<String, String> {
val result = HashMap<String, String>()
// Find cookies file path
val firefoxConfDirPath: Path?
firefoxConfDirPath = when {
isUnix() -> {
val homeDir = Paths.get(System.getenv()["HOME"])
homeDir.resolve(".mozilla/firefox")
}
isWindows() -> {
val appdata = Paths.get(System.getenv("APPDATA"))
appdata.resolve("mozilla/firefox")
}
else -> throw BandCampDownloaderError("OS not supported, cannot find Firefox cookies!")
}
val profilesListPath = firefoxConfDirPath.resolve("profiles.ini")
val profilesListFile = File(profilesListPath.toUri())
if (!profilesListFile.exists()) {
throw BandCampDownloaderError("No Firefox profiles.ini file could be found!")
}
val ini = Ini(profilesListFile)
val default = "Default"
val defaultProfileSection = ini.keys.find {
ini[it] != null
&& ini[it]!!.containsKey(default)
&& ini[it]!![default] == "1"
}
val defaultProfilePath = firefoxConfDirPath.resolve(ini.get(defaultProfileSection, "Path"))
val cookiesFilePath = defaultProfilePath.resolve("cookies.sqlite")
// Copy cookies file as tmp file
val tmpFolder = Files.createTempDirectory("bandcampCollectionDownloader")
val copiedCookiesPath = Files.copy(cookiesFilePath, tmpFolder.resolve("cookies.json"))
copiedCookiesPath.toFile().deleteOnExit()
// Start reading firefox's cookies.sqlite
var connection: Connection? = null
try {
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:$copiedCookiesPath")
val statement = connection!!.createStatement()
statement.queryTimeout = 30 // set timeout to 30 sec.
val rs = statement.executeQuery("select * from moz_cookies where baseDomain = 'bandcamp.com'")
// For each resulting row
while (rs.next()) {
// Extract data from row
val name = rs.getString("name")
val value = rs.getString("value")
val expiry = rs.getString("expiry").toLong()
// We only keep cookies that have not expired yet
val now = Instant.now().epochSecond
val difference = expiry - now
if (difference > 0)
result[name] = value
}
} finally {
connection?.close()
}
return result
}
class BandCampDownloaderError(s: String) : Exception(s)


+ 118
- 0
src/main/kotlin/bandcampcollectiondownloader/CookiesManagement.kt View File

@ -0,0 +1,118 @@
import bandcampcollectiondownloader.BandCampDownloaderError
import bandcampcollectiondownloader.isUnix
import bandcampcollectiondownloader.isWindows
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.google.gson.annotations.SerializedName
import org.ini4j.Ini
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.sql.Connection
import java.sql.DriverManager
import java.time.Instant
data class ParsedCookie(
@SerializedName("Name raw")
val nameRaw: String?,
@SerializedName("Content raw")
val contentRaw: String?
)
fun parsedCookiesToMap(parsedCookies: Array<ParsedCookie>): Map<String, String> {
val result = java.util.HashMap<String, String>()
for (parsedCookie in parsedCookies) {
if (parsedCookie.contentRaw.isNullOrEmpty()) {
throw BandCampDownloaderError("Missing 'Content raw' field in cookie number ${parsedCookies.indexOf(parsedCookie) + 1}.")
}
if (parsedCookie.nameRaw.isNullOrEmpty()) {
throw BandCampDownloaderError("Missing 'Name raw' field in cookie number ${parsedCookies.indexOf(parsedCookie) + 1}.")
}
result[parsedCookie.nameRaw!!] = parsedCookie.contentRaw!!
}
return result
}
fun retrieveCookiesFromFile(cookiesFile: Path?, gson: Gson): Map<String, String> {
if (!Files.exists(cookiesFile)) {
throw BandCampDownloaderError("Cookies file '$cookiesFile' cannot be found.")
}
val jsonData = String(Files.readAllBytes(cookiesFile))
val parsedCookies =
try {
gson.fromJson(jsonData, Array<ParsedCookie>::class.java)
} catch (e: JsonSyntaxException) {
throw BandCampDownloaderError("Cookies file '$cookiesFile' is not well formed: ${e.message}")
}
return parsedCookiesToMap(parsedCookies)
}
fun retrieveFirefoxCookies(): HashMap<String, String> {
val result = HashMap<String, String>()
// Find cookies file path
val firefoxConfDirPath: Path?
firefoxConfDirPath = when {
isUnix() -> {
val homeDir = Paths.get(System.getenv()["HOME"])
homeDir.resolve(".mozilla/firefox")
}
isWindows() -> {
val appdata = Paths.get(System.getenv("APPDATA"))
appdata.resolve("mozilla/firefox")
}
else -> throw BandCampDownloaderError("OS not supported, cannot find Firefox cookies!")
}
val profilesListPath = firefoxConfDirPath.resolve("profiles.ini")
val profilesListFile = File(profilesListPath.toUri())
if (!profilesListFile.exists()) {
throw BandCampDownloaderError("No Firefox profiles.ini file could be found!")
}
val ini = Ini(profilesListFile)
val default = "Default"
val defaultProfileSection = ini.keys.find {
ini[it] != null
&& ini[it]!!.containsKey(default)
&& ini[it]!![default] == "1"
}
val defaultProfilePath = firefoxConfDirPath.resolve(ini.get(defaultProfileSection, "Path"))
val cookiesFilePath = defaultProfilePath.resolve("cookies.sqlite")
// Copy cookies file as tmp file
val tmpFolder = Files.createTempDirectory("bandcampCollectionDownloader")
val copiedCookiesPath = Files.copy(cookiesFilePath, tmpFolder.resolve("cookies.json"))
copiedCookiesPath.toFile().deleteOnExit()
// Start reading firefox's cookies.sqlite
var connection: Connection? = null
try {
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:$copiedCookiesPath")
val statement = connection!!.createStatement()
statement.queryTimeout = 30 // set timeout to 30 sec.
val rs = statement.executeQuery("select * from moz_cookies where baseDomain = 'bandcamp.com'")
// For each resulting row
while (rs.next()) {
// Extract data from row
val name = rs.getString("name")
val value = rs.getString("value")
val expiry = rs.getString("expiry").toLong()
// We only keep cookies that have not expired yet
val now = Instant.now().epochSecond
val difference = expiry - now
if (difference > 0)
result[name] = value
}
} finally {
connection?.close()
}
return result
}

Loading…
Cancel
Save