I am trying to create a mail body template dynamically based on some conditions.
body = """ New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
"""
I need to format this string based on some conditions, like:
if 'user' in params:
body.format(user='username')
if 'link' in params:
body.format(link='new link')
if 'link2' in params:
body.format(link2='new link2')
I know I can do like below,
body.format(user='username',link='new link',link2='new link2')
But i have to do this based on the above conditions. Is there any way to achieve this in python.?
I have found this and this didn't
help me.
Thanks in advance.
Yeah, I said to use lambdas in my comment but defining a function would be better for expandability. Here's your code:
def format_template(*args):
user = 'default'
link = 'something'
link2 = 'something2'
if 'user' in args:
user = 'username'
elif 'link' in args:
link = 'link'
elif 'link2' in args:
link2 = 'link2'
body = f"""
New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
"""
return body
What about something like this?
params.setdefault('user', 'unknown user')
params.setdefault('link', 'unknown link')
params.setdefault('link2', 'unknown log link')
body = """ New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
""".format(**params)
Of course you can change the defaults ('unknown user', etc.) to whatever value you deem appropriate. If you're not allowed to modify params, you can also use params2=dict(params) and then operate on params2 instead.
What's wrong with the question you linked? This seems like it would work:
body = """ New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
""".format(user='username' if 'user' in params else '???',
link='new link' if 'link' in params else '???',
link2='new link2' if 'link2' in params else '???')
You can try like this.
Here params is a dictionary so you can iterate over its items and do the replacement.
>>> def format(body, **params):
... for key, value in params.items():
... rep = "{" + key + "}"
... if rep in body:
... body = body.replace(rep, value)
... return body
...
>>>
>>> body = """ New product has created by {user}
... This can be viewed by clicking here {link}
... Logs is here {link2}
... """
>>>
>>> print(format(body, user='username'))
New product has created by username
This can be viewed by clicking here {link}
Logs is here {link2}
>>> print(format(body, link='new link'))
New product has created by {user}
This can be viewed by clicking here new link
Logs is here {link2}
>>> print(format(body, link2='new link2'))
New product has created by {user}
This can be viewed by clicking here {link}
Logs is here new link2
>>>
>>> print(format(body, link2='new link2', link="new link"))
New product has created by {user}
This can be viewed by clicking here new link
Logs is here new link2
>>> print(format(body, link2='new link2', link="new link", user="username"))
New product has created by username
This can be viewed by clicking here new link
Logs is here new link2
>>>
Related
I've been using KuCoin API with python for a while now, but stuck trying to get advanced orders form the API. For reference, 'advanced orders' are what stop limit orders are called within KuCoin dash.
I've used the endpoint: api/v1/orders
. I've experimented with this but it only shows 'normal' orders or the order history if 'status' is set to 'done'. Ref: https://docs.kucoin.com/#list-orders
I'm wondering if instead I should use: /api/v1/limit/orders. This endpoint has an option to return stop_limit orders. But when I try, I get response:
{"code":"400007","msg":"Access denied, require more permission."}'
I checked my API permissions and its 'General' permission is set to 'read only' which is the only option. Read only would be fine for me because I only want to get the list of all 'Advanced orders'
See https://docs.kucoin.com/#recent-orders
Does anyone know how to get all open limit orders please? The reason I want this is I have placed many limit orders. I want to collect the orderid's of all stop limit orders so I can clean out just the ones not associated to an active trade.
my code is as follows:
import requests
import json
import hmac
import hashlib
import base64
from urllib.parse import urlencode
import time
from urllib.request import urlretrieve
'''working code to get active orders'''
api_key = 'api_key'
api_secret = 'api_secret'
api_passphrase = 'api_passphrase' # this is NOT trading password
base_uri = 'https://api.kucoin.com'
def get_headers(method, endpoint):
now = int(time.time() * 1000)
str_to_sign = str(now) + method + endpoint
signature = base64.b64encode(hmac.new(api_secret.encode(), str_to_sign.encode(), hashlib.sha256).digest()).decode()
passphrase = base64.b64encode(hmac.new(api_secret.encode(), api_passphrase.encode(), hashlib.sha256).digest()).decode()
return {'KC-API-KEY': api_key,
'KC-API-KEY-VERSION': '2',
'KC-API-PASSPHRASE': passphrase,
'KC-API-SIGN': signature,
'KC-API-TIMESTAMP': str(now)
}
#List Orders
method = 'GET'
endpoint = '/api/v1/limit/orders/' # main
# params = {'type': 'stop_limit'}
params = {}
# # if params :
qstr = '?' + urlencode(params)if params else ''
active_orders = requests.get(url=base_uri+endpoint+qstr, headers=get_headers(method,endpoint+qstr))
Short background of whole idea: I'm trying to create landing page and for backend I use Python/Django3 framework. I need to create form with such fields as name, surname, email, mobile number and address of customer.
I've decided to save all the information that the user enters in the database, and also send it to my email. In order to connect database to forms I use ModelForms in forms.py section (all the required code will be shown below). In order to connect my email to form I use send_mail function from django.core.mail.
So when a user fills out his form, he is redirected to the 'thank you' page and all the information from the form is saved in the database and sent to my email.
But when I finally wrote the code and started to test functionality, I found out that when I hit 'submit' form button, error <type object 'ClientInfoForm' has no attribute 'cleaned_data'> is raised.
I suppose, that method cleaned_data is wrong in my case and I have to replace it with something else but I don't know with what exactly. All the code will be placed below and any help will be helpful. Thank you!
Models.py file
from django.db import models
class ClientInfo(models.Model):
name = models.CharField(max_length=264)
surname = models.CharField(max_length=264)
email = models.EmailField(max_length=264, unique=True)
mobile_number = models.CharField(max_length=20, unique=True)
address = models.CharField(max_length=264)
def __str__(self):
return f'Client: {self.name} {self.surname}'
Forms.py file
from django import forms
from landing_page.models import ClientInfo
class ClientInfoForm(forms.ModelForm):
class Meta():
model = ClientInfo
fields = '__all__'
Views.py file
from django.shortcuts import render
from landing_page.forms import ClientInfoForm
from django.core.mail import send_mail
def thanks(request):
return render(request, 'landing_page/thanks.html')
def index(request):
form = ClientInfoForm()
if request.method == 'POST':
form = ClientInfoForm(request.POST)
if form.is_valid():
form.save(commit=True)
name = ClientInfoForm.cleaned_data['name']
surname = ClientInfoForm.cleaned_data['surname']
email = ClientInfoForm.cleaned_data['email']
mobile_number = ClientInfoForm.cleaned_data['mobile_number']
address = ClientInfoForm.cleaned_data['address']
send_mail(
f'New client: {name} {surname}',
f'Client Name: {name}\nClient Surname: {surname}\nClient email: {email}\n'
f'Client Mobile Number: {mobile_number}\nClient address: {address}',
email,
['zombe#yandex.ru'],
)
return thanks(request)
else:
print('ERROR FORM INVALID')
return render(request, 'landing_page/index.html', {'form':form})
guys, in case you all interested I found out what was the actual problem. I just had to change this code below
name = ClientInfoForm.cleaned_data['name']
surname = ClientInfoForm.cleaned_data['surname']
email = ClientInfoForm.cleaned_data['email']
mobile_number = ClientInfoForm.cleaned_data['mobile_number']
address = ClientInfoForm.cleaned_data['address']
To this version
name = form.cleaned_data['name']
surname = form.cleaned_data['surname']
email = form.cleaned_data['email']
mobile_number = form.cleaned_data['mobile_number']
address = form.cleaned_data['address']
Since i am not able to login to https://www.duif.nl/login, i tried many different methods like selenium, which i successfully logged in, but didnt manage to start crawling.
Now i tried my luck with scrapy-splash, but i cant login :(
If i render the loginpage with splash, i see following picture:
Well, there should be a loginform, like username and password, but scrapy cant see it?
Im sitting here like a week in front of that loginform and losing my will to live..
My last question didnt even get one answer, now i try it again.
here is the html code of the login-form:
When i login manual, i get redirected to "/login?returnUrl=", where i only have these form_data:
My Code
# -*- coding: utf-8 -*-
import scrapy
from scrapy_splash import SplashRequest
from scrapy.spiders import CrawlSpider, Rule
from ..items import ScrapysplashItem
from scrapy.http import FormRequest, Request
import csv
class DuifSplash(CrawlSpider):
name = "duifsplash"
allowed_domains = ['duif.nl']
login_page = 'https://www.duif.nl/login'
with open('duifonlylinks.csv', 'r') as f:
reader = csv.DictReader(f)
start_urls = [items['Link'] for items in reader]
def start_requests(self):
yield SplashRequest(
url=self.login_page,
callback=self.parse,
dont_filter=True
)
def parse(self, response):
return FormRequest.from_response(
response,
formdata={
'username' : 'not real',
'password' : 'login data',
}, callback=self.after_login)
def after_login(self, response):
accview = response.xpath('//div[#class="c-accountbox clearfix js-match-height"]/h3')
if accview:
print('success')
else:
print(':(')
for url in self.start_urls:
yield response.follow(url=url, callback=self.parse_page)
def parse_page(self, response):
productpage = response.xpath('//div[#class="product-details col-md-12"]')
if not productpage:
print('No productlink', response.url)
for a in productpage:
items = ScrapysplashItem()
items['SKU'] = response.xpath('//p[#class="desc"]/text()').get()
items['Title'] = response.xpath('//h1[#class="product-title"]/text()').get()
items['Link'] = response.url
items['Images'] = response.xpath('//div[#class="inner"]/img/#src').getall()
items['Stock'] = response.xpath('//div[#class="desc"]/ul/li/em/text()').getall()
items['Desc'] = response.xpath('//div[#class="item"]/p/text()').getall()
items['Title_small'] = response.xpath('//div[#class="left"]/p/text()').get()
items['Price'] = response.xpath('//div[#class="price"]/span/text()').get()
yield items
In my "prework", i crawled every internal link and saved it to a .csv-File, where i analyse which of the links are product links and which are not.
Now i wonder, if i open a link of my csv, it opens an authenticated session or not?
I cant find no cookies, this is also strange to me
UPDATE
I managed to login successfully :-) now i only need to know where the cookies are stored
Lua Script
LUA_SCRIPT = """
function main(splash, args)
splash:init_cookies(splash.args.cookies),
splash:go("https://www.duif.nl/login"),
splash:wait(0.5),
local title = splash.evaljs("document.title"),
return {
title=title,
cookies = splash:get_cookies(),
},
end
"""
I don't think using Splash here is the way to go, as even with a normal Request the form is there: response.xpath('//form[#id="login-form"]')
There are multiple forms available on the page, so you have to specify which form you want to base yourself on to make a FormRequest.from_response. Best specify the clickdata as well (so it goes to 'Login', not to 'forgot password'). In summary it would look something like this:
req = FormRequest.from_response(
response,
formid='login-form',
formdata={
'username' : 'not real',
'password' : 'login data'},
clickdata={'type': 'submit'}
)
If you don't use Splash, you don't have to worry about passing cookies - this is taken care of by Scrapy. Just make sure you don't put COOKIES_ENABLED=False in your settings.py
I use wp job manager on my website. when I tried to add listing by xmlrpc, everything is fine, but Categories and Location are empty.
Screenshot
Screenshot
My code is as below. Could you tell me what's wrong with my code?
Thanks
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.posts import GetPosts
from wordpress_xmlrpc.methods import posts
from wordpress_xmlrpc import WordPressTerm
from wordpress_xmlrpc.methods import taxonomies
wp = Client('http://127.0.0.1/15wp/xmlrpc.php', 'admin', '123456')
# now let's create a new product
widget = WordPressPost()
widget.post_type = 'job_listing'
widget.title = 'Widgetlast02'
widget.content = 'This is the widgets description.'
widget.post_status = 'publish'
widget.custom_fields = []
widget.custom_fields.append({
'job_location': 'Newyork',
'job_listing_category': 'hotel'
})
widget.id = wp.call(posts.NewPost(widget))
The custom_fields attribute expects a list of dicts.
Within each dict, it expects values for key and value fields.
Here, key is the name of the custom field, and value is the value you want to assign to it.
Below is the snippet for your specific example.
widget.custom_fields = [
{
'key': 'job_location',
'value': 'Newyork'
},
{
'key': 'job_listing_category',
'value': 'hotel'
}
]
This is just a guess from looking at the documentation for WordPressPost in wordpress_xmlrpc:
(Emphasis mine)
class WordPressPost
Represents a post, page, or other registered custom post type in
WordPress.
id
user
date (datetime)
date_modified (datetime)
slug
post_status
title
content
excerpt
link
comment_status
ping_status
terms (list of WordPressTerms)
terms_names (dict)
custom_fields (dict)
enclosure (dict)
password
post_format
thumbnail
sticky
post_type
It expects custom_fields to be a dict - you're creating a list and then inserting a dict into that list:
widget.custom_fields = []
widget.custom_fields.append({
'job_location': 'Newyork',
'job_listing_category': 'hotel'
})
This will probably work better:
widget.custom_fields = {
'job_location': 'Newyork',
'job_listing_category': 'hotel'
}
I'm trying to fill out the form located at https://idp.ncedcloud.org/idp/AuthnEngine#/authn with a username and password. I want to know if went through successfully or not. I tried it ith python2, but I couldn't get it to work.
#!/usr/bin/env python
import urllib
import urllib2
name = "username"
name2 = "password"
data = {
"description" : name,
"ember501": name2
}
encoded_data = urllib.urlencode(data)
content = urllib2.urlopen("https://idp.ncedcloud.org/idp/AuthnEngine#/authn",
encoded_data)
print(content)
error:
It prints the content of the same webpage, and I want it to print the new webpage content.
desired behavior:
python3 solution that goes to the next webpage, or why my code isn't working
Basic example of posting data to a webpage like this using requests library. I would suggest using session, so that your login info is saved for any following requests:
import requests
url = "http://example.com"
name = "username"
name2 = "password"
data = {
"description" : name,
"ember501": name2
}
s = requests.Session()
# If it supports basic auth you could just do
# s.auth(username, password) here before a request
req = s.post(url, data=data)
print(req.text)
Should then be able to do following requests with the s session object