--- a/doc/3.17.rst Wed Mar 27 16:36:47 2013 +0100
+++ b/doc/3.17.rst Wed Mar 27 16:58:13 2013 +0100
@@ -6,3 +6,11 @@
* The SIOC views and adapters have been removed from CubicWeb and moved to the
`sioc` cube.
+
+
+Deprecated Code Drops
+----------------------
+
+* The progress views and adapters have been removed from CubicWeb. These
+ classes were deprecated since 3.14.0. They are still available in the
+ `iprogress` cube.
--- a/doc/tools/pyjsrest.py Wed Mar 27 16:36:47 2013 +0100
+++ b/doc/tools/pyjsrest.py Wed Mar 27 16:58:13 2013 +0100
@@ -136,7 +136,6 @@
'cubicweb.preferences',
'cubicweb.edition',
'cubicweb.reledit',
- 'cubicweb.iprogress',
'cubicweb.rhythm',
'cubicweb.gmap',
'cubicweb.timeline-ext',
--- a/entities/adapters.py Wed Mar 27 16:36:47 2013 +0100
+++ b/entities/adapters.py Wed Mar 27 16:58:13 2013 +0100
@@ -404,117 +404,3 @@
"%(cls)s is deprecated") % {'cls': cls.__name__}
warn(msg, DeprecationWarning, stacklevel=2)
return type.__call__(cls, *args, **kwargs)
-
-
-class IProgressAdapter(view.EntityAdapter):
- """something that has a cost, a state and a progression.
-
- You should at least override progress_info an in_progress methods on
- concrete implementations.
- """
- __metaclass__ = adapter_deprecated
- __deprecation_warning__ = '[3.14] IProgressAdapter has been moved to iprogress cube'
- __needs_bw_compat__ = True
- __regid__ = 'IProgress'
- __select__ = implements(IProgress, warn=False) # XXX for bw compat, should be abstract
-
- @property
- @view.implements_adapter_compat('IProgress')
- def cost(self):
- """the total cost"""
- return self.progress_info()['estimated']
-
- @property
- @view.implements_adapter_compat('IProgress')
- def revised_cost(self):
- return self.progress_info().get('estimatedcorrected', self.cost)
-
- @property
- @view.implements_adapter_compat('IProgress')
- def done(self):
- """what is already done"""
- return self.progress_info()['done']
-
- @property
- @view.implements_adapter_compat('IProgress')
- def todo(self):
- """what remains to be done"""
- return self.progress_info()['todo']
-
- @view.implements_adapter_compat('IProgress')
- def progress_info(self):
- """returns a dictionary describing progress/estimated cost of the
- version.
-
- - mandatory keys are (''estimated', 'done', 'todo')
-
- - optional keys are ('notestimated', 'notestimatedcorrected',
- 'estimatedcorrected')
-
- 'noestimated' and 'notestimatedcorrected' should default to 0
- 'estimatedcorrected' should default to 'estimated'
- """
- raise NotImplementedError
-
- @view.implements_adapter_compat('IProgress')
- def finished(self):
- """returns True if status is finished"""
- return not self.in_progress()
-
- @view.implements_adapter_compat('IProgress')
- def in_progress(self):
- """returns True if status is not finished"""
- raise NotImplementedError
-
- @view.implements_adapter_compat('IProgress')
- def progress(self):
- """returns the % progress of the task item"""
- try:
- return 100. * self.done / self.revised_cost
- except ZeroDivisionError:
- # total cost is 0 : if everything was estimated, task is completed
- if self.progress_info().get('notestimated'):
- return 0.
- return 100
-
- @view.implements_adapter_compat('IProgress')
- def progress_class(self):
- return ''
-
-
-class IMileStoneAdapter(IProgressAdapter):
- __metaclass__ = adapter_deprecated
- __deprecation_warning__ = '[3.14] IMileStoneAdapter has been moved to iprogress cube'
- __needs_bw_compat__ = True
- __regid__ = 'IMileStone'
- __select__ = implements(IMileStone, warn=False) # XXX for bw compat, should be abstract
-
- parent_type = None # specify main task's type
-
- @view.implements_adapter_compat('IMileStone')
- def get_main_task(self):
- """returns the main ITask entity"""
- raise NotImplementedError
-
- @view.implements_adapter_compat('IMileStone')
- def initial_prevision_date(self):
- """returns the initial expected end of the milestone"""
- raise NotImplementedError
-
- @view.implements_adapter_compat('IMileStone')
- def eta_date(self):
- """returns expected date of completion based on what remains
- to be done
- """
- raise NotImplementedError
-
- @view.implements_adapter_compat('IMileStone')
- def completion_date(self):
- """returns date on which the subtask has been completed"""
- raise NotImplementedError
-
- @view.implements_adapter_compat('IMileStone')
- def contractors(self):
- """returns the list of persons supposed to work on this task"""
- raise NotImplementedError
-
--- a/test/unittest_vregistry.py Wed Mar 27 16:36:47 2013 +0100
+++ b/test/unittest_vregistry.py Wed Mar 27 16:58:13 2013 +0100
@@ -54,23 +54,23 @@
def test_load_subinterface_based_appobjects(self):
- self.vreg.register_objects([join(BASE, 'web', 'views', 'iprogress.py')])
- # check progressbar was kicked
- self.assertFalse(self.vreg['views'].get('progressbar'))
+ self.vreg.register_objects([join(BASE, 'web', 'views', 'idownloadable.py')])
+ # check downloadlink was kicked
+ self.assertFalse(self.vreg['views'].get('downloadlink'))
# we've to emulate register_objects to add custom MyCard objects
path = [join(BASE, 'entities', '__init__.py'),
join(BASE, 'entities', 'adapters.py'),
- join(BASE, 'web', 'views', 'iprogress.py')]
+ join(BASE, 'web', 'views', 'idownloadable.py')]
filemods = self.vreg.init_registration(path, None)
for filepath, modname in filemods:
self.vreg.load_file(filepath, modname)
- class CardIProgressAdapter(EntityAdapter):
- __regid__ = 'IProgress'
+ class CardIDownloadableAdapter(EntityAdapter):
+ __regid__ = 'IDownloadable'
self.vreg._loadedmods[__name__] = {}
- self.vreg.register(CardIProgressAdapter)
+ self.vreg.register(CardIDownloadableAdapter)
self.vreg.initialization_completed()
# check progressbar isn't kicked
- self.assertEqual(len(self.vreg['views']['progressbar']), 1)
+ self.assertEqual(len(self.vreg['views']['downloadlink']), 1)
def test_properties(self):
self.vreg.reset()
--- a/web/data/cubicweb.iprogress.css Wed Mar 27 16:36:47 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * :organization: Logilab
- * :copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
- * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
- */
-
-/******************************************************************************/
-/* progressbar */
-/******************************************************************************/
-
-.done { background:red }
-
-.inprogress { background:green }
-
-.overpassed { background: yellow}
-
-
-canvas.progressbar {
- border:1px solid black;
-}
-
-.progressbarback {
- border: 1px solid #000000;
- background: transparent;
- height: 10px;
- width: 100px;
-}
-
-/******************************************************************************/
-/* progress table */
-/******************************************************************************/
-
-table.progress {
- /* The default table view */
- margin: 10px 0px 1em;
- width: 100%;
- font-size: 0.9167em;
-}
-
-table.progress th {
- white-space: nowrap;
- font-weight: bold;
- background: %(listingHeaderBgColor)s;
- padding: 2px 4px;
- font-size:8pt;
-}
-
-table.progress th,
-table.progress td {
- border: 1px solid %(listingBorderColor)s;
-}
-
-table.progress td {
- text-align: right;
- padding: 2px 3px;
-}
-
-table.progress th.tdleft,
-table.progress td.tdleft {
- text-align: left;
- padding: 2px 3px 2px 5px;
-}
-
-table.progress tr.highlighted {
- background-color: %(listingHighlightedBgColor)s;
-}
-
-table.progress tr.highlighted .progressbarback {
- border: 1px solid %(listingHighlightedBgColor)s;
-}
-
-table.progress .progressbarback {
- border: 1px solid #777;
-}
-
-.progress_data {
- padding-right: 3px;
-}
\ No newline at end of file
--- a/web/data/cubicweb.iprogress.js Wed Mar 27 16:36:47 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-function ProgressBar() {
- this.budget = 100;
- this.todo = 100;
- this.done = 100;
- this.color_done = "green";
- this.color_budget = "blue";
- this.color_todo = "#cccccc"; // grey
- this.height = 16;
- this.middle = this.height / 2;
- this.radius = 4;
-}
-
-ProgressBar.prototype.draw_one_rect = function(ctx, pos, color, fill) {
- ctx.beginPath();
- ctx.lineWidth = 1;
- ctx.strokeStyle = color;
- if (fill) {
- ctx.fillStyle = color;
- ctx.fillRect(0, 0, pos, this.middle * 2);
- } else {
- ctx.lineWidth = 2;
- ctx.strokeStyle = "black";
- ctx.moveTo(pos, 0);
- ctx.lineTo(pos, this.middle * 2);
- ctx.stroke();
- }
-};
-
-ProgressBar.prototype.draw_one_circ = function(ctx, pos, color) {
- ctx.beginPath();
- ctx.lineWidth = 2;
- ctx.strokeStyle = color;
- ctx.moveTo(0, this.middle);
- ctx.lineTo(pos, this.middle);
- ctx.arc(pos, this.middle, this.radius, 0, Math.PI * 2, true);
- ctx.stroke();
-};
-
-ProgressBar.prototype.draw_circ = function(ctx) {
- this.draw_one_circ(ctx, this.budget, this.color_budget);
- this.draw_one_circ(ctx, this.todo, this.color_todo);
- this.draw_one_circ(ctx, this.done, this.color_done);
-};
-
-ProgressBar.prototype.draw_rect = function(ctx) {
- this.draw_one_rect(ctx, this.todo, this.color_todo, true);
- this.draw_one_rect(ctx, this.done, this.color_done, true);
- this.draw_one_rect(ctx, this.budget, this.color_budget, false);
-};
-
-function draw_progressbar(cid, done, todo, budget, color) {
- var canvas = document.getElementById(cid);
- if (canvas.getContext) {
- var ctx = canvas.getContext("2d");
- var bar = new ProgressBar();
- bar.budget = budget;
- bar.todo = todo;
- bar.done = done;
- bar.color_done = color;
- bar.draw_rect(ctx);
- }
-}
-
--- a/web/views/iprogress.py Wed Mar 27 16:36:47 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,260 +0,0 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb 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.
-#
-# CubicWeb 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 CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Specific views for entities implementing IProgress/IMileStone"""
-
-__docformat__ = "restructuredtext en"
-_ = unicode
-
-from math import floor
-
-from logilab.common.deprecation import class_deprecated
-from logilab.mtconverter import xml_escape
-
-from cubicweb.utils import make_uid
-from cubicweb.predicates import adaptable
-from cubicweb.schema import display_name
-from cubicweb.view import EntityView
-from cubicweb.web.views.tableview import EntityAttributesTableView
-
-
-class ProgressTableView(EntityAttributesTableView):
- """The progress table view is able to display progress information
- of any object implement IMileStone.
-
- The default layout is composoed of 7 columns : parent task,
- milestone, state, estimated date, cost, progressbar, and todo_by
-
- The view accepts an optional ``columns`` paramater that lets you
- remove or reorder some of those columns.
-
- To add new columns, you should extend this class, define a new
- ``columns`` class attribute and implement corresponding
- build_COLNAME_cell methods
-
- header_for_COLNAME methods allow to customize header's label
- """
- __metaclass__ = class_deprecated
- __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
-
- __regid__ = 'progress_table_view'
- __select__ = adaptable('IMileStone')
- title = _('task progression')
- table_css = "progress"
- css_files = ('cubicweb.iprogress.css',)
-
- # default columns of the table
- columns = (_('project'), _('milestone'), _('state'), _('eta_date'),
- _('cost'), _('progress'), _('todo_by'))
-
- def cell_call(self, row, col):
- _ = self._cw._
- entity = self.cw_rset.get_entity(row, col)
- infos = {}
- for col in self.columns:
- meth = getattr(self, 'build_%s_cell' % col, None)
- # find the build method or try to find matching attribute
- if meth:
- content = meth(entity)
- else:
- content = entity.printable_value(col)
- infos[col] = content
- cssclass = entity.cw_adapt_to('IMileStone').progress_class()
- self.w(u"""<tr class="%s" onmouseover="$(this).addClass('highlighted');"
- onmouseout="$(this).removeClass('highlighted')">""" % cssclass)
- line = u''.join(u'<td>%%(%s)s</td>' % col for col in self.columns)
- self.w(line % infos)
- self.w(u'</tr>\n')
-
- ## header management ######################################################
-
- def header_for_project(self, sample):
- """use entity's parent type as label"""
- return display_name(self._cw, sample.cw_adapt_to('IMileStone').parent_type)
-
- def header_for_milestone(self, sample):
- """use entity's type as label"""
- return display_name(self._cw, sample.__regid__)
-
- ## cell management ########################################################
- def build_project_cell(self, entity):
- """``project`` column cell renderer"""
- project = entity.cw_adapt_to('IMileStone').get_main_task()
- if project:
- return project.view('incontext')
- return self._cw._('no related project')
-
- def build_milestone_cell(self, entity):
- """``milestone`` column cell renderer"""
- return entity.view('incontext')
-
- def build_state_cell(self, entity):
- """``state`` column cell renderer"""
- return xml_escape(entity.cw_adapt_to('IWorkflowable').printable_state)
-
- def build_eta_date_cell(self, entity):
- """``eta_date`` column cell renderer"""
- imilestone = entity.cw_adapt_to('IMileStone')
- if imilestone.finished():
- return self._cw.format_date(imilestone.completion_date())
- formated_date = self._cw.format_date(imilestone.initial_prevision_date())
- if imilestone.in_progress():
- eta_date = self._cw.format_date(imilestone.eta_date())
- _ = self._cw._
- if formated_date:
- formated_date += u' (%s %s)' % (_('expected:'), eta_date)
- else:
- formated_date = u'%s %s' % (_('expected:'), eta_date)
- return formated_date
-
- def build_todo_by_cell(self, entity):
- """``todo_by`` column cell renderer"""
- imilestone = entity.cw_adapt_to('IMileStone')
- return u', '.join(p.view('outofcontext') for p in imilestone.contractors())
-
- def build_cost_cell(self, entity):
- """``cost`` column cell renderer"""
- _ = self._cw._
- imilestone = entity.cw_adapt_to('IMileStone')
- pinfo = imilestone.progress_info()
- totalcost = pinfo.get('estimatedcorrected', pinfo['estimated'])
- missing = pinfo.get('notestimatedcorrected', pinfo.get('notestimated', 0))
- costdescr = []
- if missing:
- # XXX: link to unestimated entities
- costdescr.append(_('%s not estimated') % missing)
- estimated = pinfo['estimated']
- if estimated and estimated != totalcost:
- costdescr.append(_('initial estimation %s') % estimated)
- if costdescr:
- return u'%s (%s)' % (totalcost, ', '.join(costdescr))
- return unicode(totalcost)
-
- def build_progress_cell(self, entity):
- """``progress`` column cell renderer"""
- return entity.view('progressbar')
-
-
-class InContextProgressTableView(ProgressTableView):
- """this views redirects to ``progress_table_view`` but removes
- the ``project`` column
- """
- __metaclass__ = class_deprecated
- __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
- __regid__ = 'ic_progress_table_view'
-
- def call(self, columns=None):
- view = self._cw.vreg['views'].select('progress_table_view', self._cw,
- rset=self.cw_rset)
- columns = list(columns or view.columns)
- try:
- columns.remove('project')
- except ValueError:
- self.info('[ic_progress_table_view] could not remove project from columns')
- view.render(w=self.w, columns=columns)
-
-
-class ProgressBarView(EntityView):
- """displays a progress bar"""
- __metaclass__ = class_deprecated
- __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
- __regid__ = 'progressbar'
- __select__ = adaptable('IProgress')
-
- title = _('progress bar')
-
- precision = 0.1
- red_threshold = 1.1
- orange_threshold = 1.05
- yellow_threshold = 1
-
- @classmethod
- def overrun(cls, iprogress):
- done = iprogress.done or 0
- todo = iprogress.todo or 0
- budget = iprogress.revised_cost or 0
- if done + todo > budget:
- overrun = done + todo - budget
- else:
- overrun = 0
- if overrun < cls.precision:
- overrun = 0
- return overrun
-
- @classmethod
- def overrun_percentage(cls, iprogress):
- budget = iprogress.revised_cost or 0
- if budget == 0:
- return 0
- return cls.overrun(iprogress) * 100. / budget
-
- def cell_call(self, row, col):
- self._cw.add_css('cubicweb.iprogress.css')
- self._cw.add_js('cubicweb.iprogress.js')
- entity = self.cw_rset.get_entity(row, col)
- iprogress = entity.cw_adapt_to('IProgress')
- done = iprogress.done or 0
- todo = iprogress.todo or 0
- budget = iprogress.revised_cost or 0
- if budget == 0:
- pourcent = 100
- else:
- pourcent = done*100./budget
- if pourcent > 100.1:
- color = 'red'
- elif todo+done > self.red_threshold*budget:
- color = 'red'
- elif todo+done > self.orange_threshold*budget:
- color = 'orange'
- elif todo+done > self.yellow_threshold*budget:
- color = 'yellow'
- else:
- color = 'green'
- if pourcent < 0:
- pourcent = 0
-
- if floor(done) == done or done>100:
- done_str = '%i' % done
- else:
- done_str = '%.1f' % done
- if floor(budget) == budget or budget>100:
- budget_str = '%i' % budget
- else:
- budget_str = '%.1f' % budget
-
- title = u'%s/%s = %i%%' % (done_str, budget_str, pourcent)
- short_title = title
- overrunpercent = self.overrun_percentage(iprogress)
- if overrunpercent:
- overrun = self.overrun(iprogress)
- title += u' overrun +%sj (+%i%%)' % (overrun, overrunpercent)
- if floor(overrun) == overrun or overrun > 100:
- short_title += u' +%i' % overrun
- else:
- short_title += u' +%.1f' % overrun
- # write bars
- maxi = max(done+todo, budget)
- if maxi == 0:
- maxi = 1
- cid = make_uid('progress_bar')
- self._cw.html_headers.add_onload(
- 'draw_progressbar("canvas%s", %i, %i, %i, "%s");' %
- (cid, int(100.*done/maxi), int(100.*(done+todo)/maxi),
- int(100.*budget/maxi), color))
- self.w(u'%s<br/>'
- u'<canvas class="progressbar" id="canvas%s" width="100" height="10"></canvas>'
- % (xml_escape(short_title), cid))