Commit 98558af4 authored by akiraohgaki's avatar akiraohgaki
Browse files

Initial import

parent 3f03ac3f
# xdgurl
\ No newline at end of file
# xdgurl
An install helper program for desktop stuff.
----
## How to install
For Ubuntu/Debian system,
you can use "install.sh" in the project to install the program.
$ sh install.sh
And you can use "uninstall.sh" to uninstall the program.
$ sh uninstall.sh
----
## How to use
#### From web browser
Open XDG-URL by click a links, or type XDG-URL in browser's address bar.
In firefox,
you can get a program selection window when first time to open XDG-URL,
and you can choose "xdgurl" as custom URL handler.
If you can not get program selection window,
you need set the xdgurl program as custom URL handler for xdg:// scheme in browser's settings.
#### From command-line terminal
Execute xdgurl program with XDG-URL as argument.
$ xdgurl "XDG-URL"
----
## XDG-URL
XDG-URL is a custom URL that represent the install method for desktop stuff.
[scheme]://[command]?[query string]
For example:
xdg://install?url=http%3A%2F%2Fexample.com%2Ficons.tar.gz&type=icons
#### Scheme
* xdg
* xdgs
For now, "xdgs" scheme is the same of the xdg scheme,
it's reserved name for secure method in the future.
#### Command
* download
* install
Command "download" will download the file from specified URL to local destination of specified install-type.
Command "install" will make file download and trigger install process.
#### Query string
XDG-URL's query string is an option of command.
*All query string values should be urlencoded.*
**url** = File URL of desktop stuff
Must be set.
**type** = Install-type
Optional.
Default is "downloads".
Available install-type:
Install-type | Local destination
-------------|------------------
downloads | ~/Downloads
documents | ~/Documents
pictures | ~/Pictures
music | ~/Music
videos | ~/Videos
wallpapers | ~/.local/share/wallpapers
fonts | ~/.fonts
cursors | ~/.icons
icons | ~/.local/share/icons
emoticons | ~/.local/share/emoticons
themes | ~/.themes
emerald_themes | ~/.emerald/themes
enlightenment_themes | ~/.e/e/themes
enlightenment_backgrounds | ~/.e/e/backgrounds
fluxbox_styles | ~/.fluxbox/styles
pekwm_themes | ~/.pekwm/themes
icewm_themes | ~/.icewm/themes
plasma_plasmoids | ~/.local/share/plasma/plasmoids
plasma_look_and_feel | ~/.local/share/plasma/look-and-feel
plasma_desktopthemes | ~/.local/share/plasma/desktoptheme
kwin_effects | ~/.local/share/kwin/effects
kwin_scripts | ~/.local/share/kwin/scripts
kwin_tabbox | ~/.local/share/kwin/tabbox
aurorae_themes | ~/.local/share/aurorae/themes
dekorator_themes | ~/.local/share/deKorator/themes
qtcurve | ~/.local/share/QtCurve
color_schemes | ~/.local/share/color-schemes
gnome_shell_extensions | ~/.local/share/gnome-shell/extensions
cinnamon_desklets | ~/.local/share/cinnamon/desklets
nautilus_scripts | ~/.local/share/nautilus/scripts
amarok_scripts | ~/.kde/share/apps/amarok/scripts
yakuake_skins | ~/.kde/share/apps/yakuake/skins
cairo_clock_themes | ~/.cairo-clock/themes
Available alias name of the install-type:
Alias | Install-type
------|-------------
gnome_shell_themes | themes
cinnamon_themes | themes
gtk2_themes | themes
gtk3_themes | themes
metacity_themes | themes
xfwm4_themes | themes
openbox_themes | themes
kvantum_themes | themes
compiz_themes | emerald_themes
beryl_themes | emerald_themes
plasma4_plasmoids | plasma_plasmoids
plasma5_plasmoids | plasma_plasmoids
plasma5_look_and_feel | plasma_look_and_feel
plasma5_desktopthemes | plasma_desktopthemes
plasma_color_schemes | color_schemes
**filename** = Alternative file name
Optional.
This option is useful if the download URL does not represent the file name.
#!/bin/bash
# Install
cd `dirname $0`
sudo apt-get update
sudo apt-get install python-tk
sudo install -m 755 src/xdgurl.py /usr/bin/xdgurl
sudo install -m 644 src/xdgurl.desktop /usr/share/applications/xdgurl.desktop
sudo update-desktop-database
[Desktop Entry]
Name=xdgurl
Exec=xdgurl %u
Type=Application
Terminal=false
NoDisplay=true
Categories=Application;Network;FileTransfer;
MimeType=x-scheme-handler/xdg;x-scheme-handler/xdgs;
#!/usr/bin/env python
import sys
import os
import json
import urllib
import urlparse
import tempfile
import mimetypes
import subprocess
import Tkinter
import tkMessageBox
class XdgUrl:
"""Core class of xdgurl"""
def __init__(self, xdg_url=''):
self.xdg_url = xdg_url
self.meta = self.parse()
self.temp_dir = tempfile.gettempdir()
self.home_dir = os.path.expanduser('~')
#self.config_dir = os.path.join(self.home_dir, '.config', 'xdgurl')
self.data_dir = os.path.join(self.home_dir, '.local', 'share')
self.kde_data_dir = os.path.join(self.home_dir, '.kde', 'share')
#self.config = {}
self.destinations = {
'downloads': os.path.join(self.home_dir, 'Downloads'),
'documents': os.path.join(self.home_dir, 'Documents'),
'pictures': os.path.join(self.home_dir, 'Pictures'),
'music': os.path.join(self.home_dir, 'Music'),
'videos': os.path.join(self.home_dir, 'Videos'),
'wallpapers': os.path.join(self.data_dir, 'wallpapers'),
'fonts': os.path.join(self.home_dir, '.fonts'),
'cursors': os.path.join(self.home_dir, '.icons'),
'icons': os.path.join(self.data_dir, 'icons'),
'emoticons': os.path.join(self.data_dir, 'emoticons'),
'themes': os.path.join(self.home_dir, '.themes'),
'emerald_themes': os.path.join(self.home_dir, '.emerald', 'themes'),
'enlightenment_themes': os.path.join(self.home_dir, '.e', 'e', 'themes'),
'enlightenment_backgrounds': os.path.join(self.home_dir, '.e', 'e', 'backgrounds'),
'fluxbox_styles': os.path.join(self.home_dir, '.fluxbox', 'styles'),
'pekwm_themes': os.path.join(self.home_dir, '.pekwm', 'themes'),
'icewm_themes': os.path.join(self.home_dir, '.icewm', 'themes'),
'plasma_plasmoids': os.path.join(self.data_dir, 'plasma', 'plasmoids'),
'plasma_look_and_feel': os.path.join(self.data_dir, 'plasma', 'look-and-feel'),
'plasma_desktopthemes': os.path.join(self.data_dir, 'plasma', 'desktoptheme'),
'kwin_effects': os.path.join(self.data_dir, 'kwin', 'effects'),
'kwin_scripts': os.path.join(self.data_dir, 'kwin', 'scripts'),
'kwin_tabbox': os.path.join(self.data_dir, 'kwin', 'tabbox'),
'aurorae_themes': os.path.join(self.data_dir, 'aurorae', 'themes'),
'dekorator_themes': os.path.join(self.data_dir, 'deKorator', 'themes'),
'qtcurve': os.path.join(self.data_dir, 'QtCurve'),
'color_schemes': os.path.join(self.data_dir, 'color-schemes'),
'gnome_shell_extensions': os.path.join(self.data_dir, 'gnome-shell', 'extensions'),
'cinnamon_desklets': os.path.join(self.data_dir, 'cinnamon', 'desklets'),
'nautilus_scripts': os.path.join(self.data_dir, 'nautilus', 'scripts'),
'amarok_scripts': os.path.join(self.kde_data_dir, 'apps', 'amarok', 'scripts'),
'yakuake_skins': os.path.join(self.kde_data_dir, 'apps', 'yakuake', 'skins'),
'cairo_clock_themes': os.path.join(self.home_dir, '.cairo-clock', 'themes')
}
self.destinations_alias = {
'gnome_shell_themes': self.destinations['themes'],
'cinnamon_themes': self.destinations['themes'],
'gtk2_themes': self.destinations['themes'],
'gtk3_themes': self.destinations['themes'],
'metacity_themes': self.destinations['themes'],
'xfwm4_themes': self.destinations['themes'],
'openbox_themes': self.destinations['themes'],
'kvantum_themes': self.destinations['themes'],
'compiz_themes': self.destinations['emerald_themes'],
'beryl_themes': self.destinations['emerald_themes'],
'plasma4_plasmoids': self.destinations['plasma_plasmoids'],
'plasma5_plasmoids': self.destinations['plasma_plasmoids'],
'plasma5_look_and_feel': self.destinations['plasma_look_and_feel'],
'plasma5_desktopthemes': self.destinations['plasma_desktopthemes'],
'plasma_color_schemes': self.destinations['color_schemes']
}
self.destinations.update(self.destinations_alias)
self.archive_types = {
'tar': [
'application/x-tar',
'application/x-gzip',
'application/gzip',
'application/x-bzip',
'application/x-bzip2',
'application/x-xz',
'application/x-lzma',
'application/x-lzip',
'application/x-compressed-tar',
'application/x-bzip-compressed-tar',
'application/x-bzip2-compressed-tar',
'application/x-xz-compressed-tar',
'application/x-lzma-compressed-tar',
'application/x-lzip-compressed-tar'
],
'zip': ['application/zip'],
'7z': ['application/x-7z-compressed'],
'rar': [
'application/x-rar',
'application/x-rar-compressed'
]
}
#self.config.update(self.read_config('config'))
#self.destinations.update(self.read_config('destinations'))
def read_config(self, name):
path = os.path.join(self.config_dir, name + '.json')
data = {}
if os.path.isfile(path):
f = open(path)
data = json.load(f)
f.close()
return data
def write_config(self, name, data):
if not os.path.isdir(self.config_dir):
os.makedirs(self.config_dir)
path = os.path.join(self.config_dir, name + '.json')
f = open(path, 'w')
json.dump(data, f)
f.close()
def parse(self):
meta = {
'command': 'download',
'url': '',
'type': 'downloads',
'filename': ''
}
parse_result = urlparse.urlparse(self.xdg_url)
query = urlparse.parse_qs(parse_result.query)
if parse_result.netloc:
meta['command'] = parse_result.netloc
if 'url' in query and query['url'][0]:
meta['url'] = urllib.unquote(query['url'][0])
if 'type' in query and query['type'][0]:
meta['type'] = urllib.unquote(query['type'][0])
if 'filename' in query and query['filename'][0]:
meta['filename'] = urllib.unquote(query['filename'][0])
if meta['url'] and not meta['filename']:
meta['filename'] = os.path.basename(meta['url'])
return meta
"""
def detect_desktop_environment(self):
desktop_environment = 'unknown'
if os.environ.get('KDE_FULL_SESSION') == 'true':
desktop_environment = 'kde'
elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
desktop_environment = 'gnome'
return desktop_environment
"""
def install_plasmapkg(self, path, type='plasmoid'):
status = subprocess.call(['plasmapkg2', '-t', type, '-i', path])
if status == 0:
return True
return False
def uncompress_archive(self, path, target_dir):
(mimetype, encoding) = mimetypes.guess_type(path)
status = None
if mimetype in self.archive_types['tar']:
status = subprocess.call(['tar', '-xf', path, '-C', target_dir])
elif mimetype in self.archive_types['zip']:
status = subprocess.call(['unzip', '-o', path, '-d', target_dir])
elif mimetype in self.archive_types['7z']:
# No space between -o and directory
status = subprocess.call(['7z', 'x', path, '-o' + target_dir])
elif mimetype in self.archive_types['rar']:
status = subprocess.call(['unrar', 'e', path, target_dir])
if status == 0:
return True
return False
def download(self):
url = self.meta['url']
type = self.meta['type']
filename = self.meta['filename']
destination = self.destinations[type]
temp_path = os.path.join(self.temp_dir, filename)
path = os.path.join(destination, filename)
print('Retrieving a file from ' + url)
urllib.urlretrieve(url, temp_path)
print('Creating a directory ' + destination)
if not os.path.isdir(destination):
os.makedirs(destination)
print('Saving a file to ' + path)
os.rename(temp_path, path)
print('Done')
def install(self):
url = self.meta['url']
type = self.meta['type']
filename = self.meta['filename']
destination = self.destinations[type]
temp_path = os.path.join(self.temp_dir, filename)
path = os.path.join(destination, filename)
print('Retrieving a file from ' + url)
urllib.urlretrieve(url, temp_path)
print('Creating a directory ' + destination)
if not os.path.isdir(destination):
os.makedirs(destination)
print('Installing')
if (type in ['plasma_plasmoids', 'plasma4_plasmoids', 'plasma5_plasmoids']
and self.install_plasmapkg(temp_path, 'plasmoid')):
print('The plasmoid has been installed')
os.remove(temp_path)
elif (type in ['plasma_look_and_feel', 'plasma5_look_and_feel']
and self.install_plasmapkg(temp_path, 'lookandfeel')):
print('The plasma look and feel has been installed')
os.remove(temp_path)
elif (type in ['plasma_desktopthemes', 'plasma5_desktopthemes']
and self.install_plasmapkg(temp_path, 'theme')):
print('The plasma desktop theme has been installed')
os.remove(temp_path)
elif (type == 'kwin_effects'
and self.install_plasmapkg(temp_path, 'kwineffect')):
print('The KWin effect has been installed')
os.remove(temp_path)
elif (type == 'kwin_scripts'
and self.install_plasmapkg(temp_path, 'kwinscript')):
print('The KWin script has been installed')
os.remove(temp_path)
elif (type == 'kwin_tabbox'
and self.install_plasmapkg(temp_path, 'windowswitcher')):
print('The KWin window switcher has been installed')
os.remove(temp_path)
elif self.uncompress_archive(temp_path, destination):
print('The archive file has been uncompressed into ' + destination)
os.remove(temp_path)
else:
print('Saving a file to ' + path)
os.rename(temp_path, path)
print('Done')
def execute(self):
try:
if (self.meta['command'] in ['download', 'install']
and self.meta['url']
and self.meta['type'] in self.destinations
and self.meta['filename']):
if self.meta['command'] == 'download':
self.download()
elif self.meta['command'] == 'install':
self.install()
return True
print('Incorrect XDG-URL ' + self.xdg_url)
return False
except:
print('Execution error')
return False
'''
class XdgUrlApp(Tkinter.Frame):
"""Confirmation dialog for xdgurl"""
def __init__(self, master=None, core=None):
Tkinter.Frame.__init__(self, master)
self.pack()
self.core = core
self.master.title('xdgurl')
self.master.geometry('300x120')
self.create_widget()
def create_widget(self):
execute_text = 'Download'
if self.core.meta['command'] == 'install':
execute_text = 'Install'
info_label = Tkinter.Label(self, text=execute_text + ': ' + self.core.meta['filename'])
info_label.pack(padx=10, pady=5, anchor=Tkinter.W)
message_label = Tkinter.Label(self, text='Do you want to continue?')
message_label.pack(padx=10, pady=5, anchor=Tkinter.W)
execute_button = Tkinter.Button(self, text=execute_text, command=self.execute)
execute_button.pack(padx=5, pady=10, side=Tkinter.RIGHT)
quit_button = Tkinter.Button(self, text='Cancel', command=self.quit)
quit_button.pack(padx=5, pady=10, side=Tkinter.RIGHT)
def execute(self):
self.core.execute()
sys.exit()
def quit(self):
sys.exit()
'''
if __name__ == '__main__':
if len(sys.argv) > 1:
"""
window = Tkinter.Tk()
core = XdgUrl(sys.argv[1])
app = XdgUrlApp(window, core)
app.mainloop()
"""
core = XdgUrl(sys.argv[1])
execute_text = 'Download'
if core.meta['command'] == 'install':
execute_text = 'Install'
info_text = execute_text + ': ' + core.meta['filename'] + '\nFrom: ' + core.meta['url']
window = Tkinter.Tk()
window.withdraw()
if tkMessageBox.askyesno('xdgurl', info_text + '\n\nDo you want to continue?'):
if core.execute():
tkMessageBox.showinfo('xdgurl', info_text + '\n\n' + execute_text + ' finished')
else:
tkMessageBox.showerror('xdgurl', info_text + '\n\n' + execute_text + ' failed')
sys.exit()
else:
print('xdgurl "XDG-URL"')
sys.exit()
#!/bin/bash
# Uninstall
sudo rm /usr/bin/xdgurl
sudo rm /usr/share/applications/xdgurl.desktop
sudo update-desktop-database
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment