Пример #1
0
    def __init__(self, app):
        """
		Set up the initial thread for monitoring the directory
		"""
        QThread.__init__(self)
        self.dw = KDirWatch()
        self.app = app
Пример #2
0
    def init(self):
        self._keywords = {}
        self._bookmarks = []
        self._googleBaseURL = ChromiumRunner.DEFAULT_GOOGLE_URL

        # FIXME: Should go to config
        homePath = os.environ.get("HOME")
        self._pathWebData    = os.path.join(homePath, ".config/chromium/Default/Web Data")
        self._pathLocalState = os.path.join(homePath, ".config/chromium/Local State")
        self._pathBookmarks  = os.path.join(homePath, ".config/chromium/Default/Bookmarks")

        self.setSyntaxes([
            Plasma.RunnerSyntax(
                "<Chromium keyword> :q:",
                "Search for :q: using Chromium keyword"),
            Plasma.RunnerSyntax(
                ":q:",
                "Search for :q: in your Chromium bookmarks")
        ])

        # Initially read data
        self._readKeywords()
        self._readBookmarks()
        self._readLastKnownGoogleUrl()

        # Watch the files for changes
        self._watcher = KDirWatch(self)
        self._watcher.addFile(self._pathWebData)
        self._watcher.addFile(self._pathLocalState)
        self._watcher.addFile(self._pathBookmarks)
        self.connect(self._watcher, SIGNAL("created(QString)"), self._updateData)
        self.connect(self._watcher, SIGNAL("dirty(QString)"), self._updateData)
Пример #3
0
    def __init__ (self, parent, path="", relative=False, busName=None, busPath=None):
        SatyrObject.__init__ (self, parent, busName, busPath)


        self.songs= []
        self.count= 0
        # (re)defined by an aggregator if we're in one of those
        self.offset= 0

        # BUG: path is not reread from the config file!
        # it breaks rescanning
        self.configValues= (
            ('path', str, path),
            )
        self.loadConfig ()
        # print busPath, self.path

        # if the user requests a new path, use it
        if self.path!=path and path!="":
            path= os.path.abspath (path)
            self.path= path
            self.forceScan= True
            logger.info ("new path, forcing (re)scan")
        else:
            self.forceScan= False
        self.relative= relative
        logger.debug ("Collection(): %s", self.path)

        self.watch= KDirWatch (self)
        self.watch.addDir (self.path,
            KDirWatch.WatchMode (KDirWatch.WatchFiles|KDirWatch.WatchSubDirs))
        self.watch.created.connect (self.newFiles)

        self.scanners= []
        self.scanning= False
        self.loadMetadata= False

        if busPath is not None:
            self.collectionFile= str (KStandardDirs.locateLocal ('data', 'satyr/%s.tdb' % self.dbusName (busPath)))
        else:
            self.collectionFile= str (KStandardDirs.locateLocal ('data', 'satyr/collection.tdb'))
 def init(self):
     """ Setup plasma layout """
     # Set initial paths
     self.project_path = '~/.sublimetext2/projects'
     self.projects = ""
     self.exe_path = '~/Sublime Text 2/sublime_text'
     self.exe = ""
     self.project_map = {}
     
     # Watch the project directory for updates
     self.dirwatch = KDirWatch(self.applet)
     self.dirwatch.addDir(QString(self.project_path))
     self.connect(self.dirwatch, SIGNAL("dirty(QString)"), self.configChanged)
     
     # Setup layout
     self.setHasConfigurationInterface(True)
     self.setAspectRatioMode(Plasma.IgnoreAspectRatio)
     self.layout = QGraphicsLinearLayout(self.applet)
     self.makeWidget()
     self.layout.addItem(self.list_view)
     self.setLayout(self.layout)
     self.resize(300,200)
Пример #5
0
class ChromiumRunner(plasmascript.Runner):

    DEFAULT_GOOGLE_URL = "https://www.google.com"
    
    def init(self):
        self._keywords = {}
        self._bookmarks = []
        self._googleBaseURL = ChromiumRunner.DEFAULT_GOOGLE_URL

        # FIXME: Should go to config
        homePath = os.environ.get("HOME")
        self._pathWebData    = os.path.join(homePath, ".config/chromium/Default/Web Data")
        self._pathLocalState = os.path.join(homePath, ".config/chromium/Local State")
        self._pathBookmarks  = os.path.join(homePath, ".config/chromium/Default/Bookmarks")

        self.setSyntaxes([
            Plasma.RunnerSyntax(
                "<Chromium keyword> :q:",
                "Search for :q: using Chromium keyword"),
            Plasma.RunnerSyntax(
                ":q:",
                "Search for :q: in your Chromium bookmarks")
        ])

        # Initially read data
        self._readKeywords()
        self._readBookmarks()
        self._readLastKnownGoogleUrl()

        # Watch the files for changes
        self._watcher = KDirWatch(self)
        self._watcher.addFile(self._pathWebData)
        self._watcher.addFile(self._pathLocalState)
        self._watcher.addFile(self._pathBookmarks)
        self.connect(self._watcher, SIGNAL("created(QString)"), self._updateData)
        self.connect(self._watcher, SIGNAL("dirty(QString)"), self._updateData)

    @pyqtSlot()
    def _updateData(self, path):
        """
        Called by KDirWatch if a watched dir has changed (dirty).
        """
        if path == self._pathWebData:
            self._readKeywords()
        elif path == self._pathLocalState:
            self._readLastKnownGoogleUrl()
        elif path == self._pathBookmarks:
            self._readBookmarks()

    @pyqtSlot()
    def _readKeywords(self):
        """
        Read chromium keywords.
        """
        # Copy Chromium Web Data as it is locked if Chromium running... This is
        # risky as sqlite could be in the middle of performing some transaction!
        if os.path.isfile(self._pathWebData) and os.access(self._pathWebData, os.R_OK):
            _, dbfile = mkstemp("krunner-chromium")
            copy2(self._pathWebData, dbfile)
            cur = sqlite3.connect(dbfile).cursor()
            try:
                cur.execute("SELECT short_name, keyword, url FROM keywords")
                self._keywords = {}
                for shortName, keyword, url in cur.fetchall():
                    if not keyword in self._keywords:
                        self._keywords[keyword] = (shortName, url) # order matters
            finally:
                cur.close()
                os.unlink(dbfile)

    @pyqtSlot()
    def _readBookmarks(self):
        """
        Read Chromium bookmarks.
        """
        with open(self._pathBookmarks, 'r') as bfile:
            def walk(element):
                for item in element:
                    if item["type"] == "url":
                        tmp = (QString(item["name"]), QString(item["url"])) # order matters
                        if not tmp in self._bookmarks:
                            self._bookmarks.append(tmp)
                    elif item["type"] == "folder":
                        walk(item["children"])
            self._bookmarks = []
            jsonRoots = json.load(bfile).get("roots", {})
            for key in (v for v in jsonRoots.itervalues() if type(v) is dict):
                walk(key.get("children", {}))

    @pyqtSlot()
    def _readLastKnownGoogleUrl(self):
        """
        Read the last_known_google_url from `Local State`.
        """
        with open(self._pathLocalState, 'r') as localStateFile:
            self._googleBaseURL = json.load(localStateFile)\
                .get("browser", {})\
                .get("last_known_google_url", ChromiumRunner.DEFAULT_GOOGLE_URL)

    def match(self, context):
        """
        Inspect the current query and provide appropriate matches.
        """
        if not context.isValid():
            return

        query = context.query().trimmed()

        # Look for keywords
        for keyword in self._keywords:
            if query.startsWith(keyword + " "):
                searchTerms = query[len(keyword)+1:]
                if len(searchTerms) >= 2:
                    self._matchKeyword(context, query, searchTerms, keyword)

        # Look for bookmarks
        flt = lambda (bmName, _): bmName.contains(query, Qt.CaseInsensitive)
        for bookmark in filter(flt, self._bookmarks):
            self._matchBookmark(context, query, bookmark)

    def _matchBookmark(self, context, query, matchedBookmark):
        """
        Add a bookmark match for the given `query` to `context`.
        """
        name, url = matchedBookmark
        m = Plasma.QueryMatch(self.runner)
        m.setText("\"%s\"\n%s" % (name, url))
        m.setType(Plasma.QueryMatch.ExactMatch)
        m.setIcon(KIcon("bookmarks"))
        m.setData(url)
        context.addMatch(query, m)
        
    def _matchKeyword(self, context, query, searchTerms, matchedKeyword):
        """
        Add a keyword match for the given `query` to `context`.
        """
        shortName, url = self._keywords[matchedKeyword]

        # This explicit "cast" to QString is necessary in order to prevent
        # python from interpreting `url` as a regular string. This way,
        # unicode handling is a lot easier.
        url = QString(url).replace("{searchTerms}", searchTerms)

        # Default google search URL is some freaky contruction like:
        # {google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}{google:searchFieldtrialParameter}{google:instantFieldTrialGroupParameter}sourceid=chrome&client=ubuntu&channel=cs&ie={inputEncoding}&q=%s
        # google:baseURL is in attr "last_known_google_url" in ~./config/chromium/Local State
        # Quick workaround...
        if url.startsWith("{google:baseURL}"):
            url = QUrl("%s/search" % self._googleBaseURL)
            url.addQueryItem("q", searchTerms)
            url.addQueryItem("qf", "f")
            url = url.toString()

        m = Plasma.QueryMatch(self.runner)
        m.setText("Query \"%s\" for '%s'\n%s" % (shortName, searchTerms, url))
        m.setType(Plasma.QueryMatch.ExactMatch)
        m.setIcon(KIcon("chromium-browser"))
        m.setData(url)
        context.addMatch(query, m)

    def run(self, context, match):
        if context.isValid():
            KToolInvocation.invokeBrowser(match.data().toString())
