I have been following this, this, this, this and this to create my own template in ST3. So when I create a new file, I preload the file with template content. I have read I should do this with a snippet.
I create a file and try to apply a snippet in the new view, but nothing happens, I do not get any feedback (not even when I input a wrong snippet name on purpose). My snippet is inside my plugin folder:
C:\Users\...\AppData\Roaming\Sublime Text 3\Packages\MyPlugin\templ.sublime-snippet
My multiple attempts are below:
def on_done(...):
...
open(path, 'a').close()
new_view = self.window.open_file(path)
# These seem to work, so the view seems valid
print(new_view.file_name())
print(new_view.line_height())
# Attempt 1
template = """<snippet>
<content><![CDATA[
Hello, \${1:this} is a \${2:snippet}.
]]></content>
</snippet>
"""
new_view.run_command("insert_snippet", {"contents": template})
# Attempt 2: from the user folder. Nothing happens
new_view.run_command("insert_snippet", { "name": "Packages/User/templ.sublime-snippet" })
# Attempt 3: from current (?) folder just in case
new_view.run_command("insert_snippet", {"name" : "templ.sublime-snippet"})
# Attempt 4, from the actual plugin folder
new_view.run_command("insert_snippet", {"name" : "Packages/MyPlugin/templ.sublime-snippet"})
# Attempt 5, absolute directory
new_view.run_command("insert_snippet", {"name" : "C:\\Users\\nerea\\AppData\\Roaming\\Sublime Text 3\\Packages\\MyPlugin\\templ.sublime-snippet"})
# Attempt 6, to check if I mistook the path if I would get any error
new_view.run_command("insert_snippet", {"name" : "Packages/User/nonexisting.sublime-snippet"})
# Attempt 7, nothing either
new_view.run_command("insert_snippet", {"contents" : "<snippet><content><![CDATA[Hello, ${1:this} is a ${2:snippet}.]]></content></snippet>"})
# This does nothing either. I supposed that should do something
new_view.run_command("insert", "wawawiwa")
The problem is that the view hasn't finished loading the file you specified when you execute the insert_snippet command.
I recommend to try this:
new_view = self.window.open_file(path)
def do_insert():
if not new_view.is_loading():
new_view.run_command("insert_snippet", { "name": "Packages/MyPlugin/templ.sublime-snippet" })
sublime.set_timeout_async(do_insert, 10)
do_insert()
if you are calling insert_snippet with the contents argument, the API expects just the snippet contents - i.e. Hello, ${1:this} is a ${2:snippet}. instead of the surrounding XML.
Note that having a backslash before the dollar in the snippet contents will cause ST to treat the dollar literally instead of delineating tab/edit points.
Related
I am a very inexperienced programmer with no formal education. Details will be extremely helpful in any responses.
I have made several basic python scripts to call SOAP APIs, but I am running into an issue with a specific API function that has an embedded array.
Here is a sample excerpt from a working XML format to show nested data:
<bomData xsi:type="urn:inputBOM" SOAP-ENC:arrayType="urn:bomItem[]">
<bomItem>
<item_partnum></item_partnum>
<item_partrev></item_partrev>
<item_serial></item_serial>
<item_lotnum></item_lotnum>
<item_sublotnum></item_sublotnum>
<item_qty></item_qty>
</bomItem>
<bomItem>
<item_partnum></item_partnum>
<item_partrev></item_partrev>
<item_serial></item_serial>
<item_lotnum></item_lotnum>
<item_sublotnum></item_sublotnum>
<item_qty></item_qty>
</bomItem>
</bomData>
I have tried 3 different things to get this to work to no avail.
I can generate the near exact XML from my script, but a key attribute missing is the 'SOAP-ENC:arrayType="urn:bomItem[]"' in the above XML example.
Option 1 was using MessagePlugin, but I get an error because my section is like the 3 element and it always injects into the first element. I have tried body[2], but this throws an error.
Option 2 I am trying to create the object(?). I read a lot of stack overflow, but I might be missing something for this.
Option 3 looked simple enough, but also failed. I tried setting the values in the JSON directly. I got these examples by an XML sample to JSON.
I have also done a several other minor things to try to get it working, but not worth mentioning. Although, if there is a way to somehow do the following, then I'm all ears:
bomItem[]: bomData = {"bomItem"[{...,...,...}]}
Here is a sample of my script:
# for python 3
# using pip install suds-py3
from suds.client import Client
from suds.plugin import MessagePlugin
# Config
#option 1: trying to set it as an array using plugin
class MyPlugin(MessagePlugin):
def marshalled(self, context):
body = context.envelope.getChild('Body')
bomItem = body[0]
bomItem.set('SOAP-ENC:arrayType', 'urn:bomItem[]')
URL = "http://localhost/application/soap?wsdl"
client = Client(URL, plugins=[MyPlugin()])
transact_info = {
"username":"",
"transaction":"",
"workorder":"",
"serial":"",
"trans_qty":"",
"seqnum":"",
"opcode":"",
"warehouseloc":"",
"warehousebin":"",
"machine_id":"",
"comment":"",
"defect_code":""
}
#WIP - trying to get bomData below working first
inputData = {
"dataItem":[
{
"fieldname": "",
"fielddata": ""
}
]
}
#option 2: trying to create the element here and define as an array
#inputbom = client.factory.create('ns3:inputBOM')
#inputbom._type = "SOAP-ENC:arrayType"
#inputbom.value = "urn:bomItem[]"
bomData = {
#Option 3: trying to set the time and array type in JSON
#"#xsi:type":"urn:inputBOM",
#"#SOAP-ENC:arrayType":"urn:bomItem[]",
"bomItem":[
{
"item_partnum":"",
"item_partrev":"",
"item_serial":"",
"item_lotnum":"",
"item_sublotnum":"",
"item_qty":""
},
{
"item_partnum":"",
"item_partrev":"",
"item_serial":"",
"item_lotnum":"",
"item_sublotnum":"",
"item_qty":""
}
]
}
try:
response = client.service.transactUnit(transact_info,inputData,bomData)
print("RESPONSE: ")
print(response)
#print(client)
#print(envelope)
except Exception as e:
#handle error here
print(e)
I appreciate any help and hope it is easy to solve.
I have found the answer I was looking for. At least a working solution.
In any case, option 1 worked out. I read up on it at the following link:
https://suds-py3.readthedocs.io/en/latest/
You can review at the '!MessagePlugin' section.
I found a solution to get message plugin working from the following post:
unmarshalling Error: For input string: ""
A user posted an example how to crawl through the XML structure and modify it.
Here is my modified example to get my script working:
#Using MessagePlugin to modify elements before sending to server
class MyPlugin(MessagePlugin):
# created method that could be reused to modify sections with similar
# structure/requirements
def addArrayType(self, dataType, arrayType, transactUnit):
# this is the code that is key to crawling through the XML - I get
# the child of each parent element until I am at the right level for
# modification
data = transactUnit.getChild(dataType)
if data:
data.set('SOAP-ENC:arrayType', arrayType)
def marshalled(self, context):
# Alter the envelope so that the xsd namespace is allowed
context.envelope.nsprefixes['xsd'] = 'http://www.w3.org/2001/XMLSchema'
body = context.envelope.getChild('Body')
transactUnit = body.getChild("transactUnit")
if transactUnit:
self.addArrayType('inputData', 'urn:dataItem[]', transactUnit)
self.addArrayType('bomData', 'urn:bomItem[]', transactUnit)
I have a Jupyter Notebook running. I want to be able to access the source of the current Jupyter Notebook from within Python. My end goal is to pass it into ast.parse so I can do some analysis on the user's code. Ideally, I'd be able to do something like this:
import ast
ast.parse(get_notebooks_code())
Obviously, if the source code was an IPYNB file, there'd be an intermediary step of extracting the code from the Python cells, but that's a relatively easy problem to solve.
So far, I've found code that will use the list_running_servers function of the IPython object in order to make a request and match up kernel IDs - this gives me the filename of the currently running notebook. This would work, except for the fact that the source code on disk may not match up with what the user has in the browser (until you save a new checkpoint).
I've seen some ideas involving extracting out data using JavaScript, but that requires either a separate cell with magic or calling the display.Javascript function - which fires asynchronously, and therefore doesn't allow me to pass the result to ast.parse.
Anyone have any clever ideas for how to dynamically get the current notebooks source code available as a string in Python for immediate processing? I'm perfectly fine if I need to make this be an extension or even a kernel wrapper, I just need to get the source code somehow.
Well, this isn't exactly what I wanted, but here's my current strategy. I need to run some Python code based on the user's code, but it doesn't actually have to be connected to the user's code directly. So I'm just going to run the following magic afterwards:
%%javascript
// Get source code from cells
var source_code = Jupyter.notebook.get_cells().map(function(cell) {
if (cell.cell_type == "code") {
var source = cell.code_mirror.getValue();
if (!source.startsWith("%%javascript")) {
return source;
}
}
}).join("\n");
// Embed the code as a Python string literal.
source_code = JSON.stringify(source_code);
var instructor_code = "student_code="+source_code;
instructor_code += "\nimport ast\nprint(ast.dump(ast.parse(student_code)))\nprint('Great')"
// Run the Python code along with additional code I wanted.
var kernel = IPython.notebook.kernel;
var t = kernel.execute(instructor_code, { 'iopub' : {'output' : function(x) {
if (x.msg_type == "error") {
console.error(x.content);
element.text(x.content.ename+": "+x.content.evalue+"\n"+x.content.traceback.join("\n"))
} else {
element.html(x.content.text.replace(/\n/g, "<br>"));
console.log(x);
}
}}});
What about combining https://stackoverflow.com/a/44589075/1825043 and https://stackoverflow.com/a/54350786/1825043 ? That gives something like
%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
and
import os
from nbformat import read, NO_CONVERT
nb_full_path = os.path.join(os.getcwd(), nb_name)
with open(nb_full_path) as fp:
notebook = read(fp, NO_CONVERT)
cells = notebook['cells']
code_cells = [c for c in cells if c['cell_type'] == 'code']
for no_cell, cell in enumerate(code_cells):
print(f"####### Cell {no_cell} #########")
print(cell['source'])
print("")
I get
####### Cell 0 #########
%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
####### Cell 1 #########
import os
from nbformat import read, NO_CONVERT
nb_full_path = os.path.join(os.getcwd(), nb_name)
with open(nb_full_path) as fp:
notebook = read(fp, NO_CONVERT)
cells = notebook['cells']
code_cells = [c for c in cells if c['cell_type'] == 'code']
for no_cell, cell in enumerate(code_cells):
print(f"####### Cell {no_cell} #########")
print(cell['source'])
print("")
Trying to create a function to streamline some automation.
When the javascript is called with the arguments directly it works perfectly and the file is created.
browser.execute_script("HAR.clear({token: \"abcd\"})")
browser.find_element_by_link_text("B").click()
browser.execute_script("HAR.triggerExport({token: \"abcd\", fileName: \"name_of_file\"}).then(result => {})")
When i try to pass it as a variable, there are no errors but the har file is not created.
Call:
simple_find("B",'\\"name_of_file\\"')
Function:
def simple_find (element, filename):
browser.execute_script("HAR.clear({token: \"abcd\"})")
browser.find_element_by_link_text(element).click()
options = '{token: \\"abcd\\", fileName: '+filename+'}'
ret=browser.execute_script("HAR.triggerExport(arguments[0]).then(result => {});return arguments[0]",options)
print ret
I added the return piece to help debug what is being passed and here is the output:
C:>python firefox-Manage.py
{token: \"abcd\", fileName: \"name_of_file\"}
It looks exactly like the call made earlier with the exception of the file not being created. What am I missing?
java version is: 1.8.0_66
selenium version is: 2.48.2
python version is: 2.7.10
thx
Your options object created from Python looks malformed. There's no reason to surround the values with \\":
options = '{token: \\"abcd\\", fileName: '+filename+'}'
My guess would be you want to pass a dictionary directly to selenium instead of a string:
options = {'token': "abcd", 'fileName': filename}
I have read alot about this but I just don't seem to figure it out... I should use Blueprint for this but the problem I am having right now is that I do not know how to pass my variable from my main file in my second file.
As an example :
/app
/runserver.py
/app
init.py
main.py
second.py
Now I do have a dictionairy in my main that I fill. And I want to use it in my second file to adjust it etc. How will I be able to do this? Since I tried to import the files and tried:
import main
dictMain = main.dictFromMain
I thought this would be enough since I read it on different question on Stack Overflow but it doesn't seem to work!
EDIT: To sketch the problem further
More background : I am making a client - server application, the client is receiving and sending data from the server. But there is a difference is the data the client is sending. On one hand you have files and paramters which I want to 'capture' with my second file with ReST. And on the other hand I got a incomming stream which I 'capture' in my main file.
Example second file:
#app.route('/uploads/', methods = ['GET', 'POST'])
def get_files():
if request.method == 'GET':
sendDict = []
for element in ctxList:
for fileCtx in element['file']:
d = { 'id' : element['id'], 'file': [ {'name': fileCtx['name'], 'uri' : fileCtx['uri'], 'path' : fileCtx['path'] } ] }
sendDict.append(d)
jsonString = jsonify(ctx=sendDict)
return jsonString
But this code uses a dictionairy from my first file (the dict ctxList) I have no idea to get it out of my first file. I used to get a error when I did : ctxList = mainFile.ctxList that the module did not have this variable, but now I am getting a error that the first file does not know the URL structure ( /uploads/ from the second file).
Pretty new to Python so I'm struggling picking this part up.
I want to put arrays into a text file and have them called with in my .py
Here is what I had:
import json
myfile = open("lists.txt")
myVars = json.load(myfile)
myVars['alist']
and in the lists.txt file:
{
"alist" : [
["1", "2", "3"]
],
"b" : [
["test"]
]
}
I called it in my .py with:
if message.body == "!r alist":
room.message("I recommend: " + choice(alist))
print("did it work?")
(choice is just to get a random one, etc.)
Something is not adding up with the code snippets. Your json loading is fine. You can pass a file pointer to json.load
The problem looks to be here:
if message.body == "!r alist":
room.message("I recommend: " + choice(alist))
print("did it work?")
Is choice a method/function? Where is it defined? Where is alist declared in this code snippet. After loading the json file you need to access alist using:
myAList = myVars['alist']
choice(myAList[0])
Assuming that choice is a valid method that can access myAList. I suspect you are not connecting the pieces of code together properly.
You're only referencing a file pointer... You're not actually loading in the data.
myfile = open('lists.txt').read()
That should give you your string which you can then load into an object using json