I am using elixir Bamboo for sending emails
I have some binary content and would like to attach to email
the simple way is:
content = <<binary-content>>
File.write("/tmp/myfile.pdf", content )
data = new_email()
|> to(email)
|> from( "email.com")
|> subject("subject")
|> put_attachment("/tmp/myfile.pdf")
|> put_header("Reply-To", "email.com")
|> html_body(html_body)
File.rm("/tmp/myfile.pdf", content )
is there a way attach files without saving them locally?
something like:
content = <<binary-content>>
data = new_email()
|> to(email)
|> from( "email.com")
|> subject("subject")
|> put_attachment(content)
|> put_header("Reply-To", "email.com")
|> html_body(html_body)
You bet. It was included prior to the 1.0 release. You can attach data directly to the struct as of this PR.
You just need to pass put_attachment a Bamboo Attachment struct with the data field populated, so:
content = <<binary-content>>
data = new_email()
|> to(email)
|> from( "email.com")
|> subject("subject")
|> put_attachment(%Bamboo.Attachment{filename: "filename.example", data: content})
|> put_header("Reply-To", "email.com")
|> html_body(html_body)
Here's the thread on the feature: https://github.com/thoughtbot/bamboo/issues/286
Related
I am working on a logistics website using Flask.
On route /step1 the user fills in a form detailing n parcels and their attributes.
The form is submitted and a POST request is sent to /step2 with the following data:
*weight1, length1, width1, height1,
weight2, length2 ...
...
...
*weightn, lengthn, widthn, heightn,
In /step2 the user fills in the sender and recipient addresses.
This form is submitted as a POST request to /process-order
Here's the problem:
How does my process_order view retrieve the data provided in both /step1 and /step2
I can think of three solutions - listed below - but I only know how to go about the first one.
storing the data submitted in step1 form inside hidden inputs and sending this to the form in step2.html and subsequently retrieving this data from the request sent to process_order and storing them as an array.
Caching
flask.g
N.B. This is my very first Flask project and I have zero experience with caching. So please dumb things down for me.
Update
Here's my actual code:
#main.route('/order', methods=['POST'])
def order():
# this function is invoked when user submits a form from the home page
country_from = request.form['country_from']
country_to = request.form['country_to']
data = request.form
parcels = []
for i in range(1, int(data['parcel_count']) + 1):
parcel = Parcel(
weight=data['weight{}'.format(i)],
length=data['length{}'.format(i)],
width=data['width{}'.format(i)],
height=data['height{}'.format(i)],
)
parcels.append(parcel)
weight_units = data['units']
if weight_units == 'kg':
distance_units = 'cm'
else:
distance_units = '"'
return render_template('order.html',
countries = COUNTRIES,
country_from = country_from,
country_to = country_to,
parcels = parcels,
weight_units = weight_units,
distance_units = distance_units,
)
#main.route('/process-order', methods=['POST'])
def process_order():
data = request.form
parcels = []
# pending
# how can I retrieve the parcels array again?
Note that my view functions are being invoked from the action attribute of the forms in my templates (not included here).
Also, you can pass the inputs between steps as parameters as follows
#app.route('/step1', methods=['GET', 'POST'])
def step1():
parcels=[(11,12,13,14),(21,22,23,24),(31,32,33,34)] # contain list of weights, lengths, widths, heights,
weight_units ='kg' # another data to pass
return redirect(url_for('step2',x=parcels,y=weight_units ))
#app.route('/step2/<x>/<y>', methods=['GET', 'POST'])
def step2(x,y):
print(x) # console output
print(y)
return 'ok'
and so on, send all to the next one with more parameters
Say I have the following html:
<div class="item">one</div>
<div class="item">two</div>
<div class="item">three</div>
I would like to log the innerHTML for each element. I have tried the following:
document
|> Document.querySelectorAll(".item")
|> NodeList.toArray /* not sure if this is needed */
|> Array.map(Document.ofNode) /* not sure if this is needed */
|> Array.map(Element.innerHTML)
|> Array.iter((number) => {
Js.log(number);
});
The error is on line |> Array.map(Element.innerHTML)
And the error is:
This has type:
array(Webapi.Dom.Element.t) => array(string)
But somewhere wanted:
array(Dom.node) => 'a
How can I use the Dom.node so that I access the innerHTML?
Document.ofNode should be Element.ofNode, but the error message indicates that this line isn't present at all in the code producing the error. ofNode also returns an option, since not all nodes are elements, so you have to unwrap that as well. Something like this should work:
document
|> Document.querySelectorAll(".item")
|> NodeList.toArray
|> Array.map(Element.ofNode)
|> Array.map(Js.Option.getExn)
|> Array.map(Element.innerHTML)
|> Array.iter(Js.log);
Or to avoid a bit of unnecessary array allocation and mapping:
document
|> Document.querySelectorAll(".item")
|> NodeList.toArray
|> Array.iter(node =>
node
|> Element.ofNode
|> Js.Option.getExn
|> Element.innerHTML
|> Js.log
);
It also has to be said that direct DOM manipulation isn't a great fit for Reason, or any statically typed functional language for that matter, since the DOM is inherently a very dynamically typed and object-oriented API. NodeList.toArray, for example, is required because a NodeList is not an array but an "array-like", which supports only a few array operations.
I try to use persistent with MongoDB in Servant webservices APIs.
Below is my model code (Model.hs)
let mongoSettings = (mkPersistSettings (ConT ''MongoContext))
in share [mkPersist mongoSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
fam String
im String
ot String
email String
login String
pswd String
deriving Show
|]
$(deriveJSON defaultOptions ''User)
And the code to access the database:
usersGet :: AppM [User]
usersGet = do
resultDB <- runDb $ do rest =<< find (select [] "user")
return resultDB
Which gives me an error:
Error: Expected type: [User] Actual type: [Document].
I understand the error, but I thought that the library should automatically generate the necessary functions for the conversion from Document -> User.
What is function that generates for that?
Use bson-generic package to generate fromBSON and toBSON functions
Then map documents you get from the database to [User]
http://hackage.haskell.org/package/bson-generic-0.0.8.1/docs/Data-Bson-Generic.html
I'm current creating some Gatling simulation to test a REST API. I don't really understand Scala.
I've created a scenario with several exec and pause;
object MyScenario {
val ccData = ssv("cardcode_fr.csv").random
val nameData = ssv("name.csv").random
val mobileData = ssv("mobile.csv").random
val emailData = ssv("email.csv").random
val itemData = ssv("item_fr.csv").random
val scn = scenario("My use case")
.feed(ccData)
.feed(nameData)
.feed(mobileData)
.feed(emailData)
.feed(itemData)
.exec(
http("GetCustomer")
.get("/rest/customers/${CardCode}")
.headers(Headers.headers)
.check(
status.is(200)
)
)
.pause(3, 5)
.exec(
http("GetOffers")
.get("/rest/offers")
.queryParam("customercode", "${CardCode}")
.headers(Headers.headers)
.check(
status.is(200)
)
)
}
And I've a simple Simulation :
class MySimulation extends Simulation {
setUp(MyScenario.scn
.inject(
constantUsersPerSec (1 ) during (1)))
.protocols(EsbHttpProtocol.httpProtocol)
.assertions(
global.successfulRequests.percent.is(100))
}
The application I'm trying to simulate is a multilocation mobile App, so I've prepared a set of samples data for each Locale (US, FR, IT...)
My REST API handles all the locales, therefore I want to make the simulation concurrently execute several instances of MyScenario, each with a different locale sample, to simulate the global load.
Is it possible to execute my simulation without having to create/duplicate the scenario and change the val ccData = ssv("cardcode_fr.csv").random for each one?
Also, each locale has its own load, how can I create a simulation that takes a single scenario and executes it several times concurrently with a different load and feeders?
Thanks in advance.
From what you've said, I think this may be a good approach:
Start by grouping your data in such a way that you can look up each item you want to send based on the current locale. For this, I would recommend using a Map that matches a locale string (such as "FR") to the item that matches that locale for the field you're looking to fill in. Then, at the start of each iteration of the scenario, you just pick which locale you want to use for the current iteration from a list. It would look something like this:
val locales = List("US", "FR", "IT")
val names = Map( "US" -> "John", "FR" -> "Pierre", "IT" -> "Guillame")
object MyScenario {
//These two lines pick a random locale from your list
val random_index = rand.nextInt(locales.length);
val currentLocale = locales(random_index);
//This line gets the name
val name = names(currentLocale)
//Do the rest of your logic here
}
This is a very simplified example - you'll have to figure out how you actually want to retrieve the data from files and put it into a Map structure, as I assume you don't want to hard code every item for every field into your code.
How would I upload a file within a form defined with Scala Play's play.api.data.Forms framework. I want the file to be stored under Treatment Image.
val cForm: Form[NewComplication] = Form(
mapping(
"Name of Vital Sign:" -> of(Formats.longFormat),
"Complication Name:" -> text,
"Definition:" -> text,
"Reason:" -> text,
"Treatment:" -> text,
"Treatment Image:" -> /*THIS IS WHERE I WANT THE FILE*/,
"Notes:" -> text,
"Weblinks:" -> text,
"Upper or Lower Bound:" -> text)
(NewComplication.apply _ )(NewComplication.unapply _ ))
is there a simple way to do this? By using built in Formats?
I think you have to handle the file component of a multipart upload separately and combine it with your form data afterwards. You could do this several ways, depending on what you want the treatment image field to actually be (the file-path as a String, or, to take you literally, as a java.io.File object.)
For that last option, you could make the treatment image field of your NewComplication case class an Option[java.io.File] and handle it in your form mapping with ignored(Option.empty[java.io.File]) (so it won't be bound with the other data.) Then in your action do something like this:
def createPost = Action(parse.multipartFormData) { implicit request =>
request.body.file("treatment_image").map { picture =>
// retrieve the image and put it where you want...
val imageFile = new java.io.File("myFileName")
picture.ref.moveTo(imageFile)
// handle the other form data
cForm.bindFromRequest.fold(
errForm => BadRequest("Ooops"),
complication => {
// Combine the file and form data...
val withPicture = complication.copy(image = Some(imageFile))
// Do something with result...
Redirect("/whereever").flashing("success" -> "hooray")
}
)
}.getOrElse(BadRequest("Missing picture."))
}
A similar thing would apply if you wanted just to store the file path.
There are several ways to handle file upload which will usually depend on what you're doing with the files server-side, so I think this approach makes sense.