From 30af48ac3cb478ecb998dc97014131c8e9b9c4dd Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 16 2015 16:35:58 +0000
Subject: [PATCH 1/7] Implement searching for users in pagure


---

diff --git a/pagure/templates/master.html b/pagure/templates/master.html
index 9cc7754..b9a7d24 100644
--- a/pagure/templates/master.html
+++ b/pagure/templates/master.html
@@ -23,6 +23,18 @@
         <div id="header">
           <img src="{{ url_for('static', filename='pagure-logo.png') }}"
             alt="pagure Logo" id="kojiLogo"/>
+          <form action="{{url_for('search')}}" id="headerSearch">
+            <select name="type">
+              <option value="projects"
+                {% if select=='projects' %} selected {% endif %}>
+                  Projects</option>
+              <option value="user"
+                {% if select=='users' %} selected {% endif %}>
+                  Users</option>
+            </select>
+            <input type="text" name="term"/>
+            <input type="submit" value="Search"/>
+          </form>
         </div><!-- end header -->
 
         <!-- MAIN NAVIGATION -->
diff --git a/pagure/ui/app.py b/pagure/ui/app.py
index 60e8439..33f5477 100644
--- a/pagure/ui/app.py
+++ b/pagure/ui/app.py
@@ -125,9 +125,29 @@ def index():
     )
 
 
+@APP.route('/search/')
+@APP.route('/search')
+def search():
+    """ Search this pagure instance for projects or users.
+    """
+    stype = flask.request.args.get('type', 'projects')
+    term = flask.request.args.get('term')
+    page = flask.request.args.get('page', 1)
+    try:
+        page = int(page)
+    except ValueError:
+        page = 1
+
+    if stype == 'projects':
+        return flask.redirect(flask.url_for('index'))
+    else:
+        return flask.redirect(flask.url_for('view_users', username=term))
+
+
 @APP.route('/users/')
 @APP.route('/users')
-def view_users():
+@APP.route('/users/<username>')
+def view_users(username=None):
     """ Present the list of users.
     """
     page = flask.request.args.get('page', 1)
@@ -136,7 +156,12 @@ def view_users():
     except ValueError:
         page = 1
 
-    users = pagure.lib.search_user(SESSION)
+    users = pagure.lib.search_user(SESSION, pattern=username)
+
+    if len(users) == 1:
+        flask.flash('Only one result found, redirecting you to it')
+        return flask.redirect(
+            flask.url_for('view_user', username=users[0].username))
 
     limit = APP.config['ITEM_PER_PAGE']
     start = limit * (page - 1)

From 70be16ae17a0283d7ef5f118d480681960ebc467 Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 17 2015 05:41:22 +0000
Subject: [PATCH 2/7] Expand the search_projects in the internal library to support searching with a pattern


---

diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py
index eef1d92..f286c9c 100644
--- a/pagure/lib/__init__.py
+++ b/pagure/lib/__init__.py
@@ -1184,7 +1184,7 @@ def fork_project(session, user, repo, gitfolder,
 
 
 def search_projects(
-        session, username=None, fork=None, tags=None,
+        session, username=None, fork=None, tags=None, pattern=None,
         start=None, limit=None, count=False):
     '''List existing projects
     '''
@@ -1258,6 +1258,12 @@ def search_projects(
             model.TagProject.tag.in_(tags)
         )
 
+    if pattern:
+        pattern = pattern.replace('*', '%')
+        projects = projects.filter(
+            model.Project.name.like(pattern)
+        )
+
     query = session.query(
         model.Project
     ).filter(

From 664d796c53eb36b1d9e7270f6f22d5e1fcc03f3c Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 17 2015 05:42:05 +0000
Subject: [PATCH 3/7] Create a new endpoint to list the projects and redirect to it from the search endpoint


---

diff --git a/pagure/ui/app.py b/pagure/ui/app.py
index 33f5477..2a7d1eb 100644
--- a/pagure/ui/app.py
+++ b/pagure/ui/app.py
@@ -139,7 +139,10 @@ def search():
         page = 1
 
     if stype == 'projects':
-        return flask.redirect(flask.url_for('index'))
+        return flask.redirect(flask.url_for('view_projects', pattern=term))
+    elif stype == 'projects_forks':
+        return flask.redirect(flask.url_for(
+            'view_projects', pattern=term, forks=True))
     else:
         return flask.redirect(flask.url_for('view_users', username=term))
 
@@ -177,6 +180,59 @@ def view_users(username=None):
         users_length=users_length,
         total_page=total_page,
         page=page,
+        select='users',
+    )
+
+
+
+@APP.route('/projects/')
+@APP.route('/projects')
+@APP.route('/projects/<pattern>')
+def view_projects(pattern=None):
+    """ Present the list of projects.
+    """
+    forks = flask.request.args.get('forks', False)
+    page = flask.request.args.get('page', 1)
+
+    try:
+        page = int(page)
+    except ValueError:
+        page = 1
+
+    select = 'projects'
+    # If forks is specified, we want both forks and projects
+    if str(forks).lower() in ['true', '1']:
+        forks = None
+        select = 'projects_forks'
+
+    limit = APP.config['ITEM_PER_PAGE']
+    start = limit * (page - 1)
+
+
+    projects = pagure.lib.search_projects(
+        SESSION, pattern=pattern, fork=forks, start=start, limit=limit)
+
+    if len(projects) == 1:
+        flask.flash('Only one result found, redirecting you to it')
+        return flask.redirect(flask.url_for(
+            'view_repo', repo=projects[0].name,
+            username=projects[0].user.username if projects[0].is_fork else None
+        ))
+
+    limit = APP.config['ITEM_PER_PAGE']
+    start = limit * (page - 1)
+    end = limit * page
+    projects_length = len(projects)
+    projects = projects[start:end]
+
+    total_page = int(ceil(projects_length / float(limit)))
+
+    return flask.render_template(
+        'index.html',
+        repos=projects,
+        total_page=total_page,
+        page=page,
+        select=select,
     )
 
 

From e06ebcff178021db2b0925e982c641cabee7046e Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 17 2015 05:42:26 +0000
Subject: [PATCH 4/7] Add the option to search both projects and forks


---

diff --git a/pagure/templates/master.html b/pagure/templates/master.html
index b9a7d24..5ca4600 100644
--- a/pagure/templates/master.html
+++ b/pagure/templates/master.html
@@ -28,6 +28,9 @@
               <option value="projects"
                 {% if select=='projects' %} selected {% endif %}>
                   Projects</option>
+              <option value="projects_forks"
+                {% if select=='projects_forks' %} selected {% endif %}>
+                  Projects &amp; Forks</option>
               <option value="user"
                 {% if select=='users' %} selected {% endif %}>
                   Users</option>

From 2ccd5c3679cb047eeed268ab574050be9d17b051 Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 17 2015 05:45:57 +0000
Subject: [PATCH 5/7] No need to use LIKE if there is no % in the pattern


---

diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py
index f286c9c..110f551 100644
--- a/pagure/lib/__init__.py
+++ b/pagure/lib/__init__.py
@@ -1260,9 +1260,14 @@ def search_projects(
 
     if pattern:
         pattern = pattern.replace('*', '%')
-        projects = projects.filter(
-            model.Project.name.like(pattern)
-        )
+        if '%' in pattern:
+            projects = projects.filter(
+                model.Project.name.like(pattern)
+            )
+        else:
+            projects = projects.filter(
+                model.Project.name == pattern
+            )
 
     query = session.query(
         model.Project

From 3799b0fcf37b79847d479f74ae7f31716c993b53 Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 17 2015 05:49:14 +0000
Subject: [PATCH 6/7] Add a title to the input field to mention the possibility to use '*'


---

diff --git a/pagure/templates/master.html b/pagure/templates/master.html
index 5ca4600..ecc4985 100644
--- a/pagure/templates/master.html
+++ b/pagure/templates/master.html
@@ -35,7 +35,8 @@
                 {% if select=='users' %} selected {% endif %}>
                   Users</option>
             </select>
-            <input type="text" name="term"/>
+            <input type="text" name="term"
+                title="Search field, use * to broaden your search" />
             <input type="submit" value="Search"/>
           </form>
         </div><!-- end header -->

From ab7d20fd18b862828e7799fd61262b274dbbc2aa Mon Sep 17 00:00:00 2001
From: Pierre-Yves Chibon <pingou@pingoured.fr>
Date: Aug 17 2015 05:55:21 +0000
Subject: [PATCH 7/7] Ensure we filter out forks unless we specify we want them


---

diff --git a/pagure/ui/app.py b/pagure/ui/app.py
index 2a7d1eb..85d9b1e 100644
--- a/pagure/ui/app.py
+++ b/pagure/ui/app.py
@@ -191,7 +191,7 @@ def view_users(username=None):
 def view_projects(pattern=None):
     """ Present the list of projects.
     """
-    forks = flask.request.args.get('forks', False)
+    forks = flask.request.args.get('forks')
     page = flask.request.args.get('page', 1)
 
     try:
@@ -204,6 +204,8 @@ def view_projects(pattern=None):
     if str(forks).lower() in ['true', '1']:
         forks = None
         select = 'projects_forks'
+    else:
+        forks = False
 
     limit = APP.config['ITEM_PER_PAGE']
     start = limit * (page - 1)

