Esempio n. 1
0
def upload_file(request):
    """
    Process file upload request
    """
    c = {'errors': {}}

    c['file'] = File()

    # process file upload
    # extract file params etc
    req = ('filedata', 'filename', 'dltype')

    for x in req:
        if x not in request.POST:
            return HTTPBadRequest()

    hfile = request.POST['filedata']

    # guess content type
    content_type = guess_type(hfile.filename)[0] or 'application/octet-stream'

    dbsession = DBSession()

    now = datetime.utcnow()

    file = dbsession.query(File).filter(File.name==request.POST['filename']).first()
    if file is None:
        file = File()
    file.name = request.POST['filename']
    file.size = len(hfile.value)
    file.dltype = 'download' if request.POST['dltype'] == 'download' else 'auto'
    file.content_type = content_type
    file.updated = h.dt_to_timestamp(now)

    # save file to the storage
    storage_dirs = get_storage_dirs()
    orig_filename = os.path.join(storage_dirs['orig'], file.name)
    fp = open(orig_filename, 'wb')
    shutil.copyfileobj(hfile.file, fp)
    hfile.file.close()
    fp.close()

    dbsession.add(file)
    dbsession.flush()
    dbsession.expunge(file)

    try:
        transaction.commit()
    except IntegrityError:
        # display error etc
        transaction.abort()
        return HTTPFound(location=route_url('admin_list_files', request))

    return HTTPFound(location=route_url('admin_list_files', request))
Esempio n. 2
0
def edit_article_comment_ajax(request):
    """
    Update comment and return updated and rendered data
    """
    comment_id = int(request.matchdict['comment_id'])
    dbsession = DBSession()

    comment = dbsession.query(Comment).options(joinedload('user')).options(joinedload('user.roles')).get(comment_id)

    # passed POST parameters are: 'body', 'name', 'email', 'website', 'date', 'ip', 'xffip'
    params = {
        'body': 'body', 
        'name': 'display_name',
        'email': 'email',
        'website': 'website',
        'ip': 'ip_address',
        'xffip': 'xff_ip_address'
        }

    for k, v in params.items():
        value = request.POST[k]
        if value == '':
            value = None
        setattr(comment, v, value)

    comment.set_body(request.POST['body'])
    comment.is_subscribed = 'is_subscribed' in request.POST

    comment.published = h.str_to_timestamp(request.POST['date'])
    dbsession.flush()

    #comment_user = None
    #if comment.user is not None:
    #    comment_user = dbsession.query(User).options(joinedload('roles')).get(comment.user)

    dbsession.expunge(comment)
    if comment.user is not None:
        dbsession.expunge(comment.user)
        for p in comment.user.roles:
            dbsession.expunge(p)

    data = {}

    # without "unicode" or "str" it generates broken HTML
    # because render() returns webhelpers.html.builder.literal
    renderer_dict = {'comment': comment}
    if comment.user is not None:
        comment._real_email = comment.user.email
    else:
        comment._real_email = comment.email

    if comment._real_email == '':
        comment._real_email = None
    data['rendered'] = render('/blog/single_comment.mako', renderer_dict, request)
    return data
