The Sword and Laser discussion

319 views
What Else Are You Reading? > Good Reads Coding

Comments Showing 1-50 of 51 (51 new)    post a comment »
« previous 1

message 1: by Rob, Roberator (last edited Nov 15, 2014 06:43AM) (new)

Rob (robzak) | 6719 comments Mod
Not sure where exactly to put this thread. It's sort of about what I'm reading.

I may move this discussion off of here though as it's not exactly S&L specific.

Anyways I'm planning to write a java based parser and utilities to process the CSV files good reads allows you to export.

I'll probably have something to share by the end of the weekend. In the meantime I'm moving my major side track out of the year end goals thread. :)

Sound off if you're interested in helping and/or have suggestions about features as I'll be fairly narrowly focused on my own particular use cases to start with.

Not sure how much time I'll put into it beyond that, but I'll at least put the code somewhere people can get to it and modify for their purposes.

Code Repository: https://github.com/robertzak/goodread...


message 2: by Sky (new)

Sky | 665 comments I'd love to help, but wont be back in the states and have time till mid next week.

as for package name, how about com.readsgood to avoid trademark issues/confusion :)


message 3: by CatBookMom (last edited Nov 06, 2014 01:15PM) (new)

CatBookMom I'm totally not a coder, but FWIW, something I'd love to be able to export from Goodreads is a text file excerpt from my "Books Read" shelf that I could copy/paste into a discussion-group post (at Ravelry.com, a knitting community website). I've been able to pare down the columns of my bookshelf "Wish List" and send that as a document to my Kindle, but I couldn't reduce it to as simple a document as I'd like for my knitting group; it still had columns and headings.

If this is the sort of input you're interested in, I hope it helps.


message 4: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Sky wrote: "I'd love to help, but wont be back in the states and have time till mid next week.

as for package name, how about com.readsgood to avoid trademark issues/confusion :)"


No worries, and that works. I was going to do org.bookmagic for lack of a better idea.


message 5: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
CatBookMom wrote: "I'm totally not a coder, but FWIW, something I'd love to be able to export from Goodreads is a text file excerpt from my "Books Read" shelf that I could copy/paste into a discussion-group post (at ..."

When I have something working I can try to explain what it does and see how easy it will be to output what you're asking for.


message 6: by [deleted user] (new)

I can help with code review or debugging down the line if you run into a wall. Will you be posting the code in a public repository?


message 7: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Yeah, probably on github. I don't expect the basic functionality to be very difficult.

The general plan is to turn the CSV file into a list of Book Objects that can then be manipulated to do things. I plan to shove the output of my stuff into a spreadsheet or something. I don't know.

The idea is less than a week old and it's already suffering from feature creep. ^_^


message 8: by [deleted user] (new)

Yaaay Github! Cool. Link when you do.

Oh dear. :P


message 9: by Geoff (new)

Geoff (geoffgreer) I'm interested to see what you get out of this.


message 10: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Geoff wrote: "I'm interested to see what you get out of this."

A lot less reading time this weekend :)