class SublimeText2Applet(plasmascript.Applet):
    def __init__(self,parent,args=None):
        plasmascript.Applet.__init__(self,parent)
    
    def init(self):
        """ Setup plasma layout """
        # Set initial paths
        self.project_path = '~/.sublimetext2/projects'
        self.projects = ""
        self.exe_path = '~/Sublime Text 2/sublime_text'
        self.exe = ""
        self.project_map = {}
        
        # Watch the project directory for updates
        self.dirwatch = KDirWatch(self.applet)
        self.dirwatch.addDir(QString(self.project_path))
        self.connect(self.dirwatch, SIGNAL("dirty(QString)"), self.configChanged)
        
        # Setup layout
        self.setHasConfigurationInterface(True)
        self.setAspectRatioMode(Plasma.IgnoreAspectRatio)
        self.layout = QGraphicsLinearLayout(self.applet)
        self.makeWidget()
        self.layout.addItem(self.list_view)
        self.setLayout(self.layout)
        self.resize(300,200)
    
    def makeWidget(self):
        """ Create the TreeView widget and connect the clicked signal """
        self.list_view = Plasma.TreeView()
        self.list_view.nativeWidget().header().hide()
        self.list_view.nativeWidget().setRootIsDecorated(False)
        self.st2_model = QStandardItemModel()
        self.list_view.setModel(self.st2_model)
        self.initSessionFiles()
        self.connect(self.list_view.nativeWidget(), SIGNAL("activated(const QModelIndex &)"), self.slotOnItemClicked)
        
 
    def initSessionFiles(self):
        """ Create the list items for the TreeView from the project directory """
        index = 1
        item = QStandardItem()
        item.setData("Start Sublime Text 2 (New Project)", role=Qt.DisplayRole)
        item.setIcon(KIcon("document-new"))
        item.setData(index, role=Qt.UserRole+1)
        self.st2_model.appendRow(item)
        
        index += 1
        item = QStandardItem()
        item.setData("Start Sublime Text 2 (Previous Session)", role=Qt.DisplayRole)
        item.setIcon(KIcon("document-edit"))
        item.setData(index, role=Qt.UserRole+1)
        self.st2_model.appendRow(item)
        
        fnames = sorted(glob.iglob(self.project_path+"/*.sublime-project"))
        for fname in fnames:
            name = os.path.basename(fname).rsplit('.')[0]
            if name == 'blank':
                continue
            index += 1
            item = QStandardItem()
            item.setData(name, role=Qt.DisplayRole)
            item.setData(index, role=Qt.UserRole+1)
            self.st2_model.appendRow(item)
            self.project_map[index] = fname
    
    def slotOnItemClicked(self,selection):
        """ Launch the application with the correct arguments """
        index = selection.data(Qt.UserRole+1).toInt()[0]
        if index == 1:
            """ 
                Hack: create a blank project to open to simulate a new blank project
                similar to Kate's behavior.  Hopefully in the future there will be a
                flag for a new project in sublime text that does not also open 
                previous session files.
            """
            with open(self.project_path+"/blank.sublime-project",'w') as blank_proj:
                blank_proj.write('{ "folders":[{}] }')
            with open(self.project_path+"/blank.sublime-workspace",'w') as blank_proj:
                blank_proj.write('''{ "auto_complete":
                                        {
                                                "selected_items":
                                                [
                                                ]
                                        },
                                        "buffers":
                                        [
                                        ],
                                        "build_system": "",
                                        "command_palette":
                                        {
                                                "height": 345.0,
                                                "selected_items":
                                                [
                                                ],
                                                "width": 449.0
                                        },
                                        "console":
                                        {
                                                "height": 0.0
                                        },
                                        "distraction_free":
                                        {
                                                "menu_visible": true,
                                                "show_minimap": false,
                                                "show_open_files": false,
                                                "show_tabs": false,
                                                "side_bar_visible": false,
                                                "status_bar_visible": false
                                        },
                                        "file_history":
                                        [
                                        ],
                                        "find":
                                        {
                                                "height": 0.0
                                        },
                                        "find_in_files":
                                        {
                                                "height": 0.0,
                                                "where_history":
                                                [
                                                ]
                                        },
                                        "find_state":
                                        {
                                                "case_sensitive": false,
                                                "find_history":
                                                [
                                                ],
                                                "highlight": true,
                                                "in_selection": false,
                                                "preserve_case": false,
                                                "regex": false,
                                                "replace_history":
                                                [
                                                ],
                                                "reverse": false,
                                                "show_context": true,
                                                "use_buffer2": true,
                                                "whole_word": false,
                                                "wrap": true
                                        },
                                        "groups":
                                        [
                                                {
                                                        "sheets":
                                                        [
                                                        ]
                                                }
                                        ],
                                        "incremental_find":
                                        {
                                                "height": 0.0
                                        },
                                        "input":
                                        {
                                                "height": 0.0
                                        },
                                        "layout":
                                        {
                                                "cells":
                                                [
                                                        [
                                                                0,
                                                                0,
                                                                1,
                                                                1
                                                        ]
                                                ],
                                                "cols":
                                                [
                                                        0.0,
                                                        1.0
                                                ],
                                                "rows":
                                                [
                                                        0.0,
                                                        1.0
                                                ]
                                        },
                                        "menu_visible": true,
                                        "replace":
                                        {
                                                "height": 0.0
                                        },
                                        "save_all_on_build": true,
                                        "select_file":
                                        {
                                                "height": 0.0,
                                                "selected_items":
                                                [
                                                ],
                                                "width": 0.0
                                        },
                                        "select_project":
                                        {
                                                "height": 0.0,
                                                "selected_items":
                                                [
                                                ],
                                                "width": 0.0
                                        },
                                        "show_minimap": true,
                                        "show_open_files": true,
                                        "show_tabs": false,
                                        "side_bar_visible": true,
                                        "side_bar_width": 303.0,
                                        "status_bar_visible": true
                                }''')
            pid = Popen([self.exe_path,'--project','%s' % self.project_path+"/blank.sublime-project"]).pid
        elif index == 2:
            # Open a new window with the previus contents
            pid = Popen([self.exe_path,'-n']).pid
        else:
            # Open a specific project file
            pid = Popen([self.exe_path,'--project','%s' % self.project_map[index]]).pid
    
    def createConfigurationInterface(self, dlg):
        """ Create the settings menu item to allow the user to set the paths """
        self.groupBox = QGroupBox()
        self.groupBox.setTitle('Projects')
        self.projects = QLineEdit(QString(self.project_path))
        self.exe = QLineEdit(QString(self.exe_path))
        self.vbox = QVBoxLayout()
        self.vbox.addWidget(QLabel(QString('Path to project files')))
        self.vbox.addWidget(self.projects)
        self.vbox.addWidget(QLabel(QString('Path to Sublime Text 2 executable')))
        self.vbox.addWidget(self.exe)
        self.groupBox.setLayout(self.vbox) 
        p = dlg.addPage(self.groupBox, "Settings" )
        p.setIcon( KIcon("preferences-system-windows-actions") )
        dlg.setButtons(KDialog.ButtonCode(KDialog.Ok | KDialog.Cancel))
        self.connect(dlg, SIGNAL("okClicked()"), self.configChanged)
    
    def configChanged(self):
        """ A change was made so update the list of projects """
        if self.projects and os.path.exists(self.projects.text()):
            self.dirwatch.removeDir(QString(self.project_path))
            self.project_path = str(self.projects.text())
            self.dirwatch.addDir(QString(self.project_path))
            self.dirwatch.startScan()
        if self.exe and os.path.exists(str(self.exe.text())):
            self.exe_path = str(self.exe.text())
        
        self.st2_model.clear()
        self.project_map = {}
        self.initSessionFiles()
