PackageManager / package_manager_ui.py

import sublime
import sublime_plugin

import contextlib
import csv
import os
import shutil
import urlparse

from package_manager import LocalPackage
from package_manager import start_download
from sublime_util import in_one_edit
import db


def draw_frame(v):
    with in_one_edit(v) as edit:
        v.insert(edit, 0, "=" * 79)
        v.insert(edit, v.size(), '\n')
        v.insert(edit, v.size(), ' Package Manager\n')
        v.insert(edit, v.size(), "=" * 79)
        v.insert(edit, v.size(), '\n')
        v.insert(edit, v.size(), "    %s%20s%20s%20s" % ('Name','Status','Origin','Author'))
        v.insert(edit, v.size(), '\n')
        v.insert(edit, v.size(), "~" * 79)
        v.insert(edit, v.size(), '\n' * 2)


def load_package_data(v):
    """Writes package data to the ui. Data is extracted from the txt db."""
    db.purge()
    with in_one_edit(v) as edit:
        for rec in db.gen_records():
            # XXX: This is awful.
            rec = "[ ]", rec[1], rec[-1], 'GitHub', 'SublimeText'
            rec_fmt = "%s %-20s%-20s%-20s%s" % rec
            v.insert(edit, v.size(), rec_fmt)
            v.insert(edit, v.size(), '\n')

    with in_one_edit(v) as edit:
        v.insert(edit, v.size(), '\n')
        v.insert(edit, v.size(), "=" * 79)


def get_selected_items(v):
    """Returns all the name fields for every item in the ui that has been
    selected by the user.
    """
    its = v.find_all(r'\[x\].*?$', 0)
    its = map(v.substr, its)
    return [x[4:].split()[0] for x in its]


class PackageManagerUiCommand(sublime_plugin.WindowCommand):
    def run(self):
        ui = self.window.new_file()
        ui.set_name('Package Manager - Sublime Text')
        draw_frame(ui)
        load_package_data(ui)
        ui.set_syntax_file('Packages/PackageManager/Support/Package Manager.tmLanguage')
        ui.set_scratch(True)
        ui.set_read_only(True)


class ToggleItemTickCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.set_read_only(False)

        current_line = self.view.line(self.view.sel()[0].begin())
        line_txt = self.view.substr(current_line)
        if line_txt.startswith("[ ]"):
            line_txt = "[x]" + line_txt[3:]
        else:
            line_txt = "[ ]" + line_txt[3:]

        with in_one_edit(self.view) as edit:
            self.view.replace(edit, current_line, line_txt)
        self.view.set_read_only(True)

    def is_enabled(self):
        is_ui = self.view.settings().get('syntax').endswith('Package Manager.tmLanguage')
        current_line = self.view.line(self.view.sel()[0].begin())
        is_item_line = self.view.substr(current_line).startswith("[")
        return is_ui and is_item_line


class CheckPackageCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        selected = get_selected_items(self.view)
        updated = db.update_db_info(selected)

        start = 0
        if updated:
            self.view.set_read_only(False)
            
            for u in updated:
                match = self.view.find(u[0], start)
                start = match.end()
                line = self.view.line(match)
                txt = self.view.substr(self.view.line(match))
                txt_parts = txt.split()
                txt_parts[2] = u[1]

                with in_one_edit(self.view) as edit:
                    print txt_parts
                    self.view.replace(edit, line, "%s %-20s%-20s%-20s%s" % tuple(txt_parts))
            
            self.view.set_read_only(True)

    def is_enabled(self):
        is_ui = self.view.settings().get('syntax').endswith('Package Manager.tmLanguage')
        return is_ui


class DownloadPackageCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        selected = get_selected_items(self.view)

        urls = []
        for i in selected:
            lp = LocalPackage(i)
            if not lp.invalid:
                urls.append(lp.url)
        start_download(urls)
        
        db.update_db_info(selected)

    def is_enabled(self):
        is_ui = self.view.settings().get('syntax').endswith('Package Manager.tmLanguage')
        return is_ui


class AddResourceCommand(sublime_plugin.WindowCommand):
    def run(self):
        self.window.show_input_panel('[PackageManager] Add Resource (url):',
                                        '', self.on_done, None, None)

    def on_done(self, s):
        rec = db.fetch_by_any_field(s)
        if rec:
            return

        data = urlparse.urlsplit(s)
        if not data.netloc.startswith('github.com'):
            print "[PackageManager]:err: Can only accept repositories at GitHub at the moment."
            sublime.status_message("[PackageManager] Can only accept repositories at GitHub at the moment.")
            return
        
        with db.open_db(mode='a') as f:
            user, item = os.path.split(data.path[1:])
            to_store = s, item, '2000-01-01T00:00:00Z', 'UNINSTALLED'
            f.write('\t'.join(to_store) + '\n')


class UninstallPackageCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        selected = get_selected_items(self.view)

        data_path = os.path.dirname(sublime.packages_path())
        installed_path = sublime.installed_packages_path()
        pristine_path = os.path.join(data_path, 'Pristine Packages')
        packages_path = sublime.packages_path()

        for name in selected:
            name_2 = "%s.sublime-package" % name
            
            if os.path.exists(os.path.join(installed_path, name_2)):
                print "[PackageManager] Deleting package %s from Installed Packages..." % name_2
                os.unlink(os.path.join(installed_path, name_2))
                if os.path.exists(os.path.join(pristine_path, name_2)):
                    print "[PackageManager] Deleting package %s from Pristine Packages..." % name_2
                    os.unlink(os.path.join(pristine_path, name_2))
                if os.path.exists(os.path.join(packages_path, name)):
                    print "[PackageManager] Deleting package %s from Packages..." % name
                    shutil.rmtree(os.path.join(packages_path, name))

        db.update_db_info(selected)
        print "[PackageManager] Finished deleting package %s." % name

    def is_enabled(self):
        is_ui = self.view.settings().get('syntax').endswith('Package Manager.tmLanguage')
        return is_ui
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.