Graphe des relations d'ajout au groupe entre les membres du Million Project
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

facebook_schema.py 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. from datetime import datetime
  2. from typing import Any, List, Optional, Self
  3. from uuid import uuid4
  4. class AudioFile:
  5. uri: str
  6. creation_timestamp: int
  7. def __init__(self, uri: str, creation_timestamp: int):
  8. self.uri = uri
  9. self.creation_timestamp = creation_timestamp
  10. @classmethod
  11. def from_dict(cls, data: dict) -> Self:
  12. return cls(
  13. uri=data['uri'],
  14. creation_timestamp=data['creation_timestamp']
  15. )
  16. class Gif:
  17. uri: str
  18. def __init__(self, uri: str):
  19. self.uri = uri
  20. @classmethod
  21. def from_dict(cls, data: dict) -> Self:
  22. return cls(
  23. uri=data['uri']
  24. )
  25. class Photo:
  26. uri: str
  27. creation_timestamp: int
  28. def __init__(self, uri: str, creation_timestamp: int):
  29. self.uri = uri
  30. self.creation_timestamp = creation_timestamp
  31. @classmethod
  32. def from_dict(cls, data: dict) -> Self:
  33. return cls(
  34. uri=data['uri'],
  35. creation_timestamp=data['creation_timestamp']
  36. )
  37. class Reaction:
  38. reaction: str
  39. actor: str
  40. def __init__(self, reaction: str, actor: str):
  41. self.reaction = reaction
  42. self.actor = actor
  43. @classmethod
  44. def from_dict(cls, data: dict) -> Self:
  45. return cls(
  46. reaction=data['reaction'],
  47. actor=data['actor']
  48. )
  49. class Share:
  50. link: str
  51. share_text: str
  52. def __init__(self, link: str, share_text: str):
  53. self.link = link
  54. self.share_text = share_text
  55. @classmethod
  56. def from_dict(cls, data: dict) -> Self:
  57. return cls(
  58. link=data['link'],
  59. share_text=data['share_text']
  60. )
  61. class Sticker:
  62. uri: str
  63. ai_stickers: Optional[List[Any]]
  64. def __init__(self, uri: str, ai_stickers: Optional[List[Any]] = None):
  65. self.uri = uri
  66. self.ai_stickers = ai_stickers if ai_stickers is not None else []
  67. @classmethod
  68. def from_dict(cls, data: dict) -> Self:
  69. return cls(
  70. uri=data['uri'],
  71. ai_stickers=data.get('ai_stickers', [])
  72. )
  73. class Video:
  74. uri: str
  75. creation_timestamp: int
  76. def __init__(self, uri: str, creation_timestamp: int):
  77. self.uri = uri
  78. self.creation_timestamp = creation_timestamp
  79. @classmethod
  80. def from_dict(cls, data: dict) -> Self:
  81. return cls(
  82. uri=data['uri'],
  83. creation_timestamp=data['creation_timestamp']
  84. )
  85. class Message:
  86. sender_name: str
  87. date_time: datetime
  88. content: Optional[str]
  89. sticker: Optional[Sticker]
  90. share: Optional[Share]
  91. photos: Optional[List[Photo]]
  92. videos: Optional[List[Video]]
  93. gifs: Optional[List[Gif]]
  94. audio_files: Optional[List[AudioFile]]
  95. call_duration: Optional[int]
  96. reactions: Optional[List[Reaction]]
  97. is_unsent: Optional[bool]
  98. is_geoblocked_for_viewer: bool
  99. _id: str
  100. def __init__(self,
  101. sender_name: str,
  102. date_time: datetime,
  103. is_geoblocked_for_viewer: bool,
  104. content: Optional[str] = None,
  105. sticker: Optional[Sticker] = None,
  106. share: Optional[Share] = None,
  107. photos: Optional[List[Photo]] = None,
  108. videos: Optional[List[Video]] = None,
  109. gifs: Optional[List[Gif]] = None,
  110. audio_files: Optional[List[AudioFile]] = None,
  111. call_duration: Optional[int] = None,
  112. reactions: Optional[List[Reaction]] = None,
  113. is_unsent: Optional[bool] = None
  114. ):
  115. self.sender_name = sender_name
  116. self.date_time = date_time
  117. self.content = content
  118. self.sticker = sticker
  119. self.share = share
  120. self.photos = photos
  121. self.videos = videos
  122. self.gifs = gifs
  123. self.audio_files = audio_files
  124. self.call_duration = call_duration
  125. self.reactions = reactions
  126. self.is_unsent = is_unsent
  127. self.is_geoblocked_for_viewer = is_geoblocked_for_viewer
  128. self._id = str(uuid4())
  129. @property
  130. def message_id(self) -> str:
  131. return self._id
  132. @classmethod
  133. def from_dict(cls, data: dict) -> Self:
  134. _timestamp_ms = data.get('timestamp_ms')
  135. _sender_name = data.get('sender_name')
  136. _is_geoblocked_for_viewer = data.get('is_geoblocked_for_viewer')
  137. _content = data.get('content')
  138. _sticker_dict = data.get('sticker')
  139. _share_dict = data.get('share')
  140. _photos_dict = data.get('photos')
  141. _videos_dict = data.get('videos')
  142. _gifs_dict = data.get('gifs')
  143. _audio_files_dict = data.get('audio_files')
  144. _call_duration = data.get('call_duration')
  145. _reactions_dict = data.get('reactions')
  146. _is_unsent = data.get('is_unsent')
  147. _date_time = datetime.fromtimestamp(_timestamp_ms / 1000)
  148. _sticker = Sticker.from_dict(_sticker_dict) if _sticker_dict else None
  149. _share = Share.from_dict(_share_dict) if _share_dict else None
  150. _photos = [Photo.from_dict(photo) for photo in _photos_dict] if _photos_dict else None
  151. _videos = [Video.from_dict(video) for video in _videos_dict] if _videos_dict else None
  152. _gifs = [Gif.from_dict(gif) for gif in _gifs_dict] if _gifs_dict else None
  153. _audio_files = [AudioFile.from_dict(audio_file) for audio_file in _audio_files_dict] if _audio_files_dict else None
  154. _reactions = [Reaction.from_dict(reaction) for reaction in _reactions_dict] if _reactions_dict else None
  155. return cls(
  156. sender_name=_sender_name,
  157. date_time=_date_time,
  158. is_geoblocked_for_viewer=_is_geoblocked_for_viewer,
  159. content=_content,
  160. sticker=_sticker,
  161. share=_share,
  162. photos=_photos,
  163. videos=_videos,
  164. gifs=_gifs,
  165. audio_files=_audio_files,
  166. call_duration=_call_duration,
  167. reactions=_reactions,
  168. is_unsent=_is_unsent
  169. )
  170. class Image:
  171. creation_timestamp: int
  172. uri: str
  173. def __init__(self, creation_timestamp: int, uri: str):
  174. self.creation_timestamp = creation_timestamp
  175. self.uri = uri
  176. @classmethod
  177. def from_dict(cls, data: dict) -> Self:
  178. return cls(
  179. creation_timestamp=data['creation_timestamp'],
  180. uri=data['uri']
  181. )
  182. class JoinableMode:
  183. mode: int
  184. link: str
  185. def __init__(self, mode: int, link: str):
  186. self.mode = mode
  187. self.link = link
  188. @classmethod
  189. def from_dict(cls, data: dict) -> Self:
  190. return cls(
  191. mode=data['mode'],
  192. link=data['link']
  193. )
  194. class Participant:
  195. name: str
  196. def __init__(self, name: str) -> None:
  197. self.name = name
  198. @classmethod
  199. def from_dict(cls, data: dict) -> Self:
  200. return cls(
  201. name = data.get('name')
  202. )
  203. class FacebookExport:
  204. messages: List[Message]
  205. participants: List[Participant]
  206. title: str
  207. is_still_participant: bool
  208. thread_path: str
  209. magic_words: List[Any]
  210. image: Image
  211. joinable_mode: JoinableMode
  212. def __init__(self,
  213. messages: List[Message],
  214. participants: List[Participant],
  215. title: str,
  216. is_still_participant: bool,
  217. thread_path: str,
  218. magic_words: List[Any],
  219. image: Image,
  220. joinable_mode: JoinableMode):
  221. self.messages = messages
  222. self.participants = participants
  223. self.title = title
  224. self.is_still_participant = is_still_participant
  225. self.thread_path = thread_path
  226. self.magic_words = magic_words
  227. self.image = image
  228. self.joinable_mode = joinable_mode
  229. @classmethod
  230. def from_dict(cls, data: dict) -> Self:
  231. messages_data = data.get('messages', [])
  232. participants_data = data.get('participants', [])
  233. title = data['title']
  234. is_still_participant = data['is_still_participant']
  235. thread_path = data['thread_path']
  236. magic_words = data.get('magic_words', [])
  237. image = Image.from_dict(data['image'])
  238. joinable_mode = JoinableMode.from_dict(data['joinable_mode'])
  239. messages = [Message.from_dict(m) for m in messages_data]
  240. participants = {Participant.from_dict(p) for p in participants_data}
  241. return cls(
  242. messages=messages,
  243. participants=participants,
  244. title=title,
  245. is_still_participant=is_still_participant,
  246. thread_path=thread_path,
  247. magic_words=magic_words,
  248. image=image,
  249. joinable_mode=joinable_mode
  250. )