[copr] master: fix colision of revision id (c702e27)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit c702e27bc94f01695c7ed90d8223a097d8b6cab7
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Fri Jan 24 13:39:08 2014 +0100
fix colision of revision id
>---------------------------------------------------------------
.../versions/498884ac47db_add_timezone_field.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/coprs_frontend/alembic/versions/498884ac47db_add_timezone_field.py b/coprs_frontend/alembic/versions/498884ac47db_add_timezone_field.py
index 5c5948b..80cda55 100644
--- a/coprs_frontend/alembic/versions/498884ac47db_add_timezone_field.py
+++ b/coprs_frontend/alembic/versions/498884ac47db_add_timezone_field.py
@@ -1,14 +1,14 @@
"""add timezone field
Revision ID: 498884ac47db
-Revises: 3a415c6392bc
+Revises: 4837ad1d96ea
Create Date: 2014-01-23 12:15:04.450292
"""
# revision identifiers, used by Alembic.
revision = '498884ac47db'
-down_revision = '3a415c6392bc'
+down_revision = '4837ad1d96ea'
from alembic import op
import sqlalchemy as sa
10 years, 3 months
[copr] master: 1044085 - move timezone modification out of template and make it actually work (ef3eb03)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit ef3eb0302c3cc805a2dd5e5116b8c2b410209ddd
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Fri Jan 24 16:30:17 2014 +0100
1044085 - move timezone modification out of template and make it actually work
>---------------------------------------------------------------
copr.spec | 2 ++
coprs_frontend/coprs/models.py | 17 +++++++++++++++++
.../templates/coprs/detail/_builds_table.html | 20 ++++++++------------
3 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/copr.spec b/copr.spec
index 93c4cf9..ca40be4 100644
--- a/copr.spec
+++ b/copr.spec
@@ -98,6 +98,7 @@ Requires: python-markdown
Requires: python-psycopg2
Requires: python-pylibravatar
Requires: python-whoosh >= 2.5.3
+Requires: pytz
# for tests:
Requires: pytest
Requires: python-flexmock
@@ -119,6 +120,7 @@ BuildRequires: yum
BuildRequires: python-flexmock
BuildRequires: python-decorator
BuildRequires: python-markdown
+BuildRequires: pytz
%description frontend
COPR is lightweight build system. It allows you to create new project in WebUI,
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 2f2fc79..6ebe6b6 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -1,5 +1,8 @@
import datetime
import markdown
+import pytz
+
+from dateutil import tz
from sqlalchemy.ext.associationproxy import association_proxy
from libravatar import libravatar_url
@@ -136,6 +139,20 @@ class User(db.Model, Serializer):
except IOError:
return ""
+ def localized_time(self, time_in):
+ """ return time shifted into self.timezone (and printed in ISO format)
+
+ Input is in EPOCH (seconds since epoch).
+ """
+ format_tz = "%Y-%m-%d %H:%M:%S %Z"
+ utc_tz = pytz.timezone('UTC')
+ if self.timezone:
+ user_tz = pytz.timezone(self.timezone)
+ else:
+ user_tz = utc_tz
+ dt_aware=datetime.datetime.fromtimestamp(time_in).replace(tzinfo=utc_tz)
+ dt_my_tz = dt_aware.astimezone(user_tz)
+ return dt_my_tz.strftime(format_tz)
class Copr(db.Model, Serializer):
"""Represents a single copr (private repo with builds, mock chroots, etc.)."""
diff --git a/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html b/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html
index ef95297..43090c3 100644
--- a/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html
+++ b/coprs_frontend/coprs/templates/coprs/detail/_builds_table.html
@@ -1,13 +1,4 @@
{% from "coprs/detail/_builds_forms.html" import copr_build_cancel_form, copr_build_repeat_form, copr_build_delete_form %}
-{% from datetime import datetime %}
-{% from dateutil import tz %}
-{{ format_tz = "%%d-%%m-%%y %%H:%%M:%%S" }}
-{{ utc_tz = tz.tzutc() }}
-{% if g.user.timezone %}
- {{ user_tz = g.user.timezone }}
-{% else %}
- {{ user_tz = utc_tz }}
-{% endif %}
{% macro builds_table(builds) %}
{% if builds %}
@@ -23,10 +14,15 @@
{% for build in builds %}
<tr class="build-{{ build.state }} build-state">
<td>{{ build.id }}</td>
- <td>{{ datetime.strptime(build.submitted_on|date_from_secs, format_tz).replace(tzinfo=utc_tz).astimezone(g.user.timezone).strftime(format_tz) }}</td>
+{% if g.user %}
+ <td>{{ g.user.localized_time(build.submitted_on) }}</td>
+{% else %}
+ <td>{{ build.submitted_on|date_from_secs }}</td>
+{% endif %}
+
<td>{{ build.user.name }}</td>
- <td>{{ datetime.strptime(build.started_on|date_from_secs, format_tz).replace(tzinfo=utc_tz).astimezone(g.user.timezone).strftime(format_tz) or 'Not yet' }}</td>
- <td>{{ datetime.strptime(build.ended_on|date_from_secs, format_tz).replace(tzinfo=utc_tz).astimezone(g.user.timezone).strftime(format_tz) or 'Not yet' }}</td>
+ <td>{{ build.started_on|date_from_secs or 'Not yet' }}</td>
+ <td>{{ build.ended_on|date_from_secs or 'Not yet' }}</td>
<td>{{ build.state }}</td>
</tr>
<tr class="details">
10 years, 3 months
[copr] master: disable test on i386 (44e1b58)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 44e1b584180c2670f1369d2c811d10d449a6952b
Author: Miroslav Suchý <miroslav(a)suchy.cz>
Date: Mon Jan 27 21:20:11 2014 +0100
disable test on i386
because otherwise python will not like that we use in test numbers higher then sys.maxint on i386
>---------------------------------------------------------------
copr.spec | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/copr.spec b/copr.spec
index d9b86b2..50fbe66 100644
--- a/copr.spec
+++ b/copr.spec
@@ -283,7 +283,7 @@ install -p -m 644 man/%{name}-selinux-relabel.8 %{buildroot}/%{_mandir}/man8/
%endif
%check
-%if %{with_test} && %{with_server}
+%if %{with_test} && %{with_server} && %{_arch} == "x86_64"
pushd coprs_frontend
COPR_CONFIG="$(pwd)/config/copr_unit_test.conf" ./manage.py test
popd
10 years, 3 months
[copr] master: use experimental createrepo_c to get rid of lock on temp files (d0cac28)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit d0cac28882575304d7b4bf69020e96233254e897
Author: Miroslav Suchý <miroslav(a)suchy.cz>
Date: Mon Jan 27 19:30:19 2014 +0100
use experimental createrepo_c to get rid of lock on temp files
see:
https://github.com/Tojaj/createrepo_c/issues/2#issuecomment-33373406
>---------------------------------------------------------------
backend/mockremote.py | 4 ++--
copr-prune-repo | 2 +-
copr.spec | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/backend/mockremote.py b/backend/mockremote.py
index fca9928..3b61629 100755
--- a/backend/mockremote.py
+++ b/backend/mockremote.py
@@ -62,9 +62,9 @@ class SortedOptParser(optparse.OptionParser):
def createrepo(path):
if os.path.exists(path + '/repodata/repomd.xml'):
- comm = ['/usr/bin/createrepo_c', '--database', '--update', path]
+ comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock', '--update', path]
else:
- comm = ['/usr/bin/createrepo_c', '--database', path]
+ comm = ['/usr/bin/createrepo_c', '--database', '--ignore-lock', path]
cmd = subprocess.Popen(comm,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = cmd.communicate()
diff --git a/copr-prune-repo b/copr-prune-repo
index c4b5ca7..6e15d68 100755
--- a/copr-prune-repo
+++ b/copr-prune-repo
@@ -44,7 +44,7 @@ for REPO in $( ls -d */*/* | grep -v '/repodata$' ); do
rm -f $LATEST_PKGS $ERR_LOG
# unless we previosly deleted the repo, regen metadata
if [ -d $(pwd) ]; then
- runuser -c "createrepo_c --update -q $(pwd)" - copr &>/dev/null || runuser -c "createrepo_c --update -q $(pwd)" - copr
+ runuser -c "createrepo_c --update -q --ignore-lock $(pwd)" - copr &>/dev/null || runuser -c "createrepo_c --update -q --ignore-lock $(pwd)" - copr
fi
popd >/dev/null
done
diff --git a/copr.spec b/copr.spec
index 0c38e02..d9b86b2 100644
--- a/copr.spec
+++ b/copr.spec
@@ -61,7 +61,7 @@ Requires: rsync
Requires: openssh-clients
Requires: mock
Requires: yum-utils
-Requires: createrepo_c
+Requires: createrepo_c >= 0.2.1-3
Requires: python-bunch
Requires: python-daemon
Requires: python-lockfile
10 years, 3 months
[copr] new: [frontend] use markdown template filter (9ebc78b)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : new
>---------------------------------------------------------------
commit 9ebc78b932d51b3c7a9ff77578837ca1fe1d3ca7
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Mon Jan 27 15:14:30 2014 +0100
[frontend] use markdown template filter
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/filters.py | 15 +++++++++++++++
coprs_frontend/coprs/models.py | 13 ++-----------
.../coprs/templates/coprs/detail/overview.html | 4 ++--
coprs_frontend/coprs/templates/coprs/show.html | 10 +++++-----
4 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/coprs_frontend/coprs/filters.py b/coprs_frontend/coprs/filters.py
index 36c568a..b37b7e9 100644
--- a/coprs_frontend/coprs/filters.py
+++ b/coprs_frontend/coprs/filters.py
@@ -1,4 +1,7 @@
import time
+import markdown
+
+from flask import Markup
from coprs import app
from coprs import helpers
@@ -28,3 +31,15 @@ def os_name_short(os_name, os_version):
elif os_name == "epel":
return "el{0}".format(os_version)
return os_name
+
+
+(a)app.template_filter("markdown")
+def markdown_filter(data):
+ if not data:
+ return ''
+
+ md = markdown.Markdown(
+ safe_mode="replace",
+ html_replacement_text="--RAW HTML NOT ALLOWED--")
+
+ return Markup(md.convert(data))
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 67f7c3f..bbdd47d 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -1,5 +1,4 @@
import datetime
-import markdown
from sqlalchemy.ext.associationproxy import association_proxy
from libravatar import libravatar_url
@@ -161,19 +160,11 @@ class Copr(db.Model, helpers.Serializer):
@property
def description_or_not_filled(self):
- md = markdown.Markdown(
- safe_mode="replace",
- html_replacement_text="--RAW HTML NOT ALLOWED--")
-
- return md.convert(self.description) or "Description not filled in by author. Very likely personal repository for testing purpose, which you should not use."
+ return self.description or "Description not filled in by author. Very likely personal repository for testing purpose, which you should not use."
@property
def instructions_or_not_filled(self):
- md = markdown.Markdown(
- safe_mode="replace",
- html_replacement_text="--RAW HTML NOT ALLOWED--")
-
- return md.convert(self.instructions) or "Instructions not filled in by author. Author knows what to do. Everybody else should avoid this repo."
+ return self.instructions or "Instructions not filled in by author. Author knows what to do. Everybody else should avoid this repo."
@property
def active_chroots(self):
diff --git a/coprs_frontend/coprs/templates/coprs/detail/overview.html b/coprs_frontend/coprs/templates/coprs/detail/overview.html
index d3bca61..7bebca0 100644
--- a/coprs_frontend/coprs/templates/coprs/detail/overview.html
+++ b/coprs_frontend/coprs/templates/coprs/detail/overview.html
@@ -6,9 +6,9 @@
{% block detail_body %}
<h2>Description</h2>
- <div class="shift-right">{{ copr.description_or_not_filled|safe }}</div>
+ <div class="shift-right">{{ copr.description_or_not_filled|markdown }}</div>
<h2>Installation Instructions</h2>
- <div class="shift-right">{{ copr.instructions_or_not_filled|safe }}</div>
+ <div class="shift-right">{{ copr.instructions_or_not_filled|markdown }}</div>
<h2>Active Releases</h2>
<div class="disclaimer">
The following unofficial repositories are provided as-is by owner of this project.
diff --git a/coprs_frontend/coprs/templates/coprs/show.html b/coprs_frontend/coprs/templates/coprs/show.html
index 2533171..4a25617 100644
--- a/coprs_frontend/coprs/templates/coprs/show.html
+++ b/coprs_frontend/coprs/templates/coprs/show.html
@@ -29,12 +29,12 @@
{% for copr in coprs %}
<div class="copr">
<a class="coprs-list" href="{{ url_for('coprs_ns.copr_detail', username = copr.owner.name, coprname = copr.name) }}">{{ copr.owner.name }}/{{ copr.name }}</a>
- <p>{{ copr.description_or_not_filled|safe }}</p>
- <p class="repos">
- {% for mock_chroot in copr.active_chroots %}
+ <p>{{ copr.description_or_not_filled|markdown }}</p>
+ <p class="repos">
+ {% for mock_chroot in copr.active_chroots %}
{{ mock_chroot.os_release|os_name_short(mock_chroot.os_version) }}.{{ mock_chroot.arch }}{% if not loop.last %}, {% endif %}
- {% endfor %}
- </p>
+ {% endfor %}
+ </p>
</div>
{% else %}
<p>No projects...</p>
10 years, 3 months
[copr] new: [frontend] use default filter instead of *_not_filled (7623184)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : new
>---------------------------------------------------------------
commit 76231848d17544fce6f3412edb83d4a973ed652a
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Mon Jan 27 15:18:49 2014 +0100
[frontend] use default filter instead of *_not_filled
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/models.py | 8 --------
.../coprs/templates/coprs/detail/overview.html | 4 ++--
coprs_frontend/coprs/templates/coprs/show.html | 2 +-
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index bbdd47d..50c1bf7 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -159,14 +159,6 @@ class Copr(db.Model, helpers.Serializer):
return self.repos.split()
@property
- def description_or_not_filled(self):
- return self.description or "Description not filled in by author. Very likely personal repository for testing purpose, which you should not use."
-
- @property
- def instructions_or_not_filled(self):
- return self.instructions or "Instructions not filled in by author. Author knows what to do. Everybody else should avoid this repo."
-
- @property
def active_chroots(self):
"""
Return list of active mock_chroots of this copr
diff --git a/coprs_frontend/coprs/templates/coprs/detail/overview.html b/coprs_frontend/coprs/templates/coprs/detail/overview.html
index 7bebca0..dadb3ac 100644
--- a/coprs_frontend/coprs/templates/coprs/detail/overview.html
+++ b/coprs_frontend/coprs/templates/coprs/detail/overview.html
@@ -6,9 +6,9 @@
{% block detail_body %}
<h2>Description</h2>
- <div class="shift-right">{{ copr.description_or_not_filled|markdown }}</div>
+ <div class="shift-right">{{ copr.description|markdown|default('Description not filled in by author. Very likely personal repository for testing purpose, which you should not use.', true) }}</div>
<h2>Installation Instructions</h2>
- <div class="shift-right">{{ copr.instructions_or_not_filled|markdown }}</div>
+ <div class="shift-right">{{ copr.instructions|markdown|default('Instructions not filled in by author. Author knows what to do. Everybody else should avoid this repo.', true) }}</div>
<h2>Active Releases</h2>
<div class="disclaimer">
The following unofficial repositories are provided as-is by owner of this project.
diff --git a/coprs_frontend/coprs/templates/coprs/show.html b/coprs_frontend/coprs/templates/coprs/show.html
index 4a25617..0971b0a 100644
--- a/coprs_frontend/coprs/templates/coprs/show.html
+++ b/coprs_frontend/coprs/templates/coprs/show.html
@@ -29,7 +29,7 @@
{% for copr in coprs %}
<div class="copr">
<a class="coprs-list" href="{{ url_for('coprs_ns.copr_detail', username = copr.owner.name, coprname = copr.name) }}">{{ copr.owner.name }}/{{ copr.name }}</a>
- <p>{{ copr.description_or_not_filled|markdown }}</p>
+ <p>{{ copr.description|markdown|default('Description not filled in by author. Very likely personal repository for testing purpose, which you should not use.', true) }}</p>
<p class="repos">
{% for mock_chroot in copr.active_chroots %}
{{ mock_chroot.os_release|os_name_short(mock_chroot.os_version) }}.{{ mock_chroot.arch }}{% if not loop.last %}, {% endif %}
10 years, 3 months
[copr] new: [frontend] use isdigit instead of is_int (95d99aa)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : new
>---------------------------------------------------------------
commit 95d99aa06af79763329731e8543c8fdbd5a041d7
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Mon Jan 27 13:59:52 2014 +0100
[frontend] use isdigit instead of is_int
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/helpers.py | 9 ---------
coprs_frontend/coprs/views/api_ns/api_general.py | 2 +-
2 files changed, 1 insertions(+), 10 deletions(-)
diff --git a/coprs_frontend/coprs/helpers.py b/coprs_frontend/coprs/helpers.py
index 048042a..2074bdb 100644
--- a/coprs_frontend/coprs/helpers.py
+++ b/coprs_frontend/coprs/helpers.py
@@ -157,15 +157,6 @@ def render_repo(copr, mock_chroot, url):
return flask.render_template("coprs/copr.repo", copr=copr, url=url)
-def is_int(s):
- """ Return True is argument is integer number. False otherwise. """
- try:
- int(s)
- return True
- except ValueError:
- return False
-
-
class Serializer(object):
def to_dict(self, options={}):
diff --git a/coprs_frontend/coprs/views/api_ns/api_general.py b/coprs_frontend/coprs/views/api_ns/api_general.py
index 92077e0..166ad13 100644
--- a/coprs_frontend/coprs/views/api_ns/api_general.py
+++ b/coprs_frontend/coprs/views/api_ns/api_general.py
@@ -198,7 +198,7 @@ def copr_new_build(username, coprname):
@api_ns.route("/coprs/build_status/<build_id>/", methods=["GET"])
@api_login_required
def build_status(build_id):
- if helpers.is_int(build_id):
+ if build_id.isdigit():
build = builds_logic.BuildsLogic.get(build_id).first()
else:
build = None
10 years, 3 months
[copr] new: [frontend] move Serializer to helpers (8998593)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : new
>---------------------------------------------------------------
commit 899859359b48eae076c53b1a3461ec7c3468dc13
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Mon Jan 27 13:53:43 2014 +0100
[frontend] move Serializer to helpers
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/helpers.py | 70 +++++++++++++++++++++++++++++++
coprs_frontend/coprs/models.py | 88 ++++-----------------------------------
2 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/coprs_frontend/coprs/helpers.py b/coprs_frontend/coprs/helpers.py
index ce91ae7..048042a 100644
--- a/coprs_frontend/coprs/helpers.py
+++ b/coprs_frontend/coprs/helpers.py
@@ -164,3 +164,73 @@ def is_int(s):
return True
except ValueError:
return False
+
+
+class Serializer(object):
+
+ def to_dict(self, options={}):
+ """
+ Usage:
+
+ SQLAlchObject.to_dict() => returns a flat dict of the object
+ SQLAlchObject.to_dict({"foo": {}}) => returns a dict of the object
+ and will include a flat dict of object foo inside of that
+ SQLAlchObject.to_dict({"foo": {"bar": {}}, "spam": {}}) => returns
+ a dict of the object, which will include dict of foo
+ (which will include dict of bar) and dict of spam.
+
+ Options can also contain two special values: __columns_only__
+ and __columns_except__
+
+ If present, the first makes only specified fiels appear,
+ the second removes specified fields. Both of these fields
+ must be either strings (only works for one field) or lists
+ (for one and more fields).
+
+ SQLAlchObject.to_dict({"foo": {"__columns_except__": ["id"]},
+ "__columns_only__": "name"}) =>
+
+ The SQLAlchObject will only put its "name" into the resulting dict,
+ while "foo" all of its fields except "id".
+
+ Options can also specify whether to include foo_id when displaying
+ related foo object (__included_ids__, defaults to True).
+ This doesn"t apply when __columns_only__ is specified.
+ """
+
+ result = {}
+ columns = self.serializable_attributes
+
+ if "__columns_only__" in options:
+ columns = options["__columns_only__"]
+ else:
+ columns = set(columns)
+ if "__columns_except__" in options:
+ columns_except = options["__columns_except__"]
+ if not isinstance(options["__columns_except__"], list):
+ columns_except = [options["__columns_except__"]]
+
+ columns -= set(columns_except)
+
+ if ("__included_ids__" in options and
+ options["__included_ids__"] is False):
+
+ related_objs_ids = [
+ r + "_id" for r, o in options.items()
+ if not r.startswith("__")]
+
+ columns -= set(related_objs_ids)
+
+ columns = list(columns)
+
+ for column in columns:
+ result[column] = getattr(self, column)
+
+ for related, values in options.items():
+ if hasattr(self, related):
+ result[related] = getattr(self, related).to_dict(values)
+ return result
+
+ @property
+ def serializable_attributes(self):
+ return map(lambda x: x.name, self.__table__.columns)
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 51c797b..67f7c3f 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -9,77 +9,7 @@ from coprs import db
from coprs import helpers
-class Serializer(object):
-
- def to_dict(self, options={}):
- """
- Usage:
-
- SQLAlchObject.to_dict() => returns a flat dict of the object
- SQLAlchObject.to_dict({"foo": {}}) => returns a dict of the object
- and will include a flat dict of object foo inside of that
- SQLAlchObject.to_dict({"foo": {"bar": {}}, "spam": {}}) => returns
- a dict of the object, which will include dict of foo
- (which will include dict of bar) and dict of spam.
-
- Options can also contain two special values: __columns_only__
- and __columns_except__
-
- If present, the first makes only specified fiels appear,
- the second removes specified fields. Both of these fields
- must be either strings (only works for one field) or lists
- (for one and more fields).
-
- SQLAlchObject.to_dict({"foo": {"__columns_except__": ["id"]},
- "__columns_only__": "name"}) =>
-
- The SQLAlchObject will only put its "name" into the resulting dict,
- while "foo" all of its fields except "id".
-
- Options can also specify whether to include foo_id when displaying
- related foo object (__included_ids__, defaults to True).
- This doesn"t apply when __columns_only__ is specified.
- """
-
- result = {}
- columns = self.serializable_attributes
-
- if "__columns_only__" in options:
- columns = options["__columns_only__"]
- else:
- columns = set(columns)
- if "__columns_except__" in options:
- columns_except = options["__columns_except__"]
- if not isinstance(options["__columns_except__"], list):
- columns_except = [options["__columns_except__"]]
-
- columns -= set(columns_except)
-
- if ("__included_ids__" in options and
- options["__included_ids__"] is False):
-
- related_objs_ids = [
- r + "_id" for r, o in options.items()
- if not r.startswith("__")]
-
- columns -= set(related_objs_ids)
-
- columns = list(columns)
-
- for column in columns:
- result[column] = getattr(self, column)
-
- for related, values in options.items():
- if hasattr(self, related):
- result[related] = getattr(self, related).to_dict(values)
- return result
-
- @property
- def serializable_attributes(self):
- return map(lambda x: x.name, self.__table__.columns)
-
-
-class User(db.Model, Serializer):
+class User(db.Model, helpers.Serializer):
"""
Represents user of the copr frontend
@@ -194,7 +124,7 @@ class User(db.Model, Serializer):
return ""
-class Copr(db.Model, Serializer):
+class Copr(db.Model, helpers.Serializer):
"""
Represents a single copr (private repo with builds, mock chroots, etc.).
@@ -289,7 +219,7 @@ class Copr(db.Model, Serializer):
return result
-class CoprPermission(db.Model, Serializer):
+class CoprPermission(db.Model, helpers.Serializer):
"""
Association class for Copr<->Permission relation
@@ -308,7 +238,7 @@ class CoprPermission(db.Model, Serializer):
copr = db.relationship("Copr", backref=db.backref("copr_permissions"))
-class Build(db.Model, Serializer):
+class Build(db.Model, helpers.Serializer):
"""
Representation of one build in one copr
@@ -384,7 +314,7 @@ class Build(db.Model, Serializer):
return self.status == helpers.StatusEnum("pending")
-class MockChroot(db.Model, Serializer):
+class MockChroot(db.Model, helpers.Serializer):
"""
Representation of mock chroot
@@ -414,7 +344,7 @@ class MockChroot(db.Model, Serializer):
arch=self.arch)
-class CoprChroot(db.Model, Serializer):
+class CoprChroot(db.Model, helpers.Serializer):
"""
Representation of Copr<->MockChroot relation
@@ -433,7 +363,7 @@ class CoprChroot(db.Model, Serializer):
cascade="all,delete,delete-orphan"))
-class BuildChroot(db.Model, Serializer):
+class BuildChroot(db.Model, helpers.Serializer):
"""
Representation of Build<->MockChroot relation
@@ -467,7 +397,7 @@ class BuildChroot(db.Model, Serializer):
return "unknown"
-class LegalFlag(db.Model, Serializer):
+class LegalFlag(db.Model, helpers.Serializer):
id = db.Column(db.Integer, primary_key=True)
# message from user who raised the flag (what he thinks is wrong)
raise_message = db.Column(db.Text)
@@ -496,7 +426,7 @@ class LegalFlag(db.Model, Serializer):
primaryjoin="LegalFlag.resolver_id==User.id")
-class Action(db.Model, Serializer):
+class Action(db.Model, helpers.Serializer):
"""
Representation of a custom action that needs
10 years, 3 months
[copr] new: [frontend] fix coding style and py3 compatibility (ff9944e)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : new
>---------------------------------------------------------------
commit ff9944ece29f34935854cf0e19432a92e43cfa51
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Mon Jan 27 13:38:14 2014 +0100
[frontend] fix coding style and py3 compatibility
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
Diff suppressed because of size. To see it, use:
git diff --patch-with-stat --no-color --find-copies-harder --ignore-space-at-eol ^ff9944ece29f34935854cf0e19432a92e43cfa51~1 ff9944ece29f34935854cf0e19432a92e43cfa51
10 years, 3 months
[copr] new: [cli] fix coding style and py3 compatibility (44eaf19)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : new
>---------------------------------------------------------------
commit 44eaf194124646291c5dfe34508d6fa66660415c
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Mon Jan 27 11:41:04 2014 +0100
[cli] fix coding style and py3 compatibility
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
copr_cli/copr_exceptions.py | 4 +
copr_cli/main.py | 79 +++++++++++-----------
copr_cli/subcommands.py | 152 ++++++++++++++++++++++--------------------
3 files changed, 123 insertions(+), 112 deletions(-)
diff --git a/copr_cli/copr_exceptions.py b/copr_cli/copr_exceptions.py
index 555ff27..bb9c009 100644
--- a/copr_cli/copr_exceptions.py
+++ b/copr_cli/copr_exceptions.py
@@ -4,17 +4,21 @@
Exceptions for copr-cli
"""
+
class CoprCliException(Exception):
+
""" Basic exception class for copr-cli. """
pass
class CoprCliNoConfException(CoprCliException):
+
""" Exception thrown when no config file is found. """
pass
class CoprCliConfigException(CoprCliException):
+
""" Exception thrown when the config file is incomplete or
malformated.
"""
diff --git a/copr_cli/main.py b/copr_cli/main.py
index e668410..9644471 100644
--- a/copr_cli/main.py
+++ b/copr_cli/main.py
@@ -7,7 +7,7 @@ import ConfigParser
import subcommands
import copr_exceptions
-__version__ = '0.2.0'
+__version__ = "0.2.0"
__description__ = "CLI tool to run copr"
@@ -54,71 +54,70 @@ def setup_parser():
"""
parser = argparse.ArgumentParser(prog="copr-cli")
# General connection options
- parser.add_argument('--version', action='version',
- version='copr-cli %s' % (__version__))
+ parser.add_argument("--version", action="version",
+ version="copr-cli {0}".format(__version__))
- subparsers = parser.add_subparsers(title='actions')
+ subparsers = parser.add_subparsers(title="actions")
# create the parser for the "list" command
- parser_list = subparsers.add_parser('list',
- help='List all the copr of the '
- 'provided '
+ parser_list = subparsers.add_parser("list",
+ help="List all the copr of the "
+ "provided "
)
- parser_list.add_argument("username", nargs='?',
- help='The username that you would like to '
- 'list the copr of (defaults to current user)'
+ parser_list.add_argument("username", nargs="?",
+ help="The username that you would like to "
+ "list the copr of (defaults to current user)"
)
parser_list.set_defaults(func=action_list)
# create the parser for the "create" command
- parser_create = subparsers.add_parser('create',
- help='Create a new copr')
- parser_create.add_argument('name',
- help='The name of the copr to create')
- parser_create.add_argument("--chroot", dest="chroots", action='append',
+ parser_create = subparsers.add_parser("create",
+ help="Create a new copr")
+ parser_create.add_argument("name",
+ help="The name of the copr to create")
+ parser_create.add_argument("--chroot", dest="chroots", action="append",
help="Chroot to use for this copr")
- parser_create.add_argument('--repo', dest='repos', action='append',
+ parser_create.add_argument("--repo", dest="repos", action="append",
help="Repository to add to this copr")
- parser_create.add_argument('--initial-pkgs', dest='initial_pkgs',
- action='append',
+ parser_create.add_argument("--initial-pkgs", dest="initial_pkgs",
+ action="append",
help="List of packages URL to build in this "
"new copr")
- parser_create.add_argument('--description',
+ parser_create.add_argument("--description",
help="Description of the copr")
- parser_create.add_argument('--instructions',
+ parser_create.add_argument("--instructions",
help="Instructions for the copr")
parser_create.set_defaults(func=action_create)
# create the parser for the "build" command
- parser_build = subparsers.add_parser('build',
- help='Build packages to a '
- 'specified copr')
- parser_build.add_argument('copr',
- help='The copr repo to build the package in'
+ parser_build = subparsers.add_parser("build",
+ help="Build packages to a "
+ "specified copr")
+ parser_build.add_argument("copr",
+ help="The copr repo to build the package in"
)
- parser_build.add_argument('pkgs', nargs='+',
- help='URL of packages to build')
- parser_build.add_argument('--memory', dest='memory',
+ parser_build.add_argument("pkgs", nargs="+",
+ help="URL of packages to build")
+ parser_build.add_argument("--memory", dest="memory",
help="")
- parser_build.add_argument('--timeout', dest='timeout',
+ parser_build.add_argument("--timeout", dest="timeout",
help="")
- parser_build.add_argument('--nowait', action="store_true", default=False,
+ parser_build.add_argument("--nowait", action="store_true", default=False,
help="Don't wait for build")
parser_build.set_defaults(func=action_build)
# create the parser for the "status" command
- parser_build = subparsers.add_parser('status',
- help='Get build status of build'
- ' specified by its ID')
- parser_build.add_argument('build_id',
- help='Build ID')
+ parser_build = subparsers.add_parser("status",
+ help="Get build status of build"
+ " specified by its ID")
+ parser_build.add_argument("build_id",
+ help="Build ID")
parser_build.set_defaults(func=action_status)
return parser
def main(argv=sys.argv[1:]):
- """ Main function """
try:
# Set up parser for global args
parser = setup_parser()
@@ -138,10 +137,10 @@ def main(argv=sys.argv[1:]):
sys.stderr.write("\nError: {0}\n".format(e))
sys.stderr.write("Lines in INI file should not be indented.\n")
sys.exit(4)
- #except Exception, e:
- #print 'Error: {0}'.format(e)
- #sys.exit(100)
+ # except Exception as e:
+ # print "Error: {0}".format(e)
+ # sys.exit(100)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/copr_cli/subcommands.py b/copr_cli/subcommands.py
index 2b980ff..0d24fed 100644
--- a/copr_cli/subcommands.py
+++ b/copr_cli/subcommands.py
@@ -23,15 +23,16 @@ def _get_data(req, user, copr=None):
check data and print nice error in case of some error (and return None)
otherwise return json object.
"""
- if '<title>Sign in Coprs</title>' in req.text:
+ if "<title>Sign in Coprs</title>" in req.text:
sys.stderr.write("Invalid API token\n")
return
if req.status_code == 404:
if copr is None:
- sys.stderr.write("User %s is unknown.\n" % user['username'])
+ sys.stderr.write("User {0} is unknown.\n".format(user["username"]))
else:
- sys.stderr.write("Project %s/%s not found.\n" % (user['username'], copr))
+ sys.stderr.write("Project {0}/{1} not found.\n".format(
+ (user["username"], copr)))
return
try:
output = json.loads(req.text)
@@ -39,40 +40,44 @@ def _get_data(req, user, copr=None):
sys.stderr.write("Unknown response from server.\n")
return
if req.status_code != 200:
- sys.stderr.write("Something went wrong:\n {0}\n".format(output['error']))
+ sys.stderr.write(
+ "Something went wrong:\n {0}\n".format(output["error"]))
return
return output
+
def get_user():
""" Retrieve the user information from the config file. """
config = ConfigParser.ConfigParser()
if not config.read(
- os.path.join(os.path.expanduser('~'), '.config', 'copr')):
+ os.path.join(os.path.expanduser("~"), ".config", "copr")):
raise copr_exceptions.CoprCliNoConfException(
- 'No configuration file "~/.config/copr" found. '
- 'See man copr-cli for more information')
+ "No configuration file '~/.config/copr' found. "
+ "See man copr-cli for more information")
try:
- username = config.get('copr-cli', 'username', None)
- login = config.get('copr-cli', 'login', None)
- token = config.get('copr-cli', 'token', None)
- except ConfigParser.Error, err:
+ username = config.get("copr-cli", "username", None)
+ login = config.get("copr-cli", "login", None)
+ token = config.get("copr-cli", "token", None)
+ except ConfigParser.Error as err:
raise copr_exceptions.CoprCliConfigException(
- 'Bad configuration file: %s' % err)
- return {'username': username, 'token': token, 'login': login}
+ "Bad configuration file: {0}".format(err))
+ return {"username": username, "token": token, "login": login}
def get_api_url():
""" Retrieve the user information from the config file. """
config = ConfigParser.ConfigParser()
config.read(
- os.path.join(os.path.expanduser('~'), '.config', 'copr')
+ os.path.join(os.path.expanduser("~"), ".config", "copr")
)
# Default copr_url:
- copr_url = 'https://copr.fedoraproject.org/'
- if config.has_section('copr-cli') and config.has_option('copr-cli', 'copr_url'):
- copr_url = config.get('copr-cli', 'copr_url')
- return '%s/api' % copr_url
+ copr_url = "https://copr.fedoraproject.org/"
+ if (config.has_section("copr-cli") and
+ config.has_option("copr-cli", "copr_url")):
+
+ copr_url = config.get("copr-cli", "copr_url")
+ return "{0}/api".format(copr_url)
def listcoprs(username=None):
@@ -80,94 +85,97 @@ def listcoprs(username=None):
user = {}
if not username:
user = get_user()
- del(user['token'])
+ del(user["token"])
if username:
- user['username'] = username
+ user["username"] = username
copr_api_url = get_api_url()
- url = '{0}/coprs/{1}/'.format(copr_api_url, user['username'])
+ url = "{0}/coprs/{1}/".format(copr_api_url, user["username"])
req = requests.get(url)
output = _get_data(req, user)
if output is None:
return
- elif 'repos' in output:
- if output['repos']:
- for repo in output['repos']:
- print 'Name: {0}'.format(repo['name'])
-
- if 'description' in repo:
- desc = repo['description']
- print ' ' * 2, 'Description: {0}'.format(desc)
-
- if 'yum_repos' in repo:
- yum_repos = repo['yum_repos']
- print ' ' * 2, 'Yum repo(s):'
+ elif "repos" in output:
+ PAD = " " * 2
+ if output["repos"]:
+ for repo in output["repos"]:
+ print("Name: {0}".format(repo["name"]))
+
+ if "description" in repo:
+ desc = repo["description"]
+ print(PAD + "Description: {0}".format(desc))
+
+ if "yum_repos" in repo:
+ yum_repos = repo["yum_repos"]
+ print(PAD + "Yum repo(s):")
for k in sorted(yum_repos.keys()):
- print ' ' * 4, '{0}: {1}'.format(k, yum_repos[k])
+ print(PAD * 2 + "{0}: {1}".format(k, yum_repos[k]))
- if 'additional_repos' in repo:
- add_repos = repo['additional_repos']
- print ' ' * 2, 'Additional repos: {0}'.format(add_repos)
+ if "additional_repos" in repo:
+ add_repos = repo["additional_repos"]
+ print(PAD + "Additional repos: {0}".format(add_repos))
- if 'instructions' in repo:
- instructions = repo['instructions']
- print ' ' * 2, 'Instructions: {0}'.format(instructions)
+ if "instructions" in repo:
+ instructions = repo["instructions"]
+ print(PAD + "Instructions: {0}".format(instructions))
else:
- print 'No copr retrieved for user: "{0}"'.format(
- user['username'])
+ print("No copr retrieved for user: '{0}'".format(
+ user["username"]))
else:
- print 'Un-expected data returned, please report this issue'
+ print("Un-expected data returned, please report this issue")
def create(name, chroots=[], description=None, instructions=None,
repos=None, initial_pkgs=None):
""" Create a new copr. """
if chroots is None:
- print "Error: At least one chroot must be selected"
+ sys.stderr.write("Error: At least one chroot must be selected\n")
sys.exit(1)
+
user = get_user()
copr_api_url = get_api_url()
- URL = '{0}/coprs/{1}/new/'.format(copr_api_url, user['username'])
+ URL = "{0}/coprs/{1}/new/".format(copr_api_url, user["username"])
if type(repos) == list():
- repos = ' '.join(repos)
+ repos = " ".join(repos)
if type(initial_pkgs) == list():
- initial_pkgs = ' '.join(initial_pkgs)
+ initial_pkgs = " ".join(initial_pkgs)
- data = {'name': name,
- 'repos': repos,
- 'initial_pkgs': initial_pkgs,
- 'description': description,
- 'instructions': instructions
+ data = {"name": name,
+ "repos": repos,
+ "initial_pkgs": initial_pkgs,
+ "description": description,
+ "instructions": instructions
}
for chroot in chroots:
- data[chroot] = 'y'
+ data[chroot] = "y"
req = requests.post(URL,
- auth=(user['login'], user['token']),
+ auth=(user["login"], user["token"]),
data=data)
output = _get_data(req, user)
if output is not None:
- print output['message']
+ print(output["message"])
+
def _fetch_status(build_id):
user = get_user()
copr_api_url = get_api_url()
- URL = '{0}/coprs/build_status/{1}/'.format(
+ URL = "{0}/coprs/build_status/{1}/".format(
copr_api_url,
build_id)
- req = requests.get(URL, auth=(user['login'], user['token']))
+ req = requests.get(URL, auth=(user["login"], user["token"]))
output = _get_data(req, user)
if output is None:
- return (False, 'Error occurred.')
- elif 'status' in output:
- return (True, output['status'])
+ return (False, "Error occurred.")
+ elif "status" in output:
+ return (True, output["status"])
else:
- return (False, output['error'])
+ return (False, output["error"])
def status(build_id):
@@ -180,42 +188,42 @@ def build(copr, pkgs, memory, timeout, wait=True):
""" Build a new package into a given copr. """
user = get_user()
copr_api_url = get_api_url()
- URL = '{0}/coprs/{1}/{2}/new_build/'.format(
+ URL = "{0}/coprs/{1}/{2}/new_build/".format(
copr_api_url,
- user['username'],
+ user["username"],
copr)
- data = {'pkgs': ' '.join(pkgs),
- 'memory': memory,
- 'timeout': timeout
+ data = {"pkgs": " ".join(pkgs),
+ "memory": memory,
+ "timeout": timeout
}
req = requests.post(URL,
- auth=(user['login'], user['token']),
+ auth=(user["login"], user["token"]),
data=data)
output = _get_data(req, user, copr)
if output is None:
return
else:
- print output['message']
+ print(output["message"])
if wait:
- print("Build ID: {0}".format(output['id']))
+ print("Build ID: {0}".format(output["id"]))
print("Watching build (this may be safely interrupted)...")
prevstatus = None
try:
while True:
- (ret, status) = _fetch_status(output['id'])
+ (ret, status) = _fetch_status(output["id"])
if not ret:
print("Unable to get build status: {0}".format(status))
return False
now = datetime.datetime.now()
if prevstatus != status:
- print("{0} {1}".format(now.strftime('%H:%M:%S'), status))
+ print("{0} {1}".format(now.strftime("%H:%M:%S"), status))
prevstatus = status
- if status in ['succeeded', 'failed']:
+ if status in ["succeeded", "failed"]:
return True
time.sleep(60)
10 years, 3 months