Esempio n. 3
0
def add_article_comment_ajax(request):
    _ = request.translate
    article_id = int(request.matchdict['article_id'])

    dbsession = DBSession()

    q = dbsession.query(Article).filter(Article.id == article_id)
    user = request.user
    if not user.has_role('editor') or not user.has_role('admin'):
        q = q.filter(Article.is_draft==False)
    article = q.first()

    if article is None or not article.is_commentable:
        return HTTPNotFound()

    if 's' not in request.POST:
        return HTTPBadRequest()

    json = {}

    key = request.POST['s']

    # all data elements are constructed from the string "key" as substrings
    body_ind = key[3:14]
    parent_ind = key[4:12]
    display_name_ind = key[0:5]
    email_ind = key[13:25]
    website_ind = key[15:21]
    is_subscribed_ind = key[19:27]

    for ind in (body_ind, parent_ind, display_name_ind, email_ind, website_ind):
        if ind not in request.POST:
            return HTTPBadRequest()

    body = request.POST[body_ind]

    if len(body) == 0:
        return {'error': _('Empty comment body is not allowed.')}

    comment = Comment()
    comment.set_body(body)

    user = request.user

    if user.kind != 'anonymous':
        comment.user_id = user.id
    else:
        # get "email", "display_name" and "website" arguments
        comment.display_name = request.POST[display_name_ind]
        comment.email = request.POST[email_ind]
        comment.website = request.POST[website_ind]

        # remember email, display_name and website in browser cookies
        request.response.set_cookie('comment_display_name', comment.display_name, max_age=31536000)
        request.response.set_cookie('comment_email', comment.email, max_age=31536000)
        request.response.set_cookie('comment_website', comment.website, max_age=31536000)

    # set parent comment
    parent_id = request.POST[parent_ind]
    try:
        parent_id = int(parent_id)
    except ValueError:
        parent_id = None

    if parent_id:
        parent = dbsession.query(Comment).filter(Comment.id == parent_id)\
            .filter(Comment.article_id == article_id).first()
        if parent is not None:
            if not parent.is_approved:
                #
                data = { 'error': _('Answering to not approved comment')}
                return json.dumps(data)

    comment.parent_id = parent_id
    comment.article_id = article_id

    if is_subscribed_ind in request.POST:
        comment.is_subscribed = True

    # this list contains notifications
    ns = []

    # if user has subscribed to answer then check is his/her email verified
    # if doesn't send verification message to the email
    if is_subscribed_ind in request.POST:
        vrf_email = ''
        if user.kind != 'anonymous':
            vrf_email = user.email
        elif request.POST[email_ind]:
            vrf_email = request.POST[email_ind]

        vrf_email = normalize_email(vrf_email)
        if vrf_email:
            # email looks ok so proceed

            send_evn = False

            vf = dbsession.query(VerifiedEmail).filter(VerifiedEmail.email == vrf_email).first()
            vf_token = ''
            if vf is not None:
                if not vf.is_verified:
                    diff = time() - vf.last_verify_date
                    #if diff > 86400:
                    if diff > 1:
                        # delay between verifications requests must be more than 24 hours
                        send_evn = True
                    vf.last_verify_date = time()
                    vf_token = vf.verification_code

            else:
                send_evn = True
                vf = VerifiedEmail(vrf_email)
                vf_token = vf.verification_code
                dbsession.add(vf)

            if send_evn:
                ns.append(notifications.gen_email_verification_notification(request, vrf_email, vf_token))

    request.response.set_cookie('is_subscribed', 'true' if comment.is_subscribed else 'false', max_age=31536000)

    # automatically approve comment if user has role "admin", "writer" or "editor"
    if user.has_role('admin') or user.has_role('writer') \
            or user.has_role('editor'):
        comment.is_approved = True

    # TODO: also automatically approve comment if it's considered as safe:
    # i.e. without hyperlinks, spam etc

    # check how much hyperlinks in the body string
    if len(re.findall('https?://', body, flags=re.IGNORECASE)) <= 1:
        comment.is_approved = True

    # record commenter ip address
    comment.ip_address = request.environ.get('REMOTE_ADDR', 'unknown')
    comment.xff_ip_address = request.environ.get('X_FORWARDED_FOR', None)

    dbsession.add(comment)
    _update_comments_counters(dbsession, article)
    dbsession.flush()
    dbsession.expunge(comment)  # remove object from the session, object state is preserved
    dbsession.expunge(article)
    transaction.commit()  # to delete, probably

    # comment added, now send notifications
    loop_limit = 100
    comment = dbsession.query(Comment).get(comment.id)
    parent = comment.parent
    admin_email = get_config('admin_notifications_email')
    vf_q = dbsession.query(VerifiedEmail)
    notifications_emails = []

    while parent is not None and loop_limit > 0:
        loop_limit -= 1
        c = parent
        parent = c.parent
        # walk up the tree
        if not c.is_subscribed:
            continue
        # find email
        email = None
        if c.user is None:
            email = c.email
        else:
            email = c.user.email

        if email is None or email == admin_email:
            continue

        email = normalize_email(email)

        if email in notifications_emails:
            continue

        vf = vf_q.filter(VerifiedEmail.email == email).first()
        if vf is not None and vf.is_verified:
            # send notification to "email"
            ns.append(notifications.gen_comment_response_notification(request, article, comment, c, email))

    admin_notifications_email = normalize_email(get_config('admin_notifications_email'))

    for nfn in ns:
        if nfn is None:
            continue

        if nfn.to == admin_notifications_email:
            continue
        nfn.send()

    # create special notification for the administrator
    nfn = notifications.gen_new_comment_admin_notification(request, article, comment)
    if nfn is not None:
        nfn.send()

    # cosntruct comment_id
    # we're not using route_url() for the article because stupid Pyramid urlencodes fragments
    comment_url = h.article_url(request, article) + '?commentid=' + str(comment.id)

    # return rendered comment
    data = {
        'body': comment.rendered_body,
        'approved': comment.is_approved,
        'id': comment.id,
        'url': comment_url
        }

    return data