Add Django Variables in Email Template - django-registration

I have a relatively simple objective: send email to Django admins when users register and activate their accounts that contain user information, like username, email, etc. I am using django-registration for handling the registration process. I then employ signals to send the emails. This process works just fine, but as soon as I try to inject the user, username or user's email into an email template I get in trouble.
Here is my signal_connectors.py:
from django.core.mail import mail_admins
from django.dispatch import receiver
from registration.signals import user_registered
from django.template.loader import render_to_string
#receiver(user_registered, dispatch_uid="common.signal_connectors.user_registered_handler")
def user_registered_handler(sender, **kwargs):
print('user registration completed...')
subject = 'registration notify'
template = 'common/email.html'
message = render_to_string(template, {'user': user})
from_email = 'from#example.com'
# send email to admins, if user has been registered
mail_admins(subject, message, fail_silently=False, connection=None, html_message=None)
print('sending email to administrators...')
The template is like so:
{{ user }} has registered at example.com
I have tried variations like {{user}}, {{user.username}}, {{request.user.username}}, etc. Also, in the message variable above, in signals_connectors.py, I have tried variations, with corresponding import statements.
I have also tried rendering templates with contexts set, and other variations that I have found on the web, eg:
finding the django-registration username variable
I keep getting something like this for an error:
global name 'user' is not defined
I think I have template context processing set up correctly, because I can use something like {{ user.username }} in another template and it works.
I have also tried correcting my import statements to include necessary objects, with no luck. I have tried most of what I can find on the web on this topic so I'm at a loss...
What am I missing?

I didn't realize this was so easy. Based on this post:
Where should signal handlers live in a django project?
I tried actually adding the user and request as arguments in the signal connector method and this worked:
. . .
#receiver(user_registered, dispatch_uid="common.signal_connectors.user_registered_handler")
def user_registered_handler(sender, user, request, **kwargs):
. . .
Then, I used this in email template:
{{ user }} has registered at example.com
I probably over-thought this one but I am surprised no one stepped up and was able to help with this...

Related

exchangelib.errors.ErrorNonExistentMailbox: when trying to access exchange with Python

I am pretty new to python and I am trying to do the following:
Use a python script to list the last 10 emails in a specific folder on exchange, however I keep getting the the following error
exchangelib.errors.ErrorNonExistentMailbox: No mailbox with such guid
Below is the script I am trying to run:
#!/usr/bin/env python
#coding:utf-8
from datetime import timedelta
from exchangelib import DELEGATE, IMPERSONATION, Account, Credentials, EWSDateTime, EWSTimeZone, Configuration, CalendarItem, Message, Mailbox, Attendee, Q, ExtendedProperty, FileAttachment, ItemAttachment, HTMLBody, Build, Version
from exchangelib import Configuration, GSSAPI, SSPI
from exchangelib.util import PrettyXmlHandler
from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
import logging
import requests
logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])
def connect_exchange(account):
exCredentials = Credentials(username='User#Domainname.com', password='**********')
exConfig = Configuration(server='mail.domainname.com', credentials=exCredentials)
account = Account(primary_smtp_address='User#Domainname.com', credentials=exCredentials, config=exConfig, autodiscover=False, access_type=DELEGATE)
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
# Print first 100 inbox messages in reverse order
for item in account.inbox.all().order_by('-datetime_received')[:10]:
print(item.subject, item.body, item.attachments)
connect_exchange()
I can see that I am able to connect to the mail server, however when the script attempts the for loop appears to be when the error above gets thrown.
Has anyone encountered such an error before? If so so ids there any workarounds?
Thanks
This is the server telling you that it doesn't know a mailbox with that name. Maybe you're connecting to the wrong server, or you misspelled the email address, or the email address is an alias for the real mailbox?
I tested your snippet on my machine, and with minimal modifications it working for me just fine. Please check your set up credentials for any typos in them.
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
logging.basicConfig(level=logging.DEBUG, handlers=[PrettyXmlHandler()])
def connect_exchange():
exCredentials = Credentials(username='admin#testexchange.local', password='Password')
exConfig = Configuration(server='testexchange.local', credentials=exCredentials)
account = Account(primary_smtp_address='user#testexchange.local', credentials=exCredentials, config=exConfig, autodiscover=False, access_type=DELEGATE)
# Print first 100 inbox messages in reverse order
for item in account.inbox.all().order_by('-datetime_received')[:10]:
print(item.subject, item.body, item.attachments)
connect_exchange()

How can I get and store a user's message with python-telegram-bot?

I'm writing a Telegram bot that must send an image to a user, get a reply and store it as a string.
I managed to write the script to start the bot and send the image (very basic, I know), but I can't figure out how to get the answer. Here is a MWE of my script:
import telegram.ext
token = '1234567890:ABCdEffGH-IJKlm1n23oPqrst_UVzAbcdE4'
bot=telegram.Bot(token=token)
user_id = 567890123
image_path='./image.png'
with open(image_path,'rb') as my_image:
bot.send_photo(chat_id=user_id,photo=my_image,caption='What is this?')
% Somehow store the answer
% Do some other stuff
How can I get and store user's answer?
I can change the script as needed, but to interact with Telegram's API I must use python-telegram-bot only.
You can make a flag called waiting_for_response and after sending the image make it True.
after that you should add a handler to the bot to recieve users reply. You can do it this way:
from telegram.ext import Updater, CommandHandler
updater = Updater(token=TOKEN, use_context=True)
dispatcher = updater.dispatcher
handler = RegexHandler(r'.+', function_name)
dispatcher.add_handler(handler)
Note: You should replace TOKEN with your own token.
by adding this lines, when user sends a message it calls the function_name function and you can define it like this:
def function_name(update, context):
global waiting_for_response
if waiting_for_response:
pass
You can add whatever you want to do with that message inside of this function using update and context.

Discord <#!userid> vs <#userid>

