Format date output in a nonRendered xPage - xpages

I am attempting to implement Julian Buss' terrific method of ical output as a non rendered xpage (http://blog.youatnotes.de/web/youatnotes/blog-jb.nsf/dx/how-to-implement-an-icalendar-feed-with-xpages.htm?opendocument&comments). But I am unable to get the date to show up as a proper ISO date format yyyymmdd
I am getting my date from a notes view. Formatting the columns has no affect. I have tried various methods of formatting the date using javascript and failed.
I am not sure if what I am doing is possible. If I should be looking at making the change to the Notes view. Or should I make the change in javascript?
Also open to alternative methods of producing an ics file from a notes database.
Here is the code from my non rendered xpage
<xp:this.afterRenderResponse><![CDATA[#{javascript:var exCon = facesContext.getExternalContext();
var writer = facesContext.getResponseWriter();
var response = exCon.getResponse();
var nview:NotesView = database.getView("ical");
nview.setAutoUpdate(false);
var vc:NotesViewEntryCollection = nview.getAllEntries();
var ve:NotesViewEntry = vc.getFirstEntry();
var values;
var date;
var body;
var period;
var i = 0;
response.setContentType("text/calendar");
response.setHeader("Cache-Control", "no-cache");
writer.write("BEGIN:VCALENDAR\r\n");
writer.write("VERSION:2.0\r\n");
writer.write("X-LOTUS-CHARSET:UTF-8\r\n");
while (ve) {
values = ve.getColumnValues();
date = ve.getColumnValues()[1];
edate = ve.getColumnValues()[2];
body = values.elementAt(3);
period = values.elementAt(2);
writer.write("BEGIN:VEVENT\r\n");
writer.write("DTSTART:"+date+"T080000\r\n");
writer.write("DTEND:"+edate+"T080000\r\n");
writer.write("DESCRIPTION:"+body+"\r\n");
writer.write("END:VEVENT\r\n");
ve = vc.getNextEntry(ve); } writer.write("END:VCALENDAR\r\n");
writer.endDocument(); }]]></xp:this.afterRenderResponse>
This is the output from an event
BEGIN:VEVENT
DTSTART:08/12/2004T080000
DTEND:08/13/2004T080000
DESCRIPTION:Patrick Sawyer: Out of Office
END:VEVENT

Patric,
best you write that output in Java. Create a class where you pass the writer and the database as parameter. Inside use the SimpleDateFormat to bend your date object to your will.
... and recycle!
JavaScript:
var exCon = facesContext.getExternalContext();
var writer = facesContext.getResponseWriter();
var response = exCon.getResponse();
response.setContentType("text/calendar");
response.setHeader("Cache-Control", "no-cache");
var ich = new com.yourdomain.IcalHelper();
ich.renderIcal(database,writer);
writer.endDocument();
Java Class:
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Vector;
import lotus.domino.Database;
import lotus.domino.DateTime;
import lotus.domino.NotesException;
import lotus.domino.View;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
public class IcalHelper {
private static String NL = "\r\n";
#SuppressWarnings("rawtypes")
public void renderIcal(Database db, PrintWriter writer) throws NotesException {
writer.write("BEGIN:VCALENDAR");
writer.write(NL);
writer.write("VERSION:2.0");
writer.write(NL);
writer.write("X-LOTUS-CHARSET:UTF-8");
writer.write(NL);
// Adjust the pattern to your needs
SimpleDateFormat sdf = new SimpleDateFormat("yyyymmdd-T0800000");
View nview = db.getView("ical");
ViewEntryCollection vc = nview.getAllEntries();
ViewEntry ve = vc.getFirstEntry();
while (ve != null) {
ViewEntry nextVe = vc.getNextEntry(ve);
// Here is the writing of the entry
Vector values = ve.getColumnValues();
DateTime date = (DateTime) values.get(1);
DateTime edate = (DateTime) values.get(2);
writer.write("BEGIN:VEVENT");
writer.write(NL);
writer.write("DTSTART:");
writer.write(sdf.format(date.toJavaDate()));
writer.write(NL);
writer.write("DTEND:");
writer.write(sdf.format(edate.toJavaDate()));
writer.write(NL);
writer.write("DESCRIPTION:");
writer.write(values.get(3).toString());
writer.write(NL);
writer.write("END:VEVENT\r\n");
date.recycle();
edate.recycle();
ve.recycle();
ve = nextVe;
}
vc.recycle();
nview.recycle();
writer.write("END:VCALENDAR\r\n");
}
}
P.S.:
In 9.0.1 the calendar API does ICAL

