Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.39 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. from random import choice
  3. import json
  4. from sys import stderr
  5.  
  6. with open("bandersnatch.json") as f:
  7. bandersnatch = json.load(f)
  8.  
  9. with open("segmentmap.json") as f:
  10. smap = json.load(f)
  11.  
  12. initial_state = { "p_sp": True, "p_tt": True, "p_8a": False, "p_td": True, "p_cs": False, "p_w1": False, "p_2b": False, "p_3j": False, "p_pt": False, "p_cd": False, "p_cj": False, "p_sj": False, "p_sj2": False, "p_tud": False, "p_lsd": False, "p_vh": False, "p_3l": False, "p_3s": False, "p_3z": False, "p_ps": "n", "p_wb": False, "p_kd": False, "p_bo": False, "p_5v": False, "p_pc": "n", "p_sc": False, "p_ty": False, "p_cm": False, "p_pr": False, "p_3ad": False, "p_s3af": False, "p_nf": False, "p_np": False, "p_ne": False, "p_pp": False, "p_tp": False, "p_bup": False, "p_be": False, "p_pe": False, "p_pae": False, "p_te": False, "p_snt": False, "p_8j": False, "p_8d": False, "p_8m": False, "p_8q": False, "p_8s": False, "p_8v": False, "p_vs": "n", "p_scs": False, "p_3ab": False, "p_3ac": False, "p_3aj": False, "p_3ah": False, "p_3ak": False, "p_3al": False, "p_3af": False, "p_5h": False, "p_5ac": False, "p_5ag": False, "p_5ad": False, "p_6c": False, "length": 0 }
  13. state = dict(initial_state)
  14.  
  15. info = bandersnatch["videos"]["80988062"]["interactiveVideoMoments"]["value"]
  16. moments = info["momentsBySegment"]
  17. preconditions = info["preconditions"]
  18. segmentGroups = info["segmentGroups"]
  19. thumbnails = info["choicePointNavigatorMetadata"]["choicePointsMetadata"]["choicePoints"]
  20.  
  21. segmentMap = {}
  22. for segmentList in moments.values():
  23. for _segment in segmentList:
  24. for _choice in _segment.get("choices", []):
  25. if "segmentId" in _choice and "text" in _choice:
  26. segmentMap[_choice["segmentId"]] = _choice["text"].title()
  27.  
  28. def msToTS(ms):
  29. s,ms = divmod(ms,1000)
  30. m,s = divmod(s,60)
  31. h,m = divmod(m,60)
  32. return "{:02d}:{:02d}:{:02d}.{:03d}".format(h,m,s,ms)
  33.  
  34. def conditionHandler(cond):
  35. global state
  36. if not cond:
  37. return True
  38. if cond[0] == "persistentState":
  39. return state[cond[1]]
  40. if cond[0] == "not":
  41. return not all(conditionHandler(c) for c in cond[1:])
  42. if cond[0] == "and":
  43. return all(conditionHandler(c) for c in cond[1:])
  44. if cond[0] == "eql":
  45. return conditionHandler(cond[1]) == cond[2]
  46. if cond[0] == "or":
  47. return any(conditionHandler(c) for c in cond[1:])
  48.  
  49. def groupHandler(group, segment=None):
  50. out = []
  51. if segment:
  52. group.append(segment)
  53. for item in group:
  54. if type(item) is str and conditionHandler( preconditions.get(item,[]) ):
  55. out.append(item)
  56. if type(item) is dict:
  57. if "segmentGroup" in item:
  58. out += groupHandler(segmentGroups[item["segmentGroup"]])
  59. if "precondition" in item:
  60. if conditionHandler( preconditions.get(item["precondition"],[]) ):
  61. out.append(item["segment"])
  62. # print("out="+repr(out),file=stderr)
  63. return out
  64.  
  65.  
  66. def followTheStory(segment):
  67. global state
  68. global history
  69. possibilities = []
  70. if segment in moments:
  71. m = moments[segment]
  72. for moment in m:
  73. if moment["type"] == "notification:playbackImpression":
  74. state.update( moment.get("impressionData",{}).get("data", {}).get("persistent", {}) )
  75. if moment["type"] == "scene:cs_bs":
  76. for option in moment["choices"]:
  77. state.update( option.get("impressionData",{}).get("data", {}).get("persistent", {}) )
  78. if "segmentId" in option:
  79. p = groupHandler([option["segmentId"]])
  80. elif "sg" in option:
  81. p = groupHandler(segmentGroups[option["sg"]])
  82. elif moment["trackingInfo"]["optionType"] == "fakeOption":
  83. continue
  84. else:
  85. raise Exception(option["id"])
  86. possibilities += p
  87. if moment["type"] == "notification:action":
  88. possibilities.append(segment)
  89. if segment in segmentGroups:
  90. possibilities += groupHandler(segmentGroups[segment])
  91. # print("poss="+repr(possibilities),file=stderr)
  92. if not possibilities:
  93. # raise Exception("hoi")
  94. possibilities += groupHandler(segmentGroups["respawnOptions"])
  95. return choice(possibilities)
  96.  
  97. def get_segment_info(segment):
  98. _ = thumbnails.get(segment, {})
  99. return {"id": segment, "url": _["image"]["styles"]["backgroundImage"][4:-1] if "image" in _ else "", "caption": _.get("description", "No caption"), "chose": segmentMap.get(segment, "No caption ({})".format(segment))}
  100.  
  101. def bandersnatch():
  102. global state
  103. concat, options = [], []
  104. state = dict(initial_state)
  105. current_segment = "1A"
  106. while True:
  107. state["length"] += smap[current_segment]["endTimeMs"] - smap[current_segment]["startTimeMs"]
  108. if current_segment[:3].lower() == "0cr":
  109.  
  110. options.append(get_segment_info(current_segment))
  111. concat.append(current_segment)
  112.  
  113. options.append(get_segment_info("IDNT"))
  114. concat.append('IDNT')
  115.  
  116. state["length"] += 10
  117. break
  118. options.append(get_segment_info(current_segment))
  119. concat.append(current_segment)
  120. current_segment = followTheStory(current_segment)
  121. if current_segment is None:
  122. break
  123. return concat, options, msToTS(state["length"])
  124.  
  125. if __name__ == "__main__":
  126. print(bandersnatch(),file=stderr)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement