Repository: gratipay/gratipay.com

Issue:
Improve search box
Suggested by Liz Pullen via [Twitter](https://twitter.com/nwjerseyliz/status/290248651035529216):

> Just looked into Gittip...at any point, will it be searchable? So, you'd search for people working on specific kinds of projects?

Adding this to The Nexus:

https://github.com/gittip/www.gittip.com/issues?milestone=25&state=open

<bountysource-plugin>

---

Want to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/316697-add-search-over-participants?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github).
</bountysource-plugin>



Discussion:
+1 from @abnor over on #689:

> To be able to find people whom you would like to donate to, a search engine is a must. Though it takes away from personal funding, it does help to be able to find them!
> 
> Requires users to pick a demographic category, for example
> - artist/musician/writer
> - engineer/software/hardware
> - community/volunteer/education
> - etc.

> Requires users to pick a demographic category, for example

@abnor I agree that users should be able to categorize themselves; I think of that under "community pages" (#496). I think search should encompass that but we can implement search without it if we want. To start with we can index username and statement.

If not for categories to search under, in the mean time you can do keyword searches based on statements. I know OKcupid does that.

http://blog.okcupid.com/index.php/page/5/

> [I]n the mean time you can do keyword searches based on statements.

Yup. Anyone interested in tackling this?

https://www.gittip.com/?limit=1000 Is there potential to make this feature a drop down menu option as a sort of primitive search engine?

+1 from @LenKendall via [Twitter](https://twitter.com/LenKendall/status/315218920988606464).

+1 from @MagDent via [Twitter](https://twitter.com/lemonylane/status/339877273991794689).

+1 from @paulhoule in [IRC](https://botbot.me/freenode/gittip/msg/12823994/).

+1 from me too. This would be great to have :cat: 

Tagged "Ready to Start" and added to the Onboarding milestone.


Resolving patch:
diff --git a/gratipay/models/participant.py b/gratipay/models/participant.py
--- a/gratipay/models/participant.py
+++ b/gratipay/models/participant.py
@@ -61,6 +61,8 @@
 
 NOTIFIED_ABOUT_EXPIRATION = b'notifiedAboutExpiration'
 
+USERNAME_MAX_SIZE = 32
+
 class Participant(Model, MixinTeam):
     """Represent a Gratipay participant.
     """
@@ -239,12 +241,13 @@ def upsert_statement(self, lang, statement):
          RETURNING true
         """, (statement, self.id, lang))
         if not r:
+            search_conf = i18n.SEARCH_CONFS.get(lang, 'simple')
             try:
                 self.db.run("""
                     INSERT INTO statements
-                                (lang, content, participant)
-                         VALUES (%s, %s, %s)
-                """, (lang, statement, self.id))
+                                (lang, content, participant, search_conf)
+                         VALUES (%s, %s, %s, %s)
+                """, (lang, statement, self.id, search_conf))
             except IntegrityError:
                 return self.upsert_statement(lang, statement)
 
@@ -713,7 +716,7 @@ def change_username(self, suggested):
         if not suggested:
             raise UsernameIsEmpty(suggested)
 
-        if len(suggested) > 32:
+        if len(suggested) > USERNAME_MAX_SIZE:
             raise UsernameTooLong(suggested)
 
         if set(suggested) - ASCII_ALLOWED_IN_USERNAME:
diff --git a/gratipay/utils/i18n.py b/gratipay/utils/i18n.py
--- a/gratipay/utils/i18n.py
+++ b/gratipay/utils/i18n.py
@@ -65,6 +65,26 @@ def make_sorted_dict(keys, d):
 LOCALE_EN.languages_2 = LANGUAGES_2
 
 
+SEARCH_CONFS = dict((
+    ('da', 'danish'),
+    ('de', 'german'),
+    ('en', 'english'),
+    ('es', 'spanish'),
+    ('fi', 'finnish'),
+    ('fr', 'french'),
+    ('hu', 'hungarian'),
+    ('it', 'italian'),
+    ('nb', 'norwegian'),
+    ('nl', 'dutch'),
+    ('nn', 'norwegian'),
+    ('pt', 'portuguese'),
+    ('ro', 'romanian'),
+    ('ru', 'russian'),
+    ('sv', 'swedish'),
+    ('tr', 'turkish'),
+))
+
+
 ternary_re = re.compile(r'^\(? *(.+?) *\? *(.+?) *: *(.+?) *\)?$')
 and_re = re.compile(r' *&& *')
 or_re = re.compile(r' *\|\| *')


Test patch: