changeset 3:041bc456db50 v2

v2 - complete rework to use filtering expressions in search string
author ovolkov
date Wed, 21 Jan 2015 19:19:02 +0300
parents db862491a577
children d88ea0fdc19c
files LFGFilter.lua LFGFilter.toc LFGFilter.txt
diffstat 3 files changed, 120 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/LFGFilter.lua	Wed Nov 12 16:21:54 2014 +0300
+++ b/LFGFilter.lua	Wed Jan 21 19:19:02 2015 +0300
@@ -1,28 +1,87 @@
-local aName, aEnv = ...
-aEnv.LFGFilter_Allow_Activity = {}
-aEnv.LFGFilter_Allow_Activity.count = 0
-local LFGFilter_Allow_Activity = aEnv.LFGFilter_Allow_Activity
+LFGListFrame.SearchPanel.SearchBox:SetMaxLetters(2048)
 
+local filter_expression_functions = setmetatable({}, {
+   __mode = "k",
+   __index = function(t, key)
+      local func, error = loadstring("return " .. key)
+      if error then print("Error in LFG filter expression:\n", error) end
+      t[key] = func
+      return func
+   end
+})
+
+function LFGListSearchPanel_DoSearch(self)
+   local searchText = self.SearchBox:GetText();
+   local real_search, filter_expression = searchText:match("^([^=]-)=(.+)$")
+   if filter_expression then
+      filter_expression = filter_expression:lower()
+      self.filter_func = filter_expression_functions[filter_expression]
+   end
+   self.filter_expression = filter_expression
+   
+   -- print("lfgsearch", real_search, filter_expression)
+   C_LFGList.Search(self.categoryID, real_search or searchText, self.filters, self.preferredFilters);
+   self.searching = true;
+   self.searchFailed = false;
+   self.selectedResult = nil;
+   LFGListSearchPanel_UpdateResultList(self);
+   LFGListSearchPanel_UpdateResults(self);
+end
+
+local result_env = {}
+-- =highmaul and ((normal and (name:match("imp") or defeated == 6)) or (heroic and defeated == 2))
 function LFGListUtil_SortSearchResults(results)
-   if LFGFilter_Allow_Activity.count > 0 then
+   local self = LFGListFrame.SearchPanel
+   if self.filter_expression then
+      local check = self.filter_func
       local shift_down = 0
       local original_size = #results
       for idx = 1, original_size do
-         local result = results[idx]
-         local _, activityID = C_LFGList.GetSearchResultInfo(result)
-         if LFGFilter_Allow_Activity[activityID] then
+         local id = results[idx]
+         local _, activityID, name, comment, voiceChat, iLvl, age, numBNetFriends, numCharFriends, numGuildMates, isDelisted, leaderName, numMembers = C_LFGList.GetSearchResultInfo(id)
+         local completedEncounters = C_LFGList.GetSearchResultEncounterInfo(id)
+         local memberCounts = C_LFGList.GetSearchResultMemberCounts(id)
+
+         wipe(result_env)
+         result_env.name = name:lower()
+         result_env.comment = comment:lower()
+         result_env.ilvl = iLvl
+         -- TODO: should be calculated in meta
+         result_env.defeated = completedEncounters and #completedEncounters or 0
+         result_env.members = numMembers
+         result_env.tanks = memberCounts.TANK
+         result_env.healers = memberCounts.HEALER
+         result_env.damagers = memberCounts.DAMAGER + memberCounts.NOROLE
+         result_env.my_server = leaderName and not leaderName:find('-')
+
+         if activityID == 37 then
+            result_env.highmaul = true
+            result_env.normal = true
+         elseif activityID == 38 then
+            result_env.highmaul = true
+            result_env.heroic = true
+         end
+
+         local pass
+         if check then
+            setfenv(check, result_env)
+            pass = check()
+         end
+
+         if pass then
             if shift_down > 0 then
-               results[idx - shift_down] = result
+               results[idx - shift_down] = id
             end
          else
             shift_down = shift_down + 1
          end
+
       end
       for idx = original_size - shift_down + 1, original_size do
          results[idx] = nil
       end
    end
-	table.sort(results, LFGListUtil_SortSearchResultsCB);
+   table.sort(results, LFGListUtil_SortSearchResultsCB);
 end
 
 function LFGListUtil_SortSearchResultsCB(id1, id2)
@@ -56,9 +115,4 @@
       local id1, activityID1, name1, comment1, voiceChat1, iLvl1, age1, numBNetFriends1, numCharFriends1, numGuildMates1, isDelisted1 = C_LFGList.GetSearchResultInfo(results[idx])
       print(id1, activityID1, C_LFGList.GetActivityInfo(activityID1), '*', name1)
    end
-end
-
--- SoO (Normal): 4
--- SoO (Heroic): 41
--- SoO (Mythic): 42
--- /run LFGFilter_Allow_Activity = { [42] = true }
\ No newline at end of file
+end
\ No newline at end of file
--- a/LFGFilter.toc	Wed Nov 12 16:21:54 2014 +0300
+++ b/LFGFilter.toc	Wed Jan 21 19:19:02 2015 +0300
@@ -1,13 +1,12 @@
 ## Interface: 60000
 
 ## Title: LFG Filter for Premade Groups
-## Version: v1
-## Notes: Sorts premade groups found by raid and difficulty, grouping all similar raids together and allows to filter search results to include only specific raids/difficulties.
+## Version: v2
+## Notes: Allows you to filter search results with complex expressions and sorts premade groups found by raid and difficulty, grouping all similar raids together.
 ## Author: Oleg "Rowaa[SR13]" Volkov
 
 ## OptionalDeps: 
 
 ## SavedVariables: 
 
-LFGFilter.lua
-Slash.lua
\ No newline at end of file
+LFGFilter.lua
\ No newline at end of file
--- a/LFGFilter.txt	Wed Nov 12 16:21:54 2014 +0300
+++ b/LFGFilter.txt	Wed Jan 21 19:19:02 2015 +0300
@@ -1,33 +1,57 @@
-LFG Filter for Premade Groups
+LFG Filter for Premade Groups, v2
 
 It's great to have built-in Premade Group finder (aka LFG internally) except all the groups are mixed together and you need to carefully scan list to find that one raid or difficulty you've interested in or use TEXT based filter and risk missing groups you'd want.
 
-This addon does two things right now:
-1) Sorts all groups by raid/difficulty, so, say, all you SoO Mythic groups are together.
-2) Allows you to filter search lists to only raid/difficulty you want, removing everything else from list.
+== Features ==
+* Sorts all groups by raid/difficulty, so, say, all you heroic groups for some specific raid are together.
+* Allows you to filter search lists to only results you want, removing everything else from list.
 
-UI and configuration is still work in progress, so you'll have to use slash commands and activity IDs.
+== Filtering expressions ==
+To filter results, enter a search expression into filter editbox on group search screen starting with =. Both text and expression will be used if you have some text before =. Expressions are constructed from variables that hold info on each found group and use Lua syntax and if you're unfamiliar with it, a short summary will be presented below. If you make an error while writing expression it will be printed in chat when you try to search and result list will be empty.
 
-/lfgaf - add a list of activities you WANT TO SEE in your search. Enter it without any IDs to remove filters and see full list or enter a list of IDs for all activities you want to see.
+=== Supported variables ===
+Logical values:
+ * highmaul - group is running Highmaul raid.
+ * normal - group is running normal difficulty.
+ * heroic - group is running heroic difficulty.
+ * my_server - group is running on my server. Useful for searching for trash runs or guild runs if you wish to join them later in mythic.
 
-Some IDs:
-4   - Siege of Orgrimmar (Normal)
-41  - Siege of Orgrimmar (Heroic)
-42  - Siege of Orgrimmar (Mythic)
-347 - Throne of Thunder (10 Normal)
-348 - Throne of Thunder (10 Heroic)
-349 - Throne of Thunder (25 Heroic)
-397 - World Bosses (Pandaria)
-More can be found by opening group search and dumping list of current groups with /run LFGPrintRawResults(), but I'll add visual selection ASAP.
-Second number is activity ID.
+String values,  all strings are automatically converted to lower case to simplify your searches. You can use string functions listed below:
+ * name - group's name - that big yellow text.
+ * comment - longish comment entered by group leader, that place where people usually put "bring curve" or something.
 
-Examples:
-  Only show SoO Mythic:
-  /lfgaf 42
+Number values:
+ * ilvl - minimum ilevel required by group.
+ * defeated - amount of bosses defeated.
+ * members - people already in group.
+ * tanks - amount of tanks.
+ * healers - amount of healers.
+ * damagers - amount of damagers.
 
-  Show all SoO difficulties:
-  /lfgaf 4 41 42
+=== Short summary of Lua syntax ===
+ * and, or, not - logical operators. "highmaul and normal" will find Highmaul normal raids, "highmaul and (normal or heroic)" will find Highmaul normal and heroic and will hide mythic.
+ * == - equal, ~= - not equal, comparison for everything.
+ * < > <= >= - comparison for numbers.
+ * :find - a string function, true if requested substring is present.
+ * :match - a string function, can be used for more complex searches with regular expressions. Look it up in Lua manual.
+ * () can be used to group and define precedence.
+ 
+=== Examples ===
+* =highmaul and heroic and defeated == 0
+** Fresh Highmaul Heroic.
 
-Change log:
+* =highmaul and ((normal and (name:find("imp") or defeated == 6)) or (heroic and defeated == 1))
+** Find Highmaul raid groups, either normal with 6 bosses defeated or "imp" mentioned in name, or heroic with just one boss defeated.
+
+* =highmaul and name:find("trash") and name:find("mythic") and my_server
+** Find Highmaul mythic trash runs on your server.
+
+* =members > 3
+** Find groups with at least 3 members. It will skip some groups that's just starting, but will also reliably hide recruit ads and other spam.
+
+== Change log ==
+2014-01-21 v2
+* Complete filtering rework: now works with expressions entered directly into group search filter field.
+
 2014-11-12 v1
-* Initial implementation: quest details and quest NPC portrait are now anchored to the right of quest list, quest list is no longer hidden when you check quest details.
\ No newline at end of file
+* Initial implementation: sort + activity ID search.
\ No newline at end of file