try it with NotesDateTime and Date
...
var dt:NotesDateTime;
var edt:NotesDateTime;
var jdt:Date;
var jedt:Date;
var ve2:NotesViewEntry
while (ve) {
values = ve.getColumnValues();
dt = session.createDateTime(ve.getColumnValues()[1]);
jdt = dt.toJavaDate;
edt = session.createDateTime(ve.getColumnValues()[2]);
jedt = edt.toJavaDate;
body = values.elementAt(3);
period = values.elementAt(2);
writer.write("BEGIN:VEVENT\r\n");
writer.write("DTSTART:"+ jdt.getYear + jdt.getMonth + jdt.getDay +"T080000\r\n");
writer.write("DTEND:"+ jedt.getYear + jedt.getMonth + jedt.getDay +"T080000\r\n");
writer.write("DESCRIPTION:"+body+"\r\n");
writer.write("END:VEVENT\r\n");
ve2=ve;
ve.recycle;
ve=null;
ve = vc.getNextEntry(ve2);
ve2.recycle;
ve2=null;
dt.recycle;
edt.recycle;
dt=null;
edt=null;
}

Related

Azure storage server auto includes x-ms-request-id header in get blob operation

I am trying list blob operation followed by get blob operation. List blob works well but when it comes to get blob , the server auto includes x-ms-request-id in the header string resulting in unmatched calculated string.
Error goes like:
The MAC signature found in the HTTP request is not the same as any computed signature. Server used following string to sign: 'GET
Is there a way to stop server from auto including x-ms-request-id ?
package com.azure;
//import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
//import java.util.Calendar;
//import java.util.TimeZone;
//import java.util.Date;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
//import java.text.DateFormat;
public class Util {
// static SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
// static Date now= new Date();
// static String strDate = fmt.format(now);
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public static String signGetBlobRequestSK(String request, String account, String key,String now) throws Exception
{
//static SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
//fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
//String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
String signedStr = Util.unsignedGetBlobRequestSK(account, now);
Mac mac = Mac.getInstance("HmacSHA256");
Decoder decoder = Base64.getDecoder();
Encoder encoder = Base64.getEncoder();
mac.init(new SecretKeySpec(decoder.decode(key), "HmacSHA256"));
String authKey = new String(encoder.encode(mac.doFinal(signedStr.getBytes("UTF-8"))));
//Byte authKeyDecoded = Byte.decode(authKey);
String auth = "SharedKey " + account + ":" + authKey;
return auth;
}
public static String unsignedGetBlobRequestSK(String account, String now) throws Exception
{
//fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
// String currentTimestamp = fmt.format(now) + " GMT";
StringBuilder sb = new StringBuilder();
sb.append("GET\n"); // method
sb.append('\n'); // content encoding
sb.append('\n'); // content language
sb.append('\n'); // content length
sb.append('\n'); // md5 (optional)
sb.append('\n'); // content type
sb.append('\n'); // legacy date
sb.append('\n'); // if-modified-since
sb.append('\n'); // if-match
sb.append('\n'); // if-none-match
sb.append('\n'); // if-unmodified-since
sb.append('\n'); // range
sb.append("x-ms-date:" + now +'\n'); // headers
sb.append("x-ms-version:2019-12-12\n");
sb.append("/" + account + '/'+ "test" + "/Test%20File%20for%20GMS.xml");
return sb.toString();
}

Constructing the hashed token signature for cosmos DB

I am trying to create hashed token for creating a document in cosmos db but I am always getting 405 method not allowed, can someone verify whether the below format I provided is correct or not?
url = https://cosmos-test-cache.documents.azure.com/dbs/FamilyDB/colls/FamilyCollection/docs/123456
ResourceLink = /dbs/FamilyDB/colls/FamilyCollection/docs/123456
ResourceType = docs
HTTP verb = POST
Response
{
"code": "MethodNotAllowed",
"message": "RequestHandler.Post"
}
If you observe the official cosmos db rest api,you could find that url sample of Creating Document is https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/docs
However,your url is
https://cosmos-test-cache.documents.azure.com/dbs/FamilyDB/colls/FamilyCollection/docs/123456 which is for Get Document,not Create Document. So,it is identified as a Get request rather than a POST request.
Then the error 405 "MethodNotAllowed" occurs.
Updates:
Let me fix it.
If you use sdk, you could set the disableAutomaticIdGeneration property to avoid setting the id.It will generate id automatically for you.
Like:
But according to the rest api document,the id property is Required. The ID field is automatically added when a document is created without specifying the ID value.
Please refer to sample java rest code:
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.json.JSONObject;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class CreateDocumentRest {
private static final String account = "***";
private static final String key = "***";
public static void main(String args[]) throws Exception {
String urlString = "https://" + account + ".documents.azure.com/dbs/db/colls/coll/docs";
//prepare for the json body
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "A");
jsonObject.put("id", "123");
String jsonStr = jsonObject.toString();
String encoding = "UTF-8";
System.out.println(jsonStr);
byte[] data = jsonStr.getBytes(encoding);
HttpURLConnection conn = (HttpURLConnection) (new URL(urlString)).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
getFileRequest(conn, data);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200) {
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
} else {
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
public static void getFileRequest(HttpURLConnection request, byte[] data)
throws Exception {
SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
String stringToSign = "POST".toLowerCase() + "\n"
+ "docs".toLowerCase() + "\n"
+ "dbs/db/colls/coll" + "\n"
+ date.toLowerCase() + "\n"
+ "" + "\n";
System.out.println("stringToSign : " + stringToSign);
String auth = getAuthenticationString(stringToSign);
request.setRequestMethod("POST");
request.setRequestProperty("x-ms-date", date);
request.setRequestProperty("x-ms-version", "2017-02-22");
request.setRequestProperty("Authorization", auth);
request.setRequestProperty("Content-Length", String.valueOf(data.length));
request.setRequestProperty("Content-Type", "application/json");
}
private static String getAuthenticationString(String stringToSign) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
String authKey = Base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8")));
System.out.println("authkey:" + authKey);
String auth = "type=master&ver=1.0&sig=" + authKey;
auth = URLEncoder.encode(auth);
System.out.println("authString:" + auth);
return auth;
}
}
Per my observation,please adjust your ResourceLink as dbs/FamilyDB/colls/FamilyCollection and url as https://cosmos-test-cache.documents.azure.com/dbs/FamilyDB/colls/FamilyCollection/docs
To add to the above answer, for post calls to create hash token
Resource method:Post
Resource Id:dbs/{dbs}/colls/{colls}
Resource Type:docs
and the url should be
dbs/{dbs}/colls/{colls}/docs

