Skip to content

Instantly share code, notes, and snippets.

@Zolomon
Created June 15, 2014 10:55
Show Gist options
  • Select an option

  • Save Zolomon/38e74cd9f04f6c58f98f to your computer and use it in GitHub Desktop.

Select an option

Save Zolomon/38e74cd9f04f6c58f98f to your computer and use it in GitHub Desktop.
Adventures in Scala
import java.io._
import com.github.tototoshi.csv.CSVReader
import scala.collection.mutable.ListBuffer
import scala.io.Source
case class Publisher(name: String)
case class Book(isbn: String, publishers: Option[List[Publisher]])
class Row(fields: ListBuffer[String]) {
val Fields = _headers.zip(fields)
private val _headers = Array("Book Id", "Title", "Author", "Author l-f", "Additional Authors", "ISBN", "ISBN13",
"My Rating", "Average Rating", "Publisher", "Binding", "Number of Pages", "Year Published",
"Original Publication Year", "Date Read", "Date Added", "Bookshelves", "Bookshelves with positions",
"Exclusive Shelf", "My Review", "Spoiler", "Private Notes", "Read Count", "Recommended For", "Recommended By",
"Owned Copies", "Original Purchase Date", "Original Purchase Location", "Condition", "Condition Description",
"BCID")
def getISBN(): String = {
val isbn = getValue("ISBN")
val isbn13 = getValue("ISBN13")
if (!isbn13.isEmpty) {
isbn13
} else {
if (!isbn.isEmpty)
isbn
else
throw new NoSuchElementException("Missing ISBN for book with id: " + getValue("Book Id"))
}
}
def getValue(field: String): String = Fields.filter(x => x._1 == field).head._2
override def toString(): String = {
fields.mkString(",")
}
}
object Faust {
def main(args: Array[String]) {
if (!args.isEmpty) {
val reader = Source.fromFile(new File("C:\\Users\\zol\\Downloads\\goodreads_export.csv"))("UTF-8")
val rows = new ListBuffer[Row]
for (line <- reader.getLines().drop(1)) {
rows += new Row(parse(line))
}
reader.close()
val json = getJSON(rows)
val writer = new PrintWriter("C:\\Users\\zol\\Downloads\\books.json")
writer.write(json)
writer.close()
} else {
val in = new BufferedReader(new FileReader(new File("C:\Users\zol\Downloads\books.json")))
val lines = in.lines()
print(lines)
}
}
def getJSON(rows: ListBuffer[Row]): String = {
val isbns = rows.map(_.getISBN()).mkString(",")
val base_url = "http://openlibrary.org/api/books?format=json&jscmd=data&bibkeys=ISBN:"
val url = base_url + isbns
getPage(url)
}
def getPage(url: String): String = {
val html = Source.fromURL(url)
html.mkString
}
// Will parse a string in the form of: 52345,"Bengt, Ericsson",26,"Nice guy",,,,Hahaha,,
// into ["52345", "Bengt, Ericsson", 26, "Nice guy", "", "", "", "Hahaha", "", ""].
def parse(s: String): ListBuffer[String] = {
val items = new ListBuffer[String]
var tmp = s;
while (tmp.length > 0) {
var commaIdx = tmp.indexOf(',')
var quoteIdx = tmp.indexOf('"')
// "...,..."
if (quoteIdx < commaIdx) {
if (quoteIdx == -1) {
// There are no quotes,
// What do we do?
// We want to return the next value from start to next comma
val item = tmp.substring(0, commaIdx)
tmp = tmp.substring(commaIdx + 1, tmp.length())
items += item
} else {
//var item = s.substring(0, commaIdx)
val nextQuoteIdx = tmp.indexOf('"', quoteIdx + 1)
val item = tmp.substring(quoteIdx + 1, nextQuoteIdx)
tmp = tmp.substring(nextQuoteIdx + 2)
items += item
}
}
// ...,"..."
if (commaIdx < quoteIdx) {
if (commaIdx == -1) {
// There are no more commas
// What do we do?
// Return the rest of the string
val nextQuoteIdx = tmp.indexOf('"', quoteIdx + 1)
val item = tmp.substring(quoteIdx, nextQuoteIdx)
items += item
} else {
val item = tmp.substring(0, commaIdx)
tmp = tmp.substring(commaIdx + 1, tmp.length())
items += item
}
}
}
items
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment