#4202 Add support for a settings page for 3rd party apps + move create_session to a better place
Merged 5 years ago by pingou. Opened 5 years ago by pingou.

file modified
+1 -1
@@ -694,7 +694,7 @@ 

          empty_dev_db(meta, eng)

  

      if args.populate or args.all:

-         session = pagure.lib.query.create_session(_config['DB_URL'])

+         session = pagure.lib.model_base.create_session(_config['DB_URL'])

          invalid_option = ['pingou', 'bar@pingou.com', 'foo', 'foo@bar.com']

          print("")

          user_name = six.moves.input(

file modified
+4 -3
@@ -8,9 +8,10 @@ 

  from sqlalchemy.exc import SQLAlchemyError

  

  import pagure.config

- import pagure.lib.query

- import pagure.lib.notify

  import pagure.lib.model as model

+ import pagure.lib.model_base

+ import pagure.lib.notify

+ import pagure.lib.query

  

  if 'PAGURE_CONFIG' not in os.environ \

          and os.path.exists('/etc/pagure/pagure.cfg'):
@@ -29,7 +30,7 @@ 

      email_dates = [email_day.date() for email_day in \

              [current_time + timedelta(days=i) for i in day_diff_for_mail]]

  

-     session = pagure.lib.query.create_session(_config['DB_URL'])

+     session = pagure.lib.model_base.create_session(_config['DB_URL'])

      tokens = session.query(model.Token).all()

  

      for token in tokens:

file modified
+4 -3
@@ -8,9 +8,10 @@ 

  from sqlalchemy.exc import SQLAlchemyError

  

  import pagure.config

- import pagure.lib.query

- import pagure.lib.notify

  import pagure.lib.model as model

+ import pagure.lib.model_base

+ import pagure.lib.notify

+ import pagure.lib.query

  

  if 'PAGURE_CONFIG' not in os.environ \

          and os.path.exists('/etc/pagure/pagure.cfg'):
@@ -23,7 +24,7 @@ 

  def main(check=False, debug=False):

      ''' The function pulls in all the changes from upstream'''

  

-     session = pagure.lib.query.create_session(_config['DB_URL'])

+     session = pagure.lib.model_base.create_session(_config['DB_URL'])

      projects = session.query(

          model.Project

      ).filter(

@@ -40,6 +40,7 @@ 

  

  

  import pagure  # noqa: E402

+ import pagure.lib.model_base  # noqa: E402

  import pagure.lib.query  # noqa: E402

  from pagure.exceptions import PagureException, PagureEvException  # noqa: E402

  
@@ -55,7 +56,7 @@ 

      global SESSION

      if SESSION is None:

          print(pagure.config.config['DB_URL'])

-         SESSION = pagure.lib.query.create_session(

+         SESSION = pagure.lib.model_base.create_session(

              pagure.config.config['DB_URL'])

  

      return SESSION

@@ -22,6 +22,7 @@ 

  from Milter.utils import parse_addr

  

  import pagure.config

+ import pagure.lib.model_base

  import pagure.lib.query

  

  
@@ -157,7 +158,7 @@ 

          # they are trying to forge their ID into someone else's

          salt = _config.get('SALT_EMAIL')

          from_email = clean_item(msg['From'])

-         session = pagure.lib.query.create_session(_config['DB_URL'])

+         session = pagure.lib.model_base.create_session(_config['DB_URL'])

          try:

              user = pagure.lib.query.get_user(session, from_email)

          except:

file modified
+3 -2
@@ -30,13 +30,14 @@ 

  import pagure.config  # noqa: E402

  import pagure.exceptions  # noqa: E402

  import pagure.lib.git  # noqa: E402

+ import pagure.lib.model_base  # noqa: E402

  import pagure.lib.query  # noqa: E402

  import pagure.lib.tasks_utils  # noqa: E402

  from pagure.flask_app import generate_user_key_files  # noqa: E402

  

  

  _config = pagure.config.reload_config()

- session = pagure.lib.query.create_session(_config["DB_URL"])

+ session = pagure.lib.model_base.create_session(_config["DB_URL"])

  _log = logging.getLogger(__name__)

  

  
@@ -1021,7 +1022,7 @@ 

  

          global session, _config

          _config = pagure.config.reload_config()

-         session = pagure.lib.query.create_session(_config["DB_URL"])

+         session = pagure.lib.model_base.create_session(_config["DB_URL"])

  

      logging.basicConfig()

      if args.debug:

file modified
+3 -2
@@ -21,8 +21,9 @@ 

  import pagure.config

  import pagure.doc_utils

  import pagure.exceptions

- import pagure.lib.query

  import pagure.lib.mimetype

+ import pagure.lib.model_base

+ import pagure.lib.query

  import pagure.forms

  

  # Create the application.
@@ -31,7 +32,7 @@ 

  # set up FAS

  APP.config = pagure.config.reload_config()

  

- SESSION = pagure.lib.query.create_session(APP.config["DB_URL"])

+ SESSION = pagure.lib.model_base.create_session(APP.config["DB_URL"])

  

  if not APP.debug:

      APP.logger.addHandler(

file modified
+1 -1
@@ -237,7 +237,7 @@ 

      """ Prepare every request. """

      flask.session.permanent = True

      if not hasattr(flask.g, "session") or not flask.g.session:

-         flask.g.session = pagure.lib.query.create_session(

+         flask.g.session = pagure.lib.model_base.create_session(

              flask.current_app.config["DB_URL"]

          )

  

file modified
+1 -1
@@ -499,7 +499,7 @@ 

          raise ValueError("Hook type %s not valid" % hooktype)

      changes = extract_changes(from_stdin=hooktype != "update")

  

-     session = pagure.lib.query.create_session(pagure_config["DB_URL"])

+     session = pagure.lib.model_base.create_session(pagure_config["DB_URL"])

      if not session:

          raise Exception("Unable to initialize db session")

  

@@ -22,6 +22,7 @@ 

      sys.path.append(PYPATH)

  

  import pagure

+ import pagure.lib.model_base

  import pagure.lib.query

  from pagure.hooks import run_project_hooks, extract_changes

  from pagure.config import config as pagure_config
@@ -40,7 +41,7 @@ 

  

  changes = extract_changes(from_stdin=hooktype != "update")

  

- session = pagure.lib.query.create_session(pagure_config["DB_URL"])

+ session = pagure.lib.model_base.create_session(pagure_config["DB_URL"])

  if not session:

      raise Exception("Unable to initialize db session")

  

file modified
+1 -1
@@ -1224,7 +1224,7 @@ 

          print(out)

          print(err)

      if not keepends:

-         out = out.rstrip(u"\n\r")

+         out = out.rstrip("\n\r")

Are you sure about this?
Since you have introduce these changes few days ago => https://pagure.io/pagure/c/6e566ade3b0907121b71d4c2c56b7e0d3169bf06?branch=master

Yes, python black removed it though and since we have decoded the string earlier I thought we should be safe here now.

  

      if error:

          return (out, err)

file modified
+4 -1
@@ -23,6 +23,7 @@ 

  from six.moves import dbm_gnu

  

  import pagure.exceptions

+ import pagure.lib.model_base

  import pagure.lib.query

  from pagure.config import config as pagure_config

  from pagure.lib import model
@@ -752,7 +753,9 @@ 

          _log.info("Refresh gitolite configuration")

  

          if project is not None or group is not None:

-             session = pagure.lib.query.create_session(pagure_config["DB_URL"])

+             session = pagure.lib.model_base.create_session(

+                 pagure_config["DB_URL"]

+             )

              cls.write_gitolite_acls(

                  session,

                  project=project,

file modified
+1 -1
@@ -1049,7 +1049,7 @@ 

          self.ltype = ltype

  

      def __enter__(self):

-         from pagure.lib.query import create_session

+         from pagure.lib.model_base import create_session

  

          self.session = create_session()

  

file modified
+56 -2
@@ -10,8 +10,11 @@ 

  

  from __future__ import unicode_literals, absolute_import

  

- from sqlalchemy import MetaData

+ import sqlalchemy

  from sqlalchemy.ext.declarative import declarative_base

+ from sqlalchemy.orm import sessionmaker

+ from sqlalchemy.orm import scoped_session

+ 

  

  CONVENTION = {

      "ix": "ix_%(table_name)s_%(column_0_label)s",
@@ -22,4 +25,55 @@ 

      "uq": "%(table_name)s_%(column_0_name)s_key",

  }

  

- BASE = declarative_base(metadata=MetaData(naming_convention=CONVENTION))

+ BASE = declarative_base(

+     metadata=sqlalchemy.MetaData(naming_convention=CONVENTION)

+ )

+ 

+ 

+ SESSIONMAKER = None

+ 

+ 

+ def create_session(db_url=None, debug=False, pool_recycle=3600):

+     """ Create the Session object to use to query the database.

+ 

+     :arg db_url: URL used to connect to the database. The URL contains

+     information with regards to the database engine, the host to connect

+     to, the user and password and the database name.

+       ie: <engine>://<user>:<password>@<host>/<dbname>

+     :kwarg debug: a boolean specifying whether we should have the verbose

+         output of sqlalchemy or not.

+     :return a Session that can be used to query the database.

+ 

+     """

+     global SESSIONMAKER

+ 

+     if SESSIONMAKER is None or (

+         db_url and db_url != ("%s" % SESSIONMAKER.kw["bind"].engine.url)

+     ):

+         if db_url is None:

+             raise ValueError("First call to create_session needs db_url")

+         if db_url.startswith("postgres"):  # pragma: no cover

+             engine = sqlalchemy.create_engine(

+                 db_url,

+                 echo=debug,

+                 pool_recycle=pool_recycle,

+                 client_encoding="utf8",

+             )

+         else:  # pragma: no cover

+             engine = sqlalchemy.create_engine(

+                 db_url, echo=debug, pool_recycle=pool_recycle

+             )

+ 

+         if db_url.startswith("sqlite:"):

+             # Ignore the warning about con_record

+             # pylint: disable=unused-argument

+             def _fk_pragma_on_connect(dbapi_con, _):  # pragma: no cover

+                 """ Tries to enforce referential constraints on sqlite. """

+                 dbapi_con.execute("pragma foreign_keys=ON")

+ 

+             sqlalchemy.event.listen(engine, "connect", _fk_pragma_on_connect)

+         SESSIONMAKER = sessionmaker(bind=engine)

+ 

+     scopedsession = scoped_session(SESSIONMAKER)

+     BASE.metadata.bind = scopedsession

+     return scopedsession

file modified
+3 -51
@@ -48,8 +48,6 @@ 

  from sqlalchemy import func

  from sqlalchemy import asc, desc

  from sqlalchemy.orm import aliased

- from sqlalchemy.orm import sessionmaker

- from sqlalchemy.orm import scoped_session

  from flask import url_for

  

  import pagure.exceptions
@@ -65,6 +63,9 @@ 

  from pagure.config import config as pagure_config

  from pagure.lib import model

  

+ # For backward compatibility since this function used to be in this file

+ from pagure.lib.model_base import create_session  # noqa

+ 

  

  REDIS = None

  PAGURE_CI = None
@@ -139,55 +140,6 @@ 

      return query.first()

  

  

- SESSIONMAKER = None

- 

- 

- def create_session(db_url=None, debug=False, pool_recycle=3600):

-     """ Create the Session object to use to query the database.

- 

-     :arg db_url: URL used to connect to the database. The URL contains

-     information with regards to the database engine, the host to connect

-     to, the user and password and the database name.

-       ie: <engine>://<user>:<password>@<host>/<dbname>

-     :kwarg debug: a boolean specifying whether we should have the verbose

-         output of sqlalchemy or not.

-     :return a Session that can be used to query the database.

- 

-     """

-     global SESSIONMAKER

- 

-     if SESSIONMAKER is None or (

-         db_url and db_url != ("%s" % SESSIONMAKER.kw["bind"].engine.url)

-     ):

-         if db_url is None:

-             raise ValueError("First call to create_session needs db_url")

-         if db_url.startswith("postgres"):  # pragma: no cover

-             engine = sqlalchemy.create_engine(

-                 db_url,

-                 echo=debug,

-                 pool_recycle=pool_recycle,

-                 client_encoding="utf8",

-             )

-         else:  # pragma: no cover

-             engine = sqlalchemy.create_engine(

-                 db_url, echo=debug, pool_recycle=pool_recycle

-             )

- 

-         if db_url.startswith("sqlite:"):

-             # Ignore the warning about con_record

-             # pylint: disable=unused-argument

-             def _fk_pragma_on_connect(dbapi_con, _):  # pragma: no cover

-                 """ Tries to enforce referential constraints on sqlite. """

-                 dbapi_con.execute("pragma foreign_keys=ON")

- 

-             sqlalchemy.event.listen(engine, "connect", _fk_pragma_on_connect)

-         SESSIONMAKER = sessionmaker(bind=engine)

- 

-     scopedsession = scoped_session(SESSIONMAKER)

-     model.BASE.metadata.bind = scopedsession

-     return scopedsession

- 

- 

  def get_next_id(session, projectid):

      """ Returns the next identifier of a project ticket or pull-request

      based on the identifier already in the database.

file modified
+2 -2
@@ -13,7 +13,7 @@ 

  import gc

  from functools import wraps

  

- import pagure.lib.query

+ import pagure.lib.model_base

  from pagure.config import config as pagure_config

  

  
@@ -31,7 +31,7 @@ 

                  self.update_state(state="RUNNING")

              except TypeError:

                  pass

-         session = pagure.lib.query.create_session(pagure_config["DB_URL"])

+         session = pagure.lib.model_base.create_session(pagure_config["DB_URL"])

          try:

              return function(self, session, *args, **kwargs)

          except:  # noqa: E722

@@ -101,6 +101,18 @@ 

              <a class="nav-item nav-link" id="deleteproject" data-toggle="tab"

              href="#deleteproject-tab" role="tab" aria-controls="deleteproject">Delete Project</a>

            {% endif %}

+ 

+           {% for blueprint in main_app.iter_blueprints() %}

+             {% if blueprint.name not in [

+                     'api_ns', 'ui_ns', 'internal_ns', 'theme'] %}

+               <a class="nav-item nav-link thirdparty_settings"

+                 id="{{ blueprint.name }}" data-name="{{ blueprint.name }}"

+                 data-url="{{ url_for(

+                     '%s.settings' % blueprint.name,

+                     repo=repo.name, namespace=repo.namespace) }}"

+               href="#{{ blueprint.name }}-tab">{{ blueprint.name }}</a>

+             {% endif %}

+           {% endfor %}

          </div>

        </nav>

      </div>
@@ -1065,10 +1077,10 @@ 

            {% endif %}

  

  

-     {% if (not repo.is_fork and config.get('ENABLE_DEL_PROJECTS', True))

-     or

-     (repo.is_fork and config.get('ENABLE_DEL_FORKS',

-           config.get('ENABLE_DEL_PROJECTS', True))) %}

+           {% if (not repo.is_fork and config.get('ENABLE_DEL_PROJECTS', True))

+           or

+           (repo.is_fork and config.get('ENABLE_DEL_FORKS',

+                 config.get('ENABLE_DEL_PROJECTS', True))) %}

            <div class="tab-pane fade" id="deleteproject-tab" role="tabpanel" aria-labelledby="deleteproject-tab">

                <h3 class="font-weight-bold mb-3">

                  Delete Project
@@ -1198,6 +1210,32 @@ 

    $(this).parent().parent().remove();

  });

  

+ $('.thirdparty_settings').click(function() {

+   $('.tab-pane fade active show').removeClass("active").removeClass("show");

+   let name = $(this).attr("data-name");

+   let target = $(this).attr("data-url");

+   let _el = $('#' + name + '-tab');

+   if (_el.length == 0) {

+     $.ajax({

+       url: target ,

+       type: 'GET',

+       dataType: 'html',

+       success: function(res) {

+         let _txt = '<div class="tab-pane fade active show" '

+         + 'id="' + name + '-tab" role="tabpanel" role="tabpanel"'

+         + 'aria-labelledby="' + name + '-tab">'

+         + res

+         + '</div>';

+           $("#nav-tabContent").append(_txt);

+       },

+     });

+   } else {

+     _el.show();

+   }

+   return false;

+ });

+ 

+ 

  {% if not repo.priorities %}

  $('#default_priorities').click(function(e) {

    let row = $('#priorities-list .blank-field');

file modified
+2 -1
@@ -22,6 +22,7 @@ 

  import pagure.login_forms as forms

  import pagure.lib.login

  import pagure.lib.model as model

+ import pagure.lib.model_base

  import pagure.lib.notify

  import pagure.lib.query

  from pagure.utils import login_required
@@ -435,7 +436,7 @@ 

      """ Set the user into flask.g if the user is logged in.

      """

      if not hasattr(flask.g, "session") or not flask.g.session:

-         flask.g.session = pagure.lib.query.create_session(

+         flask.g.session = pagure.lib.model_base.create_session(

              flask.current_app.config["DB_URL"]

          )

  

file modified
+1
@@ -1261,6 +1261,7 @@ 

          plugins=plugins,

          branchname=branchname,

          pagure_admin=pagure.utils.is_admin(),

+         main_app=flask.current_app,

      )

  

  

no initial comment

I guess an import is missing:

import pagure.lib.model_base

Consider to use debtcollector => https://docs.openstack.org/debtcollector/latest/reference/index.html#module-debtcollector.moves
Display a warning and inform users that this function has moved to an other module.

debtcollector cannot be used without triggering Pagure's license to change from GPLv2 to GPLv3, since OpenStack stuff is ASL 2.0.

Interesting lib, but it adds a new dependency :(

np :) I understand the license problem and the dependency adding

rebased onto 2c735374e2cf31cc15d9401457eb09cbad756699

5 years ago

1 new commit added

  • Black fix
5 years ago

pretty please pagure-ci rebuild

5 years ago

1 new commit added

  • Project wide black fixes
5 years ago

1 new commit added

  • Small flake8 fix
5 years ago

rebased onto a7b173f5852feab571c2187b8c3bc6126fdc2e19

5 years ago

This passed CI last time, hopefully it will again :)

(if someone wants to formally approve/comment on it :))

Are you sure about this?
Since you have introduce these changes few days ago => https://pagure.io/pagure/c/6e566ade3b0907121b71d4c2c56b7e0d3169bf06?branch=master

I guess you need to rebase or something like that

Yes, python black removed it though and since we have decoded the string earlier I thought we should be safe here now.

I'm ok with that :thumbsup:

Thanks, let's get this in then :)

rebased onto 1fa1790

5 years ago

Pull-Request has been merged by pingou

5 years ago