1
0

profile.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014-2016 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. from twisted.internet import defer
  16. from synapse.storage.roommember import ProfileInfo
  17. from synapse.api.errors import StoreError
  18. from ._base import SQLBaseStore
  19. class ProfileWorkerStore(SQLBaseStore):
  20. @defer.inlineCallbacks
  21. def get_profileinfo(self, user_localpart):
  22. try:
  23. profile = yield self._simple_select_one(
  24. table="profiles",
  25. keyvalues={"user_id": user_localpart},
  26. retcols=("displayname", "avatar_url"),
  27. desc="get_profileinfo",
  28. )
  29. except StoreError as e:
  30. if e.code == 404:
  31. # no match
  32. defer.returnValue(ProfileInfo(None, None))
  33. return
  34. else:
  35. raise
  36. defer.returnValue(
  37. ProfileInfo(
  38. avatar_url=profile['avatar_url'],
  39. display_name=profile['displayname'],
  40. )
  41. )
  42. def get_profile_displayname(self, user_localpart):
  43. return self._simple_select_one_onecol(
  44. table="profiles",
  45. keyvalues={"user_id": user_localpart},
  46. retcol="displayname",
  47. desc="get_profile_displayname",
  48. )
  49. def get_profile_avatar_url(self, user_localpart):
  50. return self._simple_select_one_onecol(
  51. table="profiles",
  52. keyvalues={"user_id": user_localpart},
  53. retcol="avatar_url",
  54. desc="get_profile_avatar_url",
  55. )
  56. def get_from_remote_profile_cache(self, user_id):
  57. return self._simple_select_one(
  58. table="remote_profile_cache",
  59. keyvalues={"user_id": user_id},
  60. retcols=("displayname", "avatar_url",),
  61. allow_none=True,
  62. desc="get_from_remote_profile_cache",
  63. )
  64. class ProfileStore(ProfileWorkerStore):
  65. def create_profile(self, user_localpart):
  66. return self._simple_insert(
  67. table="profiles",
  68. values={"user_id": user_localpart},
  69. desc="create_profile",
  70. )
  71. def set_profile_displayname(self, user_localpart, new_displayname):
  72. return self._simple_update_one(
  73. table="profiles",
  74. keyvalues={"user_id": user_localpart},
  75. updatevalues={"displayname": new_displayname},
  76. desc="set_profile_displayname",
  77. )
  78. def set_profile_avatar_url(self, user_localpart, new_avatar_url):
  79. return self._simple_update_one(
  80. table="profiles",
  81. keyvalues={"user_id": user_localpart},
  82. updatevalues={"avatar_url": new_avatar_url},
  83. desc="set_profile_avatar_url",
  84. )
  85. def add_remote_profile_cache(self, user_id, displayname, avatar_url):
  86. """Ensure we are caching the remote user's profiles.
  87. This should only be called when `is_subscribed_remote_profile_for_user`
  88. would return true for the user.
  89. """
  90. return self._simple_upsert(
  91. table="remote_profile_cache",
  92. keyvalues={"user_id": user_id},
  93. values={
  94. "displayname": displayname,
  95. "avatar_url": avatar_url,
  96. "last_check": self._clock.time_msec(),
  97. },
  98. desc="add_remote_profile_cache",
  99. )
  100. def update_remote_profile_cache(self, user_id, displayname, avatar_url):
  101. return self._simple_update(
  102. table="remote_profile_cache",
  103. keyvalues={"user_id": user_id},
  104. values={
  105. "displayname": displayname,
  106. "avatar_url": avatar_url,
  107. "last_check": self._clock.time_msec(),
  108. },
  109. desc="update_remote_profile_cache",
  110. )
  111. @defer.inlineCallbacks
  112. def maybe_delete_remote_profile_cache(self, user_id):
  113. """Check if we still care about the remote user's profile, and if we
  114. don't then remove their profile from the cache
  115. """
  116. subscribed = yield self.is_subscribed_remote_profile_for_user(user_id)
  117. if not subscribed:
  118. yield self._simple_delete(
  119. table="remote_profile_cache",
  120. keyvalues={"user_id": user_id},
  121. desc="delete_remote_profile_cache",
  122. )
  123. def get_remote_profile_cache_entries_that_expire(self, last_checked):
  124. """Get all users who haven't been checked since `last_checked`
  125. """
  126. def _get_remote_profile_cache_entries_that_expire_txn(txn):
  127. sql = """
  128. SELECT user_id, displayname, avatar_url
  129. FROM remote_profile_cache
  130. WHERE last_check < ?
  131. """
  132. txn.execute(sql, (last_checked,))
  133. return self.cursor_to_dict(txn)
  134. return self.runInteraction(
  135. "get_remote_profile_cache_entries_that_expire",
  136. _get_remote_profile_cache_entries_that_expire_txn,
  137. )
  138. @defer.inlineCallbacks
  139. def is_subscribed_remote_profile_for_user(self, user_id):
  140. """Check whether we are interested in a remote user's profile.
  141. """
  142. res = yield self._simple_select_one_onecol(
  143. table="group_users",
  144. keyvalues={"user_id": user_id},
  145. retcol="user_id",
  146. allow_none=True,
  147. desc="should_update_remote_profile_cache_for_user",
  148. )
  149. if res:
  150. defer.returnValue(True)
  151. res = yield self._simple_select_one_onecol(
  152. table="group_invites",
  153. keyvalues={"user_id": user_id},
  154. retcol="user_id",
  155. allow_none=True,
  156. desc="should_update_remote_profile_cache_for_user",
  157. )
  158. if res:
  159. defer.returnValue(True)