i already able to print text using kotlin to thermal printer, but im still dont know how to print image to thermal printer in kotlin. please give me sample printing image to thermal printer in kotlin.i already search for the topics, but it written in java, i doesnt know java very much thanks for the help
private fun p1() {
val namaToko = "Rose Medical"
val alamatToko = "Pramuka raya no.1 Jakarta Timur"
val telp = "021-85901642"
val enter = "\n"
val strip = "-"
val rp ="Rp."
val ex = " X "
val textTotal = "Total Rp:"
val ppnTv = "PPN :Rp."
val chargeTv ="Charge :Rp."
val totalTv = "Total Belanja :Rp."
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
// chunks1
try{
writeWithFormat(namaToko.toByteArray(),Formatter().get(),Formatter.centerAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(alamatToko.toByteArray(),Formatter().get(),Formatter.centerAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(telp.toByteArray(),Formatter().get(),Formatter.centerAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
}catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
// chunks2
for(pointer in salesBody.indices){
try {
val merk = salesBody[pointer].merk
writeWithFormat(merk!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(strip.toByteArray(),Formatter().get(),Formatter.leftAlign())
val barang = salesBody[pointer].namaBrg
writeWithFormat(barang!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
val varian = salesBody[pointer].varian
writeWithFormat(varian!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(rp.toByteArray(),Formatter().get(),Formatter.leftAlign())
val harga = ValidNumber().deciformat(salesBody[pointer].hargaJual.toString())
writeWithFormat(harga.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(ex.toByteArray(),Formatter().get(),Formatter.leftAlign())
val jumlah = ValidNumber().deciformat(salesBody[pointer].qty.toString())
writeWithFormat(jumlah.toByteArray(),Formatter().get(),Formatter.leftAlign())
val satuan = salesBody[pointer].unit
writeWithFormat(satuan!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(textTotal.toByteArray(),Formatter().get(),Formatter.rightAlign())
val total = ValidNumber().deciformat(salesBody[pointer].total.toString())
writeWithFormat(total.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
}catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
}
// chunks3
try{
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
val tanggal = salesHeader[0].tanggal
writeWithFormat(tanggal!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(strip.toByteArray(),Formatter().get(),Formatter.leftAlign())
val jam = salesHeader[0].jam
writeWithFormat(jam!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(strip.toByteArray(),Formatter().get(),Formatter.leftAlign())
val idTag= salesHeader[0].idTag
writeWithFormat(idTag!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
val payment= salesHeader[0].payment
writeWithFormat(payment!!.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.leftAlign())
writeWithFormat(ppnTv.toByteArray(),Formatter().get(),Formatter.rightAlign())
val ppnValue = ValidNumber().deciformat(salesHeader[0].ppn.toString())
writeWithFormat(ppnValue.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(chargeTv.toByteArray(),Formatter().get(),Formatter.rightAlign())
val chargeValue = ValidNumber().deciformat(salesHeader[0].charge.toString())
writeWithFormat(chargeValue.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(totalTv.toByteArray(),Formatter().get(),Formatter.rightAlign())
var totalValue = ValidNumber().deciformat(salesHeader[0].allTotal.toString())
writeWithFormat(totalValue.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
writeWithFormat(enter.toByteArray(),Formatter().get(),Formatter.rightAlign())
}catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
}
}
//print code
class Formatter {
/** The format that is being build on */
private val mFormat: ByteArray
init {
// Default:
mFormat = byteArrayOf(27, 33, 0)
}
/**
* Method to get the Build result
*
* #return the format
*/
fun get(): ByteArray {
return mFormat
}
fun bold(): Formatter {
// Apply bold:
mFormat[2] = (0x8 or mFormat[2].toInt()).toByte()
return this
}
fun small(): Formatter {
mFormat[2] = (0x1 or mFormat[2].toInt()).toByte()
return this
}
fun height(): Formatter {
mFormat[2] = (0x10 or mFormat[2].toInt()).toByte()
return this
}
fun width(): Formatter {
mFormat[2] = (0x20 or mFormat[2].toInt()).toByte()
return this
}
fun underlined(): Formatter {
mFormat[2] = (0x80 or mFormat[2].toInt()).toByte()
return this
}
companion object {
fun rightAlign(): ByteArray {
return byteArrayOf(0x1B, 'a'.code.toByte(), 0x02)
}
fun leftAlign(): ByteArray {
return byteArrayOf(0x1B, 'a'.code.toByte(), 0x00)
}
fun centerAlign(): ByteArray {
return byteArrayOf(0x1B, 'a'.code.toByte(), 0x01)
}
}
}//last
fun writeWithFormat(buffer: ByteArray, pFormat: ByteArray?, pAlignment: ByteArray?): Boolean {
val mmOutStream: OutputStream = mBluetoothSocket.outputStream
return try {
// Notify printer it should be printed with given alignment:
mmOutStream.write(pAlignment)
// Notify printer it should be printed in the given format:
mmOutStream.write(pFormat)
// Write the actual data:
mmOutStream.write(buffer, 0, buffer.size)
// Share the sent message back to the UI Activity
//App.getInstance().getHandler().obtainMessage(MESSAGE_WRITE, buffer.size, -1, buffer).sendToTarget()
true
} catch (e: IOException) {
Log.e(TAG, "Exception during write", e)
false
}
}
//print code close
Using Thermal Printer repo references, I managed to print image to Bluetooth thermal printer. Make sure to use a proper black and white image to print.
Here is the piece of code I used to make a java class
--BitmapHelper.java.
public class BitmapHelper {
private static String[] binaryArray = { "0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111" };
public static byte[] decodeBitmap(Bitmap bmp){
//Bitmap bmp = Bitmap.createScaledBitmap(bitmap, 50, 50, false);
int maxWidth = 350;
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
if(bmpWidth > maxWidth){
float aspectRatio = bmp.getWidth() /
(float) bmp.getHeight();
bmpWidth = maxWidth;
bmpHeight = Math.round(bmpWidth / aspectRatio);
bmp = Bitmap.createScaledBitmap(bmp, bmpWidth, bmpHeight, false);
}
List<String> list = new ArrayList<>(); //binaryString list
StringBuffer sb;
int zeroCount = bmpWidth % 8;
StringBuilder zeroStr = new StringBuilder();
if (zeroCount > 0) {
for (int i = 0; i < (8 - zeroCount); i++) {
zeroStr.append("0");
}
}
for (int i = 0; i < bmpHeight; i++) {
sb = new StringBuffer();
for (int j = 0; j < bmpWidth; j++) {
int color = bmp.getPixel(j, i);
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = color & 0xff;
// if color close to white,bit='0', else bit='1'
if (r > 160 && g > 160 && b > 160)
sb.append("0");
else
sb.append("1");
}
if (zeroCount > 0) {
sb.append(zeroStr);
}
list.add(sb.toString());
}
List<String> bmpHexList = binaryListToHexStringList(list);
String commandHexString = "1D763000";
String widthHexString = Integer
.toHexString(bmpWidth % 8 == 0 ? bmpWidth / 8
: (bmpWidth / 8 + 1));
if (widthHexString.length() > 2) {
Log.e("decodeBitmap error", " width is too large");
return null;
} else if (widthHexString.length() == 1) {
widthHexString = "0" + widthHexString;
}
widthHexString = widthHexString + "00";
String heightHexString = Integer.toHexString(bmpHeight);
if (heightHexString.length() > 2) {
Log.e("decodeBitmap error", " height is too large");
return null;
} else if (heightHexString.length() == 1) {
heightHexString = "0" + heightHexString;
}
heightHexString = heightHexString + "00";
List<String> commandList = new ArrayList<>();
commandList.add(commandHexString+widthHexString+heightHexString);
commandList.addAll(bmpHexList);
return hexList2Byte(commandList);
}
private static List<String> binaryListToHexStringList(List<String> list) {
List<String> hexList = new ArrayList<String>();
for (String binaryStr : list) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < binaryStr.length(); i += 8) {
String str = binaryStr.substring(i, i + 8);
String hexString = myBinaryStrToHexString(str);
sb.append(hexString);
}
hexList.add(sb.toString());
}
return hexList;
}
private static String myBinaryStrToHexString(String binaryStr) {
StringBuilder hex = new StringBuilder();
String f4 = binaryStr.substring(0, 4);
String b4 = binaryStr.substring(4, 8);
String hexStr = "0123456789ABCDEF";
for (int i = 0; i < binaryArray.length; i++) {
if (f4.equals(binaryArray[i]))
hex.append(hexStr.substring(i, i + 1));
}
for (int i = 0; i < binaryArray.length; i++) {
if (b4.equals(binaryArray[i]))
hex.append(hexStr.substring(i, i + 1));
}
return hex.toString();
}
private static byte[] hexList2Byte(List<String> list) {
List<byte[]> commandList = new ArrayList<byte[]>();
for (String hexStr : list) {
commandList.add(hexStringToBytes(hexStr));
}
return sysCopy(commandList);
}
private static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
private static byte[] sysCopy(List<byte[]> srcArrays) {
int len = 0;
for (byte[] srcArray : srcArrays) {
len += srcArray.length;
}
byte[] destArray = new byte[len];
int destLen = 0;
for (byte[] srcArray : srcArrays) {
System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length);
destLen += srcArray.length;
}
return destArray;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
Then I use it in the print activity:
private fun p2(){
val convertBmp : Bitmap
convertBmp = BitmapFactory.decodeResource(getResources(),com.example.ronibluetooth.R.drawable.poly)
val decodeBmp = BitmapHelper.decodeBitmap(convertBmp)
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
try {
val os =mBluetoothSocket.outputStream
os.write(decodeBmp,0,decodeBmp.size)
}
catch (e: Exception) {
Log.e("PrintActivity", "Exe ", e)
}
}
}
image to print
result print
My application actually has mail send / receive functionalities to handle.
While receiving the mail, i am unable to view the image which is an inline image being sent from outlook.
Can some one help me how can i catch the image and make available always.
I have java code like below,
try (InputStream stream = new ByteArrayInputStream(Base64
.getMimeDecoder().decode(mail))) {
MimeMessage message = new MimeMessage(null, stream);
Object messageContent = message.getContent();
if (messageContent instanceof String) {
body = (String) messageContent;
} else if (messageContent instanceof MimeMultipart) {
content = (MimeMultipart) messageContent;
for (int i = 0; i < content.getCount(); i++) {
BodyPart bodyPart = content.getBodyPart(i);
String disposition = bodyPart.getDisposition();
if (disposition == null
|| disposition
.equalsIgnoreCase(Part.INLINE)) {
Object object = bodyPart.getContent();
if (object instanceof String) {
body = object.toString();
} else if (object instanceof MimeMultipart) {
MimeMultipart mimeMultipart = (MimeMultipart) object;
String plainBody = null;
String htmlBody = null;
for (int j = 0; j < mimeMultipart.getCount(); j++) {
BodyPart multipartBodyPart = mimeMultipart
.getBodyPart(j);
String multipartDisposition = multipartBodyPart
.getDisposition();
String multipartContentType = multipartBodyPart
.getContentType();
if (multipartDisposition == null
&& multipartContentType != null) {
if (multipartContentType
.contains(MediaType.TEXT_HTML)) {
htmlBody = multipartBodyPart
.getContent().toString();
} else if (multipartContentType
.contains(MediaType.TEXT_PLAIN)) {
plainBody = multipartBodyPart
.getContent().toString();
}
}
}
if (htmlBody != null) {
body = htmlBody;
} else {
body = plainBody;
}
}
}
}
}
Client side i am using CKEditor to handle email body data.
Thanks a lot.
i got a solution from the example shared below
https://www.tutorialspoint.com/javamail_api/javamail_api_fetching_emails.htm
But, this example explains, how to find the image in body and store.
I have also done below to replace src
`
Pattern htmltag = Pattern.compile("]src=\"[^>]>(.?)");
Pattern link = Pattern.compile("src=\"[^>]\">");
String s1 = "";
Matcher tagmatch = htmltag.matcher(s1);
List<String> links = new ArrayList<String>();
while (tagmatch.find()) {
Matcher matcher = link.matcher(tagmatch.group());
matcher.find();
String link1 = matcher.group().replaceFirst("src=\"", "")
.replaceFirst("\">", "")
.replaceFirst("\"[\\s]?target=\"[a-zA-Z_0-9]*", "");
links.add(link1);
s1 = s1.replaceAll(link1, "C:\\//Initiatives_KM\\//image.jpg");
}
`
And on top of this, i gonna do Base64 encoding so that i dont require store in file system.
encodedfileString = Base64.getEncoder().encodeToString(bArray);
With all these i can conclude to say, i got solution for my issue. Thank you.
I've read a lot of the postings about 500 errors because of the channel emulator, but this is not the case here. I took the standard bot template, which works just fine with the emulator, and replaced it with
ConnectorClient connector = new ConnectorClient(new
Uri(activity.ServiceUrl));
// calculate something for us to return
// int length = (activity.Text ?? string.Empty).Length;
string responseText=
***Bot_Application2.SilviaRestClass.GetRestResult(activity.Text);***
So the issue is in executing the GetRestResult method in the SilivaRestClass.
The code itself works, I'm using it in lots of other places, as it basically sets up a simple 1)get an input utterance in text, 2)send to my SILVIA AI server, and 3)get an utterance back routine. I have a feeling it has something to do with either private vs public methods, and/or [Serializable], based on what I have read so far. The code (minus the credentials) is below. Many thanks, in advance, for any suggestions to try.
`
bool exit = false;
restResponse = "Hello";
bool sessionNew = true;
string viewMessage = null;
string SILVIAUri = "";
string SILVIACore = "/Core/Create/unique/silName";
string SILVIASubmit = "/IO/SetInputManaged/unique/hello";
string SILVIARead = "/IO/GetAll/unique";
string SILVIARelease = "/Core/Release/{unique}";
string SILVIASubKey = "";
string silName = "";
string returnMessage = null;
string holdit = null;
string holdit2 = null;
int forHold = 0;
string responseFromServer = null;
string isfalse = "false";
string myURI = null;
string unique = null;
//CREATE CORE from SILVIA SERVER
myURI = SILVIAUri + SILVIACore;
myURI = myURI.Replace("silName", silName);
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest request = WebRequest.Create(myURI);
request.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
if (sessionNew)
{
Random rnd1 = new Random();
unique = rnd1.Next().ToString() + "askgracie";
sessionNew = false;
WebResponse wResponse = request.GetResponse();
Stream dataStream = wResponse.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
// Clean up the streams and the response.
reader.Close();
wResponse.Close();
}
//SEND UTTERANCE to SILVIA
holdit = null;
myURI = null;
myURI = SILVIAUri + SILVIASubmit;
holdit = restResponse;
// holdit = HttpUtility.UrlEncode(holdit);
myURI = myURI.Replace("hello", holdit);
myURI = myURI.Replace("unique", unique);
if (holdit == "exit")
{
exit = true;
myURI = SILVIAUri + SILVIARelease;
}
System.Net.WebRequest sendRequest = WebRequest.Create(myURI);
sendRequest.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
WebResponse sendResponse = sendRequest.GetResponse();
Stream sendStream = sendResponse.GetResponseStream();
StreamReader sendReader = new StreamReader(sendStream);
string send_ResponseFromServer = sendReader.ReadToEnd();
// Clean up the streams and the response.
sendReader.Close();
sendResponse.Close();
holdit = send_ResponseFromServer;
forHold = holdit.IndexOf("success");
holdit2 = holdit.Substring(forHold + 9, 5);
if (holdit2 == isfalse)
{
var simpleUtterResponse = "The bot failed to send the
utterance to SILVIA";
}
//GETRESPONSES FROM SILVIA
returnMessage = null;
holdit = null;
responseFromServer = null;
myURI = SILVIAUri + SILVIARead;
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest readRequest = WebRequest.Create(myURI);
readRequest.Headers["Ocp-Apim-Subscription-Key"] = SILVIASubKey;
WebResponse readResponse = readRequest.GetResponse();
Stream readStream = readResponse.GetResponseStream();
StreamReader readReader = new StreamReader(readStream);
string read_ResponseFromServer = readReader.ReadToEnd();
viewMessage = read_ResponseFromServer;
string lastRead = "ID ";
List<string> myArray = new List<string>(viewMessage.Split(new
string[] { "\r\n" }, StringSplitOptions.None));
foreach (string s in myArray)
{
if (lastRead == "type: voice")
{
returnMessage = returnMessage + " " + s.Substring(8);
}
if (s.Length < 11)
{ lastRead = s;
}
else
{ lastRead = s.Substring(0, 11);
}
if (s.Length < 11)
{ lastRead = s;
}
else
{ lastRead = s.Substring(0, 11);
}
}
// Clean up the streams and the response.
//readReader.Close();
//readResponse.Close();
if (exit)
{
myURI = SILVIAUri + SILVIARelease;
myURI = myURI.Replace("unique", unique);
System.Net.WebRequest closeRequest =
WebRequest.Create(myURI);
closeRequest.Headers["Ocp-Apim-Subscription-Key"] =
SILVIASubKey;
WebResponse closeResponse = closeRequest.GetResponse();
}
return returnMessage;
}
}
}`
I ended up resolving this by cut/paste the class inside the same namespace and physical .cs file. – Brian Garr just now edit
I am now using FileStreamResult and it works to stream a video, but can't seek it. It always starts again from the beginning.
I was using ByteRangeStreamContent but it seems that it is not available anymore with dnxcore50.
So how to proceed ?
Do i need to manually parse the request range headers and write a custom FileResult that sets the response Content-Range and the rest of the headers and writes the buffer range to the response body or is there something already implemented and i'm missing it ?
Here is a naive implementation of a VideoStreamResult. I am using at the moment (the multipart content part is not tested):
public class VideoStreamResult : FileStreamResult
{
// default buffer size as defined in BufferedStream type
private const int BufferSize = 0x1000;
private string MultipartBoundary = "<qwe123>";
public VideoStreamResult(Stream fileStream, string contentType)
: base(fileStream, contentType)
{
}
public VideoStreamResult(Stream fileStream, MediaTypeHeaderValue contentType)
: base(fileStream, contentType)
{
}
private bool IsMultipartRequest(RangeHeaderValue range)
{
return range != null && range.Ranges != null && range.Ranges.Count > 1;
}
private bool IsRangeRequest(RangeHeaderValue range)
{
return range != null && range.Ranges != null && range.Ranges.Count > 0;
}
protected async Task WriteVideoAsync(HttpResponse response)
{
var bufferingFeature = response.HttpContext.Features.Get<IHttpBufferingFeature>();
bufferingFeature?.DisableResponseBuffering();
var length = FileStream.Length;
var range = response.HttpContext.GetRanges(length);
if (IsMultipartRequest(range))
{
response.ContentType = $"multipart/byteranges; boundary={MultipartBoundary}";
}
else
{
response.ContentType = ContentType.ToString();
}
response.Headers.Add("Accept-Ranges", "bytes");
if (IsRangeRequest(range))
{
response.StatusCode = (int)HttpStatusCode.PartialContent;
if (!IsMultipartRequest(range))
{
response.Headers.Add("Content-Range", $"bytes {range.Ranges.First().From}-{range.Ranges.First().To}/{length}");
}
foreach (var rangeValue in range.Ranges)
{
if (IsMultipartRequest(range)) // I don't know if multipart works
{
await response.WriteAsync($"--{MultipartBoundary}");
await response.WriteAsync(Environment.NewLine);
await response.WriteAsync($"Content-type: {ContentType}");
await response.WriteAsync(Environment.NewLine);
await response.WriteAsync($"Content-Range: bytes {range.Ranges.First().From}-{range.Ranges.First().To}/{length}");
await response.WriteAsync(Environment.NewLine);
}
await WriteDataToResponseBody(rangeValue, response);
if (IsMultipartRequest(range))
{
await response.WriteAsync(Environment.NewLine);
}
}
if (IsMultipartRequest(range))
{
await response.WriteAsync($"--{MultipartBoundary}--");
await response.WriteAsync(Environment.NewLine);
}
}
else
{
await FileStream.CopyToAsync(response.Body);
}
}
private async Task WriteDataToResponseBody(RangeItemHeaderValue rangeValue, HttpResponse response)
{
var startIndex = rangeValue.From ?? 0;
var endIndex = rangeValue.To ?? 0;
byte[] buffer = new byte[BufferSize];
long totalToSend = endIndex - startIndex;
int count = 0;
long bytesRemaining = totalToSend + 1;
response.ContentLength = bytesRemaining;
FileStream.Seek(startIndex, SeekOrigin.Begin);
while (bytesRemaining > 0)
{
try
{
if (bytesRemaining <= buffer.Length)
count = FileStream.Read(buffer, 0, (int)bytesRemaining);
else
count = FileStream.Read(buffer, 0, buffer.Length);
if (count == 0)
return;
await response.Body.WriteAsync(buffer, 0, count);
bytesRemaining -= count;
}
catch (IndexOutOfRangeException)
{
await response.Body.FlushAsync();
return;
}
finally
{
await response.Body.FlushAsync();
}
}
}
public override async Task ExecuteResultAsync(ActionContext context)
{
await WriteVideoAsync(context.HttpContext.Response);
}
}
And parse request headers range:
public static RangeHeaderValue GetRanges(this HttpContext context, long contentSize)
{
RangeHeaderValue rangesResult = null;
string rangeHeader = context.Request.Headers["Range"];
if (!string.IsNullOrEmpty(rangeHeader))
{
// rangeHeader contains the value of the Range HTTP Header and can have values like:
// Range: bytes=0-1 * Get bytes 0 and 1, inclusive
// Range: bytes=0-500 * Get bytes 0 to 500 (the first 501 bytes), inclusive
// Range: bytes=400-1000 * Get bytes 500 to 1000 (501 bytes in total), inclusive
// Range: bytes=-200 * Get the last 200 bytes
// Range: bytes=500- * Get all bytes from byte 500 to the end
//
// Can also have multiple ranges delimited by commas, as in:
// Range: bytes=0-500,600-1000 * Get bytes 0-500 (the first 501 bytes), inclusive plus bytes 600-1000 (401 bytes) inclusive
// Remove "Ranges" and break up the ranges
string[] ranges = rangeHeader.Replace("bytes=", string.Empty).Split(",".ToCharArray());
rangesResult = new RangeHeaderValue();
for (int i = 0; i < ranges.Length; i++)
{
const int START = 0, END = 1;
long endByte, startByte;
long parsedValue;
string[] currentRange = ranges[i].Split("-".ToCharArray());
if (long.TryParse(currentRange[END], out parsedValue))
endByte = parsedValue;
else
endByte = contentSize - 1;
if (long.TryParse(currentRange[START], out parsedValue))
startByte = parsedValue;
else
{
// No beginning specified, get last n bytes of file
// We already parsed end, so subtract from total and
// make end the actual size of the file
startByte = contentSize - endByte;
endByte = contentSize - 1;
}
rangesResult.Ranges.Add(new RangeItemHeaderValue(startByte, endByte));
}
}
return rangesResult;
}
FYI, built-in support for range requests will be present in .NET Core 2.1
https://github.com/aspnet/Mvc/pull/6895
I could get the handle to the google text doc i needed. I am now stuck at how to read the contents.
My code looks like:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(Constants.CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(Constants.CONSUMER_SECRET);
oauthParameters.setOAuthToken(Constants.ACCESS_TOKEN);
oauthParameters.setOAuthTokenSecret(Constants.ACCESS_TOKEN_SECRET);
DocsService client = new DocsService("sakshum-YourAppName-v1");
client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full/");
DocumentQuery dquery = new DocumentQuery(feedUrl);
dquery.setTitleQuery("blood_donor_verification_template_dev");
dquery.setTitleExact(true);
dquery.setMaxResults(10);
DocumentListFeed resultFeed = client.getFeed(dquery, DocumentListFeed.class);
System.out.println("feed size:" + resultFeed.getEntries().size());
String emailBody = "";
for (DocumentListEntry entry : resultFeed.getEntries()) {
System.out.println(entry.getPlainTextContent());
emailBody = entry.getPlainTextContent();
}
Plz note that entry.getPlainTextContent() does not work and throws object not TextContent type exception
finally i solved it as:
for (DocumentListEntry entry : resultFeed.getEntries()) {
String docId = entry.getDocId();
String docType = entry.getType();
URL exportUrl =
new URL("https://docs.google.com/feeds/download/" + docType
+ "s/Export?docID=" + docId + "&exportFormat=html");
MediaContent mc = new MediaContent();
mc.setUri(exportUrl.toString());
MediaSource ms = client.getMedia(mc);
InputStream inStream = null;
try {
inStream = ms.getInputStream();
int c;
while ((c = inStream.read()) != -1) {
emailBody.append((char)c);
}
} finally {
if (inStream != null) {
inStream.close();
}
}
}