From cbfdcad6d222a01b5b1216a7e849d1e23a8f5cbb Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2016 10:05:57 +0000 Subject: [PATCH 1/5] Add a _settings field in the user table This will be used to store global user's settings --- diff --git a/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py b/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py new file mode 100644 index 0000000..ed77f87 --- /dev/null +++ b/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py @@ -0,0 +1,29 @@ +"""Create the _settings fields for user + +Revision ID: 5083efccac7 +Revises: 26af5c3602a0 +Create Date: 2016-10-13 16:21:08.716951 + +""" + +# revision identifiers, used by Alembic. +revision = '5083efccac7' +down_revision = '26af5c3602a0' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + ''' Add the column notifications to the table users. + ''' + op.add_column( + 'users', + sa.Column('_settings', sa.Text, nullable=True) + ) + + +def downgrade(): + ''' Add the column notifications to the table users. + ''' + op.drop_column('users', '_settings') diff --git a/pagure/lib/model.py b/pagure/lib/model.py index ba58a11..08851fa 100644 --- a/pagure/lib/model.py +++ b/pagure/lib/model.py @@ -177,6 +177,7 @@ class User(BASE): fullname = sa.Column(sa.String(255), nullable=False, index=True) public_ssh_key = sa.Column(sa.Text, nullable=True) default_email = sa.Column(sa.Text, nullable=False) + _settings = sa.Column(sa.Text, nullable=True) password = sa.Column(sa.Text, nullable=True) token = sa.Column(sa.String(50), nullable=True) @@ -210,6 +211,32 @@ class User(BASE): ''' Return the list of Group.group_name in which the user is. ''' return [group.group_name for group in self.group_objs] + @property + def settings(self): + """ Return the dict stored as string in the database as an actual + dict object. + """ + default = { + 'cc_me_to_my_actions': False, + } + + if self._settings: + current = json.loads(self._settings) + # Update the current dict with the new keys + for key in default: + if key not in current: + current[key] = default[key] + elif str(current[key]).lower() in ['true', 'y']: + current[key] = True + return current + else: + return default + + @settings.setter + def settings(self, settings): + ''' Ensures the settings are properly saved. ''' + self._settings = json.dumps(settings) + def __repr__(self): ''' Return a string representation of this object. ''' From b933a23abe39243c46c46e91198b2732902adc2d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2016 10:05:57 +0000 Subject: [PATCH 2/5] Add the possibility for the user to edit their settings in their settings page This allows turning on/off their settings as they wish --- diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 11f98f6..f27ba47 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -1441,6 +1441,32 @@ def update_project_settings(session, repo, settings, user): return 'Edited successfully settings of repo: %s' % repo.fullname +def update_user_settings(session, settings, user): + ''' Update the settings of a project. ''' + user_obj = get_user(session, user) + + update = [] + new_settings = user_obj.settings + for key in new_settings: + if key in settings: + if new_settings[key] != settings[key]: + update.append(key) + new_settings[key] = settings[key] + else: + update.append(key) + val = False + new_settings[key] = val + + if not update: + return 'No settings to change' + else: + user_obj.settings = new_settings + session.add(user_obj) + session.flush() + + return 'Successfully edited your settings' + + def fork_project(session, user, repo, gitfolder, docfolder, ticketfolder, requestfolder): ''' Fork a given project into the user's forks. ''' diff --git a/pagure/templates/user_settings.html b/pagure/templates/user_settings.html index 71c2a55..fe22f90 100644 --- a/pagure/templates/user_settings.html +++ b/pagure/templates/user_settings.html @@ -112,6 +112,42 @@ + + +
+
+ User settings +
+
+
+ {% for key in user.settings | sort %} + {% if user.settings[key] in [True, False, 'y'] %} +
+ +
+ {% else %} +
+ + +
+ {% endif %} + {% endfor %} + +

+ + {{ form.csrf_token }} +