Пример #7
0
class Collection (SatyrObject):
    """A Collection of Albums"""
    newSongs= pyqtSignal ()
    scanBegins= pyqtSignal ()
    scanFinished= pyqtSignal ()

    def __init__ (self, parent, path="", relative=False, busName=None, busPath=None):
        SatyrObject.__init__ (self, parent, busName, busPath)


        self.songs= []
        self.count= 0
        # (re)defined by an aggregator if we're in one of those
        self.offset= 0

        # BUG: path is not reread from the config file!
        # it breaks rescanning
        self.configValues= (
            ('path', str, path),
            )
        self.loadConfig ()
        # print busPath, self.path

        # if the user requests a new path, use it
        if self.path!=path and path!="":
            path= os.path.abspath (path)
            self.path= path
            self.forceScan= True
            logger.info ("new path, forcing (re)scan")
        else:
            self.forceScan= False
        self.relative= relative
        logger.debug ("Collection(): %s", self.path)

        self.watch= KDirWatch (self)
        self.watch.addDir (self.path,
            KDirWatch.WatchMode (KDirWatch.WatchFiles|KDirWatch.WatchSubDirs))
        self.watch.created.connect (self.newFiles)

        self.scanners= []
        self.scanning= False
        self.loadMetadata= False

        if busPath is not None:
            self.collectionFile= str (KStandardDirs.locateLocal ('data', 'satyr/%s.tdb' % self.dbusName (busPath)))
        else:
            self.collectionFile= str (KStandardDirs.locateLocal ('data', 'satyr/collection.tdb'))

    def loadOrScan (self):
        if self.forceScan or not self.load ():
            self.scan ()

    def load (self):
        logger.info ('loading from', self.collectionFile)
        try:
            # we must remove the trailing newline
            # we could use strip(), but filenames ending with any other whitespace
            # (think of the users!) would be loaded incorrectly
            # this oneliner seems to be the fastest against:
            # * fp= []; f= open(); for line in f.readlines(): fp.append (line)
            # * fp= []; f= open(); for line in f: fp.append (line)
            filepaths= [ line[:-1] for line in open (self.collectionFile) ]
            self.add (filepaths)
            ans= True
        except IOError, e:
            logger.warning ("no database!")
            logger.warning ('FAILED!', e)
            ans= False

        return ans