Issue with a topjson object in a Meteor app built with coffeescript - coffeescript

Apologies for the lack of precision in the question, but I'm not completely sure which of possibly many things I'm doing wrong here.
I'm relatively new to Coffeescript and also geo applications in general, but here goes:
I've got a working (simple) Meteor (.7.0.1) application utilizing coffeescript in both client and server. The issue I'm having occurs when attempting to utilize TopoJSON encoded files to create a layer of US congressional districts. (the purpose of the app is to help highlight voter suppression in the US)
So, a few things: Typically in a non-Meteor app, I would just load the topoJSON file like so:
$.getJSON('./data/us-congress-113.json', function (data) {
var congress_geojson = topojson.feature(data, data.objects.districts);
congress_layer.addData(congress_geojson);
});
Now of course this won't work in Meteor because its not asynchronous.
One of the things that was recommended here on SO was to not worry about reading the file, and to instead change the json file to .js, and then set the contents (which are of course just an object) equal to a variable.
Here's what I did:
First, I changed the .json file to a .js file in the server directory, and added the "congress =" to the beginning of the file. It's a huge file so forgive me for omitting the whole object.
congress = {"type":"Topology",
"objects":
{"districts":
{"type":"GeometryCollection","geometries":[{"type":"Polygon"
Now here's where everything starts to give me issues:
In the server.coffee, I've created a variable like so to reference the congress object:
#congress_geojson = topojson.feature(congress, congress.objects.districts)
Notice how I'm putting the # symbol there? I've been told this allows a variable in Coffeescript to be globally scoped? I tried to also use a Meteor feature called "share" where I declare the variable as "share.congress_geojson". That led to the same issues which I will describe below.
Now in the client.coffee file, I'm trying to call this variable to load into a Leaflet map.
congress_layer = L.geoJson(null,
style:
color: "#DE0404"
weight: 2
opacity: 0.4
fillOpacity: 0.1
)
congress_layer.addData(#congress_geojson)
This isn't working, and specifically (despite attempts to find other ways, the errors I'm getting in the console are:
Exception from Deps afterFlush function: TypeError: Cannot read property 'features' of undefined
at o.GeoJSON.o.FeatureGroup.extend.addData (http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:39:16471)
at Object.Template.map.rendered (http://localhost:3000/client/client.coffee.js?37b1cdc5945f3407f2726a5719e1459f44d1db2d:213:18)
I have no doubt that I'm missing something stupidly obvious here. Any suggestions or tips for what I'm doing completely wrong would be appreciated. Is it a case where an object globally declared in a .js file isn't available to code in a .coffee file? Maybe I'm doing something wrong on the Meteor side?
Thanks!
Edit:
So I was able to get things working by putting the .js file containing the congress object in a root /lib folder, causing the object to load first, and then calling the congress object from the client. However, I'm still wanting to know how I could simply share this object from the server? What is the "Meteor way" here?

If you are looking for the Meteor way to order the loading of files, use the Meteor.startup function and put the initialization code there. That function is the $.ready of the Meteor world, i.e., it will execute only after all your files have been successfully loaded on the client.
So in your case:
Meter.startup ->
congress_layer.addData(#congress_geojson)

Related

How can I manually edit the list of recently opened files in VS Code?

I rely heavily on the File: Open Recent… command to open frequently used files, but yesterday my local Google Drive folder got moved to a new location and now I can no longer access any of the files in that folder through the Open Recent panel because the paths don't match.
The fix would be as simple as replacing "/Google Drive/" with "/Google Drive/My Drive/" but I have no idea what file contains the list of files that appears in the recently opened panel.
I'm assuming it's somewhere in ~/Library/Application Support/Code but not sure where.
I was wondering the same thing the other day and found this while searching for a solution, so I took some time to investigate it today.
It's been a a few weeks since you posted, so hopefully this will still be of help to you.
Also, I'm using Windows and I'm not familiar with macOS, but I think it should be easy enough adjust the solution.
Location of settings
Those setting are stored in the following file: %APPDATA%\Code\User\globalStorage\state.vscdb.
The file is an sqlite3 database, which is used as a key-value store.
It has a single table named ItemTable and the relevant key is history.recentlyOpenedPathsList.
The value has the following structure:
{
"entries": [
{
"folderUri": "/path/to/folder",
"label": "...",
"remoteAuthority": "..."
}
]
}
To view the current list, you can run the following command:
sqlite3.exe -readonly "%APPDATA%\Code\User\globalStorage\state.vscdb" "SELECT [value] FROM ItemTable WHERE [key] = 'history.recentlyOpenedPathsList'" | jq ".entries[].label"
Modifying the settings
Specifically, I was interested in changing the way it's displayed (the label), so I'll detail how I did that, but it should be just as easy to update the path.
Here's the Python code I used to make those edits:
import json, sqlite3
# open the db, get the value and parse it
db = sqlite3.connect('C:/Users/<username>/AppData/Roaming/Code/User/globalStorage/state.vscdb')
history_raw = db.execute("SELECT [value] FROM ItemTable WHERE [key] = 'history.recentlyOpenedPathsList'").fetchone()[0]
history = json.loads(history_raw)
# make the changes you'd like
# ...
# stringify and update
history_raw = json.dumps(history)
db.execute(f"UPDATE ItemTable SET [value] = '{history_raw}' WHERE key = 'history.recentlyOpenedPathsList'")
db.commit()
db.close()
Code references
For reference (mostly for my future self), here are the relevant source code areas.
The settings are read here.
The File->Open Recent uses those values as-is (see here).
However when using the Get Started page, the Recents area is populated here. In the Get Started, the label is presented in a slightly different way:
vscode snapshot
The folder name is the link, and the parent folder is the the text beside it.
This is done by the splitName method.
Notes
Before messing around with the settings file, it would be wise to back it up.
I'm not sure how vscode handles and caches the settings, so I think it's best to close all vscode instances before making any changes.
I haven't played around with it too much, so not sure how characters that need to be json-encoded or html-encoded will play out.
Keep in mind that there might be some state saved by other extensions, so if anything weird happens, blame it on that.
For reference, I'm using vscode 1.74.2.
Links
SQLite command-line tools
jq - command-line JSON processor

Eclipse Plugin Development: Adding items to a working set with the path of the item?

Hello,
I'm an eclipse plugin development newbie looking for pointers to get me started on a particular project.
I am trying to build an eclipse plugin that will automatically construct a working set from a text file that simply consists of a list of file path names. The files/items need not share any parent directories. The rough idea is represented in the following diagram:
I am not asking for the solution to this task. That's the over-arching goal. To achieve that goal, I want to conquer some smaller goals first.
With that in mind, here's the smaller goal I'm currently trying to tackle:
In Eclipse, how can I prompt the user for a single file's path, and then add that file to an existing working set?
I'm not sure where to start. Should I work directly off of the existing org.eclipse.ui.workingSets extension point? Or should I use a collection of other extension points? How do I convert strings into something that can be added to a working set? Do I write code that directly modifies the workingsets.xml file?
Even with a much simpler goal, I still feel quite overwhelmed with the vastness of eclipse extension options. There are probably many ways to go about implementing something like this, but I just need one to get started.
Thanks a bunch!
To manipulate working sets you use the working set manager interface IWorkingSetManager. Get this with:
IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager();
From this you can get a particular working by name with:
IWorkingSet workingSet = manager.getWorkingSet("name");
The contents of a working set is an array of IAdaptable objects:
IAdaptable [] contents = workingSet.getElements();
You add to the contents by adding to this array and setting the contents:
IAdaptable [] newContents
.... get new array with old contents + new contents
workingSet.setElements(newContents);
A lot of Eclipse objects implement IAdaptable, for a file in the workspace you would use IFile. You can use dialogs such as ResourceSelectionDialog to select resources from the workspace.

Meteor, coffeescript files running on every page

I am just getting started with Meteor and have encountered something that isn't necessarily an issue but something that I just don't understand. I have the following code in a file called chat.coffee...
Meteor.setInterval ( ->
console.log "Hello " + roomName
Meteor.call('keepAlive', Meteor.user(), roomName)
return
), 5000
I originally was under the impression that coffee-script files only ran on their associated html files. This doesn't seem to be the case here as this code runs on every single page regardless of the file name. Is this the intended way things are supposed to work, and if so, is there a way to enforce that only certain code runs on certain pages.
One thing to mention is that this code is running in the client side folder.
On the client side, Meteor will associate your templates with their javascript functions and helpers based upon shared template names, but that is not inherently tied to your file names.
By way of example, if you have a template named "chat" in an html file as follows:
<template name="chat"></template>
Meteor will run scripts such as Template.chat.helpers({}) or Template.chat.events({}) only in connection with the "chat" template. But that is not dependent on your file naming conventions. It could be placed in a file name chat.js for organization and convention, but could equally well reside in a file named client.js or any other arbitrarily named .js file.
Similarly, your <template name="chat"> could reside in a file named chat.html, or client.html, or an arbitrary name of your choosing.
Your setInterval function is not tied to a specific template so it will run on every page, even if it resides in a file named chat.js.
Correct.
Meteor merges all your javascript ( via coffeescript ) and all the html, which it stores in its own special way. It merges all the html in heads and body etc into a page and serves that up, and it will then render templates as you specify.
To have a more "page" oriented app you can use something like iron router.

Moodle local plugins and save_file

I've created a working form within a local plugin and it is inserting data fine into my custom table.
What I want tyo add now is a filepicker element that upon saving the form puts the file into a specified folder.
The filep[icker itself works fine but when I save the form no file appears, the code I'm using looks like this:
$mform->save_file('lowresCh', '/my_form/', false);
I've tried various things in the 'my_form' bit, but to no avail. The rest of the form still puts its data into the custom table and I can see my file in the mdl_files table (marked as draft).
With full debugging on I can get a warning of:
Warning: copy(/my_form/): failed to open stream: Is a directory in /...../lib/filestorage/stored_file.php on line 390
I don't know if I'm approaching it incorrectly or not, any help or pointers in the right direction would be most appreciated. 
Oh and I have read the Using the File API in Moodle forms page, useful in getting me to the point I'm at, but no further.
I solved it by using the filename as the second argument in save_file() and if I prepend a directory then all of the files will be saved within my plugin in a sub directory which is perfect.
So it looks like this now:
$mform->save_file('lowresCh', 'files/'.$mform->get_new_filename('lowresCh'), false);

How could I embedded socket in Lua internally, just like oslib, debuglib?

I want to implement the function like embedding the socket function in my Lua build.
So I don't need to copy socket.core.dll any more (just for fun).
I search the maillist, and see some guys discuss the topic,
http://lua-users.org/lists/lua-l/2005-10/msg00269.html
But I have question for the details steps, who could give me a detailed steps for changing the lua and luasocket code to make them work together (not with dll method).
I tried these steps in windows xp with VC2008:
1) copy luasocket code to Lua project.
2) add some code
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_SOCKETLIBNAME, luaopen_socket_core}, // add this line
{LUA_MIMELIBNAME, luaopen_socket_core}, // add this line
{NULL, NULL}
};
3) build the project, and run it.
When I type print(socket._VERSION), it shows luasocket 2.0.2, it is correct.
When I type print(socket.dns.toip("localhost")), it shows 127.0.0.1 table: 00480AD0, it is correct too.
But when I try to use other features, for example bind, it can't work.
Who could tell me the reason?
you need put luasocket stuff into the package.preload table, in this way:
lua_getfield(L, LUA_GLOBALSINDEX, "package");
lua_getfield(L, -1, "preload");
lua_pushcfunction(L, luaopen_socket_core);
lua_setfield(L, -2, "socket.core");
// add mime.core yourself...
luasocket is a mixed C/lua module, you need to bundle both versions into your application if you want it to work without any extra files.
socket.lua loads socket.core (from socket/core.dll)
mime.lua loads mime.core (from mime/core.dll)
So in order for your application to work you will need to build all the .dll files and the .lua files into your application and manually load them (or set them up to be loaded correctly via custom package loaders).
The email you quoted is tweaking the package.preload table (in a way that appears a tad odd now but might work anyway) to get the built-in C code to be loaded correctly when require is called.
Try running
for k, v in pairs(socket) do print(k, v) end
and maybe we'll be able to help.