Example #1
0
    def post(self):
        """Post an item to the DB with the request.data JSON object.

        :arg self: The class of the object to be inserted
        :returns: The JSON item stored in the DB

        """
        try:
            cls_name = self.__class__.__name__
            data = None
            self.valid_args()
            data = self._file_upload(request)
            if data is None:
                data = json.loads(request.data)
            self._forbidden_attributes(data)
            inst = self._create_instance_from_request(data)
            repo = repos[self.__class__.__name__]['repo']
            save_func = repos[self.__class__.__name__]['save']
            getattr(repo, save_func)(inst)
            self._log_changes(None, inst)
            self.refresh_cache(cls_name, inst.id)
            json_response = json.dumps(inst.dictize())
            return Response(json_response, mimetype='application/json')
        except Exception as e:
            content_type = request.headers.get('Content-Type')
            if (cls_name == 'TaskRun' and 'multipart/form-data' in content_type
                    and data):
                uploader.delete_file(data['info']['file_name'],
                                     data['info']['container'])
            return error.format_exception(
                e, target=self.__class__.__name__.lower(), action='POST')
Example #2
0
def _handle_avatar_update(user, avatar_form):
    if avatar_form.validate_on_submit():
        _file = request.files['avatar']
        coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                       avatar_form.x2.data, avatar_form.y2.data)
        prefix = time.time()
        _file.filename = "%s_avatar.png" % prefix
        container = "user_%s" % user.id
        uploader.upload_file(_file,
                             container=container,
                             coordinates=coordinates)
        # Delete previous avatar from storage
        if user.info.get('avatar'):
            uploader.delete_file(user.info['avatar'], container)
        upload_method = current_app.config.get('UPLOAD_METHOD')
        avatar_url = get_avatar_url(upload_method,
                                    _file.filename, container)
        user.info['avatar'] = _file.filename
        user.info['container'] = container
        user.info['avatar_url'] = avatar_url
        user_repo.update(user)
        cached_users.delete_user_summary(user.name)
        flash(gettext('Your avatar has been updated! It may \
                      take some minutes to refresh...'), 'success')
        return True
    else:
        flash("You have to provide an image file to update your avatar", "error")
        return False
Example #3
0
def _handle_avatar_update(user, avatar_form):
    if avatar_form.validate_on_submit():
        _file = request.files['avatar']
        coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                       avatar_form.x2.data, avatar_form.y2.data)
        prefix = time.time()
        _file.filename = "%s_avatar.png" % prefix
        container = "user_%s" % user.id
        uploader.upload_file(_file,
                             container=container,
                             coordinates=coordinates)
        # Delete previous avatar from storage
        if user.info.get('avatar'):
            uploader.delete_file(user.info['avatar'], container)
        upload_method = current_app.config.get('UPLOAD_METHOD')
        avatar_url = get_avatar_url(upload_method, _file.filename, container)
        user.info['avatar'] = _file.filename
        user.info['container'] = container
        user.info['avatar_url'] = avatar_url
        user_repo.update(user)
        cached_users.delete_user_summary(user.name)
        flash(
            gettext('Your avatar has been updated! It may \
                      take some minutes to refresh...'), 'success')
        return True
    else:
        flash("You have to provide an image file to update your avatar",
              "error")
        return False
Example #4
0
def delete_account(user_id, admin_addr, **kwargs):
    """Delete user account from the system."""
    from pybossa.core import (user_repo, uploader)
    user = user_repo.get(user_id)

    container = "user_%s" % user.id
    if user.info.get('avatar'):
        uploader.delete_file(user.info['avatar'], container)

    email = user.email_addr
    if current_app.config.get('MAILCHIMP_API_KEY'):
        from pybossa.core import newsletter
        newsletter.init_app(current_app)
        mailchimp_deleted = newsletter.delete_user(email)
    else:
        mailchimp_deleted = True
    brand = current_app.config.get('BRAND')
    user_repo.delete_data(user)
    subject = '[%s]: Your account has been deleted' % brand
    body = """Hi,\n Your account and personal data has been deleted from %s.""" % brand
    if not mailchimp_deleted:
        body += '\nWe could not delete your Mailchimp account, please contact us to fix this issue.'
    if current_app.config.get('DISQUS_SECRET_KEY'):
        body += '\nDisqus does not provide an API method to delete your account. You will have to do it by hand yourself in the disqus.com site.'
    recipients = [email]
    bcc = [admin_addr]
    mail_dict = dict(recipients=recipients, bcc=bcc, subject=subject, body=body)
    send_mail(mail_dict, mail_all=True)
Example #5
0
 def _file_delete(self, request, obj):
     """Delete file from obj."""
     keys = obj.info.keys()
     if 'file_name' in keys and 'container' in keys:
         ensure_authorized_to('delete', obj)
         uploader.delete_file(obj.info['file_name'],
                              obj.info['container'])
Example #6
0
 def _file_delete(self, request, obj):
     """Delete file object."""
     cls_name = self.__class__.__name__.lower()
     if cls_name in self.allowed_classes_upload:
         keys = obj.info.keys()
         if 'file_name' in keys and 'container' in keys:
             ensure_authorized_to('delete', obj)
             uploader.delete_file(obj.info['file_name'],
                                  obj.info['container'])
Example #7
0
 def _file_delete(self, request, obj):
     """Delete file object."""
     cls_name = self.__class__.__name__.lower()
     if cls_name in self.allowed_classes_upload:
         keys = obj.info.keys()
         if 'file_name' in keys and 'container' in keys:
             ensure_authorized_to('delete', obj)
             uploader.delete_file(obj.info['file_name'],
                                  obj.info['container'])
Example #8
0
 def _delete_zip_files_from_store(self, project):
     from pybossa.core import json_exporter, csv_exporter
     global uploader
     if uploader is None:
         from pybossa.core import uploader
     json_tasks_filename = json_exporter.download_name(project, 'task')
     csv_tasks_filename = csv_exporter.download_name(project, 'task')
     json_taskruns_filename = json_exporter.download_name(project, 'task_run')
     csv_taskruns_filename = csv_exporter.download_name(project, 'task_run')
     container = "user_%s" % project.owner_id
     uploader.delete_file(json_tasks_filename, container)
     uploader.delete_file(csv_tasks_filename, container)
     uploader.delete_file(json_taskruns_filename, container)
     uploader.delete_file(csv_taskruns_filename, container)
 def _delete_zip_files_from_store(self, project):
     from pybossa.core import json_exporter, csv_exporter
     global uploader
     if uploader is None:
         from pybossa.core import uploader
     json_tasks_filename = json_exporter.download_name(project, 'task')
     csv_tasks_filename = csv_exporter.download_name(project, 'task')
     json_taskruns_filename = json_exporter.download_name(project, 'task_run')
     csv_taskruns_filename = csv_exporter.download_name(project, 'task_run')
     container = "user_%s" % project.owner_id
     uploader.delete_file(json_tasks_filename, container)
     uploader.delete_file(csv_tasks_filename, container)
     uploader.delete_file(json_taskruns_filename, container)
     uploader.delete_file(csv_taskruns_filename, container)
def _handle_avatar_update(user, avatar_form):
    if avatar_form.validate_on_submit():
        _file = request.files['avatar']
        coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                       avatar_form.x2.data, avatar_form.y2.data)
        prefix = time.time()
        _file.filename = "%s_avatar.png" % prefix
        container = "user_%s" % user.id
        uploader.upload_file(_file,
                             container=container,
                             coordinates=coordinates)
        # Delete previous avatar from storage
        if user.info.get('avatar'):
            uploader.delete_file(user.info['avatar'], container)
        user.info = {'avatar': _file.filename,
                             'container': container}
        user_repo.update(user)
        cached_users.delete_user_summary(user.name)
        flash(gettext('Your avatar has been updated! It may \
                      take some minutes to refresh...'), 'success')
    else:
        flash("You have to provide an image file to update your avatar", "error")
Example #11
0
def _handle_avatar_update(user, avatar_form):
    if avatar_form.validate_on_submit():
        _file = request.files['avatar']
        coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                       avatar_form.x2.data, avatar_form.y2.data)
        prefix = time.time()
        _file.filename = "%s_avatar.png" % prefix
        container = "user_%s" % user.id
        uploader.upload_file(_file,
                             container=container,
                             coordinates=coordinates)
        # Delete previous avatar from storage
        if user.info.get('avatar'):
            uploader.delete_file(user.info['avatar'], container)
        user.info = {'avatar': _file.filename,
                             'container': container}
        user_repo.update(user)
        cached_users.delete_user_summary(user.name)
        flash(gettext('Your avatar has been updated! It may \
                      take some minutes to refresh...'), 'success')
    else:
        flash("You have to provide an image file to update your avatar", "error")
Example #12
0
    def _make_zipfile(self, project, obj, file_format, obj_generator, expanded=False):
        """Generate a ZIP of a certain type and upload it.

        :param project: A project object
        :param obj: The domain object to be exported
        :param file_format: The file format of the export
        :param obj_generator: A generator object containing
            the data to be written to file
        :param expanded: Boolean indicating whether or not
            relevant object metadata should be included
            in the export

        :return: The path where the .zip file is saved
        """
        name = self._project_name_latin_encoded(project)
        if obj_generator is not None:
            with tempfile.NamedTemporaryFile() as datafile:
                for line in obj_generator:
                    datafile.write(str(line))
                datafile.flush()
                obj_generator.close()

                with tempfile.NamedTemporaryFile() as zipped_datafile:
                    with self._zip_factory(zipped_datafile.name) as _zip:
                        _zip.write(datafile.name,
                                   secure_filename('{0}_{1}.{2}'
                                                   .format(name, obj, file_format)))
                        _zip.content_type = 'application/zip'

                    filename = self.download_name(project, obj)
                    zip_file = FileStorage(filename=filename,
                                           stream=zipped_datafile)

                    container = self._container(project)
                    if uploader.file_exists(filename, container):
                        assert uploader.delete_file(filename, container)
                    uploader.upload_file(zip_file, container=container)

                    if isinstance(uploader, local.LocalUploader):
                        path = uploader.get_file_path(container, filename)
                    else:
                        path = None

                    return path
Example #13
0
def update_profile():
    """
    Update user's profile.

    Returns Jinja2 template.

    """
    form = UpdateProfileForm()
    upload_form = AvatarUploadForm()
    if request.method == 'GET':
        form = UpdateProfileForm(obj=current_user)
        form.set_locales(current_app.config['LOCALES'])
        form.populate_obj(current_user)

        title_msg = "Update your profile: %s" % current_user.fullname
        return render_template('account/update.html',
                               title=title_msg,
                               form=form,
                               upload_form=upload_form)
    else:
        form = UpdateProfileForm(request.form)
        upload_form = AvatarUploadForm(request.form)
        form.set_locales(current_app.config['LOCALES'])
        if request.form['btn'] == 'Upload':
            avatar = request.files['avatar']
            extension = avatar.filename.rsplit(".")[1]
            coordinates = (upload_form.x1.data, upload_form.y1.data,
                           upload_form.x2.data, upload_form.y2.data)
            prefix = time.time()
            avatar.filename = "%s_avatar.%s" % (prefix, extension)
            container = "user_%s" % current_user.id
            uploader.upload_file(avatar,
                                 container=container,
                                 coordinates=coordinates)
            # Delete previous avatar from storage
            if 'avatar' in current_user.info:
              uploader.delete_file(current_user.info['avatar'], container)
            current_user.info = {'avatar': avatar.filename,
                                 'container': container}
            db.session.commit()
            cached_users.delete_user_summary(current_user.name)
            flash(gettext('Your avatar has been updated! It may \
                          take some minutes to refresh...'), 'success')
            return redirect(url_for('.profile'))
        else:
            if form.validate():
                current_user.id = form.id.data
                current_user.fullname = form.fullname.data
                current_user.name = form.name.data
                current_user.email_addr = form.email_addr.data
                current_user.ckan_api = form.ckan_api.data
                current_user.privacy_mode = form.privacy_mode.data
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(url_for('.profile'))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % current_user.fullname
                return render_template('/account/update.html', form=form,
                                       upload_form=upload_form,
                                       title=title_msg)
Example #14
0
def update_profile(name):
    """
    Update user's profile.

    Returns Jinja2 template.

    """
    user = User.query.filter_by(name=name).first()
    if not user:
        return abort(404)
    require.user.update(user)
    show_passwd_form = True
    if user.twitter_user_id or user.google_user_id or user.facebook_user_id:
        show_passwd_form = False
    usr = cached_users.get_user_summary(name)
    # Extend the values
    current_user.rank = usr.get('rank')
    current_user.score = usr.get('score')
    # Title page
    title_msg = "Update your profile: %s" % current_user.fullname
    # Creation of forms
    update_form = UpdateProfileForm(obj=user)
    update_form.set_locales(current_app.config['LOCALES'])
    avatar_form = AvatarUploadForm()
    password_form = ChangePasswordForm()
    external_form = update_form


    if request.method == 'GET':
        return render_template('account/update.html',
                               title=title_msg,
                               user=usr,
                               form=update_form,
                               upload_form=avatar_form,
                               password_form=password_form,
                               external_form=external_form,
                               show_passwd_form=show_passwd_form)
    else:
        # Update user avatar
        if request.form.get('btn') == 'Upload':
            avatar_form = AvatarUploadForm()
            if avatar_form.validate_on_submit():
                file = request.files['avatar']
                coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                               avatar_form.x2.data, avatar_form.y2.data)
                prefix = time.time()
                file.filename = "%s_avatar.png" % prefix
                container = "user_%s" % current_user.id
                uploader.upload_file(file,
                                     container=container,
                                     coordinates=coordinates)
                # Delete previous avatar from storage
                if current_user.info.get('avatar'):
                    uploader.delete_file(current_user.info['avatar'], container)
                current_user.info = {'avatar': file.filename,
                                     'container': container}
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(gettext('Your avatar has been updated! It may \
                              take some minutes to refresh...'), 'success')
                return redirect(url_for('.update_profile', name=current_user.name))
            else:
                flash("You have to provide an image file to update your avatar",
                      "error")
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Update user profile
        elif request.form.get('btn') == 'Profile':
            update_form = UpdateProfileForm()
            update_form.set_locales(current_app.config['LOCALES'])
            if update_form.validate():
                current_user.id = update_form.id.data
                current_user.fullname = update_form.fullname.data
                current_user.name = update_form.name.data
                current_user.email_addr = update_form.email_addr.data
                current_user.privacy_mode = update_form.privacy_mode.data
                current_user.locale = update_form.locale.data
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(url_for('.update_profile', name=current_user.name))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % current_user.fullname
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)

        # Update user password
        elif request.form.get('btn') == 'Password':
            # Update the data because passing it in the constructor does not work
            update_form.name.data = user.name
            update_form.fullname.data = user.fullname
            update_form.email_addr.data = user.email_addr
            update_form.ckan_api.data = user.ckan_api
            external_form = update_form
            if password_form.validate_on_submit():
                user = db.session.query(model.user.User).get(current_user.id)
                if user.check_password(password_form.current_password.data):
                    user.set_password(password_form.new_password.data)
                    db.session.add(user)
                    db.session.commit()
                    flash(gettext('Yay, you changed your password succesfully!'),
                          'success')
                    return redirect(url_for('.update_profile', name=name))
                else:
                    msg = gettext("Your current password doesn't match the "
                                  "one in our records")
                    flash(msg, 'error')
                    return render_template('/account/update.html',
                                           form=update_form,
                                           upload_form=avatar_form,
                                           password_form=password_form,
                                           external_form=external_form,
                                           title=title_msg,
                                           show_passwd_form=show_passwd_form)
            else:
                flash(gettext('Please correct the errors'), 'error')
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Update user external services
        elif request.form.get('btn') == 'External':
            del external_form.locale
            del external_form.email_addr
            del external_form.fullname
            del external_form.name
            if external_form.validate():
                current_user.ckan_api = external_form.ckan_api.data or None
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(url_for('.update_profile', name=current_user.name))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % current_user.fullname
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Otherwise return 415
        else:
            return abort(415)
