예제 #1
0
 def put(self):
     """
     ---
     description: Update user preferences
     requestBody:
       content:
         application/json:
           schema: UpdateUserPreferencesRequestJSON
           description: JSON describing updates to user preferences dict
     responses:
       200:
         content:
           application/json:
             schema: Success
       400:
         content:
           application/json:
             schema: Error
     """
     data = self.get_json()
     if 'preferences' not in data:
         return self.error(
             'Invalid request body: missing required "preferences" parameter'
         )
     preferences = data['preferences']
     # Do not save blank fields (empty strings)
     for k, v in preferences.items():
         if isinstance(v, dict):
             preferences[k] = {
                 key: val
                 for key, val in v.items() if val != ''
             }
     user_prefs = deepcopy(self.current_user.preferences)
     if not user_prefs:
         user_prefs = preferences
     else:
         user_prefs = recursive_update(user_prefs, preferences)
     self.current_user.preferences = user_prefs
     DBSession.add(self.current_user)
     DBSession.commit()
     if 'newsFeed' in preferences:
         self.push(action='skyportal/FETCH_NEWSFEED')
     if 'topSources' in preferences:
         self.push(action='skyportal/FETCH_TOP_SOURCES')
     return self.success(action="skyportal/FETCH_USER_PROFILE")
예제 #2
0
    def patch(self):
        """
        ---
        description: Update user preferences
        requestBody:
          content:
            application/json:
              schema:
                type: object
                properties:
                  username:
                    type: string
                    description: |
                      User's preferred user name
                  first_name:
                    type: string
                    description: |
                      User's preferred first name
                  last_name:
                    type: string
                    description: |
                       User's preferred last name
                  contact_email:
                    type: string
                    description: |
                       User's preferred email address
                  contact_phone:
                    type: string
                    description: |
                       User's preferred (international) phone number
                  preferences:
                    schema: UpdateUserPreferencesRequestJSON
                    description: JSON describing updates to user preferences dict
        responses:
          200:
            content:
              application/json:
                schema: Success
          400:
            content:
              application/json:
                schema: Error
        """
        data = self.get_json()
        user = User.query.get(self.current_user.id)
        current_username = self.current_user.username
        username_updated = False

        if data.get("username") is not None:
            username = data.pop("username").strip()
            if username == "":
                return self.error("Invalid username.")
            if len(username) < 5:
                return self.error(
                    "Username must be at least five characters long.")
            user.username = username
            if current_username != username:
                user_group = (DBSession().query(Group).filter(
                    Group.name == current_username).first())
                if user_group is not None:
                    user_group.name = slugify(username)
                username_updated = True

        if data.get("first_name") is not None:
            user.first_name = data.pop("first_name")

        if data.get("last_name") is not None:
            user.last_name = data.pop("last_name")

        if data.get("contact_phone") is not None:
            phone = data.pop("contact_phone")
            if phone not in [None, ""]:
                try:
                    if not phonenumbers.is_possible_number(
                            phonenumbers.parse(phone, "US")):
                        return self.error("Phone number given is not valid")
                except NumberParseException:
                    return self.error(
                        "Could not parse input as a phone number")
                user.contact_phone = phone
            else:
                user.contact_phone = None

        if data.get("contact_email") is not None:
            email = data.pop("contact_email")
            if email not in [None, ""]:
                if not validate_email(
                        email_address=email,
                        check_regex=True,
                        check_mx=False,
                        use_blacklist=True,
                        debug=False,
                ):
                    return self.error("Email does not appear to be valid")
                user.contact_email = email
            else:
                user.contact_email = None

        preferences = data.get("preferences", {})

        # Do not save blank fields (empty strings)
        for k, v in preferences.items():
            if isinstance(v, dict):
                preferences[k] = {
                    key: val
                    for key, val in v.items() if val != ""
                }
        user_prefs = deepcopy(user.preferences)
        if not user_prefs:
            user_prefs = preferences
        else:
            user_prefs = recursive_update(user_prefs, preferences)
        user.preferences = user_prefs

        try:
            DBSession.commit()
        except IntegrityError as e:
            if "duplicate key value violates unique constraint" in str(e):
                return self.error(
                    "Username already exists. Please try another username.")
            raise
        if "newsFeed" in preferences:
            self.push(action="skyportal/FETCH_NEWSFEED")
        if "topSources" in preferences:
            self.push(action="skyportal/FETCH_TOP_SOURCES")
        if "recentSources" in preferences:
            self.push(action="skyportal/FETCH_RECENT_SOURCES")
        if "sourceCounts" in preferences:
            self.push(action="skyportal/FETCH_SOURCE_COUNTS")
        if "weather" in preferences:
            self.push(action="skyportal/FETCH_WEATHER")

        if username_updated:
            self.push_all(action="skyportal/FETCH_GROUPS")
            self.push_all(action="skyportal/FETCH_USERS")

        return self.success(action="skyportal/FETCH_USER_PROFILE")