Thread: [Pypt-offline-general] SF.net SVN: pypt-offline: [108] trunk
Status: Beta
Brought to you by:
riteshsarraf
|
From: <rit...@us...> - 2006-12-29 18:26:57
|
Revision: 108
http://svn.sourceforge.net/pypt-offline/?rev=108&view=rev
Author: riteshsarraf
Date: 2006-12-29 10:26:58 -0800 (Fri, 29 Dec 2006)
Log Message:
-----------
Workarounds
Added Paths:
-----------
trunk/pypt-offline
Removed Paths:
-------------
trunk/pypt-offline.sh
Copied: trunk/pypt-offline (from rev 106, trunk/pypt-offline.sh)
===================================================================
--- trunk/pypt-offline (rev 0)
+++ trunk/pypt-offline 2006-12-29 18:26:58 UTC (rev 108)
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# pypt-offline.py
+#
+############################################################################
+# Copyright (C) 2005, 2006 Ritesh Raj Sarraf #
+# rr...@re... #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software F[-d] [-s] [-u]oundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+
+from pypt_core import main
+
+if __name__ == "__main__":
+ main()
Deleted: trunk/pypt-offline.sh
===================================================================
--- trunk/pypt-offline.sh 2006-12-29 18:25:31 UTC (rev 107)
+++ trunk/pypt-offline.sh 2006-12-29 18:26:58 UTC (rev 108)
@@ -1,28 +0,0 @@
-#!/usr/bin/env python
-# pypt-offline.py
-#
-############################################################################
-# Copyright (C) 2005, 2006 Ritesh Raj Sarraf #
-# rr...@re... #
-# #
-# This program is free software; you can redistribute it and#or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation; either version 2 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program; if not, write to the #
-# Free Software F[-d] [-s] [-u]oundation, Inc., #
-# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
-############################################################################
-
-
-from pypt_core import main
-
-if __name__ == "__main__":
- main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2006-12-29 18:14:52
|
Revision: 106
http://svn.sourceforge.net/pypt-offline/?rev=106&view=rev
Author: riteshsarraf
Date: 2006-12-29 10:14:53 -0800 (Fri, 29 Dec 2006)
Log Message:
-----------
Realigning the tree to trunk
Added Paths:
-----------
trunk/CHANGELOG
trunk/INSTALL
trunk/KNOWN-BUGS
trunk/LICENSE
trunk/Makefile
trunk/README
trunk/THANKS
trunk/TODO
trunk/build.xml
trunk/launch-pypt-offline-gui.py
trunk/progressbar.py
trunk/pypt-offline.sh
trunk/pypt_core.py
trunk/pypt_logger.py
trunk/pypt_magic.py
trunk/pypt_md5_check.py
trunk/pypt_offline_gui.ui.h
trunk/pypt_progressbar.py
trunk/pypt_variables.py
trunk/pyptofflinegui.py
trunk/pyptofflinegui.ui
Removed Paths:
-------------
trunk/CVSROOT/
trunk/pypt-offline/
Copied: trunk/CHANGELOG (from rev 105, trunk/pypt-offline/CHANGELOG)
===================================================================
--- trunk/CHANGELOG (rev 0)
+++ trunk/CHANGELOG 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,15 @@
+Version ?? -- XX/XX/XXXX
+ * Broke pypt-offlie.py into pypt_core.py and pypt-offline.py for modularity.
+
+Version 0.5beta -- 03/10/2005
+ * Did more code cleanup
+ * Changed the algorithm to check in local cache
+ * Now supports checking in recursive folders for packages (Like apt-proxy's folder structure)
+
+Version 0.4beta -- 02/20/2005
+ * Did some code cleanup
+ * Added support for Windows -- Now we are usable on Microsoft Windows os's also
+ * Remove dependency on "wget". Now using native python library to fetch urls.
+
+Version 0.3alpha -- 01/17/2005
+ * Initial Release
Copied: trunk/INSTALL (from rev 105, trunk/pypt-offline/INSTALL)
===================================================================
--- trunk/INSTALL (rev 0)
+++ trunk/INSTALL 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,13 @@
+## Under Linux
+
+chmod 755 pypt-offline[.py]
+Execute the command with the proper options
+./pypt-offline [OPTIONS]
+
+
+## Under Microsoft Windows
+
+# Execute the file using the python interpreter
+# Assuming python.exe is in your path
+
+C:\> python pypt-offline [OPTIONS]
Copied: trunk/KNOWN-BUGS (from rev 105, trunk/pypt-offline/KNOWN-BUGS)
===================================================================
--- trunk/KNOWN-BUGS (rev 0)
+++ trunk/KNOWN-BUGS 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,4 @@
+Version 0.5b -- 03/27/2005
+ * Executing pypt-offline without any argument causes an exception [FIXED]
+ * Loose Microsoft Windows support (I've not done thorough check on Windows machines. Please let me know of any bugs) [FIXED]
+ * urllib.urlretrieve doesn't raise an exception even if the target url is broken [FIXED]
Copied: trunk/LICENSE (from rev 105, trunk/pypt-offline/LICENSE)
===================================================================
--- trunk/LICENSE (rev 0)
+++ trunk/LICENSE 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,16 @@
+Copyright (C) 2005, 2006 by Ritesh Raj Sarraf <rr...@re...>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the
+Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\ No newline at end of file
Copied: trunk/Makefile (from rev 105, trunk/pypt-offline/Makefile)
===================================================================
--- trunk/Makefile (rev 0)
+++ trunk/Makefile 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,5 @@
+all:
+ pyuic pyptofflinegui.ui > pyptofflinegui.py
+
+clean:
+ rm -f pyptofflinegui.py
\ No newline at end of file
Copied: trunk/README (from rev 105, trunk/pypt-offline/README)
===================================================================
--- trunk/README (rev 0)
+++ trunk/README 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,188 @@
+pypt-offline -- An Offline Package Manager
+(C) 2005, 2006 Ritesh Raj Sarraf <rr...@re...>
+
+
+
+# INTRODUCTION
+
+So you've decided to give this small piece of work a try.
+Good ! Let's get it done faster.
+
+
+
+pypt-offline is an offline package management tool written in the Python Programming Language.
+This program, as of now, is intended for people using Debian (And Debian based) systems.
+
+This program allows leveraging the power of Debian (more precisely apt-get) onto a completely
+disconnected machine. Most of the people with slow or no internet connection (most of those in
+India/Nepal/Pakistan and nearby countries) have not considered using Debian (or Debian derived
+distributions) because Debian's real taste is experienced when it is connected to the internet.
+
+This utility is an attempt in making that problem eradicate. I hope this utility comes to use to you.
+I'd be eager to hear your comments/suggestions. Feel free to drop an email at rrs _AT_ researchut |DOT| com
+
+
+#########################################################################
+
+Let us assume you have a machine at home ( Hereby called Machine-A) with no or very expensive
+internet connection on which you've installed Debian (Hereby all Debian and Debian based systems
+will be called as Debian).
+
+You or your friend works at a local city office where they have High Speed Internet Connection.
+The machine used there is Linux/Windows/Mac box. We'll call this Machine-B henceforth.
+
+pypt-offline allows you to synchronize Machine-A's apt database with the Debian archives.
+It does so by
+* Extracting the details of Machine-A's apt's database which needs to updated
+* Fetches the required database on Machine-B
+* Synchronizes the fetched database back to Machine-A
+
+
+With these 3 steps you can keep a disconnected Debian machine up-to-date on a daily basis.
+
+
+The rest of the document will describe the details along with the commands.
+
+
+
+STEP - 1
+
+
+
+On Machine-A:
+
+
+pypt-offline --set-update /tmp/update-uris
+
+
+With this command, pypt-offline extracts the details from apt's database for the files that
+are required to update apt's package database. The extracted information is stored in /tmp/update-uris
+
+
+pypt-offline --set-upgrade /tmp/upgrade-uris --upgrade-type dselect-upgrade
+
+
+With this command, pypt-offline extracts the details from apt's database for the packages that
+are required to be upgraded. The extraced information is stored in /tmp/upgrade-uris
+There are 3 types of "upgrade" type. "upgrade", "dist-upgrade" and "dselect-upgrade".
+You can pass any one of them.
+Note: --set-upgrade and --upgrade-type are mutually inclusive. You cannot use one option without the other
+
+
+pypt-offline --set-install /tmp/install-uris --set-install-packages package1 package2 packageN
+
+
+With this command, pypt-offline extracts the details from apt's database for the packages
+(and its dependent packages) that are required to be installed. The extracted information is
+stored in /tmp/install-uris
+Note: --set-install and --set-install-packages are mutually inclusive. You cannot use one option
+without the other
+
+
+
+The above mentioned options are executed on Machine-A. They extract the details from apt's database.
+
+
+Now the user needs to copy the extracted data file onto a removable media and take it to Machine-B.
+
+
+
+STEP - 2
+
+
+
+On Machine-B:
+
+With the extracted data file in hand, on Machine-B, execute the following commands:
+
+
+pypt-offline --fetch-update /tmp/update-uris [ -d /tmp/updates/ -s /tmp/repository/ --disable-md5check
+--zip --zip-update-file /tmp/updates.zip --zip-upgrade-file /tmp/upgrades.zip]
+
+
+With this command, pypt-offline fetches the required data from the internet as directed by Machine-A
+The options in square bracket are optional
+
+
+-d /tm/updates/ - With this option, the directory where the downloaded data will be saved is set.
+If the option is not given, a folder named pypt-offline-downloads is created under the current working directory.
+
+
+-s /tmp/repository/ - With this option, the directory where the previously downloaded data was saved
+is searched. This is used so that you don't download the same file again and again. If the option is
+not given, the current working directory is used as the repository and all files and folders under it
+are recursively searched.
+Also the freshly downloaded files are copied to this folder so that you don't have to download it again
+the next time.
+Note: This option is effective only for packages which are downloaded and *NOT* for update files.
+Update files change almost daily in the Debian repositories, hence keeping a local cache is useless.
+
+
+--disable-md5check - It is *highly discouraged* to use this option. By default, pypt-offline compares
+the md5checksum for every package it downloads. If the md5checksum don't match, the file is deleted.
+This is necessary to make sure that you don't end up having tampered packages.
+Note: This option is effective only for packages which are downloaded and *NOT* for update files.
+Update files currently don't provide md5checksum details.
+
+
+--zip - It is *highly encouraged* to use this option. Though disabled by default, if enabled, pypt-offline
+creates a single zip file of the downloaded files. This way it is easier to track the downloaded files.
+
+
+--zip-update-files - This option sets the zip file name. If this option is not set, pypt-offline uses the
+default file name, pypt-offline-update.zip
+
+
+--zip-upgrade-files - This option sets the zip file name. If this option is not set, pypt-offline uses the
+default file name, pypt-offline-upgrade.zip
+
+
+If you don't use the --zip option, the downloaded files are stored in the folder you mentioned with the -d option.
+You'll need to copy the files from the folder.
+
+
+With this, once all the data has been downloaded, copy it to your removable storage device and take it back to Machine-A.
+
+
+
+STEP - 3
+
+
+On Machine-A:
+
+
+Once you come back to Machine-A:
+
+
+
+pypt-offline --install-update /tmp/updates.zip [ /tmp/]
+
+
+With this command, pypt-offline syncs the update files from updates.zip. If a folder name is given as an
+argument to --install-update, it searches for the required files and syncs them to apt's package database.
+
+
+pypt-offline --install-upgrade /tmp/upgrade.zip [/tmp/]
+
+
+With this command, pypt-offline syncs the package from updates.zip. If a folder name is given as an argument
+to --install-update, it searches for the requires files and syncs them to apt's package database.
+Note: Please keep in mind that this doesn't actually install/upgrade the packages.
+It just makes the "To Be Downloaded" package available. With it apt will not require to download any additional
+packages and hence will do the installation as if it was downloaded from the internet.
+
+
+NOTE: If you use apt-listbugs to track package bugs while you install, it'll fail because apt-listbugs will try
+to connect to the internet.
+
+
+
+
+
+That's all. Please send your comments and suggestions to me at rrs _AT_ researchut |DOT| com
+If you come across any bug [misbehavior, feature request], file them at the Bug tracker.
+There's also a mailing list available at https://lists.sourceforge.net/lists/listinfo/pypt-offline-general
+
+
+Thanks,
+Ritesh Raj Sarraf
\ No newline at end of file
Copied: trunk/THANKS (from rev 105, trunk/pypt-offline/THANKS)
===================================================================
--- trunk/THANKS (rev 0)
+++ trunk/THANKS 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,6 @@
+These are, namely some of the people, who've helped me a lot in my process of learning programming.
+*) Peter Otten
+*) Duncan Booth
+*) Simon Forman
+*) Dennis Lee Bieber
+*) Any others whom I've missed
\ No newline at end of file
Copied: trunk/TODO (from rev 105, trunk/pypt-offline/TODO)
===================================================================
--- trunk/TODO (rev 0)
+++ trunk/TODO 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,14 @@
+* Support for RPM packages (Using YUM)
+* Argument Parsing <done>
+* Usage of apt-proxy like services, if available <done>
+* Usage of a .pypt-offlinerc config file
+* Download status indicator <done>
+* Proxy Authentication
+* Implement a function which will keep track of the failed uris and print them at last. It'll keep the uri and it's failure reason as a dictionary <done>
+* Implement Threads - When we implement threads multiple files will be downloaded at the same time. <done>
+ At that point, say we execute with 5 threads, the progressbar for all 5 threads should be displayed together.
+* Implement Curses and GUI interfaces. For these UIs it will be interactive. For all the options, only one will be selectable and once that option
+ is selected the others will be deactivated. That's design, only one option allowed a time. :-)
+* Use Python's logging module to better handle messages, warnings and errors <done>
+* Implement apt's newly added feature (> 0.6.4) of Package Diff
+* Add functionality for Offline Bug Reports
\ No newline at end of file
Copied: trunk/build.xml (from rev 105, trunk/pypt-offline/build.xml)
===================================================================
--- trunk/build.xml (rev 0)
+++ trunk/build.xml 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<project name="pypt-offline" default="make">
+ <description>
+ Ant adaptor for the pypt-offline Makefile
+ </description>
+
+ <target name="make" description="build pyptofflinegui">
+ <exec executable="make">
+ <arg value="-f"/>
+ <arg value="Makefile"/>
+ <arg value="all"/>
+ </exec>
+ </target>
+
+ <target name="clean" description="clean pypt-offline" depends="make">
+ <exec executable="make">
+ <arg value="-f"/>
+ <arg value="Makefile"/>
+ <arg value="clean"/>
+ </exec>
+ </target>
+</project>
Copied: trunk/launch-pypt-offline-gui.py (from rev 105, trunk/pypt-offline/launch-pypt-offline-gui.py)
===================================================================
--- trunk/launch-pypt-offline-gui.py (rev 0)
+++ trunk/launch-pypt-offline-gui.py 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+from qt import *
+from pyptofflinegui import pyptofflineguiForm
+
+
+if __name__ == "__main__":
+ import sys
+ a = QApplication(sys.argv)
+ QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
+ w = pyptofflineguiForm()
+ a.setMainWidget(w)
+ w.show()
+ a.exec_loop()
Copied: trunk/progressbar.py (from rev 105, trunk/pypt-offline/progressbar.py)
===================================================================
--- trunk/progressbar.py (rev 0)
+++ trunk/progressbar.py 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,368 @@
+#!/usr/bin/python
+# -*- coding: iso-8859-1 -*-
+#
+# progressbar - Text progressbar library for python.
+# Copyright (c) 2005 Nilton Volpato
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+"""Text progressbar library for python.
+
+This library provides a text mode progressbar. This is tipically used
+to display the progress of a long running operation, providing a
+visual clue that processing is underway.
+
+The ProgressBar class manages the progress, and the format of the line
+is given by a number of widgets. A widget is an object that may
+display diferently depending on the state of the progress. There are
+three types of widget:
+- a string, which always shows itself;
+- a ProgressBarWidget, which may return a diferent value every time
+it's update method is called; and
+- a ProgressBarWidgetHFill, which is like ProgressBarWidget, except it
+expands to fill the remaining width of the line.
+
+The progressbar module is very easy to use, yet very powerful. And
+automatically supports features like auto-resizing when available.
+"""
+
+__author__ = "Nilton Volpato"
+__author_email__ = "first-name dot last-name @ gmail.com"
+__date__ = "2006-05-07"
+__version__ = "2.2"
+
+# Changelog
+#
+# 2006-05-07: v2.2 fixed bug in windows
+# 2005-12-04: v2.1 autodetect terminal width, added start method
+# 2005-12-04: v2.0 everything is now a widget (wow!)
+# 2005-12-03: v1.0 rewrite using widgets
+# 2005-06-02: v0.5 rewrite
+# 2004-??-??: v0.1 first version
+
+
+import sys, time
+from array import array
+try:
+ from fcntl import ioctl
+ import termios
+except ImportError:
+ pass
+import signal
+
+class ProgressBarWidget(object):
+ """This is an element of ProgressBar formatting.
+
+ The ProgressBar object will call it's update value when an update
+ is needed. It's size may change between call, but the results will
+ not be good if the size changes drastically and repeatedly.
+ """
+ def update(self, pbar):
+ """Returns the string representing the widget.
+
+ The parameter pbar is a reference to the calling ProgressBar,
+ where one can access attributes of the class for knowing how
+ the update must be made.
+
+ At least this function must be overriden."""
+ pass
+
+class ProgressBarWidgetHFill(object):
+ """This is a variable width element of ProgressBar formatting.
+
+ The ProgressBar object will call it's update value, informing the
+ width this object must the made. This is like TeX \\hfill, it will
+ expand to fill the line. You can use more than one in the same
+ line, and they will all have the same width, and together will
+ fill the line.
+ """
+ def update(self, pbar, width):
+ """Returns the string representing the widget.
+
+ The parameter pbar is a reference to the calling ProgressBar,
+ where one can access attributes of the class for knowing how
+ the update must be made. The parameter width is the total
+ horizontal width the widget must have.
+
+ At least this function must be overriden."""
+ pass
+
+
+class ETA(ProgressBarWidget):
+ "Widget for the Estimated Time of Arrival"
+ def format_time(self, seconds):
+ return time.strftime('%H:%M:%S', time.gmtime(seconds))
+ def update(self, pbar):
+ if pbar.currval == 0:
+ return 'ETA: --:--:--'
+ elif pbar.finished:
+ return 'Time: %s' % self.format_time(pbar.seconds_elapsed)
+ else:
+ elapsed = pbar.seconds_elapsed
+ eta = elapsed * pbar.maxval / pbar.currval - elapsed
+ return 'ETA: %s' % self.format_time(eta)
+
+class FileTransferSpeed(ProgressBarWidget):
+ "Widget for showing the transfer speed (useful for file transfers)."
+ def __init__(self):
+ self.fmt = '%6.2f %s'
+ self.units = ['B','K','M','G','T','P']
+ def update(self, pbar):
+ if pbar.seconds_elapsed < 2e-6:#== 0:
+ bps = 0.0
+ else:
+ bps = float(pbar.currval) / pbar.seconds_elapsed
+ spd = bps
+ for u in self.units:
+ if spd < 1000:
+ break
+ spd /= 1000
+ return self.fmt % (spd, u+'/s')
+
+class RotatingMarker(ProgressBarWidget):
+ "A rotating marker for filling the bar of progress."
+ def __init__(self, markers='|/-\\'):
+ self.markers = markers
+ self.curmark = -1
+ def update(self, pbar):
+ if pbar.finished:
+ return self.markers[0]
+ self.curmark = (self.curmark + 1)%len(self.markers)
+ return self.markers[self.curmark]
+
+class Percentage(ProgressBarWidget):
+ "Just the percentage done."
+ def update(self, pbar):
+ return '%3d%%' % pbar.percentage()
+
+class Bar(ProgressBarWidgetHFill):
+ "The bar of progress. It will strech to fill the line."
+ def __init__(self, marker='#', left='|', right='|'):
+ self.marker = marker
+ self.left = left
+ self.right = right
+ def _format_marker(self, pbar):
+ if isinstance(self.marker, (str, unicode)):
+ return self.marker
+ else:
+ return self.marker.update(pbar)
+ def update(self, pbar, width):
+ percent = pbar.percentage()
+ cwidth = width - len(self.left) - len(self.right)
+ marked_width = int(percent * cwidth / 100)
+ m = self._format_marker(pbar)
+ bar = (self.left + (m*marked_width).ljust(cwidth) + self.right)
+ return bar
+
+class ReverseBar(Bar):
+ "The reverse bar of progress, or bar of regress. :)"
+ def update(self, pbar, width):
+ percent = pbar.percentage()
+ cwidth = width - len(self.left) - len(self.right)
+ marked_width = int(percent * cwidth / 100)
+ m = self._format_marker(pbar)
+ bar = (self.left + (m*marked_width).rjust(cwidth) + self.right)
+ return bar
+
+default_widgets = [Percentage(), ' ', Bar()]
+class ProgressBar(object):
+ """This is the ProgressBar class, it updates and prints the bar.
+
+ The term_width parameter may be an integer. Or None, in which case
+ it will try to guess it, if it fails it will default to 80 columns.
+
+ The simple use is like this:
+ >>> pbar = ProgressBar().start()
+ >>> for i in xrange(100):
+ ... # do something
+ ... pbar.update(i+1)
+ ...
+ >>> pbar.finish()
+
+ But anything you want to do is possible (well, almost anything).
+ You can supply different widgets of any type in any order. And you
+ can even write your own widgets! There are many widgets already
+ shipped and you should experiment with them.
+
+ When implementing a widget update method you may access any
+ attribute or function of the ProgressBar object calling the
+ widget's update method. The most important attributes you would
+ like to access are:
+ - currval: current value of the progress, 0 <= currval <= maxval
+ - maxval: maximum (and final) value of the progress
+ - finished: True if the bar is have finished (reached 100%), False o/w
+ - start_time: first time update() method of ProgressBar was called
+ - seconds_elapsed: seconds elapsed since start_time
+ - percentage(): percentage of the progress (this is a method)
+ """
+ def __init__(self, maxval=100, widgets=default_widgets, term_width=None,
+ fd=sys.stderr):
+ assert maxval > 0
+ self.maxval = maxval
+ self.widgets = widgets
+ self.fd = fd
+ self.signal_set = False
+ if term_width is None:
+ try:
+ self.handle_resize(None,None)
+ signal.signal(signal.SIGWINCH, self.handle_resize)
+ self.signal_set = True
+ except:
+ self.term_width = 79
+ else:
+ self.term_width = term_width
+
+ self.currval = 0
+ self.finished = False
+ self.prev_percentage = -1
+ self.start_time = None
+ self.seconds_elapsed = 0
+
+ def handle_resize(self, signum, frame):
+ h,w=array('h', ioctl(self.fd,termios.TIOCGWINSZ,'\0'*8))[:2]
+ self.term_width = w
+
+ def percentage(self):
+ "Returns the percentage of the progress."
+ return self.currval*100.0 / self.maxval
+
+ def _format_widgets(self):
+ r = []
+ hfill_inds = []
+ num_hfill = 0
+ currwidth = 0
+ for i, w in enumerate(self.widgets):
+ if isinstance(w, ProgressBarWidgetHFill):
+ r.append(w)
+ hfill_inds.append(i)
+ num_hfill += 1
+ elif isinstance(w, (str, unicode)):
+ r.append(w)
+ currwidth += len(w)
+ else:
+ weval = w.update(self)
+ currwidth += len(weval)
+ r.append(weval)
+ for iw in hfill_inds:
+ r[iw] = r[iw].update(self, (self.term_width-currwidth)/num_hfill)
+ return r
+
+ def _format_line(self):
+ return ''.join(self._format_widgets()).ljust(self.term_width)
+
+ def _need_update(self):
+ return int(self.percentage()) != int(self.prev_percentage)
+
+ def update(self, value):
+ "Updates the progress bar to a new value."
+ #assert 0 <= value <= self.maxval
+ self.currval = value
+ if not self._need_update() or self.finished:
+ return
+ if not self.start_time:
+ self.start_time = time.time()
+ self.seconds_elapsed = time.time() - self.start_time
+ self.prev_percentage = self.percentage()
+ if value != self.maxval:
+ self.fd.write(self._format_line() + '\r')
+ else:
+ self.finished = True
+ self.fd.write(self._format_line() + '\n')
+
+ def start(self):
+ """Start measuring time, and prints the bar at 0%.
+
+ It returns self so you can use it like this:
+ >>> pbar = ProgressBar().start()
+ >>> for i in xrange(100):
+ ... # do something
+ ... pbar.update(i+1)
+ ...
+ >>> pbar.finish()
+ """
+ self.update(0)
+ return self
+
+ def finish(self):
+ """Used to tell the progress is finished."""
+ self.update(self.maxval)
+ if self.signal_set:
+ signal.signal(signal.SIGWINCH, signal.SIG_DFL)
+
+
+
+
+
+
+if __name__=='__main__':
+ import os
+
+ def example1():
+ widgets = ['Test: ', Percentage(), ' ', Bar(marker=RotatingMarker()),
+ ' ', ETA(), ' ', FileTransferSpeed()]
+ pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
+ for i in range(1000000):
+ # do something
+ pbar.update(10*i+1)
+ pbar.finish()
+ print
+
+ def example2():
+ class CrazyFileTransferSpeed(FileTransferSpeed):
+ "It's bigger between 45 and 80 percent"
+ def update(self, pbar):
+ if 45 < pbar.percentage() < 80:
+ return 'Bigger Now ' + FileTransferSpeed.update(self,pbar)
+ else:
+ return FileTransferSpeed.update(self,pbar)
+
+ widgets = [CrazyFileTransferSpeed(),' <<<', Bar(), '>>> ', Percentage(),' ', ETA()]
+ pbar = ProgressBar(widgets=widgets, maxval=10000000)
+ # maybe do something
+ pbar.start()
+ for i in range(2000000):
+ # do something
+ pbar.update(5*i+1)
+ pbar.finish()
+ print
+
+ def example3():
+ widgets = [Bar('>'), ' ', ETA(), ' ', ReverseBar('<')]
+ pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
+ for i in range(1000000):
+ # do something
+ pbar.update(10*i+1)
+ pbar.finish()
+ print
+
+ def example4():
+ widgets = ['Test: ', Percentage(), ' ',
+ Bar(marker='0',left='[',right=']'),
+ ' ', ETA(), ' ', FileTransferSpeed()]
+ pbar = ProgressBar(widgets=widgets, maxval=500)
+ pbar.start()
+ for i in range(100,500+1,50):
+ time.sleep(0.2)
+ pbar.update(i)
+ pbar.finish()
+ print
+
+
+ example1()
+ example2()
+ example3()
+ example4()
+
Added: trunk/pypt-offline.sh
===================================================================
--- trunk/pypt-offline.sh (rev 0)
+++ trunk/pypt-offline.sh 2006-12-29 18:14:53 UTC (rev 106)
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# pypt-offline.py
+#
+############################################################################
+# Copyright (C) 2005, 2006 Ritesh Raj Sarraf #
+# rr...@re... #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software F[-d] [-s] [-u]oundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+
+from pypt_core import main
+
+if __name__ == "__main__":
+ main()
Property changes on: trunk/pypt-offline.sh
____________________________________________________________...
[truncated message content] |
|
From: <rit...@us...> - 2006-12-29 18:51:08
|
Revision: 111
http://svn.sourceforge.net/pypt-offline/?rev=111&view=rev
Author: riteshsarraf
Date: 2006-12-29 10:51:08 -0800 (Fri, 29 Dec 2006)
Log Message:
-----------
They belong to the GUI branch
Removed Paths:
-------------
trunk/Makefile
trunk/build.xml
trunk/launch-pypt-offline-gui.py
trunk/pypt_offline_gui.ui.h
trunk/pyptofflinegui.py
trunk/pyptofflinegui.ui
Deleted: trunk/Makefile
===================================================================
--- trunk/Makefile 2006-12-29 18:29:26 UTC (rev 110)
+++ trunk/Makefile 2006-12-29 18:51:08 UTC (rev 111)
@@ -1,5 +0,0 @@
-all:
- pyuic pyptofflinegui.ui > pyptofflinegui.py
-
-clean:
- rm -f pyptofflinegui.py
\ No newline at end of file
Deleted: trunk/build.xml
===================================================================
--- trunk/build.xml 2006-12-29 18:29:26 UTC (rev 110)
+++ trunk/build.xml 2006-12-29 18:51:08 UTC (rev 111)
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<project name="pypt-offline" default="make">
- <description>
- Ant adaptor for the pypt-offline Makefile
- </description>
-
- <target name="make" description="build pyptofflinegui">
- <exec executable="make">
- <arg value="-f"/>
- <arg value="Makefile"/>
- <arg value="all"/>
- </exec>
- </target>
-
- <target name="clean" description="clean pypt-offline" depends="make">
- <exec executable="make">
- <arg value="-f"/>
- <arg value="Makefile"/>
- <arg value="clean"/>
- </exec>
- </target>
-</project>
Deleted: trunk/launch-pypt-offline-gui.py
===================================================================
--- trunk/launch-pypt-offline-gui.py 2006-12-29 18:29:26 UTC (rev 110)
+++ trunk/launch-pypt-offline-gui.py 2006-12-29 18:51:08 UTC (rev 111)
@@ -1,13 +0,0 @@
-#!/usr/bin/env python
-from qt import *
-from pyptofflinegui import pyptofflineguiForm
-
-
-if __name__ == "__main__":
- import sys
- a = QApplication(sys.argv)
- QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
- w = pyptofflineguiForm()
- a.setMainWidget(w)
- w.show()
- a.exec_loop()
Deleted: trunk/pypt_offline_gui.ui.h
===================================================================
--- trunk/pypt_offline_gui.ui.h 2006-12-29 18:29:26 UTC (rev 110)
+++ trunk/pypt_offline_gui.ui.h 2006-12-29 18:51:08 UTC (rev 111)
@@ -1,69 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-
-void Form1::fileExit()
-{
-
-}
-
-
-void Form1::helpIndex()
-{
-
-}
-
-
-void Form1::helpContents()
-{
-
-}
-
-
-void Form1::helpAbout()
-{
-
-}
-
-
-
-
-void Form1::whichOption(int)
-{
- if self.comboBox1.currentItem() == 0:
- # set-update
- pass
- elif self.comboBox1.currentItem() == 1:
- # set-upgrade
- self.comboBox2.setEnabled(True)
- elif self.comboBox1.currentItem() == 2:
- # fetch-update
- pass
- elif self.comboBox1.currentItem() == 3:
- # fetch-upgrade
- pass
- elif self.comboBox1.currentItem() == 4:
- # install-update
- pass
- elif self.comboBox1.currentItem() == 5:
- # install-upgrade
- pass
- else:
- error()
-}
-
-
-void Form1::whichUpgradeOption(int)
-{
- if self.comboBox2.currentItem() == 0:
- self.frame3.setEnabled(True)
-}
Deleted: trunk/pyptofflinegui.py
===================================================================
--- trunk/pyptofflinegui.py 2006-12-29 18:29:26 UTC (rev 110)
+++ trunk/pyptofflinegui.py 2006-12-29 18:51:08 UTC (rev 111)
@@ -1,648 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'pyptofflinegui.ui'
-#
-# Created: Mon Nov 6 01:06:29 2006
-# by: The PyQt User Interface Compiler (pyuic) 3.16
-#
-# WARNING! All changes made in this file will be lost!
-
-
-from qt import *
-
-image0_data = [
-"50 81 202 2",
-".J c #191919",
-".I c #1a1a1a",
-".K c #1b1b1b",
-".H c #1c1c1c",
-".E c #1d1d1d",
-".G c #1e1e1e",
-".F c #1f1f1f",
-".D c #202020",
-".x c #212121",
-".t c #222222",
-".u c #232323",
-".y c #242424",
-".s c #252525",
-".C c #262626",
-".v c #272727",
-".m c #282828",
-".B c #292929",
-".w c #2a2a2a",
-".q c #2b2b2b",
-".l c #2c2c2c",
-".j c #2d2d2d",
-".k c #2e2e2e",
-".i c #2f2f2f",
-".p c #303030",
-".r c #313131",
-".o c #323232",
-".h c #333333",
-".n c #343434",
-".c c #353535",
-".b c #363636",
-"Qt c #373737",
-".a c #383838",
-".e c #393939",
-".# c #3a3a3a",
-".d c #3b3b3b",
-".f c #3c3c3c",
-".A c #3d3d3d",
-".g c #3e3e3e",
-".z c #3f3f3f",
-".N c #404040",
-".L c #414141",
-".M c #424242",
-".V c #434343",
-".O c #444444",
-"aL c #454545",
-".Q c #464646",
-"aG c #474747",
-"#J c #484848",
-".R c #494949",
-".P c #4a4a4a",
-".W c #4b4b4b",
-".U c #4c4c4c",
-"aJ c #4d4d4d",
-".S c #4e4e4e",
-".T c #4f4f4f",
-".7 c #505050",
-".X c #515151",
-"aq c #525252",
-".Y c #535353",
-"ap c #545454",
-".8 c #555555",
-"#K c #565656",
-".9 c #575757",
-".Z c #585858",
-"ae c #595959",
-".6 c #5a5a5a",
-"#L c #5b5b5b",
-"aF c #5c5c5c",
-".0 c #5d5d5d",
-".5 c #5e5e5e",
-"aH c #5f5f5f",
-"aD c #606060",
-"aB c #616161",
-"aE c #626262",
-".1 c #636363",
-".4 c #646464",
-"aA c #656565",
-"#M c #666666",
-"#W c #676767",
-"#. c #686868",
-"al c #696969",
-"#k c #6a6a6a",
-"aC c #6b6b6b",
-".3 c #6c6c6c",
-"ai c #6d6d6d",
-".2 c #6e6e6e",
-"#y c #6f6f6f",
-"#m c #707070",
-"#j c #717171",
-"#l c #727272",
-"#I c #737373",
-"#h c #747474",
-"am c #757575",
-"#z c #767676",
-"#i c #777777",
-"#A c #787878",
-"ar c #797979",
-"#5 c #7a7a7a",
-"## c #7b7b7b",
-"#g c #7c7c7c",
-"#x c #7d7d7d",
-"#4 c #7e7e7e",
-"ah c #7f7f7f",
-"ak c #808080",
-"#n c #818181",
-"#B c #828282",
-"az c #838383",
-"#6 c #848484",
-"#a c #858585",
-"#b c #868686",
-"#o c #878787",
-"#f c #888888",
-"#c c #898989",
-"#d c #8a8a8a",
-"#w c #8b8b8b",
-"#3 c #8c8c8c",
-"#e c #8d8d8d",
-"ad c #8e8e8e",
-"#N c #8f8f8f",
-"ao c #909090",
-"#p c #919191",
-"ac c #929292",
-"#v c #939393",
-"#q c #949494",
-"#r c #959595",
-"#u c #969696",
-"#t c #979797",
-"#s c #989898",
-"as c #999999",
-"#C c #9a9a9a",
-"#D c #9b9b9b",
-"#E c #9c9c9c",
-"#F c #9d9d9d",
-"#H c #9e9e9e",
-"#O c #9f9f9f",
-"aK c #a0a0a0",
-"#G c #a1a1a1",
-"#P c #a2a2a2",
-"#Q c #a3a3a3",
-"#R c #a4a4a4",
-"#S c #a5a5a5",
-"#T c #a6a6a6",
-"#V c #a7a7a7",
-"ab c #a8a8a8",
-"#X c #a9a9a9",
-"#U c #aaaaaa",
-"#Y c #ababab",
-"#Z c #acacac",
-"#0 c #adadad",
-"aM c #aeaeae",
-"#2 c #afafaf",
-"#1 c #b0b0b0",
-"#7 c #b1b1b1",
-"a. c #b2b2b2",
-"a# c #b3b3b3",
-"aa c #b4b4b4",
-"#8 c #b5b5b5",
-"#9 c #b6b6b6",
-"af c #b7b7b7",
-"ag c #b8b8b8",
-"aj c #b9b9b9",
-"au c #bababa",
-"an c #bbbbbb",
-"at c #bcbcbc",
-"av c #bdbdbd",
-"ay c #bebebe",
-"ax c #bfbfbf",
-"aw c #c0c0c0",
-"aN c #c1c1c1",
-"aI c #c2c2c2",
-"aQ c #c3c3c3",
-"aO c #c4c4c4",
-"aV c #c5c5c5",
-"aR c #c6c6c6",
-"aZ c #c7c7c7",
-"aU c #c8c8c8",
-"aP c #c9c9c9",
-"aT c #cacaca",
-"aW c #cbcbcb",
-"aX c #cccccc",
-"a1 c #cdcdcd",
-"aY c #cecece",
-"aS c #cfcfcf",
-"a0 c #d0d0d0",
-"a4 c #d1d1d1",
-"a2 c #d2d2d2",
-"a3 c #d3d3d3",
-"a5 c #d4d4d4",
-"a7 c #d5d5d5",
-"a6 c #d6d6d6",
-"a8 c #d7d7d7",
-"a9 c #d8d8d8",
-"bb c #d9d9d9",
-"b. c #dadada",
-"bc c #dbdbdb",
-"b# c #dcdcdc",
-"ba c #dddddd",
-"bd c #dedede",
-"be c #dfdfdf",
-"bf c #e0e0e0",
-"bg c #e1e1e1",
-"bh c #e2e2e2",
-"Qt.#.a.b.c.b.a.dQt.a.eQtQtQt.a.a.e.f.f.g.b.bQt.b.b.a.d.#.e.d.e.#.d.eQt.f.d.a.a.e.a.#QtQtQt.bQtQt.d.#",
-"Qt.eQt.a.aQtQt.a.#QtQt.#.d.e.#.#.b.h.i.j.j.k.j.l.l.m.m.l.n.n.e.e.#.a.a.e.e.a.e.e.a.bQt.e.a.a.d.a.f.e",
-".a.#.aQt.aQtQt.aQtQt.e.e.d.e.o.p.l.l.q.r.k.j.o.j.j.q.s.t.u.v.m.q.p.d.f.#.a.aQt.dQt.a.aQtQt.e.e.d.f.d",
-".a.a.e.a.e.#Qt.a.a.a.a.h.q.s.s.w.m.l.v.q.w.t.t.u.m.q.l.q.u.x.x.u.y.i.e.z.f.a.#.e.aQtQt.e.a.e.a.#.A.A",
-".eQt.#.a.e.a.e.a.e.e.j.t.m.v.y.B.C.C.m.q.q.v.C.s.m.B.w.x.D.E.E.F.F.D.v.h.d.f.d.a.#QtQtQtQt.e.a.a.d.#",
-".AQt.e.aQt.e.e.d.e.w.F.D.s.C.s.C.B.w.w.l.l.q.r.j.l.q.v.s.x.G.H.I.H.G.u.w.h.a.#.e.#.e.eQtQt.aQt.a.f.f",
-".e.a.e.a.a.e.e.e.v.E.x.u.x.C.s.s.y.m.j.w.v.B.j.j.i.l.q.q.s.F.H.J.K.E.D.v.k.k.a.d.e.d.f.e.bQt.e.a.#.e",
-".e.#.a.e.e.#.A.r.t.x.y.t.u.B.w.C.x.B.v.l.B.B.m.v.w.w.m.v.t.E.H.K.D.G.F.u.m.l.q.#.d.#.e.a.a.e.a.#.#.a",
-".a.e.#.#.#.f.f.m.v.v.t.u.m.B.t.s.t.x.u.B.B.v.u.y.u.C.D.x.E.D.x.F.F.x.s.s.m.C.s.C.b.#.e.e.#.#.e.#.#.a",
-".a.#.f.#.f.z.r.w.m.s.x.y.m.C.s.u.D.D.u.v.C.y.t.s.u.m.B.y.m.t.x.G.D.t.y.k.q.B.C.u.u.b.f.aQt.#.A.A.a.e",
-".#.a.a.A.#.a.v.y.s.u.y.w.B.B.y.t.y.y.l.w.w.m.s.q.l.j.r.j.v.t.D.F.F.v.m.w.w.m.m.s.u.k.e.a.e.#.f.d.e.d",
-".A.f.d.#.f.c.y.v.u.D.x.v.u.y.v.y.w.lQt.p.i.c.r.c.A.L.M.a.k.w.C.D.F.x.u.m.w.B.m.C.G.q.N.e.a.#.a.f.#.f",
-".a.g.d.d.a.o.m.v.t.D.x.s.s.B.l.rQtQt.f.d.O.P.Q.R.S.T.T.U.R.O.b.v.x.y.C.s.B.k.v.C.m.C.e.#.a.A.e.d.f.e",
-".d.#.#.#.e.B.s.v.x.t.m.m.oQt.A.V.Q.W.X.Y.Z.0.0.1.2.3.4.0.5.6.U.e.B.v.s.w.w.m.y.t.y.v.l.#.d.e.#.d.#.a",
-".e.e.g.g.n.s.s.u.u.v.l.e.7.8.9.Z.1#..2###a#b#c#d#e#f#g#h#i#j.4.T.c.B.w.l.r.B.s.u.x.y.p.e.A.f.A.a.d.e",
-".d.#.a.#.k.C.y.y.B.v.h.X#k#l#m#h#n#o#p#q#r#s#t#u#v#r#v#w#x#h#y.0.g.r.N.f.r.j.s.t.D.G.q.d.e.#.A.g.e.d",
-".a.e.#.d.j.m.s.C.C.m.A.0#z#A#g#B#d#p#u#s#C#C#D#E#F#G#H#C#t#I.Z.S#J#K#L.7.p.v.x.G.G.F.v.f.d.AQt.#.f.e",
-".e.#.d.d.p.C.C.y.s.l.P#M#z###n#f#N#u#O#P#Q#R#S#S#T#U#U#V#G#F#v#B#l#l#z#W.Q.s.F.E.E.E.s.g.f.d.#.#.d.A",
-".e.d.d.#.r.y.y.C.B.f.8#.#A#n#b#e#v#F#Q#X#Y#Z#0#U#Z#1#2#U#Y#U#G#q#3#f#a#4.2.b.u.t.x.G.t.f.d.A.#.e.d.#",
-".#.#.e.d.b.y.u.s.q.N#K#W#5#6#w#p#t#P#U#2#7#8#9a.a#aaaa#7a##1ab#Hacad#w#a#5#L.e.w.t.G.y.g.A.f.a.d.e.a",
-"Qt.f.d.A.d.m.y.C.k.Oae#k#x#b#e#p#E#S#0#2a.afag#8aaaf#9#8#9#7#U#F#rac#3#cah#W.P.p.y.F.C.A.f.A.z.fQt.d",
-".e.g.#.e.A.r.y.B.k.N#Lai#g#b#N#q#H#X#1a##8agaj#9#9afajafaf#1#U#P#r#v#e#oak.3.7.n.y.x.B.g.#.d.d.A.e.d",
-".f.e.#.a.gQt.B.m.j.Lalam#x#d#v#F#S#Ua##9af#9an#9#9afafaj#9a##2#X#E#uao#d#n#lap.e.C.t.i.f.g.g.#.d.#.d",
-".#.d.e.d.g.e.m.v.kaq#har#B#eas#V#1#8anatanauatatatanagatavawataaab#F#v#3#n#i.Z.p.q.v.c.z.g.f.A.f.#.d",
-".d.d.e.d.d.A.B.q.eal#i#i#xakao#P#0#8auauavavawaxaxayavataxaxana##Z#H#eaz#n#AaA.h.w.l.N.z.f.f.e.A.#.#",
-".f.g.z.N.g.N.k.k.W#z#z#WaBaAaiarao#P#X#0aaagavawayavaj#T#G#Had#d#o#4am.2.2#l#I.N.l.p.g.A.g.f.#.d.A.#",
-".A.g.A.A.A.N.a.r.9#5aCaD#MalaD.X.Sap.6.3#b#O#7aganav#2#v#v#c.Z.U.Sae#j#5#IaE#j.7.l.n.g.g.A.A.e.f.f.f",
-".z.A.f.A.N.L.A.r#L##amam#5#Bah#AaiaAaF.0#.#b#Q#Yaa#8#P#f#o###lai#m#h#B#N#w###haE.k.d.f.N.z.f.f.d.d.f",
-".L.g.A.zaGaD.U.haH#5ah#6#4ai.4.ZaG#M#e#o#5ah#t#Zaf#1#U#s#a#4#w#x#h#z#h#a#v#e#4#..o.L.L.L.g.f.A.A.a.d",
-".z.A.g.g.X#A#l.aaE#4#6azaC.9ac#M.7#m#9ac#v#4#3#Zawat#S#N#b#eakaG.Q#x#W#k#fao#a#k.f.P.N.g.A.g.d.d.d.f",
-".z.M.z.NaD#I#f.RaAak#o#Bar#h#t#r#k#DaIab#p#v#f#Rataf#H#p#v#Q#S.RaJ#Q#r.1#5#3#f.3.9##ap.z.f.z.f.f.#.f",
-".L.M.L.O#m#A#o.9#y#B#w#e#bah#6ao#sas#D#OaK#v#e#G#2#2#D#u#N#D#Y#s#s#V#3#nadad#c#y#.#Bai.g.A.A.g.d.e.#",
-".N.L.OaLai###daH#i#a#w#pao#3ad#p#q#v#u#P#Oaoac#F#U#U#H#s#Q#C#vao#p#e#p#p#q#p#c#z#A#i#b.N.f.g.f.d.d.#",
-".L.L.V.V.1#B#b#oah#aad#t#FaK#O#EaK#S#Zab#E#t#u#O#Z#Z#P#G#R#V#Oasas#D#O#O#H#v#c###cak#B.O.A.#.g.g.f.g",
-".M.M.L.M.6#b#fac#4azad#Hab#Y#Y#X#Z#1#2#U#H#t#t#Sa##7#Sabab#1aM#Yabab#Y#U#Vas#dah#c#e#i.L.A.d.d.d.f.f",
-".O.V.M.Oaq#a#wak#4az#N#P#2#7a.#7a.#8#8aM#P#u#s#U#9a#ab#V#Za##8a.#1#Y#Y#0#Z#Padaz#e#eaB.z.z.z.g.d.d.d",
-".O.M.VaL.W#gao#qak#bad#O#2#9afafafauauaMasao#F#2af#8#0#Q#Y#9atan#8a.#7#7#7#Pacaz#Nad.Z.L.z.d.A.g.A.z",
-".V.Q.OaL.R.2#o#H#d#6adasabaaagauatayaj#Tadao#SajaNau#Y#O#OagaNawanatafaa#2#R#v#v#E#d.U.L.A.z.NaL.Q.L",
-".O.OaL.O#J.Y#oac#b#n#N#s#R#7#9anayaxaa#F#r#D#0aOaPaN#1#Y#GaMayaOaIayag#7#0#Pao#t#qam.O.M.N.g.z.g.z.z",
-".V.V.OaL.R.W#5ac#q#nad#t#G#Z#9ajatan#7#OaKaK#H#8an#7aba##T#YauawaQaxaja.#X#F#eaoao.5.z.z.g.g.L.N.L.g",
-"aL.O.QaL.Q.P.X#z.2#5#3#q#Daba#aganatag#0#Dar#b#D#H#F#x#t#VagatanayavagaM#R#u#c#Had.7.O.g.N.z.z.g.z.N",
-".M.VaLaq.W.R.U.W.U.2#f#pas#Q#1#9ajagaf#8#2ab#G#S#SaM#X#0auavaxauafafaa#XaK#v#5#Map.V.M.M.z.g.z.M.g.M",
-".M.V.S.QaL#J.R.PaJ.1#a#N#s#O#Y#0aa#8a##1#U#V#0aaa.#8#7aM#9anatagaa#8#1#R#sad.3aGaL.O.V.L.N.N.V.L.N.N",
-".V.OaGaG#JaGaG.P.S.6azad#u#D#T#XaM#2#U#V#Vab#UaM#Z#2#7#7#7afag#9#1aM#X#G#r#f.0.R.O.OaL.M.V.M.L.N.N.M",
-".M.V.QaG.PaG.R.P.U.X#x#3#uas#G#G#U#Z#X#G#tac#r#F#R#H#E#S#2#0aM#2#0#T#T#O#vaz.X.Q.O.O.V.M.L.L.V.L.N.L",
-".OaLaG.QaG#J.Q.P.R.U#y#cac#t#O#Oab#X#q#Aarah#b#w#N#b#bak#6#d#F#1#Y#S#S#Fadar.WaGaL.N.VaL.M.V.V.O.V.M",
-".MaL.Q.OaG#J#J.WaJ.W#L#B#e#v#C#G#X#Z#X#p#oaoaK#R#Q#T#G#s#N#q#RaM#Z#V#Ras#w#.#J.QaLaLaLaL.O.N.LaL.O.V",
-".VaL.QaG.R.Q.P.R.RaJ.7#A#cad#t#H#T#Y#1ab#F#t#DaK#P#R#P#H#Q#2a##7#U#Q#H#r#B.7aG.O.O.O.V.V.O.M.OaG.O.N",
-"aG.Q#JaG.Q.R.R.P.W.W.U.2az#dao#u#F#S#Z#V#VaK#C#u#q#u#G#Y#1#8a.aM#T#H#Cad#k.P.R#J.Q.V.V.V.O.V.O.V.M.z",
-".O.OaGaGaGaG.R#J.W.W.UaE#n#6#f#pas#P#Sab#Y#1#2#0#Z#X#0a.a.#7#0#X#G#C#q#o.8#J.PaG.O#JaL.MaL.O.O.O.M.g",
-"aL#J.RaG#J.R.P.R.PaJ.T#caz#naz#d#N#CaK#Z#8anajagauanavan#9#2#0#S#D#v#w#B#A.T.RaL.R.Q.Q.MaL.O.L.V.N.V",
-"aL#JaG.QaG.P.W.P.P.Wai#G#Baz#n#n#bao#D#X#7ajagafanananau#9#2#V#H#p#f#f#g.2#z#J#J.QaGaL.O.Q.M.L.M.M.L",
-".Q#J#J.W#J.W.P.P.U.Yas#tar#baz#g#4#aad#E#P#0#1#2a#af#8#1#2#T#D#e#B#f#d#i.SazaE#J.O.O.QaL.O.O.V.Q.M.V",
-".R.W#J.U.S.9aE#z#w#Ga##3aC#b#o#B#g##akad#r#DaK#HaKab#X#R#E#r#o#n#c#Nadam.SaB#w.UaGaG.O.QaL.V.VaL.O.V",
-"aq#j#d#s#Q#0#2#2#Za.#9aoaB#6#3#w#B#g###4#6#a#f#cao#v#v#p#w#o#b#w#q#uadaE.Oaq#Q.5.RaLaLaLaL.O.O.Q.VaL",
-"aaaRaOaNavaj#2#0a.#9au#Eaq#6#3#N#e#aaz#6#f#w#3#f#N#p#N#e#N#e#N#t#E#C#NaA.n.Tab#D#k.XaJ.R.QaL.Q.Q.QaL",
-"aSaTaOaIaNav#1#0afataI#2.T#6#N#r#sac#w#c#w#p#E#X#Z#Qas#qaoac#C#G#F#Cao#h.hae#2aQavaM#c.Z#JaL.Q.Q.Q.O",
-"aTaUaVaOaIay#9#9ajaQaUaQaA#4#q#D#F#E#u#taoao#v#F#P#Has#t#s#F#P#R#P#Cac#g.NaCauaRawaNaQaj#vaAaJ#J.R.V",
-"aWaTaNawaOavagauavaRaXaYacai#v#H#P#G#C#C#Oasacac#u#D#F#G#P#P#Vab#S#E#q#6aL#oaVaZaVaVaUaWaRat#V#o#k#K",
-"aSaUavaQaOa#auataIaTaSaSataCao#F#S#S#R#FaK#P#O#F#P#T#T#R#Rab#Z#X#Q#Dasak.S#YaXaPaVaQaPaYaWaRaIaOaQaf",
-"aSaOayaUag#7axaNaRaXa0a0aP#3az#D#Tab#VaK#T#S#Tab#U#Z#0#Y#Y#2#0#X#P#E#Dam#WataYaTaZaVaRa1a0aWaWa2a3a0",
-"aYawaNaT#0a#aIaQaPaYa4a4aSag#h#s#R#X#X#V#S#V#X#2#1a.#1#0#2#1aM#T#G#O#saB#CaPa4aPaUaUaPaSaYa4aSaSaXaP",
-"a1aNaIaTabajaQaOaPa1a0a5a3aT#fadaK#Z#Y#Xab#V#XaM#2#2aMaM#2#2ab#P#P#R#w.3ayaSa4a1aXa1aYa5aYa2a4aXaRaR",
-"aYaIaRaX#YaxaQaOaTaSa3a6a3aSa.#g#Cab#Y#Y#X#T#Tab#U#Y#Z#Z#0#Y#S#Qab#R#j#saWa3a3a0a0a3a4a5a2a2aSaUaRaR",
-"a0aQaTaX#1aQaOaRaWa3a7a6a7a4aT#aao#R#ZaM#Z#U#Vab#U#YaM#2#0#T#Q#X#2#q.2aya0a5a2a4a2a5a7a2a2a6a4a1a0a3",
-"aYaVaYaPanaVaVaZa1a3a6a7a8a5a4#0#d#F#0aa#8#7#Y#XaM#0#0aMaM#Z#0aa#ZaraoaXa7a8a2a3a5a7a7a3a2a8a5a7a9b.",
-"a1aRa0aQaNaZaRaPa1a2aS#8asaVa6aT#t#D#U#9aj#9a.#1aM#7#7aaaaa.afau#s#gaya2a8a9a2a3a6a8a6a5a7a9a6a9b#ba",
-"aTaRa1aIaOaVaUaPaW#9acaCal#Za2a4#9#C#0aaauajafafafafafajagagan#1#w#2a1a3a9a8a2a3a8bbbba8a7a8a9bcbab#",
-"aUaWaTaRaOaOaZaVa#aK#E#H#va#aSaXaUa.#Yaganavatanavavayavanat#9aKaMaZa4a6a9a9a3a5a6a9b.b.a3a8b.b.bdbc",
-"aWaXaPaTaRayaI#1aMaaagaN#2a#aTa0aWaR#1ataNawawaNaIawaIaIawaj#YaxaOa0a4a7a9a6a2a7a6bbbcbca7bbbcb#bab.",
-"aXaPaWaWaUaPanaaaNaWaTaWaRagaIaXa0aXaIajaNaQaOaVaVaQaQaOaN#1aUaUaXaWa0bba9a5a4a5a8b.bcb#a8b#bcbab#bc",
-"aXaXaYaSaXaUaQaUa2a8a2aSa2aYaTaWaIaVaWaNajawaNaIaIaNaNaw#7aNaSaTaSaVa7a9#PaVa0a3a6bbb.b#bbbcb#b#b#bc",
-"a4a0a3aSaXa2a5a6a9a9a7a0a5bba6a5aSayata1anagavawaxaway#Yaua1aSaWa4a7a9a1araraVa3a7bbbcb#bcb.b#b#bcb#",
-"a6a6a8a8a9b#bcb.bcb.a8a2a4a9bbbbbbaYaQaUaW#9aaanatay#Y#ZaSa1a4a2a2a6a9aS#7ak#baPa7b.bcb.b#a9bcbab#b#",
-"a8a8bbbcb#babdb#bcbca9a7a0a5b.b.bcb.a7aYaWaR#2a.af#1#FaVa5a6a6a4a8b.a9a6a3aN#G#SaXa8bba8b.a9bbbdbaba",
-"bbbbb.bcbabdbdb#b#b#b.a8a4a3bcbcb#babaa9a5a1at#Z#Z#tafa0a9bba7a5a8a8a9bbbcbca5aN#9a1a9a6a9bbb.bdb#ba",
-"b.bbbcb#babdbabababab#bba5a5a8b#b#b#bdb#bbaSaSab#o#FaYa3a7a7a5a5a6bbb#babebdbdbaa7aPaPa6b.bbbbbdb#b#",
-"bcbcbcb#b#bdbdbababdb#bca8a7a5bbbab.b#b#baa6aYaM.3ayaSa0a0a4a7a9bcb#bdbebebebfbebfbea8aWa5b.a9babab#",
-"b#bcb.bcbabababababab#b#bba6a5a8bcbabcb#bdbda5ay#FaWa4a1a0a8bcbabdbfbfbgbfbebgbfbgbebfbda4a7b.babebc",
-"b#b#bcbcb#babdb#b#bababcbba8a6a6bbb#b#bcb#b#aSaQaPa7a7aSa8b#bebebfbebfbgbfbgbfbgbfbgbfbfbababebfbebc",
-"babab#babcbababababab#b#b.a9a8a6b.bcb#bcbca2ajaTa6a9bba6bcbebdbebfbfbfbhbgbhbfbfbgbgbgbgbebdbfbfbdb#"
-]
-image1_data = \
- "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
- "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
- "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
- "\x99\x49\x44\x41\x54\x38\x8d\xed\x94\x41\x0e\x85" \
- "\x20\x0c\x44\x5f\x89\xc7\x36\x7f\x61\xbc\x77\x5d" \
- "\x28\x48\xa4\x28\x60\xff\xce\xd9\x54\x8b\xbe\x8e" \
- "\x13\x04\x3e\x1d\x92\x81\x77\xf4\x81\xa1\x23\xdc" \
- "\x2b\x34\xf6\xf4\x7a\x3d\xe2\xb8\x65\xa8\x84\x3f" \
- "\x40\x01\x98\x2a\x0b\x3d\x5f\x62\xc5\x83\x00\xaa" \
- "\x1a\xd7\x05\x50\x44\x9a\xb9\xd5\x07\xa7\x73\xa8" \
- "\xa4\xba\x4f\x92\xa2\xdf\x33\x3c\x64\xc6\x3b\xeb" \
- "\xbd\x82\xe5\xb8\xad\xde\xcb\xcc\x78\x20\xeb\x42" \
- "\x66\xc6\x39\x74\x5d\xfa\x80\xf3\x6f\xaf\x66\xc6" \
- "\x6f\xa1\x9c\x3f\x88\x2f\xb4\x70\xec\x05\xcd\xc0" \
- "\xbe\xd0\x78\x93\xf6\x8e\x17\x14\x92\x63\x5f\x68" \
- "\x6c\x3e\xef\xf6\xba\x3c\x8f\xdd\x36\x6d\xc4\xc0" \
- "\x45\x2c\x87\x81\xf8\x08\x00\x00\x00\x00\x49\x45" \
- "\x4e\x44\xae\x42\x60\x82"
-
-class pyptofflineguiForm(QMainWindow):
- def __init__(self,parent = None,name = None,fl = 0):
- QMainWindow.__init__(self,parent,name,fl)
- self.statusBar()
-
- self.image1 = QPixmap()
- self.image1.loadFromData(image1_data,"PNG")
- self.image0 = QPixmap(image0_data)
-
- if not name:
- self.setName("pyptofflineguiForm")
-
- self.setUsesTextLabel(1)
-
- self.setCentralWidget(QWidget(self,"qt_central_widget"))
-
- self.pyptTabWidget = QTabWidget(self.centralWidget(),"pyptTabWidget")
- self.pyptTabWidget.setGeometry(QRect(10,0,580,430))
-
- self.tab = QWidget(self.pyptTabWidget,"tab")
-
- self.pixmapLabel1 = QLabel(self.tab,"pixmapLabel1")
- self.pixmapLabel1.setGeometry(QRect(230,80,120,150))
- self.pixmapLabel1.setPixmap(self.image0)
- self.pixmapLabel1.setScaledContents(1)
-
- self.textLabel1 = QLabel(self.tab,"textLabel1")
- self.textLabel1.setGeometry(QRect(98,264,381,111))
- textLabel1_font = QFont(self.textLabel1.font())
- textLabel1_font.setPointSize(48)
- self.textLabel1.setFont(textLabel1_font)
- self.pyptTabWidget.insertTab(self.tab,QString.fromLatin1(""))
-
- self.tab_2 = QWidget(self.pyptTabWidget,"tab_2")
-
- LayoutWidget = QWidget(self.tab_2,"layout20")
- LayoutWidget.setGeometry(QRect(10,30,380,210))
- layout20 = QGridLayout(LayoutWidget,1,1,11,6,"layout20")
-
- self.setInstallPackageTextLabel = QLabel(LayoutWidget,"setInstallPackageTextLabel")
-
- layout20.addWidget(self.setInstallPackageTextLabel,2,0)
-
- self.setUpgradeTypeComboBox = QComboBox(0,LayoutWidget,"setUpgradeTypeComboBox")
-
- layout20.addWidget(self.setUpgradeTypeComboBox,1,1)
-
- self.setFilePathLineEdit = QLineEdit(LayoutWidget,"setFilePathLineEdit")
- self.setFilePathLineEdit.setPaletteBackgroundColor(QColor(255,255,127))
- self.setFilePathLineEdit.setAlignment(QLineEdit.AlignAuto)
-
- layout20.addWidget(self.setFilePathLineEdit,3,1)
-
- self.pushButton6 = QPushButton(LayoutWidget,"pushButton6")
-
- layout20.addWidget(self.pushButton6,3,2)
-
- self.setUpgradeTypeTextLabel = QLabel(LayoutWidget,"setUpgradeTypeTextLabel")
-
- layout20.addWidget(self.setUpgradeTypeTextLabel,1,0)
-
- self.setInstallationTypeTextLabel = QLabel(LayoutWidget,"setInstallationTypeTextLabel")
-
- layout20.addWidget(self.setInstallationTypeTextLabel,0,0)
-
- self.setFilePathTextLabel = QLabel(LayoutWidget,"setFilePathTextLabel")
-
- layout20.addWidget(self.setFilePathTextLabel,3,0)
-
- self.setInstallationTypeComboBox = QComboBox(0,LayoutWidget,"setInstallationTypeComboBox")
-
- layout20.addWidget(self.setInstallationTypeComboBox,0,1)
-
- self.setInstallPackagesLineEdit = QLineEdit(LayoutWidget,"setInstallPackagesLineEdit")
- self.setInstallPackagesLineEdit.setPaletteBackgroundColor(QColor(255,255,127))
- setInstallPackagesLineEdit_font = QFont(self.setInstallPackagesLineEdit.font())
- setInstallPackagesLineEdit_font.setBold(1)
- self.setInstallPackagesLineEdit.setFont(setInstallPackagesLineEdit_font)
- self.setInstallPackagesLineEdit.setAlignment(QLineEdit.AlignAuto)
-
- layout20.addWidget(self.setInstallPackagesLineEdit,2,1)
-
- self.pushButton5 = QPushButton(self.tab_2,"pushButton5")
- self.pushButton5.setGeometry(QRect(440,340,100,20))
- self.pyptTabWidget.insertTab(self.tab_2,QString.fromLatin1(""))
-
- self.TabPage = QWidget(self.pyptTabWidget,"TabPage")
-
- LayoutWidget_2 = QWidget(self.TabPage,"layout22")
- LayoutWidget_2.setGeometry(QRect(18,30,340,130))
- layout22 = QGridLayout(LayoutWidget_2,1,1,11,6,"layout22")
-
- self.fetchUpdateDataRadioButton = QRadioButton(LayoutWidget_2,"fetchUpdateDataRadioButton")
-
- layout22.addWidget(self.fetchUpdateDataRadioButton,0,0)
-
- self.fetchUpgradeDataRadioButton = QRadioButton(LayoutWidget_2,"fetchUpgradeDataRadioButton")
-
- layout22.addWidget(self.fetchUpgradeDataRadioButton,1,0)
-
- self.fetchBrowseLineEdit = QLineEdit(LayoutWidget_2,"fetchBrowseLineEdit")
- self.fetchBrowseLineEdit.setPaletteBackgroundColor(QColor(255,255,127))
-
- layout22.addWidget(self.fetchBrowseLineEdit,2,0)
-
- self.fetchBrowsePushButton = QPushButton(LayoutWidget_2,"fetchBrowsePushButton")
-
- layout22.addWidget(self.fetchBrowsePushButton,2,1)
-
- self.fetchConsoleOutputTextLabel = QLabel(self.TabPage,"fetchConsoleOutputTextLabel")
- self.fetchConsoleOutputTextLabel.setGeometry(QRect(20,160,141,20))
-
- self.fetchStartButton = QPushButton(self.TabPage,"fetchStartButton")
- self.fetchStartButton.setGeometry(QRect(440,340,100,20))
-
- self.fetchTextBrowser = QTextBrowser(self.TabPage,"fetchTextBrowser")
- self.fetchTextBrowser.setGeometry(QRect(20,181,340,160))
-
- self.fetchProgressBar = QProgressBar(self.TabPage,"fetchProgressBar")
- self.fetchProgressBar.setGeometry(QRect(20,350,340,20))
-
- self.fetchOptionsButtonGroup = QButtonGroup(self.TabPage,"fetchOptionsButtonGroup")
- self.fetchOptionsButtonGroup.setGeometry(QRect(380,20,190,250))
-
- self.fetchZipCheckBox = QCheckBox(self.fetchOptionsButtonGroup,"fetchZipCheckBox")
- self.fetchZipCheckBox.setGeometry(QRect(8,23,91,20))
- self.fetchZipCheckBox.setChecked(1)
-
- self.fetchTargetDownloadFolderCheckbox = QCheckBox(self.fetchOptionsButtonGroup,"fetchTargetDownloadFolderCheckbox")
- self.fetchTargetDownloadFolderCheckbox.setGeometry(QRect(8,71,130,21))
-
- self.lineEdit7 = QLineEdit(self.fetchOptionsButtonGroup,"lineEdit7")
- self.lineEdit7.setGeometry(QRect(8,44,141,21))
- self.lineEdit7.setPaletteBackgroundColor(QColor(255,255,127))
-
- self.fetchTargetDownloadFolderPushButton = QPushButton(self.fetchOptionsButtonGroup,"fetchTargetDownloadFolderPushButton")
- self.fetchTargetDownloadFolderPushButton.setGeometry(QRect(150,94,30,21))
-
- self.fetchZipPushButton = QPushButton(self.fetchOptionsButtonGroup,"fetchZipPushButton")
- self.fetchZipPushButton.setGeometry(QRect(150,44,30,20))
-
- self.fetchCacheDirectoryCheckBox = QCheckBox(self.fetchOptionsButtonGroup,"fetchCacheDirectoryCheckBox")
- self.fetchCacheDirectoryCheckBox.setGeometry(QRect(8,119,100,21))
-
- self.fetchDisableMD5ChecksumCheckBox = QCheckBox(self.fetchOptionsButtonGroup,"fetchDisableMD5ChecksumCheckBox")
- self.fetchDisableMD5ChecksumCheckBox.setGeometry(QRect(8,174,130,21))
-
- self.fetchThreadsTextLabel = QLabel(self.fetchOptionsButtonGroup,"fetchThreadsTextLabel")
- self.fetchThreadsTextLabel.setGeometry(QRect(10,200,121,21))
-
- self.fetchThreadsSpinBox = QSpinBox(self.fetchOptionsButtonGroup,"fetchThreadsSpinBox")
- self.fetchThreadsSpinBox.setGeometry(QRect(10,223,131,21))
- self.fetchThreadsSpinBox.setMaxValue(5)
- self.fetchThreadsSpinBox.setMinValue(1)
-
- self.fetchCacheDirectoryLineEdit = QLineEdit(self.fetchOptionsButtonGroup,"fetchCacheDirectoryLineEdit")
- self.fetchCacheDirectoryLineEdit.setGeometry(QRect(10,140,140,21))
- self.fetchCacheDirectoryLineEdit.setPaletteBackgroundColor(QColor(255,255,127))
-
- self.fetchTargetDownloadFolderLineEdit = QLineEdit(self.fetchOptionsButtonGroup,"fetchTargetDownloadFolderLineEdit")
- self.fetchTargetDownloadFolderLineEdit.setGeometry(QRect(8,94,140,21))
- self.fetchTargetDownloadFolderLineEdit.setPaletteBackgroundColor(QColor(255,255,127))
-
- self.fetchCacheDirectoryPushButton = QPushButton(self.fetchOptionsButtonGroup,"fetchCacheDirectoryPushButton")
- self.fetchCacheDirectoryPushButton.setGeometry(QRect(151,140,30,21))
- self.pyptTabWidget.insertTab(self.TabPage,QString.fromLatin1(""))
-
- self.TabPage_2 = QWidget(self.pyptTabWidget,"TabPage_2")
-
- self.installTextBrowser = QTextBrowser(self.TabPage_2,"installTextBrowser")
- self.installTextBrowser.setGeometry(QRect(28,184,331,201))
-
- LayoutWidget_3 = QWidget(self.TabPage_2,"layout24")
- LayoutWidget_3.setGeometry(QRect(30,20,330,130))
- layout24 = QGridLayout(LayoutWidget_3,1,1,11,6,"layout24")
-
- self.installUpdateDataRadioButton = QRadioButton(LayoutWidget_3,"installUpdateDataRadioButton")
-
- layout24.addWidget(self.installUpdateDataRadioButton,0,0)
-
- self.installUpgradeDataRadioButton = QRadioButton(LayoutWidget_3,"installUpgradeDataRadioButton")
-
- layout24.addWidget(self.installUpgradeDataRadioButton,1,0)
-
- self.instalBrowsePushButton = QPushButton(LayoutWidget_3,"instalBrowsePushButton")
-
- layout24.addWidget(self.instalBrowsePushButton,2,1)
-
- self.installLineEdit = QLineEdit(LayoutWidget_3,"installLineEdit")
-
- layout24.addWidget(self.installLineEdit,2,0)
-
- self.textLabel7 = QLabel(self.TabPage_2,"textLabel7")
- self.textLabel7.setGeometry(QRect(30,150,171,31))
-
- self.installStartPushButton = QPushButton(self.TabPage_2,"installStartPushButton")
- self.installStartPushButton.setGeometry(QRect(440,340,100,20))
- self.pyptTabWidget.insertTab(self.TabPage_2,QString.fromLatin1(""))
-
- self.fileOpenAction = QAction(self,"fileOpenAction")
- self.fileOpenAction.setIconSet(QIconSet(self.image1))
- self.fileExitAction = QAction(self,"fileExitAction")
- self.helpContentsAction = QAction(self,"helpContentsAction")
- self.helpAboutAction = QAction(self,"helpAboutAction")
-
-
-
-
- self.MenuBar = QMenuBar(self,"MenuBar")
-
-
- self.fileMenu = QPopupMenu(self)
- self.fileOpenAction.addTo(self.fileMenu)
- self.fileMenu.insertSeparator()
- self.fileMenu.insertSeparator()
- self.fileExitAction.addTo(self.fileMenu)
- self.MenuBar.insertItem(QString(""),self.fileMenu,1)
-
- self.helpMenu = QPopupMenu(self)
- self.helpContentsAction.addTo(self.helpMenu)
- self.helpMenu.insertSeparator()
- self.helpAboutAction.addTo(self.helpMenu)
- self.MenuBar.insertItem(QString(""),self.helpMenu,2)
-
-
- self.languageChange()
-
- self.resize(QSize(618,480).expandedTo(self.minimumSizeHint()))
- self.clearWState(Qt.WState_Polished)
-
- self.connect(self.fileOpenAction,SIGNAL("activated()"),self.fileOpen)
- self.connect(self.fileExitAction,SIGNAL("activated()"),self.close)
- self.connect(self.helpContentsAction,SIGNAL("activated()"),self.helpContents)
- self.connect(self.helpAboutAction,SIGNAL("activated()"),self.helpAbout)
-
- self.setInstallPackageTextLabel.setBuddy(self.setInstallPackagesLineEdit)
- self.setUpgradeTypeTextLabel.setBuddy(self.setUpgradeTypeComboBox)
- self.setFilePathTextLabel.setBuddy(self.setFilePathLineEdit)
-
-
- def languageChange(self):
- self.setCaption(self.__tr("pypt-offline | Offline Package Manager | (C) Ritesh Raj Sarraf - RESEARCHUT"))
- self.textLabel1.setText(self.__tr("<p align=\"center\">pypt-offline</p>"))
- self.pyptTabWidget.changeTab(self.tab,self.__tr("Welcome"))
- self.setInstallPackageTextLabel.setText(self.__tr("Install Packages"))
- self.setUpgradeTypeComboBox.clear()
- self.setUpgradeTypeComboBox.insertItem(QString.null)
- self.setUpgradeTypeComboBox.insertItem(self.__tr("upgrade"))
- self.setUpgradeTypeComboBox.insertItem(self.__tr("dist-upgrade"))
- self.setUpgradeTypeComboBox.insertItem(self.__tr("dselect-upgrade"))
- self.pushButton6.setText(self.__tr("Browse"))
- self.setUpgradeTypeTextLabel.setText(self.__tr("Upgrade Type"))
- self.setInstallationTypeTextLabel.setText(self.__tr("Installation Type"))
- self.setFilePathTextLabel.setText(self.__tr("File Path"))
- self.setInstallationTypeComboBox.clear()
- self.setInstallationTypeComboBox.insertItem(QString.null)
- self.setInstallationTypeComboBox.insertItem(self.__tr("Update"))
- self.setInstallationTypeComboBox.insertItem(self.__tr("Upgrade"))
- self.setInstallationTypeComboBox.insertItem(self.__tr("Install"))
- self.pushButton5.setText(self.__tr("Start"))
- self.pushButton5.setAccel(QKeySequence(QString.null))
- self.pyptTabWidget.changeTab(self.tab_2,self.__tr("Set"))
- self.fetchUpdateDataRadioButton.setText(self.__tr("Update Data"))
- self.fetchUpgradeDataRadioButton.setText(self.__tr("Upgrade Data"))
- self.fetchBrowsePushButton.setText(self.__tr("Browse"))
- self.fetchConsoleOutputTextLabel.setText(self.__tr("Console Output"))
- self.fetchStartButton.setText(self.__tr("Start"))
- self.fetchOptionsButtonGroup.setTitle(self.__tr("Options"))
- self.fetchZipCheckBox.setText(self.__tr("Zip"))
- ...
[truncated message content] |
|
From: <rit...@us...> - 2007-01-15 21:56:25
|
Revision: 120
http://svn.sourceforge.net/pypt-offline/?rev=120&view=rev
Author: riteshsarraf
Date: 2007-01-14 05:12:16 -0800 (Sun, 14 Jan 2007)
Log Message:
-----------
* Merging changes from branch progressbar.
* For now we'll move with a cumulative progressbar.
Modified Paths:
--------------
trunk/pypt_core.py
trunk/pypt_progressbar.py
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-01-14 09:46:02 UTC (rev 119)
+++ trunk/pypt_core.py 2007-01-14 13:12:16 UTC (rev 120)
@@ -1,5 +1,5 @@
import os, shutil, string, sys, urllib2, Queue, threading
-import pypt_progressbar, pypt_md5_check, pypt_variables, pypt_logger, progressbar
+import pypt_progressbar, pypt_md5_check, pypt_variables, pypt_logger, pypt_progressbar
'''This is the core module. It does the main job of downloading packages/update packages,\nfiguring out if the packages are in the local cache, handling exceptions and many more stuff'''
@@ -123,20 +123,17 @@
size = int(headers['Content-Length'])
data = open(file,'wb')
- log.msg("Downloading %s\n" % (file))
- prog = pypt_progressbar.myReportHook(size, number_of_threads)
- #widgets = ['Test: ', progressbar.Percentage(), ' ', progressbar.Bar(marker=progressbar.RotatingMarker()), ' ', progressbar.ETA(), ' ', progressbar.FileTransferSpeed()]
- #widgets = [CrazyFileTransferSpeed(),' <<<', Bar(), '>>> ', Percentage(),' ', ETA()]
- #pbar = progressbar.ProgressBar(widgets=widgets, maxval=size)
- #pbar.start()
+ progbar.addItem(size)
+
+ log.msg("Downloading %s - %d KB\n" % (file, size/1024))
while i < size:
data.write (temp.read(block_size))
+ increment = min(block_size, size - i)
i += block_size
counter += 1
- #pbar.update(i)
- prog.updateAmount(counter * block_size, thread_name)
- #pbar.finish()
- #print "\n"
+ progbar.updateValue(increment)
+ progbar.completed()
+ log.msg("%s\tdone.\n" % (file))
data.close()
temp.close()
@@ -247,7 +244,7 @@
try:
shutil.copy(os.path.join(path, file), dest_dir)
except shutil.Error:
- log.msg("%s available. Skipping Copy!\n\n" % (file, dest_dir))
+ log.verbose("%s already available in dest_dir. Skipping copy!!!\n\n" % (file))
return True
return False
@@ -334,6 +331,10 @@
arg_type - arg_type is basically used to identify wether it's a update download or upgrade download
'''
+ #INFO: For the Progress Bar
+ global progbar
+ progbar = pypt_progressbar.ProgressBar(width = 30)
+
if arg_type == 1:
#INFO: Oh! We're only downloading the update package list database
# Package Update database changes almost daily in Debian.
@@ -380,8 +381,8 @@
else:
#INFO: Thread Support
if pypt_variables.options.num_of_threads > 1:
- log.msg("WARNING: Threads is still in alpha stage. It's better to use just a single thread at the moment.\n")
- log.warn("Threads is still in alpha stage. It's better to use just a single thread at the moment.\n")
+ log.msg("WARNING: Threads is still in alpha stage. It's better to use just a single thread at the moment.\n\n")
+ log.warn("Threads is still in alpha stage. It's better to use just a single thread at the moment.\n\n")
NUMTHREADS = pypt_variables.options.num_of_threads
ziplock = threading.Lock()
@@ -607,7 +608,7 @@
if len(pypt_variables.errlist) == 0:
pass # Don't print if nothing failed.
else:
- log.err("The following files failed to be downloaded.\n")
+ log.err("\n\nThe following files failed to be downloaded.\n")
for error in pypt_variables.errlist:
log.err("%s failed.\n" % (error))
Modified: trunk/pypt_progressbar.py
===================================================================
--- trunk/pypt_progressbar.py 2007-01-14 09:46:02 UTC (rev 119)
+++ trunk/pypt_progressbar.py 2007-01-14 13:12:16 UTC (rev 120)
@@ -1,54 +1,63 @@
-import sys
+# A minor part of this code is taken from Nilton Volpato's progressbar implementation,
+# precisely the terminal width probe code.
+# Rest of the code was mostly from Dennis Lee Beiber
+import signal, sys
+from array import array
-class progressBar:
- def __init__(self, minValue = 0, maxValue = 10, totalWidth = 12, number_of_threads = 1):
- self.progBar = {}
- for thread in range(number_of_threads):
- self.progBar["Thread-" + str(thread+1)] = ""
- #self.progBar = "[]" # This holds the progress bar string
+if sys.platform == "win32":
+ pass
+else:
+ from fcntl import ioctl
+ import termios
+
+
+class ProgressBar(object):
+ def __init__(self, minValue = 0, maxValue = 0, width = None, fd = sys.stderr):
+ #width does NOT include the two places for [] markers
self.min = minValue
self.max = maxValue
- self.span = maxValue - minValue
- self.width = totalWidth
- self.amount = 0 # When amount == max, we are 100% done
- self.updateAmount(0) # Build progress bar string
-
- def updateAmount(self, newAmount = 0, thread_name = "Thread-1"):
- if newAmount < self.min: newAmount = self.min
- if newAmount > self.max: newAmount = self.max
- self.amount = newAmount
-
- # Figure out the new percent done, round to an integer
- diffFromMin = float(self.amount - self.min)
- percentDone = (diffFromMin / float(self.span)) * 100.0
- percentDone = round(percentDone)
- percentDone = int(percentDone)
-
- # Figure out how many hash bars the percentage should be
- allFull = self.width - 2
- numHashes = (percentDone / 100.0) * allFull
- numHashes = int(round(numHashes))
+ self.span = float(self.max - self.min)
+ self.fd = fd
+ self.signal_set = False
+ if width is None:
+ try:
+ self.handle_resize(None, None)
+ signal.signal(signal.SIGWINCH, self.handle_resize)
+ self.signal_set = True
+ except:
+ self.width = 79 #The standard
+ else:
+ self.width = width
+ self.value = self.min
+ self.items = 0 #count of items being tracked
+ self.complete = 0
- for name in self.progBar.keys():
- if name == thread_name:
- self.progBar[name] = "[" + '#'*numHashes + ' '*(allFull-numHashes) + "]"
-
- percentPlace = (len(self.progBar[name]) / 2) - len(str(percentDone))
- percentString = str(percentDone) + "%"
-
- self.progBar[name] = self.progBar[name][0:percentPlace] + percentString + self.progBar[name][percentPlace+len(percentString):] \
- + " " + str(newAmount/1024) + "KB of " + str(self.max/1024) + "KB"
-
- progress = ""
- keys = self.progBar.keys()
- keys.sort()
- for name in keys:
- progress += self.progBar[name] + " "
- #print self.progBar[name],
- #sys.stdout.write(self.progBar[name] + "\t")
- sys.stdout.write(progress + "\r")
- #sys.stdout.write("\r")
+ def handle_resize(self, signum, frame):
+ h,w=array('h', ioctl(self.fd,termios.TIOCGWINSZ,'\0'*8))[:2]
+ self.width = w
+
+ def updateValue(self, newValue):
+ #require caller to supply a value! newValue is the increment from last call
+ self.value = max(self.min, min(self.max, self.value + newValue))
+ self.display()
-def myReportHook(totalSize, number_of_threads):
- prog = progressBar(0,totalSize,50, number_of_threads)
- return prog
\ No newline at end of file
+ def completed(self):
+ self.complete = self.complete + 1
+ if self.signal_set:
+ signal.signal(signal.SIGWINCH, signal.SIG_DFL)
+ self.display()
+
+ def addItem(self, maxValue):
+ self.max = self.max + maxValue
+ self.span = float(self.max - self.min)
+ self.items = self.items + 1
+ self.display()
+
+ def display(self):
+ print "%3s/%3s items: %s\r" % (self.complete, self.items, str(self)),
+
+ def __str__(self):
+ #compute display fraction
+ percentFilled = ((self.value - self.min) / self.span)
+ widthFilled = int(self.width * percentFilled + 0.5)
+ return ("[" + "#"*widthFilled + " "*(self.width - widthFilled) + "]" + " %5.1f%% of %d KB" % (percentFilled * 100.0, self.max/1024))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-01-28 20:16:58
|
Revision: 123
http://svn.sourceforge.net/pypt-offline/?rev=123&view=rev
Author: riteshsarraf
Date: 2007-01-28 12:16:55 -0800 (Sun, 28 Jan 2007)
Log Message:
-----------
* Minor progressbar display changes
Modified Paths:
--------------
trunk/pypt_core.py
trunk/pypt_progressbar.py
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-01-14 13:28:59 UTC (rev 122)
+++ trunk/pypt_core.py 2007-01-28 20:16:55 UTC (rev 123)
@@ -133,7 +133,7 @@
counter += 1
progbar.updateValue(increment)
progbar.completed()
- log.msg("%s\tdone.\n" % (file))
+ log.msg("\r%s %s done.\n" % (file, " "))
data.close()
temp.close()
@@ -812,4 +812,4 @@
except KeyboardInterrupt:
log.err("\nInterrupted by user. Exiting!\n")
- sys.exit(1)
\ No newline at end of file
+ sys.exit(1)
Modified: trunk/pypt_progressbar.py
===================================================================
--- trunk/pypt_progressbar.py 2007-01-14 13:28:59 UTC (rev 122)
+++ trunk/pypt_progressbar.py 2007-01-28 20:16:55 UTC (rev 123)
@@ -54,7 +54,7 @@
self.display()
def display(self):
- print "%3s/%3s items: %s\r" % (self.complete, self.items, str(self)),
+ print "\r%3s/%3s items: %s\r" % (self.complete, self.items, str(self)),
def __str__(self):
#compute display fraction
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-02-11 09:43:21
|
Revision: 126
http://svn.sourceforge.net/pypt-offline/?rev=126&view=rev
Author: riteshsarraf
Date: 2007-02-11 01:43:21 -0800 (Sun, 11 Feb 2007)
Log Message:
-----------
* Move from sys.paltform to platform.system(). The output of sys.platform has not been consistent
It has rather been confusing. IMO, sys.paltform outputs the details on the platform the python interpreter
was built.
Modified Paths:
--------------
trunk/pypt_core.py
trunk/pypt_variables.py
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-02-06 12:25:17 UTC (rev 125)
+++ trunk/pypt_core.py 2007-02-11 09:43:21 UTC (rev 126)
@@ -1,4 +1,4 @@
-import os, shutil, string, sys, urllib2, Queue, threading
+import os, shutil, string, sys, urllib2, Queue, threading, platform
import pypt_progressbar, pypt_md5_check, pypt_variables, pypt_logger, pypt_progressbar
'''This is the core module. It does the main job of downloading packages/update packages,\nfiguring out if the packages are in the local cache, handling exceptions and many more stuff'''
@@ -696,7 +696,7 @@
log.msg("Copyright %s\n" % (pypt_variables.copyright))
if pypt_variables.options.set_update:
- if sys.platform in pypt_variables.supported_platforms:
+ if platform.system() in pypt_variables.supported_platforms:
if os.geteuid() != 0:
pypt_variables.parser.error("This option requires super-user privileges. Execute as root or use sudo/su")
else:
@@ -712,7 +712,7 @@
if not (pypt_variables.options.set_upgrade and pypt_variables.options.upgrade_type):
pypt_variables.parser.error("Options --set-upgrade and --upgrade-type are mutually inclusive\n")
- if sys.platform in pypt_variables.supported_platforms:
+ if platform.system() in pypt_variables.supported_platforms:
if os.geteuid() != 0:
pypt_variables.parser.error("This option requires super-user privileges. Execute as root or use sudo/su")
#TODO: Use a more Pythonic way for it
@@ -741,7 +741,7 @@
if not (pypt_variables.options.set_install_packages and pypt_variables.options.set_install):
pypt_variables.parser.error("Options --set-install and --set-install-package are mutually inclusive\n")
- if sys.platform in pypt_variables.supported_platforms:
+ if platform.system() in pypt_variables.supported_platforms:
if os.geteuid() != 0:
pypt_variables.parser.error("This option requires super-user privileges. Execute as root or use sudo/su")
Modified: trunk/pypt_variables.py
===================================================================
--- trunk/pypt_variables.py 2007-02-06 12:25:17 UTC (rev 125)
+++ trunk/pypt_variables.py 2007-02-11 09:43:21 UTC (rev 126)
@@ -7,7 +7,7 @@
copyright = "(C) 2005 - 2007 Ritesh Raj Sarraf - RESEARCHUT (http://www.researchut.com/)"
errlist = []
-supported_platforms = ["linux2", "gnu0", "gnukfreebsd5"]
+supported_platforms = ["Linux", "GNU/kFreeBSD", "GNU"]
apt_update_target_path = '/var/lib/apt/lists/'
apt_package_target_path = '/var/cache/apt/archives/'
# Dummy paths while testing on Windows
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-03-12 13:45:51
|
Revision: 127
http://svn.sourceforge.net/pypt-offline/?rev=127&view=rev
Author: riteshsarraf
Date: 2007-03-12 06:45:51 -0700 (Mon, 12 Mar 2007)
Log Message:
-----------
* This is again a heavy re-write of the existing code.
* Lot of things are being re-organized.
* fetcher() has been completely re-written.
* Now supports simultaneous downlods of both update/upgrade files
Modified Paths:
--------------
trunk/pypt_core.py
Removed Paths:
-------------
trunk/pypt_logger.py
trunk/pypt_md5_check.py
trunk/pypt_progressbar.py
trunk/pypt_variables.py
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-02-11 09:43:21 UTC (rev 126)
+++ trunk/pypt_core.py 2007-03-12 13:45:51 UTC (rev 127)
@@ -1,111 +1,281 @@
-import os, shutil, string, sys, urllib2, Queue, threading, platform
-import pypt_progressbar, pypt_md5_check, pypt_variables, pypt_logger, pypt_progressbar
+import os
+import sys
+import shutil
+import platform
+import string
+import urllib2
+import Queue
+import threading
+import signal
+import optparse
+import array
+from array import array
+
+#INFO: They aren't on Windows
+try:
+ from fcntl import ioctl
+ import termios
+except ImportError:
+ pass
+
'''This is the core module. It does the main job of downloading packages/update packages,\nfiguring out if the packages are in the local cache, handling exceptions and many more stuff'''
-def compress_the_file(zip_file_name, files_to_compress, download_dir):
- '''Condenses all the files into one single file for easy transfer'''
+
+version = "0.6.4"
+copyright = "(C) 2005 - 2007 Ritesh Raj Sarraf - RESEARCHUT (http://www.researchut.com/)"
+
+errlist = []
+supported_platforms = ["Linux", "GNU/kFreeBSD", "GNU"]
+apt_update_target_path = '/var/lib/apt/lists/'
+apt_package_target_path = '/var/cache/apt/archives/'
+# Dummy paths while testing on Windows
+#apt_update_target_path = 'C:\\temp'
+#apt_package_target_path = 'C:\\temp'
+
+
+class MD5Check:
- try:
- import zipfile
- except ImportError:
- log.err("Aieee!! Module not found.\n")
+ def md5_string(data):
+ hash = md5.new()
+ hash.update(data.read())
+ return hash.hexdigest()
+
+ def md5_check(file, checksum):
+ data = open(file, 'rb')
+ #local = md5_string(data)
+ if checksum == md5_string(data):
+ return True
+ return False
- try:
- os.chdir(download_dir)
- except:
- #TODO: Handle this exception
- log.err("Aieeee! I got a fatal exception that I don't understand.\nPlease debug.\n")
+class ProgressBar(object):
+ def __init__(self, minValue = 0, maxValue = 0, width = None, fd = sys.stderr):
+ #width does NOT include the two places for [] markers
+ self.min = minValue
+ self.max = maxValue
+ self.span = float(self.max - self.min)
+ self.fd = fd
+ self.signal_set = False
+ if width is None:
+ try:
+ self.handle_resize(None, None)
+ signal.signal(signal.SIGWINCH, self.handle_resize)
+ self.signal_set = True
+ except:
+ self.width = 79 #The standard
+ else:
+ self.width = width
+ self.value = self.min
+ self.items = 0 #count of items being tracked
+ self.complete = 0
+
+ def handle_resize(self, signum, frame):
+ h,w=array('h', ioctl(self.fd,termios.TIOCGWINSZ,'\0'*8))[:2]
+ self.width = w
- try:
- filename = zipfile.ZipFile(zip_file_name, "a")
- except IOError:
- #INFO By design zipfile throws an IOError exception when you open
- # in "append" mode and the file is not present.
- filename = zipfile.ZipFile(zip_file_name, "w")
- except:
- #TODO Handle the exception
- log.err("\nAieee! Some error exception in creating zip file %s\n" % (zip_file_name))
- sys.exit(1)
+ def updateValue(self, newValue):
+ #require caller to supply a value! newValue is the increment from last call
+ self.value = max(self.min, min(self.max, self.value + newValue))
+ self.display()
- filename.write(files_to_compress, files_to_compress, zipfile.ZIP_DEFLATED)
- filename.close()
+ def completed(self):
+ self.complete = self.complete + 1
+ if self.signal_set:
+ signal.signal(signal.SIGWINCH, signal.SIG_DFL)
+ self.display()
+
+ def addItem(self, maxValue):
+ self.max = self.max + maxValue
+ self.span = float(self.max - self.min)
+ self.items = self.items + 1
+ self.display()
+
+ def display(self):
+ print "\r%3s/%3s items: %s\r" % (self.complete, self.items, str(self)),
+
+ def __str__(self):
+ #compute display fraction
+ percentFilled = ((self.value - self.min) / self.span)
+ widthFilled = int(self.width * percentFilled + 0.5)
+ return ("[" + "#"*widthFilled + " "*(self.width - widthFilled) + "]" + " %5.1f%% of %d KB" % (percentFilled * 100.0, self.max/1024))
-def decompress_the_file(file, path, filename, archive_type):
- '''Extracts all the files from a single condensed archive file'''
+class Log:
+ '''A OOP implementation for logging.
+ warnings is to tackle the warning option
+ verbose is to tackle the verbose option
+ debug is to tackle the debug option
+ You should pass these options, taking it from optparse/getopt,
+ during instantiation'''
- if archive_type is 1:
- try:
- import bz2
- except ImportError:
- log.err("Aieeee! Module bz2 is not available.\n")
+ def __init__(self, warnings, verbose, debug):
+
+ if warnings is True:
+ self.WARN = True
+ else: self.WARN = False
+
+ if verbose is True:
+ self.VERBOSE = True
+ else: self.VERBOSE = False
+
+ if debug is True:
+ self.DEBUG = True
+ else: self.DEBUG = False
+
+ def msg(self, msg):
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+
+ def err(self, msg):
+ sys.stderr.write(msg)
+ sys.stderr.flush()
+
+ # For the rest, we need to check the options also
+ def warn(self, msg):
+ if self.WARN is True:
+ #if options.warnings is True:
+ sys.stderr.write(msg)
+ sys.stderr.flush()
+
+ def verbose(self, msg):
+ if self.VERBOSE is True:
+ #if options.verbose is True:
+ sys.stdout.write(msg)
+ sys.stdout.flush()
- try:
- fh = bz2.BZ2File(file, 'r')
- except:
- log.err("Couldn't open file %s for reading.\n" % (file))
+ def debug(self, msg):
+ if self.DEBUG is True:
+ #if options.debug is True:
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+class Archiver:
+ def __init__(self, lock=None):
+ if lock is None or lock != 1:
+ self.ziplock = False
+ else:
+ self.ZipLock = threading.Lock()
+ self.lock = True
+
+ def TarGzipBZ2_Uncompress(self, SourceFileHandle, TargetFileHandle):
try:
- wr_fh = open (os.path.join(path, filename), 'wb')
- except:
- log.err("Couldn't open file %s at path %s for writing.\n" % (filename, path))
-
- try:
- wr_fh.write(fh.read())
- except EOFError, e:
- log.err("Bad file %s\n%s" % (file, e))
+ TargetFileHandle.write(SourceFileHandle.read() )
+ except EOFError:
pass
+ return True
- wr_fh.close()
- fh.close()
- log.msg("%s file synced\n" % (filename))
+ def compress_the_file(self, zip_file_name, files_to_compress):
+ '''Condenses all the files into one single file for easy transfer'''
- elif archive_type is 2:
try:
- import gzip
+ import zipfile
except ImportError:
- log.err("Aieee! Module gzip is not available.\n")
-
+ return False
+
try:
- fh = gzip.GzipFile(file, 'r')
- except:
- log.err("Couldn't open file %s for reading.\n" % (file))
+ if self.lock:
+ self.ZipLock.acquire()
- try:
- wr_fh = open(os.path.join(path,filename), 'wb')
- except:
- log.err("Couldn't open file %s at path %s for writing.\n" % (filename, path))
+ filename = zipfile.ZipFile(zip_file_name, "a")
+ except IOError:
+ #INFO: By design zipfile throws an IOError exception when you open
+ # in "append" mode and the file is not present.
+ filename = zipfile.ZipFile(zip_file_name, "w")
+ #except:
+ #TODO Handle the exception
+ #return False
+
+ filename.write(files_to_compress, files_to_compress, zipfile.ZIP_DEFLATED)
+ filename.close()
+ if self.lock:
+ self.ZipLock.release()
+ return True
- try:
- wr_fh.write(fh.read())
- except EOFError, e:
- log.err("Bad file %s\n%s" % (file, e))
- pass
+ def decompress_the_file(self, archive_file, path, target_file, archive_type):
+ '''Extracts all the files from a single condensed archive file'''
- wr_fh.close()
- fh.close()
- log.msg("%s file synced\n" % (filename))
- elif archive_type is 3:
- try:
- zip_file = zipfile.ZipFile(file, 'rb')
- except:
- #TODO: Handle the exceptions
- log.err("\nAieee! Some error exception in reading the zip file %s\n" % (file))
- return False
+ if archive_type is 1:
+ try:
+ import bz2
+ except ImportError:
+ return False
- for filename in zip_file.namelist():
- data = zip_file.read()
+ try:
+ read_from = bz2.BZ2File(archive_file, 'r')
+ except:
+ return False
+
+ try:
+ write_to = open (os.path.join(path, filename), 'wb')
+ except:
+ return False
+
+ if TarGzipBZ2_Uncomprerssed(read_from, write_to) != True:
+ raise ArchiveError
- zip_file.close()
+ write_to.close()
+ read_from.close()
+ return True
+
+ elif archive_type is 2:
+ try:
+ import gzip
+ except ImportError:
+ return False
+
+ try:
+ read_from = gzip.GzipFile(file, 'r')
+ except:
+ return False
+
+ try:
+ write_to = open(os.path.join(path,filename), 'wb')
+ except:
+ return False
+
+ if TarGzipBZ2_Uncomprerssed(read_from, write_to) != True:
+ raise ArchiveError
+
+ write_to.close()
+ read_from.close()
+ return True
+
+ elif archive_type is 3:
+ # FIXME: This looks odd. Where are we writing to a file ???
+ try:
+ zip_file = zipfile.ZipFile(file, 'rb')
+ except:
+ return False
+
+ for filename in zip_file.namelist():
+ data = zip_file.read()
+
+ zip_file.close()
+ return True
+ else:
+ return False
+
+
+def files(self, root):
+ for path, folders, files in os.walk(root):
+ for file in files:
+ yield path, file
+
+def find_first_match(cache_dir=None, filename=None):
+ '''Return the full path of the filename if a match is found
+ Else Return False'''
+
+ # Do the sanity check first
+ if cache_dir is None or filename is None or os.path.isdir(cache_dir) is False:
+ return False
else:
- log.err("Aieeee! %s is unknown archive.\n" % (file))
- return False
-
- return True
-
-def download_from_web(url, file, download_dir, checksum, number_of_threads, thread_name):
+ for path, file in files(cache_dir):
+ if file == filename:
+ return os.path.join(path, file)
+ return False
+
+def download_from_web(url, file, download_dir, ProgressBarInstance):
'''
Download the required file from the web
The arguments are passed everytime to the function so that,
@@ -123,29 +293,19 @@
size = int(headers['Content-Length'])
data = open(file,'wb')
- progbar.addItem(size)
+ ProgressBarInstance.addItem(size)
- log.msg("Downloading %s - %d KB\n" % (file, size/1024))
+
while i < size:
data.write (temp.read(block_size))
increment = min(block_size, size - i)
i += block_size
counter += 1
- progbar.updateValue(increment)
- progbar.completed()
- log.msg("\r%s %s done.\n" % (file, " "))
+ ProgressBarInstance.updateValue(increment)
+ ProgressBarInstance.completed()
data.close()
temp.close()
- #INFO: Do an md5 checksum
- if pypt_variables.options.disable_md5check == True:
- pass
- else:
- if pypt_md5_check.md5_check(file, checksum, download_dir) != True:
- os.unlink(file)
- log.err("%s checksum mismatch. File removed\n" % (file))
- return False
- log.verbose("%s successfully downloaded from %s\n\n" % (file, url))
return True
#FIXME: Find out optimal fix for this exception handling
@@ -172,52 +332,6 @@
if hasattr(e, 'code') and hasattr(e, 'reason'):
errfunc(e.code, e.reason, file)
-#TODO: walk_tree_copy_debs - DEPRECATED
-# This might require simplification and optimization.
-# But for now it's doing the job.
-# Need to find a better algorithm, maybe os.walk()
-def walk_tree_copy_debs(cache, sFile, sSourceDir):
- '''
- This function checks for a package to see if its already downloaded
- It can search directories with depths.
- '''
- #The core algorithm is here for the whole program to function'\n'
- #It recursively searches a tree/subtree of folders for package files'\n'
- #like the directory structure of "apt-proxy". If files are found (.deb || .rpm)'\n'
- #it checks wether they are on the list of packages to be fetched. If yes,'\n\
- #it copies them. Same goes for flat "apt archives folders" also.'\n'
- #Else it fetches the package from the net"""
- bFound = False
- try:
- if cache is not None:
- for name in os.listdir(cache) and bFound == True:
- #if bFound == True:
- # break
- path = os.path.join(cache, name)
- if os.path.isdir(path):
- walk_tree_copy_debs(path, sFile, sSourceDir)
- #walk_tree_copy_debs(path, sFile)
- elif name.endswith('.deb') or name.endswith('.rpm'):
- if name == sFile:
- try:
- shutil.copy(path, sSourceDir)
- except IOError, (errno, errstring):
- errfunc(errno, errstring)
- except shutil.Error:
- log.msg("%s is available in %s. Skipping Copy!\n" % (name, sSourceDir))
- bFound = True
- break
-
- #shutil.copy(path, sSourceDir)
- #bFound = True
- #break
- #return bFound
- #return False
- except OSError, (errno, strerror):
- log.err("%s %s\n" % (errno, strerror))
- errfunc(errno, strerror)
-
-
def files(root):
for path, folders, files in os.walk(root):
for file in files:
@@ -267,7 +381,7 @@
item = item.split(' ')
url = string.rstrip(string.lstrip(''.join(item[0]), chars="'"), chars="'")
file = string.rstrip(string.lstrip(''.join(item[1]), chars="'"), chars="'")
- size = string.rstrip(string.lstrip(''.join(item[2]), chars = "'"), chars="'")
+ size = int(string.rstrip(string.lstrip(''.join(item[2]), chars = "'"), chars="'"))
#INFO: md5 ends up having '\n' with it.
# That needs to be stripped too.
md5_text = string.rstrip(string.lstrip(''.join(item[3]), chars = "'"), chars = "'")
@@ -323,7 +437,7 @@
log.err("Aieee! I don't understand this errorcode\n" % (errno))
sys.exit(errno)
-def fetcher(url_file, download_dir, cache_dir, zip_bool, zip_type_file, arg_type = 0):
+def fetcher(ArgumentOptions, arg_type = None):
'''
uri - The uri data whill will contain the information
path - The path (if any) where the download needs to be done
@@ -331,285 +445,290 @@
arg_type - arg_type is basically used to identify wether it's a update download or upgrade download
'''
+ cache_dir = ArgumentOptions.cache_dir
+ zip_bool = ArgumentOptions.zip_it
+
+ class FetcherClass(ProgressBar, Archiver, MD5Check):
+ def __init__(self, width, lock):
+ ProgressBar.__init__(self, width=width)
+ #ProgressBar.__init__(self, width)
+ #self.width = width
+ Archiver.__init__(self, lock=lock)
+ #self.lock = lock
+
+ #global FetcherInstance
+ FetcherInstance = FetcherClass(width=30, lock=True)
#INFO: For the Progress Bar
- global progbar
- progbar = pypt_progressbar.ProgressBar(width = 30)
+ #progbar = ProgressBar(width = 30)
- if arg_type == 1:
- #INFO: Oh! We're only downloading the update package list database
- # Package Update database changes almost daily in Debian.
- # This is at least true for Sid. Hence it doesn't make sense to copy
- # update packages' database from a cache.
-
- if download_dir is None:
- if os.access("pypt-downloads", os.W_OK) is True:
- download_dir = os.path.abspath("pypt-downloads")
- else:
- try:
- os.umask(0002)
- os.mkdir("pypt-downloads")
- download_dir = os.path.abspath("pypt-downloads")
- except:
- log.err("Aieeee! I couldn't create a directory")
- errfunc(1, '')
+ if ArgumentOptions.download_dir is None:
+ if os.access("pypt-downloads", os.W_OK) is True:
+ download_path = os.path.abspath("pypt-downloads")
else:
- download_dir = os.path.abspath(download_dir)
+ try:
+ os.umask(0002)
+ os.mkdir("pypt-downloads")
+ download_path = os.path.abspath("pypt-downloads")
+ except:
+ log.err("Aieeee! I couldn't create a directory")
+ errfunc(1, '')
+ else:
+ download_path = os.path.abspath(ArgumentOptions.download_dir)
+
+ FetchData = {}
+ if ArgumentOptions.fetch_update:
+ try:
+ raw_data_list = open(ArgumentOptions.fetch_update, 'r').readlines()
+ except IOError, (errno, strerror):
+ log.err("%s %s\n" % (errno, strerror))
+ errfunc(errno, '')
- if os.access(os.path.join(download_dir, zip_type_file), os.F_OK):
- log.err("%s already present.\nRemove it first.\n" % (zip_type_file))
+ FetchData['Update'] = []
+ for item in raw_data_list:
+ FetchData['Update'].append(item)
+
+ if os.access(os.path.join(download_path, ArgumentOptions.zip_update_file), os.F_OK):
+ log.err("%s already present.\nRemove it first.\n" % (ArgumentOptions.zip_update_file) )
sys.exit(1)
+
+ if ArgumentOptions.fetch_upgrade:
try:
- raw_data_list = open(url_file, 'r').readlines()
+ raw_data_list = open(ArgumentOptions.fetch_upgrade, 'r').readlines()
except IOError, (errno, strerror):
log.err("%s %s\n" % (errno, strerror))
errfunc(errno, '')
+
+ FetchData['Upgrade'] = []
+ for item in raw_data_list:
+ FetchData['Upgrade'].append(item)
- #INFO: Mac OS is having issues with Python Threading.
- # Use the conventional model for Mac OS
- if sys.platform == 'darwin':
- log.verbose("Running on Mac OS. Python doesn't have proper support for Threads on Mac OS X.\n")
- log.verbose("Running in the conventional non-threaded way.\n")
- for each_single_item in raw_data_list:
- (url, file, download_size, checksum) = stripper(each_single_item)
- if download_from_web(url, file, download_dir, None) != True:
- pypt_variables.errlist.append(file)
- else:
- if zip_bool:
- compress_the_file(zip_type_file, file, download_dir)
- os.unlink(os.path.join(download_dir, file)) # Remove it because we don't need the file once it is zipped.
- else:
- #INFO: Thread Support
- if pypt_variables.options.num_of_threads > 1:
- log.msg("WARNING: Threads is still in alpha stage. It's better to use just a single thread at the moment.\n\n")
- log.warn("Threads is still in alpha stage. It's better to use just a single thread at the moment.\n\n")
-
- NUMTHREADS = pypt_variables.options.num_of_threads
- ziplock = threading.Lock()
+ if os.access(os.path.join(download_path, ArgumentOptions.zip_upgrade_file), os.F_OK):
+ log.err("%s already present.\nRemove it first.\n" % (ArgumentOptions.zip_upgrade_file) )
+ sys.exit(1)
- def run(request, response, func=download_from_web):
- '''Get items from the request Queue, process them
- with func(), put the results along with the
- Thread's name into the response Queue.
+ del raw_data_list
+
+
+ #INFO: Mac OS is having issues with Python Threading.
+ # Use the conventional model for Mac OS
+ if sys.platform == 'darwin':
+ log.verbose("Running on Mac OS! pypt-offline doesn't have proper support for Threads on Mac OS X.\n")
+ log.verbose("Running in the conventional non-threaded way.\n")
+
+ for key in FetchData.keys():
+ for item in FetchData.get(key):
- Stop running once an item is None.'''
-
- while 1:
- item = request.get()
- if item is None:
- break
- (url, file, download_size, checksum) = stripper(item)
- thread_name = threading.currentThread().getName()
- response.put((thread_name, url, file, func(url, file, download_dir, None, NUMTHREADS, thread_name)))
-
- # This will take care of making sure that if downloaded, they are zipped
- (thread_name, url, file, exit_status) = responseQueue.get()
- if exit_status == True:
- if zip_bool:
- ziplock.acquire()
- try:
- compress_the_file(zip_type_file, file, download_dir)
- os.unlink(os.path.join(download_dir, file)) # Remove it because we don't need the file once it is zipped.
- finally:
- ziplock.release()
- else:
- pypt_variables.errlist.append(file)
- #pass
-
- # Create two Queues for the requests and responses
- requestQueue = Queue.Queue()
- responseQueue = Queue.Queue()
-
- # Pool of NUMTHREADS Threads that run run().
- thread_pool = [
- threading.Thread(
- target=run,
- args=(requestQueue, responseQueue)
- )
- for i in range(NUMTHREADS)
- ]
-
- # Start the threads.
- for t in thread_pool: t.start()
-
- # Queue up the requests.
- for item in raw_data_list: requestQueue.put(item)
-
- # Shut down the threads after all requests end.
- # (Put one None "sentinel" for each thread.)
- for t in thread_pool: requestQueue.put(None)
-
- # Don't end the program prematurely.
- #
- # (Note that because Queue.get() is blocking by
- # defualt this isn't strictly necessary. But if
- # you were, say, handling responses in another
- # thread, you'd want something like this in your
- # main thread.)
- for t in thread_pool: t.join()
-
- if arg_type == 2:
- if download_dir is None:
- if os.access("pypt-downloads", os.W_OK) is True:
- download_dir = os.path.abspath("pypt-downloads")
- else:
- try:
- os.umask(0002)
- os.mkdir("pypt-downloads")
- download_dir = os.path.abspath("pypt-downloads")
- except:
- log.err("Aieeee! I couldn't create a directory")
- else:
- download_dir = os.path.abspath(download_dir)
-
- if os.access(os.path.join(download_dir, zip_type_file), os.F_OK):
- log.err("%s already present.\nRemove it first.\n" % (zip_type_file))
- sys.exit(1)
-
- if cache_dir is not None:
- cache_dir = os.path.abspath(cache_dir)
-
- try:
- raw_data_list = open(url_file, 'r').readlines()
- except IOError, (errno, strerror):
- log.err("%s %s\n" %(errno, strerror))
- errfunc(errno, '', url_file)
-
- #INFO: Mac OS X in mis-behaving with Python Threading
- # Use the conventional model for Mac OS X
- if sys.platform == 'darwin':
- log.verbose("Running on Mac OS. Python doesn't have proper support for Threads on Mac OS X.\n")
- log.verbose("Running in the conventional non-threaded way.\n")
- for each_single_item in raw_data_list:
(url, file, download_size, checksum) = stripper(each_single_item)
+ log.msg("Downloading %s\n" % (file) )
- if cache_dir is None:
- if download_from_web(url, file, download_dir, checksum) != True:
- pypt_variables.errlist.append(file)
+ if key == 'Update':
+ if download_from_web(url, file, download_path, FetcherInstance) != True:
+ errlist.append(file)
+ else:
+ log.msg("\r%s %s done.\n" % (file, " ") )
if zip_bool:
- compress_the_file(zip_type_file, file, download_dir)
- os.unlink(os.path.join(download_dir, file))
- else:
- if copy_first_match(cache_dir, file, download_dir, checksum) == False:
- if download_from_web(url, file, download_dir, checksum) != True:
- pypt_variables.errlist.append(file)
- else:
- if os.access(os.path.join(cache_dir, file), os.F_OK):
- log.debug("%s file is already present in cache-dir %s. Skipping copy.\n" % (file, cache_dir)) #INFO: The file is already there.
- log.verbose("%s file is already present in cache-dir %s. Skipping copy.\n" % (file, cache_dir))
+ if archive.compress_the_file(ArgumentOptions.zip_update_file, file) != True:
+ log.verbose("%s added to archive %s.\n" % (file, ArgumentOptions.zip_update_file) )
+ os.unlink(os.path.join(download_path, file) ) # Remove it because we don't need the file once it is zipped.
+ sys.exit(1)
+ pass
+
+ elif key == 'Upgrade':
+ if cache_dir is None:
+ log.msg("Downloading %s - %d KB\n" % (file, size/1024))
+ if download_from_web(url, file, download_path, FetcherInstance) != True:
+ pypt_variables.errlist.append(file)
+ if zip_bool:
+ log.msg("\r%s %s done.\n" % (file, " "))
+ archive.compress_the_file(ArgumentOptions.zip_upgrade_file, file)
+ os.unlink(os.path.join(download_path, file))
+ else:
+ if copy_first_match(cache_dir, file, download_path, checksum) == False:
+ log.msg("Downloading %s - %d KB\n" % (file, size/1024))
+ if download_from_web(url, file, down...
[truncated message content] |
|
From: <rit...@us...> - 2007-03-13 09:28:25
|
Revision: 128
http://svn.sourceforge.net/pypt-offline/?rev=128&view=rev
Author: riteshsarraf
Date: 2007-03-13 02:28:26 -0700 (Tue, 13 Mar 2007)
Log Message:
-----------
* Removing progressbar.py
Removed Paths:
-------------
trunk/progressbar.py
Property Changed:
----------------
trunk/
Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
+ .project
Deleted: trunk/progressbar.py
===================================================================
--- trunk/progressbar.py 2007-03-12 13:45:51 UTC (rev 127)
+++ trunk/progressbar.py 2007-03-13 09:28:26 UTC (rev 128)
@@ -1,368 +0,0 @@
-#!/usr/bin/python
-# -*- coding: iso-8859-1 -*-
-#
-# progressbar - Text progressbar library for python.
-# Copyright (c) 2005 Nilton Volpato
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-"""Text progressbar library for python.
-
-This library provides a text mode progressbar. This is tipically used
-to display the progress of a long running operation, providing a
-visual clue that processing is underway.
-
-The ProgressBar class manages the progress, and the format of the line
-is given by a number of widgets. A widget is an object that may
-display diferently depending on the state of the progress. There are
-three types of widget:
-- a string, which always shows itself;
-- a ProgressBarWidget, which may return a diferent value every time
-it's update method is called; and
-- a ProgressBarWidgetHFill, which is like ProgressBarWidget, except it
-expands to fill the remaining width of the line.
-
-The progressbar module is very easy to use, yet very powerful. And
-automatically supports features like auto-resizing when available.
-"""
-
-__author__ = "Nilton Volpato"
-__author_email__ = "first-name dot last-name @ gmail.com"
-__date__ = "2006-05-07"
-__version__ = "2.2"
-
-# Changelog
-#
-# 2006-05-07: v2.2 fixed bug in windows
-# 2005-12-04: v2.1 autodetect terminal width, added start method
-# 2005-12-04: v2.0 everything is now a widget (wow!)
-# 2005-12-03: v1.0 rewrite using widgets
-# 2005-06-02: v0.5 rewrite
-# 2004-??-??: v0.1 first version
-
-
-import sys, time
-from array import array
-try:
- from fcntl import ioctl
- import termios
-except ImportError:
- pass
-import signal
-
-class ProgressBarWidget(object):
- """This is an element of ProgressBar formatting.
-
- The ProgressBar object will call it's update value when an update
- is needed. It's size may change between call, but the results will
- not be good if the size changes drastically and repeatedly.
- """
- def update(self, pbar):
- """Returns the string representing the widget.
-
- The parameter pbar is a reference to the calling ProgressBar,
- where one can access attributes of the class for knowing how
- the update must be made.
-
- At least this function must be overriden."""
- pass
-
-class ProgressBarWidgetHFill(object):
- """This is a variable width element of ProgressBar formatting.
-
- The ProgressBar object will call it's update value, informing the
- width this object must the made. This is like TeX \\hfill, it will
- expand to fill the line. You can use more than one in the same
- line, and they will all have the same width, and together will
- fill the line.
- """
- def update(self, pbar, width):
- """Returns the string representing the widget.
-
- The parameter pbar is a reference to the calling ProgressBar,
- where one can access attributes of the class for knowing how
- the update must be made. The parameter width is the total
- horizontal width the widget must have.
-
- At least this function must be overriden."""
- pass
-
-
-class ETA(ProgressBarWidget):
- "Widget for the Estimated Time of Arrival"
- def format_time(self, seconds):
- return time.strftime('%H:%M:%S', time.gmtime(seconds))
- def update(self, pbar):
- if pbar.currval == 0:
- return 'ETA: --:--:--'
- elif pbar.finished:
- return 'Time: %s' % self.format_time(pbar.seconds_elapsed)
- else:
- elapsed = pbar.seconds_elapsed
- eta = elapsed * pbar.maxval / pbar.currval - elapsed
- return 'ETA: %s' % self.format_time(eta)
-
-class FileTransferSpeed(ProgressBarWidget):
- "Widget for showing the transfer speed (useful for file transfers)."
- def __init__(self):
- self.fmt = '%6.2f %s'
- self.units = ['B','K','M','G','T','P']
- def update(self, pbar):
- if pbar.seconds_elapsed < 2e-6:#== 0:
- bps = 0.0
- else:
- bps = float(pbar.currval) / pbar.seconds_elapsed
- spd = bps
- for u in self.units:
- if spd < 1000:
- break
- spd /= 1000
- return self.fmt % (spd, u+'/s')
-
-class RotatingMarker(ProgressBarWidget):
- "A rotating marker for filling the bar of progress."
- def __init__(self, markers='|/-\\'):
- self.markers = markers
- self.curmark = -1
- def update(self, pbar):
- if pbar.finished:
- return self.markers[0]
- self.curmark = (self.curmark + 1)%len(self.markers)
- return self.markers[self.curmark]
-
-class Percentage(ProgressBarWidget):
- "Just the percentage done."
- def update(self, pbar):
- return '%3d%%' % pbar.percentage()
-
-class Bar(ProgressBarWidgetHFill):
- "The bar of progress. It will strech to fill the line."
- def __init__(self, marker='#', left='|', right='|'):
- self.marker = marker
- self.left = left
- self.right = right
- def _format_marker(self, pbar):
- if isinstance(self.marker, (str, unicode)):
- return self.marker
- else:
- return self.marker.update(pbar)
- def update(self, pbar, width):
- percent = pbar.percentage()
- cwidth = width - len(self.left) - len(self.right)
- marked_width = int(percent * cwidth / 100)
- m = self._format_marker(pbar)
- bar = (self.left + (m*marked_width).ljust(cwidth) + self.right)
- return bar
-
-class ReverseBar(Bar):
- "The reverse bar of progress, or bar of regress. :)"
- def update(self, pbar, width):
- percent = pbar.percentage()
- cwidth = width - len(self.left) - len(self.right)
- marked_width = int(percent * cwidth / 100)
- m = self._format_marker(pbar)
- bar = (self.left + (m*marked_width).rjust(cwidth) + self.right)
- return bar
-
-default_widgets = [Percentage(), ' ', Bar()]
-class ProgressBar(object):
- """This is the ProgressBar class, it updates and prints the bar.
-
- The term_width parameter may be an integer. Or None, in which case
- it will try to guess it, if it fails it will default to 80 columns.
-
- The simple use is like this:
- >>> pbar = ProgressBar().start()
- >>> for i in xrange(100):
- ... # do something
- ... pbar.update(i+1)
- ...
- >>> pbar.finish()
-
- But anything you want to do is possible (well, almost anything).
- You can supply different widgets of any type in any order. And you
- can even write your own widgets! There are many widgets already
- shipped and you should experiment with them.
-
- When implementing a widget update method you may access any
- attribute or function of the ProgressBar object calling the
- widget's update method. The most important attributes you would
- like to access are:
- - currval: current value of the progress, 0 <= currval <= maxval
- - maxval: maximum (and final) value of the progress
- - finished: True if the bar is have finished (reached 100%), False o/w
- - start_time: first time update() method of ProgressBar was called
- - seconds_elapsed: seconds elapsed since start_time
- - percentage(): percentage of the progress (this is a method)
- """
- def __init__(self, maxval=100, widgets=default_widgets, term_width=None,
- fd=sys.stderr):
- assert maxval > 0
- self.maxval = maxval
- self.widgets = widgets
- self.fd = fd
- self.signal_set = False
- if term_width is None:
- try:
- self.handle_resize(None,None)
- signal.signal(signal.SIGWINCH, self.handle_resize)
- self.signal_set = True
- except:
- self.term_width = 79
- else:
- self.term_width = term_width
-
- self.currval = 0
- self.finished = False
- self.prev_percentage = -1
- self.start_time = None
- self.seconds_elapsed = 0
-
- def handle_resize(self, signum, frame):
- h,w=array('h', ioctl(self.fd,termios.TIOCGWINSZ,'\0'*8))[:2]
- self.term_width = w
-
- def percentage(self):
- "Returns the percentage of the progress."
- return self.currval*100.0 / self.maxval
-
- def _format_widgets(self):
- r = []
- hfill_inds = []
- num_hfill = 0
- currwidth = 0
- for i, w in enumerate(self.widgets):
- if isinstance(w, ProgressBarWidgetHFill):
- r.append(w)
- hfill_inds.append(i)
- num_hfill += 1
- elif isinstance(w, (str, unicode)):
- r.append(w)
- currwidth += len(w)
- else:
- weval = w.update(self)
- currwidth += len(weval)
- r.append(weval)
- for iw in hfill_inds:
- r[iw] = r[iw].update(self, (self.term_width-currwidth)/num_hfill)
- return r
-
- def _format_line(self):
- return ''.join(self._format_widgets()).ljust(self.term_width)
-
- def _need_update(self):
- return int(self.percentage()) != int(self.prev_percentage)
-
- def update(self, value):
- "Updates the progress bar to a new value."
- #assert 0 <= value <= self.maxval
- self.currval = value
- if not self._need_update() or self.finished:
- return
- if not self.start_time:
- self.start_time = time.time()
- self.seconds_elapsed = time.time() - self.start_time
- self.prev_percentage = self.percentage()
- if value != self.maxval:
- self.fd.write(self._format_line() + '\r')
- else:
- self.finished = True
- self.fd.write(self._format_line() + '\n')
-
- def start(self):
- """Start measuring time, and prints the bar at 0%.
-
- It returns self so you can use it like this:
- >>> pbar = ProgressBar().start()
- >>> for i in xrange(100):
- ... # do something
- ... pbar.update(i+1)
- ...
- >>> pbar.finish()
- """
- self.update(0)
- return self
-
- def finish(self):
- """Used to tell the progress is finished."""
- self.update(self.maxval)
- if self.signal_set:
- signal.signal(signal.SIGWINCH, signal.SIG_DFL)
-
-
-
-
-
-
-if __name__=='__main__':
- import os
-
- def example1():
- widgets = ['Test: ', Percentage(), ' ', Bar(marker=RotatingMarker()),
- ' ', ETA(), ' ', FileTransferSpeed()]
- pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
- for i in range(1000000):
- # do something
- pbar.update(10*i+1)
- pbar.finish()
- print
-
- def example2():
- class CrazyFileTransferSpeed(FileTransferSpeed):
- "It's bigger between 45 and 80 percent"
- def update(self, pbar):
- if 45 < pbar.percentage() < 80:
- return 'Bigger Now ' + FileTransferSpeed.update(self,pbar)
- else:
- return FileTransferSpeed.update(self,pbar)
-
- widgets = [CrazyFileTransferSpeed(),' <<<', Bar(), '>>> ', Percentage(),' ', ETA()]
- pbar = ProgressBar(widgets=widgets, maxval=10000000)
- # maybe do something
- pbar.start()
- for i in range(2000000):
- # do something
- pbar.update(5*i+1)
- pbar.finish()
- print
-
- def example3():
- widgets = [Bar('>'), ' ', ETA(), ' ', ReverseBar('<')]
- pbar = ProgressBar(widgets=widgets, maxval=10000000).start()
- for i in range(1000000):
- # do something
- pbar.update(10*i+1)
- pbar.finish()
- print
-
- def example4():
- widgets = ['Test: ', Percentage(), ' ',
- Bar(marker='0',left='[',right=']'),
- ' ', ETA(), ' ', FileTransferSpeed()]
- pbar = ProgressBar(widgets=widgets, maxval=500)
- pbar.start()
- for i in range(100,500+1,50):
- time.sleep(0.2)
- pbar.update(i)
- pbar.finish()
- print
-
-
- example1()
- example2()
- example3()
- example4()
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-03-22 11:02:59
|
Revision: 134
http://svn.sourceforge.net/pypt-offline/?rev=134&view=rev
Author: riteshsarraf
Date: 2007-03-22 04:02:57 -0700 (Thu, 22 Mar 2007)
Log Message:
-----------
* Fixed color display on Microsoft Windows. Will need more beautification
Modified Paths:
--------------
trunk/TODO
trunk/pypt_core.py
Property Changed:
----------------
trunk/
Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
- .project
+ .project
.pydevproject
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2007-03-22 10:06:03 UTC (rev 133)
+++ trunk/TODO 2007-03-22 11:02:57 UTC (rev 134)
@@ -11,4 +11,5 @@
is selected the others will be deactivated. That's design, only one option allowed a time. :-)
* Use Python's logging module to better handle messages, warnings and errors <done>
* Implement apt's newly added feature (> 0.6.4) of Package Diff
-* Add functionality for Offline Bug Reports
\ No newline at end of file
+* Add functionality for Offline Bug Reports
+* Handle KeyboardInterrupt exception in threads so that if the user sends an interrupt signal, the program should exit
\ No newline at end of file
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-03-22 10:06:03 UTC (rev 133)
+++ trunk/pypt_core.py 2007-03-22 11:02:57 UTC (rev 134)
@@ -19,6 +19,12 @@
except ImportError:
pass
+WindowColor = True
+try:
+ import WConio
+except ImportError:
+ WindowColor = False
+
'''This is the core module. It does the main job of downloading packages/update packages,\nfiguring out if the packages are in the local cache, handling exceptions and many more stuff'''
@@ -118,12 +124,7 @@
Light Cyan = 11
'''
- try:
- import WConio
- except ImportError:
- WindowColor = False
-
- def __init__(self, warnings, verbose):
+ def __init__(self, warnings, verbose, color = None):
if warnings is True:
self.WARN = True
@@ -133,14 +134,16 @@
self.VERBOSE = True
else: self.VERBOSE = False
+ self.color = color
+
def msg(self, msg):
- if self.WindowColor:
+ if self.color:
WConio.textcolor(15)
sys.stdout.write(msg)
sys.stdout.flush()
def err(self, msg):
- if self.WindowColor:
+ if self.color:
WConio.textcolor(4)
sys.stderr.write(msg)
sys.stderr.flush()
@@ -148,14 +151,14 @@
# For the rest, we need to check the options also
def warn(self, msg):
if self.WARN is True:
- if self.WindowColor:
+ if self.color:
WConio.textcolor(12)
sys.stderr.write(msg)
sys.stderr.flush()
def verbose(self, msg):
if self.VERBOSE is True:
- if self.WindowColor:
+ if self.color:
WConio.textcolor(11)
sys.stdout.write(msg)
sys.stdout.flush()
@@ -623,6 +626,8 @@
log.err("Couldn't archive %s to file %s.\n" % (file, ArgumentOptions.zip_update_file) )
sys.exit(1)
os.unlink(os.path.join(download_path, file) )
+ else:
+ errlist.append(file)
elif key == 'Upgrade':
response.put(func(cache_dir, file) )
@@ -878,7 +883,7 @@
# The log implementation
# Instantiate the class
global log
- log = Log(options.warnings, options.verbose)
+ log = Log(options.warnings, options.verbose, WindowColor)
log.msg("pypt-offline %s\n" % (version))
log.msg("Copyright %s\n" % (copyright))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-04-25 14:18:33
|
Revision: 136
http://svn.sourceforge.net/pypt-offline/?rev=136&view=rev
Author: riteshsarraf
Date: 2007-04-25 07:18:34 -0700 (Wed, 25 Apr 2007)
Log Message:
-----------
* Adding offline bug report functionality for Debian.
* We rely on reportbug packages. We ship them here for user convenience because they also have to be run on windows.
* For the latest and greates reportbug, you can always go and download it from Debian Alioth
Added Paths:
-----------
trunk/checkversions.py
trunk/debianbts.py
trunk/fetch_bugs.py
trunk/reportbug.py
trunk/reportbug_exceptions.py
trunk/urlutils.py
Added: trunk/checkversions.py
===================================================================
--- trunk/checkversions.py (rev 0)
+++ trunk/checkversions.py 2007-04-25 14:18:34 UTC (rev 136)
@@ -0,0 +1,334 @@
+#
+# checkversions.py - Find if the installed version of a package is the latest
+#
+# Written by Chris Lawrence <law...@de...>
+# (C) 2002-06 Chris Lawrence
+#
+# This program is freely distributable per the following license:
+#
+## Permission to use, copy, modify, and distribute this software and its
+## documentation for any purpose and without fee is hereby granted,
+## provided that the above copyright notice appears in all copies and that
+## both that copyright notice and this permission notice appear in
+## supporting documentation.
+##
+## I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
+## BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+## DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+## WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+## ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+## SOFTWARE.
+#
+# $Id: checkversions.py,v 1.6.2.3 2006/10/16 18:52:41 lawrencc Exp $
+#
+# Version 3.35; see changelog for revision history
+
+import sgmllib
+#import HTMLParser
+
+import os, re, sys, urllib2
+from urlutils import open_url
+from reportbug_exceptions import *
+
+PACKAGES_URL = 'http://packages.debian.org/%s'
+INCOMING_URL = 'http://incoming.debian.org/'
+NEWQUEUE_URL = 'http://ftp-master.debian.org/new.html'
+
+# The format is an unordered list
+
+class BaseParser(sgmllib.SGMLParser):
+ def __init__(self):
+ sgmllib.SGMLParser.__init__(self)
+ self.savedata = None
+
+ # --- Formatter interface, taking care of 'savedata' mode;
+ # shouldn't need to be overridden
+
+ def handle_data(self, data):
+ if self.savedata is not None:
+ self.savedata = self.savedata + data
+
+ # --- Hooks to save data; shouldn't need to be overridden
+ def save_bgn(self):
+ self.savedata = ''
+
+ def save_end(self, mode=0):
+ data = self.savedata
+ self.savedata = None
+ if not mode and data is not None: data = ' '.join(data.split())
+ return data
+
+class PackagesParser(BaseParser):
+ def __init__(self, arch='i386'):
+ BaseParser.__init__(self)
+ self.versions = {}
+ self.row = None
+ arch = r'\s(all|'+re.escape(arch)+r')\b'
+ self.arch = re.compile(arch)
+ self.dist = None
+
+ def start_li(self, attrs):
+ if self.row is not None:
+ self.end_li()
+ self.row = []
+
+ def start_a(self, attrs):
+ if self.row is not None:
+ self.save_bgn()
+
+ def end_a(self):
+ if self.row is not None and self.savedata:
+ self.dist = self.save_end()
+
+ def lineend(self):
+ line = self.save_end().strip()
+ if self.arch.search(line):
+ version = line.split(': ', 1)
+ self.versions[self.dist] = version[0]
+
+ def start_br(self, attrs):
+ if self.savedata:
+ self.lineend()
+ self.save_bgn()
+
+ def end_li(self):
+ if self.savedata:
+ self.lineend()
+ self.row = None
+
+class IncomingParser(sgmllib.SGMLParser):
+ def __init__(self, package, arch='i386'):
+ sgmllib.SGMLParser.__init__(self)
+ self.found = []
+ self.savedata = None
+ arch = r'(?:all|'+re.escape(arch)+')'
+ self.package = re.compile(re.escape(package)+r'_([^_]+)_'+arch+'.deb')
+
+ def start_a(self, attrs):
+ for attrib, value in attrs:
+ if attrib.lower() != 'href':
+ continue
+
+ mob = self.package.match(value)
+ if mob:
+ self.found.append(mob.group(1))
+
+class NewQueueParser(BaseParser):
+ def __init__(self, package, arch='i386'):
+ BaseParser.__init__(self)
+ self.package = package
+ self.row = None
+ arch = r'\s(all|'+re.escape(arch)+r')\b'
+ self.arch = re.compile(arch)
+ self.versions = {}
+
+ def start_tr (self, attrs):
+ for name, value in attrs:
+ if name == 'class' and value in ("odd", "even"):
+ self.row = []
+
+ def end_tr (self):
+ if self.row is not None:
+ # row (name, versions, architectures, distribution)
+ dist = "%s (new queue)" % self.row[3]
+ for version in self.row[1].split():
+ self.versions[dist] = version
+ self.row = None
+
+ def start_td (self, attrs):
+ if self.row is None:
+ return
+ self.save_bgn()
+
+ def end_td (self):
+ if self.row is None:
+ return
+ data = self.save_end()
+ l = len(self.row)
+ if l == 0:
+ # package name
+ if self.package == data:
+ # found package name
+ self.row.append(data)
+ else:
+ self.row = None
+ elif l == 2:
+ # architecture
+ if self.arch.search(data):
+ self.row.append(data)
+ else:
+ self.row = None
+ else:
+ self.row.append(data)
+
+def compare_versions(current, upstream):
+ """Return 1 if upstream is newer than current, -1 if current is
+ newer than upstream, and 0 if the same."""
+ if not upstream: return 0
+ rc = os.system('dpkg --compare-versions %s lt %s' % (current, upstream))
+ rc2 = os.system('dpkg --compare-versions %s gt %s' % (current, upstream))
+ if not rc:
+ return 1
+ elif not rc2:
+ return -1
+ return 0
+
+def later_version(a, b):
+ if compare_versions(a, b) > 0:
+ return b
+ return a
+
+def get_versions_available(package, dists=None, http_proxy=None, arch='i386'):
+ if not dists:
+ dists = ('stable', 'testing', 'unstable')
+
+ try:
+ page = open_url(PACKAGES_URL % package, http_proxy)
+ except NoNetwork:
+ return {}
+ except urllib2.HTTPError, x:
+ print >> sys.stderr, "Warning:", x
+ return {}
+ if not page:
+ return {}
+
+ parser = PackagesParser(arch)
+ for line in page:
+ parser.feed(line)
+ parser.close()
+ try:
+ page.fp._sock.recv = None
+ except:
+ pass
+ page.close()
+
+## content = page.read()
+## parser.feed(content)
+## parser.close()
+## page.close()
+
+ versions = {}
+ for dist in dists:
+ if dist in parser.versions:
+ versions[dist] = parser.versions[dist]
+ del parser
+ del page
+
+ return versions
+
+def get_newqueue_available(package, dists=None, http_proxy=None, arch='i386'):
+ if dists is None:
+ dists = ('unstable (new queue)', )
+ try:
+ page = open_url(NEWQUEUE_URL, http_proxy)
+ except NoNetwork:
+ return {}
+ except urllib2.HTTPError, x:
+ print >> sys.stderr, "Warning:", x
+ return {}
+ if not page:
+ return {}
+ parser = NewQueueParser(package, arch)
+ for line in page:
+ parser.feed(line)
+ parser.close()
+ try:
+ page.fp._sock.recv = None
+ except:
+ pass
+ page.close()
+
+ #print repr(page)
+
+ versions = {}
+ for dist in dists:
+ if dist in parser.versions:
+ versions[dist] = parser.versions[dist]
+
+ del parser
+ del page
+ #print 'HERE', gc.garbage
+ return versions
+
+def get_incoming_version(package, http_proxy=None, arch='i386'):
+ try:
+ page = open_url(INCOMING_URL, http_proxy)
+ except NoNetwork:
+ return None
+ except urllib2.HTTPError, x:
+ print >> sys.stderr, "Warning:", x
+ return None
+ if not page:
+ return None
+
+ parser = IncomingParser(package, arch)
+ for line in page:
+ parser.feed(line)
+ parser.close()
+ try:
+ page.fp._sock.recv = None
+ except:
+ pass
+ page.close()
+
+ if parser.found:
+ found = parser.found
+ del parser
+ return reduce(later_version, found, '0')
+
+ del page
+ del parser
+ return None
+
+import gc
+def check_available(package, version, dists=None, check_incoming=True,
+ check_newqueue=True,
+ http_proxy=None, arch='i386'):
+ avail = {}
+
+ if check_incoming:
+ iv = get_incoming_version(package, http_proxy, arch)
+ if iv:
+ avail['incoming'] = iv
+ stuff = get_versions_available(package, dists, http_proxy, arch)
+ avail.update(stuff)
+ if check_newqueue:
+ import reportbug
+ srcpackage = reportbug.get_source_name(package)
+ if srcpackage is None:
+ srcpackage = package
+ stuff = get_newqueue_available(srcpackage, dists, http_proxy, arch)
+ avail.update(stuff)
+ #print gc.garbage, stuff
+
+ new = {}
+ newer = 0
+ for dist in avail:
+ if dist == 'incoming':
+ if ':' in version:
+ ver = version.split(':', 1)[1]
+ else:
+ ver = version
+ comparison = compare_versions(ver, avail[dist])
+ else:
+ comparison = compare_versions(version, avail[dist])
+ if comparison > 0:
+ new[dist] = avail[dist]
+ elif comparison < 0:
+ newer += 1
+ too_new = (newer and newer == len(avail))
+ return new, too_new
+
+if __name__=='__main__':
+ import time
+ import gc
+
+ gc.set_debug(gc.DEBUG_LEAK)
+ print get_newqueue_available('reportbug')
+ print gc.garbage
+ print check_available('reportbug', '3.7', arch='s390')
+ #print check_available('openssh-server', '1:4.2p1-8', arch='i386')
+ #print check_available('openssh-server', '1:4.2p1-8', arch='kfreebsd-i386')
+ time.sleep(1000)
+ #print check_available('dpkg', '1.10.2', arch='sparc')
Added: trunk/debianbts.py
===================================================================
--- trunk/debianbts.py (rev 0)
+++ trunk/debianbts.py 2007-04-25 14:18:34 UTC (rev 136)
@@ -0,0 +1,875 @@
+#
+# debianbts.py - Routines to deal with the debbugs web pages
+#
+# Written by Chris Lawrence <law...@de...>
+# (C) 1999-2006 Chris Lawrence
+#
+# This program is freely distributable per the following license:
+#
+## Permission to use, copy, modify, and distribute this software and its
+## documentation for any purpose and without fee is hereby granted,
+## provided that the above copyright notice appears in all copies and that
+## both that copyright notice and this permission notice appear in
+## supporting documentation.
+##
+## I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
+## BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+## DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+## WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+## ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+## SOFTWARE.
+#
+# Version 3.35; see changelog for revision history
+#
+# $Id: debianbts.py,v 1.24.2.7 2006/10/16 17:14:03 lawrencc Exp $
+
+import sgmllib, glob, os, re, reportbug, rfc822, time, urllib, checkversions
+from urlutils import open_url
+import sys
+
+import mailbox
+import email
+import email.Errors
+import cStringIO
+import cgi
+
+def msgfactory(fp):
+ try:
+ return email.message_from_file(fp)
+ except email.Errors.MessageParseError:
+ # Don't return None since that will
+ # stop the mailbox iterator
+ return ''
+
+class Error(Exception):
+ pass
+
+# Severity levels
+SEVERITIES = {
+ 'critical' : """makes unrelated software on the system (or the
+ whole system) break, or causes serious data loss, or introduces a
+ security hole on systems where you install the package.""",
+ 'grave' : """makes the package in question unusable by most or all users,
+ or causes data loss, or introduces a security hole allowing access
+ to the accounts of users who use the package.""",
+ 'serious' : """is a severe violation of Debian policy (that is,
+ the problem is a violation of a 'must' or 'required' directive);
+ may or may not affect the usability of the package. Note that non-severe
+ policy violations may be 'normal,' 'minor,' or 'wishlist' bugs.
+ (Package maintainers may also designate other bugs as 'serious' and thus
+ release-critical; however, end users should not do so.)""",
+ 'important' : """a bug which has a major effect on the usability
+ of a package, without rendering it completely unusable to
+ everyone.""",
+ 'does-not-build' : """a bug that stops the package from being built
+ from source. (This is a 'virtual severity'.)""",
+ 'normal' : """a bug that does not undermine the usability of the
+ whole package; for example, a problem with a particular option or
+ menu item.""",
+ 'minor' : """things like spelling mistakes and other minor
+ cosmetic errors that do not affect the core functionality of the
+ package.""",
+ 'wishlist' : "suggestions and requests for new features.",
+ }
+
+# justifications for critical bugs
+JUSTIFICATIONS = {
+ 'critical' : (
+ ('breaks unrelated software', """breaks unrelated software on the system
+ (packages that have a dependency relationship are not unrelated)"""),
+ ('breaks the whole system', """renders the entire system unusable (e.g.,
+ unbootable, unable to reach a multiuser runlevel, etc.)"""),
+ ('causes serious data loss', """causes loss of important, irreplaceable
+ data"""),
+ ('root security hole', """introduces a security hole allowing access to
+ root (or another privileged system account), or data normally
+ accessible only by such accounts"""),
+ ('unknown', """not sure, or none of the above"""),
+ ),
+ 'grave' : (
+ ('renders package unusable', """renders the package unusable, or mostly
+ so, on all or nearly all possible systems on which it could be installed
+ (i.e., not a hardware-specific bug); or renders package uninstallable
+ or unremovable without special effort"""),
+ ('causes non-serious data loss', """causes the loss of data on the system
+ that is unimportant, or restorable without resorting to backup media"""),
+ ('user security hole', """introduces a security hole allowing access to
+ user accounts or data not normally accessible"""),
+ ('unknown', """not sure, or none of the above"""),
+ )
+ }
+
+
+# Ordering for justifications
+JUSTORDER = {
+ 'critical' : ['breaks unrelated software',
+ 'breaks the whole system',
+ 'causes serious data loss',
+ 'root security hole',
+ 'unknown'],
+ 'grave' : ['renders package unusable',
+ 'causes non-serious data loss',
+ 'user security hole',
+ 'unknown']
+ }
+
+SEVERITIES_gnats = {
+ 'critical' : 'The product, component or concept is completely'
+ 'non-operational or some essential functionality is missing. No'
+ 'workaround is known.',
+ 'serious' : 'The product, component or concept is not working'
+ 'properly or significant functionality is missing. Problems that'
+ 'would otherwise be considered ''critical'' are rated ''serious'' when'
+ 'a workaround is known.',
+ 'non-critical' : 'The product, component or concept is working'
+ 'in general, but lacks features, has irritating behavior, does'
+ 'something wrong, or doesn''t match its documentation.',
+ }
+
+# Rank order of severities, for sorting
+SEVLIST = ['critical', 'grave', 'serious', 'important', 'does-not-build',
+ 'normal', 'non-critical', 'minor', 'wishlist', 'fixed']
+
+def convert_severity(severity, type='debbugs'):
+ "Convert severity names if needed."
+ if type == 'debbugs':
+ return {'non-critical' : 'normal'}.get(severity, severity)
+ elif type == 'gnats':
+ return {'grave' : 'critical',
+ 'important' : 'serious',
+ 'normal' : 'non-critical',
+ 'minor' : 'non-critical',
+ 'wishlist' : 'non-critical'}.get(severity, severity)
+ else:
+ return severity
+
+# These packages are virtual in Debian; we don't look them up...
+debother = {
+ 'base' : 'General bugs in the base system',
+# Actually a real package, but most people don't have boot-floppies installed for good reason
+# 'boot-floppy' : '(Obsolete, please use boot-floppies instead.)',
+ 'boot-floppies' : 'Bugs in the woody installation subsystem',
+ 'bugs.debian.org' : 'The bug tracking system, @bugs.debian.org',
+ 'cdimage.debian.org' : 'CD Image issues',
+ 'cdrom' : 'Problems with installation from CD-ROMs',
+# dpkg-iwj -- The dpkg branch maintained by Ian Jackson
+ 'debian-policy' : 'Proposed changes in the Debian policy documentation',
+ 'ftp.debian.org' : 'Problems with the FTP site',
+ 'general' : 'General problems (e.g., that many manpages are mode 755)',
+ 'install' : 'Problems with the sarge installer.',
+ 'installation' : 'General installation problems not covered otherwise.',
+# 'kernel' : '(Obsolete, please use "linux-image" instead.)',
+ 'linux-image' : 'Problems with the Linux kernel, or the kernel shipped with Debian',
+ 'listarchives' : 'Problems with the WWW mailing list archives',
+ 'lists.debian.org' : 'The mailing lists, debian-*@lists.debian.org.',
+ 'mirrors' : 'Problems with Debian archive mirrors.',
+ 'nonus.debian.org' : 'Problems with the non-US FTP site',
+ 'press' : 'Press release issues',
+ 'project' : 'Problems related to Project administration',
+ 'qa.debian.org' : 'Problems related to the quality assurance group',
+#slink-cd -- Slink CD
+#spam -- Spam (reassign spam to here so we can complain about it)
+ 'security.debian.org' : 'Problems with the security updates server',
+ 'upgrade-reports' : 'Reports of successful and unsucessful upgrades',
+ 'wnpp' : 'Work-Needing and Prospective Packages list',
+ 'www.debian.org' : 'Problems with the WWW site (including other *.debian.org sites)'
+ }
+
+progenyother = {
+ 'debian-general' : 'Any non-package-specific bug',
+ }
+
+def handle_wnpp(package, bts, ui, fromaddr, online=True, http_proxy=None):
+ desc = body = ''
+ headers = []
+ pseudos = []
+ query = True
+
+ tag = ui.menu('What sort of request is this? (If none of these '
+ 'things mean anything to you, or you are trying to report '
+ 'a bug in an existing package, please press Enter to '
+ 'exit reportbug.)', {
+ 'O' :
+ "The package has been `Orphaned'. It needs a new maintainer as soon as possible.",
+ 'RFA' :
+ "This is a `Request for Adoption'. Due to lack of time, resources, interest or something similar, the current maintainer is asking for someone else to maintain this package. He/she will maintain it in the meantime, but perhaps not in the best possible way. In short: the package needs a new maintainer.",
+ 'RFH' :
+ "This is a `Request For Help'. The current maintainer wants to continue to maintain this package, but he/she needs some help to do this, because his/her time is limited or the package is quite big and needs several maintainers.",
+ 'ITP' :
+ "This is an `Intent To Package'. Please submit a package description along with copyright and URL in such a report.",
+ 'RFP' :
+ "This is a `Request For Package'. You have found an interesting piece of software and would like someone else to maintain it for Debian. Please submit a package description along with copyright and URL in such a report.",
+ }, 'Choose the request type: ', empty_ok=True)
+ if not tag:
+ ui.long_message('To report a bug in a package, use the name of the package, not wnpp.\n')
+ raise SystemExit
+
+ if tag in ('RFP', 'ITP'):
+ prompt = 'Please enter the proposed package name: '
+ else:
+ prompt = 'Please enter the name of the package: '
+ package = ui.get_string(prompt)
+ if not package: return
+
+ ui.ewrite('Checking status database...\n')
+ info = reportbug.get_package_status(package)
+ available = info[1]
+
+ severity = 'normal'
+ if tag in ('ITP', 'RFP'):
+ if available and (not online or checkversions.check_available(
+ package, '0', http_proxy=http_proxy)):
+ if not ui.yes_no(
+ ('A package called %s already appears to exist (at least on '
+ 'your system); continue?' % package),
+ 'Ignore this problem and continue. If you have '
+ 'already locally created a package with this name, this '
+ 'warning message may have been produced in error.',
+ 'Exit without filing a report.', default=0):
+ sys.exit(1)
+
+ severity = 'wishlist'
+
+ desc = ui.get_string(
+ 'Please briefly describe this package; this should be an '
+ 'appropriate short description for the eventual package: ')
+ if not desc:
+ return
+
+ if tag == 'ITP':
+ headers.append('X-Debbugs-CC: deb...@li...')
+ pseudos.append('Owner: %s' % fromaddr)
+ ui.ewrite('Your report will be carbon-copied to debian-devel, '
+ 'per Debian policy.\n')
+
+ body = """* Package name : %s
+ Version : x.y.z
+ Upstream Author : Name <som...@ex...>
+* URL : http://www.example.org/
+* License : (GPL, LGPL, BSD, MIT/X, etc.)
+ Programming Lang: (C, C++, C#, Perl, Python, etc.)
+ Description : %s
+
+(Include the long description here.)
+""" % (package, desc)
+ elif tag in ('O', 'RFA', 'RFH'):
+ severity = 'normal'
+ query = False
+ if not available:
+ info = reportbug.get_source_package(package)
+ if info:
+ info = reportbug.get_package_status(info[0][0])
+
+ if not info:
+ cont = ui.select_options(
+ "This package doesn't appear to exist; continue?",
+ 'yN', {'y': 'Ignore this problem and continue.',
+ 'n': 'Exit without filing a report.' })
+ if cont == 'n':
+ sys.exit(1)
+ desc = fulldesc = ''
+ else:
+ desc = info[11] or ''
+ package = info[12] or package
+ fulldesc = info[13]
+
+ if tag == 'O' and info and info[9] in \
+ ('required', 'important', 'standard'):
+ severity = 'important'
+
+ if tag == 'RFH':
+ headers.append('X-Debbugs-CC: deb...@li...')
+ ui.ewrite('Your request will be carbon-copied to debian-devel, '
+ 'per Debian policy.\n')
+
+ if fulldesc:
+ orphstr = 'intend to orphan'
+ if tag == 'RFA':
+ orphstr = 'request an adopter for'
+ elif tag == 'RFH':
+ orphstr = 'request assistance with maintaining'
+
+ body = ('I %s the %s package.\n\n'
+ 'The package description is:\n') % (orphstr, package)
+ body = body + fulldesc + '\n'
+
+ if desc:
+ subject = '%s: %s -- %s' % (tag, package, desc)
+ else:
+ subject = '%s: %s' % (tag, package)
+
+ return (subject, severity, headers, pseudos, body, query)
+
+# Supported servers
+# Theoretically support for GNATS and Jitterbug could be added here.
+SYSTEMS = { 'debian' :
+ { 'name' : 'Debian', 'email': '%s...@bu...',
+ 'btsroot' : 'http://www.debian.org/Bugs/',
+ 'otherpkgs' : debother,
+ 'nonvirtual' : ['linux-image', 'kernel-image'],
+ 'specials' : { 'wnpp': handle_wnpp },
+ # Dependency packages
+ 'deppkgs' : ('gcc', 'g++', 'cpp', 'gcj', 'gpc', 'gobjc',
+ 'chill', 'gij', 'g77', 'python', 'python-base',
+ 'x-window-system-core', 'x-window-system'),
+ 'cgiroot' : 'http://bugs.debian.org/cgi-bin/' },
+ 'kde' :
+ { 'name' : 'KDE Project', 'email': '%s...@bu...',
+ 'btsroot': 'http://bugs.kde.org/' },
+ 'mandrake' :
+ { 'name' : 'Linux-Mandrake', 'email': '%s...@bu...',
+ 'type' : 'mailto', 'query-dpkg' : False },
+ 'gnome' :
+ { 'name' : 'GNOME Project', 'email': '%s...@bu...',
+ 'type' : 'mailto', 'query-dpkg' : False },
+ 'ximian' :
+ { 'name' : 'Ximian', 'email': '%s...@bu...',
+ 'type' : 'mailto' },
+ 'progeny' :
+ { 'name' : 'Progeny', 'email' : 'bu...@pr...',
+ 'type' : 'gnats', 'otherpkgs' : progenyother },
+ 'ubuntu' :
+ { 'name' : 'Ubuntu', 'email' : 'ubu...@li...',
+ 'type' : 'mailto' },
+ 'guug' :
+ { 'name' : 'GUUG (German Unix User Group)',
+ 'email' : '%s...@bu...', 'query-dpkg' : False },
+ 'grml' :
+ { 'name' : 'grml', 'email': '%s...@bu...',
+ 'btsroot' : 'http://bugs.grml.org/',
+ 'cgiroot' : 'http://bugs.grml.org/cgi-bin/' },
+ }
+
+SYSTEMS['helixcode'] = SYSTEMS['ximian']
+
+CLASSES = {
+ 'sw-bug' : 'The problem is a bug in the software or code. For'
+ 'example, a crash would be a sw-bug.',
+ 'doc-bug' : 'The problem is in the documentation. For example,'
+ 'an error in a man page would be a doc-bug.',
+ 'change-request' : 'You are requesting a new feature or a change'
+ 'in the behavior of software, or are making a suggestion. For'
+ 'example, if you wanted reportbug to be able to get your local'
+ 'weather forecast, as well as report bugs, that would be a'
+ 'change-request.',
+ }
+
+CLASSLIST = ['sw-bug', 'doc-bug', 'change-request']
+
+CRITICAL_TAGS = {
+ 'security' : 'This problem is a security vulnerability in Debian.',
+}
+
+TAGS = {
+ 'patch' : 'You are including a patch to fix this problem.',
+## 'upstream' : 'You believe this problem is not specific to Debian.',
+## 'potato' : 'This bug only applies to the potato release (Debian 2.2).',
+## 'woody' : 'This bug only applies to the woody release (Debian 3.0).',
+## 'sarge' : 'This bug only applies to the sarge release (Debian 3.1).',
+## 'sid' : 'This bug only applies to the unstable branch of Debian.',
+ "l10n" : "This bug reports a localization/internationalization issue.",
+## 'done' : 'No more tags.',
+ }
+
+EXTRA_TAGS = ['potato', 'woody', 'sarge', 'security', 'sid', 'upstream']
+
+TAGLIST = ['l10n', 'patch']
+CRITICAL_TAGLIST = ['security']
+
+def yn_bool(setting):
+ if setting:
+ if str(setting) == 'no':
+ return 'no'
+ return 'yes'
+ else:
+ return 'no'
+
+def cgi_report_url(system, number, archived=False, mbox=False):
+ root = SYSTEMS[system].get('cgiroot')
+ if root:
+ return '%sbugreport.cgi?bug=%d&archived=%s&mbox=%s' % (
+ root, number, archived, yn_bool(mbox))
+ return None
+
+def cgi_package_url(system, package, archived=False, source=False,
+ repeatmerged=True, version=None):
+ root = SYSTEMS[system].get('cgiroot')
+ if not root: return None
+
+ #package = urllib.quote_plus(package.lower())
+ if source:
+ query = {'src' : package.lower()}
+ else:
+ query = {'pkg' : package.lower()}
+
+ query['repeatmerged'] = yn_bool(repeatmerged)
+ query['archived'] = yn_bool(archived)
+
+ if version:
+ query['version'] = str(version)
+
+ qstr = urllib.urlencode(query)
+ #print qstr
+ return '%spkgreport.cgi?%s' % (root, qstr)
+
+def package_url(system, package, mirrors=None, source=False,
+ repeatmerged=True):
+ btsroot=get_btsroot(system, mirrors)
+ package = urllib.quote_plus(package.lower())
+ return btsroot+('db/pa/l%s.html' % package)
+
+def report_url(system, number, mirrors=None):
+ number = str(number)
+ if len(number) < 2: return None
+ btsroot=get_btsroot(system, mirrors)
+ return btsroot+('db/%s/%s.html' % (number[:2], number))
+
+def get_package_url(system, package, mirrors=None, source=False,
+ archived=False, repeatmerged=True):
+ return (cgi_package_url(system, package, archived, source, repeatmerged) or
+ package_url(system, package, mirrors, source, repeatmerged))
+
+def get_report_url(system, number, mirrors=None, archived=False, mbox=False):
+ return (cgi_report_url(system, number, archived, mbox) or
+ report_url(system, number, mirrors))
+
+def parse_bts_url(url):
+ bits = url.split(':', 1)
+ if len(bits) != 2: return None
+
+ type, loc = bits
+ if loc.startswith('//'): loc = loc[2:]
+ while loc.endswith('/'): loc = loc[:-1]
+ return type, loc
+
+# Dynamically add any additional systems found
+for origin in glob.glob('/etc/dpkg/origins/*'):
+ try:
+ ...
[truncated message content] |
|
From: <rit...@us...> - 2007-04-25 14:55:41
|
Revision: 137
http://svn.sourceforge.net/pypt-offline/?rev=137&view=rev
Author: riteshsarraf
Date: 2007-04-25 07:55:41 -0700 (Wed, 25 Apr 2007)
Log Message:
-----------
* This should be better. Most files which aren't required for bug details fetch
are not required for my purpose. Also there are minor import modifications in
debianbts.py because I don't need the full reportbug suite.
* This hopefully should be the final package selection
Modified Paths:
--------------
trunk/debianbts.py
trunk/fetch_bugs.py
trunk/pypt_core.py
Removed Paths:
-------------
trunk/checkversions.py
trunk/reportbug.py
Deleted: trunk/checkversions.py
===================================================================
--- trunk/checkversions.py 2007-04-25 14:18:34 UTC (rev 136)
+++ trunk/checkversions.py 2007-04-25 14:55:41 UTC (rev 137)
@@ -1,334 +0,0 @@
-#
-# checkversions.py - Find if the installed version of a package is the latest
-#
-# Written by Chris Lawrence <law...@de...>
-# (C) 2002-06 Chris Lawrence
-#
-# This program is freely distributable per the following license:
-#
-## Permission to use, copy, modify, and distribute this software and its
-## documentation for any purpose and without fee is hereby granted,
-## provided that the above copyright notice appears in all copies and that
-## both that copyright notice and this permission notice appear in
-## supporting documentation.
-##
-## I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
-## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
-## BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-## DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-## WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-## ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-## SOFTWARE.
-#
-# $Id: checkversions.py,v 1.6.2.3 2006/10/16 18:52:41 lawrencc Exp $
-#
-# Version 3.35; see changelog for revision history
-
-import sgmllib
-#import HTMLParser
-
-import os, re, sys, urllib2
-from urlutils import open_url
-from reportbug_exceptions import *
-
-PACKAGES_URL = 'http://packages.debian.org/%s'
-INCOMING_URL = 'http://incoming.debian.org/'
-NEWQUEUE_URL = 'http://ftp-master.debian.org/new.html'
-
-# The format is an unordered list
-
-class BaseParser(sgmllib.SGMLParser):
- def __init__(self):
- sgmllib.SGMLParser.__init__(self)
- self.savedata = None
-
- # --- Formatter interface, taking care of 'savedata' mode;
- # shouldn't need to be overridden
-
- def handle_data(self, data):
- if self.savedata is not None:
- self.savedata = self.savedata + data
-
- # --- Hooks to save data; shouldn't need to be overridden
- def save_bgn(self):
- self.savedata = ''
-
- def save_end(self, mode=0):
- data = self.savedata
- self.savedata = None
- if not mode and data is not None: data = ' '.join(data.split())
- return data
-
-class PackagesParser(BaseParser):
- def __init__(self, arch='i386'):
- BaseParser.__init__(self)
- self.versions = {}
- self.row = None
- arch = r'\s(all|'+re.escape(arch)+r')\b'
- self.arch = re.compile(arch)
- self.dist = None
-
- def start_li(self, attrs):
- if self.row is not None:
- self.end_li()
- self.row = []
-
- def start_a(self, attrs):
- if self.row is not None:
- self.save_bgn()
-
- def end_a(self):
- if self.row is not None and self.savedata:
- self.dist = self.save_end()
-
- def lineend(self):
- line = self.save_end().strip()
- if self.arch.search(line):
- version = line.split(': ', 1)
- self.versions[self.dist] = version[0]
-
- def start_br(self, attrs):
- if self.savedata:
- self.lineend()
- self.save_bgn()
-
- def end_li(self):
- if self.savedata:
- self.lineend()
- self.row = None
-
-class IncomingParser(sgmllib.SGMLParser):
- def __init__(self, package, arch='i386'):
- sgmllib.SGMLParser.__init__(self)
- self.found = []
- self.savedata = None
- arch = r'(?:all|'+re.escape(arch)+')'
- self.package = re.compile(re.escape(package)+r'_([^_]+)_'+arch+'.deb')
-
- def start_a(self, attrs):
- for attrib, value in attrs:
- if attrib.lower() != 'href':
- continue
-
- mob = self.package.match(value)
- if mob:
- self.found.append(mob.group(1))
-
-class NewQueueParser(BaseParser):
- def __init__(self, package, arch='i386'):
- BaseParser.__init__(self)
- self.package = package
- self.row = None
- arch = r'\s(all|'+re.escape(arch)+r')\b'
- self.arch = re.compile(arch)
- self.versions = {}
-
- def start_tr (self, attrs):
- for name, value in attrs:
- if name == 'class' and value in ("odd", "even"):
- self.row = []
-
- def end_tr (self):
- if self.row is not None:
- # row (name, versions, architectures, distribution)
- dist = "%s (new queue)" % self.row[3]
- for version in self.row[1].split():
- self.versions[dist] = version
- self.row = None
-
- def start_td (self, attrs):
- if self.row is None:
- return
- self.save_bgn()
-
- def end_td (self):
- if self.row is None:
- return
- data = self.save_end()
- l = len(self.row)
- if l == 0:
- # package name
- if self.package == data:
- # found package name
- self.row.append(data)
- else:
- self.row = None
- elif l == 2:
- # architecture
- if self.arch.search(data):
- self.row.append(data)
- else:
- self.row = None
- else:
- self.row.append(data)
-
-def compare_versions(current, upstream):
- """Return 1 if upstream is newer than current, -1 if current is
- newer than upstream, and 0 if the same."""
- if not upstream: return 0
- rc = os.system('dpkg --compare-versions %s lt %s' % (current, upstream))
- rc2 = os.system('dpkg --compare-versions %s gt %s' % (current, upstream))
- if not rc:
- return 1
- elif not rc2:
- return -1
- return 0
-
-def later_version(a, b):
- if compare_versions(a, b) > 0:
- return b
- return a
-
-def get_versions_available(package, dists=None, http_proxy=None, arch='i386'):
- if not dists:
- dists = ('stable', 'testing', 'unstable')
-
- try:
- page = open_url(PACKAGES_URL % package, http_proxy)
- except NoNetwork:
- return {}
- except urllib2.HTTPError, x:
- print >> sys.stderr, "Warning:", x
- return {}
- if not page:
- return {}
-
- parser = PackagesParser(arch)
- for line in page:
- parser.feed(line)
- parser.close()
- try:
- page.fp._sock.recv = None
- except:
- pass
- page.close()
-
-## content = page.read()
-## parser.feed(content)
-## parser.close()
-## page.close()
-
- versions = {}
- for dist in dists:
- if dist in parser.versions:
- versions[dist] = parser.versions[dist]
- del parser
- del page
-
- return versions
-
-def get_newqueue_available(package, dists=None, http_proxy=None, arch='i386'):
- if dists is None:
- dists = ('unstable (new queue)', )
- try:
- page = open_url(NEWQUEUE_URL, http_proxy)
- except NoNetwork:
- return {}
- except urllib2.HTTPError, x:
- print >> sys.stderr, "Warning:", x
- return {}
- if not page:
- return {}
- parser = NewQueueParser(package, arch)
- for line in page:
- parser.feed(line)
- parser.close()
- try:
- page.fp._sock.recv = None
- except:
- pass
- page.close()
-
- #print repr(page)
-
- versions = {}
- for dist in dists:
- if dist in parser.versions:
- versions[dist] = parser.versions[dist]
-
- del parser
- del page
- #print 'HERE', gc.garbage
- return versions
-
-def get_incoming_version(package, http_proxy=None, arch='i386'):
- try:
- page = open_url(INCOMING_URL, http_proxy)
- except NoNetwork:
- return None
- except urllib2.HTTPError, x:
- print >> sys.stderr, "Warning:", x
- return None
- if not page:
- return None
-
- parser = IncomingParser(package, arch)
- for line in page:
- parser.feed(line)
- parser.close()
- try:
- page.fp._sock.recv = None
- except:
- pass
- page.close()
-
- if parser.found:
- found = parser.found
- del parser
- return reduce(later_version, found, '0')
-
- del page
- del parser
- return None
-
-import gc
-def check_available(package, version, dists=None, check_incoming=True,
- check_newqueue=True,
- http_proxy=None, arch='i386'):
- avail = {}
-
- if check_incoming:
- iv = get_incoming_version(package, http_proxy, arch)
- if iv:
- avail['incoming'] = iv
- stuff = get_versions_available(package, dists, http_proxy, arch)
- avail.update(stuff)
- if check_newqueue:
- import reportbug
- srcpackage = reportbug.get_source_name(package)
- if srcpackage is None:
- srcpackage = package
- stuff = get_newqueue_available(srcpackage, dists, http_proxy, arch)
- avail.update(stuff)
- #print gc.garbage, stuff
-
- new = {}
- newer = 0
- for dist in avail:
- if dist == 'incoming':
- if ':' in version:
- ver = version.split(':', 1)[1]
- else:
- ver = version
- comparison = compare_versions(ver, avail[dist])
- else:
- comparison = compare_versions(version, avail[dist])
- if comparison > 0:
- new[dist] = avail[dist]
- elif comparison < 0:
- newer += 1
- too_new = (newer and newer == len(avail))
- return new, too_new
-
-if __name__=='__main__':
- import time
- import gc
-
- gc.set_debug(gc.DEBUG_LEAK)
- print get_newqueue_available('reportbug')
- print gc.garbage
- print check_available('reportbug', '3.7', arch='s390')
- #print check_available('openssh-server', '1:4.2p1-8', arch='i386')
- #print check_available('openssh-server', '1:4.2p1-8', arch='kfreebsd-i386')
- time.sleep(1000)
- #print check_available('dpkg', '1.10.2', arch='sparc')
Modified: trunk/debianbts.py
===================================================================
--- trunk/debianbts.py 2007-04-25 14:18:34 UTC (rev 136)
+++ trunk/debianbts.py 2007-04-25 14:55:41 UTC (rev 137)
@@ -24,7 +24,7 @@
#
# $Id: debianbts.py,v 1.24.2.7 2006/10/16 17:14:03 lawrencc Exp $
-import sgmllib, glob, os, re, reportbug, rfc822, time, urllib, checkversions
+import sgmllib, glob, os, re, rfc822, time, urllib
from urlutils import open_url
import sys
Modified: trunk/fetch_bugs.py
===================================================================
--- trunk/fetch_bugs.py 2007-04-25 14:18:34 UTC (rev 136)
+++ trunk/fetch_bugs.py 2007-04-25 14:55:41 UTC (rev 137)
@@ -2,13 +2,11 @@
import sys
import string
-sys.path.append('/usr/share/reportbug')
import debianbts
package = "sl"
-bug_dict = {}
bug_list = []
-file = "/tmp/bug_report.txt"
+file = "C:\\bug_report.txt"
file_handle = open(file, 'w')
(num_of_bugs, header, bugs_list) = debianbts.get_reports(package)
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-04-25 14:18:34 UTC (rev 136)
+++ trunk/pypt_core.py 2007-04-25 14:55:41 UTC (rev 137)
@@ -282,6 +282,32 @@
return False
+def FetchBugReportsDebian(PackageName, FileHandle):
+ try:
+ import debianbts
+ except ImportError:
+ return False
+
+ bug_list = []
+ file_handle = open("FileHandle", 'w')
+
+ (num_of_bugs, header, bugs_list) = debianbts.get_reports(package)
+
+ if num_of_bugs:
+ for x in bugs_list:
+ (sub_bugs_header, sub_bugs_list) = x
+ for x in sub_bugs_list:
+ break_bugs = x.split(':')
+ bug_num = string.lstrip(break_bugs[0], '#')
+ data = debianbts.get_report(bug_num, followups=True)
+ file_handle.write(data[0] + "\n\n")
+ for x in data[1]:
+ file_handle.write(x)
+ file_handle.write("\n")
+ file_handle.write("\n\n\n")
+ file_handle.flush()
+
+
def files(root):
for path, folders, files in os.walk(root):
for file in files:
Deleted: trunk/reportbug.py
===================================================================
--- trunk/reportbug.py 2007-04-25 14:18:34 UTC (rev 136)
+++ trunk/reportbug.py 2007-04-25 14:55:41 UTC (rev 137)
@@ -1,1026 +0,0 @@
-#
-# Reportbug module - common functions for reportbug and greportbug
-# Written by Chris Lawrence <law...@de...>
-# Copyright (C) 1999-2006 Chris Lawrence
-#
-# This program is freely distributable per the following license:
-#
-## Permission to use, copy, modify, and distribute this software and its
-## documentation for any purpose and without fee is hereby granted,
-## provided that the above copyright notice appears in all copies and that
-## both that copyright notice and this permission notice appear in
-## supporting documentation.
-##
-## I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
-## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
-## BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-## DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-## WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-## ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-## SOFTWARE.
-#
-# Version 3.35; see changelog for revision history
-#
-# $Id: reportbug.py,v 1.35.2.18 2007/04/08 03:22:21 lawrencc Exp $
-
-VERSION = "reportbug 3.35"
-VERSION_NUMBER = "3.35"
-COPYRIGHT = VERSION + '\nCopyright (C) 1999-2006 Chris Lawrence <law...@de...>'
-
-import time, sys, os, locale, re, pwd, commands, shlex, debianbts, rfc822
-import socket
-import pprint
-import subprocess
-
-from string import ascii_letters, digits
-
-# Paths for dpkg
-DPKGLIB = '/var/lib/dpkg'
-AVAILDB = os.path.join(DPKGLIB, 'available')
-STATUSDB = os.path.join(DPKGLIB, 'status')
-
-# Headers other than these become email headers for debbugs servers
-PSEUDOHEADERS = ('Package', 'Version', 'Severity', 'File', 'Tags',
- 'Justification', 'Followup-For', 'Owner')
-
-VALID_UIS = ['newt', 'text', 'gnome2', 'urwid']
-AVAILABLE_UIS = []
-for ui in VALID_UIS:
- pkgname = 'reportbug_ui_%s.py' % ui
- for d in sys.path:
- if os.path.exists(os.path.join(d, pkgname)):
- AVAILABLE_UIS.append(ui)
- break
-
-UIS = {'text': 'A text-oriented console interface',
- 'urwid': 'A menu-based console interface',
- 'gnome2': 'A graphical (Gnome 2) interface'}
-
-MODES = {'novice': 'Offer simple prompts, bypassing technical questions.',
- 'standard': 'Offer more extensive prompts, including asking about '
- 'things that a moderately sophisticated user would be expected to '
- 'know about Debian.',
- 'advanced' : 'Like standard, but assumes you know a bit more about '
- 'Debian, including "incoming".',
- 'expert': 'Bypass most handholding measures and preliminary triage '
- 'routines. This mode should not be used by people unfamiliar with '
- 'Debian\'s policies and operating procedures.'}
-MODELIST = ['novice', 'standard', 'advanced', 'expert']
-for mode in MODELIST:
- exec 'MODE_%s=%d' % (mode.upper(), MODELIST.index(mode))
-del mode
-
-NEWBIELINE = '*** Please type your report below this line ***'
-
-fhs_directories = ['/', '/usr', '/usr/share', '/var', '/usr/X11R6',
- '/usr/man', '/usr/doc', '/usr/bin']
-
-def realpath(filename):
- filename = os.path.abspath(filename)
-
- bits = filename.split('/')
- for i in range(2, len(bits)+1):
- component = '/'.join(bits[0:i])
- if component in fhs_directories:
- continue
-
- if os.path.islink(component):
- resolved = os.readlink(component)
- (dir, file) = os.path.split(component)
- resolved = os.path.normpath(os.path.join(dir, resolved))
- newpath = apply(os.path.join, [resolved] + bits[i:])
- return realpath(newpath)
-
- return filename
-
-pathdirs = ['/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/X11R6/bin',
- '/usr/games']
-
-def search_path_for(filename):
- d, f = os.path.split(filename)
- if d: return realpath(filename)
-
- path = os.environ.get("PATH", os.defpath).split('/')
- for d in pathdirs:
- if not d in path:
- path.append(d)
-
- for d in path:
- fullname = os.path.join(d, f)
- if os.path.exists(fullname):
- return realpath(fullname)
- return None
-
-def glob_escape(filename):
- filename = re.sub(r'([*?\[\]])', r'\\\1', filename)
- return filename
-
-def search_pipe(searchfile, use_dlocate=True):
- arg = commands.mkarg(searchfile)
- if use_dlocate and os.path.exists('/usr/bin/dlocate'):
- pipe = os.popen('COLUMNS=79 dlocate -S %s 2>/dev/null' % arg)
- else:
- use_dlocate = False
- pipe = os.popen('COLUMNS=79 dpkg --search %s 2>/dev/null' % arg)
- return (pipe, use_dlocate)
-
-def query_dpkg_for(filename, use_dlocate=True):
- try:
- x = os.getcwd()
- except OSError:
- os.chdir('/')
- searchfilename = glob_escape(filename)
- (pipe, dlocate_used) = search_pipe(searchfilename)
- packages = {}
-
- for line in pipe:
- line = line.strip()
- # Ignore diversions
- if 'diversion by' in line: continue
-
- (package, path) = line.split(':', 1)
- path = path.strip()
- packlist = package.split(', ')
- for package in packlist:
- if packages.has_key(package):
- packages[package].append(path)
- else:
- packages[package] = [path]
- pipe.close()
- # Try again without dlocate if no packages found
- if not packages and dlocate_used:
- return query_dpkg_for(filename, use_dlocate=False)
-
- return filename, packages
-
-def find_package_for(filename, pathonly=False):
- """Find the package(s) containing this file."""
- packages = {}
- if filename[0] == '/':
- fn, pkglist = query_dpkg_for(filename)
- if pkglist: return fn, pkglist
-
- newfilename = search_path_for(filename)
- if pathonly and not newfilename:
- return (filename, None)
- return query_dpkg_for(newfilename or filename)
-
-def find_rewritten(username):
- for filename in ['/etc/email-addresses']:
- if os.path.exists(filename):
- try:
- fp = file(filename)
- except IOError:
- continue
- for line in fp:
- line = line.strip().split('#')[0]
- if not line:
- continue
- try:
- name, alias = line.split(':')
- if name.strip() == username:
- return alias.strip()
- except ValueError:
- print 'Invalid entry in %s' % filename
- return None
-
-def get_email_addr(addr):
- addr = rfc822.AddressList(addr)
- return addr.addresslist[0]
-
-def get_email(email='', realname=''):
- return get_email_addr(get_user_id(email, realname))
-
-def get_user_id(email='', realname='', charset='utf-8'):
- uid = os.getuid()
- info = pwd.getpwuid(uid)
- email = (os.environ.get('REPORTBUGEMAIL', email) or
- os.environ.get('DEBEMAIL') or os.environ.get('EMAIL'))
-
- email = email or find_rewritten(info[0]) or info[0]
-
- if '@' not in email:
- if os.path.exists('/etc/mailname'):
- domainname = file('/etc/mailname').readline().strip()
- else:
- domainname = socket.getfqdn()
-
- email = email+'@'+domainname
-
- # Handle EMAIL if it's formatted as 'Bob <bob@host>'.
- if '<' in email or '(' in email:
- realname, email = get_email_addr(email)
-
- if not realname:
- realname = (os.environ.get('DEBFULLNAME') or os.environ.get('DEBNAME')
- or os.environ.get('NAME'))
- if not realname:
- realname = info[4].split(',', 1)[0]
- # Convert & in gecos field 4 to capitalized logname: #224231
- realname = realname.replace('&', info[0].upper())
-
- if not realname:
- return email
-
- # Decode the realname from the charset -
- # but only if it is not already in Unicode
- if isinstance(realname, str):
- realname = realname.decode(charset, 'replace')
-
- if re.match(r'[\w\s]+$', realname):
- return '%s <%s>' % (realname, email)
-
- return rfc822.dump_address_pair( (realname, email) )
-
-statuscache = {}
-def get_package_status(package, avail=False):
- if not avail and package in statuscache:
- return statuscache[package]
-
- versionre = re.compile('Version: ')
- packagere = re.compile('Package: ')
- priorityre = re.compile('Priority: ')
- dependsre = re.compile('(Pre-)?Depends: ')
- recsre = re.compile('Recommends: ')
- conffilesre = re.compile('Conffiles: ')
- maintre = re.compile('Maintainer: ')
- statusre = re.compile('Status: ')
- originre = re.compile('Origin: ')
- bugsre = re.compile('Bugs: ')
- descre = re.compile('Description: ')
- fullre = re.compile(' ')
- srcre = re.compile('Source: ')
-
- pkgversion = pkgavail = maintainer = status = origin = None
- bugs = vendor = priority = desc = src_name = None
- conffiles = []
- fulldesc = []
- depends = []
- recommends = []
- confmode = False
- state = ''
-
- try:
- x = os.getcwd()
- except OSError:
- os.chdir('/')
-
- packarg = commands.mkarg(package)
- if avail:
- output = commands.getoutput(
- "COLUMNS=79 dpkg --print-avail %s 2>/dev/null" % packarg)
- else:
- output = commands.getoutput(
- "COLUMNS=79 dpkg --status %s 2>/dev/null" % packarg)
-
- # dpkg output is in UTF-8 format
- output = output.decode('utf-8', 'replace')
-
- for line in output.split(os.linesep):
- line = line.rstrip()
- if not line: continue
-
- if confmode:
- if line[0] != '/':
- confmode = False
- else:
- conffiles = conffiles + (line.split(),)
-
- if versionre.match(line):
- (crud, pkgversion) = line.split(": ", 1)
- elif statusre.match(line):
- (crud, status) = line.split(": ", 1)
- elif priorityre.match(line):
- (crud, priority) = line.split(": ", 1)
- elif packagere.match(line):
- (crud, pkgavail) = line.split(": ", 1)
- elif originre.match(line):
- (crud, origin) = line.split(": ", 1)
- elif bugsre.match(line):
- (crud, bugs) = line.split(": ", 1)
- elif descre.match(line):
- (crud, desc) = line.split(": ", 1)
- elif dependsre.match(line):
- (crud, thisdepends) = line.split(": ", 1)
- # Remove versioning crud
- thisdepends = [[y.split()[0] for y in x.split('|')]
- for x in (thisdepends.split(', '))]
- depends.extend(thisdepends)
- elif recsre.match(line):
- (crud, thisdepends) = line.split(": ", 1)
- # Remove versioning crud
- thisdepends = [[y.split()[0] for y in x.split('|')]
- for x in (thisdepends.split(', '))]
- recommends.extend(thisdepends)
- elif conffilesre.match(line):
- confmode = True
- elif maintre.match(line):
- crud, maintainer = line.split(": ", 1)
- elif srcre.match(line):
- crud, src_name = line.split(": ", 1)
- src_name = src_name.split()[0]
- elif desc and line[0]==' ':
- fulldesc.append(line)
-
- installed = False
- if status:
- state = status.split()[2]
- installed = (state not in ('config-files', 'not-installed'))
-
- reportinfo = None
- if bugs:
- reportinfo = debianbts.parse_bts_url(bugs)
- elif origin:
- if debianbts.SYSTEMS.has_key(origin):
- vendor = debianbts.SYSTEMS[origin]['name']
- reportinfo = (debianbts.SYSTEMS[origin].get('type', 'debbugs'),
- debianbts.SYSTEMS[origin]['btsroot'])
- else:
- vendor = origin.capitalize()
- else:
- vendor = ''
-
- info = (pkgversion, pkgavail, tuple(depends), tuple(recommends),
- tuple(conffiles),
- maintainer, installed, origin, vendor, reportinfo, priority,
- desc, src_name, os.linesep.join(fulldesc), state)
-
- if not avail:
- statuscache[package] = info
- return info
-
-#dbase = []
-#avail = []
-
-# Object that essentially chunkifies the output of apt-cache dumpavail
-class AvailDB(object):
- def __init__(self, fp=None, popenob=None):
- self.popenob = popenob
- if fp:
- self.fp = fp
- elif popenob:
- self.fp = popenob.stdout
-
- def __iter__(self):
- return self
-
- def next(self):
- chunk = u''
- while True:
- if self.popenob:
- if self.popenob.returncode:
- break
-
- line = self.fp.readline()
- if not line:
- break
-
- if line == '\n':
- return chunk
- chunk += line.decode('utf-8', 'replace')
-
- if chunk:
- return chunk
-
- raise StopIteration
-
- def __del__(self):
- #print >> sys.stderr, 'availdb cleanup', repr(self.popenob), repr(self.fp)
- if self.fp:
- self.fp.close()
- if self.popenob:
- try:
- self.popenob.wait()
- except:
- pass
-
-def get_dpkg_database():
- if os.path.exists(STATUSDB):
- fp = open(STATUSDB)
- if fp:
- return AvailDB(fp=fp)
-
- print >> sys.stderr, 'Unable to open', STATUSDB
- sys.exit(1)
-
-def get_avail_database():
- #print >> sys.stderr, 'Searching available database'
- subp = subprocess.Popen(('apt-cache', 'dumpavail'), stdout=subprocess.PIPE)
- return AvailDB(popenob=subp)
-
-def get_source_package(package):
- """Return any binary packages provided by a source package."""
- packinfo = get_avail_database()
- packages = []
- packob = re.compile(r'^Package: (?P<pkg>.*)$', re.MULTILINE)
- descob = re.compile(r'^Description: (?P<desc>.*)$', re.MULTILINE)
- hassource = re.compile(r'^Source: .*$', re.MULTILINE)
- if package == 'libc':
- searchob1 = re.compile(r'^Source: g?libc[\d.]*$', re.MULTILINE)
- searchob2 = re.compile(r'^Package: g?libc[\d.]*$', re.MULTILINE)
- else:
- searchob1 = re.compile(r'^Source: '+re.escape(package)+r'$',
- re.MULTILINE)
- searchob2 = re.compile(r'^Package: '+re.escape(package)+r'$',
- re.MULTILINE)
-
- for p in packinfo:
- match = searchob1.search(p)
- if match:
- packname = packdesc = ''
- namematch, descmatch = packob.search(p), descob.search(p)
-
- if namematch:
- packname = namematch.group('pkg')
- if descmatch:
- packdesc = descmatch.group('desc')
-
- if packname:
- packages.append( (packname, packdesc) )
- elif hassource.search(p):
- continue
-
- match = searchob2.search(p)
- if match:
- packname = packdesc = ''
- namematch, descmatch = packob.search(p), descob.search(p)
-
- if namematch:
- packname = namematch.group('pkg')
- if descmatch:
- packdesc = descmatch.group('desc')
-
- if packname:
- packages.append( (packname, packdesc) )
-
-
- packages.sort()
- return packages
-
-def get_source_name(package):
- """Return source package name for given package or None."""
- packinfo = get_avail_database()
- has_source = re.compile(r'^Source: %s$' % re.escape(package), re.MULTILINE).search
- get_source = re.compile(r'^Source: (?P<pkg>.*)$', re.MULTILINE).search
- has_package = re.compile(r'^Package: %s$' % re.escape(package), re.MULTILINE).search
- for p in packinfo:
- match = has_source(p)
- if match:
- return package
- if has_package(p):
- match = get_source(p)
- if match:
- return match.group('pkg')
- return None
-
-def get_package_info(packages, skip_notfound=False):
- if not packages:
- return []
-
- packinfo = get_dpkg_database()
- pkgname = r'(?:[\S]+(?:$|,\s+))'
-
- groupfor = {}
- searchpkgs = []
- searchbits = []
- for (group, package) in packages:
- groupfor[package] = group
- escpkg = re.escape(package)
- searchpkgs.append(escpkg)
-
- searchbits = [
- # Package regular expression
- r'^(?P<hdr>Package):\s+('+'|'.join(searchpkgs)+')$',
- # Provides regular expression
- r'^(?P<hdr>Provides):\s+'+pkgname+r'*(?P<pkg>'+'|'.join(searchpkgs)+
- r')(?:$|,\s+)'+pkgname+'*$'
- ]
-
- groups = groupfor.values()
- found = {}
-
- searchobs = [re.compile(x, re.MULTIL...
[truncated message content] |
|
From: <rit...@us...> - 2007-05-01 17:32:28
|
Revision: 138
http://svn.sourceforge.net/pypt-offline/?rev=138&view=rev
Author: riteshsarraf
Date: 2007-05-01 10:32:26 -0700 (Tue, 01 May 2007)
Log Message:
-----------
* Don't fetch "Resolved" bug reports.
Modified Paths:
--------------
trunk/fetch_bugs.py
trunk/pypt_core.py
Modified: trunk/fetch_bugs.py
===================================================================
--- trunk/fetch_bugs.py 2007-04-25 14:55:41 UTC (rev 137)
+++ trunk/fetch_bugs.py 2007-05-01 17:32:26 UTC (rev 138)
@@ -1,26 +1,8 @@
-import os
-import sys
-import string
+from pypt_core import FetchBugReportsDebian
-import debianbts
+package = "bash"
+file = "/tmp/bug_report.txt"
-package = "sl"
-bug_list = []
-file = "C:\\bug_report.txt"
-file_handle = open(file, 'w')
-(num_of_bugs, header, bugs_list) = debianbts.get_reports(package)
-
-if num_of_bugs:
- for x in bugs_list:
- (sub_bugs_header, sub_bugs_list) = x
- for x in sub_bugs_list:
- break_bugs = x.split(':')
- bug_num = string.lstrip(break_bugs[0], '#')
- data = debianbts.get_report(bug_num, followups=True)
- file_handle.write(data[0] + "\n\n")
- for x in data[1]:
- file_handle.write(x)
- file_handle.write("\n")
- file_handle.write("\n\n\n")
- file_handle.flush()
\ No newline at end of file
+if FetchBugReportsDebian(package, file) is True:
+ print "Wrote bug report details for package %s to file %s.\n" % (package, file)
\ No newline at end of file
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-04-25 14:55:41 UTC (rev 137)
+++ trunk/pypt_core.py 2007-05-01 17:32:26 UTC (rev 138)
@@ -289,23 +289,24 @@
return False
bug_list = []
- file_handle = open("FileHandle", 'w')
+ file_handle = open(FileHandle, 'w')
- (num_of_bugs, header, bugs_list) = debianbts.get_reports(package)
+ (num_of_bugs, header, bugs_list) = debianbts.get_reports(PackageName)
if num_of_bugs:
for x in bugs_list:
(sub_bugs_header, sub_bugs_list) = x
- for x in sub_bugs_list:
- break_bugs = x.split(':')
- bug_num = string.lstrip(break_bugs[0], '#')
- data = debianbts.get_report(bug_num, followups=True)
- file_handle.write(data[0] + "\n\n")
- for x in data[1]:
- file_handle.write(x)
- file_handle.write("\n")
- file_handle.write("\n\n\n")
- file_handle.flush()
+ if not "Resolved bugs" in sub_bugs_header:
+ for x in sub_bugs_list:
+ break_bugs = x.split(':')
+ bug_num = string.lstrip(break_bugs[0], '#')
+ data = debianbts.get_report(bug_num, followups=True)
+ file_handle.write(data[0] + "\n\n")
+ for x in data[1]:
+ file_handle.write(x)
+ file_handle.write("\n")
+ file_handle.write("\n" * 3)
+ file_handle.flush()
def files(root):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-05-08 13:27:27
|
Revision: 140
http://svn.sourceforge.net/pypt-offline/?rev=140&view=rev
Author: riteshsarraf
Date: 2007-05-08 06:27:28 -0700 (Tue, 08 May 2007)
Log Message:
-----------
* Added the option for bug fetching
* Minor cosmetic changes
Modified Paths:
--------------
trunk/LICENSE
trunk/pypt_core.py
Modified: trunk/LICENSE
===================================================================
--- trunk/LICENSE 2007-05-04 14:47:18 UTC (rev 139)
+++ trunk/LICENSE 2007-05-08 13:27:28 UTC (rev 140)
@@ -1,4 +1,4 @@
-Copyright (C) 2005, 2006 by Ritesh Raj Sarraf <rr...@re...>
+Copyright (C) 2005 - 2007 Ritesh Raj Sarraf - RESEARCHUT
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-05-04 14:47:18 UTC (rev 139)
+++ trunk/pypt_core.py 2007-05-08 13:27:28 UTC (rev 140)
@@ -28,7 +28,7 @@
'''This is the core module. It does the main job of downloading packages/update packages,\nfiguring out if the packages are in the local cache, handling exceptions and many more stuff'''
-version = "0.6.4"
+version = "0.7.0"
copyright = "(C) 2005 - 2007 Ritesh Raj Sarraf - RESEARCHUT (http://www.researchut.com/)"
errlist = []
@@ -777,6 +777,7 @@
# Print the failed files
if len(errlist) == 0:
+ log.msg("\nAll files have been downloaded.\n")
pass # Don't print if nothing failed.
else:
log.err("\n\nThe following files failed to be downloaded.\n")
@@ -914,6 +915,8 @@
parser.add_option("", "--install-upgrade", dest="install_upgrade",
help="Install the fetched packages to the NONET machine and _upgrade_ the packages on the NONET machine. This command must be executed on the NONET machine",
action="store", type="string", metavar="pypt-offline-upgrade.zip")
+ parser.add_option("", "--fetch-bug-reports", dest="deb_bugs",
+ help="Fetch bug reports from the BTS", action="store_false")
#global options, args
(options, args) = parser.parse_args()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-05-24 12:26:57
|
Revision: 147
http://svn.sourceforge.net/pypt-offline/?rev=147&view=rev
Author: riteshsarraf
Date: 2007-05-24 05:26:56 -0700 (Thu, 24 May 2007)
Log Message:
-----------
* Removed --warnings. One is sufficient
* Changed the BugReport code to a class
* Better logic in the if/else constructs in fetcher() of when to fetch bugreports with zip
Modified Paths:
--------------
trunk/fetch_bugs.py
trunk/pypt_core.py
Modified: trunk/fetch_bugs.py
===================================================================
--- trunk/fetch_bugs.py 2007-05-19 20:50:10 UTC (rev 146)
+++ trunk/fetch_bugs.py 2007-05-24 12:26:56 UTC (rev 147)
@@ -1,8 +1,17 @@
-from pypt_core import FetchBugReportsDebian
+#!/usr/bin/env python
+import pypt_core
+
package = raw_input("Please enter the Debian package name: ")
file = raw_input("Please enter the filename with full path: ")
-if FetchBugReportsDebian(package, file) is True:
- print "Wrote bug report details for package %s to file %s.\n" % (package, file)
\ No newline at end of file
+#if pypt_core.FetchBugReportsDebian(package, file) is True:
+# print "Wrote bug report details for package %s to file %s.\n" % (package, file)
+
+BugReportDebian = pypt_core.FetchBugReports()
+
+if BugReportDebian.FetchBugsDebian(package, file) is True:
+ print "Wrote bug report details for package %s to file %s.\n" % (package, file)
+else:
+ print "No bugs found for package %s.\n" % (package)
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-05-19 20:50:10 UTC (rev 146)
+++ trunk/pypt_core.py 2007-05-24 12:26:56 UTC (rev 147)
@@ -132,12 +132,8 @@
Light Cyan = 11
'''
- def __init__(self, warnings, verbose, color = None):
+ def __init__(self, verbose, color = None):
- if warnings is True:
- self.WARN = True
- else: self.WARN = False
-
if verbose is True:
self.VERBOSE = True
else: self.VERBOSE = False
@@ -172,15 +168,6 @@
sys.stdout.flush()
# For the rest, we need to check the options also
- def warn(self, msg):
- 'Print warnings'
-
- if self.WARN is True:
- if self.color:
- WConio.textcolor(12)
-
- sys.stderr.write(msg)
- sys.stderr.flush()
def verbose(self, msg):
'Print verbose messages'
@@ -298,56 +285,77 @@
return False
-def FetchBugReportsDebian(PackageName, ZipFileName=None, lock=False):
- try:
- import debianbts
- except ImportError:
- return False
-
- bug_list = []
- bug_types = ["Resolved bugs", "Minor bugs", "Wishlist items"]
- #INFO: These are the ignore bug types. No one should really be caring about these
-
-
- if ZipFileName is not None:
- AddToArchive = Archiver(lock)
-
- (num_of_bugs, header, bugs_list) = debianbts.get_reports(PackageName)
-
- if num_of_bugs:
- for x in bugs_list:
- (sub_bugs_header, sub_bugs_list) = x
-
- for BugType in bug_types:
- if BugType in sub_bugs_header:
- bug_flag = 0
- break
- bug_flag = 1
-
- if bug_flag:
- for x in sub_bugs_list:
- break_bugs = x.split(':')
- bug_num = string.lstrip(break_bugs[0], '#')
- data = debianbts.get_report(bug_num, followups=True)
- FileName = PackageName + "." + bug_num
- file_handle = open(FileName, 'w')
- file_handle.write(data[0] + "\n\n")
-
- for x in data[1]:
- file_handle.write(x)
- file_handle.write("\n")
+class FetchBugReports(Archiver):
+ def __init__(self, bugTypes=["Resolved bugs", "Normal bugs", "Minor bugs", "Wishlist items"], lock=False, ArchiveFile=None):
+
+ self.bugsList = []
+ self.bugTypes = bugTypes
+ self.lock = lock
+
+ if self.lock:
+ Archiver.__init__(self, lock)
+ self.ArchiveFile = ArchiveFile
+ #ArchiveFiles = Archiver(True)
+ #import debianbts
+
+ def FetchBugsDebian(self, PackageName, Filename=None):
+
+ try:
+ import debianbts
+ except ImportError:
+ return False
+
+ if Filename != None:
+ try:
+ file_handle = open(Filename, 'a')
+ except IOError:
+ sys.exit(1)
+
+ (num_of_bugs, header, self.bugs_list) = debianbts.get_reports(PackageName)
+
+ if num_of_bugs:
+ for x in self.bugs_list:
+ (sub_bugs_header, sub_bugs_list) = x
+
+ for BugType in self.bugTypes:
+ if BugType in sub_bugs_header:
+ bug_flag = 0
+ break
+ bug_flag = 1
- file_handle.write("\n" * 3)
- file_handle.flush()
- file_handle.close()
+ if bug_flag:
+ bug_downloaded = True
- if ZipFileName is not None:
- AddToArchive.compress_the_file(ZipFileName, FileName)
- os.unlink(FileName)
+ for x in sub_bugs_list:
+ break_bugs = x.split(':')
+ bug_num = string.lstrip(break_bugs[0], '#')
+ data = debianbts.get_report(bug_num, followups=True)
+ if Filename == None:
+ self.fileName = PackageName + "." + bug_num
+ file_handle = open(self.fileName, 'w')
+ else:
+ file_handle = open(Filename, 'a')
+
+ file_handle.write(data[0] + "\n\n")
+ for x in data[1]:
+ file_handle.write(x)
+ file_handle.write("\n")
- return True
- return False
+ file_handle.write("\n" * 3)
+ file_handle.flush()
+ file_handle.close()
+
+ if self.lock:
+ self.AddToArchive(self.ArchiveFile)
+ return True
+ def AddToArchive(self, ArchiveFile):
+ if self.compress_the_file(self.ArchiveFile, self.fileName):
+ os.unlink(self.fileName)
+ return True
+
+
+
def files(root):
for path, folders, files in os.walk(root):
@@ -366,17 +374,29 @@
if file == filename:
return os.path.join(path, file)
return False
+
+
+
class DownloadFromWeb(ProgressBar):
+ '''
+ Class for DownloadFromWeb
+ This class also inherits progressbar functionalities from
+ parent class, ProgressBar
+ '''
+
def __init__(self, width):
+ '''
+ width = Progress Bar width
+ '''
ProgressBar.__init__(self, width=width)
def download_from_web(self, url, file, download_dir):
'''
- Download the required file from the web
- The arguments are passed everytime to the function so that,
- may be in future, we could reuse this function
+ url = url to fetch
+ file = file to save to
+ donwload_dir = download path
'''
try:
@@ -547,6 +567,12 @@
#INFO: For the Progress Bar
#progbar = ProgressBar(width = 30)
+ if ArgumentOptions.deb_bugs:
+ if ArgumentOptions.zip_it:
+ FetchBugReportsDebian = FetchBugReports(lock=True, ArchiveFile=ArgumentOptions.zip_upgrade_file)
+ else:
+ FetchBugReportsDebian = FetchBugReports()
+
if ArgumentOptions.download_dir is None:
if os.access("pypt-downloads", os.W_OK) is True:
download_path = os.path.abspath("pypt-downloads")
@@ -632,20 +658,22 @@
if FetcherInstance.download_from_web(url, file, download_path) != True:
errlist.append(PackageName)
+ else:
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
- bug_report_fetch_flag = 0
if ArgumentOptions.zip_it:
log.success("\n%s done.\n" % (PackageName) )
FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, file)
os.unlink(os.path.join(download_path, file))
- if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file) is True:
- log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- bug_report_fetch_flag = 1
-
- if ArgumentOptions.deb_bugs and bug_report_fetch_flag != 1:
- if FetchBugReportsDebian(PackageName) is True:
- log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+
+ if bug_fetched:
+ if FetchBugReportsDebian.AddToArchive(ArgumentOptions.zip_upgrade_file):
+ log.verbose("Archived bug reports for package %s to archive %s\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
+
else:
if find_first_match(cache_dir, file, download_path, checksum) == False:
log.msg("Downloading %s - %d KB\n" % (PackageName, size/1024))
@@ -663,31 +691,34 @@
else:
log.verbose("Cannot copy %s to %s. Is %s writeable??\n" % (file, cache_dir))
- bug_report_fetch_flag = 0
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
+
if ArgumentOptions.zip_it:
FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, file)
os.unlink(os.path.join(download_path, file))
- if ArgumentOptions.deb_bugs:
- FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file)
- log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- bug_report_fetch_flag = 1
+
+ if bug_fetched:
+ if FetchBugReportsDebian.AddToArchive(ArgumentOptions.zip_upgrade_file):
+ log.verbose("Archived bug reports for package %s to archive %s\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- if ArgumentOptions.deb_bugs and bug_report_fetch_flag != 1:
- if FetchBugReportsDebian(PackageName) is True:
- log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
elif True:
- bug_report_fetch_flag = 0
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
+
if ArgumentOptions.zip_it:
FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, file)
os.unlink(os.path.join(download_path, file))
- if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file) is True:
- log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- bug_report_fetch_flag = 1
-
- if ArgumentOptions.deb_bugs and bug_report_fetch_flag != 1:
- if FetchBugReportsDebian(PackageName) is True:
- log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+
+ if bug_fetched:
+ if FetchBugReportsDebian.AddToArchive(ArgumentOptions.zip_upgrade_file):
+ log.verbose("Archived bug reports for package %s to archive %s\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
else:
raise FetchDataKeyError
@@ -749,9 +780,16 @@
if full_file_path != False:
if ArgumentOptions.disable_md5check is False:
if FetcherInstance.md5_check(full_file_path, checksum) is True:
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
+
if ArgumentOptions.zip_it:
if FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, full_file_path) is True:
log.success("%s copied from local cache directory %s\n" % (PackageName, cache_dir) )
+
if ArgumentOptions.deb_bugs:
if FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file, lock=True) is True:
log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
@@ -763,7 +801,7 @@
log.verbose("%s already available in %s. Skipping copy!!!\n\n" % (file, download_path) )
if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, lock=True) is True:
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
else:
@@ -777,21 +815,23 @@
log.verbose("%s copied to local cache directory %s\n" % (file, ArgumentOptions.cache_dir) )
except shutil.Error:
log.verbose("Couldn't copy %s to %s\n\n" % (file, ArgumentOptions.cache_dir) )
+
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
+
if ArgumentOptions.zip_it:
if FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, file) != True:
log.err("Couldn't archive %s to file %s\n" % (file, ArgumentOptions.zip_upgrade_file) )
sys.exit(1)
os.unlink(os.path.join(download_path, file) )
- bug_report_fetch_flag = 0
- if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file, lock=True) is True:
- log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- bug_report_fetch_flag = 1
-
- if ArgumentOptions.deb_bugs and bug_report_fetch_flag != 1:
- if FetchBugReportsDebian(PackageName, lock=True) is True:
- log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ if bug_fetched:
+ if FetchBugReportsDebian.AddToArchive(ArgumentOptions.zip_upgrade_file):
+ log.verbose("Archived bug reports for package %s to archive %s\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
+
else:
#INFO: If md5check is disabled, just copy it to the cache_dir
try:
@@ -813,37 +853,36 @@
except shutil.Error:
log.verbose("%s already available in %s. Skipping copy!!!\n\n" % (file, ArgumentOptions.cache_dir) )
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
+
if ArgumentOptions.zip_it:
if FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, file) != True:
log.err("Couldn't archive %s to file %s\n" % (file, ArgumentOptions.zip_upgrade_file) )
sys.exit(1)
log.verbose("%s added to archive %s\n" % (file, ArgumentOptions.zip_upgrade_file) )
os.unlink(os.path.join(download_path, file) )
- bug_report_fetch_flag = 0
- if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file, lock=True) is True:
- log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- bug_report_fetch_flag = 1
- if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, lock=True) is True:
- log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+
+ if bug_fetched:
+ if FetchBugReportsDebian.AddToArchive(ArgumentOptions.zip_upgrade_file):
+ log.verbose("Archived bug reports for package %s to archive %s\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
+ if ArgumentOptions.deb_bugs:
+ bug_fetched = 0
+ if FetchBugReportsDebian.FetchBugsDebian(PackageName):
+ log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
+ bug_fetched = 1
+
if ArgumentOptions.zip_it:
if FetcherInstance.compress_the_file(ArgumentOptions.zip_upgrade_file, file) != True:
log.err("Couldn't archive %s to file %s\n" % (file, ArgumentOptions.zip_upgrade_file) )
sys.exit(1)
log.verbose("%s added to archive %s\n" % (file, ArgumentOptions.zip_upgrade_file) )
os.unlink(os.path.join(download_path, file) )
- bug_report_fetch_flag = 0
- if ArgumentOptions.deb_bugs:
- if FetchBugReportsDebian(PackageName, ArgumentOptions.zip_upgrade_file, lock=True) is True:
- log.verbose("Fetched bug reports for package %s and archived to file %s.\n" % (PackageName, ArgumentOptions.zip_upgrade_file) )
- bug_report_fetch_flag = 1
-
- if ArgumentOptions.deb_bugs and bug_report_fetch_flag != 1:
- if FetchBugReportsDebian(PackageName, lock=True) is True:
- log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
-
+
log.success("\r%s done.%s\n" % (PackageName, " "* 60) )
else:
#log.err("Couldn't find %s\n" % (PackageName) )
@@ -981,7 +1020,6 @@
help="Root directory path where the pre-downloaded files will be searched. If not, give a period '.'",
action="store", type="string", metavar=".")
parser.add_option("--verbose", dest="verbose", help="Enable verbose messages", action="store_true")
- parser.add_option("--warnings", dest="warnings", help="Enable warnings", action="store_true")
parser.add_option("-u","--uris", dest="uris_file",
help="Full path of the uris file which contains the main database of files to be downloaded",action="store", type="string")
parser.add_option("","--disable-md5check", dest="disable_md5check",
@@ -1034,7 +1072,7 @@
# The log implementation
# Instantiate the class
global log
- log = Log(options.warnings, options.verbose, WindowColor)
+ log = Log(options.verbose, WindowColor)
log.msg("pypt-offline %s\n" % (version))
log.msg("Copyright %s\n" % (copyright))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-07-24 11:58:51
|
Revision: 153
http://svn.sourceforge.net/pypt-offline/?rev=153&view=rev
Author: riteshsarraf
Date: 2007-07-24 04:58:53 -0700 (Tue, 24 Jul 2007)
Log Message:
-----------
* Passing the filename to write() in ZipFile ended up with full path name inside the archive. We don't need that, hence use basename.
* Minor string formatting error in the --cache-dir option
Modified Paths:
--------------
trunk/pypt_core.py
Property Changed:
----------------
trunk/
Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
- .project
.pydevproject
+ .project
.pydevproject
hgrc
hg_push_repos
.hg
pypt-downloads
.hgrc
.hgignore
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-07-24 08:26:23 UTC (rev 152)
+++ trunk/pypt_core.py 2007-07-24 11:58:53 UTC (rev 153)
@@ -219,7 +219,7 @@
#except:
#TODO Handle the exception
#return False
- filename.write(files_to_compress, files_to_compress, zipfile.ZIP_DEFLATED)
+ filename.write(files_to_compress, os.path.basename(files_to_compress), zipfile.ZIP_DEFLATED)
filename.close()
if self.lock:
@@ -807,7 +807,7 @@
if ArgumentOptions.deb_bugs:
bug_fetched = 0
- log.verbose("Fetching bug reports for package %s.\n" (PackageName) )
+ log.verbose("Fetching bug reports for package %s.\n" % (PackageName) )
if FetchBugReportsDebian.FetchBugsDebian(PackageName):
log.verbose("Fetched bug reports for package %s.\n" % (PackageName) )
bug_fetched = 1
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-08-02 19:11:38
|
Revision: 164
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=164&view=rev
Author: riteshsarraf
Date: 2007-08-02 12:11:41 -0700 (Thu, 02 Aug 2007)
Log Message:
-----------
[fetch_bugy.py]
* Strip the carriage returns
* Move bugTypes to global
* Align FetchBugReports() call
[pypt_core.py]
* Bring bugTypes to global
* Some stupid fixes in the offline bug support in syncer()
* syncer() offline bug report is broken currently.
* syncer() wasn't used for long and was completely broken. options wasn't supposed to be passed to it. Only install_upgrade and apt_$$_$$_type was required.
Modified Paths:
--------------
trunk/fetch_bugs.py
trunk/pypt_core.py
Modified: trunk/fetch_bugs.py
===================================================================
--- trunk/fetch_bugs.py 2007-08-02 09:52:09 UTC (rev 163)
+++ trunk/fetch_bugs.py 2007-08-02 19:11:41 UTC (rev 164)
@@ -3,13 +3,17 @@
import pypt_core
package = raw_input("Please enter the Debian package name: ")
+package = package.rstrip("\r")
file = raw_input("Please enter the filename with full path: ")
+file = file.rstrip("\r")
+bugTypes = ["Resolved bugs", "Normal bugs", "Minor bugs", "Wishlist items", "FIXED"]
+
#if pypt_core.FetchBugReportsDebian(package, file) is True:
# print "Wrote bug report details for package %s to file %s.\n" % (package, file)
-BugReportDebian = pypt_core.FetchBugReports()
+BugReportDebian = pypt_core.FetchBugReports(file, bugTypes)
if BugReportDebian.FetchBugsDebian(package, file) is True:
print "Wrote bug report details for package %s to file %s.\n" % (package, file)
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-08-02 09:52:09 UTC (rev 163)
+++ trunk/pypt_core.py 2007-08-02 19:11:41 UTC (rev 164)
@@ -46,6 +46,7 @@
#apt_package_target_path = 'C:\\temp'
pypt_bug_file_format = "__pypt__bug__report"
+bugTypes = ["Resolved bugs", "Normal bugs", "Minor bugs", "Wishlist items", "FIXED"]
#These are spaces which will overwrite the progressbar left mess
LINE_OVERWRITE_MID = " " * 30
@@ -336,7 +337,7 @@
class FetchBugReports(Archiver):
- def __init__(self, pypt_bug_file_format, bugTypes=["Resolved bugs", "Normal bugs", "Minor bugs", "Wishlist items", "FIXED"], lock=False, ArchiveFile=None):
+ def __init__(self, pypt_bug_file_format, bugTypes, ArchiveFile=None, lock=False):
self.bugsList = []
self.bugTypes = bugTypes
@@ -649,9 +650,9 @@
if ArgumentOptions.deb_bugs:
if ArgumentOptions.zip_it:
- FetchBugReportsDebian = FetchBugReports(pypt_bug_file_format, ArgumentOptions.zip_upgrade_file, lock=True)
+ FetchBugReportsDebian = FetchBugReports(pypt_bug_file_format, bugTypes, ArgumentOptions.zip_upgrade_file, lock=True)
else:
- FetchBugReportsDebian = FetchBugReports(pypt_bug_file_format)
+ FetchBugReportsDebian = FetchBugReports(pypt_bug_file_format, bugTypes)
if ArgumentOptions.download_dir is None:
if os.access("pypt-downloads", os.W_OK) is True:
@@ -1105,9 +1106,27 @@
bugs_number = []
for filename in file.namelist():
if filename.endswith(pypt_bug_file_format):
- bugs_number += filename
+ bugs_number.append(filename)
if bugs_number:
+ log.msg("\n\nFollowing are the list of bugs present.\n")
+ for each_bug in bugs_number:
+ each_bug = each_bug.split('.')[1]
+ log.msg("%s\n" % (each_bug) )
+ response = raw_input("What would you like to do next:\t (y, N, Bug Number, ?)" )
+ response = response.rstrip("\r")
+ if response == "?":
+ log.msg("(yY) Yes. Proceed with installation\n")
+ log.msg("(nN) No, Abort.\n")
+ log.msg("(Bug Number) Display the bug report.\n")
+ log.msg("(?) Display this help message.\n")
+ elif respone == 'y' or response == 'Y':
+ pass
+ elif response == 'n' or response == 'N':
+ pass
+ elif response == 'Number':
+ pass
+
printf("I found %d number of bugs.\n" % len(bugs_number) )
pass
@@ -1364,9 +1383,9 @@
log.err("\nYou need superuser privileges to execute this option\n")
sys.exit(1)
if os.path.isfile(options.install_upgrade) is True:
- syncer(options, 1)
+ syncer(options.install_upgrade, apt_package_target_path, 1)
elif os.path.isdir(options.install_upgrade) is True:
- syncer(options, 2)
+ syncer(options.install_upgrade, apt_package_target_path, 2)
else:
log.err("Aieee! %s is unsupported format\n" % (options.install_upgrade))
sys.exit(0)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-08-09 08:57:59
|
Revision: 173
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=173&view=rev
Author: riteshsarraf
Date: 2007-08-09 01:57:56 -0700 (Thu, 09 Aug 2007)
Log Message:
-----------
rrs@learner:~/devel/eclipse/pypt-offline$ hg log -l 5 -v
changeset: 137:6fe9b0d23825
branch: trunk
tag: tip
user: Ritesh Raj Sarraf <rr...@re...>
date: Thu Aug 09 14:24:52 2007 +0530
files: pypt_core.py
description:
* The same should also be the case just if apt fails for some reason.
changeset: 136:65d86034ae3a
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Thu Aug 09 14:23:04 2007 +0530
files: LICENSE
description:
* Switching the GPL v3
changeset: 135:ff49ce32503d
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Wed Aug 08 01:12:33 2007 +0530
files: pypt_core.py
description:
* Handle Unicode problems of apt.
* Currently when you have a proper locale set like en_US.UTF-8, apt also
* extracts translation URIs. But those URIs don't have a correct URL.
* And I don't know why.
* But it has nothing to do with Python
Modified Paths:
--------------
trunk/LICENSE
trunk/pypt_core.py
Modified: trunk/LICENSE
===================================================================
--- trunk/LICENSE 2007-08-05 21:25:42 UTC (rev 172)
+++ trunk/LICENSE 2007-08-09 08:57:56 UTC (rev 173)
@@ -1,16 +1,677 @@
-Copyright (C) 2005 - 2007 Ritesh Raj Sarraf - RESEARCHUT
+Copyright (C) - Ritesh Raj Sarraf - RESEARCHUT
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the
-Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\ No newline at end of file
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party...
[truncated message content] |
|
From: <rit...@us...> - 2007-08-09 09:50:42
|
Revision: 174
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=174&view=rev
Author: riteshsarraf
Date: 2007-08-09 02:50:42 -0700 (Thu, 09 Aug 2007)
Log Message:
-----------
* More license structuring
Modified Paths:
--------------
trunk/fetch_bugs.py
trunk/pypt_core.py
Modified: trunk/fetch_bugs.py
===================================================================
--- trunk/fetch_bugs.py 2007-08-09 08:57:56 UTC (rev 173)
+++ trunk/fetch_bugs.py 2007-08-09 09:50:42 UTC (rev 174)
@@ -1,5 +1,24 @@
#!/usr/bin/env python
+'''
+ pypt-offline -- An offline package manager for Debian and its derivatives
+ Copyright (C) 2007 Ritesh Raj Sarraf
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+'''
+
+
import pypt_core
package = raw_input("Please enter the Debian package name: ")
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-08-09 08:57:56 UTC (rev 173)
+++ trunk/pypt_core.py 2007-08-09 09:50:42 UTC (rev 174)
@@ -1,3 +1,21 @@
+'''
+ pypt-offline -- An offline package manager for Debian and its derivatives
+ Copyright (C) 2007 Ritesh Raj Sarraf
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+'''
+
import os
import md5
import sys
@@ -36,6 +54,8 @@
version = "0.7.0"
copyright = "(C) 2005 - 2007 Ritesh Raj Sarraf - RESEARCHUT (http://www.researchut.com/)"
+terminal_license = "This program comes with ABSOLUTELY NO WARRANTY.\n\
+This is free software, and you are welcome to redistribute it under certain conditions.\n"
errlist = []
supported_platforms = ["Linux", "GNU/kFreeBSD", "GNU"]
@@ -1352,6 +1372,7 @@
log.msg("pypt-offline %s\n" % (version))
log.msg("Copyright %s\n" % (copyright))
+ log.msg(terminal_license)
if options.set_update:
if platform.system() in supported_platforms:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-08-10 22:05:05
|
Revision: 180
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=180&view=rev
Author: riteshsarraf
Date: 2007-08-10 15:04:27 -0700 (Fri, 10 Aug 2007)
Log Message:
-----------
C:\Eclipse\Workspace\pypt-offline>hg log -l 3 -v
changeset: 148:2ce875b21899
branch: trunk
tag: tip
user: Ritesh Raj Sarraf <rr...@re...>
date: Sat Aug 11 03:31:00 2007 +0530
files: TODO pypt_core.py
description:
* I don't understand why import under __init__() aren't allowed. I mean, they make perfect sense to me. Anyway, for now, live with the common ugly (IMO) way.
* Updates in the TODO
changeset: 147:581b615c5324
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Sat Aug 11 03:03:00 2007 +0530
files: pypt_core.py
description:
* We should only be checking for 'microsoft' here.
* stderr also need to be color changed
Modified Paths:
--------------
trunk/TODO
trunk/pypt_core.py
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2007-08-10 12:18:13 UTC (rev 179)
+++ trunk/TODO 2007-08-10 22:04:27 UTC (rev 180)
@@ -6,10 +6,10 @@
* Proxy Authentication
* Implement a function which will keep track of the failed uris and print them at last. It'll keep the uri and it's failure reason as a dictionary <done>
* Implement Threads - When we implement threads multiple files will be downloaded at the same time. <done>
- At that point, say we execute with 5 threads, the progressbar for all 5 threads should be displayed together.
+ At that point, say we execute with 5 threads, the progressbar for all 5 threads should be displayed together. <done>
* Implement Curses and GUI interfaces. For these UIs it will be interactive. For all the options, only one will be selectable and once that option
is selected the others will be deactivated. That's design, only one option allowed a time. :-)
* Use Python's logging module to better handle messages, warnings and errors <done>
* Implement apt's newly added feature (> 0.6.4) of Package Diff
-* Add functionality for Offline Bug Reports
+* Add functionality for Offline Bug Reports <done>
* Handle KeyboardInterrupt exception in threads so that if the user sends an interrupt signal, the program should exit
\ No newline at end of file
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-08-10 12:18:13 UTC (rev 179)
+++ trunk/pypt_core.py 2007-08-10 22:04:27 UTC (rev 180)
@@ -43,11 +43,11 @@
except ImportError:
pass
-#WindowColor = True
-#try:
-# import WConio
-#except ImportError:
-# WindowColor = False
+WindowColor = True
+try:
+ import WConio
+except ImportError:
+ WindowColor = False
'''This is the core module. It does the main job of downloading packages/update packages,\nfiguring out if the packages are in the local cache, handling exceptions and many more stuff'''
@@ -236,7 +236,15 @@
'Blink': '5m', 'SwitchOffAttributes': '0m'}
elif os.name in ['nt', 'dos']:
- self.platform = 'microsoft'
+ self.platform = None
+
+ #try:
+ # import WConio
+ #except ImportError:
+ # self.platform = None
+ if WindowColor is True:
+ self.platform = 'microsoft'
+
self.color = {'Red': 4, 'Black': 0,
'Green': 2, 'White': 15,
'LightRed': 12, 'LightCyan': 11,
@@ -250,7 +258,8 @@
if self.platform == 'posix':
sys.stdout.write(self.color_syntax + self.color[color])
- elif self.platform in ['n', 'dos']:
+ sys.stderr.write(self.color_syntax + self.color(color))
+ elif self.platform == 'microsoft':
WConio.textcolor(self.color[color])
def msg(self, msg):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-08-21 20:29:10
|
Revision: 191
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=191&view=rev
Author: riteshsarraf
Date: 2007-08-21 13:28:35 -0700 (Tue, 21 Aug 2007)
Log Message:
-----------
changeset: 175:9b45cef98006
branch: trunk
tag: tip
user: Ritesh Raj Sarraf <rr...@re...>
date: Wed Aug 22 01:48:50 2007 +0530
files: pypt-offline.1 pypt_core.py
description:
* Added a socket timeout option which sets the socket timeout to a user
* supplied value
changeset: 174:5754621a926e
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Wed Aug 22 01:02:27 2007 +0530
files: pypt-offline.1
description:
* Updated the pypt-offline.1 manpage
changeset: 173:6b84e630839d
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Wed Aug 22 00:22:16 2007 +0530
files: pypt-offline.1 pypt_core.py
description:
* Remove the -u/--uris option. It is not used anymore
* Order the parser options properly.
changeset: 172:abd2471381ce
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Tue Aug 21 23:58:37 2007 +0530
files: pypt_core.py
description:
* Simplified error and verbose display
changeset: 171:a823825c4f59
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Tue Aug 21 23:53:53 2007 +0530
files: pypt_core.py
description:
* Added option to choose a release when requesting for a package install
Modified Paths:
--------------
trunk/pypt-offline.1
trunk/pypt_core.py
Modified: trunk/pypt-offline.1
===================================================================
--- trunk/pypt-offline.1 2007-08-20 13:54:32 UTC (rev 190)
+++ trunk/pypt-offline.1 2007-08-21 20:28:35 UTC (rev 191)
@@ -1,30 +1,149 @@
-.TH pypt-offline 1 "December 10, 2006" "version 0.6.2" "USER COMMANDS"
+.TH pypt-offline 1 "August 20, 2007" "version 0.7.0" "USER COMMANDS"
.SH NAME
pypt-offline \- Offline Package manager
.SH SYNOPSIS
.B pypt-offline
[OPTIONS] [ARGUMENTS]
.SH DESCRIPTION
-pypt-offline is an Offline Package Manager for Debian based systems. It bring offline package management functionality. It can download the required packages for a disconnected machine from a connected machine running Windows or Linux or Mac OS X.
+pypt-offline is an Offline Package Manager for Debian based systems. It bring offline package management functionality.
+It can download the required packages for a disconnected machine from a different connected machine running Windows or Linux or Mac OS X.
.PP
+It can also fetch bug reports for packages which are downloaded.
+.PP
Currently it supports only apt based systems but plans are there to support RPM based distros also.
.SH OPTIONS
.TP
+\-\-set\-update filename
+Specify the file to which the details about the update files with be written to
+.TP
+\-\-set\-upgrade filename
+Specify the file to which the details about the package files will be written to
+.TP
+\-\-upgrade\-type upgrade-type
+Specify the type of upgrade you want to do. Possible values are upgrade/dist-upgrade
+.TP
+\-\-set\-install filename
+Specify the file to which the details about the packages to be installed will be written to
+.TP
+\-\-set\-install\-packages [package names]
+Specify the name of packages which you want to install
+.TP
+\-\-set\-install\-release [release name]
+Specify the name of the release from which you want to download the packages. Eg. testing/unstable/experimental
+.TP
\-\-fetch\-update filename
Specify the data file which contains the details about update files to be downloaded
.TP
+\-\-fetch\-upgrade filename
+Specify the data file which contains the details about the package files to be downloaded
+.TP
+\-\-fetch\-bug\-reports
+Fetch bug reports for the packages which are to be downloaded. Currently works only with Debian BTS
+.TP
+\-\-install\-update filename
+Specify the archive file or folder path which contains the update data you downloaded
+.TP
+\-\-install\-upgrade filename
+Specify the archive file or folder path which contains the package data you downloaded
+.TP
+\-z/\-\-zip
+Zip the downloaded files to a single zip archive file
+.TP
+\-\-zip\-update\-file filename
+Specify a zip file name for the downloaded files to be archived to. Default: pypt-offline-update.zip
+.TP
+\-\-zip\-upgrade\-file filename
+Specify a zip file name for the downloaded files to be archived to. Default: pypt-offline-upgrade.zip
+.TP
\-\-threads N
Specifiy the number of threads to be spawned (Default: 1)
.TP
+\-\-disable\-md5check
+Disable MD5 Checksum. Default: False
+.TP
+\-d/\-\-download\-dir path
+Path where the downloaded files will be saved to. Eg: C:\\debs or /var/tmp/debs
+.TP
+\-s/\-\-cache\-dir path
+Path to search for files before downloading from the web. Eg: C:\\debs or /var/tmp/debs
+.TP
+\-\-socket\-timeout N
+Set socket timeout value. Default: 30
+.TP
+\-\-verbose
+Enable verbose messages
+.TP
+\-\-test\-windows
+This switch is used while doing testing on Microsoft Windows
+.TP
\-\-help
display a short help text
.TP
\-\-version
display the version of the progream
+
.SH EXAMPLES
.TP
-.B pypt-offline \-\-fetch\-update uris\-file
+.B To keep your disconnected machine up-to-date, here are the examples
+.TP
+.B pypt-offline \-\-set\-update update_uris
+This command will extract the details about the files that need to be fetched to update the package management database on the machine without internet connection.
+.TP
+.B pypt-offline \-\-fetch\-update update_uris
+This command will fetch the required data as defined in the update_uris file and create a zip archive if the \-z option is used
+.TP
+.B pypt-offline \-\-install\-update pypt-offline-update.zip
+This command will update your disconnected machine's package management database by extracting the data from the file pypt-offline-update.zip
+
+.TP
+.B To upgrade/install packages on your disconnected machine, here are the examples
+.TP
+.B pypt-offline \-\-set\-upgrade upgrade_uris
+This command will extract the details about the packages that need to be fetched to upgrade the softwares install on your machine without an internet connection.
+.TP
+.B pypt-offline \-\-fetch\-upgrade upgrade_uris
+This command will fetch the required data as defined in the upgrade_uris file and create a zip archive if the \-z option is used. Else it will download it into the folder you specify.
+.TP
+.B pypt-offline \-\-install\-upgrade pypt-offline-upgrade.zip
+This command will install packages to your disconnected machine's package management database by extracting the data from the file pypt-offlien-upgrade.zip. If you didn't use the \-z option, you will have to specify the directory path
+Once the packages are synced, you can do the installation as you usually do by using "apt-get install package_name" or "apt-get upgrade". apt will not ask you to download any additional byte.
+
+.TP
+.B Other important options to use with the above
+
+.TP
+.B -z / --zip
+This option, when used along with \-\-fetch\-up[date/grade], creates a archive file for the files which are downloaded. It becomes convenient to use a single zip archive file.
+This option is highly recommended to be used but is not enable by default.
+
+.TP
+.B --threads N
+This option allows multiple downloads to be enabled. It spawns multiple threads when downloading. Use this when you have a high speed internet connection.
+On a high speed internet connection, 5 is a good value to use.
+
+.TP
+.B --disable-md5check
+This option, if enabled, disables MD5 Checksum for the data which is downloaded. It is HIGHLY DISCOURAGED to use this option
+
+.TP
+.B --fetch-bug-reports
+This option, if enabled, fetched bug reports for packages which are being downloaded. Currently only Debian BTS is supported.
+Disabled by default but highly recommened to use it.
+
.SH AUTHOR
-Ritesh Raj Sarraf (rr...@re...)
+.B Ritesh Raj Sarraf (rr...@re...)
+
+.SH BUGS
+Currently there is no way to break out from the application which it is fetching the required packages.
+This is because when multiple threads are spawned, the signal needs to be handled accordingly. This is in the TODO list.
+
+
+If you wish to report a bug in pypt-offline, please see
+.B http://sf.net/projects/pypt-offline
+or send an email to me at
+.B rr...@re...
+
.SH SEE ALSO
-.SM apt(1)
+.SM apt-get(8)
+.SM apt-cache(8)
+.SM dpkg(8)
\ No newline at end of file
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-08-20 13:54:32 UTC (rev 190)
+++ trunk/pypt_core.py 2007-08-21 20:28:35 UTC (rev 191)
@@ -286,7 +286,7 @@
self.DispLock.acquire(True)
self.set_color('Red')
- sys.stderr.write(msg)
+ sys.stderr.write("ERROR: " + msg)
sys.stderr.flush()
self.set_color('SwitchOffAttributes')
@@ -318,7 +318,7 @@
if self.VERBOSE is True:
self.set_color('Cyan')
- sys.stdout.write(msg)
+ sys.stdout.write("VERBOSE: " + msg)
sys.stdout.flush()
self.set_color('SwitchOffAttributes')
@@ -710,7 +710,7 @@
sys.exit(errno)
else:
- log.err("Error: I don't understand this errorcode\n" % (errno))
+ log.err("I don't understand this errorcode\n" % (errno))
sys.exit(errno)
def get_pager_cmd(pager_cmd = None):
@@ -799,7 +799,7 @@
os.mkdir("pypt-downloads")
download_path = os.path.abspath("pypt-downloads")
except:
- log.err("Error: I couldn't create a directory")
+ log.err("I couldn't create a directory")
errfunc(1, '')
else:
download_path = os.path.abspath(ArgumentOptions.download_dir)
@@ -1270,12 +1270,12 @@
shutil.copy(archive_file, target_path + filename)
retval = True
else:
- log.err("ERROR: Cannot write to target path %s\n" % (target_path) )
+ log.err("Cannot write to target path %s\n" % (target_path) )
sys.exit(1)
elif filename.endswith(pypt_bug_file_format):
retval = False # We intentionally put the bug report files as not printed.
else:
- log.err("ERROR: I couldn't understand file type %s.\n" % (filename) )
+ log.err("I couldn't understand file type %s.\n" % (filename) )
if retval is True:
log.msg("%s file synced.\n" % (filename))
@@ -1383,7 +1383,7 @@
magic_check_and_uncompress(archive_file, target_path, filename)
data.file.close()
else:
- log.err("ERROR: Inappropriate argument sent to syncer during data fetch. Do you need to fetch bugs or not?\n")
+ log.err("Inappropriate argument sent to syncer during data fetch. Do you need to fetch bugs or not?\n")
sys.exit(1)
elif path_type == 2:
@@ -1464,7 +1464,7 @@
magic_check_and_uncompress(archive_file, target_path, filename)
else:
- log.err("ERROR: Inappropriate argument sent to syncer during data fetch. Do you need to fetch bugs or not?\n")
+ log.err("Inappropriate argument sent to syncer during data fetch. Do you need to fetch bugs or not?\n")
sys.exit(1)
def main():
@@ -1483,12 +1483,13 @@
help="Root directory path where the pre-downloaded files will be searched.Make sure you give the full path of the cache directory. If not, give a period '.'",
action="store", type="string", metavar=".")
parser.add_option("--verbose", dest="verbose", help="Enable verbose messages", action="store_true")
- parser.add_option("-u","--uris", dest="uris_file",
- help="Full path of the uris file which contains the main database of files to be downloaded",action="store", type="string")
parser.add_option("","--disable-md5check", dest="disable_md5check",
help="Disable md5checksum validation on downloaded files",action="store_false", default=False)
parser.add_option("", "--threads", dest="num_of_threads", help="Number of threads to spawn",
action="store", type="int", metavar="1", default=1)
+ parser.add_option("", "--test-windows", dest="test_windows", help="This switch is used while doing testing on windows.", action="store_true")
+ parser.add_option("", "--socket-timeout", dest="socket_timeout", help="Set the socket timeout value. Default is 30s.",
+ action="store", type="int", metavar="30", default=30)
#INFO: Option zip is not enabled by default but is highly encouraged.
parser.add_option("-z","--zip", dest="zip_it", help="Zip the downloaded files to a single zip file", action="store_true")
@@ -1506,29 +1507,32 @@
action="store", metavar="pypt-offline-install.dat")
parser.add_option("", "--set-install-packages", dest="set_install_packages", help="Name of the packages which need to be fetched",
action="store_true", metavar="package_names")
+ parser.add_option("", "--set-install-release", dest="set_install_release", help="Name of the release from which packages need to be fetched",
+ action="store", metavar="release_name")
parser.add_option("", "--set-update", dest="set_update", help="Extract the list of uris which need to be fetched for updation",
action="store", type="string", metavar="pypt-offline-update.dat")
- parser.add_option("", "--fetch-update", dest="fetch_update",
- help="Fetch the list of uris which are needed for apt's databases _updation_. This command must be executed on the WITHNET machine",
- action="store", type="string", metavar="pypt-offline-update.dat")
- parser.add_option("", "--install-update", dest="install_update",
- help="Install the fetched database files to the NONET machine and _update_ the apt database on the NONET machine. This command must be executed on the NONET machine",
- action="store", type="string", metavar="pypt-offline-update.zip")
parser.add_option("", "--set-upgrade", dest="set_upgrade", help="Extract the list of uris which need to be fetched for _upgradation_",
action="store", type="string", metavar="pypt-offline-upgrade.dat")
parser.add_option("", "--upgrade-type", dest="upgrade_type",
help="Type of upgrade to do. Use one of upgrade, dist-upgrade, dselect-ugprade",
action="store", type="string", metavar="upgrade")
+
+ parser.add_option("", "--fetch-update", dest="fetch_update",
+ help="Fetch the list of uris which are needed for apt's databases _updation_. This command must be executed on the WITHNET machine",
+ action="store", type="string", metavar="pypt-offline-update.dat")
parser.add_option("", "--fetch-upgrade", dest="fetch_upgrade",
help="Fetch the list of uris which are needed for apt's databases _upgradation_. This command must be executed on the WITHNET machine",
action="store", type="string", metavar="pypt-offline-upgrade.dat")
+ parser.add_option("", "--fetch-bug-reports", dest="deb_bugs",
+ help="Fetch bug reports from the BTS", action="store_true")
+
+ parser.add_option("", "--install-update", dest="install_update",
+ help="Install the fetched database files to the NONET machine and _update_ the apt database on the NONET machine. This command must be executed on the NONET machine",
+ action="store", type="string", metavar="pypt-offline-update.zip")
parser.add_option("", "--install-upgrade", dest="install_upgrade",
help="Install the fetched packages to the NONET machine and _upgrade_ the packages on the NONET machine. This command must be executed on the NONET machine",
action="store", type="string", metavar="pypt-offline-upgrade.zip")
- parser.add_option("", "--fetch-bug-reports", dest="deb_bugs",
- help="Fetch bug reports from the BTS", action="store_true")
- parser.add_option("", "--test-windows", dest="test_windows", help="This switch is used while doing testing on windows.", action="store_true")
#global options, args
(options, args) = parser.parse_args()
@@ -1542,6 +1546,15 @@
log.msg("Copyright %s\n" % (copyright))
log.msg(terminal_license)
+ if options.socket_timeout:
+ try:
+ options.socket_timeout.__int__()
+ socket.setdefaulttimeout(options.socket_timeout)
+ log.verbose("Default timeout now is: %d.\n" % (socket.getdefaulttimeout() ) )
+ except AttributeError:
+ log.err("Incorrect value set for socket timeout.\n")
+ sys.exit(1)
+
if options.test_windows:
global apt_package_target_path
global apt_update_target_path
@@ -1624,9 +1637,14 @@
for x in args:
os.environ['__pypt_set_install_packages'] += x + ' '
- #FIXME: Find a more Pythonic implementation
- if os.system('/usr/bin/apt-get -qq --print-uris install $__pypt_set_install_packages > $__pypt_set_install') != 0:
- log.err("FATAL: Something is wrong with the apt system.\n")
+ if options.set_install_release:
+ os.environ['__pypt_set_install_release'] = options.set_install_release
+ if os.system('/usr/bin/apt-get -qq --print-uris -t $__pypt_set_install_release install $__pypt_set_install_packages > $__pypt_set_install') != 0:
+ log.err("FATAL: Something is wrong with the apt system.\n")
+ else:
+ #FIXME: Find a more Pythonic implementation
+ if os.system('/usr/bin/apt-get -qq --print-uris install $__pypt_set_install_packages > $__pypt_set_install') != 0:
+ log.err("FATAL: Something is wrong with the apt system.\n")
else:
parser.error("This argument is supported only on Unix like systems with apt installed\n")
sys.exit(1)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rit...@us...> - 2007-12-27 20:00:56
|
Revision: 198
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=198&view=rev
Author: riteshsarraf
Date: 2007-12-27 12:01:00 -0800 (Thu, 27 Dec 2007)
Log Message:
-----------
changeset: 356:466803e87132
branch: trunk
tag: tip
user: Ritesh Raj Sarraf <rr...@re...>
date: Fri Dec 28 01:25:55 2007 +0530
files: Makefile build.xml pyptofflinegui.ui
description:
Add GUI files for pypt-offline
changeset: 355:ff94448c4c76
branch: trunk
user: Ritesh Raj Sarraf <rr...@re...>
date: Fri Dec 28 01:25:20 2007 +0530
files: pypt_core.py
description:
Indentation fixes.
Remove duplicate array import
Modified Paths:
--------------
trunk/pypt_core.py
Added Paths:
-----------
trunk/Makefile
trunk/build.xml
trunk/pyptofflinegui.ui
Added: trunk/Makefile
===================================================================
--- trunk/Makefile (rev 0)
+++ trunk/Makefile 2007-12-27 20:01:00 UTC (rev 198)
@@ -0,0 +1,5 @@
+all:
+ pyuic pyptofflinegui.ui > pyptofflinegui.py
+
+clean:
+ rm -f pyptofflinegui.py
\ No newline at end of file
Added: trunk/build.xml
===================================================================
--- trunk/build.xml (rev 0)
+++ trunk/build.xml 2007-12-27 20:01:00 UTC (rev 198)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<project name="pypt-offline" default="make">
+ <description>
+ Ant adaptor for the pypt-offline Makefile
+ </description>
+
+ <target name="make" description="build pyptofflinegui">
+ <exec executable="make">
+ <arg value="-f"/>
+ <arg value="Makefile"/>
+ <arg value="all"/>
+ </exec>
+ </target>
+
+ <target name="clean" description="clean pypt-offline" depends="make">
+ <exec executable="make">
+ <arg value="-f"/>
+ <arg value="Makefile"/>
+ <arg value="clean"/>
+ </exec>
+ </target>
+</project>
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-08-26 20:16:00 UTC (rev 197)
+++ trunk/pypt_core.py 2007-12-27 20:01:00 UTC (rev 198)
@@ -27,7 +27,6 @@
import threading
import signal
import optparse
-import array
import socket
import tempfile
@@ -906,7 +905,7 @@
log.msg("Downloading %s - %d KB%s\n" % (PackageName, size/1024, LINE_OVERWRITE_MID) )
if FetcherInstance.download_from_web(url, file, download_path) != True:
- errlist.append(PackageName)
+ errlist.append(PackageName)
else:
log.success("%s done.%s\n" % (PackageName, LINE_OVERWRITE_FULL) )
if os.access(os.path.join(cache_dir, file), os.F_OK):
Added: trunk/pyptofflinegui.ui
===================================================================
--- trunk/pyptofflinegui.ui (rev 0)
+++ trunk/pyptofflinegui.ui 2007-12-27 20:01:00 UTC (rev 198)
@@ -0,0 +1,895 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>pyptofflineguiForm</class>
+<widget class="QMainWindow">
+ <property name="name">
+ <cstring>pyptofflineguiForm</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>618</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>pypt-offline | Offline Package Manager | (C) Ritesh Raj Sarraf - RESEARCHUT</string>
+ </property>
+ <property name="usesTextLabel">
+ <bool>true</bool>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>pyptTabWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>0</y>
+ <width>600</width>
+ <height>430</height>
+ </rect>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Welcome</string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>81</y>
+ <width>361</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>48</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string><p align="center">pypt-offline</p></string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>150</x>
+ <y>190</y>
+ <width>280</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string><p align="center"><font><font size="+1">Offline Package Manager</font></font></p></string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>220</y>
+ <width>291</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string><p align="center"><font size="+1">(C) Ritesh Raj Sarraf - RESEARCHUT</font></p></string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Set</string>
+ </attribute>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout20</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>380</width>
+ <height>210</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>setInstallPackageTextLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Install Packages</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>setInstallPackagesLineEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>upgrade</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>dist-upgrade</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>dselect-upgrade</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>setUpgradeTypeComboBox</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the type of upgrade you want to perform</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>setFilePathLineEdit</cstring>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="alignment">
+ <set>AlignAuto</set>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Full path to a file you want to write to</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="2">
+ <property name="name">
+ <cstring>pushButton6</cstring>
+ </property>
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>setUpgradeTypeTextLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Upgrade Type</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>setUpgradeTypeComboBox</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>setInstallationTypeTextLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Installation Type</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>comboBox3</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>setFilePathTextLabel</cstring>
+ </property>
+ <property name="text">
+ <string>File Path</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>setFilePathLineEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <item>
+ <property name="text">
+ <string></string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Update</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Upgrade</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Install</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>setInstallationTypeComboBox</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select the type of installation you want to perform</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>setInstallPackagesLineEdit</cstring>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="alignment">
+ <set>AlignAuto</set>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Package names separated by space</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>450</x>
+ <y>350</y>
+ <width>100</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Start</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QTextBrowser">
+ <property name="name">
+ <cstring>textBrowser3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>249</y>
+ <width>381</width>
+ <height>140</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>228</y>
+ <width>191</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>textLabel3</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Fetch</string>
+ </attribute>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout22</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>18</x>
+ <y>30</y>
+ <width>340</width>
+ <height>130</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>fetchUpdateDataRadioButton</cstring>
+ </property>
+ <property name="text">
+ <string>Update Data</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select this if you want to fetch the package database updates</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>fetchUpgradeDataRadioButton</cstring>
+ </property>
+ <property name="text">
+ <string>Upgrade Data</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select this if you want to fetch the packages which need to be upgraded/installed</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="0">
+ <property name="name">
+ <cstring>fetchBrowseLineEdit</cstring>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Path to the data file that was generated on the disconnected machine</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>fetchBrowsePushButton</cstring>
+ </property>
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QProgressBar">
+ <property name="name">
+ <cstring>fetchProgressBar</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>350</y>
+ <width>340</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Not Implemented Yet</string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>fetchOptionsButtonGroup</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>380</x>
+ <y>20</y>
+ <width>190</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>fetchZipCheckBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>23</y>
+ <width>91</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Zip</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>fetchTargetDownloadFolderPushButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>150</x>
+ <y>94</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>fetchZipPushButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>150</x>
+ <y>44</y>
+ <width>30</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>fetchCacheDirectoryPushButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>151</x>
+ <y>140</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>fetchCacheDirectoryCheckBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>119</y>
+ <width>170</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Cache Directory</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>fetchTargetDownloadFolderCheckbox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>71</y>
+ <width>170</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Target Download Folder</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>fetchCacheDirectoryLineEdit</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>140</y>
+ <width>140</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Check this and specify the cache directory which contains pre-downloaded packages</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>fetchTargetDownloadFolderLineEdit</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>94</y>
+ <width>140</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Check this and specify the target download folder where the downloaded data will be saved</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>lineEdit7</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>8</x>
+ <y>44</y>
+ <width>141</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Check this and specify the full path for zip archive</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>fetchThreadsSpinBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>131</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>5</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Number of threads you want to spawn</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>fetchThreadsTextLabel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>240</y>
+ <width>121</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Threads</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>fetchDisableMD5ChecksumCheckBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>190</y>
+ <width>170</width>
+ <height>21</height>
+ ...
[truncated message content] |
|
From: <rit...@us...> - 2007-12-28 18:46:24
|
Revision: 199
http://pypt-offline.svn.sourceforge.net/pypt-offline/?rev=199&view=rev
Author: riteshsarraf
Date: 2007-12-28 10:46:29 -0800 (Fri, 28 Dec 2007)
Log Message:
-----------
Add initial GUI support to pypt-offline
Modified Paths:
--------------
trunk/pypt_core.py
Added Paths:
-----------
trunk/pyptofflinegui.py
Modified: trunk/pypt_core.py
===================================================================
--- trunk/pypt_core.py 2007-12-27 20:01:00 UTC (rev 198)
+++ trunk/pypt_core.py 2007-12-28 18:46:29 UTC (rev 199)
@@ -1489,6 +1489,8 @@
parser.add_option("", "--test-windows", dest="test_windows", help="This switch is used while doing testing on windows.", action="store_true")
parser.add_option("", "--socket-timeout", dest="socket_timeout", help="Set the socket timeout value. Default is 30s.",
action="store", type="int", metavar="30", default=30)
+ parser.add_option("", "--gui", dest="gui", help="Run in Graphical Mode",
+ action="store_true")
#INFO: Option zip is not enabled by default but is highly encouraged.
parser.add_option("-z","--zip", dest="zip_it", help="Zip the downloaded files to a single zip file", action="store_true")
@@ -1536,6 +1538,23 @@
(options, args) = parser.parse_args()
try:
+ if options.gui:
+ try:
+ from qt import *
+ except ImportError:
+ sys.exit(1)
+
+ try:
+ from pyptofflinegui import pyptofflineguiForm
+ except ImportError:
+ sys.exit(1)
+
+ app = QApplication(sys.argv)
+ QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()") )
+ w = pyptofflineguiForm()
+ app.setMainWidget(w)
+ w.show()
+ app.exec_loop()
# The log implementation
# Instantiate the class
global log
Added: trunk/pyptofflinegui.py
===================================================================
--- trunk/pyptofflinegui.py (rev 0)
+++ trunk/pyptofflinegui.py 2007-12-28 18:46:29 UTC (rev 199)
@@ -0,0 +1,358 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'pyptofflinegui.ui'
+#
+# Created: Fri Dec 28 18:18:28 2007
+# by: The PyQt User Interface Compiler (pyuic) 3.17.3
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from qt import *
+
+
+class pyptofflineguiForm(QMainWindow):
+ def __init__(self,parent = None,name = None,fl = 0):
+ QMainWindow.__init__(self,parent,name,fl)
+ self.statusBar()
+
+ if not name:
+ self.setName("pyptofflineguiForm")
+
+ self.setUsesTextLabel(1)
+
+ self.setCentralWidget(QWidget(self,"qt_central_widget"))
+
+ self.pyptTabWidget = QTabWidget(self.centralWidget(),"pyptTabWidget")
+ self.pyptTabWidget.setGeometry(QRect(10,0,600,430))
+
+ self.tab = QWidget(self.pyptTabWidget,"tab")
+
+ self.textLabel1 = QLabel(self.tab,"textLabel1")
+ self.textLabel1.setGeometry(QRect(110,81,361,80))
+ textLabel1_font = QFont(self.textLabel1.font())
+ textLabel1_font.setPointSize(48)
+ self.textLabel1.setFont(textLabel1_font)
+
+ self.textLabel1_2 = QLabel(self.tab,"textLabel1_2")
+ self.textLabel1_2.setGeometry(QRect(150,190,280,24))
+
+ self.textLabel2 = QLabel(self.tab,"textLabel2")
+ self.textLabel2.setGeometry(QRect(140,220,291,21))
+ self.pyptTabWidget.insertTab(self.tab,QString.fromLatin1(""))
+
+ self.tab_2 = QWidget(self.pyptTabWidget,"tab_2")
+
+ LayoutWidget = QWidget(self.tab_2,"layout20")
+ LayoutWidget.setGeometry(QRect(10,20,380,210))
+ layout20 = QGridLayout(LayoutWidget,1,1,11,6,"layout20")
+
+ self.setInstallPackageTextLabel = QLabel(LayoutWidget,"setInstallPackageTextLabel")
+
+ layout20.addWidget(self.setInstallPackageTextLabel,2,0)
+
+ self.setUpgradeTypeComboBox = QComboBox(0,LayoutWidget,"setUpgradeTypeComboBox")
+
+ layout20.addWidget(self.setUpgradeTypeComboBox,1,1)
+
+ self.setFilePathLineEdit = QLineEdit(LayoutWidget,"setFilePathLineEdit")
+ self.setFilePathLineEdit.setPaletteBackgroundColor(QColor(255,255,255))
+ self.setFilePathLineEdit.setAlignment(QLineEdit.AlignAuto)
+
+ layout20.addWidget(self.setFilePathLineEdit,3,1)
+
+ self.pushButton6 = QPushButton(LayoutWidget,"pushButton6")
+
+ layout20.addWidget(self.pushButton6,3,2)
+
+ self.setUpgradeTypeTextLabel = QLabel(LayoutWidget,"setUpgradeTypeTextLabel")
+
+ layout20.addWidget(self.setUpgradeTypeTextLabel,1,0)
+
+ self.setInstallationTypeTextLabel = QLabel(LayoutWidget,"setInstallationTypeTextLabel")
+
+ layout20.addWidget(self.setInstallationTypeTextLabel,0,0)
+
+ self.setFilePathTextLabel = QLabel(LayoutWidget,"setFilePathTextLabel")
+
+ layout20.addWidget(self.setFilePathTextLabel,3,0)
+
+ self.setInstallationTypeComboBox = QComboBox(0,LayoutWidget,"setInstallationTypeComboBox")
+
+ layout20.addWidget(self.setInstallationTypeComboBox,0,1)
+
+ self.setInstallPackagesLineEdit = QLineEdit(LayoutWidget,"setInstallPackagesLineEdit")
+ self.setInstallPackagesLineEdit.setPaletteBackgroundColor(QColor(255,255,255))
+ setInstallPackagesLineEdit_font = QFont(self.setInstallPackagesLineEdit.font())
+ setInstallPackagesLineEdit_font.setBold(1)
+ self.setInstallPackagesLineEdit.setFont(setInstallPackagesLineEdit_font)
+ self.setInstallPackagesLineEdit.setAlignment(QLineEdit.AlignAuto)
+
+ layout20.addWidget(self.setInstallPackagesLineEdit,2,1)
+
+ self.pushButton5 = QPushButton(self.tab_2,"pushButton5")
+ self.pushButton5.setGeometry(QRect(450,350,100,20))
+
+ self.textBrowser3 = QTextBrowser(self.tab_2,"textBrowser3")
+ self.textBrowser3.setGeometry(QRect(8,249,381,140))
+
+ self.textLabel3 = QLabel(self.tab_2,"textLabel3")
+ self.textLabel3.setGeometry(QRect(8,228,191,21))
+ self.pyptTabWidget.insertTab(self.tab_2,QString.fromLatin1(""))
+
+ self.TabPage = QWidget(self.pyptTabWidget,"TabPage")
+
+ LayoutWidget_2 = QWidget(self.TabPage,"layout22")
+ LayoutWidget_2.setGeometry(QRect(18,30,340,130))
+ layout22 = QGridLayout(LayoutWidget_2,1,1,11,6,"layout22")
+
+ self.fetchUpdateDataRadioButton = QRadioButton(LayoutWidget_2,"fetchUpdateDataRadioButton")
+
+ layout22.addWidget(self.fetchUpdateDataRadioButton,0,0)
+
+ self.fetchUpgradeDataRadioButton = QRadioButton(LayoutWidget_2,"fetchUpgradeDataRadioButton")
+
+ layout22.addWidget(self.fetchUpgradeDataRadioButton,1,0)
+
+ self.fetchBrowseLineEdit = QLineEdit(LayoutWidget_2,"fetchBrowseLineEdit")
+ self.fetchBrowseLineEdit.setPaletteBackgroundColor(QColor(255,255,255))
+
+ layout22.addWidget(self.fetchBrowseLineEdit,2,0)
+
+ self.fetchBrowsePushButton = QPushButton(LayoutWidget_2,"fetchBrowsePushButton")
+
+ layout22.addWidget(self.fetchBrowsePushButton,2,1)
+
+ self.fetchProgressBar = QProgressBar(self.TabPage,"fetchProgressBar")
+ self.fetchProgressBar.setGeometry(QRect(20,350,340,20))
+
+ self.fetchOptionsButtonGroup = QButtonGroup(self.TabPage,"fetchOptionsButtonGroup")
+ self.fetchOptionsButtonGroup.setGeometry(QRect(380,20,190,290))
+
+ self.fetchZipCheckBox = QCheckBox(self.fetchOptionsButtonGroup,"fetchZipCheckBox")
+ self.fetchZipCheckBox.setGeometry(QRect(8,23,91,20))
+ self.fetchZipCheckBox.setChecked(1)
+
+ self.fetchTargetDownloadFolderPushButton = QPushButton(self.fetchOptionsButtonGroup,"fetchTargetDownloadFolderPushButton")
+ self.fetchTargetDownloadFolderPushButton.setGeometry(QRect(150,94,30,21))
+
+ self.fetchZipPushButton = QPushButton(self.fetchOptionsButtonGroup,"fetchZipPushButton")
+ self.fetchZipPushButton.setGeometry(QRect(150,44,30,20))
+
+ self.fetchCacheDirectoryPushButton = QPushButton(self.fetchOptionsButtonGroup,"fetchCacheDirectoryPushButton")
+ self.fetchCacheDirectoryPushButton.setGeometry(QRect(151,140,30,21))
+
+ self.fetchCacheDirectoryCheckBox = QCheckBox(self.fetchOptionsButtonGroup,"fetchCacheDirectoryCheckBox")
+ self.fetchCacheDirectoryCheckBox.setGeometry(QRect(8,119,170,21))
+
+ self.fetchTargetDownloadFolderCheckbox = QCheckBox(self.fetchOptionsButtonGroup,"fetchTargetDownloadFolderCheckbox")
+ self.fetchTargetDownloadFolderCheckbox.setGeometry(QRect(8,71,170,21))
+
+ self.fetchCacheDirectoryLineEdit = QLineEdit(self.fetchOptionsButtonGroup,"fetchCacheDirectoryLineEdit")
+ self.fetchCacheDirectoryLineEdit.setGeometry(QRect(10,140,140,21))
+ self.fetchCacheDirectoryLineEdit.setPaletteBackgroundColor(QColor(255,255,255))
+
+ self.fetchTargetDownloadFolderLineEdit = QLineEdit(self.fetchOptionsButtonGroup,"fetchTargetDownloadFolderLineEdit")
+ self.fetchTargetDownloadFolderLineEdit.setGeometry(QRect(8,94,140,21))
+ self.fetchTargetDownloadFolderLineEdit.setPaletteBackgroundColor(QColor(255,255,255))
+
+ self.lineEdit7 = QLineEdit(self.fetchOptionsButtonGroup,"lineEdit7")
+ self.lineEdit7.setGeometry(QRect(8,44,141,21))
+ self.lineEdit7.setPaletteBackgroundColor(QColor(255,255,255))
+
+ self.fetchThreadsSpinBox = QSpinBox(self.fetchOptionsButtonGroup,"fetchThreadsSpinBox")
+ self.fetchThreadsSpinBox.setGeometry(QRect(10,260,131,21))
+ self.fetchThreadsSpinBox.setMaxValue(5)
+ self.fetchThreadsSpinBox.setMinValue(1)
+
+ self.fetchThreadsTextLabel = QLabel(self.fetchOptionsButtonGroup,"fetchThreadsTextLabel")
+ self.fetchThreadsTextLabel.setGeometry(QRect(10,240,121,21))
+
+ self.fetchDisableMD5ChecksumCheckBox = QCheckBox(self.fetchOptionsButtonGroup,"fetchDisableMD5ChecksumCheckBox")
+ self.fetchDisableMD5ChecksumCheckBox.setGeometry(QRect(10,190,170,21))
+
+ self.checkBox5 = QCheckBox(self.fetchOptionsButtonGroup,"checkBox5")
+ self.checkBox5.setGeometry(QRect(10,210,170,21))
+ self.checkBox5.setChecked(1)
+
+ self.fetchStartButton = QPushButton(self.TabPage,"fetchStartButton")
+ self.fetchStartButton.setGeometry(QRect(450,350,100,20))
+
+ self.fetchTextBrowser = QTextBrowser(self.TabPage,"fetchTextBrowser")
+ self.fetchTextBrowser.setGeometry(QRect(20,181,340,160))
+
+ self.fetchConsoleOutputTextLabel = QLabel(self.TabPage,"fetchConsoleOutputTextLabel")
+ self.fetchConsoleOutputTextLabel.setGeometry(QRect(20,160,141,20))
+ self.pyptTabWidget.insertTab(self.TabPage,QString.fromLatin1(""))
+
+ self.TabPage_2 = QWidget(self.pyptTabWidget,"TabPage_2")
+
+ LayoutWidget_3 = QWidget(self.TabPage_2,"layout24")
+ LayoutWidget_3.setGeometry(QRect(30,20,330,130))
+ layout24 = QGridLayout(LayoutWidget_3,1,1,11,6,"layout24")
+
+ self.installUpdateDataRadioButton = QRadioButton(LayoutWidget_3,"installUpdateDataRadioButton")
+
+ layout24.addWidget(self.installUpdateDataRadioButton,0,0)
+
+ self.installUpgradeDataRadioButton = QRadioButton(LayoutWidget_3,"installUpgradeDataRadioButton")
+
+ layout24.addWidget(self.installUpgradeDataRadioButton,1,0)
+
+ self.instalBrowsePushButton = QPushButton(LayoutWidget_3,"instalBrowsePushButton")
+
+ layout24.addWidget(self.instalBrowsePushButton,2,1)
+
+ self.installLineEdit = QLineEdit(LayoutWidget_3,"installLineEdit")
+
+ layout24.addWidget(self.installLineEdit,2,0)
+
+ self.textLabel7 = QLabel(self.TabPage_2,"textLabel7")
+ self.textLabel7.setGeometry(QRect(30,150,171,31))
+
+ self.installTextBrowser = QTextBrowser(self.TabPage_2,"installTextBrowser")
+ self.installTextBrowser.setGeometry(QRect(28,184,331,201))
+
+ self.installStartPushButton = QPushButton(self.TabPage_2,"installStartPushButton")
+ self.installStartPushButton.setGeometry(QRect(450,350,100,20))
+ self.pyptTabWidget.insertTab(self.TabPage_2,QString.fromLatin1(""))
+
+ self.fileExitAction = QAction(self,"fileExitAction")
+ self.helpAboutAction = QAction(self,"helpAboutAction")
+
+
+
+
+ self.MenuBar = QMenuBar(self,"MenuBar")
+
+
+ self.fileMenu = QPopupMenu(self)
+ self.fileMenu.insertSeparator()
+ self.fileMenu.insertSeparator()
+ self.fileExitAction.addTo(self.fileMenu)
+ self.MenuBar.insertItem(QString(""),self.fileMenu,1)
+
+ self.helpMenu = QPopupMenu(self)
+ self.helpAboutAction.addTo(self.helpMenu)
+ self.helpMenu.insertSeparator()
+ self.MenuBar.insertItem(QString(""),self.helpMenu,2)
+
+
+ self.languageChange()
+
+ self.resize(QSize(618,480).expandedTo(self.minimumSizeHint()))
+ self.clearWState(Qt.WState_Polished)
+
+ self.connect(self.fileExitAction,SIGNAL("activated()"),self.close)
+ self.connect(self.helpAboutAction,SIGNAL("activated()"),self.helpAbout)
+
+ self.setInstallPackageTextLabel.setBuddy(self.setInstallPackagesLineEdit)
+ self.setUpgradeTypeTextLabel.setBuddy(self.setUpgradeTypeComboBox)
+ self.setFilePathTextLabel.setBuddy(self.setFilePathLineEdit)
+
+
+ def languageChange(self):
+ self.setCaption(self.__tr("pypt-offline | Offline Package Manager | (C) Ritesh Raj Sarraf - RESEARCHUT"))
+ self.textLabel1.setText(self.__tr("<p align=\"center\">pypt-offline</p>"))
+ self.textLabel1_2.setText(self.__tr("<p align=\"center\"><font><font size=\"+1\">Offline Package Manager</font></font></p>"))
+ self.textLabel2.setText(self.__tr("<p align=\"center\"><font size=\"+1\">(C) Ritesh Raj Sarraf - RESEARCHUT</font></p>"))
+ self.pyptTabWidget.changeTab(self.tab,self.__tr("Welcome"))
+ self.setInstallPackageTextLabel.setText(self.__tr("Install Packages"))
+ self.setUpgradeTypeComboBox.clear()
+ self.setUpgradeTypeComboBox.insertItem(QString.null)
+ self.setUpgradeTypeComboBox.insertItem(self.__tr("upgrade"))
+ self.setUpgradeTypeComboBox.insertItem(self.__tr("dist-upgrade"))
+ self.setUpgradeTypeComboBox.insertItem(self.__tr("dselect-upgrade"))
+ QToolTip.add(self.setUpgradeTypeComboBox,self.__tr("Select the type of upgrade you want to perform"))
+ QToolTip.add(self.setFilePathLineEdit,self.__tr("Full path to a file you want to write to"))
+ self.pushButton6.setText(self.__tr("Browse"))
+ self.setUpgradeTypeTextLabel.setText(self.__tr("Upgrade Type"))
+ self.setInstallationTypeTextLabel.setText(self.__tr("Installation Type"))
+ self.setFilePathTextLabel.setText(self.__tr("File Path"))
+ self.setInstallationTypeComboBox.clear()
+ self.setInstallationTypeComboBox.insertItem(QString.null)
+ self.setInstallationTypeComboBox.insertItem(self.__tr("Update"))
+ self.setInstallationTypeComboBox.insertItem(self.__tr("Upgrade"))
+ self.setInstallationTypeComboBox.insertItem(self.__tr("Install"))
+ QToolTip.add(self.setInstallationTypeComboBox,self.__tr("Select the type of installation you want to perform"))
+ QToolTip.add(self.setInstallPackagesLineEdit,self.__tr("Package names separated by space"))
+ self.pushButton5.setText(self.__tr("Start"))
+ self.pushButton5.setAccel(QKeySequence(QString.null))
+ self.textLabel3.setText(self.__tr("textLabel3"))
+ self.pyptTabWidget.changeTab(self.tab_2,self.__tr("Set"))
+ self.fetchUpdateDataRadioButton.setText(self.__tr("Update Data"))
+ QToolTip.add(self.fetchUpdateDataRadioButton,self.__tr("Select this if you want to fetch the package database updates"))
+ self.fetchUpgradeDataRadioButton.setText(self.__tr("Upgrade Data"))
+ QToolTip.add(self.fetchUpgradeDataRadioButton,self.__tr("Select this if you want to fetch the packages which need to be upgraded/installed"))
+ QToolTip.add(self.fetchBrowseLineEdit,self.__tr("Path to the data file that was generated on the disconnected machine"))
+ self.fetchBrowsePushButton.setText(self.__tr("Browse"))
+ QToolTip.add(self.fetchProgressBar,self.__tr("Not Implemented Yet"))
+ self.fetchOptionsButtonGroup.setTitle(self.__tr("Options"))
+ self.fetchZipCheckBox.setText(self.__tr("Zip"))
+ self.fetchTargetDownloadFolderPushButton.setText(self.__tr("..."))
+ self.fetchZipPushButton.setText(self.__tr("..."))
+ self.fetchCacheDirectoryPushButton.setText(self.__tr("..."))
+ self.fetchCacheDirectoryCheckBox.setText(self.__tr("Cache Directory"))
+ self.fetchTargetDownloadFolderCheckbox.setText(self.__tr("Target Download Folder"))
+ QToolTip.add(self.fetchCacheDirectoryLineEdit,self.__tr("Check this and specify the cache directory which contains pre-downloaded packages"))
+ QToolTip.add(self.fetchTargetDownloadFolderLineEdit,self.__tr("Check this and specify the target download folder where the downloaded data will be saved"))
+ QToolTip.add(self.lineEdit7,self.__tr("Check this and specify the full path for zip archive"))
+ QToolTip.add(self.fetchThreadsSpinBox,self.__tr("Number of threads you want to spawn"))
+ self.fetchThreadsTextLabel.setText(self.__tr("Threads"))
+ self.fetchDisableMD5ChecksumCheckBox.setText(self.__tr("Disable MD5 Checksum"))
+ QToolTip.add(self.fetchDisableMD5ChecksumCheckBox,self.__tr("Check this if you want to disable MD5 Checksum"))
+ self.checkBox5.setText(self.__tr("Fetch Bug Reports"))
+ QToolTip.add(self.checkBox5,self.__tr("Check this if you want to download the bug reports"))
+ self.fetchStartButton.setText(self.__tr("Start"))
+ self.fetchConsoleOutputTextLabel.setText(self.__tr("Console Output"))
+ self.pyptTabWidget.changeTab(self.TabPage,self.__tr("Fetch"))
+ self.installUpdateDataRadioButton.setText(self.__tr("Update Data"))
+ QToolTip.add(self.installUpdateDataRadioButton,self.__tr("Select this to install the package database update"))
+ self.installUpgradeDataRadioButton.setText(self.__tr("Upgrade Data"))
+ QToolTip.add(self.installUpgradeDataRadioButton,self.__tr("Select this to install/upgrade the packages"))
+ self.instalBrowsePushButton.setText(self.__tr("Browse"))
+ QToolTip.add(self.installLineEdit,self.__tr("Specify the zip archive or full folder path which contains the downloaded data"))
+ self.textLabel7.setText(self.__tr("Console Output"))
+ self.installStartPushButton.setText(self.__tr("Start"))
+ self.pyptTabWidget.changeTab(self.TabPage_2,self.__tr("Install"))
+ self.fileExitAction.setText(self.__tr("Exit"))
+ self.fileExitAction.setMenuText(self.__tr("E&xit"))
+ self.fileExitAction.setAccel(QString.null)
+ self.helpAboutAction.setText(self.__tr("About"))
+ self.helpAboutAction.setMenuText(self.__tr("&About"))
+ self.helpAboutAction.setAccel(QString.null)
+ if self.MenuBar.findItem(1):
+ self.MenuBar.findItem(1).setText(self.__tr("&File"))
+ if self.MenuBar.findItem(2):
+ self.MenuBar.findItem(2).setText(self.__tr("&Help"))
+
+
+ def fileNew(self):
+ print "pyptofflineguiForm.fileNew(): Not implemented yet"
+
+ def fileOpen(self):
+ print "pyptofflineguiForm.fileOpen(): Not implemented yet"
+
+ def fileSave(self):
+ print "pyptofflineguiForm.fileSave(): Not implemented yet"
+
+ def fileSaveAs(self):
+ print "pyptofflineguiForm.fileSaveAs(): Not implemented yet"
+
+ def filePrint(self):
+ print "pyptofflineguiForm.filePrint(): Not implemented yet"
+
+ def fileExit(self):
+ print "pyptofflineguiForm.fileExit(): Not implemented yet"
+
+ def helpIndex(self):
+ print "pyptofflineguiForm.helpIndex(): Not implemented yet"
+
+ def helpContents(self):
+ print "pyptofflineguiForm.helpContents(): Not implemented yet"
+
+ def helpAbout(self):
+ print "pyptofflineguiForm.helpAbout(): Not implemented yet"
+
+ def __tr(self,s,c = None):
+ return qApp.translate("pyptofflineguiForm",s,c)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|