need help creating permalinks in google app engine - python

So I am trying to create a unique permalink each time that a person posts on my webpage and I want it to be relatively search engine friendly so I have made a little code to change the title to a good search engine title and it is working but then my handler cannot accept it. At least that is what I think is happening because the webpage just gives me a 404 error. The HTML works fine because when I redirect to a static page it all goes through. Here is the applicable code:
def post(self):
subject = self.request.get('subject')
content = self.request.get('content')
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content)
p.put()
id=str(p.key().id())
subject = str(subject)
subject = subject.replace(' ', '25fdsa67ggggsd5')
subject = ''.join(e for e in subject if e.isalnum())
subject = subject.replace('25fdsa67ggggsd5', '-')
subject = subject.lower()
url = '/blog/%s/%s' % (id, subject)
self.redirect('/blog/%s/%s' % (id, subject))
class PostPage(BlogHandler):
def get(self, post_id):
key = db.Key.from_path('PersonalPost', int(post_id), parent=blog_key())
post = db.get(key)
if not post:
self.error(404)
return
self.render("permalink.html", post = post)
class PersonalPost(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
last_modified = db.DateTimeProperty(auto_now = True)
user_id = db.StringProperty(required = True)
def render(self):
self._render_text = self.content.replace('\n', '<br>')
return render_str("post.html", p = self)
def blog_key(name = 'default'):
return db.Key.from_path('blogs', name)
app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
And again it works when I just have it redirect to the main page and list them but not when I try to direct to the new SEO page.
UPDATE:
The test url I am using is setting
subject = "test-url"
id = "1234"
The app then directs me to www.url.com/blog/1234/test-url but it gives me a 404 error.

You define two groups in ('/blog/([0-9]+)/([.*]+) but your PostPage.get() only takes one.
Change it to def get(self, post_id, subject) or remove the second group ('/blog/([0-9]+)/[.*]+

I think you should have a look at the quotes on ur handler mapping, it seems inconsistent.
yours: app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
try : app = webapp2.WSGIApplication(['/blog/([0-9]+)/([.*]+)', PostPage)]

Related

How do you mock an object in a list?

I have the following function:
signature_request = client.send_signature_request_embedded_with_template(
client_id = self.CLIENT_ID,
template_id = self.template_id,
title = self.title,
subject = self.email_subject,
message = self.message,
signers = self.signers,
custom_fields = self.custom_fields
)
signature_id = signature_request.signatures[0].signature_id
I cannot for the life of me mock the signature_id value in my test. I know that I am properly mocking the correct target because I am successfully mocking another return value from this signature_request object. Any help would be highly appreciated!
I have tried the following:
send_request_mocked.return_value.signatures.return_value =
[PropertyMock(signature_id = 'signature_id')]
send_request_mocked.return_value.signatures.return_value =
[Mock(signature_id = 'signature_id')]
etc.

How to make multiple buttons in Flask process them in separate way?

I'm creating my very first web app with Flask. It must connect to MySQL (table called "Tasks") with SQLAlchemy and after that output all tasks from this table. All "tasks" have fields "StartDevelop" and "FinishDevelop" (DateTime fields). So my task is to output two buttons next to every name of "task". They must work with MySQL and send current time.
How can I connect two buttons to every row and connect all of them to python's script?
Example:
task1(string), AcceptTask1(button), CompleteTask1(button)
task2(string), AcceptTask2(button), CompleteTask2(button)
task3(string), AcceptTask3(button), CompleteTask3(button)
task4(string), AcceptTask4(button), CompleteTask4(button)
...
where number of tasks is accepted from datebase.
Code I made
I made dictionary, where key is task.Id and value is form(with string fields and two buttons). I also using field.descriptions to output/not output them.
#app.route('/database', methods=['GET','POST'])
#login_required
def database():
page = request.args.get('page', 1, type=int)
tasks = Tasks.query.filter(current_user.Id == Tasks.Developer or current_user.Id == Tasks.Reviewer).paginate(page, app.config['TASKS_PER_PAGE'], False)
forms = dict()
for task in tasks.items:
forms[task.Id] = DataBaseForm()
forms[task.Id].set_values(task,current_user)
class DataBaseForm(FlaskForm):
eord = StringField()
task = StringField()
assign_date = DateTimeField()
type = StringField()
accept_date = DateTimeField()
accepted = SubmitField(label = 'Submit', description = 'Submit')
comment = StringField()
completed = SubmitField(label = 'Submit', description = None)
def set_values(self, task, user):
self.eord.description = task.course.Name
self.task.description = task.Name
self.assign_date.description = task.Created
if (user.Id == task.Developer):
if(task.EndDevelop):
self.accept_date.description = task.EndDevelop
self.accepted.description = ""
else:
self.accepted.description = 'Submit'
self.comment.description = 'Comment'
if (user.Id == task.Reviewer):
if(task.EndReview):
self.accept_date.description = task.EndReview
self.accepted.description = ""
else:
self.accepted.description = 'Submit'
self.comment.description = 'Comment'
if(task.EndReview and task.EndDevelop):
self.completed.description = 'Complete'

How to get Filename in DjangoWebApp based on a Model containing FileField?

I making a email delivery WebApp, I have an Email Class with uploadcsvfile to upload the .csv contact file from the user's computer to server at location CONTACT_DIR, what I'm unable to figure out is how to get the saved contacts_some_char.csv name in my views.py, the purpouse of getting it's name is so that I can parse the email list and send email to them.
I have my model.py as follows :
class Email(models.Model):
fromemail = models.EmailField(blank = False, max_length = 254)
uploadcsvfile = models.FileField(upload_to = 'Contacts', blank = False)
subject = models.CharField(blank=False,max_length = 254)
bodyHeading = models.CharField(blank = False,max_length = 254)
bodytext = models.TextField(blank = False)
name = models.CharField(blank = False,max_length = 254)
Here is my views.py :
def index(request):
if request.method == 'POST':
email_form = EmailForm(request.POST, request.FILES)
if email_form.is_valid():
email_form.save(commit = True)
print(Email.uploadcsvfile)
contacts = Contacts()
#path = settings.CONTACT_DIR
f = open(settings.CONTACT_DIR+"/"+str(uploaded_file_name))
csv_f = csv.reader(f)
Emails = []
Names= []
L_Names = []
for x in csv_f:
Emails.append(x[0])
Names.append(x[1])
L_Names.append(x[2])
f.close()
contacts.ListOfEmails = json.dumps(Emails)
contacts.ListOfFirstNames = json.dumps(Names)
contacts.ListOfLastNames = json.dumps(L_Names)
contacts.save()
Here is forms.py for the same :
from django import forms
from dcsvreader.models import Email
class EmailForm(forms.ModelForm):
class Meta():
model = Email
fields = "__all__"
A.K.A How do i get uploaded_file_name in views.py, I'm reading in various QnA at S.O that this is related to FileDescriptor but can't find how exactly also, print(Email.uploadcsvfile) gives <django.db.models.fields.files.FileDescriptor object at 0x03F7DF90> as output.
request.FILES is a dictionary-like object containing all uploaded files and the uploadcsvfile is the key in which you are making a POST request. Hence, request.FILES['uploadcsvfile'] will hold the particular file as InMemoryUploadedFile and it has a variable .name which holds the filename
Try this,
file_name = request.FILES['uploadcsvfile'].name
Reference
uploadfile.name
request.FILES
I'm pretty new to django myself but it looks like here:
print(Email.uploadcsvfile)
You're trying to print a class attribute rather than an attribute of an instance.
Have you tried the following?
print(email_form.uploadcsvfile.name)

AttributeError: 'Query' object has no attribute 'has_key'

I have changed my table definitions to use Reference Property. Now when I try to do an insert I get if value is not None and not value.has_key(): AttributeError: 'Query' object has no attribute 'has_key'
subject = self.request.get('subject')
content = self.request.get('content')
user = self.request.get('name')
name = User.all().filter('name =', user)
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content, user = name)
p.put()
This is my Post class
class Post(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
last_modified = db.DateTimeProperty(auto_now = True)
user = db.ReferenceProperty(User)
I am using Python 2.7. I have tried to follow the instruction from another posting regarding if value is not None and not value.has_key(): but those suggestions haven't worked for me.
Thanks everyone for your help.
I added and then set name to p.
for p in q.run():
print "name ", p.name
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content, name = p)

making many to many relationships database in google app engine by python

Im trying to make 3 database; person, event and hobby. Each person selects hobbies from the list that is provided, which are in the hobby database. when a person creates a event, that person choose which hobby will be tagged to that event. From there event invitation will be send out to person who selected that hobby. And the event will be made using Google Calendar API....
im stuck on making this 3 database and trying to relate them using either relationalproperty or list property... looked around but not too good with programming so im kinda stuck...
if anyone could help me that would be really appreciated.
class Hobby(db.Model):
name = db.StringProperty()
#property
def members(self):
return Person.all().filter('hobby', self.key())
h1 = Hobby(key_name ='key1', name = 'tennis')
h2 = Hobby(name = 'basketball')
h1.put()
h2.put()
class Person(db.Model):
name = db.StringProperty()
hobby = db.ListProperty(db.Key)
p1 = Person(name = 'tom', hobby = Hobby.get_by_key_name(['key1']))
p1.put()
class Event(db.Model):
title = db.StringProperty(required=True)
description = db.TextProperty()
time = db.DateTimeProperty()
location = db.TextProperty()
creator = db.UserProperty()
edit_link = db.TextProperty()
gcal_event_link = db.TextProperty()
gcal_event_xml = db.TextProperty()
hobby = db.ListProperty(db.Key)
#property
def members(self):
return Person.all().filter('event', self.key())
class Attendee(db.Model):
email = db.StringProperty()
event = db.ReferenceProperty(Event)
hobby = db.ReferenceProperty(Hobby)
class Greeting(db.Model):
author = db.UserProperty()
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
class BasePage(webapp.RequestHandler):
title = ''
def write_page_header(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('<html><head><title>%s</title>'
'<link href="static/invitations.css" rel="stylesheet" type="text/css"/>'
'</head><body><div id="main">' % (
self.title,))
self.write_signin_links()
def write_signin_links(self):
if users.get_current_user():
template_values = {
'signed_in': True,
'user_link': users.create_logout_url('/')}
else:
template_values = {
'signed_in': False,
'user_link': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'signin.html')
self.response.out.write(template.render(path, template_values))
def write_page_footer(self):
self.response.out.write('</div></body></html>')
class StartPage(BasePage):
title = 'One Macnica'
def get(self):
self.write_page_header()
template_values = {'sign_in': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'start.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()
class EventsPage(BasePage):
title = 'One Macnica'
def __init__(self):
# Create a Google Calendar client to talk to the Google Calendar service.
self.calendar_client = gdata.calendar.service.CalendarService()
# Modify the client to search for auth tokens in the datastore and use
# urlfetch instead of httplib to make HTTP requests to Google Calendar.
gdata.alt.appengine.run_on_appengine(self.calendar_client)
def get(self):
"""Displays the events the user has created or is invited to."""
self.write_page_header()
# Find all events which this user has created, and find events which this
# user has been invited to.
invited_events = []
owned_events = []
token_request_url = None
# Find an AuthSub token in the current URL if we arrived at this page from
# an AuthSub redirect.
auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri)
if auth_token:
self.calendar_client.SetAuthSubToken(
self.calendar_client.upgrade_to_session_token(auth_token))
# Check to see if the app has permission to write to the user's
# Google Calendar.
if not isinstance(self.calendar_client.token_store.find_token(
'http://www.google.com/calendar/feeds/'),
gdata.auth.AuthSubToken):
token_request_url = gdata.auth.generate_auth_sub_url(self.request.uri,
('http://www.google.com/calendar/feeds/',))
query_time = self.request.get('start_time')
# TODO handle times provided in the URL.
if not query_time:
query_time = datetime.datetime.now()
# Find the events which were created by this user, and those which the user
# is invited to.
if users.get_current_user():
owned_query = Event.gql('WHERE creator = :1 ORDER BY time',
users.get_current_user())
owned_events = owned_query.fetch(5)
invited_query = Attendee.gql('WHERE email = :1',
users.get_current_user().email())
for invitation in invited_query.fetch(5):
try:
invited_events.append(invitation.event)
except db.Error, message:
if message[0] == 'ReferenceProperty failed to be resolved':
# The invitee has an invitation to an event which no longer exists.
pass
else:
raise
template_values = {
'token_request_url': token_request_url,
'owned_events': owned_events,
'invited_events': invited_events,
}
# Display the events.
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'events.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()
def post(self):
"""Adds an event to Google Calendar."""
event_id = self.request.get('event_id')
# Fetch the event from the datastore and make sure that the current user
# is an owner since only event owners are allowed to create a calendar
# event.
event = Event.get_by_id(long(event_id))
if users.get_current_user() == event.creator:
# Create a new Google Calendar event.
event_entry = gdata.calendar.CalendarEventEntry()
event_entry.title = atom.Title(text=event.title)
event_entry.content = atom.Content(text=event.description)
if start_time is None:
start_time = '%s.000Z' % event.time.isoformat()
end_time = '%s.000Z' % event.time.isoformat(time.time()+3600)
event_entry.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time))
event_entry.where.append(
gdata.calendar.Where(value_string=event.location))
# Add a who element for each attendee.
attendee_list = event.attendee_set
if attendee_list:
for attendee in attendee_list:
new_attendee = gdata.calendar.Who()
new_attendee.email = attendee.email
event_entry.who.append(new_attendee)
#Adding hobby for each attendee
"""hobby_list = event.hobby_set
if hobby_list:
for hobby in hobby_list:
new_hobby = gdata.calendar.ExtendedProperty()
new_hobby.name = hobby.name
event_entry.extended_property.append(new_hobby)
"""
# Hobby to which a person belongs:
p = db.get(person_key)
hobby = db.get(p.hobby) #batch get using list of keys
for hobby in hobby:
new_hobby = gdata.calendar.ExtendedProperty()
new_hobby = hobby.name
event_entry.extended_property.append(new_hobby)
#Person that belong to a hobby:
h = db.get(hobby_key)
for person in h.members:
new_person = gdata.calendar.Who()
new_person.name = person.name
event_entry.who.append(new_person)
# Event to which a person belongs:
p = db.get(person_key)
event = db.get(p.event)
for event in event:
new_event = gdata.calendar.ExtendedProperty()
new_event = event.title
event_entry.extended_property.append(new_event)
# Person that belong to a event:
e = db.get(event_key)
for person in e.members:
new_person = gdata.calendar.Who()
new_person.name = person.name
event_entry.who.append(new_person)
# Send the event information to Google Calendar and receive a
# Google Calendar event.
try:
cal_event = self.calendar_client.InsertEvent(event_entry,
'http://www.google.com/calendar/feeds/default/private/full')
edit_link = cal_event.GetEditLink()
if edit_link and edit_link.href:
# Add the edit link to the Calendar event to use for making changes.
event.edit_link = edit_link.href
alternate_link = cal_event.GetHtmlLink()
if alternate_link and alternate_link.href:
# Add a link to the event in the Google Calendar HTML web UI.
event.gcal_event_link = alternate_link.href
event.gcal_event_xml = str(cal_event)
event.put()
# If adding the event to Google Calendar failed due to a bad auth token,
# remove the user's auth tokens from the datastore so that they can
# request a new one.
except gdata.service.RequestError, request_exception:
request_error = request_exception[0]
if request_error['status'] == 401 or request_error['status'] == 403:
gdata.alt.appengine.save_auth_tokens({})
# If the request failure was not due to a bad auth token, reraise the
# exception for handling elsewhere.
else:
raise
else:
self.response.out.write('I\'m sorry, you don\'t have permission to add'
' this event to Google Calendar.')
# Display the list of events also as if this were a get.
self.get()
I have posted some of my code. I have edit event class and such after this but i guess its not that important in solving the database situation...
thanks in advance for any help or advice.
Your problem with creating a Person entity is that above (at p1) you're trying to assign a Hobby entity to Person.hobby which should be a list of Hobby keys (and probably be named hobbies)
h = Hobby(name='basketball')
h_key = h.put() # or after h.put(), h.key()
p = Person(name='tom', hobbies=[h_key])
p.put()
Also, your Person model has no property event so Event.members will fail.
Other than these, using db.ListProperty() is the correct way to handle many to many relationships which carry no additional information.

Categories

Resources