Xamarin.iOS add left image to UILable

Here is my case I have custom control that inherent from UILable
and I need to create method that take image (from code or storyboard)
to be added to my label
My tries to convert this code to Xamarin.iOS Source
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "yourIcon.png")
let attachmentString = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: price)
myString.appendAttributedString(attachmentString)
label.attributedText = myString
public void SetLeftDrawable(UIImage image){
var attachment = new NSTextAttachment();
attachment.Image = image;
var attachmentString = new
NSAttributedString(attachment,null); // this method take string not NSTextAttachment
}
any one could help me
Try this:
public void SetLeftDrawable (UIImage image)
{
var attachment = new NSTextAttachment ();
attachment.Image = image;
var attachmentString = NSAttributedString.FromAttachment (attachment);
//replace "price" with your string.
var myString = new NSMutableAttributedString ("price");
myString.Append (attachmentString);
AttributedText = myString;
}
Hope this helps.-

C# Streamreader hangs after using statement

private void testbtn_Click(object sender, RoutedEventArgs e)
{
string url = "http://api.eve-central.com/api/evemon";
var request = WebRequest.Create(url);
request.ContentType = "application/json; charset=utf-8";
string text;
var response = (HttpWebResponse)request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
var data = JObject.Parse(text);
string finalized = data.ToString();
Im trying to parse a json response to get the string / int values out of ~6 fields, but for some reason or another the program hangs on:
text = sr.ReadToEnd();
if there the line:
var data = JObject.Parse(text);
is present. The function works properly if those lines are not present (although it just prints the raw json response with the markup tags). anybody know how to fix this?

Return Dataset as Excel

New to MVC and having some trouble with what should be simple. I'm trying to return a dataset to just an Excel spreadsheet without any real UI.
Here's my code (cannibalized from a few sources):
Controller code:
public ActionResult GetCommissionsExcel(string agencyid, string month, string year)
{
try
{
var as400rep = new iSeriesRepository(new iSeriesContext());
var results = as400rep.GetCommissionExcel(agencyid, month, year);
string xml = String.Empty;
XmlDocument xmlDoc = new XmlDocument();
XmlSerializer xmlSerializer = new XmlSerializer(results.GetType());
using (System.IO.MemoryStream xmlStream = new System.IO.MemoryStream())
{
xmlSerializer.Serialize(xmlStream, results);
xmlStream.Position = 0;
xmlDoc.Load(xmlStream);
xml = xmlDoc.InnerXml;
}
var fName = string.Format("CommissionsExcelExport-{0}", DateTime.Now.ToString("s"));
byte[] fileContents = System.Text.Encoding.UTF8.GetBytes(xml);
return File(fileContents, "application/vnd.ms-excel", fName);
}
catch (Exception ex)
{
Log.Error(ex.Message, ex.InnerException);
throw;
}
}
The jQuery call:
function getExcelExport() {
var activePane = $('div.tab-pane.active');
var agencyCompany = $(activePane).find('#Agency_AgencyId').val();
var month = $(activePane).find('#CommissionMonth').val();
var year = $(activePane).find('#CommissionYear').val();
var url = '#Url.Content("~")' + 'AgencyManagement/GetCommissionsExcel';
window.location = 'AgencyManagement/GetCommissionsExcel';
//$.post('#Url.Action("GetCommissionsExcel", "AgencyManagement")' , {agencyid: agencyCompany, month: month, year: year});
};
It pulls back the data, but I can't figure out how to get it to pop from the search window. It looks like the window.location line makes the call, but I need to post the parameters to the call and that's where I'm stuck.
Figured it out. Just needed to call the jQuery as follows:
window.location = 'AgencyManagement/GetCommissionsExcel?agencyID=' + agencyCompany + '&month=' + month + '&year=' + year;
And I needed to append ".xls" to the filename in the controller action.
var fName = string.Format("CommissionsExcelExport-{0}", DateTime.Now.ToString("s"));
fName = fName + ".xls";
Worked like a charm

Resources