Calculate longest Stack Exchange streak Introduction
This challenge is inspired by the Meta Stack Exchange question The longest consecutive days streak; it turns out that the URL https://codegolf.stackexchange.com/users/daily-site-access/[user id], where the last number is your user ID (found in the URL of your profile) contains information about which days you visited the site, in the following format:
var visited = {2015:{6:{3:1,8:1,12:1,13:1,18:1,19:1,21:1,22:1,23:1,24:1,26:1},7:{7:1,8:1,9:1,10:1,11:1,12:1,14:1,16:1,19:1,21:1,23:1,27:1,28:1,29:1,30:1},8:{1:1,2:1,3:1,5:1,7:1,17:1,19:1,23:1,26:1,28:1,30:1},9:{5:1,6:1,7:1,14:1,22:1,25:1,29:1,30:1},10: ...

(When viewed in a browser, the document seems empty; try viewing the source instead. Unless you are a ♦ moderator, you can only see this information for your own account.)
The string has a rather peculiar format but presumably it's an easy way to populate the calendar:

The information can be used to calculate the longest consecutive days streak, i.e. the one that determines if you get the Fanatic badge. The linked question has a working JavaScript example by user @ShadowWizard.
Standard code-golf rules apply: the shortest code wins.
Input
A string with the exact format provided by Stack Exchange, e.g. {2015:{6:{3:1}}}. Top level keys are years, second level keys are months, third level keys are days. All values are 1. You may assume the dates are not earlier than July 31st, 2008, which is when the first Stack Overflow question was posted. You may also assume there's at least one day in the input; the information is only provided to registered users, who must have visited the site at least once.
Output
The length of the longest streak, i.e. consecutive days in the input. You may choose to return it as a number or a string.
Test cases
(besides your own streak on CGCC of course; you should be able to verify if you're eligible for the Enthusiast and Fanatic badges or not)




Input
Output




{2015:{6:{3:1}}}
1


{2015:{6:{3:1}},2016:{6:{3:1}}}
1


{2015:{6:{3:1},7:{3:1}}}
1


{2015:{6:{3:1,5:1}}}
1


{2015:{6:{3:1,4:1}}}
2


{2015:{2:{28:1},3:{1:1}}}
2


{2016:{2:{28:1},3:{1:1}}}
1


{2016:{1:{30:1},2:{1:1}}}
1


{2016:{4:{30:1},5:{1:1}}}
2


{2016:{4:{30:1},6:{1:1}}}
1


{2016:{12:{31:1}},2017:{1:{1:1}}}
2


{2016:{12:{31:1}},2018:{1:{1:1}}}
1


{2016:{11:{29:1},12:{30:1,31:1}},2017:{1:{1:1,2:1,4:1}}}
4


{2100:{2:{28:1},3:{1:1}}}
2


{2400:{2:{28:1},3:{1:1}}}
1
Python 2,  186 184 179 177 173 172  162 bytes
-10 thanks to ovs! (avoiding use of .items)

x=input()
from datetime import*
a=sorted(date(y,m,d)for y in x for m in x[y]for d in x[y][m])
print max(map(len,`[d+timedelta(1)in a for d in a*2]`.split('s')))/6

Try it online! Or see the test-suite.
Huh, how?
In Python 2 input implicitly attempts an eval on the string which, in this case, will produce a nested dictionary.
a is then a list of the dates in order (sorted(...)), this is formed by inspecting the nested dictionaries in a nested for loop, and passing the resulting parts of the dates to date(year, month, day).
[d+timedelta(1)in a for d in a*2] forms a list of booleans which identify whether the next date is present for each date in the sorted dates repeated twice, a*2.
Note that the final value of a will always be False. The reason for repeating a is to avoid something later (see the final paragraph).
`[...]` gets the Python string representation (AKA repr) of that list - for example, something like &quot;[False, True, True, False, False, False, True, True, False, False]&quot; for an input with three consecutive dates between two others.
.split('s') splits the resulting string at occurrences of the 's' character - so for the above, that would be ['[Fal', 'e, True, True, Fal', 'e, Fal', 'e, Fal', 'e, True, True, Fal', 'e, Fal', 'e]'].
map(len,...) simply gives us a list of the lengths of the strings in the above list - so for the above, that would be [4, 18, 6, 6, 18, 6, 2].
max(...) gives the maximum value of that list - so for the above, that would be 18.
To find the number of consecutive days we want to count how many Trues there were in that longest section and then add one. In the above example, we can simply divide by six (the length of either 'True, ' or 'e, Fal'), hence the /6 at the end.
If the longest run of consecutive dates is at the left of the sorted dates we'd get something like '[True, True, Fal' (or '[Fal' when no dates at all are consecutive), which would be two shy of what we need, so if we were to perform all of this across a rather than a*2 we'd need to add two before performing the integer division (e.g. (...+2)/6). This wouldn't affect any other results but costs one more byte than simply repeating a with a*2, whereupon we'll get the longer string later on - this is guaranteed by the fact that d+timedelta(1) for the maximal d will give False.