message 11: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
I spent way too much time on this already..and there is already a bug (due to comma's in some of the fields) ..But it's a start:

[main] INFO org.bookmagic.BookMagic - Book [title="The Drawing of the Three (Dark Tower, author=Contributor [firstName=, lastName=#2)", role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title="Wolves of the Calla (The Dark Tower #5)", author=Contributor [firstName="Stephen, lastName=King", role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title="Hamlet", author=Contributor [firstName="William, lastName=Shakespeare", role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title="Angels & Demons (Robert Langdon, author=Contributor [firstName=, lastName=#1)", role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title="The Broker", author=Contributor [firstName="John, lastName=Grisham", role=AUTHOR]]

I'll probably be switching to a 3rd party CSV parser this weekend..


message 12: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Man I love open source. quick google search and a pom update later and bam:

[main] INFO org.bookmagic.BookMagic - Book [title=The Broker, author=Contributor [firstName=John, lastName=Grisham, role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title=Harry Potter and the Order of the Phoenix (Harry Potter, #5), author=Contributor [firstName=J.K., lastName=Rowling, role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title=Cryptonomicon, author=Contributor [firstName=Neal, lastName=Stephenson, role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title=Snow Crash, author=Contributor [firstName=Neal, lastName=Stephenson, role=AUTHOR]]
[main] INFO org.bookmagic.BookMagic - Book [title=Harry Potter and the Half-Blood Prince (Harry Potter, #6), author=Contributor [firstName=J.K., lastName=Rowling, role=AUTHOR]]


message 13: by Sky (new)

Sky | 665 comments Nice!!!


message 14: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
So I'm still working on this, though I spent less time last weekend that I had expected to. I did put a good amount of time in yesterday and almost have it working as I'd like.

I'm still probably going to have to shove the output into a spreadsheet and do some manual editing though to get everything I want because of lack of data on Good Read's part.

The other option would be to add a GUI and maybe an embedded database to allow you to modify/enhance/save data.

The database piece should be simple enough..but I'm terrible at GUI. The last time I worked on one was like 10 years ago in Swing and I'm pretty terrible at it. I work in middleware and back end code for a reason.

I have no idea what people use these days. All of our stuff has a web interface rather than a thick client. Anyone any good with GUI?

Adding a GUI could potentially turn this from a bit of code for coders to use into a tool others can use.

Overall the main method and reporting functions need help too. Mostly because I'm terrible at output. I'm looking into a 3rd party library for formatting output.

So far I'm looking at j-text-utils but I'm not sure that will let me do exactly what I'm hoping for.

Anyways, hopefully I'll have the code to share sometime this coming weekend. Unless someone is just really dying for it, and I suppose I could consider uploading what I have in it's current state.


message 15: by Serendi (new)

Serendi | 828 comments Wandering through... Since you obviously already know, where can I find out about Goodread's export capabilities? I didn't know it had them.


message 16: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Serendi wrote: "Wandering through... Since you obviously already know, where can I find out about Goodread's export capabilities? I didn't know it had them."

https://www.goodreads.com/review/import

Then click the option that says: export to a csv file in the upper right hand side of the page.

Or here's a direct link: https://www.goodreads.com/review_port...

The direct link may take awhile depending on how much data you have, there is no options, it just starts generating the CSV file and will prompt you to save once it's ready.

No idea if any of this works on mobile. I've always done it from a computer.


message 17: by Sky (new)

Sky | 665 comments Back home! But unfortunately I haven't done GUI in 15 years. But I could write some rocking command line arguments for displaying parts of data, modifying, writing back in, or an interactive shell :) The other option is to be able to write back to CSV, modify it it in excel/open office/whatever, save that, and the reload it into your tool.


message 18: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
honestly, I'd be fine with a command line shell or something. I know(think?) spring has some kind of support for that, but it would be a lot more usable to non-tech folks if it had a GUI.

Maybe I'll ask our GUI guys if they know what is used for thick clients these days. I know Swing added some layouts that are meant to be done by tools, so maybe there is an eclipse plug-in or something to do simple GUI shit.

Apparently there is something called Java FX

Of course all this depends on me being motivated to add features for people who may not exist/would never know about the code.

It's probably easier to avoid a GUI unless someone volunteers to add one.


message 19: by Serendi (new)

Serendi | 828 comments Rob - Your first link is to import, not export.

Anywho, since I don't have any shelves, I have nothing to export. Interested to know the option exists, though. Thanks for the info!


message 20: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Serendi wrote: "Rob - Your first link is to import, not export."

I know, there is a link to export your data on the upper right of the page.

That's why I said: "Then click the option that says: export to a csv file in the upper right hand side of the page." immediately after that link. I wasn't sure if the direct link would work because there is no page to render.


message 21: by Serendi (new)

Serendi | 828 comments Oh. It didn't say that because I don't have any books to export; it said:

"Export Your Books
Once you’ve added some books, you can export and download a backup of your bookshelves."

...which I missed.

But yeah, if I'd paid a little more attention I would have seen it... Sorry about that, chief!


message 22: by Robyn (new)

Robyn | 115 comments I know(think?) spring has some kind of support for that, but it would be a lot more usable to non-tech folks if it had a GUI.

I have to admit I have no idea what's being in said in most of these comments, but would love to have the abilities you're writing the program to do, so if it is possible to make it clear to non-tech people, that would be awesome. (But not at the expense of reading time!)


message 23: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Haha. I definitely spent more time coding than reading on my day off yesterday.


message 24: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Well if last night is any indication, I may be putting this project on hold for a bit. We'll see. I'd still like to fix a few more things this weekend..but World of Warcraft apparently needed all of 5 minutes to get its hooks back into last night. With the new expansion today..well free time priorities are going to be shifted for awhile.

I did fix a bug or two last night while I was upgrading my video drivers.

At a minimum though I'll get it up on github if people want to take a look/make improvements.


message 25: by Sky (new)

Sky | 665 comments :) Thanks Rob, when you feel ready to throw it up on GitHub that'd be sweet.


message 26: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Well I'm not sure I'll ever be ready for that. There is a some sketchy code there. Some of it is largely dependent on how I shelve my books too.

In fact I'm going to fix some of my shelves and re-export to help the code do it's job a bit better.


message 27: by Sky (new)

Sky | 665 comments Nobody is ever truly ready to share their code :) Don't worry, I write the ugliest code in the world.


message 28: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Well not to sound arrogant, but my normal code is pretty good. This on the other hand has not had much testing and/or refinement.

I have a ton of TODOs and questions/notes to myself (others?) in comments scattered throughout the code.

It's also way over engineered. I have interfaces and abstract classes for things where it's probably not needed. Lol.

The idea was to to make it easier for other people to add their own implementations so they don't break mine or something. I dunno.


message 29: by [deleted user] (new)

Robyn wrote: "I know(think?) spring has some kind of support for that, but it would be a lot more usable to non-tech folks if it had a GUI.

I have to admit I have no idea what's being in said in most of these c..."

Hey Robyn, I teach programming to adults and have access to a lot of resources. If you want to begin the journey down the rabbit hole, just let me know!


message 30: by Sky (new)

Sky | 665 comments Rob wrote: "The idea was to to make it easier for other people to add their own implementations so they don't break mine or something. I dunno. "

Don't worry, we use fork and pull and you can be the final arbiter :)


message 31: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Oh I should also warn you I'm a git noob. I've been using SVN for almost 10 years. I only started using git in the last 6 months..and not well. lol.


message 32: by [deleted user] (new)

Rob wrote: "Oh I should also warn you I'm a git noob. I've been using SVN for almost 10 years. I only started using git in the last 6 months..and not well. lol."

Ahh! Some of my favourite things are git blame, git bisect, and branching. Branching's my love. <3


message 33: by Robyn (new)

Robyn | 115 comments Anja wrote: "Robyn wrote: "I know(think?) spring has some kind of support for that, but it would be a lot more usable to non-tech folks if it had a GUI.

I have to admit I have no idea what's being in said in m..."


That's a really lovely offer! Thank you. I'm pretty sure that my talents lie in other directions but when Rob posts this and I can't figure out how to make it work, I might very well ask for those resources.


message 34: by Rob, Roberator (last edited Nov 15, 2014 06:47AM) (new)

Rob (robzak) | 6719 comments Mod
OK, I posted what I have, but it's far from done. I'm not sure if I'll be doing any work on it in the near future, but figured I should at least share what I have so far.

https://github.com/robertzak/goodread...

I don't know anything on the licensing stuff, so I just randomly went with the apache one since I use so much of their stuff.

It's not exactly as if I'm concerned what people do with this code though.


message 35: by Sky (new)

Sky | 665 comments Sweet! Thanks Rob!


message 36: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
sure thing. hopefully it's useful to someone. wow was down this morning, so I made a few more fixes. lol.


message 37: by Trike (new)

Trike | 8180 comments Why are you playing WoW? You're a wizard in real life!


message 38: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Trike wrote: "Why are you playing WoW? You're a wizard in real life!"

Lol. My main is a rogue, but I pvp as a mage.


message 39: by Pris (new)

Pris (pnasrat) I'm happy to help out, main thing I notice is
ENOTEST
, and as discussed elsewhere there are some preconceptions on structure and personal filing which strikes me as less than desirable. There should be enough semantic information to tag books - but I guess you are avoiding using the API by just using the exported CSV rather than being able to query live.


message 40: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
I think some of what you posted got eaten as html or something..

I'm avoiding using the API because they make you jump through a ton of hoops to be able to do so. I did look into that.

If this was a serious app and not just something I did for fun one week I'd probably pursue it, but I'm not really that interested in doing that work on a toy app.

I originally wasn't even going to share the code, but some people were interested in it. You can happily fork it into something better and/or contribute it back if you're so inclined.

I did try to make a lot of the stuff extendable so implementations can be swapped out (ie replace my custom stuff that really only works with my data for something more generic, or at least works with someone else's data).

I'm sure there are a lot of things that can use help. I never really got much feed back from the initial posting and I think you're only the second person to actually look at the code. Possibly the first apart from myself.


message 41: by Pris (new)

Pris (pnasrat) It's cool I'll give some feedback via github - it may take some time as I have to jump through some hoops for any open source contribution.

Thanks for the code nonetheless.


message 42: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
I wish they made it easier to use the api, but I guess since you're accessing data based on user accounts and there are privacy settings associated with it, they rightfully want to be careful about how it's accessed.

No worries on the time, until my WoW time goes down again I'm not sure I'm going to be willing to spend much time on it. I will try to add at least a few basics to the readme though.

If nothing else I can copy/paste some of the stuff I've posted about it here.

Thanks for your interest!


message 43: by Trike (new)

Trike | 8180 comments I once programmed something in BASIC in 1985 and stopped there, so I have no idea how it works, but is it possible to do the shelving so that it's generic for anyone? Like a blank field that simply propagates based on the person's particular shelving peculiarities or something.

Use a magic wand or something, maybe. That's how it works here in the future, right?


message 44: by Pris (new)

Pris (pnasrat) The problem is for a general open source app - that is one that someone downloads the source and run there is friction as the user would have to apply for an API key and grant permissions. It'd be possible to use the library with a web site to give a better copy/paste output of the stats. I'll mull over, as once you've got something with a key you can probably at least bucket genre's based on goodread's perception.


message 45: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Trike wrote: "I once programmed something in BASIC in 1985 and stopped there, so I have no idea how it works, but is it possible to do the shelving so that it's generic for anyone? Like a blank field that simply..."

There are basically a few options as I see it..

1) Force everyone to shelve their books like I do
2) Add a GUI that lets you modify your data after importimg it
3) Find a more open book database and enrich a user's data by cross referencing by isbn.
4) Provide a way to export it back out to csv so it can be modified in a spreadsheet (which probably doesn't offer much over simply importing the original file)

Some combination of 2 & 3 would be my preference, but I'm terrible at GUI and I'm not sure what (if any) open book databases exist out there.


message 46: by John (Nevets) (new)

John (Nevets) Nevets (nevets) | 1531 comments I will probably be able to contribute zero other info to this thread. But my first thought about the DB was the Library of Congress, but that didn't work as well as I thought. But a very quick Google search of "ISBN database" turned out a couple of what appear to be good resources for the top two. If you decided to go down that road, I hope that helps.

I'll admit I'm probably not picky enough, or a heavy enough reader to want to do this with my own library, but I think it is really cool that some do.


message 47: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
Thanks John. I'll admit I hadn't looked into it myself. Another one of those things on the TODO list that got put off. lol.


message 48: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
With the year almost over I'm revisiting this for the first time in almost a year.

I made some minor improvements to the code, but it's still very custom to my own shelving system.

I'm trying to con(vince) a coworker that I discuss books with to help me with a GUI, but I don't think he's really excited by the idea. Alas. For now this is probably good enough for me unless I get someone else interested enough to make more serious tweaks.


message 49: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
With the year finally over I made some more tweaks to my GoodReads Parser Application.

The main new feature is reread support. This is something I've wanted to do for a bit because Goodreads doesn't handle rereads very well in my opinion.

I also added some extra error handling for the audiobook stuff. Goodreads doesn't really do audiobooks well either (which was another of my main reasons for the code). The best you can do is interpret page count as a duration rounded to the nearest hour. Often times this number is missing or wrong (ie someone puts in the hardcover page count instead of hours).

It's still not quite right though since I don't shelve books more than once and an audio reread may not counted as audio and therefore skew the number of pages read or if it is counted, it may be skewing my number of hours. I think it's the former, but I need to investigate. I may be forced to shelve books I've both read in text and reread in audio twice for the sake of better statistics. I just wish goodreads handled both audiobooks and rereads better.

Future plans include yearly comparisons (ie how many books/pages/etc I read in 2014 compared to 2015, etc). Maybe I'll tackle that next year unless I'm feeling inspired later this weekend. I suspect now that I have my 2015 report with rereads I won't spend more time on the code until I'm doing 2016's report.

If you're a Java coder (especially if you can do GUI) and would be interested in helping let me know. The biggest issues remaining that prevent turning this from something useful to just me to something useful for all goodread users is how heavily it relies on how I shelve my books and general usability for the non-programmers out there.

There isn't really much I can do about the shelving thing due to lack of data on goodreads part. Their book web pages seem to infer genres from stats on user shelving I think, or they have genre data that's simply not included in the CSV file. So tweaking the shelves and adding custom handling for data enrichment seems to be the best I can do. It's a lot of work for someone who's not as OCD about their shelves as I am though.

I never got around to investigating the library of congress database for the purposes of data enrichment. Maybe some day. That might allow me to overcome some of the relying on specific shelving of your books.

Adding a GUI letting users easily load a CSV file and generate one or more reports, modifying data, and saving it to a database would all be nice features to add. I can probably throw the stuff into SQLite pretty easily, but without a GUI making it easier to tweak the data, there is little point for me doing that.

Anyways, here's what this year's report looks like. I'm pretty happy with it overall.

As you can see I do 33% more books in audio as I do in text. I'm a pretty slow reader and in general I have a lot more audio time.

Year: 2015
Total Books: 110
Rereads: 5

********************
* Format Breakdown *
********************
Total EBOOK Count: 19
Total GRAPHIC_NOVEL Count: 11
Total AUDIO_BOOK Count: 61
Total BOOK Count: 19

*******************
* Genre Breakdown *
*******************
Total MYSTERY Count: 4
Total HORROR Count: 1
Total SCIFI Count: 35
Total HISTORICAL Count: 4
Total STEAMPUNK Count: 2
Total NONFICTION Count: 4
Total FANTASY Count: 60

Average Rating: 3.78
Total 2 Count: 5
Total 3 Count: 24
Total 4 Count: 71
Total 5 Count: 10

Number of Books: 49
Total Pages: 15371
Average Pages: 313.69

Number of Books (Excluding Graphic Novels): 38
Total Pages (Excluding Graphic Novels): 13740
Average Pages (Excluding Graphic Novels): 361.58

Number of Audiobooks: 61
Total Audio Hours: 1281
Average Hours: 21


message 50: by Rob, Roberator (new)

Rob (robzak) | 6719 comments Mod
I'm not sure if anyone is still interested in this project but I figured I'd post an update since I've made numerous changes since last year to my GoodReads Parser Application.

First and foremost I finally got a better Read Me going so it should be decent overview for anyone checking out the project.

I've also added support for author gender, but it's mostly another "hack" based on how I shelve my books. I added breakdowns for year and decade as well.

Finally I added a bunch of new report types and statistics. Most of the work was done in year-to-year comparisons, and adding percentages to to all the various counts. The year-to-year stuff compares things like Genre, read/listen quantity, book formats (ebook, physical, audio, graphic novels), author gender, decades published, and Goodreads ratings

Below you can see my report for 2016.

Year: 2016
Total Books: 90
Rereads: 8

********************
* Format Breakdown *
********************
Total AUDIO_BOOK Count: 54 (60.00%)
Total BOOK Count: 11 (12.22%)
Total EBOOK Count: 16 (17.78%)
Total GRAPHIC_NOVEL Count: 9 (10.00%)

*******************
* Genre Breakdown *
*******************
Total FANTASY Count: 42 (46.67%)
Total HISTORICAL Count: 5 (5.56%)
Total HORROR Count: 1 (1.11%)
Total HUMOR Count: 2 (2.22%)
Total MYSTERY Count: 3 (3.33%)
Total NONFICTION Count: 7 (7.78%)
Total STEAMPUNK Count: 2 (2.22%)
Total SCIFI Count: 24 (26.67%)
Total THRILLER Count: 4 (4.44%)

***************************
* Author Gender Breakdown *
***************************
Total MALE Count: 73 (81.11%)
Total FEMALE Count: 15 (16.67%)

Average Rating: 3.69
Total 2 Count: 5 (5.56%)
Total 3 Count: 25 (27.78%)
Total 4 Count: 53 (58.89%)
Total 5 Count: 7 (7.78%)

Years Published:
Total 1950 Count: 1 (1.11%)
Total 1958 Count: 1 (1.11%)
Total 1971 Count: 1 (1.11%)
Total 1973 Count: 1 (1.11%)
Total 1977 Count: 1 (1.11%)
Total 1985 Count: 1 (1.11%)
Total 1987 Count: 1 (1.11%)
Total 1989 Count: 2 (2.22%)
Total 1990 Count: 4 (4.44%)
Total 1991 Count: 2 (2.22%)
Total 1992 Count: 2 (2.22%)
Total 1993 Count: 2 (2.22%)
Total 1994 Count: 1 (1.11%)
Total 1995 Count: 1 (1.11%)
Total 1996 Count: 3 (3.33%)
Total 1999 Count: 1 (1.11%)
Total 2001 Count: 1 (1.11%)
Total 2004 Count: 1 (1.11%)
Total 2005 Count: 2 (2.22%)
Total 2006 Count: 2 (2.22%)
Total 2007 Count: 2 (2.22%)
Total 2009 Count: 1 (1.11%)
Total 2010 Count: 1 (1.11%)
Total 2011 Count: 3 (3.33%)
Total 2012 Count: 3 (3.33%)
Total 2013 Count: 3 (3.33%)
Total 2014 Count: 4 (4.44%)
Total 2015 Count: 12 (13.33%)
Total 2016 Count: 30 (33.33%)

Decade Published:
Total 1950 Count: 2 (2.22%)
Total 1970 Count: 3 (3.33%)
Total 1980 Count: 4 (4.44%)
Total 1990 Count: 16 (17.78%)
Total 2000 Count: 9 (10.00%)
Total 2010 Count: 56 (62.22%)

Number of Books: 36
Total Pages: 12364
Longest Book (Pages): 726
Average Pages: 343.44

Number of Books (Excluding Graphic Novels): 27
Total Pages (Excluding Graphic Novels): 10908
Average Pages (Excluding Graphic Novels): 404

Number of Audiobooks: 54
Total Audio Hours: 914
Longest Book (Hours): 42
Average Hours: 16.93


« previous 1
back to top