View Single Post
Old 10-07-2025, 03:17 PM   #11351
marshie250
Enthusiast
marshie250 began at the beginning.
 
Posts: 36
Karma: 10
Join Date: Jun 2019
Device: Kobo
Metadata collection and calculations

Hello everyone! No specific question here--just curious if anyone looks for the same things data-wise as I do and if so, how they collect it (especially if it's more efficient than how I do it). If you are not as obsessive, feel free to ignore!

I'm mostly concerned with tracking words read over the course of the year to see if I hit my reading goals. I track traditionally published books and fanfic in Calibre, which is handy. Word counts on tradpubs are easy, as it's just a simple count pages, but fanfic can be tricky with word counts changing with every update. First, I have an old-word-count column, which records the total word count the last time I marked a book as read (I use Action Chains for this). A separate column, #year-to-date, then takes this number and subtracts from it a year-start-word-count column, to return the total number of words read on that story that year:

Code:
#ytd
program:
(field ('#word')-field('#remaining')-field('#yearstart'))+(field ('#word')*field ('#reread'))
(I also have a column that I manually increase after a reread)

When a story updates, I have a third column, #remaining, which takes the new total word count and subtracts the old-word-count column to return the total number of words left to read in that book. This works well if a book updates more than once before I can read the new chapters, as the old-word-count column is not changed until the whole thing is marked as read.

Code:
#remaining
program:
if 'Yes' inlist field('#toread') then
	(field('#word')-field('#oldwords'))

fi
I then use Sum Column to tally that up every so often to see if I am on pace to meet 50-75k per day for the year.

I also like to track the pace at which a story updates, as I have a long TBR and it helps me figure out what to read next. That's a simple calculation in a column built from other columns:

Code:
#avpace
program:
if 'FanFiction' inlist field('tags') then
	if field('#chapters')==1 then
'0'
else
	if field('#chapters') then
	round(days_between(field('#updated'),field('pubdate'))/field('#chapters'))
	fi
fi
fi
which I then use to calculate when the next chapter might be posted (using 2 weeks as a default if there's only been one chapter):

Code:
#next
program:
	if 'In-Progress' inlist field('#status') then
		if field('#avpace')<1 then
			shorten(fractional_part(14-(days_between(today(), field('#updated')))),4,"",0)+(14-(days_between(today(), field('#updated')))-fractional_part(14-(days_between(today(), field('#updated')))))
			else
			shorten(fractional_part(field('#avpace')-(days_between(today(), field('#updated')))),4,"",0)+(field('#avpace')-(days_between(today(), field('#updated')))-fractional_part(field('#avpace')-(days_between(today(), field('#updated')))))				fi
	fi

I use the expected pace of a story to classify the status of the story (Extreme, Hiatus, Lapsed, and Updating) (with Completed and Dead not as a part of this equation, but also as classifications) (Names of the classifications had to be alphabetical as the tag browser automatically alphabetizes, and I wanted them to display in order).

Code:
#overdue
program:
	if 'In-Progress' inlist field('#status') then
		if field('#avpace')<1 then
		(((days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+15)))/(field('#avpace')+14)))
			else
			(((days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+1)))/(field('#avpace'))))
		fi
			fi
Code:
#HLevel
program:
	if 'Yes' inlist field('#toread') then 

				if 'Completed' inlist field('#status') then  
				'Completed'
				else
					if 'Dead' inlist field('#status') then  
					'Dead'
					else
						if 'In-Progress' inlist field('#status') then  
							if field('#avpace')<1 then
								if (days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+15)))/(field('#avpace')+14)<2 then
								"Updating"
								else
									if	(days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+15)))/(field('#avpace')+14)<5 then
									"Lapsed"
									else
										if (days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+15)))/(field('#avpace')+14)<10 then
										"Hiatus"
										else
										"Extreme"
										fi
									fi
								fi
							else
								if (days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+1)))/(field('#avpace'))<2 then
								"Updating"
								else
									if	(days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+1)))/(field('#avpace'))<5 then
									"Lapsed"
									else
										if	(days_between(today(), field('#updated'))-(days_between(today(), field('#updated'))/(field('#avpace')+1)))/(field('#avpace'))<10 then
										"Hiatus"
										else
										"Extreme"
										fi
									fi			
								fi
							fi
						fi
					
				fi
			fi
	fi
I can then calculate how often to check for updates (in case I missed subscribing to something), or how often to pull in updated metadata:

Code:
#update
program:
if 'FanFiction' inlist field('tags') then
if 'Update' inlist field('#errors') then
'Anthology Update'
else
	if days_between(today(), field('#lastchecked'))-1>0 then							
		if days_between(today(), field('#lastchecked'))-62>=0 then
			if 'Anthology' inlist field('tags') then
			'Anthology Update'
			else
			'Update'
			fi	
		else
			if 'Completed' inlist field('#status') then	
				if days_between(today(), field('#lastchecked'))-7>=0 then				
					if days_between(today(), field('#updated'))-7>=0 then		
						if 29-days_between(today(), field('#updated'))>=0 then				
							if 'Anthology' inlist field('tags') then
							'Anthology Update'
							else
							'Update'
							fi						
						fi
					fi
				fi
			else
				if 'Yes' inlist field('#approved') then		
				''
				else
					if (days_between(today(), field('#lastchecked')))-((days_between(today(), field('#updated'))/(field('#avpace')+2))+2+field('#avpace'))>=0 then
						if 'Anthology' inlist field('tags') then
						'Anthology Update'
						else
						'Update'
						fi
					else
						if 'Updating' inlist field('#hiatuslevel') then
							if (days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue'))))-(fractional_part(days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue')))))))>0 then
								if (days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue'))))-(fractional_part(days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue')))))))<2 then
									if 'Anthology' inlist field('tags') then
									'Anthology Update'
									else
									'Update'
									fi
								fi
							else
								if 'Lapsed' inlist field('#hiatuslevel') then
									if (days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue'))))-(fractional_part(days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue')))))))>0 then
										if (days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue'))))-(fractional_part(days_between(today(),field('#updated'))-(field('#avpace')*((field('#overdue'))-fractional_part(field('#overdue')))))))<2 then
											if 'Anthology' inlist field('tags') then
											'Anthology Update'
											else
											'Update'
											fi
										fi
									fi
								fi
							fi
						fi
					fi
				fi
			fi
		fi
	else							
		if field('#lastchecked') then						
			if days_between(today(), field('date'))-62>=0 then					
			'Meta'					
			else					
				if days_between(today(), field('date'))-7>=0 then		
					if days_between(today(), field('#updated'))-7>=0 then	
						if 29-days_between(today(), field('#updated'))>=0 then
						'Meta'
						fi
					fi	
				fi				
			fi					
		fi						
	fi																
fi
fi

If a story has also indicated an expected total of chapters, I like to calculate how long until the story is expected to be finished:

Code:
#expchap (yes there is a spelling error in this one but it was too entrenched by the time I noticed it)
program:
if '\?' inlist field('#chaptotal') then
	''
else
field('#exectedchaps')
fi


Code:
#completiondate
program:
if 'In-Progress' inlist field('#status') then
	if field('#expchap')>=1 then
	if field('#expchap')-field('#chapters')>=1 then
		if field('#avpace')>0 then
			if field('#overdue')>=1 then
			(field('#expchap')-(field('#chapters')+1))*(days_between(today(),field('pubdate'))/(field('#chapters')+1))
			else
			(field('#expchap')-field('#chapters'))*field('#avpace')-(fractional_part(field('#overdue'))*field('#avpace'))
			fi
		else
((field('#expchap')-(field('#chapters')+1))*(days_between(today(),field('pubdate'))/(field('#chapters')+1)))-(fractional_part(field('#overdue'))*(days_between(today(),field('pubdate'))/(field('#chapters')+1)))		
fi
fi
fi
fi

I also occasionally go onto the AO3 page for my fandoms and sort by kudos, then do a little math to calculate the top 1% and 10% of stories in the fandom (not to influence what I read, but just out of curiosity) and then do a column like this:

Code:
#Rank
program: 
if and('XXXXXX' inlist field('#fandom'),field('#kudos') >=780) then '1%' else
if and('XXXXXX' inlist field('#fandom'),field('#kudos') >=648) then '10%' else
Things I'm currently tinkering with: adding chapter updated dates and word counts to the html of each chapter (maybe using CustomOutputs?)--I don't want it displayed while reading, but I recently accidentally marked my entire library as read and it was a pain to recalculate everything. Would have been nice to be able to use that info.

Also, working on the Subscribed column--I only have it partially set up and can't remember why I stopped!

Ideally, it would be nice to mark if I left kudos/comments (even if only on a single chapter, as I imagine it would be confusing to see what chapters I left a comment on and which ones I missed).

Is any of this necessary? No. Did I know what I was doing when I set it up? Not really. I just like the challenge. But as I said, if you are collecting or calculating things I am not, or are doing something similar in a better way, I'd love to know!
marshie250 is offline   Reply With Quote