-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
db41dba
commit 9c254bf
Showing
22 changed files
with
3,815 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Package: eepdater | ||
Version: 0.17bodhi1 | ||
Section: main | ||
Priority: optional | ||
Architecture: all | ||
Depends: python-efl, python-apt, esudo, python-elm-extensions | ||
Maintainer: Jeff Hoogland | ||
Description: eepDater GUI System Updater | ||
An Elementary GUI for installing system updates written in py-efls. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
|
||
DIRECTORY="/opt/eepDater" | ||
|
||
if [ -d "$DIRECTORY" ]; then | ||
# Control will enter here if $DIRECTORY exists. | ||
rm -rf $DIRECTORY | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,364 @@ | ||
#!/usr/bin/python | ||
# encoding: utf-8 | ||
|
||
#eepDater - an GUI system updater for apt-get powered systems written in python and elementary | ||
# | ||
#Written by: Jeff Hoogland | ||
#Started: 03/04/2014 | ||
|
||
from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL | ||
from efl import elementary | ||
from efl.elementary.window import StandardWindow | ||
from efl.elementary.box import Box | ||
from efl.elementary.separator import Separator | ||
from efl.elementary.button import Button | ||
from efl.elementary.entry import Entry | ||
from efl.elementary.toolbar import Toolbar, ELM_TOOLBAR_SHRINK_MENU, \ | ||
ELM_OBJECT_SELECT_MODE_NONE | ||
from efl.elementary.frame import Frame | ||
from efl.elementary.label import Label | ||
from efl.elementary.scroller import Scroller | ||
from efl.elementary.check import Check | ||
from efl.elementary.progressbar import Progressbar | ||
from efl.elementary.popup import Popup | ||
from efl.elementary.icon import Icon | ||
from efl.elementary.image import Image | ||
from efl.elementary.innerwindow import InnerWindow | ||
from efl.elementary.entry import Entry, ELM_TEXT_FORMAT_PLAIN_UTF8 | ||
from efl.elementary.flip import Flip, ELM_FLIP_ROTATE_X_CENTER_AXIS, \ | ||
ELM_FLIP_ROTATE_Y_CENTER_AXIS, ELM_FLIP_ROTATE_XZ_CENTER_AXIS, \ | ||
ELM_FLIP_ROTATE_YZ_CENTER_AXIS, ELM_FLIP_CUBE_LEFT, ELM_FLIP_CUBE_RIGHT, \ | ||
ELM_FLIP_CUBE_UP, ELM_FLIP_CUBE_DOWN, ELM_FLIP_PAGE_LEFT, \ | ||
ELM_FLIP_PAGE_RIGHT, ELM_FLIP_PAGE_UP, ELM_FLIP_PAGE_DOWN, \ | ||
ELM_FLIP_DIRECTION_UP, ELM_FLIP_DIRECTION_DOWN, \ | ||
ELM_FLIP_DIRECTION_LEFT, ELM_FLIP_DIRECTION_RIGHT, \ | ||
ELM_FLIP_INTERACTION_NONE, ELM_FLIP_INTERACTION_ROTATE, \ | ||
ELM_FLIP_INTERACTION_CUBE, ELM_FLIP_INTERACTION_PAGE | ||
import efl.ecore as ecore | ||
|
||
from elmextensions import SortedList | ||
from elmextensions import EmbeddedTerminal | ||
|
||
import apt | ||
from apt.progress.base import OpProgress as BaseOpProgress | ||
from apt.progress.base import AcquireProgress as BaseAcquireProgress | ||
from apt.progress.base import InstallProgress as BaseInstallProgress | ||
import os | ||
|
||
EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND | ||
EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 | ||
FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL | ||
FILL_HORIZ = EVAS_HINT_FILL, 0.5 | ||
ALIGN_CENTER = 0.5, 0.5 | ||
|
||
class MainWin(StandardWindow): | ||
def __init__(self, app): | ||
# create the main window | ||
StandardWindow.__init__(self, "eepDater", "eepDater - System Updater", | ||
autodel=True, size=(600, 400)) | ||
self.callback_delete_request_add(lambda o: elementary.exit()) | ||
self.app = app | ||
|
||
icon = Icon(self) | ||
icon.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND) | ||
icon.size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL) | ||
icon.standard_set('update-manager') | ||
icon.show() | ||
self.icon_object_set(icon.object_get()) | ||
|
||
# build the two main boxes | ||
self.mainBox = self.buildMainBox() | ||
self.loadBox = self.buildLoadBox() | ||
|
||
# build the information details inwin object | ||
self.buildDetailsWin() | ||
|
||
# the flip object has the load screen on one side and the GUI on the other | ||
self.flip = Flip(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_BOTH) | ||
self.flip.part_content_set("front", self.mainBox) | ||
self.flip.part_content_set("back", self.loadBox) | ||
self.resize_object_add(self.flip) | ||
self.flip.show() | ||
|
||
# show the window | ||
self.show() | ||
|
||
def buildDetailsWin(self): | ||
self.updateTerm = EmbeddedTerminal(self, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) | ||
self.updateTerm.show() | ||
|
||
closebtn = Button(self) | ||
closebtn.text_set("Done") | ||
closebtn.callback_pressed_add(self.innerWinHide) | ||
closebtn.show() | ||
|
||
box = Box(self, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) | ||
box.pack_end(self.updateTerm) | ||
box.pack_end(closebtn) | ||
box.show() | ||
|
||
self.innerWin = InnerWindow(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_HORIZ) | ||
self.innerWin.content_set(box) | ||
|
||
def innerWinShow(self, obj=False): | ||
self.innerWin.show() | ||
self.innerWin.activate() | ||
|
||
def innerWinHide(self, obj=False): | ||
self.innerWin.hide() | ||
|
||
def buildLoadBox(self): | ||
# build the load label | ||
loadLable = Label(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_HORIZ) | ||
loadLable.text = "<b>Processing</b>" | ||
loadLable.show() | ||
|
||
# build the spinning wheel | ||
wheel = Progressbar(self, pulse_mode=True, | ||
size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_HORIZ) | ||
wheel.pulse(True) | ||
wheel.show() | ||
|
||
detailsbtn = Button(self, style="anchor") | ||
detailsbtn.text_set("Details") | ||
detailsbtn.callback_pressed_add(self.innerWinShow) | ||
detailsbtn.show() | ||
|
||
# build the status label | ||
self.statusLabel = Label(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_HORIZ) | ||
self.statusLabel.show() | ||
|
||
# put all the built objects in a vertical box | ||
box = Box(self, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) | ||
box.pack_end(loadLable) | ||
box.pack_end(wheel) | ||
box.pack_end(self.statusLabel) | ||
box.pack_end(detailsbtn) | ||
box.show() | ||
|
||
return box | ||
|
||
def buildMainBox(self): | ||
location = os.path.dirname(os.path.abspath(__file__)) | ||
self.updatedImage = Icon(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_BOTH) | ||
self.updatedImage.standard_set("dialog-ok") | ||
self.updatedImage.show() | ||
|
||
# build our toolbar | ||
self.mainTb = Toolbar(self, homogeneous=False, | ||
size_hint_weight=(0.0, 0.0), | ||
size_hint_align=(EVAS_HINT_FILL, 0.0)) | ||
self.buildToolbar() | ||
|
||
# build our sortable list that displays packages that need updates | ||
titles = [("Upgrade", True), ("Package", True), | ||
("Installed", True), ("Available", True)] | ||
|
||
self.packageList = SortedList(self, titles=titles, homogeneous=False, | ||
size_hint_weight=EXPAND_HORIZ) | ||
|
||
# build the label that shows the package's description | ||
self.currentDescription = Label(self, | ||
size_hint_weight=FILL_BOTH) | ||
self.currentDescription.text = "Select a package for information" | ||
self.currentDescription.line_wrap_set(True) | ||
self.currentDescription.show() | ||
|
||
self.desFrame = Frame(self, size_hint_weight=EXPAND_HORIZ, | ||
size_hint_align=FILL_HORIZ) | ||
self.desFrame.text = "Description" | ||
self.desFrame.content = self.currentDescription | ||
self.desFrame.show() | ||
|
||
self.mainFlip = Flip(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_BOTH) | ||
self.mainFlip.part_content_set("front", self.packageList) | ||
self.mainFlip.part_content_set("back", self.updatedImage) | ||
self.mainFlip.show() | ||
|
||
# add all of our objects to the box | ||
box = Box(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_BOTH) | ||
box.pack_end(self.mainTb) | ||
box.pack_end(self.mainFlip) | ||
box.pack_end(self.desFrame) | ||
box.show() | ||
|
||
return box | ||
|
||
def buildToolbar(self, allClear=False): | ||
#self.mainTb.delete() | ||
while self.mainTb.first_item_get() is not None: | ||
self.mainTb.first_item_get().delete() | ||
if not allClear: | ||
self.mainTb.item_append("remove", "Clear", self.clearPressed) | ||
self.mainTb.item_append("add", "Select All", self.selectAllPressed) | ||
self.mainTb.item_append("view-refresh", "Refresh", self.refreshPressed) | ||
self.mainTb.item_append("info", "Log", self.detailsPressed) | ||
if not allClear: | ||
self.mainTb.item_append("system-upgrade", "Apply", self.installUpdatesPressed) | ||
self.mainTb.show() | ||
|
||
def detailsPressed(self, obj, it): | ||
it.selected = False | ||
self.innerWinShow() | ||
|
||
def clearPressed(self, obj, it): | ||
it.selected = False | ||
for rw in self.packageList.rows: | ||
rw[0].state = False | ||
self.app.checkChange(rw[0]) | ||
|
||
def selectAllPressed(self, obj, it): | ||
it.selected = False | ||
for rw in self.packageList.rows: | ||
rw[0].state = True | ||
self.app.checkChange(rw[0]) | ||
|
||
def refreshPressed(self, obj, it): | ||
it.selected = False | ||
self.app.refreshPackages() | ||
|
||
def installUpdatesPressed(self, obj, it): | ||
it.selected = False | ||
self.app.installUpdates() | ||
|
||
def packagePressed(self, obj): | ||
self.desFrame.text = "Description - %s" % obj.text | ||
self.currentDescription.text = obj.data["packageDes"] | ||
|
||
def addPackage(self, pak): | ||
row = [] | ||
|
||
ourCheck = Check(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=ALIGN_CENTER) | ||
ourCheck.data['packageName'] = pak.name | ||
ourCheck.callback_changed_add(self.app.checkChange) | ||
ourCheck.show() | ||
row.append(ourCheck) | ||
|
||
ourName = Button(self, style="anchor", size_hint_weight=(1, EVAS_HINT_EXPAND)) | ||
ourName.text = pak.name | ||
ourName.data["packageDes"] = pak.candidate.description | ||
ourName.callback_pressed_add(self.packagePressed) | ||
ourName.show() | ||
|
||
row.append(ourName) | ||
|
||
ourVersion = Label(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_BOTH) | ||
ourVersion.text = pak.installed.version | ||
ourVersion.show() | ||
|
||
row.append(ourVersion) | ||
|
||
newVersion = Label(self, size_hint_weight=EXPAND_BOTH, | ||
size_hint_align=FILL_BOTH) | ||
newVersion.text = pak.candidate.version | ||
newVersion.show() | ||
|
||
row.append(newVersion) | ||
|
||
self.packageList.row_pack(row, sort=False) | ||
|
||
def showDialog(self, title, msg): | ||
dia = Popup(self) | ||
dia.part_text_set("title,text", title) | ||
dia.part_text_set("default", msg) | ||
|
||
bt = Button(dia, text="Ok") | ||
bt.callback_clicked_add(lambda b: dia.delete()) | ||
dia.part_content_set("button1", bt) | ||
|
||
dia.show() | ||
|
||
def updatesPending(self): | ||
if not self.mainFlip.front_visible: | ||
self.mainFlip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) | ||
self.buildToolbar() | ||
|
||
def fullyUpdated(self): | ||
if self.mainFlip.front_visible: | ||
self.mainFlip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) | ||
self.buildToolbar(True) | ||
self.desFrame.text = "Fully Updated" | ||
self.currentDescription.text = "Your system is fully up to date!" | ||
|
||
|
||
class eepDater(object): | ||
def __init__(self): | ||
self.packagesToUpdate = [] | ||
self.apt = apt.cache.Cache() | ||
|
||
self.win = MainWin(self) | ||
|
||
def checkChange(self, obj): | ||
packageName = obj.data['packageName'] | ||
if obj.state_get() == True: | ||
self.packagesToUpdate.append(packageName) | ||
else: | ||
self.packagesToUpdate.remove(packageName) | ||
|
||
def installUpdates(self): | ||
if len(self.packagesToUpdate) == 0: | ||
self.win.showDialog("Nothing to do", | ||
"No packages selected to upgrade.<br>" \ | ||
"You must select at least one package from the list.") | ||
return | ||
self.win.statusLabel.text = "<i>Installing selected packages...</i>" | ||
self.win.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) | ||
packageList = "" | ||
for pkg in self.packagesToUpdate: | ||
packageList = "%s %s"%(packageList, pkg) | ||
#Adding running the command in the default xterm to work around ncurses bugs | ||
self.win.updateTerm.runCommand("terminology -H -e 'sudo apt-get -y install%s'"%packageList, self.installUpdatesDone) | ||
|
||
def installUpdatesDone(self): | ||
del self.packagesToUpdate[:] | ||
self.refreshPackages(False) | ||
|
||
def refreshPackages(self, flippy=True): | ||
self.win.statusLabel.text = "<i>Refreshing package lists...</i>" | ||
if flippy: | ||
self.win.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) | ||
|
||
self.win.updateTerm.runCommand("apt-get update", self.refreshPackagesDone) | ||
|
||
def refreshPackagesDone(self): | ||
# clear the packages list | ||
storerows = list(self.win.packageList.rows) | ||
|
||
for row in storerows: | ||
self.win.packageList.row_unpack(row, True) | ||
|
||
upgradables = [] | ||
# populate the packages list | ||
self.apt.open() | ||
for pak in self.apt: | ||
if pak.is_upgradable: | ||
upgradables.append(pak) | ||
|
||
if len(upgradables): | ||
self.win.updatesPending() | ||
for pak in upgradables: | ||
self.win.addPackage(pak) | ||
else: | ||
self.win.fullyUpdated() | ||
|
||
self.win.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) | ||
|
||
if __name__ == "__main__": | ||
elementary.init() | ||
|
||
app = eepDater() | ||
app.refreshPackages() | ||
|
||
elementary.run() | ||
|
||
elementary.shutdown() |
Oops, something went wrong.