I installed the rets-client package from npm.
I ran other query and get meta which works fine but when I am trying to do the photo streaming example I kept on getting errors
Error: RetsReplyError: RETS Server reply while attempting getObject - ReplyCode 20403 (NO_OBJECT_FOUND); ReplyText: No Object Found [260978536:1].
I followed the the code in the example
https://github.com/sbruno81/rets-client#photo-streaming-example
try {
rets.getAutoLogoutClient(clientSettings, async (client) => {
const photoIds = {
'260978536': '*', // get all photos for listingId 260978536
};
const photoStream = await client.objects.stream.getObjects('Property', 'Photo', photoIds, {
alwaysGroupObjects: true,
ObjectData: '*'
});
console.log("========================================");
console.log("======== Photo Stream Results ========");
console.log("========================================");
return new Promise(function (resolve, reject) {
let i = 0;
photoStream.objectStream.on('data', function (event) {
try {
if (event.type === 'headerInfo') {
console.log(' ~~~~~~~~~ Header Info ~~~~~~~~~');
outputFields(event.headerInfo);
return
}
console.log(" -------- Photo " + (i + 1) + " --------");
if (event.type === 'error') {
console.log(" Error: " + event.error);
} else if (event.type === 'dataStream') {
outputFields(event.headerInfo);
fileStream = fs.createWriteStream(
"/tmp/photo_" + event.headerInfo.contentId + "_" + event.headerInfo.objectId + "." + event.headerInfo.contentType.match(/\w+\/(\w+)/i)[1]);
event.dataStream.pipe(fileStream);
}
i++;
} catch (err) {
reject(err);
}
});
photoStream.objectStream.on('error', function (errorInfo) {
reject(errorInfo);
});
photoStream.objectStream.on('end', function () {
resolve();
});
})
})
} catch (errorInfo) {
const error = errorInfo.error || errorInfo;
console.log(" ERROR: issue encountered:");
outputFields(error);
console.log(' ' + (error.stack || error).replace(/\n/g, '\n '));
}
reason I used that photo id is because when I do query I can see that this listing id has PictureCount of 20 but somehow it's giving me no object found.
sample listing query return for the same id
{ L_Area: 'Islands-Van. & Gulf',
L_ListingID: '260978536',
L_Status: 'Expired',
L_PictureCount: '20',
L_Last_Photo_updt: '2015-07-15T04:27:00',
L_DisplayId: 'V1064230' }
Can someone please give me a hand on where I am doing wrong here?
Thanks in advance for any help and suggestions.
P.S. I also tried using one L_ListingID with L_Status as Active instead of Expired but the result is the same
The RETS server you're connecting to does not allow image downloads because it's a staging server and they want to keep the bandwidth low. You'll have to test your code against their production server, or ask the MLS to allow downloads from their staging environment.
Points to note while downloading images from RETS server:
Ensure you have permission to access listing images.
Secondly check you have image download access or public image url access only(CDN link)? Depends on RETS server either one or both permission will be given.
To download images/imageURLs you need photoIds. Here either "listingId" or "listingKey" will work, again depends on RETS server. So try with both.
You may have access to multiple image types like Thumbnail, normal size and high resolution. That also you can mention in the "getObject" method.
Once an image/imageURL downloaded, frequently cross check Photo Modification Timestamp field to identify any modification to the image/imageURL.
Some of the RETS servers will provide image URLs as data via resources like Media, Tour etc.
Related
NativeScript core CameraPlus with MLKit doesn't works if saveToGallery is false. Are thera any method to do this without saving the photo in galery? It works with camera basic plugin.
Here is my code:
const HomeViewModel = require("./home-view-model");
const firebase = require("nativescript-plugin-firebase");
exports.onNavigatingTo = function (args) {
page = args.object;
mv = page.bindingContext = new HomeViewModel();
page.getViewById("camPlus")
.addEventListener("photoCapturedEvent", photoCapturedEvent);
};
exports.onCapture = function() {
camera = page.getViewById("camPlus");
//Must be false
camera.takePicture({ saveToGallery: false});
};
function photoCapturedEvent(args) {
const source = new imageSourceModule.ImageSource();
source.fromAsset(args.data).then((imageSource) => {
getTextFromPhoto(imageSource);
}).catch(function (err) {
console.log("Error -> " + err.message);
});
}
function getTextFromPhoto(imageSource) {
firebase.mlkit.textrecognition.recognizeTextOnDevice({
image: imageSource
}).then(function (result) {
mv.idContainer = getDataFromCameraText(result.text);
if (mv.idContainer == "") {
getTextFromPhotoOnline(imageSource);
} else {
containerDataIsValid(true);
}
}).catch(function (errorMessage) {
return console.log("ML Kit error: " + errorMessage);
});
}
The method "photoCapturedEvent" gives me an error of undefined:
JS: Error -> undefined
JS: Asset
'/storage/emulated/0/Android/data/org.nativescript.gScanContainer/files/IMG_1543942676583.jpg'
cannot be found.
how could I get te image without saving it?
I checked the source code of the plugin and it seems to be a bug. As the error says, they never save the image data in the path they pass on to the photo captured event.
So the only option for you would be, always enable saveToGallery and delete the file once you are done with getTextFromPhoto.
That's an older thread but since this hasn't been fixed in the plugin, for everybody who's running into the same problem, here's a solution:
Instead of always saving the image to the gallery and then tediously fetching it from there, storing it somewhere else and delete the image from the gallery, you can simply add this to the index.ios.js:
On line 490 ff you'll find the method MySwifty.prototype.savePhoto
On iOS, this._photoToSave is a UIImage and ImageAsset doesn't seem to like that. Hence the asset is empty.
So I added this to the method:
if (isIOS) {
const imageFolder = knownFolders.documents();
const iosImage = UIImageJPEGRepresentation(this._photoToSave, 0.7);
const result1 = NSFileManager.defaultManager.createFileAtPathContentsAttributes(imageFolder.path + "/cam_capture.jpg", iosImage, null);
const asset = new ImageAsset(imageFolder.path + "/cam_capture.jpg");
_this._owner.get().sendEvent(CameraPlus.photoCapturedEvent, asset);
_this.resetPreview();
}
This saves the image and returns an image asset to the photoCapturedEvent.
You can of course change the image name to something more generic and change the image-path, too.
If you want to save the image as PNG instead of JPG, then you'd use
const iosImage = UIImagePNGRepresentation(this._photoToSave);
I've written a webapp that allows you to store the images in the localStorage until you hit save (so it works offline, if signal is poor).
When the localStorage reaches 5MB Google Chrome produces an error in the javascript console log:
Uncaught Error: QUOTA_EXCEEDED_ERR: DOM Exception 22
How do I increase the size of the localStorage quota on Google Chrome?
5MB is a hard limit and that is stupid. IndexedDB gives you ~50MB which is more reasonable. To make it easier to use try Dexie.js https://github.com/dfahlander/Dexie.js
Update:
Dexie.js was actually still an overkill for my simple key-value purposes so I wrote this much simpler script https://github.com/DVLP/localStorageDB
with this you have 50MB and can get and set values like that
// Setting values
ldb.set('nameGoesHere', 'value goes here');
// Getting values - callback is required because the data is being retrieved asynchronously:
ldb.get('nameGoesHere', function (value) {
console.log('And the value is', value);
});
Copy/paste the line below so ldb.set() and ldb.get() from the example above will become available.
!function(){function e(t,o){return n?void(n.transaction("s").objectStore("s").get(t).onsuccess=function(e){var t=e.target.result&&e.target.result.v||null;o(t)}):void setTimeout(function(){e(t,o)},100)}var t=window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB;if(!t)return void console.error("indexDB not supported");var n,o={k:"",v:""},r=t.open("d2",1);r.onsuccess=function(e){n=this.result},r.onerror=function(e){console.error("indexedDB request error"),console.log(e)},r.onupgradeneeded=function(e){n=null;var t=e.target.result.createObjectStore("s",{keyPath:"k"});t.transaction.oncomplete=function(e){n=e.target.db}},window.ldb={get:e,set:function(e,t){o.k=e,o.v=t,n.transaction("s","readwrite").objectStore("s").put(o)}}}();
You can't, it's hard-wired at 5MB. This is a design decision by the Chrome developers.
In Chrome, the Web SQL db and cache manifest also have low limits by default, but if you package the app for the Chrome App Store you can increase them.
See also Managing HTML5 Offline Storage - Google Chrome.
The quota is for the user to set, how much space he wishes to allow to each website.
Therefore since the purpose is to restrict the web pages, the web pages cannot change the restriction.
If storage is low, you can prompt the user to increase local storage.
To find out if storage is low, you could probe the local storage size by saving an object then deleting it.
You can't but if you save JSON in your localStorage you can use a library to compress data like : https://github.com/k-yak/JJLC
demo : http://k-yak.github.io/JJLC/
Here you can test your program , you should handle also the cases when the cuota is exceed
https://stackoverflow.com/a/5664344/2630686 The above answer is much amazing. I applied it in my project and implement a full solution to request all kinds of resource.
// Firstly reference the above ldb code in the answer I mentioned.
export function get_file({ url, d3, name, enable_request = false }) {
if (name === undefined) { // set saved data name by url parsing alternatively
name = url.split('?')[0].split('/').at(-1).split('.')[0];
}
const html_name = location.href.split('/').at(-1).split('.')[0]
name = `${html_name}_${name}`
let ret = null;
const is_outer = is_outer_net(url); // check outer net url by its start with http or //
// try to access data from local. Return null if not found
if (is_outer && !enable_request) {
if (localStorage[name]) {
ret = new Promise(resolve => resolve(JSON.parse(localStorage[name])));
} else {
ret = new Promise(r => {
ldb.get(name, function (value) {
r(value)
})
});
}
} else {
ret = new Promise(r => r(null))
}
ret.then(data => {
if (data) {
return data
} else {
const method = url.split('.').at(-1)
// d3 method supported
if (d3 && d3[method]) {
ret = d3[method](url)
} else {
if (url.startsWith('~/')) { // local files accessed supported. You need a local service that can return local file data by requested url's address value
url = `http://localhost:8010/get_file?address=${url}`
}
ret = fetch(url).then(data => {
// parse data by requested data type
if (url.endsWith('txt')) {
return data.text()
} else {
return data.json()
}
})
}
ret = ret.then(da => {
data = da
if (is_outer) { // save data to localStorage firstly
localStorage[name] = JSON.stringify(data);
}
}).catch(e => { // save to ldb if 5MB exceed
ldb.set(name, data);
}).finally(_ => {
return data;
});
}
})
return ret;
}
I am running Node.js server with express. I'd also like the server to accept IceCast audio stream.
I could use another port, sure, but not all hostings (like Heroku) allow that. Ice cast's stream request looks like this:
SOURCE /mountpoint ICE/1.0\n
content-type: audio/mpeg\n
Authorization: Basic USER+PASS base64encoded\n
ice-name: This is my server name\n
ice-url: http://www.oddsock.org\n
ice-genre: Rock\n
ice-bitrate: 128\n
ice-private: 0\n
ice-public: 1\n
ice-description: This is my server description\n
ice-audio-info: ice-samplerate=44100;ice-bitrate=128;ice-channels=2\n
\n
After that, audio stream follows. I wrote a separate server that handles this on another port and it works fine.
var headers = "";
var headersEnd = false;
var mp3;
const audioServer = net.createServer(function (socket) {
if (mp3) {
socket.write("HTTP/1.0 403 Client already connected\r\n\r\n");
socket.end();
socket.on("error", (e) => {});
return;
}
mp3 = fs.createWriteStream("test.mp3", { encoding: null, flags: "a" });
socket.on("data", (data) => {
if (!headersEnd) {
var tmp = "";
for (let i = 0, l = data.byteLength; i < l; ++i) {
const item = data[i];
if (item == CR_NUMBER)
continue;
const character = String.fromCharCode(item);
tmp += character;
headers += character;
if (headers.endsWith("\n\n")) {
headersEnd = true;
console.log("ICE CAST HEADERS: \n", headers.replace(/\n/g, "\\n\n").replace(/\r/g, "\\r"));
break;
}
}
}
else {
mp3.write(data);
}
});
socket.on("close", () => {
console.log("ICE CAST: END");
if (mp3) {
mp3.close();
mp3 = null;
}
});
socket.on("error", (e) => {
console.log("ICE CAST: ERROR" + e.message);
socket.end();
});
});
audioServer.listen(11666);
What I'd like is to somehow bootstrap node's HTTP server so that I can stream over the same port.
I tried to access the req connection info, that doesn't really work, because the server does not even let the SOURCE /mountpoint ICE/1.0 through.
const server = http.createServer(function (req, res) {
/// does not happen, server closes the connection from icecast
if (handleAudioStream(req, res)) {
return;
}
else {
return expressApp(req, res);
}
});
So I'd need to go deeper. I tried to inspect the net and http code, but didn't fund anything useful.
How can I do this? I really need to use same port, and since icecast DOES send the HTTP-like headers, it should be possible.
This isn't trivial, but possible. You can do some duck punching/monkey patching. See this answer: https://stackoverflow.com/a/24298059/362536
Also, it may be possible to get official support some day, but we're a ways off from that. The first blocker was the non-standard SOURCE method. I sponsored a bounty on that and Ben Noordhuis was kind enough to implement last week: https://github.com/nodejs/http-parser/issues/405 It should land in Node.js eventually.
The next issue is the ICE/1.0. I've opened an issue for that here: https://github.com/nodejs/http-parser/issues/410 There hasn't been any objection to adding it to the parser yet, but if you want to add a pull request, that might help a chance of approval.
You'll find other compatibility issues as well as you continue down this road, but all I've hit I've been able to overcome with various solutions. The trick is, maintaining strict compatibility with the Node.js core as it is updated.
I tried to use getDownloadURL() method to retrieve the url of my images which stored in firebase storage.
Weird is it returns a url which is an object, instead of images
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓EXAMPLE URL↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/images%2Fcat.png
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑EXAMPLE URL↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
I did some research online and found out the correct url to display my image should be like this...
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓EXAMPLE URL↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/images%2Fcat.png?alt=media&token=sometoken
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑EXAMPLE URL↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
But I have no clue how to get the url by using getDownloadURL()...
Here's my code...
var storage = firebase.storage();
$scope.getImgUrl = function(file) {
storage.ref("images/" + file + ".png")
.getDownloadURL()
.then(function onSuccess(url) {
return url;
})
.catch(function onError(err) {
console.log("Error occured..." + err);
})
}
Any idea?
So the correct way to get an image url from Firebase is this:
$scope.getImgUrl = function(file) {
storage.child("images/" + file +".png").getDownloadURL().then(function(url) {
return url;
}).catch(function(error) {
// Handle any errors here
});
}
Note that you are using storage.child() instead of storage.ref()
The return you have in the then() callback doesn't do what you expect it to do. When you call getDownloadUrl() it returns a promise. If you simply bind that promise to the scope, you can use it in your HTML:
$scope.getImgUrl = function(file) {
return storage.ref("images/" + file + ".png").getDownloadURL();
}
this work for me
firebase.storage().ref().child('Audios/file.wav').getDownloadURL().then(function(downloadURL) {
console.log('File available at', downloadURL);
});
I was also stumbling around with the same problem a couple years later in 2020 xD
turns out... I just had to configure my firebase security to public when I'm testing from this
// Only authenticated users can read or write to the bucket
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
to this, in the firebase rules tab
// Only authenticated users can read or write to the bucket
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
the below code works for me. it works for video files and images.
var ref = firebase.storage().ref().child('child');
var file = document.querySelector("#htmlInputTagID").files[0];
var task = ref.child(('file name').toString()).put(file);
var imgURL = "";
task.then(snapshot => {
snapshot.ref.getDownloadURL().then(url => {
imgURL = url;//this is the URL I use and it works
//for me it can be done also for video files
});
});
Since Microsoft in those days is giving away 100GB + 100GB and I've got some GBs free for a few years I tought of using this space as a media storage directory for files downloaded from my VPS.
So I started reading the OneDrive REST Docs for authenticate myself using Node.JS and I did it successfully.
I'm able to:
Login and access whenever I want (using Access Tokens and Refresh Tokens)
Upload, edit, remove a file
Create, edit, remove a directory
List a directory content
All of this by using the REST API.
The problem is that due to some rescrition of these OneDrive REST APIs I have to cycle through directories to detect their contents (making N calls, depending on the depth of the folder) instead of requesting one single time the desired directory.
I'm just trying to develop a ls like command for OneDrive to complete my VPS-OneDrive sync project.
This is my code so far:
function lsdir(path, originalpath, folder, callback) {
dirs = path.split("/");
if (folder == null) {
originalpath = path;
request("https://apis.live.net/v5.0/me/skydrive?access_token=" + at, function(err, res, body) {
var json = JSON.parse(body);
var upload_location = json.upload_location;
request(upload_location + "?access_token=" + at, function(err, res, body) {
//console.log(body);
json = JSON.parse(body);
var found = false;
if (originalpath == "/") {
callback(json, originalpath);
return;
}
for (i in json.data) {
currentFolder = json.data[i];
if (currentFolder.name == dirs[1]) {
found = currentFolder;
if (dirs.length > 2) {
lsdir(dirs.slice(2, dirs.length).join("/"), originalpath, currentFolder, callback);
} else {
callback(currentFolder, originalpath);
return;
}
break;
}
}
});
});
} else if (dirs.length > 0) {
request(folder.upload_location + "/?access_token=" + at, function(err, res, body) {
json = JSON.parse(body);
var found = false;
if (dirs.length == 1) {
callback(json, originalpath);
} else {
for (i in json.data) {
currentFolder = json.data[i];
if (currentFolder.name == dirs[0]) {
lsdir(dirs.slice(1, dirs.length).join("/"), originalpath, currentFolder, callback);
break;
}
}
}
});
}
}
lsdir("/vpsSync/", null, null, function(folder, originalpath) {
console.log(("Directory contents of " + originalpath).bold);
console.log(folder.data.map(function(arr) {
if (arr.type == "folder") {
return arr.name + "/";
}
return arr.name;
}).join("\n"));
});
Is there a way to reduce the recursion (or remove it completly)? The Micro$ft servers are really slow (3-5 secs per request!)
Thank you all and enjoy the 215GB of OneDrive :)
You may want to consider using our just-announced API, which has the ability to do sync.
http://onedrive.github.io/items/view_changes.htm
If you start the sync operation from the point at which you want to begin traversing the hierarchy, and do not provide a token, it should return you a complete view. For larger hierarchies you will still need to make multiple requests (based on the value of "#changes.hasMorechanges" and "#odata.nextLink") but that will still be far fewer than one per folder.