+
+
+
+
{% if config.get('PAGURE_AUTH')=='local' %} Change password diff --git a/pagure/ui/app.py b/pagure/ui/app.py index 6f2f8f7..adef315 100644 --- a/pagure/ui/app.py +++ b/pagure/ui/app.py @@ -471,6 +471,49 @@ def user_settings(): form=form, ) +@APP.route('/settings/usersettings', methods=['POST']) +@login_required +def update_user_settings(): + """ Update the user's settings set in the settings page. + """ + if admin_session_timedout(): + if flask.request.method == 'POST': + flask.flash('Action canceled, try it again', 'error') + return flask.redirect( + flask.url_for('auth_login', next=flask.request.url)) + + + user = pagure.lib.search_user( + SESSION, username=flask.g.fas_user.username) + if not user: + flask.abort(404, 'User not found') + + form = pagure.forms.ConfirmationForm() + + if form.validate_on_submit(): + settings = {} + for key in flask.request.form: + if key == 'csrf_token': + continue + settings[key] = flask.request.form[key] + + try: + message = pagure.lib.update_user_settings( + SESSION, + settings=settings, + user=flask.g.fas_user.username, + ) + SESSION.commit() + flask.flash(message) + except pagure.exceptions.PagureException as msg: + SESSION.rollback() + flask.flash(msg, 'error') + except SQLAlchemyError as err: # pragma: no cover + SESSION.rollback() + flask.flash(str(err), 'error') + + return flask.redirect(flask.url_for('user_settings')) + @APP.route('/markdown/', methods=['POST']) def markdown_preview(): From 08cf01b635e683a4cbe90cf3121e3316307d6c2e Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2016 10:05:57 +0000 Subject: [PATCH 3/5] Notify user of their own action if they asked for it Fixes https://pagure.io/pagure/issue/1400 --- diff --git a/pagure/lib/notify.py b/pagure/lib/notify.py index 4f6ef18..190bd85 100644 --- a/pagure/lib/notify.py +++ b/pagure/lib/notify.py @@ -83,7 +83,9 @@ def _clean_emails(emails, user): This avoids receiving emails about action you do. ''' # Remove the user doing the action from the list of person to email - if user and user.emails: + # unless they actively asked for it + if user and user.emails \ + and not user.settings.get('cc_me_to_my_actions', False): for email in user.emails: if email.email in emails: emails.remove(email.email) From 711d5c4d1619c0eb8e276ec87453624a7ff404f1 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2016 10:05:57 +0000 Subject: [PATCH 4/5] Fix left over from copy/paste and code style error pointed out by @vivekanand1101 --- diff --git a/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py b/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py index ed77f87..c27af4a 100644 --- a/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py +++ b/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py @@ -15,7 +15,7 @@ import sqlalchemy as sa def upgrade(): - ''' Add the column notifications to the table users. + ''' Add the column _settings to the table users. ''' op.add_column( 'users', @@ -24,6 +24,6 @@ def upgrade(): def downgrade(): - ''' Add the column notifications to the table users. + ''' Add the column _settings to the table users. ''' op.drop_column('users', '_settings') diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index f27ba47..1cff0ab 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -1454,8 +1454,7 @@ def update_user_settings(session, settings, user): new_settings[key] = settings[key] else: update.append(key) - val = False - new_settings[key] = val + new_settings[key] = False if not update: return 'No settings to change' diff --git a/pagure/ui/app.py b/pagure/ui/app.py index adef315..3f99321 100644 --- a/pagure/ui/app.py +++ b/pagure/ui/app.py @@ -482,7 +482,6 @@ def update_user_settings(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) - user = pagure.lib.search_user( SESSION, username=flask.g.fas_user.username) if not user: From 499208743652741dc67b535610f8ff88e7045f78 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2016 10:20:40 +0000 Subject: [PATCH 5/5] Fix the docstring --- diff --git a/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py b/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py index c27af4a..4ff0e36 100644 --- a/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py +++ b/alembic/versions/5083efccac7_create_the__settings_fields_for_user.py @@ -24,6 +24,6 @@ def upgrade(): def downgrade(): - ''' Add the column _settings to the table users. + ''' Drop the column _settings to the table users. ''' op.drop_column('users', '_settings')