From 10cb48229482701fc90fbd857c45bc66008e3916 Mon Sep 17 00:00:00 2001 From: volpino Date: Fri, 20 Jul 2012 17:10:12 +0200 Subject: [PATCH] euscanwww: Icons for watching and refreshing, a user can refresh only once Signed-off-by: volpino --- euscanwww/djeuscan/migrations/0014_auto.py | 206 ++++++++++++++++++ euscanwww/djeuscan/models.py | 1 + .../djeuscan/templates/euscan/category.html | 4 +- euscanwww/djeuscan/templates/euscan/herd.html | 4 +- .../djeuscan/templates/euscan/maintainer.html | 4 +- .../djeuscan/templates/euscan/overlay.html | 4 +- .../djeuscan/templates/euscan/package.html | 26 ++- euscanwww/djeuscan/utils.py | 4 +- euscanwww/djeuscan/views.py | 13 ++ euscanwww/htdocs/img/refresh-active.png | Bin 0 -> 1919 bytes euscanwww/htdocs/img/refresh-inactive.png | Bin 0 -> 1809 bytes euscanwww/htdocs/img/unwatch-icon.png | Bin 0 -> 2000 bytes euscanwww/htdocs/img/watch-icon.png | Bin 0 -> 1758 bytes 13 files changed, 247 insertions(+), 19 deletions(-) create mode 100644 euscanwww/djeuscan/migrations/0014_auto.py create mode 100644 euscanwww/htdocs/img/refresh-active.png create mode 100644 euscanwww/htdocs/img/refresh-inactive.png create mode 100644 euscanwww/htdocs/img/unwatch-icon.png create mode 100644 euscanwww/htdocs/img/watch-icon.png diff --git a/euscanwww/djeuscan/migrations/0014_auto.py b/euscanwww/djeuscan/migrations/0014_auto.py new file mode 100644 index 0000000..74cc7c3 --- /dev/null +++ b/euscanwww/djeuscan/migrations/0014_auto.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding M2M table for field users on 'RefreshPackageQuery' + db.create_table('djeuscan_refreshpackagequery_users', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('refreshpackagequery', models.ForeignKey(orm['djeuscan.refreshpackagequery'], null=False)), + ('user', models.ForeignKey(orm['auth.user'], null=False)) + )) + db.create_unique('djeuscan_refreshpackagequery_users', ['refreshpackagequery_id', 'user_id']) + + def backwards(self, orm): + # Removing M2M table for field users on 'RefreshPackageQuery' + db.delete_table('djeuscan_refreshpackagequery_users') + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'djeuscan.categoryassociation': { + 'Meta': {'unique_together': "(['user', 'category'],)", 'object_name': 'CategoryAssociation'}, + 'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'djeuscan.categorylog': { + 'Meta': {'object_name': 'CategoryLog', '_ormbases': ['djeuscan.Log']}, + 'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'log_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['djeuscan.Log']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'djeuscan.euscanresult': { + 'Meta': {'object_name': 'EuscanResult'}, + 'datetime': ('django.db.models.fields.DateTimeField', [], {}), + 'ebuild': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}), + 'result': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'scan_time': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}) + }, + 'djeuscan.herd': { + 'Meta': {'object_name': 'Herd'}, + 'email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'herd': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Maintainer']", 'symmetrical': 'False'}) + }, + 'djeuscan.herdassociation': { + 'Meta': {'unique_together': "(['user', 'herd'],)", 'object_name': 'HerdAssociation'}, + 'herd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Herd']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'djeuscan.herdlog': { + 'Meta': {'object_name': 'HerdLog', '_ormbases': ['djeuscan.Log']}, + 'herd': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Herd']"}), + 'log_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['djeuscan.Log']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'djeuscan.log': { + 'Meta': {'object_name': 'Log'}, + 'datetime': ('django.db.models.fields.DateTimeField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'n_packages_gentoo': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_packages_outdated': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_packages_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_versions_gentoo': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_versions_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_versions_upstream': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + 'djeuscan.maintainer': { + 'Meta': {'object_name': 'Maintainer'}, + 'email': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'djeuscan.maintainerassociation': { + 'Meta': {'unique_together': "(['user', 'maintainer'],)", 'object_name': 'MaintainerAssociation'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'maintainer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Maintainer']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'djeuscan.maintainerlog': { + 'Meta': {'object_name': 'MaintainerLog', '_ormbases': ['djeuscan.Log']}, + 'log_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['djeuscan.Log']", 'unique': 'True', 'primary_key': 'True'}), + 'maintainer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Maintainer']"}) + }, + 'djeuscan.overlayassociation': { + 'Meta': {'unique_together': "(['user', 'overlay'],)", 'object_name': 'OverlayAssociation'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'overlay': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'djeuscan.package': { + 'Meta': {'unique_together': "(['category', 'name'],)", 'object_name': 'Package'}, + 'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'herds': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Herd']", 'symmetrical': 'False', 'blank': 'True'}), + 'homepage': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_version_gentoo': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_version_gentoo'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['djeuscan.Version']"}), + 'last_version_overlay': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_version_overlay'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['djeuscan.Version']"}), + 'last_version_upstream': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_version_upstream'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['djeuscan.Version']"}), + 'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Maintainer']", 'symmetrical': 'False', 'blank': 'True'}), + 'n_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_packaged': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'n_versions': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'djeuscan.packageassociation': { + 'Meta': {'unique_together': "(['user', 'package'],)", 'object_name': 'PackageAssociation'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'djeuscan.problemreport': { + 'Meta': {'object_name': 'ProblemReport'}, + 'datetime': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'version': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Version']", 'null': 'True', 'blank': 'True'}) + }, + 'djeuscan.refreshpackagequery': { + 'Meta': {'object_name': 'RefreshPackageQuery'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}), + 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) + }, + 'djeuscan.version': { + 'Meta': {'unique_together': "(['package', 'slot', 'revision', 'version', 'overlay'],)", 'object_name': 'Version'}, + 'alive': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'confidence': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'ebuild_path': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), + 'handler': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'metadata_path': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), + 'overlay': ('django.db.models.fields.CharField', [], {'default': "'gentoo'", 'max_length': '128', 'db_index': 'True', 'blank': 'True'}), + 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}), + 'packaged': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'slot': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'urls': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'vtype': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}) + }, + 'djeuscan.versionlog': { + 'Meta': {'object_name': 'VersionLog'}, + 'action': ('django.db.models.fields.IntegerField', [], {}), + 'datetime': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'overlay': ('django.db.models.fields.CharField', [], {'default': "'gentoo'", 'max_length': '128', 'blank': 'True'}), + 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}), + 'packaged': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'slot': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'vtype': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}) + }, + 'djeuscan.worldlog': { + 'Meta': {'object_name': 'WorldLog', '_ormbases': ['djeuscan.Log']}, + 'log_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['djeuscan.Log']", 'unique': 'True', 'primary_key': 'True'}) + } + } + + complete_apps = ['djeuscan'] \ No newline at end of file diff --git a/euscanwww/djeuscan/models.py b/euscanwww/djeuscan/models.py index 5c70c45..5101ea8 100644 --- a/euscanwww/djeuscan/models.py +++ b/euscanwww/djeuscan/models.py @@ -277,6 +277,7 @@ class MaintainerLog(Log): class RefreshPackageQuery(models.Model): package = models.ForeignKey(Package) priority = models.IntegerField(default=0) + users = models.ManyToManyField(User) def __unicode__(self): return u'[%d] %s' % (self.priority, self.package) diff --git a/euscanwww/djeuscan/templates/euscan/category.html b/euscanwww/djeuscan/templates/euscan/category.html index f4f123c..8474914 100644 --- a/euscanwww/djeuscan/templates/euscan/category.html +++ b/euscanwww/djeuscan/templates/euscan/category.html @@ -21,10 +21,10 @@ {% if user.is_authenticated %} {% endif %} diff --git a/euscanwww/djeuscan/templates/euscan/herd.html b/euscanwww/djeuscan/templates/euscan/herd.html index c940556..3dc1969 100644 --- a/euscanwww/djeuscan/templates/euscan/herd.html +++ b/euscanwww/djeuscan/templates/euscan/herd.html @@ -20,10 +20,10 @@ Herd: {{ herd.herd }} {% if user.is_authenticated %} {% endif %} diff --git a/euscanwww/djeuscan/templates/euscan/maintainer.html b/euscanwww/djeuscan/templates/euscan/maintainer.html index a68f987..03bd60d 100644 --- a/euscanwww/djeuscan/templates/euscan/maintainer.html +++ b/euscanwww/djeuscan/templates/euscan/maintainer.html @@ -22,10 +22,10 @@ Maintainer: {{ maintainer.name }} <{{ maintainer.email }}> {% if user.is_authenticated %} {% endif %} diff --git a/euscanwww/djeuscan/templates/euscan/overlay.html b/euscanwww/djeuscan/templates/euscan/overlay.html index 21e6a3c..46249ea 100644 --- a/euscanwww/djeuscan/templates/euscan/overlay.html +++ b/euscanwww/djeuscan/templates/euscan/overlay.html @@ -12,10 +12,10 @@ Overlay: {{ overlay }} {% if user.is_authenticated %} {% endif %} diff --git a/euscanwww/djeuscan/templates/euscan/package.html b/euscanwww/djeuscan/templates/euscan/package.html index ef4b753..416cd03 100644 --- a/euscanwww/djeuscan/templates/euscan/package.html +++ b/euscanwww/djeuscan/templates/euscan/package.html @@ -36,15 +36,20 @@ {{ package.category }}/{{ package.name }} {% if user.is_authenticated %} - - - + + + + + + {% endif %}
@@ -207,7 +212,8 @@ var url = "{% url "refresh_package" "XXX" "YYY" %}"; $.post(url.replace("XXX", $(this).data("category")).replace("YYY", $(this).data("package")), function() { - alert("Submitted!"); + $(".refresh-button").addClass("hide"); + $(".refresh-button-disabled").removeClass("hide"); }); }); diff --git a/euscanwww/djeuscan/utils.py b/euscanwww/djeuscan/utils.py index 79565e8..60965e0 100644 --- a/euscanwww/djeuscan/utils.py +++ b/euscanwww/djeuscan/utils.py @@ -68,7 +68,7 @@ def plaintext2html(text, tabstop=4): prefix = '' last = m.groups()[-1] if last in ['\n', '\r', '\r\n']: - last = '
' + last = '
' return '%s%s' % (prefix, url) re_string = re.compile( r'(?P[<&>])|(?P^[ \t]+)|(?P\r\n|\r|\n)|' @@ -77,6 +77,8 @@ def plaintext2html(text, tabstop=4): ) result = re.sub(re_string, do_sub, text) + result = re.sub(r"\\n", "
", result) + result = recolor('cyan', result) result = recolor('blue', result) result = recolor('red', result) diff --git a/euscanwww/djeuscan/views.py b/euscanwww/djeuscan/views.py index 09f48b9..b1eb056 100644 --- a/euscanwww/djeuscan/views.py +++ b/euscanwww/djeuscan/views.py @@ -216,6 +216,12 @@ def package(request, category, package): else: favourited = True + try: + refreshed = request.user in \ + RefreshPackageQuery.objects.get(package=package).users.all() + except RefreshPackageQuery.DoesNotExist: + refreshed = False + thanks_for_reporting = False if request.method == "POST": problem_form = ProblemReportForm(package, request.POST) @@ -238,6 +244,7 @@ def package(request, category, package): 'vlog': vlog, 'last_scan': last_scan, 'favourited': favourited, + 'refreshed': refreshed, 'problem_form': problem_form, 'thanks_for_reporting': thanks_for_reporting } @@ -352,6 +359,12 @@ def refresh_package(request, category, package): pkg = get_object_or_404(Package, category=category, name=package) obj, created = RefreshPackageQuery.objects.get_or_create(package=pkg) + + if request.user in \ + RefreshPackageQuery.objects.get(package=pkg).users.all(): + return {"result": "failure"} + + obj.users.add(request.user) if not created: obj.priority += 1 obj.save() diff --git a/euscanwww/htdocs/img/refresh-active.png b/euscanwww/htdocs/img/refresh-active.png new file mode 100644 index 0000000000000000000000000000000000000000..c4b88d7dd0b8855a52ffa0d63d7cb83373b3aad2 GIT binary patch literal 1919 zcmV-_2Y~pAP)l~UD;FI=ELjpkN$Z+lUm3Mu#aYFp`m)9XcI|Ete*_ka(eU>$eV3}DE?z{q# z&JTty(|T&z+O7jP1ZZx&d!+13-wt&5{R@)GtJ}e%n-GINvYhjHenB}%WW-tN&7Q8A z%7E^cQ_$bj@mefyJ@(*J1IF|KXYUG^<*&|QT%%{;5{Kw(^SVnG=4KZIVzJ5IH|=7! zf*a1CIS1_*n*W|ivWI@MZTLEfG{BjPaB0q0Gk_(5ArELK16AZ|{P%Tc6S8pe^Jo0cfgQIa=gh;kX-`UDeId+12~~s*|ZB zPGjxyrLjA57I|!8TMP)V3E~N52=rtdP!t2cH*n>m8w_38QTb^1(=$2z{@(`u9tFKs zilfCo!Ib5^C6b&|ET(5oFYW!NKJ@nct*;(DsXy)joH%sH*kXmb#f*8}dHiVrJJphO zp==OL+QIWv9EL9YfN5lV#oCUIGeOku&bl8ZQX30d%!P=mx=Zg-d9z()UZl=Yg6ulf z*m~%cagPIVcwgDjQrwqGWIJR zP6u#uXQmoY&^@=Ku!p;osuY&Hu;jW1p(ImOdgkRu?P$HR!~r<4`?hD2N$c5^Mpa#> zeCsJ=l-U762?i?hoWr@WBJ+rs0P>3RjQo=P=N6Qocy6X$IJPzL>_QwZR0TdXxIhtH zK}Xz%;L#-iVs{JisjzC!*YVBT(Jg^rm62GkicMQwL84pX`9xvVlqt28UspvXugbnP z8-SAy{9cTrF>1|K{Jj@~QX&EC7mK4RVx~NP_R4rI$91f1d56$98}uLF2*7zZF9YL; zD>E^V4r}+pK{^+J(|fZ^tvFjxbbHk>(~WC)a@yXmDnT9vWQCxhi;{pi8g_xM+2SJK z0nr8k!xRx?V$@K@opk~en11xNI^CKTpfq1V0WX4t#@P8zi^1f5i4VRsAE^q#UYAHR z-J;;8h60IE4_~>;g^43<+OJCJ*rF!2#RV=-Y>;TmMXDPpGxb!{pWjKDw*oK$v3_kP`sF%5zq**f zbGE%|g^SzgF4%={yI;`PH?N{Kx|r{h1OO2Fn3J?=`*(hFb0Bq2MNA%WyE;w zrLo9#gFg>Ll89j6);wIkNap|5D8`gx5z8ntpyANfsQKX5*tBo0pX*(~A<%cf=|Nw= zQ$Z^hdXOJmC_XY~t$K1~#ti!Zx{M}XXXo1S3$rgA;J;)~FN@G!L81Tv002ovPDHLk FV1fm5sQLf^ literal 0 HcmV?d00001 diff --git a/euscanwww/htdocs/img/refresh-inactive.png b/euscanwww/htdocs/img/refresh-inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..457c6c9926abc82d1b0623892d9df82f98f4346f GIT binary patch literal 1809 zcmV+s2k!WZP)J3sJOC&|(zDa)X)}$;J81%w%TXnfHCqdp^3jGefS?m}{k* zK5$@Q&N=_zdCvbl&kVsw#LUbLu`G*GN-aVNgb>{KeR=fgQT&Y``&Mbcr z;Kq#`%Y=|rxm=z&apJ_;RpP$|@aJ?o-IqutK*+`trnN>cmqR|EFAE|5aQ5ukOX~t$ zx^$_sW53f}FT!yg3=R&$w(T_#jYb1ku3V`qrH1d_ zyH{L&1w=~O74M{&5CWwX^7%YG&x2{2Xf~UepPxsuSd^aUEqR^?&iRgHGHDDC4F*i4tb6xif z##rBj2M<1b`t<2%(P%WyIUk#wn_GJQ`nA?t>xG2{U9Z>I7;|J~1f27e2M!#Fb^(MC zL@Cu3?c8m%*@To59YZ#o&3s>9-^ldz^j~h@zFqB{?9rn~wTBNMew#=nMx>N?s?}-$ zAY58n5}b1thM@|>P={ftEz82dz`!N|zwQFGS}mfK!fFTrFijJYNCdWRBOZ@q+qP|6 z`}_Md?{oX~^mH|mNc_gKtbYk1azcpZa=E+`hG8=dLqGf>#P;pmC4j>KzyRRTp+jGV zVQ5iGyJi9a!!Y1D4lK)pVHilIQV>G?;_%_aJu@>iGw*_U{P=Nj$(Vn0AUz{QVPd$5R1jI zYu7F~j+423`SR)aWkO2%Pbua1TI)Ab$~V66XN3@1Aw*sXQH(~T%R-2F_Z4u?CmW5% zAA=xp+Gf%1SD+}R$}kMY7^9YDnU-atzrR0BrBXfb0~jA4_fDNU^-3wVoiP>(f}jb& z0T2P;5JGGzrLlkieqsQ?#Kgqc0KUd246St?Km|aAa~_dWMzq!ut+lO`ifFAZt#!8& zuGg$cG#VwXR!eSFJd?>-K@e!h*a`sK_kFv4dK-YvIgc>L)a>l6Ha^s-) zjOm*o&|L?V%&0ccQ4xl+pN2m`PH*sWH}CWI7L_kwq35db-U{5bmh`pCk37{auwHE0vW28lDLODPKt@ML*S)fdi3vt2 z9keV<5JFr^X@gQ)Cxp}h)BvmiSgBMhRmRxdhcW;F2*VJB5S31+RW_SdjImDN==SDw z=gyHxBw|xalK`mi`%OX!Cxn=kQWJnFgfIb^oO5$!Wkpj;Uu_8B>eZ{Nr>948&UG%A z(;Z_1V3|yY*tSg>V}@y(41nOAd+io&05GML1|h^?jG0nOqfjUql+xGt@86f*O1NIM zS}k3x)wJunYrfmGX%iV99wxC^4DC`*wAPdmqP5lvfCL}_NUgOHLWq|yUwQ!ky|lEX zHUzL<%+Jq*5TXYM2fM!^$PfKox5Z^!ToOXW;^Lz4eSh)p-Mg*M9_+s@I1394SYBSn z-o1NQ_YvI|R&8-vDwSlpT&~`_b*sF3J^K_@FPqIG8jWJ-&Yi0Yp;lUJMJZK{Mne{h z#n!cJ*D7zXWuL0_zIgFM4-O6@9*=7PiV&hq)0D33s%o|BPfbm^?^?$`VeQB4>?~@v znkIzkSS+TLQp)#ze*XOV5dY&KKjnYt|9AWc2%+nUJQ;Ab00000NkvXXu0mjfn$u1z literal 0 HcmV?d00001 diff --git a/euscanwww/htdocs/img/unwatch-icon.png b/euscanwww/htdocs/img/unwatch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f6875a622809ee7ea698671d23b2fccaeaa69175 GIT binary patch literal 2000 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 A)&Kwi literal 0 HcmV?d00001