<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://charlesreid1.com/w/index.php?action=history&amp;feed=atom&amp;title=Whoosh%2FSearch</id>
	<title>Whoosh/Search - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://charlesreid1.com/w/index.php?action=history&amp;feed=atom&amp;title=Whoosh%2FSearch"/>
	<link rel="alternate" type="text/html" href="https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;action=history"/>
	<updated>2026-06-20T02:37:36Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.12</generator>
	<entry>
		<id>https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27432&amp;oldid=prev</id>
		<title>Admin: /* whoosh Search class for Github issues */</title>
		<link rel="alternate" type="text/html" href="https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27432&amp;oldid=prev"/>
		<updated>2020-02-17T22:10:07Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;whoosh Search class for Github issues&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:10, 17 February 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l515&quot;&gt;Line 515:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 515:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         return self.ix.searcher().doc_count_all()&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         return self.ix.searcher().doc_count_all()&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=Flags=&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{WhooshFlag}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27431&amp;oldid=prev</id>
		<title>Admin: /* Flags */</title>
		<link rel="alternate" type="text/html" href="https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27431&amp;oldid=prev"/>
		<updated>2020-02-17T22:09:57Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Flags&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:09, 17 February 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l211&quot;&gt;Line 211:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 211:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==Flags==&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{WhooshFlag}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===whoosh Search class for Github issues===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===whoosh Search class for Github issues===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27430&amp;oldid=prev</id>
		<title>Admin: /* whoosh Search class for folder of Markdown files */</title>
		<link rel="alternate" type="text/html" href="https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27430&amp;oldid=prev"/>
		<updated>2020-02-17T22:09:45Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;whoosh Search class for folder of Markdown files&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:09, 17 February 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l210&quot;&gt;Line 210:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 210:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==Flags==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{WhooshFlag}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===whoosh Search class for Github issues===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===whoosh Search class for Github issues===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27429&amp;oldid=prev</id>
		<title>Admin: /* whoosh Search class for folder of Markdown files */</title>
		<link rel="alternate" type="text/html" href="https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27429&amp;oldid=prev"/>
		<updated>2020-02-17T22:09:20Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;whoosh Search class for folder of Markdown files&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:09, 17 February 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l208&quot;&gt;Line 208:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 208:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     def get_document_total_count(self):&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     def get_document_total_count(self):&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         return self.ix.searcher().doc_count_all()&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         return self.ix.searcher().doc_count_all()&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/&lt;/ins&gt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27428&amp;oldid=prev</id>
		<title>Admin: Created page with &quot;=Whoosh Search=  ==About the Search class==  The Search class in Whoosh defines key behavior like how to iterate over all documents (and how to access documents in the first p...&quot;</title>
		<link rel="alternate" type="text/html" href="https://charlesreid1.com/w/index.php?title=Whoosh/Search&amp;diff=27428&amp;oldid=prev"/>
		<updated>2020-02-17T22:09:01Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;=Whoosh Search=  ==About the Search class==  The Search class in Whoosh defines key behavior like how to iterate over all documents (and how to access documents in the first p...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=Whoosh Search=&lt;br /&gt;
&lt;br /&gt;
==About the Search class==&lt;br /&gt;
&lt;br /&gt;
The Search class in Whoosh defines key behavior like how to iterate over all documents (and how to access documents in the first place).&lt;br /&gt;
&lt;br /&gt;
If a custom document type needs to be defined (e.g., a Google Drive spreadsheet), the Search class is where we define how to iterate over all the spreadsheets, process the contents, and add the document to the search index.&lt;br /&gt;
&lt;br /&gt;
The Search class makes high-level calls to the Index class (like &amp;quot;add a new document to the search index, with the following values for each field&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Search class vs Index class==&lt;br /&gt;
&lt;br /&gt;
As mentioned above, the [[Whoosh/Index]] class provides a high-level interface, which is called by the Search class.&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
&lt;br /&gt;
The Search class is defined &lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
===whoosh Search class for folder of Markdown files===&lt;br /&gt;
&lt;br /&gt;
Example Search class for creating an index of a folder full of markdown files: https://git.charlesreid1.com/charlesreid1/markdown-search/src/branch/master/search_md.py&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Search:&lt;br /&gt;
    ix = None&lt;br /&gt;
    index_folder = None&lt;br /&gt;
    markdown = mistune.Markdown(renderer=DontEscapeHtmlInCodeRenderer(), escape=False)&lt;br /&gt;
    html_parser = html.parser.HTMLParser()&lt;br /&gt;
    schema = None&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, index_folder):&lt;br /&gt;
        self.open_index(index_folder)&lt;br /&gt;
&lt;br /&gt;
    def open_index(self, index_folder, create_new=False):&lt;br /&gt;
        self.index_folder = index_folder&lt;br /&gt;
        if create_new:&lt;br /&gt;
            if os.path.exists(index_folder):&lt;br /&gt;
                shutil.rmtree(index_folder)&lt;br /&gt;
                print(&amp;quot;deleted index folder: &amp;quot; + index_folder)&lt;br /&gt;
&lt;br /&gt;
        if not os.path.exists(index_folder):&lt;br /&gt;
            os.mkdir(index_folder)&lt;br /&gt;
&lt;br /&gt;
        exists = index.exists_in(index_folder)&lt;br /&gt;
        stemming_analyzer = StemmingAnalyzer()&lt;br /&gt;
&lt;br /&gt;
        schema = Schema(&lt;br /&gt;
            path=ID(stored=True, unique=True)&lt;br /&gt;
            , filename=TEXT(stored=True, field_boost=100.0)&lt;br /&gt;
            , headlines=KEYWORD(stored=True, scorable=True, field_boost=60.0)&lt;br /&gt;
            , content=TEXT(stored=True, analyzer=stemming_analyzer)&lt;br /&gt;
            , time=STORED&lt;br /&gt;
        )&lt;br /&gt;
        if not exists:&lt;br /&gt;
            self.ix = index.create_in(index_folder, schema)&lt;br /&gt;
        else:&lt;br /&gt;
            self.ix = index.open_dir(index_folder)&lt;br /&gt;
&lt;br /&gt;
    def add_document(self, writer, file_path, config):&lt;br /&gt;
        file_name = file_path.replace(&amp;quot;.&amp;quot;, &amp;quot; &amp;quot;).replace(&amp;quot;/&amp;quot;, &amp;quot; &amp;quot;).replace(&amp;quot;\\&amp;quot;, &amp;quot; &amp;quot;).replace(&amp;quot;_&amp;quot;, &amp;quot; &amp;quot;).replace(&amp;quot;-&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
        # read file content&lt;br /&gt;
        with codecs.open(file_path, &amp;#039;r&amp;#039;, encoding=&amp;#039;utf-8&amp;#039;) as f:&lt;br /&gt;
            content = f.read()&lt;br /&gt;
            path = file_path&lt;br /&gt;
&lt;br /&gt;
        # parse markdown fields&lt;br /&gt;
        parser = MarkdownParser()&lt;br /&gt;
        parser.parse(content, config)&lt;br /&gt;
&lt;br /&gt;
        modtime = os.path.getmtime(path)&lt;br /&gt;
        print(&amp;quot;adding to index: path: %s size:%d headlines:&amp;#039;%s&amp;#039; modtime=%d&amp;quot; % (&lt;br /&gt;
            path, len(content), parser.headlines, modtime))&lt;br /&gt;
        writer.add_document(&lt;br /&gt;
            path=path&lt;br /&gt;
            , filename=file_name&lt;br /&gt;
            , headlines=parser.headlines&lt;br /&gt;
            , content=content&lt;br /&gt;
            , time = modtime&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def add_all_files(self, file_dir, config, create_new_index=False):&lt;br /&gt;
        if create_new_index:&lt;br /&gt;
            self.open_index(self.index_folder, create_new=True)&lt;br /&gt;
&lt;br /&gt;
        count = 0&lt;br /&gt;
        writer = self.ix.writer()&lt;br /&gt;
        for root, dirs, files in os.walk(file_dir, followlinks=True):&lt;br /&gt;
            for ff in files:&lt;br /&gt;
                if ff.endswith(&amp;quot;.md&amp;quot;) or ff.endswith(&amp;quot;.markdown&amp;quot;):&lt;br /&gt;
                    path = os.path.join(root, ff)&lt;br /&gt;
                    self.add_document(writer, path, config)&lt;br /&gt;
                    count += 1&lt;br /&gt;
        writer.commit()&lt;br /&gt;
        print(&amp;quot;Done, added %d documents to the index&amp;quot; % count)&lt;br /&gt;
&lt;br /&gt;
    def update_index_incremental(self, config, create_new_index=False):&lt;br /&gt;
        file_dir = config[&amp;quot;MARKDOWN_FILES_DIR&amp;quot;]&lt;br /&gt;
        if create_new_index:&lt;br /&gt;
            self.open_index(self.index_folder, create_new=True)&lt;br /&gt;
&lt;br /&gt;
        all_files = []&lt;br /&gt;
        for root, dirs, files in os.walk(file_dir, followlinks=True):&lt;br /&gt;
            if not root.endswith(&amp;quot;.git&amp;quot;):&lt;br /&gt;
                for ff in files:&lt;br /&gt;
                    if ff.endswith(&amp;quot;.md&amp;quot;) or ff.endswith(&amp;quot;.markdown&amp;quot;):&lt;br /&gt;
                        path = os.path.join(root, ff)&lt;br /&gt;
                        print(&amp;#039;updating file %s&amp;#039;%(path))&lt;br /&gt;
                        all_files.append(path)&lt;br /&gt;
&lt;br /&gt;
        # see: https://pythonhosted.org/Whoosh/indexing.html#incremental-indexing&lt;br /&gt;
        # The set of all paths in the index&lt;br /&gt;
        indexed_paths = set()&lt;br /&gt;
        # The set of all paths we need to re-index&lt;br /&gt;
        to_index = set()&lt;br /&gt;
&lt;br /&gt;
        count = 0&lt;br /&gt;
        with self.ix.searcher() as searcher:&lt;br /&gt;
            writer = self.ix.writer()&lt;br /&gt;
&lt;br /&gt;
            # Loop over the stored fields in the index&lt;br /&gt;
            for fields in searcher.all_stored_fields():&lt;br /&gt;
                indexed_path = fields[&amp;#039;path&amp;#039;]&lt;br /&gt;
                indexed_paths.add(indexed_path)&lt;br /&gt;
&lt;br /&gt;
                if not os.path.exists(indexed_path):&lt;br /&gt;
                    # This file was deleted since it was indexed&lt;br /&gt;
                    writer.delete_by_term(&amp;#039;path&amp;#039;, indexed_path)&lt;br /&gt;
                    print(&amp;quot;removed from index: %s&amp;quot; % indexed_path)&lt;br /&gt;
&lt;br /&gt;
                else:&lt;br /&gt;
                    # Check if this file was changed since it&lt;br /&gt;
                    # was indexed&lt;br /&gt;
                    indexed_time = fields[&amp;#039;time&amp;#039;]&lt;br /&gt;
                    mtime = os.path.getmtime(indexed_path)&lt;br /&gt;
                    if mtime &amp;gt; indexed_time:&lt;br /&gt;
                        # The file has changed, delete it and add it to the list of&lt;br /&gt;
                        # files to reindex&lt;br /&gt;
                        writer.delete_by_term(&amp;#039;path&amp;#039;, indexed_path)&lt;br /&gt;
                        to_index.add(indexed_path)&lt;br /&gt;
&lt;br /&gt;
            # Loop over the files in the filesystem&lt;br /&gt;
            for path in all_files:&lt;br /&gt;
                if path in to_index or path not in indexed_paths:&lt;br /&gt;
                    # This is either a file that&amp;#039;s changed, or a new file&lt;br /&gt;
                    # that wasn&amp;#039;t indexed before. So index it!&lt;br /&gt;
                    self.add_document(writer, path, config)&lt;br /&gt;
                    count += 1&lt;br /&gt;
&lt;br /&gt;
            writer.commit()&lt;br /&gt;
&lt;br /&gt;
            print(&amp;quot;Done, updated %d documents in the index&amp;quot; % count)&lt;br /&gt;
&lt;br /&gt;
    def create_search_result(self, results):&lt;br /&gt;
        # Allow larger fragments&lt;br /&gt;
        results.fragmenter.maxchars = 300&lt;br /&gt;
&lt;br /&gt;
        # Show more context before and after&lt;br /&gt;
        results.fragmenter.surround = 50&lt;br /&gt;
&lt;br /&gt;
        search_results = []&lt;br /&gt;
        for r in results:&lt;br /&gt;
            sr = SearchResult()&lt;br /&gt;
            #import pdb; pdb.set_trace()&lt;br /&gt;
            #print(dir(r))&lt;br /&gt;
            sr.score = r.score&lt;br /&gt;
            sr.path = r[&amp;quot;path&amp;quot;]&lt;br /&gt;
            sr.content = r[&amp;quot;content&amp;quot;]&lt;br /&gt;
            highlights = r.highlights(&amp;quot;content&amp;quot;)&lt;br /&gt;
            if not highlights:&lt;br /&gt;
                highlights = self.cap(r[&amp;quot;content&amp;quot;], 1000)&lt;br /&gt;
            # unescape&lt;br /&gt;
            highlights = self.html_parser.unescape(highlights)&lt;br /&gt;
            html = self.markdown(highlights)&lt;br /&gt;
            sr.content_highlight = html&lt;br /&gt;
            if &amp;quot;headlines&amp;quot; in r:&lt;br /&gt;
                sr.headlines = r[&amp;quot;headlines&amp;quot;]&lt;br /&gt;
            search_results.append(sr)&lt;br /&gt;
&lt;br /&gt;
        return search_results&lt;br /&gt;
&lt;br /&gt;
    def cap(self, s, l):&lt;br /&gt;
        return s if len(s) &amp;lt;= l else s[0:l - 3] + &amp;#039;...&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    def search(self, query_list, fields=None):&lt;br /&gt;
        with self.ix.searcher() as searcher:&lt;br /&gt;
            query_string = &amp;quot; &amp;quot;.join(query_list)&lt;br /&gt;
            query = None&lt;br /&gt;
            if &amp;quot;\&amp;quot;&amp;quot; in query_string or &amp;quot;:&amp;quot; in query_string:&lt;br /&gt;
                query = QueryParser(&amp;quot;content&amp;quot;, self.schema).parse(query_string)&lt;br /&gt;
            elif len(fields) == 1 and fields[0] == &amp;quot;filename&amp;quot;:&lt;br /&gt;
                pass&lt;br /&gt;
            elif len(fields) == 2:&lt;br /&gt;
                pass&lt;br /&gt;
            else:&lt;br /&gt;
                fields = [&amp;quot;headlines&amp;quot;, &amp;quot;content&amp;quot;, &amp;quot;filename&amp;quot;, &amp;quot;doubleemphasiswords&amp;quot;, &amp;quot;emphasiswords&amp;quot;]&lt;br /&gt;
            if not query:&lt;br /&gt;
                query = MultifieldParser(fields, schema=self.ix.schema).parse(query_string)&lt;br /&gt;
            parsed_query = &amp;quot;%s&amp;quot; % query&lt;br /&gt;
            print(&amp;quot;query: %s&amp;quot; % parsed_query)&lt;br /&gt;
            results = searcher.search(query, terms=False, scored=True, groupedby=&amp;quot;path&amp;quot;)&lt;br /&gt;
            search_result = self.create_search_result(results)&lt;br /&gt;
&lt;br /&gt;
        return parsed_query, search_result&lt;br /&gt;
&lt;br /&gt;
    def get_document_total_count(self):&lt;br /&gt;
        return self.ix.searcher().doc_count_all()&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===whoosh Search class for Github issues===&lt;br /&gt;
&lt;br /&gt;
Example Search class for creating an index of Github issues: https://git.charlesreid1.com/charlesreid1/issues-search/src/branch/master/issues_search.py&lt;br /&gt;
&lt;br /&gt;
(The trick here is to re-use the Markdown class above, and turn each Github issue + comments thread into a Markdown file.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Search:&lt;br /&gt;
    ix = None&lt;br /&gt;
    index_folder = None&lt;br /&gt;
    markdown = mistune.Markdown(renderer=DontEscapeHtmlInCodeRenderer(), escape=False)&lt;br /&gt;
    html_parser = html.parser.HTMLParser()&lt;br /&gt;
    schema = None&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, index_folder):&lt;br /&gt;
        self.open_index(index_folder)&lt;br /&gt;
&lt;br /&gt;
    def open_index(self, index_folder, create_new=False):&lt;br /&gt;
        self.index_folder = index_folder&lt;br /&gt;
        if create_new:&lt;br /&gt;
            if os.path.exists(index_folder):&lt;br /&gt;
                shutil.rmtree(index_folder)&lt;br /&gt;
                print(&amp;quot;deleted index folder: &amp;quot; + index_folder)&lt;br /&gt;
&lt;br /&gt;
        if not os.path.exists(index_folder):&lt;br /&gt;
            os.mkdir(index_folder)&lt;br /&gt;
&lt;br /&gt;
        exists = index.exists_in(index_folder)&lt;br /&gt;
        stemming_analyzer = StemmingAnalyzer()&lt;br /&gt;
&lt;br /&gt;
        schema = Schema(&lt;br /&gt;
                url=ID(stored=True, unique=True),&lt;br /&gt;
                is_comment=BOOLEAN(stored=True),&lt;br /&gt;
                timestamp=STORED,&lt;br /&gt;
                repo_name=TEXT(stored=True),&lt;br /&gt;
                repo_url=ID(stored=True),&lt;br /&gt;
                issue_title=TEXT(stored=True, field_boost=100.0),&lt;br /&gt;
                issue_url=ID(stored=True),&lt;br /&gt;
                user=TEXT(stored=True),&lt;br /&gt;
                content=TEXT(stored=True, analyzer=stemming_analyzer)&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        if not exists:&lt;br /&gt;
            self.ix = index.create_in(index_folder, schema)&lt;br /&gt;
        else:&lt;br /&gt;
            self.ix = index.open_dir(index_folder)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def add_issue(self, writer, issue, repo, config):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Add Github issue to search index.&lt;br /&gt;
&lt;br /&gt;
        Replaces add_document&lt;br /&gt;
&lt;br /&gt;
        This must:&lt;br /&gt;
        - deal with original issue content&lt;br /&gt;
        - iterate over each comment&lt;br /&gt;
        - deal with comment content&lt;br /&gt;
&lt;br /&gt;
        Schema:&lt;br /&gt;
        - url&lt;br /&gt;
        - is_comment&lt;br /&gt;
        - timestamp&lt;br /&gt;
        - repo_name&lt;br /&gt;
        - repo_url&lt;br /&gt;
        - issue_title&lt;br /&gt;
        - issue_url&lt;br /&gt;
        - user&lt;br /&gt;
        - content&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # should store urls of all issues and comments&lt;br /&gt;
&lt;br /&gt;
        repo_name = repo.name&lt;br /&gt;
        repo_url = repo.html_url&lt;br /&gt;
&lt;br /&gt;
        count = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Handle the issue content&lt;br /&gt;
        print(&amp;quot;Indexing issue %s&amp;quot;%(issue.html_url))&lt;br /&gt;
        writer.add_document(&lt;br /&gt;
                url = issue.html_url,&lt;br /&gt;
                is_comment = False,&lt;br /&gt;
                timestamp = issue.created_at,&lt;br /&gt;
                repo_name = repo_name,&lt;br /&gt;
                repo_url = repo_url,&lt;br /&gt;
                issue_title = issue.title,&lt;br /&gt;
                issue_url = issue.html_url,&lt;br /&gt;
                user = issue.user.login,&lt;br /&gt;
                content = issue.body.rstrip()&lt;br /&gt;
        )&lt;br /&gt;
        count += 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Handle the comments content&lt;br /&gt;
        if(issue.comments&amp;gt;0):&lt;br /&gt;
            comments = issue.get_comments()&lt;br /&gt;
            for comment in comments:&lt;br /&gt;
                print(&amp;quot; &amp;gt; Indexing comment %s&amp;quot;%(comment.html_url))&lt;br /&gt;
                writer.add_document(&lt;br /&gt;
                        url = comment.html_url,&lt;br /&gt;
                        is_comment = True,&lt;br /&gt;
                        timestamp = comment.created_at,&lt;br /&gt;
                        repo_name = repo_name,&lt;br /&gt;
                        repo_url = repo_url,&lt;br /&gt;
                        issue_title = issue.title,&lt;br /&gt;
                        issue_url = issue.html_url,&lt;br /&gt;
                        user = comment.user.login,&lt;br /&gt;
                        content = comment.body.strip()&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
        count += 1&lt;br /&gt;
        return count&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def add_all_issues(self, gh_access_token, list_of_repos, which_org, config, create_new_index=False):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Add all issues in a given github repo to the search index.&lt;br /&gt;
&lt;br /&gt;
        Replaces add_all_files&lt;br /&gt;
&lt;br /&gt;
        Takes as inputs:&lt;br /&gt;
        - github access token&lt;br /&gt;
        - list of github repos&lt;br /&gt;
        - github org/user owning these repos&lt;br /&gt;
        - location of the whoosh config file for configuring the search engine&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        if create_new_index:&lt;br /&gt;
            self.open_index(self.index_folder, create_new=True)&lt;br /&gt;
&lt;br /&gt;
        writer = self.ix.writer()&lt;br /&gt;
&lt;br /&gt;
        # ------------&lt;br /&gt;
        # Iterate over each repo&lt;br /&gt;
        # Iterate over each thread (github issue)&lt;br /&gt;
        # Iterate over each comment &lt;br /&gt;
&lt;br /&gt;
        g = Github(gh_access_token)&lt;br /&gt;
        org = g.get_organization(which_org)&lt;br /&gt;
&lt;br /&gt;
        c = 0 &lt;br /&gt;
&lt;br /&gt;
        # Iterate over each repo&lt;br /&gt;
        for this_repo in list_of_repos:&lt;br /&gt;
&lt;br /&gt;
            repo = org.get_repo(this_repo)&lt;br /&gt;
            reponame = repo.name&lt;br /&gt;
&lt;br /&gt;
            # Iterate over each thread&lt;br /&gt;
            issues = repo.get_issues()&lt;br /&gt;
            for issue in issues:&lt;br /&gt;
&lt;br /&gt;
                # Deal with original issue content&lt;br /&gt;
                # AND iterate over each comment &lt;br /&gt;
                c += self.add_issue(writer, issue, repo, config)&lt;br /&gt;
&lt;br /&gt;
                # should store urls of all issues and comments&lt;br /&gt;
&lt;br /&gt;
        writer.commit()&lt;br /&gt;
        print(&amp;quot;Done, added %d documents to the index&amp;quot; % c)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def update_index_incremental(self, gh_access_token, list_of_repos, which_org, config, create_new_index=False):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Update the index of issues of a given github repo.&lt;br /&gt;
&lt;br /&gt;
        Takes as inputs:&lt;br /&gt;
        - github access token&lt;br /&gt;
        - list of github repos&lt;br /&gt;
        - github org/user owning these repos&lt;br /&gt;
        - location of the whoosh config file for configuring the search engine&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        if create_new_index:&lt;br /&gt;
            self.open_index(self.index_folder, create_new=True)&lt;br /&gt;
&lt;br /&gt;
        # Using URL as the unique identifier&lt;br /&gt;
        # Start by getting a list of URLs that are indexed&lt;br /&gt;
        # Then walk all URLs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        g = Github(gh_access_token)&lt;br /&gt;
        org = g.get_organization(which_org)&lt;br /&gt;
&lt;br /&gt;
        # Set of all URLs as existing on github&lt;br /&gt;
        to_index = set()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        writer = self.ix.writer()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # fix this. the delete all in index&lt;br /&gt;
        # is not occurring in right place.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Iterate over each repo&lt;br /&gt;
        for this_repo in list_of_repos:&lt;br /&gt;
&lt;br /&gt;
            repo = org.get_repo(this_repo)&lt;br /&gt;
            reponame = repo.name&lt;br /&gt;
&lt;br /&gt;
            count = 0&lt;br /&gt;
&lt;br /&gt;
            # Iterate over each thread&lt;br /&gt;
            issues = repo.get_issues()&lt;br /&gt;
            for issue in issues:&lt;br /&gt;
&lt;br /&gt;
                # This approach is more work than is needed&lt;br /&gt;
                # but PoC||GTFO&lt;br /&gt;
&lt;br /&gt;
                # For each issue/comment URL,&lt;br /&gt;
                # remove the corresponding item&lt;br /&gt;
                # and re-add it to the index&lt;br /&gt;
&lt;br /&gt;
                to_index.add(issue.html_url)&lt;br /&gt;
                writer.delete_by_term(&amp;#039;url&amp;#039;, issue.html_url)&lt;br /&gt;
                comments = issue.get_comments()&lt;br /&gt;
&lt;br /&gt;
                for comment in comments:&lt;br /&gt;
                    to_index.add(comment.html_url)&lt;br /&gt;
                    writer.delete_by_term(&amp;#039;url&amp;#039;, comment.html_url)&lt;br /&gt;
&lt;br /&gt;
                # Now re-add this issue to the index&lt;br /&gt;
                count += self.add_issue(writer, issue, repo, config)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        writer.commit()&lt;br /&gt;
        print(&amp;quot;Done, updated %d documents in the index&amp;quot; % count)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def create_search_result(self, results):&lt;br /&gt;
        # Allow larger fragments&lt;br /&gt;
        results.fragmenter.maxchars = 300&lt;br /&gt;
&lt;br /&gt;
        # Show more context before and after&lt;br /&gt;
        results.fragmenter.surround = 50&lt;br /&gt;
&lt;br /&gt;
        search_results = []&lt;br /&gt;
        for r in results:&lt;br /&gt;
&lt;br /&gt;
            # Note: this is where we package things up &lt;br /&gt;
            # for the Jinja template &amp;quot;search.html&amp;quot;.&lt;br /&gt;
            # For example, the Jinja template&lt;br /&gt;
            # contains a {% for e in entries %}&lt;br /&gt;
            # and then an {{e.score}}&lt;br /&gt;
&lt;br /&gt;
            sr = SearchResult()&lt;br /&gt;
            sr.score = r.score&lt;br /&gt;
            sr.url = r[&amp;#039;url&amp;#039;]&lt;br /&gt;
            sr.title = r[&amp;#039;issue_title&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
            sr.repo_name = r[&amp;#039;repo_name&amp;#039;]&lt;br /&gt;
            sr.repo_url = r[&amp;#039;repo_url&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
            sr.issue_title = r[&amp;#039;issue_title&amp;#039;]&lt;br /&gt;
            sr.issue_url = r[&amp;#039;issue_url&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
            sr.is_comment = r[&amp;#039;is_comment&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
            sr.content = r[&amp;#039;content&amp;#039;]&lt;br /&gt;
            highlights = r.highlights(&amp;#039;content&amp;#039;)&lt;br /&gt;
            if not highlights:&lt;br /&gt;
                # just use the first 1,000 words of the document&lt;br /&gt;
                highlights = self.cap(r[&amp;#039;content&amp;#039;], 1000)&lt;br /&gt;
&lt;br /&gt;
            highlights = self.html_parser.unescape(highlights)&lt;br /&gt;
            html = self.markdown(highlights)&lt;br /&gt;
            sr.content_highlight = html&lt;br /&gt;
            search_results.append(sr)&lt;br /&gt;
&lt;br /&gt;
        return search_results&lt;br /&gt;
&lt;br /&gt;
    def cap(self, s, l):&lt;br /&gt;
        return s if len(s) &amp;lt;= l else s[0:l - 3] + &amp;#039;...&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    def search(self, query_list, fields=None):&lt;br /&gt;
        with self.ix.searcher() as searcher:&lt;br /&gt;
            query_string = &amp;quot; &amp;quot;.join(query_list)&lt;br /&gt;
            query = None&lt;br /&gt;
            if &amp;quot;\&amp;quot;&amp;quot; in query_string or &amp;quot;:&amp;quot; in query_string:&lt;br /&gt;
                query = QueryParser(&amp;quot;content&amp;quot;, self.schema).parse(query_string)&lt;br /&gt;
            elif len(fields) == 1 and fields[0] == &amp;quot;filename&amp;quot;:&lt;br /&gt;
                pass&lt;br /&gt;
            elif len(fields) == 2:&lt;br /&gt;
                pass&lt;br /&gt;
            else:&lt;br /&gt;
                fields = [&amp;quot;headlines&amp;quot;, &amp;quot;content&amp;quot;, &amp;quot;filename&amp;quot;, &amp;quot;doubleemphasiswords&amp;quot;, &amp;quot;emphasiswords&amp;quot;]&lt;br /&gt;
            if not query:&lt;br /&gt;
                query = MultifieldParser(fields, schema=self.ix.schema).parse(query_string)&lt;br /&gt;
            parsed_query = &amp;quot;%s&amp;quot; % query&lt;br /&gt;
            print(&amp;quot;query: %s&amp;quot; % parsed_query)&lt;br /&gt;
            results = searcher.search(query, terms=False, scored=True, groupedby=&amp;quot;url&amp;quot;)&lt;br /&gt;
            search_result = self.create_search_result(results)&lt;br /&gt;
&lt;br /&gt;
        return parsed_query, search_result&lt;br /&gt;
&lt;br /&gt;
    def get_document_total_count(self):&lt;br /&gt;
        return self.ix.searcher().doc_count_all()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>