Example #15
0
def update_profile(name):
    """
    Update user's profile.

    Returns Jinja2 template.

    """
    user = User.query.filter_by(name=name).first()
    if not user:
        return abort(404)
    require.user.update(user)
    show_passwd_form = True
    if user.twitter_user_id or user.google_user_id or user.facebook_user_id:
        show_passwd_form = False
    usr = cached_users.get_user_summary(name)
    # Extend the values
    current_user.rank = usr.get('rank')
    current_user.score = usr.get('score')
    # Title page
    title_msg = "Update your profile: %s" % current_user.fullname
    # Creation of forms
    update_form = UpdateProfileForm(obj=user)
    update_form.set_locales(current_app.config['LOCALES'])
    avatar_form = AvatarUploadForm()
    password_form = ChangePasswordForm()
    external_form = update_form

    if request.method == 'GET':
        return render_template('account/update.html',
                               title=title_msg,
                               user=usr,
                               form=update_form,
                               upload_form=avatar_form,
                               password_form=password_form,
                               external_form=external_form,
                               show_passwd_form=show_passwd_form)
    else:
        # Update user avatar
        if request.form.get('btn') == 'Upload':
            avatar_form = AvatarUploadForm()
            if avatar_form.validate_on_submit():
                file = request.files['avatar']
                coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                               avatar_form.x2.data, avatar_form.y2.data)
                prefix = time.time()
                file.filename = "%s_avatar.png" % prefix
                container = "user_%s" % current_user.id
                uploader.upload_file(file,
                                     container=container,
                                     coordinates=coordinates)
                # Delete previous avatar from storage
                if current_user.info.get('avatar'):
                    uploader.delete_file(current_user.info['avatar'],
                                         container)
                current_user.info = {
                    'avatar': file.filename,
                    'container': container
                }
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(
                    gettext('Your avatar has been updated! It may \
                              take some minutes to refresh...'), 'success')
                return redirect(
                    url_for('.update_profile', name=current_user.name))
            else:
                flash(
                    "You have to provide an image file to update your avatar",
                    "error")
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Update user profile
        elif request.form.get('btn') == 'Profile':
            update_form = UpdateProfileForm()
            update_form.set_locales(current_app.config['LOCALES'])
            if update_form.validate():
                current_user.id = update_form.id.data
                current_user.fullname = update_form.fullname.data
                current_user.name = update_form.name.data
                current_user.email_addr = update_form.email_addr.data
                current_user.privacy_mode = update_form.privacy_mode.data
                current_user.locale = update_form.locale.data
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(
                    url_for('.update_profile', name=current_user.name))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % current_user.fullname
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)

        # Update user password
        elif request.form.get('btn') == 'Password':
            # Update the data because passing it in the constructor does not work
            update_form.name.data = user.name
            update_form.fullname.data = user.fullname
            update_form.email_addr.data = user.email_addr
            update_form.ckan_api.data = user.ckan_api
            external_form = update_form
            if password_form.validate_on_submit():
                user = db.session.query(model.user.User).get(current_user.id)
                if user.check_password(password_form.current_password.data):
                    user.set_password(password_form.new_password.data)
                    db.session.add(user)
                    db.session.commit()
                    flash(
                        gettext('Yay, you changed your password succesfully!'),
                        'success')
                    return redirect(url_for('.update_profile', name=name))
                else:
                    msg = gettext("Your current password doesn't match the "
                                  "one in our records")
                    flash(msg, 'error')
                    return render_template('/account/update.html',
                                           form=update_form,
                                           upload_form=avatar_form,
                                           password_form=password_form,
                                           external_form=external_form,
                                           title=title_msg,
                                           show_passwd_form=show_passwd_form)
            else:
                flash(gettext('Please correct the errors'), 'error')
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Update user external services
        elif request.form.get('btn') == 'External':
            del external_form.locale
            del external_form.email_addr
            del external_form.fullname
            del external_form.name
            if external_form.validate():
                current_user.ckan_api = external_form.ckan_api.data or None
                db.session.commit()
                cached_users.delete_user_summary(current_user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(
                    url_for('.update_profile', name=current_user.name))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % current_user.fullname
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Otherwise return 415
        else:
            return abort(415)
Example #16
0
def delete_file(fname, container):
    """Delete file."""
    from pybossa.core import uploader
    return uploader.delete_file(fname, container)
Example #17
0
 def delete_existing_zip(self, project, ty):
     """Delete existing ZIP from uploads directory"""
     filename = self.download_name(project, ty)
     if uploader.file_exists(filename, self._container(project)):
         assert uploader.delete_file(filename, self._container(project))
Example #18
0
def update_profile(name):
    """
    Update user's profile.

    Returns Jinja2 template.

    """
    user = user_repo.get_by_name(name)
    if not user:
        return abort(404)
    require.user.update(user)
    show_passwd_form = True
    if user.twitter_user_id or user.google_user_id or user.facebook_user_id:
        show_passwd_form = False
    usr = cached_users.get_user_summary(name)
    # Extend the values
    user.rank = usr.get('rank')
    user.score = usr.get('score')
    # Title page
    title_msg = "Update your profile: %s" % user.fullname
    # Creation of forms
    update_form = UpdateProfileForm(obj=user)
    update_form.set_locales(current_app.config['LOCALES'])
    avatar_form = AvatarUploadForm()
    password_form = ChangePasswordForm()
    external_form = update_form

    if request.method == 'GET':
        return render_template('account/update.html',
                               title=title_msg,
                               user=usr,
                               form=update_form,
                               upload_form=avatar_form,
                               password_form=password_form,
                               external_form=external_form,
                               show_passwd_form=show_passwd_form)
    else:
        acc_conf_dis = current_app.config.get('ACCOUNT_CONFIRMATION_DISABLED')
        # Update user avatar
        if request.form.get('btn') == 'Upload':
            avatar_form = AvatarUploadForm()
            if avatar_form.validate_on_submit():
                file = request.files['avatar']
                coordinates = (avatar_form.x1.data, avatar_form.y1.data,
                               avatar_form.x2.data, avatar_form.y2.data)
                prefix = time.time()
                file.filename = "%s_avatar.png" % prefix
                container = "user_%s" % user.id
                uploader.upload_file(file,
                                     container=container,
                                     coordinates=coordinates)
                # Delete previous avatar from storage
                if user.info.get('avatar'):
                    uploader.delete_file(user.info['avatar'], container)
                user.info = {'avatar': file.filename, 'container': container}
                user_repo.update(user)
                cached_users.delete_user_summary(user.name)
                flash(
                    gettext('Your avatar has been updated! It may \
                              take some minutes to refresh...'), 'success')
                return redirect(url_for('.update_profile', name=user.name))
            else:
                flash(
                    "You have to provide an image file to update your avatar",
                    "error")
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Update user profile
        elif request.form.get('btn') == 'Profile':
            update_form = UpdateProfileForm()
            update_form.set_locales(current_app.config['LOCALES'])
            if update_form.validate():
                user.id = update_form.id.data
                user.fullname = update_form.fullname.data
                user.name = update_form.name.data
                if (user.email_addr != update_form.email_addr.data
                        and acc_conf_dis is False):
                    user.valid_email = False
                    user.newsletter_prompted = False
                    account = dict(fullname=update_form.fullname.data,
                                   name=update_form.name.data,
                                   email_addr=update_form.email_addr.data)
                    confirm_url = get_email_confirmation_url(account)
                    subject = ('You have updated your email in %s! Verify it' \
                               % current_app.config.get('BRAND'))
                    msg = dict(subject=subject,
                               recipients=[update_form.email_addr.data],
                               body=render_template(
                                   '/account/email/validate_email.md',
                                   user=account,
                                   confirm_url=confirm_url))
                    msg['html'] = markdown(msg['body'])
                    mail_queue.enqueue(send_mail, msg)
                    user.confirmation_email_sent = True
                    fls = gettext('An email has been sent to verify your \
                                  new email: %s. Once you verify it, it will \
                                  be updated.' % account['email_addr'])
                    flash(fls, 'info')
                if acc_conf_dis:
                    user.email_addr = update_form.email_addr.data
                user.privacy_mode = update_form.privacy_mode.data
                user.locale = update_form.locale.data
                user_repo.update(user)
                cached_users.delete_user_summary(user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(url_for('.update_profile', name=user.name))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % user.fullname
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)

        # Update user password
        elif request.form.get('btn') == 'Password':
            # Update the data because passing it in the constructor does not work
            update_form.name.data = user.name
            update_form.fullname.data = user.fullname
            update_form.email_addr.data = user.email_addr
            update_form.ckan_api.data = user.ckan_api
            external_form = update_form
            if password_form.validate_on_submit():
                user = user_repo.get(user.id)
                if user.check_password(password_form.current_password.data):
                    user.set_password(password_form.new_password.data)
                    user_repo.update(user)
                    flash(
                        gettext('Yay, you changed your password succesfully!'),
                        'success')
                    return redirect(url_for('.update_profile', name=name))
                else:
                    msg = gettext("Your current password doesn't match the "
                                  "one in our records")
                    flash(msg, 'error')
                    return render_template('/account/update.html',
                                           form=update_form,
                                           upload_form=avatar_form,
                                           password_form=password_form,
                                           external_form=external_form,
                                           title=title_msg,
                                           show_passwd_form=show_passwd_form)
            else:
                flash(gettext('Please correct the errors'), 'error')
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Update user external services
        elif request.form.get('btn') == 'External':
            del external_form.locale
            del external_form.email_addr
            del external_form.fullname
            del external_form.name
            if external_form.validate():
                user.ckan_api = external_form.ckan_api.data or None
                user_repo.update(user)
                cached_users.delete_user_summary(user.name)
                flash(gettext('Your profile has been updated!'), 'success')
                return redirect(url_for('.update_profile', name=user.name))
            else:
                flash(gettext('Please correct the errors'), 'error')
                title_msg = 'Update your profile: %s' % user.fullname
                return render_template('/account/update.html',
                                       form=update_form,
                                       upload_form=avatar_form,
                                       password_form=password_form,
                                       external_form=external_form,
                                       title=title_msg,
                                       show_passwd_form=show_passwd_form)
        # Otherwise return 415
        else:
            return abort(415)
def import_repo(short_name):
    """Import a project from a GitHub repo."""
    project = project_repo.get_by_shortname(short_name)
    if not project:  # pragma: no cover
        abort(404)
    ensure_authorized_to('update', project)

    github_url = request.args.get('github_url')
    try:
        gh_repo = GitHubRepo(github_url)
    except GitHubURLError as e:
        flash(str(e), 'error')
        return redirect(url_for('.sync', short_name=project.short_name))

    gh_repo.load_contents()
    try:
        gh_repo.validate()
    except InvalidPybossaProjectError as e:
        flash(str(e), 'error')
        return redirect(url_for('.sync', short_name=project.short_name))

    form = GitHubProjectForm(request.form)
    project_json = gh_repo.get_project_json()
    _populate_form(form, gh_repo.contents, project_json)
    categories = project_repo.get_all_categories()

    if request.method == 'POST' and form.validate():
        info = json.loads(form.additional_properties.data)
        original_short_name = project_json['short_name']
        if form.tutorial.data:
            resp = github.get(form.tutorial.data)
            info['tutorial'] = resp.content.replace(original_short_name,
                                                    project.short_name)
        if form.task_presenter.data:
            resp = github.get(form.task_presenter.data)
            info['task_presenter'] = resp.content.replace(original_short_name,
                                                          project.short_name)
        if form.results.data:
            resp = github.get(form.results.data)
            info['results'] = resp.content.replace(original_short_name,
                                                   project.short_name)
        long_description = None
        if form.long_description.data:
            resp = github.get(form.long_description.data)
            long_description = resp.content

        old_project = Project(**project.dictize())
        project.description = form.description.data
        project.long_description = long_description
        project.category_id = form.category_id.data
        project.webhook = form.webhook.data
        project.info = info

        if form.thumbnail.data:
            data = github.get(form.thumbnail.data).content
            prefix = time.time()
            filename = "project_%s_thumbnail_%i.png" % (project.id, prefix)
            container = "user_%s" % current_user.id
            _download(filename, container, data)
            if project.info.get("thumbnail"):
                uploader.delete_file(project.info["thumbnail"], container)
            project.info['container'] = container
            project.info['thumbnail'] = filename
        try:
            project_repo.update(project)
        except sqlalchemy.exc.DataError as e:  # pragma: no cover
            flash('''DataError: {0} <br><br>Please check the files being
                  imported from GitHub'''.format(e.orig), 'danger')
            return redirect(url_for('.sync', short_name=project.short_name))

        auditlogger.add_log_entry(old_project, project, current_user)
        cached_cat.reset()
        cached_projects.get_project(project.short_name)
        flash(gettext('Project updated!'), 'success')
        return redirect(url_for('project.tasks',
                                short_name=project.short_name))

    elif request.method == 'POST':  # pragma: no cover
        flash(gettext('Please correct the errors'), 'error')

    else:
        form.process()
        form.description.data = project_json.get('description', '')
        form.webhook.data = project_json.get('webhook', '')

        reserved_keys = ['name', 'short_name', 'description', 'webhook',
                         'category_id']
        for k in reserved_keys:
            project_json.pop(k, None)
        form.additional_properties.data = json.dumps(project_json)

    return render_template('projects/github/import.html', form=form,
                           github_url=github_url, project=project)
Example #20
0
def update_volume(short_name, volume_id):
    """Update a volume."""
    category = project_repo.get_category_by(short_name=short_name)
    if not category:  # pragma: no cover
        abort(404)

    ensure_authorized_to('update', category)
    volumes = category.info.get('volumes', [])

    try:
        volume = [v for v in volumes if v['id'] == volume_id][0]
    except IndexError:
        abort(404)

    form = VolumeForm(**volume)
    form.category_id.data = category.id
    all_importers = importer.get_all_importer_names()
    form.importer.choices = [(name, name) for name in all_importers]

    upload_form = AvatarUploadForm()
    import_form = GenericBulkTaskImportForm()(volume['importer'],
                                              **volume.get('data', {}))

    def update():
        """Helper function to update the current volume."""
        try:
            idx = [
                i for i, _vol in enumerate(volumes) if _vol['id'] == volume_id
            ][0]
        except IndexError:  # pragma: no cover
            abort(404)
        volumes[idx] = volume
        category.info['volumes'] = volumes
        project_repo.update_category(category)

    cat_projects = project_repo.filter_by(category_id=category.id)
    has_projects = len(
        [p for p in cat_projects if p.info.get('volume_id') == volume_id]) > 0

    if request.method == 'POST':
        # Process task import form
        if (request.form.get('btn') == 'Import'
                or request.body.get('btn') == 'Import'):

            import_form = GenericBulkTaskImportForm()(volume['importer'],
                                                      request.body)
            if import_form.validate():
                if has_projects:
                    flash('Update failed as projects have already been built',
                          'error')
                else:
                    volume['data'] = import_form.get_import_data()
                    import_data = import_form.get_import_data()
                    try:
                        importer.count_tasks_to_import(**import_data)
                        update()
                        flash('Volume updated', 'success')
                    except BulkImportException as err:
                        flash(err.message, 'error')

            else:
                flash('Please correct the errors', 'error')

        # Process volume details form
        elif request.form.get('btn') != 'Upload':
            form = VolumeForm(request.body)
            all_importers = importer.get_all_importer_names()
            form.importer.choices = [(name, name) for name in all_importers]

            if form.validate():
                if has_projects:
                    flash('Update failed as projects have already been built',
                          'error')
                else:
                    volume['name'] = form.name.data
                    volume['short_name'] = form.short_name.data
                    volume['importer'] = form.importer.data
                    update()
                    flash('Volume updated', 'success')
            else:
                flash('Please correct the errors', 'error')

        # Process thumbnail upload form
        else:
            if upload_form.validate_on_submit():
                _file = request.files['avatar']
                coordinates = (upload_form.x1.data, upload_form.y1.data,
                               upload_form.x2.data, upload_form.y2.data)
                suffix = time.time()
                _file.filename = "volume_{0}_{1}.png".format(
                    volume['id'], suffix)
                container = "category_{}".format(category.id)
                uploader.upload_file(_file,
                                     container=container,
                                     coordinates=coordinates)

                # Delete previous thumbnail from storage
                if volume.get('thumbnail'):
                    uploader.delete_file(volume['thumbnail'], container)
                volume['thumbnail'] = _file.filename
                volume['container'] = container
                upload_method = current_app.config.get('UPLOAD_METHOD')
                thumbnail_url = get_avatar_url(upload_method, _file.filename,
                                               container)
                volume['thumbnail_url'] = thumbnail_url
                update()
                project_repo.save_category(category)
                flash('Thumbnail updated', 'success')
                url = url_for('.get_volumes', short_name=category.short_name)
                return redirect_content_type(url)
            else:
                flash('You must provide a file', 'error')

    response = dict(form=form,
                    all_importers=all_importers,
                    upload_form=upload_form,
                    import_form=import_form,
                    volume=volume,
                    has_projects=has_projects)
    return handle_content_type(response)
Example #21
0
def delete_file(fname, container):
    """Delete file."""
    from pybossa.core import uploader
    return uploader.delete_file(fname, container)