so I'm creating a bot using Node.JS / Discord.JS and I have a question.
On some servers, when you mention a user, it returns in the console as <#!userid> and on other it returns as <#userid>.
My bot has a simple points / level system, and it saves in a JSON file as <#!userid>, so on some servers when trying to look at a users points by mentioning them will work, and on others it won't.
Does anyone have any idea how to fix this? I've tried to find an answer many times, and I don't want to have it save twice, once as <#!userid> and then <#userid>. If this is the only way to fix it then I understand.
Thanks for your help!
The exclamation mark in the <#!userID> means they have a nickname set in that server. Using it without the exclamation mark is more reliable as it works anywhere. Furthermore, you should save users with their id, not the whole mention (the "<#userid>"). Parse out the extra symbols using regex.
var user = "<#!123456789>" //Just assuming that's their user id.
var userID = user.replace(/[<#!>]/g, '');
Which would give us 123456789. Their user id. Of course, you can easily obtain the user object (you most likely would to get their username) in two ways, if they're in the server where you're using the command, you can just
var member = message.guild.member(userID);
OR if they're not in the server and you still want to access their user object, then;
client.fetchUser(userID)
.then(user => {
//Do some stuff with the user object.
}, rejection => {
//Handle the error in case one happens (that is, it could not find the user.)
});
You can ALSO simply access the member object directly from the tag (if they tagged them in the message).
var member = message.mentions.members.first();
And just like that, without any regex, you can get the full member object and save their id.
var memberID = member.id;

Login plugin Hooks not running

I am trying to send a 2nd email to my sites admin when a user registers.
I made a postHook snippet that sends an email but it didnt work - the Registration process worked as expected, but I got no 2nd email from the hook.
In testing I set the hook from postHook to preHook and tried again - this time the form didnt process at all - no new user was created and no activation email was sent. It didnt even redirect to the submittedResourceId.
So, I deleted everything in my preHook Snippet, except the return true; and tried again - still nothing.
It appears Login wont run any Hooks at all. I have no idea why.
Would anyone be able to suggest any fixes?
My register snippet is:
[[!Register?
&submitVar=`registerbtn`
&activationResourceId=`19`
&activationEmailTpl=`lgnActivateEmailTpl`
&activationEmailSubject=`Thanks for Registering!`
&submittedResourceId=`23`
&usergroups=`2`
&validate=`nospam:blank,
username:required:minLength=^6^,
password:required:minLength=^6^,
password_confirm:password_confirm=^password^,
fullname:required,
email:required:email`
&preHooks=`adminEmailHook`
]]
I've done something similar before. There is my code:
[[!Register? &postHooks=`sendMessageToAdmin`
Snippet sendMessageToAdmin:
<?php
$message = 'Auto message:<br><br>A new user signed up: '.$hook->getValue('fullname') . ', using email address '.$hook->getValue('email').'.';
$modx->getService('mail', 'mail.modPHPMailer');
$modx->mail->set(modMail::MAIL_BODY,$message);
$modx->mail->set(modMail::MAIL_FROM,'info#domain.com');
$modx->mail->set(modMail::MAIL_FROM_NAME,'My website');
$modx->mail->set(modMail::MAIL_SENDER,'Auto message from my website');
$modx->mail->set(modMail::MAIL_SUBJECT,'Someone signed up');
$modx->mail->address('to','info#domain.com');
$modx->mail->setHTML(true);
if (!$modx->mail->send()) {
$modx->log(modX::LOG_LEVEL_ERROR,'sendMessageToAdmin: An error occurred while trying to send the email: '.$err);
}
$modx->mail->reset();
/* tell our snippet we're good and can continue */
return true;

Pyramid - Include user object in every request and rendering?

In my website I have a user panel which displays info about user (or a custom message if he is not logged in). I'd like to know how can I do that a user object is accessible within every template? (like Django's CONTEXT_PROCESSORS).
I know I can add_request_method() to my config object but as far as I understand it will only make user's object available in request but I will have to add it to returned context manually each time - not good.
Maybe I should add user's object to session?
What is the proper way to do it?
What you need in Pyramid is an authentication policy. This can be as simple as adding these lines to your __init__.py:
from pyramid.authentication import AuthTktAuthenticationPolicy
def main(global_config, **settings):
...
authentication_policy = AuthTktAuthenticationPolicy('some_key')
config = Configurator(settings=settings,
authentication_policy=authentication_policy)
...
Once an authentication policy is in place, you can use the 'forget' and 'remember' functions from pyramid.security to allow users to log in and out. Here's a simplified view function that handles logins:
from pyramid.security import remember, forget
def sign_in(request):
username = request.POST.get('username')
password = request.POST.get('password')
if username and User.verify_password(username, password):
headers = remember(request, username)
else:
headers = forget(request)
return HTTPFound(location=request.route_url('index'),
headers=headers)
There are a few things you'll have to change there - maybe your User object doesn't have a 'verify_password' method; maybe you want to redirect to a different page on successful login, etc. But it's something to get started with.
Then in my base template I can add:
<%
from pyramid.security import authenticated_userid
user_id = authenticated_userid(request)
%>
to make the user_id available for use in the template and then:
% if user_id:
<p>Welcome ${user_id}</p>
% else:
<p>Please login here</p>
% endif
Note I'm using Mako syntax - if you're using a different templating engine you should check their syntax for imports, conditionals, etc.
I've given a basic outline of the different pieces and how they slot together, but Pyramid has powerful authentication features, and I encourage you to read a little about how it works:
The Pyramid documentation: http://docs.pylonsproject.org/projects/pyramid/en/latest/api/authentication.html
This excellent demo of Pyramid's authentication policies:
https://github.com/mmerickel/pyramid_auth_demo
I know you already mentioned the add_request_method() solution, but that's what I ended up with after following this tutorial on adding a user object to the request.
I might not be doing anything that out there with my pyramid apps, but basically every view and template I have has a request object as part of it, so within any template I can do <% request.user %> and have my user object and everything part of that available. I even have some helper methods and relationships that just come through and are available automagically as request.user.
What example case do you have where the request object isn't available?

Resources