The database lookups of the user and repositories are moved outside, into the callers, which have already looked up the relevant objects, thus saving two database lookups when creating a PR.
db: rename UserFollowing.follows_repo_id to follows_repository_id
Since the relationship is 'follows_repository', rename the column to be 'follows_repository_id', not 'follows_repo_id'. This also makes the Python column name match the actual database column name.
(The inconsistency dates back to early RhodeCode days.)
Many calls to Session().flush() were completely superfluous and have been removed. (See also the note on "flush" in the contributor docs.) For the remaining calls, a comment has been added to explain why it's necessary.
style: put all datatable widgets on one line above the table
This makes tables look less messy - especially on the repogroups page where there are 2 datatables.
We put all the info above the template so it is visible and stays in the same place, no matter how many entries are shown or if filtering change the number.
TODO: We should probably get a wrapper around datatable instead of repeating this so many times ...
templates: fix dropdown functionality of current menu item
After 3e46e6b6a27a, the 'current' menu would have two class attributes and it would not work as a dropdown. For example, it was not possible to navigate from Admin>Users to Admin>User Groups.
Instead, get rid of the is_current "helper" and just handle classes explicitly. That might be slightly more verbose but is also more explicit ... and it works.
template: remove obsolete filter textbox and user_group_count
I used grep to find any reference to user_group_count but found none. So there seems to be no code that actually sets this count. So I removed it. And since the table is a datatable the filter is redundant anyway.
To simplify email filtering, add a header indicating the type of email being sent. The 'type_' value corresponds to one of the types defined in class Notification in kallithea/model/db.py, e.g. 'cs_comment', 'pull_request', 'pull_request_comment', ...
lib: move get_custom_lexer from utils to pygmentsutils
get_custom_lexer is the only dependency from helpers to utils. In attempting to get a clearer dependency tree, we can move out get_custom_lexer to a different place so that helpers does not depend on utils.
It so happens that there already is a pygmentsutils.py file in lib, which is a very good fit, since the lexers used in Kallithea are effectively provided by pygments.
To avoid circular imports, we need to determine some 'rules'. Helpers have minimal dependencies to model. Most of the model imports that are currently global are only used in a few methods. Therefore, it makes sense to make these imports local to the method, so they won't 'count' for circular imports at module level.
helpers.py imported tons of unused names. Most of these are assumed to be due to historical changes without cleanup. Several webhelpers names were imported as a group, but this is not deemed useful.
helpers: move Page/RepoPage to a separate file page.py
The Page and RepoPage classes are not used from templates and thus do not belong in helpers. They could have been put in utils.py, but because they are completely standalone we can easily split them to a separate file.
model: rename db.BaseModel to avoid confusion with base.BaseModel
There exist two BaseModel classes in kallithea.model: - kallithea.model.base.BaseModel (previously kallithea.model.BaseModel) - kallithea.model.db.BaseModel
Needless to say, this is very confusing, so rename one of them.
Having too much code, in particular too much imports, inside a package's __init__.py is a recipe for circular imports, and considered bad practice in Python [1]
Move out everything from kallithea/model/__init__.py to a new file kallithea/model/base.py and adapt the existing imports.
helpers: allow to set class for repo_link breadcrumb links
This helps Bootstrap support.
(Since this is a high level function that returns several links and not just a single html element, the patch has been modified to only allow specifying a class that is used for all the links.)
Don't take a database object, grab its ID, then use the ID to load the same database object once again. This also applies to creating AuthUser objects, which will happily take a User object instead of a user_id.
cleanup: don't check if currently logged-in user exists
Don't check if the currently logged-in User exists. Every request runs in a database transaction; if the object existed at the start, it still exists (unless we add a way for a user to delete themselves).
Rename the 'user_id' field to 'author_id' and replace other references to the comment 'user' throughout the model. The database column name 'user_id' remain unchanged for now; a later Alembic script can fix the name of these and other columns to match their Python name.
db: PullRequest/Repository/RepoGroup/UserGroup: change 'user' to 'owner'
Rename the 'user' and 'user_id' fields on the four classes to something more informative. The database column names remain unchanged for now; a later Alembic script can fix the name of these and other columns to match their Python name.
This might break rcextensions, though, and external scripts that use the HTML form interface.
Don't re-add objects to the SQLAlchemy Session just because they were modified. Session.add is only for freshly constructed objects that SQLAlchemy doesn't know about yet.
The rules are quite simple:
When creating a database object by calling the constructor directly, it must explicitly be added to the session.
When creating an object using a factory function (like "create_repo"), the returned object has already (by convention) been added to the session, and should not be added again.
When getting an object from the session (via Session.query or any of the utility functions that look up objects in the database), it's already added, and should not be added again. SQLAlchemy notices attribute modifications automatically for all objects it knows about.
db: do case-insensitive explicit sorting of RepoGroup names
This does not change the implicit sorting enabled via __mapper_args__, which is a bad idea anyway (and now deprecated), and will have to be dealt with in a later changeset.
The use of __mapper_args__ implicitly adds sorting to every query of RepoGroup objects throughout the code (including implicit queries via relationships). For the relationships, __mapper_args can be replaced with "order_by" on each individual relationship, and it's reasonably straight-forward to identify every RepoGroup query throughout the code, and add explicit sorting. But we don't really need that sorting most of the time, so a better way forward may be to identify all the places that actually needs the sorting, make it explicit there, and then kill the __mapper_args__. (Anyway, future work.)
db: always do case-insensitive sorting of repository names
We retain the implicit order_by on the follows_repository relationship. This is probably a bad idea, since it causes sorting even when it's not needed; but for now, at least, we consistently do case-insensitive sort.