sublime text 3 auto-complete plugin not working - python

I try to write a plugin to get all the classes in current folder to do an auto-complete injection.
the following code is in my python file:
class FolderPathAutoComplete(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
folders = view.window().folders()
results = get_path_classes(folders)
all_text = ""
for result in results:
all_text += result + "\n"
#sublime.error_message(all_text)
return results
def get_path_classes(folders):
classesList = []
for folder in folders:
for root, dirs, files in os.walk(folder):
for filename in files:
filepath = root +"/"+filename
if filepath.endswith(".java"):
filepath = filepath.replace(".java","")
filepath = filepath[filepath.rfind("/"):]
filepath = filepath[1:]
classesList.append(filepath)
return classesList
but somehow when I work in a folder dir with a class named "LandingController.java" and I try to get the result, the auto complete is not working at all.
However, as you may noticed I did a error_message output of all the contents I got, there are actual a list of class name found.
Can anyone help me solve this? thank you!

It turn outs that the actual format which sublime text accept is: [(word,word),...]
but thanks to MattDMo who point out the documentation since the official documentation says nothing about the auto complete part.
For better understanding of the auto complete injection api, you could follow Zinggi's plugin DictionaryAutoComplete and this is the github link
So for a standard solution:
class FolderPathAutoComplete(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
suggestlist = self.get_autocomplete_list(prefix)
return suggestlist
def get_autocomplete_list(self, word):
global classesList
autocomplete_list = []
uniqueautocomplete = set()
# filter relevant items:
for w in classesList:
try:
if word.lower() in w.lower():
actual_class = parse_class_path_only_name(w)
if actual_class not in uniqueautocomplete:
uniqueautocomplete.add(actual_class)
autocomplete_list.append((actual_class, actual_class))
except UnicodeDecodeError:
print(actual_class)
# autocomplete_list.append((w, w))
continue
return autocomplete_list

Related

try except block prints 'hello'

I have a perculiar problem.
I'm using the extract_msg package to analyse a bunch of .msg files.
The package results in an NotImplementedError error when the .msg file contains attachtments.
I'm using a try-except block to catch this error, but for some weird reason its prints "hello" for every error it finds. Nowhere in my code I wrote it to print "hello" so I'm a bit baffled here.
Has anyone seen this before? And how can I avoid this strange thing from happening?
#f-variabele
f = glob.glob(r'D:\AA Brenda\Python\DVS_lang\*\*.msg', recursive=True)
instead of this please do like this and try again
f = glob.glob(r'D:/AA Brenda/Python/DVS_lang/**/*.msg', recursive=True)
#loop over folders
paths =[]
senders = []
recipients = []
dates = []
subjects = []
body = []
#append data to lists:
for filename in f:
try:
msg = extract_msg.Message(filename)
paths.append(filename)
senders.append(msg.sender)
recipients.append(msg.to)
dates.append(msg.date)
subjects.append(msg.subject)
body.append(msg.body)
except NotImplementedError: #"NotImplementedError: Current version of ExtractMsg.py does not
#support extraction of containers that are not embeded msg files."
print("")
It's in their library:
https://github.com/TeamMsgExtractor/msg-extractor/blob/master/extract_msg/msg.py#L644
If that really bothers you, you can use the following:
How to block calls to print?

How do I get the path of an open Microsoft Office program from the command line?

I'm writing something in python that needs to know which specific files/programs are open. I've mapped the list of running processes to find the executable paths of the processes I'm looking for. This works for most things, but all Microsoft Office programs run under general processes like WINWORD.exe or EXCEL.exe etc. I've also tried getting a list of open windows and their titles to see what file is being edited, but the window titles are relative paths not absolute paths to the file being edited.
Here's a sample:
import wmi
f = wmi.WMI()
pid_map = {}
PID = 4464 #pid of Microsoft Word
for process in f.Win32_Process():
if not process.Commandline: continue
pid_map[process.ProcessID] = process.Commandline
pid_map[PID]
Outputs:
'"C:\\Program Files\\Microsoft Office\\root\\Office16\\WINWORD.EXE" '
How do I get the path of the file actually being edited?
I figured it out. Here is a function that will return the files being edited.
import pythoncom
def get_office(): # creates doctype: docpath dictionary
context = pythoncom.CreateBindCtx(0)
files = {}
dupl = 1
patt2 = re.compile(r'(?i)(\w:)((\\|\/)+([\w\-\.\(\)\{\}\s]+))+'+r'(\.\w+)') #matches files, can change the latter to only get specific files
#look for path in ROT
for moniker in pythoncom.GetRunningObjectTable():
name = moniker.GetDisplayName(context, None)
checker = re.search(patt2,name)
if checker:
match = checker.group(5) #extension
if match in ('.XLAM','.xlam'): continue #These files aren't useful
try:
files[match[1:]] # check to see if the file type was already documented
match += str(dupl)
dupl += 1
except KeyError:
pass
files[match[1:]] = name #add doctype: doc path pairing to dictionary

Python - pygithub If file exists then update else create

Im using PyGithub library to update files. Im facing an issue with that. Generally, we have to options. We can create a new file or if the file exists then we can update.
Doc Ref: https://pygithub.readthedocs.io/en/latest/examples/Repository.html#create-a-new-file-in-the-repository
But the problem is, I want to create a new file it if doesn't exist. If exist the use update option.
Is this possible with PyGithub?
I followed The Otterlord's suggestion and I have achieved this. Sharing my code here, it maybe helpful to someone.
from github import Github
g = Github("username", "password")
repo = g.get_user().get_repo(GITHUB_REPO)
all_files = []
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
else:
file = file_content
all_files.append(str(file).replace('ContentFile(path="','').replace('")',''))
with open('/tmp/file.txt', 'r') as file:
content = file.read()
# Upload to github
git_prefix = 'folder1/'
git_file = git_prefix + 'file.txt'
if git_file in all_files:
contents = repo.get_contents(git_file)
repo.update_file(contents.path, "committing files", content, contents.sha, branch="master")
print(git_file + ' UPDATED')
else:
repo.create_file(git_file, "committing files", content, branch="master")
print(git_file + ' CREATED')
If you are interested in knowing if a single path exists in your repo you can use something like this and then branch your logic out from the result.
from github.Repository import Repository
def does_object_exists_in_branch(repo: Repository, branch: str, object_path: str) -> bool:
try:
repo.get_contents(object_path, branch)
return True
except github.UnknownObjectException:
return False
But the method in the approved answer is more efficient if you want to check if multiple files exist in a given path, but I wanted to provide this as an alternative.

Take uploaded files on plone and download them via a python script?

I created a document site on plone from which file uploads can be made. I saw that plone saves them in the filesystem in the form of a blob, now I need to take them through a python script that will process the pdfs downloaded with an OCR. Does anyone have any idea how to do it? Thank you
Not sure how to extract PDFs from BLOB-storage or if it's possible at all, but you can extract them from a running Plone-site (e.g. executing the script via a browser-view):
import os
from Products.CMFCore.utils import getToolByName
def isPdf(search_result):
"""Check mime_type for Plone >= 5.1, otherwise check file-extension."""
if mimeTypeIsPdf(search_result) or search_result.id.endswith('.pdf'):
return True
return False
def mimeTypeIsPdf(search_result):
"""
Plone-5.1 introduced the mime_type-attribute on files.
Try to get it, if it doesn't exist, fail silently.
Return True if mime_type exists and is PDF, otherwise False.
"""
try:
mime_type = search_result.mime_type
if mime_type == 'application/pdf':
return True
except:
pass
return False
def exportPdfFiles(context, export_path):
"""
Get all PDF-files of site and write them to export_path on the filessytem.
Remain folder-structure of site.
"""
catalog = getToolByName(context, 'portal_catalog')
search_results = catalog(portal_type='File', Language='all')
for search_result in search_results:
# For each PDF-file:
if isPdf(search_result):
file_path = export_path + search_result.getPath()
file_content = search_result.getObject().data
parent_path = '/'.join(file_path.split('/')[:-1])
# Create missing directories on the fly:
if not os.path.exists(parent_path):
os.makedirs(parent_path)
# Write PDF:
with open(file_path, 'w') as fil:
fil.write(file_content)
print 'Wrote ' + file_path
print 'Finished exporting PDF-files to ' + export_path
The example keeps the folder-structure of the Plone-site in the export-directory. If you want them flat in one directory, a handler for duplicate file-names is needed.

How can I change a part of a filename with python

I am brand new to python (and coding in general) and I've been unable to find a solution to my specific problem online. I am currently creating a tool which will allow a user to save a file to a network location. The file will have a version number. What I would like to is to have the script auto version up before it saves. I have the rest of the script done, but it is the auto versioning that I am having issues with. Here's what I have so far:
import re
import os
def main():
wip_folder = "L:/xxx/xxx/xxx/scenes/wip/"
_file_list = os.listdir('%s' % wip_folder)
if os.path.exists('%s' wip_path):
for file in _file_list:
versionPattern = re.compile('_v\d{3}')
curVersions = versionPattern.findall('%s' % wip_folder)
curVersions.sort()
nextVersion = '_v%03d' % (int(curVersions[-1][2:]) + 1)
return nextVersion
else:
nextVersion = '_v001'
name = xxx_xxx_xx
name += '%s' nextVersion
name += '_xxx_wip
I should probably point out that main() is going to be called by a QPushbutton in another module. Also, that wip_path will most likely have several versions of a single file in it. So if there are 10 versions of this file in wip_path, this save should be v011. I apologize if this question makes no sense. Any help would be appreciated. Thank you!
You do not need to use re at all, programming is about simplification and you are over complicating it! I chose to return but anything in this function can be changed to whatever you need it to specifically do! Just read the comments and good luck!
def getVersioning(path):
#passing path
count = 1 #init count
versionStr = 'wip_path_v'
try: #in case path dosen't exist
for i in os.listdir(path): #loop thorough files in passed dir
if versionStr in i: #check if files contain default versioning string e.g. wip_path_V or any other (used in case other files are in the same dir)
count += 1 #incriment count
except:
os.mkdir(path) #makedir if one does not exist for future use
newName = versionStr + str(count) #new versioning file name
return newName #return new versioning name
print getVersioning('tstFold')

Categories