Version 1.6

- NOTICE: config.default.php has changed, update your config.php!!
- [change] Moved magnet popups into combined function
- [change] Better handling of EZTV TV Show data
- [change] Better handling of YTS movie data
- [change] Added 6 new public trackers for Magnets
- [change] Removed regularly unresponsive trackers for Magnets
- [change] Search query string processed before search so all engines don't have to do it individually
- [change] Updated help page
- [new] Special searches can have a note/disclaimer in the lower right corner
- [new] Results pagination for all search tabs (Requires caching to be enabled)
- [new] WordPress function, hook and filter lookup as a special search (See help page)
- [new] Language meta data for some Magnet results
- [new] Try to detect audio codec for EZTV results
- [new] Show MPA Rating for some movie results
- [new] Filter to include NSFW Magnet results or not
- [new] Override NSFW filter with prefix keywords (see config.php)
- [new] Simple search stat counter (Link in footer)
- [tweak] Muted the blue and white text in dark theme a tiny bit
- [tweak] Better light blue header in light theme
- [tweak] Added title and alt attributes to relevant links/images
- [tweak] Removed Magnet search limit of 200 results
- [fix] HTML rendering issues for `<center>` tags in paragraphs
- [fix] Start page buttons in light theme now use the right css variables
- [fix] Properly decode quotes in code snippers for PHP special search
- [fix] Image, News and Magnet search no longer work if they're disabled in config.php
- [fix] 2nd search suggestion not showing if it's available
- [fix] Removed non-functional checking if query is empty in every engine
- [fix] Correctly uses user provided auth hash to keep searching
- [fix] Correctly 'expire' share links for guests so they can not use Goosle beyond seeing the shared results
This commit is contained in:
Arnan de Gans 2024-07-15 14:11:08 -06:00
parent c70fb52917
commit 9f3c62c219
50 changed files with 1855 additions and 1745 deletions

View file

@ -2,15 +2,16 @@
/* Main colors */ /* Main colors */
--color-accent: #1fa4d1; /* Blue */ --color-accent: #1fa4d1; /* Blue */
--background: #232323; /* Almost black */ --background: #232323; /* Almost black */
--background-alt: #1f242b; /* Almost black */ --background-alt: #1f242b; /* Blueish black */
--text: #eff1f7; /* Almost white */ --background-popup: #1f242b; /* Blueish black */
--text-alt: #eff1f7; /* Almost white */ --text: #d6dbdf; /* Almost white */
--text-alt: #eaecee; /* Almost white */
--border: #5f6368; /* Grey */ --border: #5f6368; /* Grey */
--border-alt: #466f82; /* Dark blue */ --border-alt: #466f82; /* Dark blue */
--button-bg: #1fa4d1; /* Blue */ --button-bg: #1fa4d1; /* Blue */
--button-text: #f0f6fc; /* Almost white */ --button-text: #f0f6fc; /* Almost white */
--button-hover: #466f82; /* Dark blue */ --button-hover: #466f82; /* Dark blue */
--link: #2f8ad0; /* Blue */ --link: #3498db; /* Blue */
--link-visited: #6d59a3; /* Purple */ --link-visited: #6d59a3; /* Purple */
--link-source: #eff1f7; /* Almost white */ --link-source: #eff1f7; /* Almost white */
--meta: #999; /* Grey */ --meta: #999; /* Grey */
@ -19,6 +20,7 @@
/* Front page (Also used on oAUTH page) */ /* Front page (Also used on oAUTH page) */
--startpage-border: #545a5f; /* Grey */ --startpage-border: #545a5f; /* Grey */
--startpage-border-alt: #6c747a; /* Lighter grey */ --startpage-border-alt: #6c747a; /* Lighter grey */
--startpage-button-text: #f0f6fc; /* Almost white */
--startpage-button-bg: #2b323b; /* Blueish grey */ --startpage-button-bg: #2b323b; /* Blueish grey */
--startpage-button-bg-alt: #363e4a; /* Lighter blueish grey */ --startpage-button-bg-alt: #363e4a; /* Lighter blueish grey */

View file

@ -3,6 +3,7 @@
--color-accent: #1fa4d1; /* Blue */ --color-accent: #1fa4d1; /* Blue */
--background: #fff; /* White */ --background: #fff; /* White */
--background-alt: #1f242b; /* Almost black */ --background-alt: #1f242b; /* Almost black */
--background-popup: #ebf5fb; /* Blueish white */
--text: #494949; /* Dark grey */ --text: #494949; /* Dark grey */
--text-alt: #f0f6fc; /* Almost white */ --text-alt: #f0f6fc; /* Almost white */
--border: #5f6368; /* Grey */ --border: #5f6368; /* Grey */
@ -19,6 +20,7 @@
/* Front page (Also used on oAUTH page) */ /* Front page (Also used on oAUTH page) */
--startpage-border: #545a5f; /* Grey */ --startpage-border: #545a5f; /* Grey */
--startpage-border-alt: #6c747a; /* Lighter grey */ --startpage-border-alt: #6c747a; /* Lighter grey */
--startpage-button-text: #f0f6fc; /* Almost white */
--startpage-button-bg: #2b323b; /* Blueish grey */ --startpage-button-bg: #2b323b; /* Blueish grey */
--startpage-button-bg-alt: #363e4a; /* Lighter blueish grey */ --startpage-button-bg-alt: #363e4a; /* Lighter blueish grey */

View file

@ -2,10 +2,11 @@
/* Main colors */ /* Main colors */
--color-accent: #1fa4d1; /* Blue */ --color-accent: #1fa4d1; /* Blue */
--background: #fff; /* White */ --background: #fff; /* White */
--background-alt: #ebf3fa; /* Light blue */ --background-alt: #d6eaf8; /* Light blue */
--background-popup: #ebf5fb; /* Blueish white */
--text: #494949; /* Dark grey */ --text: #494949; /* Dark grey */
--text-alt: #494949; /* Dark grey */ --text-alt: #494949; /* Dark grey */
--border: #5f6368; /* Grey */ --border: #808b96; /* Grey */
--border-alt: #466f82; /* Dark blue */ --border-alt: #466f82; /* Dark blue */
--button-bg: #1fa4d1; /* Blue */ --button-bg: #1fa4d1; /* Blue */
--button-text: #f0f6fc; /* Almost white */ --button-text: #f0f6fc; /* Almost white */
@ -17,10 +18,11 @@
--result-special-background: #ebf3fa; /* Light blue */ --result-special-background: #ebf3fa; /* Light blue */
/* Front page (Also used on oAUTH page) */ /* Front page (Also used on oAUTH page) */
--startpage-border: #545a5f; /* Grey */ --startpage-border: #808b96; /* Grey */
--startpage-border-alt: #6c747a; /* Lighter grey */ --startpage-border-alt: #808b96; /* Lighter grey */
--startpage-button-bg: #2b323b; /* Blueish grey */ --startpage-button-text: #f0f6fc; /* Almost white */
--startpage-button-bg-alt: #363e4a; /* Lighter blueish grey */ --startpage-button-bg: #2980B9; /* Blueish grey */
--startpage-button-bg-alt: #7FB3D5; /* Lighter blueish grey */
/* Misc */ /* Misc */
--green: #518257; /* Green */ --green: #518257; /* Green */

View file

@ -7,37 +7,29 @@
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT. * COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any * By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use. * liability that might arise from its use.
---------------------------------------------------------------------------------------
* All icons are borrowed from IconFinder (https://www.iconfinder.com/search/icons?family=unicons-line)
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
body { margin:0; padding:0; line-height:1.2; font-family:Arial, Helvetica, sans-serif; font-weight:400; font-size:1rem; background-color:var(--background); color:var(--text); } body { min-height:100vh; display:flex; flex-direction:column; margin:0; padding:0; line-height:1.2; font-family:Arial, Helvetica, sans-serif; font-weight:400; font-size:1rem; background-color:var(--background); color:var(--text); }
div { margin:0; padding:0; border:0; vertical-align:baseline; } div { margin:0; padding:0; border:0; vertical-align:baseline; }
h2, h3, h4, h5, h6 { margin:0; padding-top:.1em; padding-bottom:.3em; font-weight:400; } h2, h3, h4, h5, h6 { margin:0; padding-top:.1em; padding-bottom:.3em; font-weight:500; }
h1 { font-size:4em; } h1 { font-size:4em; }
h2 { font-size:2em; } h2 { font-size:2em; }
h3 { font-size:1.5em; } h3 { font-size:1.5em; }
h4, h5, h6 { font-size:1em; } h4, h5, h6 { font-size:1.2em; }
p, ul, ol { margin:0; padding-top:.2em; padding-bottom:.5em; } p { margin:0; padding-top:.2em; padding-bottom:.5em; }
ul, ul > li { margin:0; padding:0; list-style:none; } ul, ul > li { margin:0; padding:0; list-style:none; }
input, button { outline:none; } input, button { outline:none; }
button { cursor:pointer; } button { cursor:pointer; }
a { text-decoration:none; color:var(--link); } a { text-decoration:none; color:var(--link); }
a:hover { text-decoration:underline; } a:hover { text-decoration:underline; }
small { padding:5px 0; color:var(--meta); font-size:.8rem; } small { color:var(--meta); font-size:.8rem; }
input[type="text"]:invalid ~ input[type="submit"] { opacity:0.5; pointer-events:none; } input[type="text"]:invalid ~ input[type="submit"] { opacity:0.5; pointer-events:none; }
input[type="search"]::-webkit-search-cancel-button { -webkit-appearance:none; -webkit-mask-image:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMy40MSwxMmw0LjMtNC4yOWExLDEsMCwxLDAtMS40Mi0xLjQyTDEyLDEwLjU5LDcuNzEsNi4yOUExLDEsMCwwLDAsNi4yOSw3LjcxTDEwLjU5LDEybC00LjMsNC4yOWExLDEsMCwwLDAsMCwxLjQyLDEsMSwwLDAsMCwxLjQyLDBMMTIsMTMuNDFsNC4yOSw0LjNhMSwxLDAsMCwwLDEuNDIsMCwxLDEsMCwwLDAsMC0xLjQyWiIgZmlsbD0iIzY1NjNmZiIvPjwvc3ZnPg=="); } input[type="search"]::-webkit-search-cancel-button { -webkit-appearance:none; -webkit-mask-image:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMy40MSwxMmw0LjMtNC4yOWExLDEsMCwxLDAtMS40Mi0xLjQyTDEyLDEwLjU5LDcuNzEsNi4yOUExLDEsMCwwLDAsNi4yOSw3LjcxTDEwLjU5LDEybC00LjMsNC4yOWExLDEsMCwwLDAsMCwxLjQyLDEsMSwwLDAsMCwxLjQyLDBMMTIsMTMuNDFsNC4yOSw0LjNhMSwxLDAsMCwwLDEuNDIsMCwxLDEsMCwwLDAsMC0xLjQyWiIgZmlsbD0iIzY1NjNmZiIvPjwvc3ZnPg=="); }
/* Page structure */ .content { margin:25px 158px; padding:0; }
body { min-height:100vh; display:flex; flex-direction:column; }
.header { padding:0; width:100%; }
.header form { margin:35px 0; }
.content { margin:15px 158px; padding:0; }
.footer { box-sizing:border-box; bottom:0; margin-top:auto; padding:10px 5px; width:100%; }
/* Flex grid (Box office, footer) */
.grid-container { display:flex; flex-direction:row; }
.list-grid, .footer-grid { flex:1; width:50%; }
.list-grid:first-child, .footer-grid:first-child { margin-right:20px; }
.footer-grid:nth-child(2) { text-align:right; }
/* Start page */ /* Start page */
.startpage { background-color:var(--background-alt); color:var(--text-alt); } .startpage { background-color:var(--background-alt); color:var(--text-alt); }
@ -45,7 +37,7 @@ body { min-height:100vh; display:flex; flex-direction:column; }
.startpage .search-field, .password-generator .password { padding:10px 20px; width:600px; color:var(--text-alt); background-color:var(--background-alt); font-size:2rem; border:1px solid var(--startpage-border); border-radius:10px; } .startpage .search-field, .password-generator .password { padding:10px 20px; width:600px; color:var(--text-alt); background-color:var(--background-alt); font-size:2rem; border:1px solid var(--startpage-border); border-radius:10px; }
.startpage .search-field:focus, .password-generator .password:focus { border:1px solid var(--startpage-border-alt); } .startpage .search-field:focus, .password-generator .password:focus { border:1px solid var(--startpage-border-alt); }
.startpage .search-field[type="search"]::-webkit-search-cancel-button { background-size:28px 28px; height:28px; width:28px; background:var(--text-alt); } .startpage .search-field[type="search"]::-webkit-search-cancel-button { background-size:28px 28px; height:28px; width:28px; background:var(--text-alt); }
.startpage .web-search, .startpage .image-search, .startpage .magnet-search, .startpage .box-office { display:inline-block; box-sizing:border-box; margin:30px 20px 10px 20px; padding:13px 10px; min-width:130px; min-height:48px; vertical-align:middle; text-align:center; font-size:1rem; font-weight:400; background-color:var(--startpage-button-bg); color:var(--text-alt); border:1px solid var(--startpage-border); border-radius:6px; } .startpage .web-search, .startpage .image-search, .startpage .magnet-search, .startpage .box-office { display:inline-block; box-sizing:border-box; margin:30px 20px 10px 20px; padding:13px 10px; min-width:130px; min-height:48px; vertical-align:middle; text-align:center; font-size:1rem; font-weight:400; background-color:var(--startpage-button-bg); color:var(--startpage-button-text); border:1px solid var(--startpage-border); border-radius:6px; }
.startpage .magnet-search { margin-right:0; border-radius:6px 0 0 6px; } .startpage .magnet-search { margin-right:0; border-radius:6px 0 0 6px; }
.startpage .box-office { margin-left:0; border-left:1px solid var(--startpage-button-bg); border-radius:0 6px 6px 0; } .startpage .box-office { margin-left:0; border-left:1px solid var(--startpage-button-bg); border-radius:0 6px 6px 0; }
.startpage .web-search:hover, .startpage .image-search:hover, .startpage .magnet-search:hover, .startpage .box-office:hover { border:1px solid var(--startpage-border-alt); background-color:var(--startpage-button-bg-alt); text-decoration:none; } .startpage .web-search:hover, .startpage .image-search:hover, .startpage .magnet-search:hover, .startpage .box-office:hover { border:1px solid var(--startpage-border-alt); background-color:var(--startpage-button-bg-alt); text-decoration:none; }
@ -54,7 +46,8 @@ body { min-height:100vh; display:flex; flex-direction:column; }
.password-generator .password { margin:10px auto; width:300px; text-align:center; font-size:.8rem; } .password-generator .password { margin:10px auto; width:300px; text-align:center; font-size:.8rem; }
/* Page header (Search results, Help, Box office) */ /* Page header (Search results, Help, Box office) */
.header { background-color:var(--background-alt); color:var(--text-alt); border-bottom:3px solid var(--color-accent); } .header { padding:0; width:100%; background-color:var(--background-alt); color:var(--text-alt); border-bottom:3px solid var(--color-accent); }
.header form { margin:35px 0; }
.header .logo { position:absolute; margin:0 18px; font-size:2rem; } .header .logo { position:absolute; margin:0 18px; font-size:2rem; }
.header .logo a, .header .logo a:hover { text-decoration:none; color:var(--text-alt); cursor:pointer; } .header .logo a, .header .logo a:hover { text-decoration:none; color:var(--text-alt); cursor:pointer; }
.header .search-field, .header .button { display:inline-block; box-sizing:border-box; vertical-align:middle; height:40px; font-size:1.2rem } .header .search-field, .header .button { display:inline-block; box-sizing:border-box; vertical-align:middle; height:40px; font-size:1.2rem }
@ -62,47 +55,52 @@ body { min-height:100vh; display:flex; flex-direction:column; }
.header .search-field[type="search"]::-webkit-search-cancel-button { background-size:20px 20px; height:20px; width:20px; background-color:var(--text-alt); } .header .search-field[type="search"]::-webkit-search-cancel-button { background-size:20px 20px; height:20px; width:20px; background-color:var(--text-alt); }
.header .button { margin:0 10px 0 0; padding:5px 20px 5px 15px; color:var(--button-text); background-color:var(--button-bg); border:none; border-radius:0 10px 10px 0; } .header .button { margin:0 10px 0 0; padding:5px 20px 5px 15px; color:var(--button-text); background-color:var(--button-bg); border:none; border-radius:0 10px 10px 0; }
.header .navigation { margin-left:158px; margin-bottom:8px; } /* Margin-bottom must match with padding-bottom on line 79 */ .navigation { margin-left:158px; margin-bottom:8px; } /* Margin-bottom must match with padding-bottom on line 79 */
.header .navigation img { margin-right:5px; height:16px; vertical-align:middle; } .navigation a { margin-right:20px; border:none; cursor:pointer; text-decoration:none; }
.header .navigation a { margin-right:20px; border:none; cursor:pointer; text-decoration:none; } .navigation a:visited { color:var(--link); }
.header .navigation a:visited { color:var(--link); } .navigation a:hover { color:var(--text-alt); }
.header .navigation a:hover { color:var(--text-alt); } .navigation .active { padding-bottom:8px; border-bottom:4px solid var(--color-accent); }
.header .navigation .active { padding-bottom:8px; border-bottom:4px solid var(--color-accent); }
/* Navigation icons (https://www.iconfinder.com/search/icons?family=unicons-line) */ /* Navigation icons */
.navigation a.tab-search::before { content:""; display:inline-block; width:20px; height:20px; background:var(--color-accent); vertical-align:middle; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMiwyMEg1YTEsMSwwLDAsMS0xLTFWNUExLDEsMCwwLDEsNSw0aDVWN2EzLDMsMCwwLDAsMywzaDN2MWExLDEsMCwwLDAsMiwwVjlzMCwwLDAtLjA2YTEuMzEsMS4zMSwwLDAsMC0uMDYtLjI3bDAtLjA5YTEuMDcsMS4wNywwLDAsMC0uMTktLjI4aDBsLTYtNmgwYTEuMDcsMS4wNywwLDAsMC0uMjgtLjE5LjMyLjMyLDAsMCwwLS4wOSwwQS44OC44OCwwLDAsMCwxMS4wNSwySDVBMywzLDAsMCwwLDIsNVYxOWEzLDMsMCwwLDAsMywzaDdhMSwxLDAsMCwwLDAtMlpNMTIsNS40MSwxNC41OSw4SDEzYTEsMSwwLDAsMS0xLTFaTTcsOGExLDEsMCwwLDAsMCwySDhBMSwxLDAsMCwwLDgsOFpNMjEuNzEsMjAuMjlsLTEuMTctMS4xNkEzLjQ0LDMuNDQsMCwwLDAsMjAsMTVoMEEzLjQ5LDMuNDksMCwwLDAsMTQsMTcuNDlhMy40NiwzLjQ2LDAsMCwwLDUuMTMsMy4wNWwxLjE2LDEuMTdhMSwxLDAsMCwwLDEuNDIsMEExLDEsMCwwLDAsMjEuNzEsMjAuMjlabS0zLjE3LTEuNzVhMS41NCwxLjU0LDAsMCwxLTIuMTEsMEExLjUsMS41LDAsMCwxLDE2LDE3LjQ5YTEuNDYsMS40NiwwLDAsMSwuNDQtMS4wNiwxLjQ4LDEuNDgsMCwwLDEsMS0uNDNBMS40NywxLjQ3LDAsMCwxLDE5LDE3LjQ5LDEuNSwxLjUsMCwwLDEsMTguNTQsMTguNTRaTTEzLDEySDdhMSwxLDAsMCwwLDAsMmg2YTEsMSwwLDAsMCwwLTJabS0yLDZhMSwxLDAsMCwwLDAtMkg3YTEsMSwwLDAsMCwwLDJaIiBmaWxsPSIjNjU2M2ZmIi8+PC9zdmc+'); } .navigation a.tab-search::before { content:""; display:inline-block; width:1.1em; height:1.1em; background:var(--color-accent); vertical-align:text-bottom; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMiwyMEg1YTEsMSwwLDAsMS0xLTFWNUExLDEsMCwwLDEsNSw0aDVWN2EzLDMsMCwwLDAsMywzaDN2MWExLDEsMCwwLDAsMiwwVjlzMCwwLDAtLjA2YTEuMzEsMS4zMSwwLDAsMC0uMDYtLjI3bDAtLjA5YTEuMDcsMS4wNywwLDAsMC0uMTktLjI4aDBsLTYtNmgwYTEuMDcsMS4wNywwLDAsMC0uMjgtLjE5LjMyLjMyLDAsMCwwLS4wOSwwQS44OC44OCwwLDAsMCwxMS4wNSwySDVBMywzLDAsMCwwLDIsNVYxOWEzLDMsMCwwLDAsMywzaDdhMSwxLDAsMCwwLDAtMlpNMTIsNS40MSwxNC41OSw4SDEzYTEsMSwwLDAsMS0xLTFaTTcsOGExLDEsMCwwLDAsMCwySDhBMSwxLDAsMCwwLDgsOFpNMjEuNzEsMjAuMjlsLTEuMTctMS4xNkEzLjQ0LDMuNDQsMCwwLDAsMjAsMTVoMEEzLjQ5LDMuNDksMCwwLDAsMTQsMTcuNDlhMy40NiwzLjQ2LDAsMCwwLDUuMTMsMy4wNWwxLjE2LDEuMTdhMSwxLDAsMCwwLDEuNDIsMEExLDEsMCwwLDAsMjEuNzEsMjAuMjlabS0zLjE3LTEuNzVhMS41NCwxLjU0LDAsMCwxLTIuMTEsMEExLjUsMS41LDAsMCwxLDE2LDE3LjQ5YTEuNDYsMS40NiwwLDAsMSwuNDQtMS4wNiwxLjQ4LDEuNDgsMCwwLDEsMS0uNDNBMS40NywxLjQ3LDAsMCwxLDE5LDE3LjQ5LDEuNSwxLjUsMCwwLDEsMTguNTQsMTguNTRaTTEzLDEySDdhMSwxLDAsMCwwLDAsMmg2YTEsMSwwLDAsMCwwLTJabS0yLDZhMSwxLDAsMCwwLDAtMkg3YTEsMSwwLDAsMCwwLDJaIiBmaWxsPSIjNjU2M2ZmIi8+PC9zdmc+'); }
.navigation a.tab-image::before { content:""; display:inline-block; width:20px; height:20px; background:var(--color-accent); vertical-align:middle; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xOSwxM2ExLDEsMCwwLDAtMSwxdi4zOWwtMS40OC0xLjQ4YTIuNzksMi43OSwwLDAsMC0zLjkzLDBsLS43LjdMOS40MSwxMS4xMmEyLjg3LDIuODcsMCwwLDAtMy45MywwTDQsMTIuNjFWN0ExLDEsMCwwLDEsNSw2SDlBMSwxLDAsMCwwLDksNEg1QTMsMywwLDAsMCwyLDdWMTlhMywzLDAsMCwwLDMsM0gxN2EzLDMsMCwwLDAsMy0zVjE0QTEsMSwwLDAsMCwxOSwxM1pNNSwyMGExLDEsMCwwLDEtMS0xVjE1LjQzbDIuOS0yLjg5YS43OS43OSwwLDAsMSwxLjA5LDBsMy4xNywzLjE3LDAsMEwxNS40NSwyMFptMTMtMWExLDEsMCwwLDEtLjE4LjU0TDEzLjMxLDE1bC43LS42OWEuNzcuNzcsMCwwLDEsMS4xLDBMMTgsMTcuMjJabTMuNzEtOC43MUwyMCw4LjU3YTQuMzEsNC4zMSwwLDEsMC02LjcyLjc5LDQuMjcsNC4yNywwLDAsMCwzLDEuMjZBNC4zNCw0LjM0LDAsMCwwLDE4LjU3LDEwbDEuNzIsMS43M2ExLDEsMCwwLDAsMS40MiwwQTEsMSwwLDAsMCwyMS43MSwxMC4yOVpNMTgsOGEyLjMyLDIuMzIsMCwxLDEsMC0zLjI3QTIuMzIsMi4zMiwwLDAsMSwxOCw4WiIgZmlsbD0iIzY1NjNmZiIvPjwvc3ZnPg=='); } .navigation a.tab-image::before { content:""; display:inline-block; width:1.1em; height:1.1em; background:var(--color-accent); vertical-align:text-bottom; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xOSwxM2ExLDEsMCwwLDAtMSwxdi4zOWwtMS40OC0xLjQ4YTIuNzksMi43OSwwLDAsMC0zLjkzLDBsLS43LjdMOS40MSwxMS4xMmEyLjg3LDIuODcsMCwwLDAtMy45MywwTDQsMTIuNjFWN0ExLDEsMCwwLDEsNSw2SDlBMSwxLDAsMCwwLDksNEg1QTMsMywwLDAsMCwyLDdWMTlhMywzLDAsMCwwLDMsM0gxN2EzLDMsMCwwLDAsMy0zVjE0QTEsMSwwLDAsMCwxOSwxM1pNNSwyMGExLDEsMCwwLDEtMS0xVjE1LjQzbDIuOS0yLjg5YS43OS43OSwwLDAsMSwxLjA5LDBsMy4xNywzLjE3LDAsMEwxNS40NSwyMFptMTMtMWExLDEsMCwwLDEtLjE4LjU0TDEzLjMxLDE1bC43LS42OWEuNzcuNzcsMCwwLDEsMS4xLDBMMTgsMTcuMjJabTMuNzEtOC43MUwyMCw4LjU3YTQuMzEsNC4zMSwwLDEsMC02LjcyLjc5LDQuMjcsNC4yNywwLDAsMCwzLDEuMjZBNC4zNCw0LjM0LDAsMCwwLDE4LjU3LDEwbDEuNzIsMS43M2ExLDEsMCwwLDAsMS40MiwwQTEsMSwwLDAsMCwyMS43MSwxMC4yOVpNMTgsOGEyLjMyLDIuMzIsMCwxLDEsMC0zLjI3QTIuMzIsMi4zMiwwLDAsMSwxOCw4WiIgZmlsbD0iIzY1NjNmZiIvPjwvc3ZnPg=='); }
.navigation a.tab-news::before { content:""; display:inline-block; width:20px; height:20px; background:var(--color-accent); vertical-align:middle; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNywxMUgxNmExLDEsMCwwLDAsMCwyaDFhMSwxLDAsMCwwLDAtMlptMCw0SDE2YTEsMSwwLDAsMCwwLDJoMWExLDEsMCwwLDAsMC0yWk0xMSw5aDZhMSwxLDAsMCwwLDAtMkgxMWExLDEsMCwwLDAsMCwyWk0yMSwzSDdBMSwxLDAsMCwwLDYsNFY3SDNBMSwxLDAsMCwwLDIsOFYxOGEzLDMsMCwwLDAsMywzSDE4YTQsNCwwLDAsMCw0LTRWNEExLDEsMCwwLDAsMjEsM1pNNiwxOGExLDEsMCwwLDEtMiwwVjlINlptMTQtMWEyLDIsMCwwLDEtMiwySDcuODJBMywzLDAsMCwwLDgsMThWNUgyMFptLTktNGgxYTEsMSwwLDAsMCwwLTJIMTFhMSwxLDAsMCwwLDAsMlptMCw0aDFhMSwxLDAsMCwwLDAtMkgxMWExLDEsMCwwLDAsMCwyWiIgZmlsbD0iIzY1NjNmZiIvPjwvc3ZnPg=='); } .navigation a.tab-news::before { content:""; display:inline-block; width:1.1em; height:1.1em; background:var(--color-accent); vertical-align:text-bottom; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNywxMUgxNmExLDEsMCwwLDAsMCwyaDFhMSwxLDAsMCwwLDAtMlptMCw0SDE2YTEsMSwwLDAsMCwwLDJoMWExLDEsMCwwLDAsMC0yWk0xMSw5aDZhMSwxLDAsMCwwLDAtMkgxMWExLDEsMCwwLDAsMCwyWk0yMSwzSDdBMSwxLDAsMCwwLDYsNFY3SDNBMSwxLDAsMCwwLDIsOFYxOGEzLDMsMCwwLDAsMywzSDE4YTQsNCwwLDAsMCw0LTRWNEExLDEsMCwwLDAsMjEsM1pNNiwxOGExLDEsMCwwLDEtMiwwVjlINlptMTQtMWEyLDIsMCwwLDEtMiwySDcuODJBMywzLDAsMCwwLDgsMThWNUgyMFptLTktNGgxYTEsMSwwLDAsMCwwLTJIMTFhMSwxLDAsMCwwLDAsMlptMCw0aDFhMSwxLDAsMCwwLDAtMkgxMWExLDEsMCwwLDAsMCwyWiIgZmlsbD0iIzY1NjNmZiIvPjwvc3ZnPg=='); }
.navigation a.tab-magnet::before { content:""; display:inline-block; width:20px; height:20px; background:var(--color-accent); vertical-align:middle; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0yMCw4Ljk0YTEuMzEsMS4zMSwwLDAsMC0uMDYtLjI3bDAtLjA5YTEuMDcsMS4wNywwLDAsMC0uMTktLjI4aDBsLTYtNmgwYTEuMDcsMS4wNywwLDAsMC0uMjgtLjE5bC0uMSwwQTEuMSwxLjEsMCwwLDAsMTMuMDYsMkg3QTMsMywwLDAsMCw0LDVWMTlhMywzLDAsMCwwLDMsM0gxN2EzLDMsMCwwLDAsMy0zVjlTMjAsOSwyMCw4Ljk0Wk0xNCw1LjQxLDE2LjU5LDhIMTVhMSwxLDAsMCwxLTEtMVpNMTgsMTlhMSwxLDAsMCwxLTEsMUg3YTEsMSwwLDAsMS0xLTFWNUExLDEsMCwwLDEsNyw0aDVWN2EzLDMsMCwwLDAsMywzaDNabS00LjcxLTQuNzEtLjI5LjNWMTJhMSwxLDAsMCwwLTIsMHYyLjU5bC0uMjktLjNhMSwxLDAsMCwwLTEuNDIsMS40MmwyLDJhMSwxLDAsMCwwLC4zMy4yMS45NC45NCwwLDAsMCwuNzYsMCwxLDEsMCwwLDAsLjMzLS4yMWwyLTJhMSwxLDAsMCwwLTEuNDItMS40MloiIGZpbGw9IiM2NTYzZmYiLz48L3N2Zz4='); } .navigation a.tab-magnet::before { content:""; display:inline-block; width:1.1em; height:1.1em; background:var(--color-accent); vertical-align:text-bottom; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0yMCw4Ljk0YTEuMzEsMS4zMSwwLDAsMC0uMDYtLjI3bDAtLjA5YTEuMDcsMS4wNywwLDAsMC0uMTktLjI4aDBsLTYtNmgwYTEuMDcsMS4wNywwLDAsMC0uMjgtLjE5bC0uMSwwQTEuMSwxLjEsMCwwLDAsMTMuMDYsMkg3QTMsMywwLDAsMCw0LDVWMTlhMywzLDAsMCwwLDMsM0gxN2EzLDMsMCwwLDAsMy0zVjlTMjAsOSwyMCw4Ljk0Wk0xNCw1LjQxLDE2LjU5LDhIMTVhMSwxLDAsMCwxLTEtMVpNMTgsMTlhMSwxLDAsMCwxLTEsMUg3YTEsMSwwLDAsMS0xLTFWNUExLDEsMCwwLDEsNyw0aDVWN2EzLDMsMCwwLDAsMywzaDNabS00LjcxLTQuNzEtLjI5LjNWMTJhMSwxLDAsMCwwLTIsMHYyLjU5bC0uMjktLjNhMSwxLDAsMCwwLTEuNDIsMS40MmwyLDJhMSwxLDAsMCwwLC4zMy4yMS45NC45NCwwLDAsMCwuNzYsMCwxLDEsMCwwLDAsLjMzLS4yMWwyLTJhMSwxLDAsMCwwLTEuNDItMS40MloiIGZpbGw9IiM2NTYzZmYiLz48L3N2Zz4='); }
/* Search results (web, image, magnet, box office) */ /* Search results (web, image, magnet, box office) */
.resultspage .timer { margin:10px 0 0 0; } .resultspage .meta { margin:0 0 15px 0; }
.resultspage .sources { font-size:.8rem; color:var(--meta); } .resultspage .timer, .resultspage .didyoumean { margin:0; padding:0; }
.resultspage .result, .boxofficepage .result, .resultspage .result-special, .resultspage .result.shared, .resultspage .sources, .resultspage .suggestion { margin:0 0 25px 0; } .resultspage .sources, .resultspage .suggestion { padding:0; font-size:.8rem; color:var(--meta); }
.resultspage .result-grid .result, .resultspage .result.image { margin:0; } .resultspage .result, .resultspage .result-special, .resultspage .result.shared, .boxofficepage .result { margin:0 0 25px 0; }
.resultspage .result-special, .resultspage .result.shared { padding:10px; } .resultspage .result-special, .resultspage .result.shared { padding:10px; }
/* Results formatting */ /* Results formatting */
div.title, div.description, div.text, div.url, div.source { word-wrap:break-word; } .resultspage .title, .resultspage .description, .resultspage .text, .resultspage .url, .resultspage .source, .resultspage .note { word-wrap:break-word; }
.result div.url, .result-special div.source { line-height:1.6; letter-spacing:.2px; } .resultspage .result .url, .resultspage .result-special .source { letter-spacing:.2px; }
.result div.url a, .result-special div.source a { cursor:pointer; text-decoration:none; color:var(--link-source); } .resultspage .result .url a, .resultspage .result-special .source a { cursor:pointer; text-decoration:none; color:var(--link-source); }
.result div.title h2 { position:relative; letter-spacing:-.01px; font-size:1.5rem; } .resultspage .result .title h2 { position:relative; letter-spacing:-.01px; font-size:1.5rem; }
.result div.title h2:hover { text-decoration:underline; } .resultspage .result .title h2:hover { text-decoration:underline; }
.result div.title a { display:block; cursor:pointer; } .resultspage .result .title a { display:block; cursor:pointer; }
.result div.title a:visited { color:var(--link-visited); } .resultspage .result .title a:visited { color:var(--link-visited); }
.result div.description { line-height:1.4; }
.result div.description p { padding-top:0; padding-bottom:0; }
.result div.meta { padding:5px 0; font-size:.8rem; color:var(--meta); }
.result div.engines { padding:2px 0; font-size:.8rem; color:var(--meta); }
.result.news h2 { padding-top:0; padding-bottom:0; } .resultspage .result .description p, .resultspage .result .meta p { padding-top:0; padding-bottom:0; }
.result.news { clear:both; overflow:auto; } .resultspage .result .meta { padding:0; font-size:.8rem; color:var(--meta); text-align:center; }
.resultspage .result.image .meta { margin:5px 0 0 0; }
.resultspage .result .engines { padding:2px 0; font-size:.8rem; color:var(--meta); }
.resultspage .result.news { display:flex; flex-direction:row; column-gap:1rem; width:100%; }
.resultspage .result.news .title h2, .resultspage .result.magnet .title h2 { padding-top:0; padding-bottom:.2em; }
.resultspage .result.news .image { position:relative; overflow:hidden; width:140px; min-width:140px; height: 100px; border-radius:10px; }
.resultspage .result.news .image::before { content:""; position:absolute; height:100%; width:100%; background-color:var(--color-accent); background-image:url('/assets/images/goosle-nobg.webp'); background-position:center; background-repeat:no-repeat; border-radius:10px; z-index:-1; }
.resultspage .result.news .image img { object-fit:cover; object-position:center; width:100%; height:100%; border-radius:10px; }
.resultspage .result-special .note { text-align:right; }
/* Special results and shared magnet result */ /* Special results and shared magnet result */
.result.shared, .result-special { overflow:hidden; background-color:var(--result-special-background); border:1px solid var(--border-alt); border-radius:10px; } .resultspage .result.shared, .resultspage .result-special { overflow:hidden; background-color:var(--result-special-background); border:1px solid var(--border-alt); border-radius:10px; }
.result.shared div.title h2, .result-special div.title h2 { padding-top:0; text-decoration:none; } .resultspage .result.shared div.title h2, .resultspage .result-special div.title h2 { padding-top:0; text-decoration:none; }
.boxofficepage .result { border:1px solid var(--result-border); border-radius:8px; } .boxofficepage .result { border:1px solid var(--result-border); border-radius:8px; }
.boxofficepage .result div.title h2 { font-size:1.2rem; } .boxofficepage .result div.title h2 { font-size:1.2rem; }
@ -112,26 +110,27 @@ div.title, div.description, div.text, div.url, div.source { word-wrap:break-word
/* Grids (image and magnet highlights) */ /* Grids (image and magnet highlights) */
@supports (display:grid) { @supports (display:grid) {
.result-grid ul { display:grid; grid-template-columns:repeat(auto-fill, minmax(8rem, 1fr)); grid-gap:1rem; } .result-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(8rem, 1fr)); row-gap:2rem; column-gap:1rem; }
} }
@supports not (display:grid) { @supports not (display:grid) {
.result-grid ul > * { max-width:8rem; margin-left:auto; margin-right:auto; } .result-grid > * { max-width:8rem; margin-left:auto; margin-right:auto; }
.result-grid ul .result { display:inline-block; margin:.75rem; width:12.5%; } .result-grid .result { display:inline-block; margin:.75rem; width:12.5%; }
.result-grid ul > * + * { margin-top:1rem; } .result-grid > * + * { margin-top:1rem; }
} }
/* Grid results */ /* Grid results */
.result-grid { width:100%; margin:0 0 25px 0; } .result-grid { margin:0 0 25px 0; }
.result-grid ul .result .result-box { position:relative; } .result-grid .result.image .thumb, .result-grid .result.highlight .thumb { position:relative; overflow:hidden; height: 140px; border-radius:10px; }
.result-grid ul .result.image .result-box::after, .result-grid ul .result.eztv .result-box::after { display:block; padding-bottom:100%; content:""; } .result-grid .result.yts .thumb { height: 210px;; }
.result-grid ul .result.image .result-box img, .result-grid ul .result.eztv .result-box img { position:absolute; object-fit:cover; width:100%; height:100%; border-radius:10px; } .result-grid .result.image .thumb::before, .result-grid .result.highlight .thumb::before { position:absolute; height:100%; width:100%; background-color:var(--color-accent); background-image:url('/assets/images/goosle-nobg.webp'); background-position:center; background-repeat:no-repeat; border-radius:10px; content:""; z-index:-1; }
.result-grid ul .result.yts .result-box img { width:100%; height:100%; border-radius:10px; } .result-grid .result.image .thumb img, .result-grid .result.highlight .thumb img { object-fit:cover; object-position:center; width:100%; height:100%; border-radius:10px; }
.result-grid ul .result .result-box img:hover { outline:none; border-color:var(--border); border-radius:10px; box-shadow:0 0 10px var(--border); } .result-grid .result.image .thumb:hover, .result-grid .result.highlight .thumb:hover { outline:none; border-color:var(--border); border-radius:10px; box-shadow:0 0 10px var(--border); }
.result-grid .result, .result-grid .meta { margin:0; padding:0; }
/* Magnet highlight/Share/Boxoffice popup */ /* Magnet highlight/Share/Boxoffice popup */
.goosebox { display:none; position:fixed; inset:0; z-index:10000; overflow:auto; background-color:rgb(0, 0, 0, .75); } .goosebox { display:none; position:fixed; inset:0; z-index:10000; overflow:auto; background-color:rgb(0, 0, 0, .75); }
.goosebox.open { display:block; } .goosebox.open { display:block; }
.goosebox-body { margin:50px auto; padding:20px; width:50%; background:var(--background); border:1px solid var(--border); border-radius:10px; } .goosebox-body { margin:50px auto; padding:20px; width:50%; background:var(--background-popup); border:1px solid var(--border); border-radius:10px; }
.goosebox-body h2 { padding:0 0 .3em 0; } .goosebox-body h2 { padding:0 0 .3em 0; }
.goosebox-body h3 { font-size:1.2rem; } .goosebox-body h3 { font-size:1.2rem; }
.goosebox-body p { padding-top:.1em; padding-bottom:.2em; } .goosebox-body p { padding-top:.1em; padding-bottom:.2em; }
@ -144,6 +143,11 @@ div.title, div.description, div.text, div.url, div.source { word-wrap:break-word
.goosebox-body .share-button { margin:0 auto 10px auto; border-radius:0 0 10px 10px; } .goosebox-body .share-button { margin:0 auto 10px auto; border-radius:0 0 10px 10px; }
.goosebox-body .success, .goosebox-body .fail { font-weight:600; } .goosebox-body .success, .goosebox-body .fail { font-weight:600; }
/* Stats display (stats page) */
.statspage h1 { margin-bottom:10px; padding:0; text-align:center; font-size:2.5em; font-weight:400; }
.statspage h2 { margin-bottom:10px; padding:0; text-align:center; font-size:1.5em; }
.statspage p { font-family:'american typewriter'; }
/* oAUTH page */ /* oAUTH page */
.oauthpage { background-color:var(--background-alt); color:var(--text-alt); } .oauthpage { background-color:var(--background-alt); color:var(--text-alt); }
.oauthpage .oauth-form { text-align:center; margin-top:20px; } .oauthpage .oauth-form { text-align:center; margin-top:20px; }
@ -152,10 +156,37 @@ div.title, div.description, div.text, div.url, div.source { word-wrap:break-word
.oauthpage .oauth-buttons button { margin:30px 20px 10px 20px; padding:13px 10px; min-width:130px; color:var(--text-alt); background-color:var(--startpage-button-bg); border:1px solid var(--startpage-border); font-size:1.2rem; border-radius:6px; } .oauthpage .oauth-buttons button { margin:30px 20px 10px 20px; padding:13px 10px; min-width:130px; color:var(--text-alt); background-color:var(--startpage-button-bg); border:1px solid var(--startpage-border); font-size:1.2rem; border-radius:6px; }
.oauthpage .oauth-buttons button:hover { border:1px solid var(--startpage-border-alt); background-color:var(--startpage-button-bg-alt); text-decoration:none; } .oauthpage .oauth-buttons button:hover { border:1px solid var(--startpage-border-alt); background-color:var(--startpage-button-bg-alt); text-decoration:none; }
/* Pagination */
.pagination { text-align:center; }
.pagination a { font-size:1.2em; }
.pagination a.current { font-size:1.4em; font-weight:400; text-decoration:underline; }
.arrow-left::before { content:""; display:inline-block; width:1.2em; height:1.2em; background:var(--link); vertical-align:text-top; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgZGF0YS1uYW1lPSJMYXllciAxIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE3LDExSDkuNDFsMy4zLTMuMjlhMSwxLDAsMSwwLTEuNDItMS40MmwtNSw1YTEsMSwwLDAsMC0uMjEuMzMsMSwxLDAsMCwwLDAsLjc2LDEsMSwwLDAsMCwuMjEuMzNsNSw1YTEsMSwwLDAsMCwxLjQyLDAsMSwxLDAsMCwwLDAtMS40Mkw5LjQxLDEzSDE3YTEsMSwwLDAsMCwwLTJaIiBmaWxsPSIjNjU2M2ZmIi8+PC9zdmc+'); }
.arrow-right::before { content:""; display:inline-block; width:1.2em; height:1.2em; background:var(--link); vertical-align:text-top; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgZGF0YS1uYW1lPSJMYXllciAxIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE3LjkyLDExLjYyYTEsMSwwLDAsMC0uMjEtLjMzbC01LTVhMSwxLDAsMCwwLTEuNDIsMS40MkwxNC41OSwxMUg3YTEsMSwwLDAsMCwwLDJoNy41OWwtMy4zLDMuMjlhMSwxLDAsMCwwLDAsMS40MiwxLDEsMCwwLDAsMS40MiwwbDUtNWExLDEsMCwwLDAsLjIxLS4zM0ExLDEsMCwwLDAsMTcuOTIsMTEuNjJaIiBmaWxsPSIjNjU2M2ZmIi8+PC9zdmc+'); }
/* Flex grid (footer) */
.footer { display:flex; flex-direction:row; }
.footer-grid { flex:1; width:50%; }
.footer-grid:first-child { margin-right:20px; }
.footer-grid:nth-child(2) { text-align:right; }
/* Footer */ /* Footer */
.footer { background-color:var(--background-alt); color:var(--text-alt); border-top:2px solid var(--color-accent); font-size:.9rem; } .footer { box-sizing:border-box; bottom:0; margin-top:auto; padding:10px 5px; width:100%; background-color:var(--background-alt); color:var(--text-alt); border-top:2px solid var(--color-accent); font-size:.9rem; }
.footer a { color:var(--text-alt); } .footer a { color:var(--text-alt); }
/* MPA rating colors */
.mpa-g { color:#518257; }
.mpa-pg { color:#EB984E; }
.mpa-pg13 { color:#8E44AD; }
.mpa-r { color:#C0392B; }
.mpa-nc17 { color:#1A5276; }
/* Tooltips */
.tooltip { position:relative; display:inline-block; }
.tooltip-question::before { content:""; display:inline-block; width:1.1em; height:1.1em; background:var(--link); vertical-align:text-bottom; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMS4yOSwxNS4yOWExLjU4LDEuNTgsMCwwLDAtLjEyLjE1Ljc2Ljc2LDAsMCwwLS4wOS4xOC42NC42NCwwLDAsMC0uMDYuMTgsMS4zNiwxLjM2LDAsMCwwLDAsLjIuODQuODQsMCwwLDAsLjA4LjM4LjkuOSwwLDAsMCwuNTQuNTQuOTQuOTQsMCwwLDAsLjc2LDAsLjkuOSwwLDAsMCwuNTQtLjU0QTEsMSwwLDAsMCwxMywxNmExLDEsMCwwLDAtLjI5LS43MUExLDEsMCwwLDAsMTEuMjksMTUuMjlaTTEyLDJBMTAsMTAsMCwxLDAsMjIsMTIsMTAsMTAsMCwwLDAsMTIsMlptMCwxOGE4LDgsMCwxLDEsOC04QTgsOCwwLDAsMSwxMiwyMFpNMTIsN0EzLDMsMCwwLDAsOS40LDguNWExLDEsMCwxLDAsMS43MywxQTEsMSwwLDAsMSwxMiw5YTEsMSwwLDAsMSwwLDIsMSwxLDAsMCwwLTEsMXYxYTEsMSwwLDAsMCwyLDB2LS4xOEEzLDMsMCwwLDAsMTIsN1oiIGZpbGw9IiM2NTYzZmYiLz48L3N2Zz4='); }
.tooltip-alert::before { content:""; display:inline-block; width:1.1em; height:1.1em; background:var(--link); vertical-align:text-bottom; mask-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMiwxNmExLDEsMCwxLDAsMSwxQTEsMSwwLDAsMCwxMiwxNlptMTAuNjcsMS40Ny04LjA1LTE0YTMsMywwLDAsMC01LjI0LDBsLTgsMTRBMywzLDAsMCwwLDMuOTQsMjJIMjAuMDZhMywzLDAsMCwwLDIuNjEtNC41M1ptLTEuNzMsMmExLDEsMCwwLDEtLjg4LjUxSDMuOTRhMSwxLDAsMCwxLS44OC0uNTEsMSwxLDAsMCwxLDAtMWw4LTE0YTEsMSwwLDAsMSwxLjc4LDBsOC4wNSwxNEExLDEsMCwwLDEsMjAuOTQsMTkuNDlaTTEyLDhhMSwxLDAsMCwwLTEsMXY0YTEsMSwwLDAsMCwyLDBWOUExLDEsMCwwLDAsMTIsOFoiIGZpbGw9IiM2NTYzZmYiLz48L3N2Zz4='); }
.tooltip .tooltiptext { visibility:hidden; position:absolute; padding:10px 15px; width:350px; background:var(--background-popup); border:1px solid var(--border); border-radius:10px; z-index: 10000; }
.tooltip:hover .tooltiptext { visibility:visible; }
/* Misc */ /* Misc */
.goosle-g { color:var(--color-accent); } .goosle-g { color:var(--color-accent); }
.green { color:var(--green); } .green { color:var(--green); }
@ -163,6 +194,9 @@ div.title, div.description, div.text, div.url, div.source { word-wrap:break-word
.yellow { color:var(--yellow); } .yellow { color:var(--yellow); }
.star { font-weight:800; } .star { font-weight:800; }
img.help { padding:0 .5rem .5rem 0; float:left; border-radius:20px; } img.help { padding:0 .5rem .5rem 0; float:left; border-radius:20px; }
.text-xxl { font-size:8em; }
.text-xl { font-size:3em; }
.text-center { text-align:center; }
.warning { position:relative; overflow:hidden; margin:20px 0; padding:10px; color:var(--warning); background-color:var(--warning-background); border:1px solid var(--warning); border-radius:10px; } .warning { position:relative; overflow:hidden; margin:20px 0; padding:10px; color:var(--warning); background-color:var(--warning-background); border:1px solid var(--warning); border-radius:10px; }
.error { position:relative; overflow:hidden; margin:20px 0; padding:10px; color:var(--error); background-color:var(--error-background); border:1px solid var(--error); border-radius:10px; } .error { position:relative; overflow:hidden; margin:20px 0; padding:10px; color:var(--error); background-color:var(--error-background); border:1px solid var(--error); border-radius:10px; }
.auth-success { margin-top:15%; text-align:center; color:var(--text-alt); } .auth-success { margin-top:15%; text-align:center; color:var(--text-alt); }
@ -170,10 +204,7 @@ img.help { padding:0 .5rem .5rem 0; float:left; border-radius:20px; }
a.update { color:var(--red); font-weight:600; } a.update { color:var(--red); font-weight:600; }
@media only screen and (max-width:960px) { /* Tablet, landscape iPad, lo-res/smaller laptops */ @media only screen and (max-width:960px) { /* Tablet, landscape iPad, lo-res/smaller laptops */
/* Page structure */
.header form { margin:15px 0 0 0; }
.content { position:relative; margin:15px 48px; } .content { position:relative; margin:15px 48px; }
.footer-left, .footer-right { display:block; text-align:center; }
/* Start page */ /* Start page */
.startpage .content { margin-top:0; } .startpage .content { margin-top:0; }
@ -183,6 +214,7 @@ a.update { color:var(--red); font-weight:600; }
/* Page header (Search results, Help, Box office) */ /* Page header (Search results, Help, Box office) */
.header { margin-left:auto; margin-right:auto; text-align:center; } .header { margin-left:auto; margin-right:auto; text-align:center; }
.header form { margin:15px 0 0 0; }
.header .logo { position:relative; display:block; margin:10px auto; float:none; font-size:1.8rem; } .header .logo { position:relative; display:block; margin:10px auto; float:none; font-size:1.8rem; }
.header .search-field { margin:10px 0 28px 48px; width:400px; } .header .search-field { margin:10px 0 28px 48px; width:400px; }
.header .search-field, .header .button { margin:10px 0 28px 0; } .header .search-field, .header .button { margin:10px 0 28px 0; }
@ -192,26 +224,26 @@ a.update { color:var(--red); font-weight:600; }
/* Magnet highlight info popup */ /* Magnet highlight info popup */
.goosebox-body { margin:25px auto; width:75%; } .goosebox-body { margin:25px auto; width:75%; }
/* Box Office */ /* Footer */
.grid-container { flex-direction:column; } .footer { flex-direction:column; }
.list-grid:first-child, .footer-grid:first-child { margin-right:0; } .footer-left, .footer-right { display:block; text-align:center; }
.list-grid { width:100%; }
.footer-grid, .footer-grid:nth-child(2) { width:100%; text-align:center; } .footer-grid, .footer-grid:nth-child(2) { width:100%; text-align:center; }
} }
@media only screen and (max-width:640px) { /* Portrait tablets, portrait iPad, landscape e-readers, landscape 800x480 or 854x480 phones */ @media only screen and (max-width:640px) { /* Portrait tablets, portrait iPad, landscape e-readers, landscape 800x480 or 854x480 phones */
/* Page structure */
.header form { margin:15px 0 10px 0; }
.content { position:relative; margin:10px 10px; } .content { position:relative; margin:10px 10px; }
/* Page header (Search results, Help, Box office) */ /* Page header (Search results, Help, Box office) */
.header form { margin:15px 0 10px 0; }
.header .search-field, .header .button { margin:0 0 10px 0; width:80%; border-radius:25px; } .header .search-field, .header .button { margin:0 0 10px 0; width:80%; border-radius:25px; }
/* Grids (image and magnet highlights) */ /* Grids (image and magnet highlights) */
@supports (display:grid) { @supports (display:grid) {
.result-grid ul { grid-gap:0.75rem; } .result-grid { grid-template-columns:repeat(auto-fill, minmax(8rem, 1fr)); row-gap:.5rem; column-gap:.5rem; }
} }
.result-grid .result.image .thumb, .result-grid .result.highlight .thumb { width:120px; height: 120px; }
/* Magnet highlight info popup */ /* Magnet highlight info popup */
.goosebox-body { margin:15px auto; width:90%; } .goosebox-body { margin:15px auto; width:90%; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -1,20 +1,4 @@
<?php <?php
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
require ABSPATH.'functions/tools-magnet.php';
require ABSPATH.'functions/tools-update.php';
require ABSPATH.'engines/boxoffice/yts.php';
require ABSPATH.'engines/boxoffice/eztv.php';
require ABSPATH.'engines/boxoffice/thepiratebay.php';
require ABSPATH.'engines/boxoffice/nyaa.php';
// Blue pixel
$blank_thumb = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOUX3LxDAAE4AJiVKIoaQAAAABJRU5ErkJggg==';
$opts = load_opts();
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works. * Goosle - The fast, privacy oriented search tool that just works.
* *
@ -25,6 +9,17 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
* By using this code you agree to indemnify Arnan de Gans from any * By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
require ABSPATH.'functions/tools-magnet.php';
require ABSPATH.'engines/boxoffice/yts.php';
require ABSPATH.'engines/boxoffice/eztv.php';
$opts = load_opts();
$search = load_search();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -37,7 +32,7 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
<meta name="referrer" content="no-referrer"/> <meta name="referrer" content="no-referrer"/>
<meta name="description" content="View the latest magnet links available for download!" /> <meta name="description" content="View the latest magnet links available for download!" />
<meta property="og:site_name" content="Goosle Search Box Office" /> <meta property="og:site_name" content="Goosle Search" />
<meta property="og:title" content="Goosle Search Box Office" /> <meta property="og:title" content="Goosle Search Box Office" />
<meta property="og:description" content="View the latest magnet links available for download!" /> <meta property="og:description" content="View the latest magnet links available for download!" />
<meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/box-office.php" /> <meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/box-office.php" />
@ -55,30 +50,30 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
<body class="boxofficepage"> <body class="boxofficepage">
<?php <?php
if(verify_hash($opts->hash_auth, $opts->hash, $auth)) { if(verify_hash($opts->hash_auth, $opts->hash, $opts->user_auth)) {
?> ?>
<div class="header"> <div class="header">
<form action="results.php" method="get" autocomplete="off"> <form action="results.php" method="get" autocomplete="off">
<h1 class="logo"><a href="./?a=<?php echo $opts->hash; ?>"><span class="goosle-g">G</span>oosle</a></h1> <h1 class="logo"><a href="./?a=<?php echo $opts->user_auth; ?>"><span class="goosle-g">G</span>oosle</a></h1>
<input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($opts->query) > 0) ? htmlspecialchars($opts->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" /> <input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($search->query) > 0) ? htmlspecialchars($search->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" />
<input type="hidden" name="t" value="<?php echo $opts->type; ?>"/> <input type="hidden" name="t" value="<?php echo $search->type; ?>"/>
<input type="hidden" name="a" value="<?php echo $opts->hash; ?>"> <input type="hidden" name="a" value="<?php echo $opts->user_auth; ?>">
</form> </form>
<div class="navigation"> <div class="navigation">
<a class="<?php echo ($opts->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=0">Search</a> <a class="<?php echo ($search->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=0">Search</a>
<?php if($opts->enable_image_search == 'on') { ?> <?php if($opts->enable_image_search == 'on') { ?>
<a class="<?php echo ($opts->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=1" >Images</a> <a class="<?php echo ($search->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=1" >Images</a>
<?php } ?> <?php } ?>
<?php if($opts->enable_news_search == 'on') { ?> <?php if($opts->enable_news_search == 'on') { ?>
<a class="<?php echo ($opts->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=2">News</a> <a class="<?php echo ($search->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=2">News</a>
<?php } ?> <?php } ?>
<?php if($opts->enable_magnet_search == 'on') { ?> <?php if($opts->enable_magnet_search == 'on') { ?>
<a class="<?php echo ($opts->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=9">Magnet links</a> <a class="<?php echo ($search->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=9">Magnet links</a>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
@ -86,156 +81,76 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<div class="content"> <div class="content">
<h2>The Box Office</h2> <h2>The Box Office</h2>
<div class="result-grid"> <p>Click on any movie poster for more information and available download links.</p>
<p>Click on any movie poster for more information and available download links. All other results are direct download links.</p>
<h3>Recently added movies on YTS</h3> <h3>Recently added movies on YTS</h3>
<?php
$highlights = array_slice(yts_boxoffice($opts, 'date_added'), 0, 24);
?>
<ul class="result-grid">
<?php <?php
$highlights = array_slice(yts_boxoffice($opts, 'date_added'), 0, 24); foreach($highlights as $highlight) {
?> $thumb = (!empty($highlight['thumbnail'])) ? $highlight['thumbnail'] : $opts-pixel;
<ul>
<?php
foreach($highlights as $highlight) {
$thumb = (!empty($highlight['thumbnail'])) ? $highlight['thumbnail'] : $blank_thumb;
$search_query = urlencode($highlight['name']." ".$highlight['year']);
echo "<li class=\"result highlight yts id-".$highlight['id']."\">"; echo "<li class=\"result highlight yts id-".$highlight['id']."\">";
echo " <div class=\"result-box\">"; echo " <div class=\"thumb\">";
echo " <a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['name']."\"><img src=\"".$thumb."\" alt=\"".$highlight['name']."\" /></a>"; echo " <a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['title']."\"><img src=\"".$thumb."\" alt=\"".$highlight['title']."\" /></a>";
echo " </div>"; echo " </div>";
echo " <span><center><a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['name']."\">".$highlight['name']."</a></center></span>"; echo " <span><center><a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['title']."\">".$highlight['title']."</a></center></span>";
// HTML for popup // HTML for popup
echo " <div id=\"highlight-".$highlight['id']."\" class=\"goosebox\">"; echo highlight_popup($opts->user_auth, $highlight);
echo " <div class=\"goosebox-body\">";
echo " <h2>".$highlight['name']."</h2>";
echo " <p>".$highlight['summary']."</p>";
echo " <p><a href=\"./results.php?q=".$search_query."&a=".$opts->hash."&t=0\" title=\"Search on Goosle Web Search!\">Search on Goosle</a> &bull; <a href=\"./results.php?q=".$search_query."&a=".$opts->hash."&t=9\" title=\"Search on Goosle Magnet Search! For new additions results may be limited.\">Find more Magnet links</a></p>";
echo " <p><strong>Genre:</strong> ".$highlight['category']."<br /><strong>Released:</strong> ".$highlight['year']."<br /><strong>Rating:</strong> ".movie_star_rating($highlight['rating'])." <small>(".$highlight['rating']." / 10)</small></p>";
// List downloads echo "</li>";
echo " <h3>Downloads:</h3>";
echo " <p>";
foreach($highlight['magnet_links'] as $magnet) {
if(!is_null($magnet['quality'])) $meta[] = $magnet['quality'];
if(!is_null($magnet['type'])) $meta[] = $magnet['type'];
$meta[] = human_filesize($magnet['filesize']);
echo "<button class=\"download\" onclick=\"location.href=".$magnet['magnet']."\">".implode(' / ', $meta)."</button>";
unset($meta);
}
echo " </p>";
echo " <p><a onclick=\"closepopup()\">Close</a></p>";
echo " </div>";
echo " </div>";
echo "</li>";
unset($highlight, $thumb, $search_query, $magnet);
}
unset($highlights);
?>
</ul>
<h3>Latest TV Show releases from EZTV</h3> unset($highlight, $thumb);
<?php }
$highlights = array_slice(eztv_boxoffice($opts), 0, 24); unset($highlights);
?> ?>
<ul> </ul>
<?php
foreach($highlights as $highlight) {
$thumb = (!empty($highlight['thumbnail'])) ? $highlight['thumbnail'] : $blank_thumb;
echo "<li class=\"result highlight eztv id-".$highlight['id']."\">";
echo " <div class=\"result-box\">";
echo " <a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['name']."\"><img src=\"".$thumb."\" alt=\"".$highlight['name']."\" /></a>";
echo " </div>";
echo " <span><center><a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['name']."\">".$highlight['name']."</a></center></span>";
// HTML for popup <h3>Latest TV Show releases from EZTV</h3>
echo " <div id=\"highlight-".$highlight['id']."\" class=\"goosebox\">"; <?php
echo " <div class=\"goosebox-body\">"; $highlights = array_slice(eztv_boxoffice($opts), 0, 24);
echo " <h2>".$highlight['name']."</h2>"; ?>
echo " <p><a href=\"./results.php?q=".urlencode($highlight['name'])."&a=".$opts->hash."&t=0\" title=\"Search on Goosle Web Search!\">Search on Goosle</a> &bull; <a href=\"./results.php?q=".urlencode($highlight['name'])."&a=".$opts->hash."&t=9\" title=\"Search on Goosle Magnet Search! For new additions results may be limited.\">Find more Magnet links</a></p>"; <ul class="result-grid">
<?php
foreach($highlights as $highlight) {
$thumb = (!empty($highlight['thumbnail'])) ? $highlight['thumbnail'] : $opts->pixel;
echo "<li class=\"result highlight eztv id-".$highlight['id']."\">";
echo " <div class=\"thumb\">";
echo " <a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['title']."\"><img src=\"".$thumb."\" alt=\"".$highlight['title']."\" /></a>";
echo " </div>";
echo " <span><center><a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['title']."\">".$highlight['title']."</a></center></span>";
// List downloads // HTML for popup
echo " <h3>Downloads:</h3>"; echo highlight_popup($opts->user_auth, $highlight);
echo " <p>";
foreach($highlight['magnet_links'] as $magnet) {
if(!is_null($magnet['quality'])) $meta[] = $magnet['quality'];
$meta[] = human_filesize($magnet['filesize']);
echo "<button class=\"download\" onclick=\"location.href=".$magnet['magnet']."\">".implode(' / ', $meta)."</button>";
unset($meta);
}
echo " </p>";
echo " <p><a onclick=\"closepopup()\">Close</a></p>"; echo "</li>";
echo " </div>";
echo " </div>"; unset($highlight, $thumb);
}
unset($highlights);
?>
</ul>
echo "</li>"; <p class="text-center"><small>Goosle does not index, offer or distribute torrent files.</small></p>
unset($highlight, $thumb, $magnet);
}
unset($highlights);
?>
</ul>
</div>
<div class="grid-container">
<div class="list-grid piratebay">
<h3>Newest downloads on ThePirateBay</h3>
<ol>
<?php
foreach(piratebay_boxoffice($opts, 10) as $highlight) {
echo "<li class=\"result magnet id-".$highlight['id']."\">";
echo "<div class=\"title\"><a href=\"".$highlight['magnet']."\"><h2>".stripslashes($highlight['name'])."</h2></a></div>";
echo "<div class=\"description\"><strong>Seeds:</strong> <span class=\"green\">".$highlight['seeders']."</span> - <strong>Peers:</strong> <span class=\"red\">".$highlight['leechers']."</span> - <strong>Size:</strong> ".human_filesize($highlight['filesize'])."<br /><strong>Category:</strong> ".$highlight['category']."</div>";
echo "</li>";
unset($highlight);
}
?>
</ol>
</div>
<div class="list-grid nyaa">
<h3>Newest downloads on Nyaa</h3>
<ol>
<?php
foreach(nyaa_boxoffice($opts, 10) as $highlight) {
echo "<li class=\"result magnet id-".$highlight['id']."\">";
echo "<div class=\"title\"><a href=\"".$highlight['magnet']."\"><h2>".stripslashes($highlight['name'])."</h2></a></div>";
echo "<div class=\"description\"><strong>Seeds:</strong> <span class=\"green\">".$highlight['seeders']."</span> - <strong>Peers:</strong> <span class=\"red\">".$highlight['leechers']."</span> - <strong>Size:</strong> ".human_filesize($highlight['filesize'])."<br /><strong>Category:</strong> ".$highlight['category']."</div>";
echo "</li>";
unset($highlight);
}
?>
</ol>
</div>
</div>
<center><small>Goosle does not index, offer or distribute torrent files.</small></center>
</div> </div>
<div class="footer grid-container"> <div class="footer grid-container">
<div class="footer-grid"> <div class="footer-grid">
&copy; <?php echo date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>. &copy; <?php echo the_date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>.
</div> </div>
<div class="footer-grid"> <div class="footer-grid">
<a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->hash; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> <a href="./?a=<?php echo $opts->user_auth; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->user_auth; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->user_auth; ?>">Help</a> - <a href="./stats.php?a=<?php echo $opts->hash; ?>">Stats</a>
</div> </div>
</div> </div>
<?php <?php } else { ?>
} else { <div class="auth-error">Redirecting</div>
echo "<div class=\"auth-error\">Goosle</div>"; <meta http-equiv="refresh" content="1; url=<?php echo get_base_url($opts->siteurl); ?>/error.php" />
} <?php } ?>
?>
</body> </body>
</html> </html>

View file

@ -23,86 +23,87 @@ COLORSCHEME:
'auto' Let the browser decide what to use, uses dark.css for Darkmode. default.css for regular viewing. 'auto' Let the browser decide what to use, uses dark.css for Darkmode. default.css for regular viewing.
For advanced users: You can create your own colorschemes this way too. For advanced users: You can create your own colorschemes this way too.
Name the file something like 'mycolorscheme.css', place it in /assets/css/ and use the keyword 'mycolorscheme' in this setting for it to work. Duplicate the file /assets/css/default.css and name it something like 'mycolorscheme.css'.
Edit the color variables to your liking.
To use the colorscheme, use the filename without extension in this setting.
HASH: HASH:
A simple lowercase passphrase, something simple like: j9fg-i2du-er6m or 1846. A simple lowercase passphrase, something simple like: goose1234 or 1846.
Used for caching results and optionally for accessing Goosle (See HASH_AUTH option). Used for caching search results and optionally for accessing Goosle (See HASH_AUTH option).
HASH_AUTH: HASH_AUTH:
Use the above hash as a simple passphrase. Use the HASH option as a simple passphrase.
Using a passphrase lets you host Goosle on a public facing server without providing a public service. Using a passphrase lets you host Goosle on a public facing server without providing a public service.
This is useful for if just you and some friends or family should be able to use Goosle from anywhere. This is useful for if just you and some friends or family should be able to use Goosle from anywhere.
'off' Don't use the hash as a password. 'off' Don't use the hash as a password.
'on' Use the hash as a password. 'on' Use the hash as a password.
Usage: https://example.com/?a=j9fg-i2du-er6m Usage: https://example.com/?a=goose1234
Disclaimer: This is not meant to 'hack proof' or truly secure the setup. Just a simple token to keep surface level prying eyes out. Disclaimer: This is not meant to 'hack proof' or truly secure the setup. Just a simple token to keep surface level prying eyes out.
CACHE_TYPE: CACHE_TYPE:
It is highly recommended to enable caching as it will speed up repeat searches by a lot. It is highly recommended to enable caching as it will speed up repeat searches by a lot.
The cache is NOT unique per user but shared between all users. Different users searching for the exact same thing get the same results. The cache is NOT unique per user but shared between all users. Different users searching for the exact same thing get the same results.
Results loaded from the cache are much much faster to load.
Caching can be done in memory with APCu or as temporary files in the /cache/ folder. Caching can be done in memory with APCu or as temporary files in the /cache/ folder.
Enabling caching also enables pagination for search results.
'off' No caching. 'off' No caching.
'file' Store results in text files (Default). 'file' Store results in text files (Default).
'apcu' Faster, utilizes memory. 'apcu' Faster, requires more memory.
CACHE_TIME: CACHE_TIME:
APCu stores in memory, using a longer cache time takes up more of it. It is recommended to not exceed a few hours for APCu. APCu stores in memory, using a longer cache time takes up more of it. It is recommended to not exceed a few (1 or 2?) hours for APCu.
The file cache is only limited by your hosting storage space and can safely be much much longer if you want. The file cache is only limited by your hosting storage space and can safely be much much longer if you want.
To not show outdated results the 'limit' is 48 hours. To not show outdated results the 'limit' is 48 hours.
Ignored if above 'CACHE_TYPE' option is set to off. Ignored if above 'CACHE_TYPE' option is set to off.
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
LANGUAGE: LANGUAGE:
To not fit the USA mold, Goosle defaults to the United Kingdom for english results. To not fit the USA mold, Goosle defaults to the United Kingdom for english results.
DuckDuckGo and Google are mostly language agnostic. DuckDuckGo and Google are language agnostic.
Invalid values either cause the search to fail or will default to English depending on how wrong the value is. Invalid values either cause the search engine to fail or will default to English depending on how wrong the value is.
Google has no language setting because as soon as you specify it all 'anonymous' settings stop working. Google has no language setting because as soon as you specify it all 'anonymous' settings stop working.
DuckDuckGo uses language regions and defaults to the United Kingdom. To change it see if your region is available - https://duckduckgo.com/duckduckgo-help-pages/settings/params/. DuckDuckGo uses language regions and defaults to the United Kingdom. To change it see if your region is available - https://duckduckgo.com/duckduckgo-help-pages/settings/params/.
Wikipedia needs to be told which language you want. This changes the search url. Use any of their supported languages (en, es, fr, nl, etc.) Wikipedia needs to be told which language you want. This changes the search url. Use any of their supported languages (en, es, fr, nl, etc.)
Qwant uses a locale similar to DuckDuckGo and defaults to the United Kingdom as well. Qwant uses a locale similar to DuckDuckGo and defaults to the United Kingdom as well.
Available locales are: bg_bg, br_fr, ca_ad, ca_es, ca_fr, co_fr, cs_cz, cy_gb, da_dk, de_at, de_ch, de_de, ec_ca, el_gr, en_au, en_ca, en_gb, en_ie, en_my, en_nz, en_us, es_ad, es_ar, es_cl, es_co, es_es, es_mx, es_pe, et_ee, eu_es, eu_fr, fc_ca, fi_fi, fr_ad, fr_be, fr_ca, fr_ch, fr_fr, gd_gb, he_il, hu_hu, it_ch, it_it, ko_kr, nb_no, nl_be, nl_nl, pl_pl, pt_ad, pt_pt, ro_ro, sv_se, th_th, zh_cn, zh_hk. Available locales are: bg_bg, br_fr, ca_ad, ca_es, ca_fr, co_fr, cs_cz, cy_gb, da_dk, de_at, de_ch, de_de, ec_ca, el_gr, en_au, en_ca, en_gb, en_ie, en_my, en_nz, en_us, es_ad, es_ar, es_cl, es_co, es_es, es_mx, es_pe, et_ee, eu_es, eu_fr, fc_ca, fi_fi, fr_ad, fr_be, fr_ca, fr_ch, fr_fr, gd_gb, he_il, hu_hu, it_ch, it_it, ko_kr, nb_no, nl_be, nl_nl, pl_pl, pt_ad, pt_pt, ro_ro, sv_se, th_th, zh_cn, zh_hk.
SOCIAL MEDIA RELEVANCE: SOCIAL MEDIA RELEVANCE:
Show social media results lower in the combined results if you don't value such results. Show social media results lower in results if you don't value such results.
Downranked results include websites like Facebook, Instagram, Twitter, Snapchat, TikTok, LinkedIn and Reddit. This includes websites like Facebook, Instagram, Twitter/X, Snapchat, TikTok, LinkedIn and Reddit.
!! CAREFUL !! This is a blanket setting, if what (or who) you're searching for primarily has social media links then less relevant results may show first. !! CAREFUL !! This is a blanket setting, if what (or who) you're searching for primarily has social media links then less relevant results may show first.
Accepts a numeric value between 1 and 10. With 10 having *NO* effect on the rank, and 0 not ranking the link at all (shows very very low in the results). Accepts a numeric value between 1 and 10. With 10 having *NO* effect on the rank, and 0 not ranking the link at all (shows very very low in the results).
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
USER AGENTS: USER AGENTS:
Add more or less user agents to the list but keep at least one! Add more or less user agents to the list but keep at least one!
On every search Goosle picks one at random to identify as. On every search Goosle picks a user agent at random to identify as.
Keep them generic to prevent profiling, but also so that the request comes off as a generic boring browser and not as a server/crawler. Keep them generic to prevent profiling, but also so that the request comes off as a generic boring browser and not as a server/crawler.
Safari, Firefox and Internet Explorer (Yes that's old!) should be safe to use. Safari, Firefox and Internet Explorer (Yes that's old!) should be safe to use.
Chrome may attract attention because of the lack of Chrome information (tracking) aside from the user agent. The search engine may know something is 'weird'. Chrome may attract attention because of the lack of Chrome information (tracking) aside from the user agent. The search engine may know something is 'weird'.
Opera/Edge/Brave and many others use Chrome under the hood and are not a good pick for that reason. Opera/Edge/Brave and many others use Chrome under the hood and are not a good pick for that reason.
Mobile user agents may work, but some services like Wikipedia are a bit picky when it comes to answering API calls.
Mobile users generally do not use APIs, so they may block your search or show a trimmed version of results. Do not use user agents for mobile devices. Where possible Goosle explicitly tells the service it's a desktop computer to get a certain format for results.
Contradicting the request with a mobile user agent may get your banned.
MAGNET TRACKERS: MAGNET TRACKERS:
Add more or less magnet trackers to the list but keep at least five or so!
These are added to the magnet links Goosle creates by itself. These are added to the magnet links Goosle creates by itself.
Generally you do not need to change these. Generally you do not need to change these.
Currently only The Pirate Bay, LimeTorrents and YTS use generated magnet links.
You can add more or replace the existing ones if you know what you're doing. But keep at least one, preferably 3-5+.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
return (object) array( return (object) array(
'siteurl' => 'example.com', // Make sure this is accurate 'siteurl' => 'example.com', // Make sure this is accurate (ex. example.com, goosle.example.com, example.com/goosle/)
'colorscheme' => 'default', // Default colorscheme to use 'colorscheme' => 'default', // Default colorscheme to use
'hash' => 'j9fg-i2du-er6m', // Some kind of alphanumeric password-like string, used for caching and optionally for access to Goosle 'hash' => '123456', // Some kind of alphanumeric password-like string, used for caching and optionally for access to Goosle
'hash_auth' => 'off', // Default: off 'hash_auth' => 'off', // Default: off
'cache_type' => 'file', // Default: file 'cache_type' => 'file', // Default: file
'cache_time' => 8, // Default: 8 (Hours) 'cache_time' => 8, // Default: 8 (Hours), see the recommendations above.
'timezone' => 'UTC', // Default: 'UTC (London. Enter UTC+1, UTC-6 etc. for your timezone) 'timezone' => 'UTC', // Default: UTC (Enter UTC+1, UTC-6 etc. for your timezone - Find yours https://time.is/UTC)
'enable_duckduckgo' => 'on', // Default: on 'enable_duckduckgo' => 'on', // Default: on
'enable_google' => 'on', // Default: on 'enable_google' => 'on', // Default: on
@ -110,7 +111,7 @@ return (object) array(
'enable_brave' => 'on', // Default: on 'enable_brave' => 'on', // Default: on
'enable_wikipedia' => 'on', // Default: on 'enable_wikipedia' => 'on', // Default: on
'enable_news_search' => 'on', // Default: on (Disables all news search regardless of settings for individual engines, results are mixed in with regular search) 'enable_news_search' => 'on', // Default: on (Disables all news search regardless of settings for individual engines)
'enable_qwantnews' => 'on', // Default: on 'enable_qwantnews' => 'on', // Default: on
'enable_yahoonews' => 'on', // Default: on 'enable_yahoonews' => 'on', // Default: on
'enable_bravenews' => 'on', // Default: on 'enable_bravenews' => 'on', // Default: on
@ -118,7 +119,7 @@ return (object) array(
'enable_image_search' => 'on', // Default: on (Disables all image search regardless of settings for individual engines) 'enable_image_search' => 'on', // Default: on (Disables all image search regardless of settings for individual engines)
'enable_yahooimages' => 'on', // Default: on 'enable_yahooimages' => 'on', // Default: on
'enable_openverse' => 'off', // Default: off (Requires API token, see readme for details) 'enable_openverse' => 'off', // Default: off (Requires API token, see readme.md for details)
'enable_qwantimages' => 'on', // Default: on 'enable_qwantimages' => 'on', // Default: on
'enable_magnet_search' => 'on', // Default: on (Disables all magnet search regardless of settings for individual engines as well as the box office page) 'enable_magnet_search' => 'on', // Default: on (Disables all magnet search regardless of settings for individual engines as well as the box office page)
@ -133,25 +134,29 @@ return (object) array(
'wikipedia_language' => 'en', // Default: en (English) 'wikipedia_language' => 'en', // Default: en (English)
'qwant_language' => 'en_gb', // Default: en_gb (United Kingdom) 'qwant_language' => 'en_gb', // Default: en_gb (United Kingdom)
'search_results_per_page' => 24, // Default: 24 (Any number between 8 and 160, preferably a multiple of 8. Ignored if caching is off)
'social_media_relevance' => 8, // Default: 8 'social_media_relevance' => 8, // Default: 8
'show_search_source' => 'on', // Default: on 'show_search_source' => 'on', // Default: on
'show_search_rank' => 'off', // Default: off 'show_search_rank' => 'off', // Default: off (Mostly for debugging)
'imdb_id_search' => 'off', // Default: off, Requires Magnet search to also be on 'imdb_id_search' => 'off', // Default: off, (Requires enable_magnet_search to also be on)
'password_generator' => 'on', // Default: on 'password_generator' => 'on', // Default: on
'special' => array( 'special' => array(
'currency' => 'on', // Default: on, Currency converter 'currency' => 'on', // Default: on, Currency converter
'definition' => 'on', // Default: on, Word dictionary 'definition' => 'on', // Default: on, Word dictionary
'ipaddress' => 'on', // Default: on, Look up your IP Address 'ipaddress' => 'on', // Default: on, Look up your IP Address
'phpnet' => 'on', // Default: on, PHP-dot-net highlight 'phpnet' => 'on', // Default: on, PHP-dot-net functions highlight
'wordpress' => 'off' // Default: off, Wordpress functions highlight
), ),
'show_nsfw_magnets' => 'off', // Default: off (Set to 'off' to try and hide adult content. Override with 'safe:off', 'xxx' or 'porn')
'show_zero_seeders' => 'off', // Default: off 'show_zero_seeders' => 'off', // Default: off
'show_yts_highlight' => 'on', // Default: off (Show latest YTS movies above Magnet search results) 'show_yts_highlight' => 'on', // Default: off (Show latest YTS movies above Magnet search results)
'show_share_option' => 'on', // Default: on (Show a share option for Magnet results) 'show_share_option' => 'on', // Default: on (Show a share option for Magnet results)
'piratebay_categories_blocked' => array(206, 210), // Default: 206, 210 (Comma separated numbers, see /engines/magnet/thepiratebay.php for all categories) 'piratebay_categories_blocked' => array(206, 210), // Default: 206, 210 (Comma separated numbers, see /engines/magnet/thepiratebay.php for all categories)
'yts_categories_blocked' => array('horror'), // Default: 'horror' (Comma separated keywords; 'action', 'drama', 'sci-fi' etc.. There is no defined list, so block keywords that you see and don't like) 'yts_categories_blocked' => array('horror'), // Default: 'horror' (Comma separated keywords; array('action', 'drama', 'sci-fi') etc.. There is no defined list, so block keywords that you see on results and don't like)
// Keep at-least 1
'user_agents' => array( 'user_agents' => array(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15) Gecko/20100101 Firefox/119.0', // macOS 10.15, Firefox 119 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15) Gecko/20100101 Firefox/119.0', // macOS 10.15, Firefox 119
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/116.0', // Windows 10, Firefox 116 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/116.0', // Windows 10, Firefox 116
@ -159,7 +164,15 @@ return (object) array(
'Mozilla/5.0 (X11; Linux i686) Gecko/20100101 Firefox/119.0', // Linux Generic, Firefox 119 'Mozilla/5.0 (X11; Linux i686) Gecko/20100101 Firefox/119.0', // Linux Generic, Firefox 119
), ),
// Keep at-least 5
'magnet_trackers' => array( 'magnet_trackers' => array(
'udp://tracker.coppersurfer.tk:6969',
'udp://tracker.leechers-paradise.org:6969',
'udp://p4p.arenabg.ch:1337',
'udp://tracker.internetwarriors.net:1337',
'udp://glotorrents.pw:6969/announce',
'udp://torrent.gresille.org:80/announce',
'udp://tracker.openbittorrent.com:80',
'http://nyaa.tracker.wf:7777/announce', 'http://nyaa.tracker.wf:7777/announce',
'udp://tracker.opentrackr.org:1337/announce', 'udp://tracker.opentrackr.org:1337/announce',
'udp://exodus.desync.com:6969/announce', 'udp://exodus.desync.com:6969/announce',

View file

@ -33,28 +33,30 @@ function eztv_boxoffice($opts) {
if($json_response['torrents_count'] == 0) return $results; if($json_response['torrents_count'] == 0) return $results;
foreach($json_response['torrents'] as $result) { foreach($json_response['torrents'] as $result) {
$name = sanitize($result['title']); $title = (!empty($result['title'])) ? sanitize($result['title']) : null;
$hash = strtolower(sanitize($result['hash'])); $year = (!empty($result['date_released_unix'])) ? gmdate('Y', sanitize($result['date_released_unix'])) : null;
$thumbnail = sanitize($result['small_screenshot']); $hash = (!empty($result['hash'])) ? strtolower(sanitize($result['hash'])) : null;
$magnet_link = sanitize($result['magnet_url']); $thumbnail = (!empty($result['small_screenshot'])) ? sanitize($result['small_screenshot']) : null;
$filesize = sanitize($result['size_bytes']); $magnet_link = (!empty($result['magnet_url'])) ? sanitize($result['magnet_url']) : null;
$filesize = (!empty($result['size_bytes'])) ? sanitize($result['size_bytes']) : null;
// Get extra data // Get extra data
$quality = find_video_quality($name); $quality = find_video_quality($title);
$codec = find_video_codec($name); $codec = find_video_codec($title);
$audio = find_audio_codec($title);
// Add codec to quality // Add codec to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
// Clean up show name // Clean up show name
$name = (preg_match('/.+?(?=[0-9]{3,4}p|xvid|divx|(x|h)26(4|5))/i', $name, $clean_name)) ? $clean_name[0] : $name; // Break off show name before video resolution $title = (preg_match('/.+?(?=[0-9]{3,4}p|xvid|divx|(x|h)26(4|5))/i', $title, $clean_name)) ? $clean_name[0] : $title; // Break off show name before video resolution
$name = trim(str_replace(array('S0E0', 'S00E00'), '', $name)); // Strip spaces and empty season/episode indicator from name $title = trim(str_replace(array('S0E0', 'S00E00'), '', $title)); // Strip spaces and empty season/episode indicator from name
// Group the same episodes in one result // Group the same episodes in one result
if(count($results) > 0) { if(count($results) > 0) {
// Do a match // Do a match
$result_urls = array_column($results, 'name', 'id'); $result_urls = array_column($results, 'title', 'id');
$found_id = array_search($name, $result_urls); // Return the result ID $found_id = array_search($title, $result_urls); // Return the result ID
} else { } else {
$found_id = false; $found_id = false;
} }
@ -65,25 +67,28 @@ function eztv_boxoffice($opts) {
'hash' => $hash, 'hash' => $hash,
'magnet' => $magnet_link, 'magnet' => $magnet_link,
'filesize' => $filesize, 'filesize' => $filesize,
'quality' => $quality 'quality' => $quality,
'audio' => $audio
); );
} else { } else {
$result_id = md5($name); // Predictable/repeatable 'unique' string $result_id = md5($title); // Predictable/repeatable 'unique' string, can't be md5($hash) other nothing will match/merge!
// First/new result // First/new result
$results[$result_id] = array ( $results[$result_id] = array (
'id' => $result_id, // string 'id' => $result_id, // string
'name' => $name, // string 'title' => $title, // string
'year' => $year, // int(4)
'thumbnail' => $thumbnail, // string 'thumbnail' => $thumbnail, // string
'magnet_links' => array(array( // Yes, two array... 'magnet_links' => array(array( // Yes, two array (For merging results)...
'hash' => $hash, // string 'hash' => $hash, // string
'magnet' => $magnet_link, // string 'magnet' => $magnet_link, // string
'filesize' => $filesize, // int 'filesize' => $filesize, // int
'quality' => $quality, // string 'quality' => $quality, // string
'audio' => $audio // string
)) ))
); );
} }
unset($result, $result_urls, $found_id, $result_id, $name, $hash, $thumbnail, $magnet_link, $quality, $codec); unset($result, $result_urls, $found_id, $result_id, $title, $hash, $thumbnail, $magnet_link, $quality, $codec);
} }
unset($response, $json_response); unset($response, $json_response);

View file

@ -1,83 +0,0 @@
<?php
/* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works.
*
* COPYRIGHT NOTICE
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
*
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use.
------------------------------------------------------------------------------------ */
function nyaa_boxoffice($opts, $amount) {
$api_url = 'https://nyaa.si/';
$results = array();
// If there is a cached result use that instead
if($opts->cache_type !== 'off' && has_cached_results($opts->cache_type, $opts->hash, $api_url, $opts->cache_time)) {
return fetch_cached_results($opts->cache_type, $opts->hash, $api_url);
}
$response = do_curl_request(
$api_url, // (string) Where?
array('Accept: text/html, application/xhtml+xml, application/xml;q=0.8, */*;q=0.7', 'User-Agent: '.$opts->user_agents[0].';'), // (array) User agent + Headers
'get', // (string) post/get
null // (assoc array|null) Post body
);
$xpath = get_xpath($response);
$results = array();
// No response
if(!$xpath) return $results;
// Scrape the results
$limit = $amount + 16;
$scrape = $xpath->query("//tbody/tr[position() <= $limit]");
// No results
if(count($scrape) == 0) return $results;
foreach($scrape as $result) {
$meta = $xpath->evaluate(".//td[@class='text-center']", $result);
$name = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result);
if($name->length == 0) continue;
$magnet = $xpath->evaluate(".//a[2]/@href", $meta[0]);
if($magnet->length == 0) $magnet = $xpath->evaluate(".//a/@href", $meta[0]);
if($magnet->length == 0) continue;
$name = sanitize($name[0]->textContent);
$magnet = sanitize($magnet[0]->textContent);
parse_str(parse_url($magnet, PHP_URL_QUERY), $hash_parameters);
$hash = strtolower(str_replace('urn:btih:', '', $hash_parameters['xt']));
$seeders = sanitize($meta[3]->textContent);
$leechers = sanitize($meta[4]->textContent);
$filesize = filesize_to_bytes(str_replace('TiB', 'TB', str_replace('GiB', 'GB', str_replace('MiB', 'MB', str_replace('KiB', 'KB', sanitize($meta[1]->textContent))))));
$category = sanitize($xpath->evaluate(".//td[1]//a/@title", $result)[0]->textContent);
$category = str_replace(' - ', '/', $category);
$results[] = array (
'id' => uniqid(rand(0, 9999)), // Semi random string to separate results on the results page
'name' => $name, // string
'magnet' => $magnet, // string
'seeders' => $seeders, // int
'leechers' => $leechers, // int
'filesize' => $filesize, // int
'category' => $category, // string
);
unset($result, $meta, $name, $magnet, $seeders, $leechers, $filesize, $category);
}
unset($response, $xpath, $scrape, $limit);
$results = array_slice($results, 0, $amount);
// Cache last request if there is something to cache
if($opts->cache_type !== 'off') {
if(count($results) > 0) store_cached_results($opts->cache_type, $opts->hash, $api_url, $results, $opts->cache_time);
}
return $results;
}
?>

View file

@ -1,134 +0,0 @@
<?php
/* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works.
*
* COPYRIGHT NOTICE
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
*
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use.
------------------------------------------------------------------------------------ */
function piratebay_boxoffice($opts, $amount) {
$api_url = 'https://apibay.org/precompiled/data_top100_recent.json';
// If there is a cached result use that instead
if($opts->cache_type !== 'off' && has_cached_results($opts->cache_type, $opts->hash, $api_url, $opts->cache_time)) {
return fetch_cached_results($opts->cache_type, $opts->hash, $api_url);
}
$response = do_curl_request(
$api_url, // (string) Where?
array('Accept: application/json, */*;q=0.7', 'User-Agent: '.$opts->user_agents[0].';'), // (array) User agent + Headers
'get', // (string) post/get
null // (assoc array|null) Post body
);
$json_response = json_decode($response, true);
$results = array();
// No response
if(empty($json_response)) return $results;
// No results
if($json_response[0]['name'] == 'No results returned') return $results;
$categories = array(
100 => 'Audio',
101 => 'Music',
102 => 'Audio Book',
103 => 'Sound Clips',
104 => 'Audio FLAC',
199 => 'Audio Other',
200 => 'Video',
201 => 'Movie',
202 => 'Movie DVDr',
203 => 'Music Video',
204 => 'Movie Clip',
205 => 'TV Show',
206 => 'Handheld',
207 => 'HD Movie',
208 => 'HD TV Show',
209 => '3D Movie',
210 => 'CAM/TS',
211 => 'UHD/4K Movie',
212 => 'UHD/4K TV Show',
299 => 'Video Other',
300 => 'Applications',
301 => 'Apps Windows',
302 => 'Apps Apple',
303 => 'Apps Unix',
304 => 'Apps Handheld',
305 => 'Apps iOS',
306 => 'Apps Android',
399 => 'Apps Other OS',
400 => 'Games',
401 => 'Games PC',
402 => 'Games Apple',
403 => 'Games PSx',
404 => 'Games XBOX360',
405 => 'Games Wii',
406 => 'Games Handheld',
407 => 'Games iOS',
408 => 'Games Android',
499 => 'Games Other OS',
500 => 'Porn',
501 => 'Porn Movie',
502 => 'Porn Movie DVDr',
503 => 'Porn Pictures',
504 => 'Porn Games',
505 => 'Porn HD Movie',
506 => 'Porn Movie Clip',
507 => 'Porn UHD/4K Movie',
599 => 'Porn Other',
600 => 'Other',
601 => 'Other E-Book',
602 => 'Other Comic',
603 => 'Other Pictures',
604 => 'Other Covers',
605 => 'Other Physibles',
699 => 'Other Other'
);
foreach($json_response as $result) {
$name = sanitize($result['name']);
$hash = strtolower(sanitize($result['info_hash']));
$magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($name).'&tr='.implode('&tr=', $opts->magnet_trackers);
$seeders = sanitize($result['seeders']);
$leechers = sanitize($result['leechers']);
$filesize = sanitize($result['size']);
$category = sanitize($result['category']);
// Block these categories
if(in_array($category, $opts->piratebay_categories_blocked)) continue;
// Set actual category
$category = $categories[$category];
$results[] = array(
'id' => uniqid(rand(0, 9999)), // Semi random string to separate results on the results page
'name' => $name, // string
'magnet' => $magnet, // string
'seeders' => $seeders, // int
'leechers' => $leechers, // int
'filesize' => $filesize, // int
'category' => $category // string
);
unset($result, $name, $magnet, $seeders, $leechers, $filesize, $category);
}
unset($response, $json_response, $categories);
$results = array_slice($results, 0, $amount);
// Cache last request if there is something to cache
if($opts->cache_type !== 'off') {
if(count($results) > 0) store_cached_results($opts->cache_type, $opts->hash, $api_url, $results, $opts->cache_time);
}
return $results;
}
?>

View file

@ -33,53 +33,69 @@ function yts_boxoffice($opts, $what) {
if($json_response['data']['movie_count'] == 0) return $results; if($json_response['data']['movie_count'] == 0) return $results;
foreach($json_response['data']['movies'] as $result) { foreach($json_response['data']['movies'] as $result) {
$name = sanitize($result['title']); $title = sanitize($result['title']);
$year = (array_key_exists('year', $result)) ? sanitize($result['year']) : 0; $year = (!empty($result['year'])) ? sanitize($result['year']) : 0;
$category = (array_key_exists('genres', $result)) ? $result['genres'] : array(); $category = (!empty($result['genres'])) ? $result['genres'] : null;
$rating = (array_key_exists('rating', $result)) ? sanitize($result['rating']) : 0; $language = (!empty($result['language'])) ? sanitize($result['language']) : null;
$summary = (array_key_exists('summary', $result)) ? sanitize($result['summary']) : "No summary provided"; $rating = (!empty($result['rating'])) ? sanitize($result['rating']) : null;
$thumbnail = (array_key_exists('medium_cover_image', $result)) ? sanitize($result['medium_cover_image']) : ""; $mpa_rating = (!empty($result['mpa_rating'])) ? sanitize($result['mpa_rating']) : null;
$summary = (!empty($result['summary'])) ? sanitize($result['summary']) : null;
if(is_null($summary)) $summary = (!empty($result['synopsis'])) ? sanitize($result['synopsis']) : "No summary provided";
$thumbnail = (!empty($result['medium_cover_image'])) ? sanitize($result['medium_cover_image']) : null;
if(is_null($thumbnail)) $thumbnail = (!empty($result['small_cover_image'])) ? sanitize($result['small_cover_image']) : "";
// Block these categories // Process extra data
if(count(array_uintersect($category, $opts->yts_categories_blocked, 'strcasecmp')) > 0) continue; if(is_array($category)) {
// Set actual category // Block these categories
$category = sanitize(implode(', ', $category)); if(count(array_uintersect($category, $opts->yts_categories_blocked, 'strcasecmp')) > 0) continue;
// Set actual category
$category = sanitize(implode(', ', $category));
}
foreach($result['torrents'] as $download) { foreach($result['torrents'] as $download) {
$hash = strtolower(sanitize($download['hash'])); $hash = strtolower(sanitize($download['hash']));
$magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($name).'&tr='.implode('&tr=', $opts->magnet_trackers); $magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($title).'&tr='.implode('&tr=', $opts->magnet_trackers);
$filesize = filesize_to_bytes(sanitize($download['size'])); $filesize = filesize_to_bytes(sanitize($download['size']));
$type = (array_key_exists('type', $download)) ? sanitize(strtolower($download['type'])) : null; $type = (!empty($download['type'])) ? sanitize(strtolower($download['type'])) : null;
$quality = (array_key_exists('quality', $download)) ? sanitize($download['quality']) : null; $quality = (!empty($download['quality'])) ? sanitize($download['quality']) : null;
$codec = (array_key_exists('video_codec', $download)) ? sanitize($download['video_codec']) : null; $codec = (!empty($download['video_codec'])) ? sanitize($download['video_codec']) : null;
$bitrate = (!empty($download['bit_depth'])) ? sanitize($download['bit_depth']) : null;
$audio = (!empty($download['audio_channels'])) ? sanitize('AAC '.$download['audio_channels']) : null;
// Add codec to quality // Add codec and bitrate to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
if(!empty($bitrate)) $quality = $quality.' '.$bitrate.'bit';
$downloads[] = array ( $downloads[] = array (
'hash' => $hash, 'hash' => $hash,
'magnet' => $magnet, 'magnet' => $magnet,
'filesize' => $filesize, 'filesize' => $filesize,
'type' => $type, 'type' => $type,
'quality' => $quality 'quality' => $quality,
'audio' => $audio
); );
unset($download, $hash, $magnet, $filesize, $type, $quality, $codec); unset($download, $hash, $magnet, $filesize, $type, $quality, $codec, $bitrate, $audio);
} }
$results[] = array ( $result_id = md5($title);
'id' => uniqid(rand(0, 9999)), // Semi random string to separate results on the results page
'name' => $name, // string $results[$result_id] = array (
'id' => $result_id, // Semi random string to separate results
'title' => $title, // string
'year' => $year, // int(4) 'year' => $year, // int(4)
'category' => $category, // string 'category' => $category, // string|null
'rating' => $rating, // float|int 'language' => $language, // string|null
'rating' => $rating, // float|null
'mpa_rating' => $mpa_rating, // string|null
'summary' => $summary, // string 'summary' => $summary, // string
'thumbnail' => $thumbnail, // string|empty 'thumbnail' => $thumbnail, // string|empty
'magnet_links' => $downloads // array 'magnet_links' => $downloads // array
); );
unset($result, $name, $thumbnail, $year, $category, $rating, $url, $summary, $downloads); unset($result, $title, $thumbnail, $year, $category, $language, $rating, $url, $summary, $downloads);
} }
unset($response, $json_response); unset($response, $json_response);

View file

@ -11,28 +11,21 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class OpenverseRequest extends EngineRequest { class OpenverseRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search override // Safe search override
$safe = '0'; // No mature results if($this->search->safe == 0) {
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) { $safe = '1';
if($matches[2] == 'on') $safe = '0'; } else {
if($matches[2] == 'off') $safe = '1'; $safe = '0';
$query = str_replace($matches[0], '', $query);
} }
unset($matches);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://api.openverse.org/v1/images/?'.http_build_query(array( $url = 'https://api.openverse.org/v1/images/?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
'format' => 'json', // Response format 'format' => 'json', // Response format
'mature' => $safe, // Safe search (1 = ON, 0 = OFF) 'page_size' => 50, // How many results to get
'page_size' => 50 // How many results to get 'mature' => $safe // Safe search (1 = ON, 0 = OFF)
)); ));
unset($query, $safe); unset($safe);
return $url; return $url;
} }
@ -108,10 +101,8 @@ class OpenverseRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Openverse'; $engine_result['source'] = 'Openverse';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,22 +11,13 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class QwantImageRequest extends EngineRequest { class QwantImageRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $query = $this->search->query;
// Safe search override
$safe = '1'; // Moderate results
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) {
if($matches[2] == 'on') $safe = '2';
if($matches[2] == 'off') $safe = '0';
$query = str_replace($matches[0], '', $query);
}
unset($matches);
// Size override // Size override
$size = 'all'; // All sizes $size = 'all'; // All sizes
if(preg_match('/(size:)(small|medium|large|xlarge)/i', $query, $matches)) { if(preg_match('/(size:)(small|medium|large|xlarge)/i', $this->search->query_terms[0], $matches)) {
$size = $matches[1]; $size = $matches[1];
$query = str_replace($matches[0], '', $query); $query = str_replace($this->search->query_terms[0], '', $query);
// Engine specific // Engine specific
if($size == 'xlarge') $size = 'large'; if($size == 'xlarge') $size = 'large';
@ -36,9 +27,7 @@ class QwantImageRequest extends EngineRequest {
// Set locale // Set locale
$language = (strlen($this->opts->qwant_language) > 0 && strlen($this->opts->qwant_language < 6)) ? $this->opts->qwant_language : 'en_gb'; $language = (strlen($this->opts->qwant_language) > 0 && strlen($this->opts->qwant_language < 6)) ? $this->opts->qwant_language : 'en_gb';
// Is there no query left? Bail! // Based on https://github.com/locness3/qwant-api-docs and variables from qwant website
if(empty($query)) return false;
$url = 'https://api.qwant.com/v3/search/images?'.http_build_query(array( $url = 'https://api.qwant.com/v3/search/images?'.http_build_query(array(
'q' => $query, // Search query 'q' => $query, // Search query
't' => 'images', // Type of search, Images 't' => 'images', // Type of search, Images
@ -46,10 +35,10 @@ class QwantImageRequest extends EngineRequest {
'size' => $size, // General image size 'size' => $size, // General image size
'locale' => $language, // In which language should the search be done 'locale' => $language, // In which language should the search be done
'device' => 'desktop', // What kind of device are we searching from? 'device' => 'desktop', // What kind of device are we searching from?
'safesearch' => $safe // Safe search filter (0 = off, 1 = normal, 2 = strict) 'safesearch' => $this->search->safe // Safe search filter (0 = off, 1 = normal, 2 = strict)
)); ));
unset($query, $safe, $size, $language); unset($query, $size, $language);
return $url; return $url;
} }
@ -117,10 +106,8 @@ class QwantImageRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Qwant'; $engine_result['source'] = 'Qwant';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,31 +11,26 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class YahooImageRequest extends EngineRequest { class YahooImageRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $query = $this->search->query;
// Safe search override // Safe search override
$safe = ''; // No mature results if($this->search->safe == 0) {
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) { $safe = '0';
if($matches[2] == 'on') $safe = ''; } else {
if($matches[2] == 'off') $safe = '0'; $safe = '';
$query = str_replace($matches[0], '', $query);
} }
unset($matches);
// Size override // Size override
$size = ''; // All sizes $size = ''; // All sizes
if(preg_match('/(size:)(small|medium|large|xlarge)/i', $query, $matches)) { if(preg_match('/(size:)(small|medium|large|xlarge)/i', $this->search->query_terms[0], $matches)) {
$size = $matches[1]; $size = $matches[1];
$query = str_replace($matches[0], '', $query); $query = str_replace($this->search->query_terms[0], '', $query);
// Engine specific // Engine specific
if($size == 'xlarge') $size = 'wallpaper'; if($size == 'xlarge') $size = 'wallpaper';
} }
unset($matches); unset($matches);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://images.search.yahoo.com/search/images?'.http_build_query(array( $url = 'https://images.search.yahoo.com/search/images?'.http_build_query(array(
'p' => $query, // Search query 'p' => $query, // Search query
'imgsz' => $size, // Image size (small|medium|large|wallpaper) 'imgsz' => $size, // Image size (small|medium|large|wallpaper)
@ -154,10 +149,8 @@ class YahooImageRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Yahoo! Images'; $engine_result['source'] = 'Yahoo! Images';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,10 +11,7 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class EZTVRequest extends EngineRequest { class EZTVRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = preg_replace('/[^0-9]+/', '', $this->query); $query = preg_replace('/[^0-9]+/', '', $this->search->query);
// Is there no query left? Bail!
if(empty($query)) return false;
// Is eztvx.to blocked for you? Use one of these urls as an alternative // Is eztvx.to blocked for you? Use one of these urls as an alternative
// Try: eztv1.xyz, eztv.wf, eztv.tf, eztv.yt // Try: eztv1.xyz, eztv.wf, eztv.tf, eztv.yt
@ -47,7 +44,7 @@ class EZTVRequest extends EngineRequest {
if($json_response['torrents_count'] == 0) return $engine_temp; if($json_response['torrents_count'] == 0) return $engine_temp;
foreach($json_response['torrents'] as $result) { foreach($json_response['torrents'] as $result) {
$name = sanitize($result['title']); $title = sanitize($result['title']);
$hash = strtolower(sanitize($result['hash'])); $hash = strtolower(sanitize($result['hash']));
$magnet = sanitize($result['magnet_url']); $magnet = sanitize($result['magnet_url']);
$seeders = sanitize($result['seeds']); $seeders = sanitize($result['seeds']);
@ -64,48 +61,49 @@ class EZTVRequest extends EngineRequest {
if($episode < 10) $episode = '0'.$episode; if($episode < 10) $episode = '0'.$episode;
// Throw out mismatched episodes // Throw out mismatched episodes
if(!is_season_or_episode($this->query, 'S'.$season.'E'.$episode)) continue; if(!is_season_or_episode($this->search->query, 'S'.$season.'E'.$episode)) continue;
// Get extra data // Get extra data
$date_added = (array_key_exists('date_released_unix', $result)) ? timezone_offset($result['date_released_unix'], $this->opts->timezone) : null; $timestamp = (isset($result['date_released_unix'])) ? sanitize($result['date_released_unix']) : null;
$quality = find_video_quality($name); $quality = find_video_quality($title);
$codec = find_video_codec($name); $codec = find_video_codec($title);
$audio = find_audio_codec($name); $audio = find_audio_codec($title);
// Add codec to quality // Add codec to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
// Clean up show name // Clean up show name
$name = (preg_match('/.+?(?=[0-9]{3,4}p)|xvid|divx|(x|h)26(4|5)/i', $name, $clean_name)) ? $clean_name[0] : $name; // Break off show name before video resolution $title = (preg_match('/.+?(?=[0-9]{3,4}p)|xvid|divx|(x|h)26(4|5)/i', $title, $clean_name)) ? $clean_name[0] : $title; // Break off show name before video resolution
$name = str_replace(array('S0E0', 'S00E00'), '', $name); // Strip empty season/episode indicator from name $title = str_replace(array('S0E0', 'S00E00'), '', $title); // Strip empty season/episode indicator from name
$engine_temp[] = array ( $engine_temp[] = array (
// Required // Required
'hash' => $hash, // string 'hash' => $hash, // string
'name' => $name, // string 'title' => $title, // string
'magnet' => $magnet, // string 'magnet' => $magnet, // string
'seeders' => $seeders, // int 'seeders' => $seeders, // int
'leechers' => $leechers, // int 'leechers' => $leechers, // int
'filesize' => $filesize, // int 'filesize' => $filesize, // int
// Optional // Optional
'nsfw' => false, // bool
'quality' => $quality, // string|null 'quality' => $quality, // string|null
'type' => null, // string|null 'type' => null, // string|null
'audio' => $audio, // string|null 'audio' => $audio, // string|null
'runtime' => null, // int(timestamp)|null 'runtime' => null, // int(timestamp)|null
'year' => null, // int(4)|null 'year' => null, // int(4)|null
'date_added' => $date_added, // int(timestamp)|null 'timestamp' => $timestamp, // int(timestamp)|null
'category' => null, // string|null 'category' => null, // string|null
'mpa_rating' => null, // string|null
'language' => null, // string|null
'url' => null // string|null 'url' => null // string|null
); );
unset($result, $season, $episode, $name, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $date_added); unset($result, $season, $episode, $title, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $date_added);
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'EZTV'; $engine_result['source'] = 'EZTV';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,13 +11,9 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class LimeRequest extends EngineRequest { class LimeRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $query = preg_replace('/[^a-z0-9- ]+/', '', $this->search->query);
$query = preg_replace('/[^a-z0-9- ]+/', '', $query);
$query = strtolower(str_replace(' ', '-', $query)); $query = strtolower(str_replace(' ', '-', $query));
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://www.limetorrents.lol/search/all/'.$query.'/'; $url = 'https://www.limetorrents.lol/search/all/'.$query.'/';
unset($query); unset($query);
@ -46,22 +42,22 @@ class LimeRequest extends EngineRequest {
foreach($scrape as $result) { foreach($scrape as $result) {
// Find data // Find data
$name = $xpath->evaluate(".//td[@class='tdleft']//a[2]", $result); $title = $xpath->evaluate(".//td[@class='tdleft']//a[2]", $result);
$hash = $xpath->evaluate(".//td[@class='tdleft']//a[1]/@href", $result); $hash = $xpath->evaluate(".//td[@class='tdleft']//a[1]/@href", $result);
$seeders = $xpath->evaluate(".//td[@class='tdseed']", $result); $seeders = $xpath->evaluate(".//td[@class='tdseed']", $result);
$leechers = $xpath->evaluate(".//td[@class='tdleech']", $result); $leechers = $xpath->evaluate(".//td[@class='tdleech']", $result);
$filesize = $xpath->evaluate(".//td[@class='tdnormal'][2]", $result); $filesize = $xpath->evaluate(".//td[@class='tdnormal'][2]", $result);
// Skip broken results // Skip broken results
if($name->length == 0) continue; if($title->length == 0) continue;
if($hash->length == 0) continue; if($hash->length == 0) continue;
// Process data // Process data
$name = sanitize($name[0]->textContent); $title = sanitize($title[0]->textContent);
$hash = sanitize($hash[0]->textContent); $hash = sanitize($hash[0]->textContent);
$hash = explode('/', substr($hash, 0, strpos($hash, '.torrent?'))); $hash = explode('/', substr($hash, 0, strpos($hash, '.torrent?')));
$hash = strtolower($hash[array_key_last($hash)]); $hash = strtolower($hash[array_key_last($hash)]);
$magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($name).'&tr='.implode('&tr=', $this->opts->magnet_trackers); $magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($title).'&tr='.implode('&tr=', $this->opts->magnet_trackers);
$seeders = ($seeders->length > 0) ? sanitize($seeders[0]->textContent) : 0; $seeders = ($seeders->length > 0) ? sanitize($seeders[0]->textContent) : 0;
$leechers = ($leechers->length > 0) ? sanitize($leechers[0]->textContent) : 0; $leechers = ($leechers->length > 0) ? sanitize($leechers[0]->textContent) : 0;
$filesize = ($filesize->length > 0) ? human_filesize(filesize_to_bytes(sanitize($filesize[0]->textContent))) : 0; $filesize = ($filesize->length > 0) ? human_filesize(filesize_to_bytes(sanitize($filesize[0]->textContent))) : 0;
@ -70,7 +66,7 @@ class LimeRequest extends EngineRequest {
if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue; if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue;
// Throw out mismatched tv-show episodes when searching for tv shows // Throw out mismatched tv-show episodes when searching for tv shows
if(!is_season_or_episode($this->query, $name)) continue; if(!is_season_or_episode($this->search->query, $title)) continue;
// Find extra data // Find extra data
$category = $xpath->evaluate(".//td[@class='tdnormal'][1]", $result); $category = $xpath->evaluate(".//td[@class='tdnormal'][1]", $result);
@ -86,46 +82,48 @@ class LimeRequest extends EngineRequest {
} }
$url = ($url->length > 0) ? 'https://www.limetorrents.lol'.sanitize($url[0]->textContent) : null; $url = ($url->length > 0) ? 'https://www.limetorrents.lol'.sanitize($url[0]->textContent) : null;
// Find meta data for certain categories
$nsfw = (detect_nsfw($title)) ? true : false;
$quality = $codec = $audio = null; $quality = $codec = $audio = null;
if(in_array(strtolower($category), array('movies', 'tv shows', 'anime'))) { if(in_array(strtolower($category), array('movies', 'tv shows', 'anime'))) {
$quality = find_video_quality($name); $quality = find_video_quality($title);
$codec = find_video_codec($name); $codec = find_video_codec($title);
$audio = find_audio_codec($title);
// Add codec to quality // Add codec to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
} } else if(in_array(strtolower($category), array('music'))) {
$audio = find_audio_codec($title);
if(in_array(strtolower($category), array('music', 'movies', 'tv shows', 'anime'))) {
$audio = find_audio_codec($name);
} }
$engine_temp[] = array ( $engine_temp[] = array (
// Required // Required
'hash' => $hash, // string 'hash' => $hash, // string
'name' => $name, // string 'title' => $title, // string
'magnet' => $magnet, // string 'magnet' => $magnet, // string
'seeders' => $seeders, // int 'seeders' => $seeders, // int
'leechers' => $leechers, // int 'leechers' => $leechers, // int
'filesize' => $filesize, // int 'filesize' => $filesize, // int
// Optional // Optional
'nsfw' => $nsfw, // bool
'quality' => $quality, // string|null 'quality' => $quality, // string|null
'type' => null, // string|null 'type' => null, // string|null
'audio' => $audio, // string|null 'audio' => $audio, // string|null
'runtime' => null, // int(timestamp)|null 'runtime' => null, // int(timestamp)|null
'year' => null, // int(4)|null 'year' => null, // int(4)|null
'date_added' => null, // int(timestamp)|null 'timestamp' => null, // int(timestamp)|null
'category' => $category, // string|null 'category' => $category, // string|null
'mpa_rating' => null, // string|null
'language' => null, // string|null
'url' => $url // string|null 'url' => $url // string|null
); );
unset($result, $name, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url); unset($result, $title, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url);
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'limetorrents.lol'; $engine_result['source'] = 'limetorrents.lol';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,14 +11,7 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class NyaaRequest extends EngineRequest { class NyaaRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $url = 'https://nyaa.si/?q='.urlencode($this->search->query);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://nyaa.si/?q='.urlencode($query);
unset($query);
return $url; return $url;
} }
@ -45,16 +38,16 @@ class NyaaRequest extends EngineRequest {
foreach($scrape as $result) { foreach($scrape as $result) {
// Find data // Find data
$meta = $xpath->evaluate(".//td[@class='text-center']", $result); $meta = $xpath->evaluate(".//td[@class='text-center']", $result);
$name = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result); $title = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result);
$magnet = $xpath->evaluate(".//a[2]/@href", $meta[0]); $magnet = $xpath->evaluate(".//a[2]/@href", $meta[0]);
// Skip broken results // Skip broken results
if($name->length == 0) continue; if($title->length == 0) continue;
if($magnet->length == 0) $magnet = $xpath->evaluate(".//a/@href", $meta[0]); // This matches if no torrent file is provided on the page if($magnet->length == 0) $magnet = $xpath->evaluate(".//a/@href", $meta[0]); // This matches if no torrent file is provided
if($magnet->length == 0) continue; if($magnet->length == 0) continue;
// Process data // Process data
$name = sanitize($name[0]->textContent); $title = sanitize($title[0]->textContent);
$magnet = sanitize($magnet[0]->textContent); $magnet = sanitize($magnet[0]->textContent);
parse_str(parse_url($magnet, PHP_URL_QUERY), $hash_parameters); parse_str(parse_url($magnet, PHP_URL_QUERY), $hash_parameters);
$hash = strtolower(str_replace('urn:btih:', '', $hash_parameters['xt'])); $hash = strtolower(str_replace('urn:btih:', '', $hash_parameters['xt']));
@ -66,58 +59,60 @@ class NyaaRequest extends EngineRequest {
if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue; if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue;
// Throw out mismatched tv-show episodes when searching for tv shows // Throw out mismatched tv-show episodes when searching for tv shows
if(!is_season_or_episode($this->query, $name)) continue; if(!is_season_or_episode($this->search->query, $title)) continue;
// Find extra data // Find extra data
$category = $xpath->evaluate(".//td[1]//a/@title", $result); $category = $xpath->evaluate(".//td[1]//a/@title", $result);
$url = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@href", $result); $url = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@href", $result);
$date_added = $xpath->evaluate(".//td[@class='text-center']/@data-timestamp", $result);
// Process extra data // Process extra data
$category = ($category->length > 0) ? str_replace(' - ', '/', sanitize($category[0]->textContent)) : null; $category = ($category->length > 0) ? str_replace(' - ', '/', sanitize($category[0]->textContent)) : null;
$url = ($url->length > 0) ? 'https://nyaa.si'.sanitize($url[0]->textContent) : null; $url = ($url->length > 0) ? 'https://nyaa.si'.sanitize($url[0]->textContent) : null;
$date_added = explode('-', substr(sanitize($meta[2]->textContent), 0, 10)); $timestamp = sanitize($date_added[0]->textContent);
$date_added = timezone_offset(gmmktime(0, 0, 0, intval($date_added[1]), intval($date_added[2]), intval($date_added[0])), $this->opts->timezone);
// Find meta data for certain categories
$nsfw = (detect_nsfw($title)) ? true : false;
$quality = $codec = $audio = null; $quality = $codec = $audio = null;
if(in_array(strtolower($category), array('anime/anime music video', 'anime/non-english-translated', 'anime/english-translated', 'anime/raw', 'live action/english-translated', 'live action/non-english-translated', 'live action/idol/promotional video', 'live action/raw'))) { if(in_array(strtolower($category), array('anime/anime music video', 'anime/non-english-translated', 'anime/english-translated', 'anime/raw', 'live action/english-translated', 'live action/non-english-translated', 'live action/idol/promotional video', 'live action/raw'))) {
$quality = find_video_quality($name); $quality = find_video_quality($title);
$codec = find_video_codec($name); $codec = find_video_codec($title);
$audio = find_audio_codec($title);
// Add codec to quality // Add codec to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
} } else if(in_array(strtolower($category), array('audio/lossless', 'audio/lossy'))) {
$audio = find_audio_codec($title);
if(in_array(strtolower($category), array('audio/lossless', 'audio/lossy', 'anime/anime music video', 'anime/non-english-translated', 'anime/english-translated', 'anime/raw', 'live action/english-translated', 'live action/non-english-translated', 'live action/idol/promotional video', 'live action/raw'))) {
$audio = find_audio_codec($name);
} }
$engine_temp[] = array ( $engine_temp[] = array (
// Required // Required
'hash' => $hash, // string 'hash' => $hash, // string
'name' => $name, // string 'title' => $title, // string
'magnet' => $magnet, // string 'magnet' => $magnet, // string
'seeders' => $seeders, // int 'seeders' => $seeders, // int
'leechers' => $leechers, // int 'leechers' => $leechers, // int
'filesize' => $filesize, // int 'filesize' => $filesize, // int
// Optional // Optional
'nsfw' => $nsfw, // bool
'quality' => $quality, // string|null 'quality' => $quality, // string|null
'type' => null, // string|null 'type' => null, // string|null
'audio' => $audio, // string|null 'audio' => $audio, // string|null
'runtime' => null, // int(timestamp)|null 'runtime' => null, // int(timestamp)|null
'year' => null, // int(4)|null 'year' => null, // int(4)|null
'date_added' => $date_added, // int(timestamp)|null 'timestamp' => $timestamp, // int(timestamp)|null
'category' => $category, // string|null 'category' => $category, // string|null
'mpa_rating' => null, // string|null
'language' => null, // string|null
'url' => $url // string|null 'url' => $url // string|null
); );
unset($result, $name, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url, $date_added); unset($result, $title, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url, $date_added);
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'nyaa.si'; $engine_result['source'] = 'nyaa.si';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,14 +11,7 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class SukebeiRequest extends EngineRequest { class SukebeiRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $url = 'https://sukebei.nyaa.si/?q='.urlencode($this->search->query);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://sukebei.nyaa.si/?q='.urlencode($query);
unset($query);
return $url; return $url;
} }
@ -45,16 +38,16 @@ class SukebeiRequest extends EngineRequest {
foreach($scrape as $result) { foreach($scrape as $result) {
// Find data // Find data
$meta = $xpath->evaluate(".//td[@class='text-center']", $result); $meta = $xpath->evaluate(".//td[@class='text-center']", $result);
$name = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result); $title = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@title", $result);
$magnet = $xpath->evaluate(".//a[2]/@href", $meta[0]); $magnet = $xpath->evaluate(".//a[2]/@href", $meta[0]);
// Skip broken results // Skip broken results
if($name->length == 0) continue; if($title->length == 0) continue;
if($magnet->length == 0) $magnet = $xpath->evaluate(".//a/@href", $meta[0]); // This matches if no torrent file is provided on the page if($magnet->length == 0) $magnet = $xpath->evaluate(".//a/@href", $meta[0]); // This matches if no torrent file is provided
if($magnet->length == 0) continue; if($magnet->length == 0) continue;
// Process data // Process data
$name = sanitize($name[0]->textContent); $title = sanitize($title[0]->textContent);
$magnet = sanitize($magnet[0]->textContent); $magnet = sanitize($magnet[0]->textContent);
parse_str(parse_url($magnet, PHP_URL_QUERY), $hash_parameters); parse_str(parse_url($magnet, PHP_URL_QUERY), $hash_parameters);
$hash = strtolower(str_replace('urn:btih:', '', $hash_parameters['xt'])); $hash = strtolower(str_replace('urn:btih:', '', $hash_parameters['xt']));
@ -66,23 +59,24 @@ class SukebeiRequest extends EngineRequest {
if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue; if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue;
// Throw out mismatched tv-show episodes when searching for tv shows // Throw out mismatched tv-show episodes when searching for tv shows
if(!is_season_or_episode($this->query, $name)) continue; if(!is_season_or_episode($this->search->query, $title)) continue;
// Find extra data // Find extra data
$category = $xpath->evaluate(".//td[1]//a/@title", $result); $category = $xpath->evaluate(".//td[1]//a/@title", $result);
$url = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@href", $result); $url = $xpath->evaluate(".//td[@colspan='2']//a[not(contains(@class, 'comments'))]/@href", $result);
$date_added = $xpath->evaluate(".//td[@class='text-center']/@data-timestamp", $result);
// Process extra data // Process extra data
$category = ($category->length > 0) ? str_replace(' - ', '/', sanitize($category[0]->textContent)) : null; $category = ($category->length > 0) ? str_replace(' - ', '/', sanitize($category[0]->textContent)) : null;
$url = ($url->length > 0) ? 'https://sukebei.nyaa.si'.sanitize($url[0]->textContent) : null; $url = ($url->length > 0) ? 'https://sukebei.nyaa.si'.sanitize($url[0]->textContent) : null;
$date_added = explode('-', substr(sanitize($meta[2]->textContent), 0, 10)); $timestamp = sanitize($date_added[0]->textContent);
$date_added = timezone_offset(gmmktime(0, 0, 0, intval($date_added[1]), intval($date_added[2]), intval($date_added[0])), $this->opts->timezone);
// Find meta data for certain categories
$quality = $codec = $audio = null; $quality = $codec = $audio = null;
if(in_array(strtolower($category), array('art/anime', 'real life/videos'))) { if(in_array(strtolower($category), array('art/anime', 'real life/videos'))) {
$quality = find_video_quality($name); $quality = find_video_quality($title);
$codec = find_video_codec($name); $codec = find_video_codec($title);
$audio = find_audio_codec($name); $audio = find_audio_codec($title);
// Add codec to quality // Add codec to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
@ -91,30 +85,31 @@ class SukebeiRequest extends EngineRequest {
$engine_temp[] = array ( $engine_temp[] = array (
// Required // Required
'hash' => $hash, // string 'hash' => $hash, // string
'name' => $name, // string 'title' => $title, // string
'magnet' => $magnet, // string 'magnet' => $magnet, // string
'seeders' => $seeders, // int 'seeders' => $seeders, // int
'leechers' => $leechers, // int 'leechers' => $leechers, // int
'filesize' => $filesize, // int 'filesize' => $filesize, // int
// Optional // Optional
'nsfw' => true, // bool
'quality' => $quality, // string|null 'quality' => $quality, // string|null
'type' => null, // string|null 'type' => null, // string|null
'audio' => $audio, // string|null 'audio' => $audio, // string|null
'runtime' => null, // int(timestamp)|null 'runtime' => null, // int(timestamp)|null
'year' => null, // int(4)|null 'year' => null, // int(4)|null
'date_added' => $date_added, // int(timestamp)|null 'timestamp' => $timestamp, // int(timestamp)|null
'category' => $category, // string|null 'category' => $category, // string|null
'mpa_rating' => null, // string|null
'language' => null, // string|null
'url' => $url // string|null 'url' => $url // string|null
); );
unset($result, $name, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url, $date_added); unset($result, $title, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url, $date_added);
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'sukebei.nyaa.si'; $engine_result['source'] = 'sukebei.nyaa.si';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,14 +11,7 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class PirateBayRequest extends EngineRequest { class PirateBayRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $url = 'https://apibay.org/q.php?q='.urlencode($this->search->query);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://apibay.org/q.php?q='.urlencode($query);
unset($query);
return $url; return $url;
} }
@ -108,9 +101,9 @@ class PirateBayRequest extends EngineRequest {
foreach($json_response as $result) { foreach($json_response as $result) {
// Find and process data // Find and process data
$name = sanitize($result['name']); $title = sanitize($result['name']);
$hash = strtolower(sanitize($result['info_hash'])); $hash = strtolower(sanitize($result['info_hash']));
$magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($name).'&tr='.implode('&tr=', $this->opts->magnet_trackers); $magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($title).'&tr='.implode('&tr=', $this->opts->magnet_trackers);
$seeders = sanitize($result['seeders']); $seeders = sanitize($result['seeders']);
$leechers = sanitize($result['leechers']); $leechers = sanitize($result['leechers']);
$filesize = human_filesize(sanitize($result['size'])); $filesize = human_filesize(sanitize($result['size']));
@ -119,30 +112,30 @@ class PirateBayRequest extends EngineRequest {
if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue; if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue;
// Throw out mismatched tv-show episodes when searching for tv shows // Throw out mismatched tv-show episodes when searching for tv shows
if(!is_season_or_episode($this->query, $name)) continue; if(!is_season_or_episode($this->search->query, $title)) continue;
// Find extra data // Find extra data
$category = (array_key_exists('category', $result)) ? sanitize($result['category']) : null; $category = (array_key_exists('category', $result)) ? sanitize($result['category']) : null;
$url = (array_key_exists('id', $result)) ? 'https://thepiratebay.org/description.php?id='.sanitize($result['id']) : null; $url = (array_key_exists('id', $result)) ? 'https://thepiratebay.org/description.php?id='.sanitize($result['id']) : null;
$date_added = (array_key_exists('added', $result)) ? timezone_offset(sanitize($result['added']), $this->opts->timezone) : null; $timestamp = (isset($result['added'])) ? sanitize($result['added']) : null;
// Process extra data // Process extra data
if(!is_null($category)) { if(!is_null($category)) {
// Block these categories // Block these categories
if(in_array($category, $this->opts->piratebay_categories_blocked)) continue; if(in_array($category, $this->opts->piratebay_categories_blocked)) continue;
// Detect technical data // Find meta data for certain categories
$nsfw = ($category >= 500 && $category <= 599) ? true : false;
$quality = $codec = $audio = null; $quality = $codec = $audio = null;
if(($category >= 200 && $category < 300) || ($category >= 500 && $category < 600)) { if(($category >= 200 && $category <= 299) || ($category >= 500 && $category <= 599)) {
$quality = find_video_quality($name); $quality = find_video_quality($title);
$codec = find_video_codec($name); $codec = find_video_codec($title);
$audio = find_audio_codec($title);
// Add codec to quality // Add codec to quality
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
} } else if($category >= 100 && $category <= 199) {
$audio = find_audio_codec($title);
if(($category >= 100 && $category < 200) || ($category >= 200 && $category < 300) || ($category >= 500 && $category < 600)) {
$audio = find_audio_codec($name);
} }
// Set actual category // Set actual category
@ -152,30 +145,31 @@ class PirateBayRequest extends EngineRequest {
$engine_temp[] = array( $engine_temp[] = array(
// Required // Required
'hash' => $hash, // string 'hash' => $hash, // string
'name' => $name, // string 'title' => $title, // string
'magnet' => $magnet, // string 'magnet' => $magnet, // string
'seeders' => $seeders, // int 'seeders' => $seeders, // int
'leechers' => $leechers, // int 'leechers' => $leechers, // int
'filesize' => $filesize, // int 'filesize' => $filesize, // int
// Optional // Optional
'nsfw' => $nsfw, // bool
'quality' => $quality, // string|null 'quality' => $quality, // string|null
'type' => null, // string|null 'type' => null, // string|null
'audio' => $audio, // string|null 'audio' => $audio, // string|null
'runtime' => null, // int(timestamp)|null 'runtime' => null, // int(timestamp)|null
'year' => null, // int(4)|null 'year' => null, // int(4)|null
'date_added' => $date_added, // int(timestamp)|null 'timestamp' => $timestamp, // int(timestamp)|null
'category' => $category, // string|null 'category' => $category, // string|null
'language' => null, // string|null
'mpa_rating' => null, // string|null
'url' => $url // string|null 'url' => $url // string|null
); );
unset($result, $name, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url, $date_added); unset($result, $title, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $audio, $category, $url, $date_added);
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'thepiratebay.org'; $engine_result['source'] = 'thepiratebay.org';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,14 +11,7 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class YTSRequest extends EngineRequest { class YTSRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); $url = 'https://yts.mx/api/v2/list_movies.json?query_term='.urlencode($this->search->query);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://yts.mx/api/v2/list_movies.json?query_term='.urlencode($query);
unset($query);
return $url; return $url;
} }
@ -46,17 +39,19 @@ class YTSRequest extends EngineRequest {
foreach($json_response['data']['movies'] as $result) { foreach($json_response['data']['movies'] as $result) {
// Find and process data // Find and process data
$name = sanitize($result['title']); $title = sanitize($result['title']);
// Find extra data // Find extra data
$year = (array_key_exists('year', $result)) ? sanitize($result['year']) : null; $runtime = (!empty($result['runtime'])) ? date('H:i', mktime(0, sanitize($result['runtime']))) : null;
$category = (array_key_exists('genres', $result)) ? $result['genres'] : null; // Sanitized later $year = (!empty($result['year'])) ? sanitize($result['year']) : 0;
$runtime = (array_key_exists('runtime', $result)) ? date('H:i', mktime(0, sanitize($result['runtime']))) : null; $category = (!empty($result['genres'])) ? $result['genres'] : null;
$url = (array_key_exists('url', $result)) ? sanitize($result['url']) : null; $mpa_rating = (!empty($result['mpa_rating'])) ? sanitize($result['mpa_rating']) : null;
$date_added = (array_key_exists('date_uploaded_unix', $result)) ? timezone_offset(sanitize($result['date_uploaded_unix']), $this->opts->timezone) : null; $timestamp = (!empty($result['date_uploaded_unix'])) ? sanitize($result['date_uploaded_unix']) : null;
$language = (!empty($result['language'])) ? sanitize($result['language']) : null;
$url = (!empty($result['url'])) ? sanitize($result['url']) : null;
// Process extra data // Process extra data
if(!is_null($category)) { if(is_array($category)) {
// Block these categories // Block these categories
if(count(array_uintersect($category, $this->opts->yts_categories_blocked, 'strcasecmp')) > 0) continue; if(count(array_uintersect($category, $this->opts->yts_categories_blocked, 'strcasecmp')) > 0) continue;
@ -67,7 +62,7 @@ class YTSRequest extends EngineRequest {
foreach ($result['torrents'] as $download) { foreach ($result['torrents'] as $download) {
// Find and process data // Find and process data
$hash = strtolower(sanitize($download['hash'])); $hash = strtolower(sanitize($download['hash']));
$magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($name).'&tr='.implode('&tr=', $this->opts->magnet_trackers); $magnet = 'magnet:?xt=urn:btih:'.$hash.'&dn='.urlencode($title).'&tr='.implode('&tr=', $this->opts->magnet_trackers);
$seeders = sanitize($download['seeds']); $seeders = sanitize($download['seeds']);
$leechers = sanitize($download['peers']); $leechers = sanitize($download['peers']);
$filesize = human_filesize(filesize_to_bytes(sanitize($download['size']))); $filesize = human_filesize(filesize_to_bytes(sanitize($download['size'])));
@ -76,42 +71,45 @@ class YTSRequest extends EngineRequest {
if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue; if($this->opts->show_zero_seeders == 'off' AND $seeders == 0) continue;
// Find extra data // Find extra data
$quality = (array_key_exists('quality', $download)) ? sanitize(strtolower($download['quality'])) : null; $quality = (!empty($download['quality'])) ? sanitize(strtolower($download['quality'])) : null;
$codec = (array_key_exists('video_codec', $download)) ? sanitize(strtolower($download['video_codec'])) : null; $codec = (!empty($download['video_codec'])) ? sanitize(strtolower($download['video_codec'])) : null;
$type = (array_key_exists('type', $download)) ? ucfirst(sanitize(strtolower($download['type']))) : null; $bitrate = (!empty($download['bit_depth'])) ? sanitize($download['bit_depth']) : null;
$audio = (array_key_exists('audio_channels', $download)) ? sanitize('AAC '.$download['audio_channels']) : null; $type = (!empty($download['type'])) ? ucfirst(sanitize(strtolower($download['type']))) : null;
$audio = (!empty($download['audio_channels'])) ? sanitize('AAC '.$download['audio_channels']) : null;
// Process extra data // Process extra data
if(!empty($codec)) $quality = $quality.' '.$codec; if(!empty($codec)) $quality = $quality.' '.$codec;
if(!empty($bitrate)) $quality = $quality.' '.$bitrate.'bit';
$engine_temp[] = array ( $engine_temp[] = array (
// Required // Required
'hash' => $hash, // string 'hash' => $hash, // string
'name' => $name, // string 'title' => $title, // string
'magnet' => $magnet, // string 'magnet' => $magnet, // string
'seeders' => $seeders, // int 'seeders' => $seeders, // int
'leechers' => $leechers, // int 'leechers' => $leechers, // int
'filesize' => $filesize, // int 'filesize' => $filesize, // int
// Optional // Optional
'nsfw' => false, // bool
'quality' => $quality, // string|null 'quality' => $quality, // string|null
'type' => $type, // string|null 'type' => $type, // string|null
'audio' => $audio, // string|null 'audio' => $audio, // string|null
'year' => $year, // int(4)|null
'category' => $category, // string|null
'runtime' => $runtime, // int(timestamp)|null 'runtime' => $runtime, // int(timestamp)|null
'url' => $url, // string|null 'year' => $year, // int(4)|null
'date_added' => $date_added // int(timestamp)|null 'timestamp' => $timestamp, // int(timestamp)|null
'category' => $category, // string|null
'mpa_rating' => $mpa_rating, // string|null
'language' => $language, // string|null
'url' => $url // string|null
); );
unset($download, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $type, $audio); unset($download, $hash, $magnet, $seeders, $leechers, $filesize, $quality, $codec, $bitrate, $type, $audio);
} }
unset($result, $name, $year, $category, $runtime, $url, $date_added); unset($result, $title, $year, $category, $language, $runtime, $url, $date_added);
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'yts.mx'; $engine_result['source'] = 'yts.mx';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,48 +11,13 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class BraveNewsRequest extends EngineRequest { class BraveNewsRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
$query_terms = explode(' ', $query);
$query_terms[0] = strtolower($query_terms[0]);
// Safe search ignore (not supported)
if($query_terms[0] == 'safe:on' || $query_terms[0] == 'safe:off') {
$query = trim(str_replace($query_terms[0], '', $query));
}
// Search range
$today = time() - 86400;
if($query_terms[0] == 'now' || $query_terms[0] == 'today' || $query_terms[0] == 'yesterday') {
// Last 24 hours
$this->opts->result_range = $today;
$age = 'pd';
} else if($query_terms[0] == 'week' || ($query_terms[0] == 'this' && $query_terms[1] == 'week') || $query_terms[0] == 'recent') {
// Last 7 days
$this->opts->result_range = $today - (6 * 86400);
$age = 'pw';
} else if($query_terms[0] == 'year' || ($query_terms[0] == 'this' && $query_terms[1] == 'year')) {
// This year
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, 1, 1, gmdate('Y')), $this->opts->timezone);
$age = 'py';
} else {
// This month (default)
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, gmdate('m'), 1, gmdate('Y')), $this->opts->timezone);
$age = 'pm';
}
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://search.brave.com/news?'.http_build_query(array( $url = 'https://search.brave.com/news?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
'offset' => 0, // Start on 'page' 1 of results (0 = 1) 'offset' => 0, // Start on 'page' 1 of results (0 = 1)
'spellcheck' => 0, // No spellcheck on your query 'spellcheck' => 0, // No spellcheck on your query
'source' => 'web', // Where are you searching from? (Web) 'source' => 'web', // Where are you searching from? (Web)
'tf' => $age // How old may the article be? 'tf' => 'pm' // How old may the article be?
)); ));
unset($query, $query_terms, $today, $age);
return $url; return $url;
} }
@ -84,6 +49,7 @@ class BraveNewsRequest extends EngineRequest {
$title = $xpath->evaluate(".//a[contains(@class, 'result-header')]//span[contains(@class, 'snippet-title')]", $result); $title = $xpath->evaluate(".//a[contains(@class, 'result-header')]//span[contains(@class, 'snippet-title')]", $result);
$url = $xpath->evaluate(".//a[contains(@class, 'result-header')]/@href", $result); $url = $xpath->evaluate(".//a[contains(@class, 'result-header')]/@href", $result);
$description = $xpath->evaluate(".//p[contains(@class, 'snippet-description')]", $result); $description = $xpath->evaluate(".//p[contains(@class, 'snippet-description')]", $result);
$image = $xpath->evaluate(".//div[contains(@class, 'image-wrapper')]/img/@src", $result);
$date_added = $xpath->evaluate(".//cite[contains(@class, 'snippet-url')]/span[2]", $result); $date_added = $xpath->evaluate(".//cite[contains(@class, 'snippet-url')]/span[2]", $result);
// Skip broken results // Skip broken results
@ -95,35 +61,30 @@ class BraveNewsRequest extends EngineRequest {
$url = sanitize($url[0]->textContent); $url = sanitize($url[0]->textContent);
// $url = (strpos($url, "/a/redirect?click_url=", 0) !== false) ? "https://search.brave.com".$url : $url; // $url = (strpos($url, "/a/redirect?click_url=", 0) !== false) ? "https://search.brave.com".$url : $url;
$description = ($description->length == 0) ? "No description was provided for this site." : limit_string_length(strip_newlines(sanitize($description[0]->textContent))); $description = ($description->length == 0) ? "No description was provided for this site." : limit_string_length(strip_newlines(sanitize($description[0]->textContent)));
$image = ($image->length == 0) ? null : sanitize($image[0]->textContent);
$source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))); $source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST)));
$date_added = ($date_added->length == 0) ? null : timezone_offset(strtotime(sanitize($date_added[0]->textContent)), $this->opts->timezone); $timestamp = ($date_added->length == 0) ? null : strtotime(sanitize($date_added[0]->textContent));
// filter duplicate urls/results // filter duplicate urls/results
if(!empty($engine_temp)) { if(!empty($engine_temp)) {
if(in_array($url, array_column($engine_temp, 'url'))) continue; if(in_array($url, array_column($engine_temp, 'url'))) continue;
} }
// Ignore results that are too old
if(isset($this->opts->result_range) && !is_null($date_added)) {
if($date_added < $this->opts->result_range) continue;
}
$engine_temp[] = array( $engine_temp[] = array(
'title' => $title, // string 'title' => $title, // string
'url' => $url, // string 'url' => $url, // string
'description' => $description, // string 'description' => $description, // string
'image' => $image, // string|null
'source' => $source, // string 'source' => $source, // string
'date_added' => $date_added, // int (timestamp) 'timestamp' => $timestamp, // int|null
'engine_rank' => $rank // int 'engine_rank' => $rank // int
); );
$rank -= 1; $rank -= 1;
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Brave News'; $engine_result['source'] = 'Brave News';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,50 +11,18 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class HackernewsRequest extends EngineRequest { class HackernewsRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); // Search range (must be in GMT)
$article_date = time() - (30 * 86400);
$query_terms = explode(' ', $query);
$query_terms[0] = strtolower($query_terms[0]);
// Safe search ignore (not supported)
if($query_terms[0] == 'safe:on' || $query_terms[0] == 'safe:off') {
$query = trim(str_replace($query_terms[0], '', $query));
}
// Search range
$today = time() - 86400;
if($query_terms[0] == 'now' || $query_terms[0] == 'today' || $query_terms[0] == 'yesterday') {
// Last 24 hours
$this->opts->result_range = $today;
$age = 'created_at_i>'.$this->opts->result_range.',created_at_i<'.$today; // Yesterday
} else if($query_terms[0] == 'week' || ($query_terms[0] == 'this' && $query_terms[1] == 'week') || $query_terms[0] == 'recent') {
// Last 7 days
$this->opts->result_range = $today - (6 * 86400);
$age = 'created_at_i>'.$this->opts->result_range; // This week
} else if($query_terms[0] == 'year' || ($query_terms[0] == 'this' && $query_terms[1] == 'year')) {
// This year
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, 1, 1, gmdate('Y')), $this->opts->timezone);
$age = 'created_at_i>'.$this->opts->result_range;
} else {
// This month (default)
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, gmdate('m'), 1, gmdate('Y')), $this->opts->timezone);
$age = 'created_at_i>'.$this->opts->result_range;
}
// Is there no query left? Bail!
if(empty($query)) return false;
// More info on https://hn.algolia.com/api // More info on https://hn.algolia.com/api
$url = 'http://hn.algolia.com/api/v1/search_by_date?'.http_build_query(array( $url = 'https://hn.algolia.com/api/v1/search_by_date?'.http_build_query(array(
'query' => $query, // Search query 'query' => $this->search->query, // Search query
'tags' => 'story', // What type of results to show? (story = News stories) 'tags' => 'story', // What type of results to show? (story = News stories)
'hitsPerPage' => 30, // How many results to return? 'hitsPerPage' => 30, // How many results to return?
'restrictSearchableAttributes' => 'title,url', // Only match on URLs 'numericFilters' => 'created_at_i>'.$article_date // How old may the article be?
'attributesToRetrieve' => '_tags,title,url,author,created_at_i', // Data to retrieve
'numericFilters' => $age // How old may the article be?
)); ));
unset($query, $query_terms, $today, $age); unset($article_date);
return $url; return $url;
} }
@ -93,34 +61,28 @@ class HackernewsRequest extends EngineRequest {
$url = sanitize($result['url']); $url = sanitize($result['url']);
$description = (array_key_exists('story_text', $result)) ? limit_string_length(strip_newlines(sanitize($result['story_text']))) : $title; $description = (array_key_exists('story_text', $result)) ? limit_string_length(strip_newlines(sanitize($result['story_text']))) : $title;
$source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))); $source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST)));
$date_added = timezone_offset(sanitize($result['created_at_i']), $this->opts->timezone); $timestamp = sanitize($result['created_at_i']);
// Skip duplicate urls/results // Skip duplicate urls/results
if(!empty($engine_temp)) { if(!empty($engine_temp)) {
if(in_array($url, array_column($engine_temp, 'url'))) continue; if(in_array($url, array_column($engine_temp, 'url'))) continue;
} }
// Ignore results that are too old
if(isset($this->opts->result_range)) {
if($date_added < $this->opts->result_range) continue;
}
$engine_temp[] = array ( $engine_temp[] = array (
'title' => $title, // string 'title' => $title, // string
'url' => $url, // string 'url' => $url, // string
'description' => $description, // string 'description' => $description, // string
'image' => null, // string|null
'source' => $source, // string 'source' => $source, // string
'date_added' => $date_added, // int (timestamp) 'timestamp' => $timestamp, // int|null
'engine_rank' => $rank // int 'engine_rank' => $rank // int
); );
$rank -= 1; $rank -= 1;
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Hackernews'; $engine_result['source'] = 'Hackernews';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,60 +11,23 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class QwantNewsRequest extends EngineRequest { class QwantNewsRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search override
$safe = '1'; // Moderate results
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) {
if($matches[2] == 'on') $safe = '2';
if($matches[2] == 'off') $safe = '0';
$query = trim(str_replace($matches[0], '', $query));
}
unset($matches);
// Set locale // Set locale
$language = (preg_match('/[a-z]{2}_[a-z]{2}/i', $this->opts->qwant_language) && strlen($this->opts->qwant_language) == 5) ? strtolower($this->opts->qwant_language) : 'en_gb'; $language = (preg_match('/[a-z]{2}_[a-z]{2}/i', $this->opts->qwant_language) && strlen($this->opts->qwant_language) == 5) ? strtolower($this->opts->qwant_language) : 'en_gb';
$query_terms = explode(' ', $query);
$query_terms[0] = strtolower($query_terms[0]);
// Search range
$today = time() - 86400;
if($query_terms[0] == 'now' || $query_terms[0] == 'today' || $query_terms[0] == 'yesterday') {
// Last 24 hours
$this->opts->result_range = $today;
$age = 'day';
} else if($query_terms[0] == 'week' || ($query_terms[0] == 'this' && $query_terms[1] == 'week') || $query_terms[0] == 'recent') {
// Last 7 days
$this->opts->result_range = $today - (6 * 86400);
$age = 'week';
} else if($query_terms[0] == 'year' || ($query_terms[0] == 'this' && $query_terms[1] == 'year')) {
// This year
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, 1, 1, gmdate('Y')), $this->opts->timezone);
$age = 'all';
} else {
// This month
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, gmdate('m'), 1, gmdate('Y')), $this->opts->timezone);
$age = 'month';
}
// Is there no query left? Bail!
if(empty($query)) return false;
// Based on https://github.com/locness3/qwant-api-docs and variables from qwant website // Based on https://github.com/locness3/qwant-api-docs and variables from qwant website
$url = 'https://api.qwant.com/v3/search/news?'.http_build_query(array( $url = 'https://api.qwant.com/v3/search/news?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
't' => 'news', // News search 't' => 'news', // News search
'safesearch' => $safe, // Safe search filter (0 = off, 1 = normal, 2 = strict) 'safesearch' => $this->search->safe, // Safe search filter (0 = off, 1 = normal, 2 = strict)
'locale' => $language, // Language region 'locale' => $language, // Language region
'count' => 30, // How many results? (Maximum 50) 'count' => 30, // How many results? (Maximum 50)
'device' => 'desktop', // Where are you searching from 'device' => 'desktop', // Where are you searching from
'source' => 'all', // Where to get the news from (All) 'source' => 'all', // Where to get the news from (All)
'freshness' => $age, // How old may the article be? 'freshness' => 'month', // How old may the article be?
'order' => 'date' // Sort by date 'order' => 'date' // Sort by date
)); ));
unset($query, $query_terms, $safe, $language, $age); unset($language);
return $url; return $url;
} }
@ -98,30 +61,28 @@ class QwantNewsRequest extends EngineRequest {
$title = sanitize($result['title']); $title = sanitize($result['title']);
$url = strip_newlines(sanitize($result['url'])); $url = strip_newlines(sanitize($result['url']));
$description = limit_string_length(strip_newlines(sanitize($result['desc']))); $description = limit_string_length(strip_newlines(sanitize($result['desc'])));
$image = sanitize($result['media'][0]['pict']['url']);
$source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))); $source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST)));
$date_added = timezone_offset(sanitize($result['date']), $this->opts->timezone); $timestamp = sanitize($result['date']);
// Ignore results that are too old // Fix up the image
if(isset($this->opts->result_range)) { if($image == 'NULL') $image = null;
if($date_added < $this->opts->result_range) continue;
}
$engine_temp[] = array( $engine_temp[] = array(
'title' => $title, // string 'title' => $title, // string
'url' => $url, // sting 'url' => $url, // string
'description' => $description, // string 'description' => $description, // string
'image' => $image, // string|null
'source' => $source, // string 'source' => $source, // string
'date_added' => $date_added, // int (timestamp) 'timestamp' => $timestamp, // int|null
'engine_rank' => $rank // int 'engine_rank' => $rank // int
); );
$rank -= 1; $rank -= 1;
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Qwant News'; $engine_result['source'] = 'Qwant News';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,45 +11,19 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class YahooNewsRequest extends EngineRequest { class YahooNewsRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search override // Safe search override
$safe = ''; // No mature results if($this->search->safe == 0) {
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) { $safe = '0';
if($matches[2] == 'on') $safe = '';
if($matches[2] == 'off') $safe = '0';
$query = str_replace($matches[0], '', $query);
}
unset($matches);
$query_terms = explode(' ', $query);
$query_terms[0] = strtolower($query_terms[0]);
// Search range
$today = time() - 86400;
if($query_terms[0] == 'now' || $query_terms[0] == 'today' || $query_terms[0] == 'yesterday') {
// Last 24 hours
$this->opts->result_range = $today;
} else if($query_terms[0] == 'week' || ($query_terms[0] == 'this' && $query_terms[1] == 'week') || $query_terms[0] == 'recent') {
// Last 7 days
$this->opts->result_range = $today - (6 * 86400);
} else if($query_terms[0] == 'year' || ($query_terms[0] == 'this' && $query_terms[1] == 'year')) {
// This year
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, 1, 1, gmdate('Y')), $this->opts->timezone);
} else { } else {
// This month $safe = '';
$this->opts->result_range = timezone_offset(gmmktime(0, 0, 0, gmdate('m'), 1, gmdate('Y')), $this->opts->timezone);
} }
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://news.search.yahoo.com/search?'.http_build_query(array( $url = 'https://news.search.yahoo.com/search?'.http_build_query(array(
'p' => $query, // Search query 'p' => $this->search->query, // Search query
'safe' => $safe // Safe search filter (0 = off, "" = on) 'safe' => $safe // Safe search filter (0 = off, "" = on)
)); ));
unset($query, $query_terms, $safe, $today); unset($safe);
return $url; return $url;
} }
@ -81,6 +55,7 @@ class YahooNewsRequest extends EngineRequest {
$title = $xpath->evaluate("./div/ul/li/a[contains(@class, 'thmb')]/@title", $result); $title = $xpath->evaluate("./div/ul/li/a[contains(@class, 'thmb')]/@title", $result);
$url = $xpath->evaluate("./div/ul/li/h4[contains(@class, 's-title')]/a/@href", $result); $url = $xpath->evaluate("./div/ul/li/h4[contains(@class, 's-title')]/a/@href", $result);
$description = $xpath->evaluate("./div/ul/li/p[contains(@class, 's-desc')]", $result); $description = $xpath->evaluate("./div/ul/li/p[contains(@class, 's-desc')]", $result);
$image = $xpath->evaluate("./div/ul/li/a/img[@class='s-img']/@src", $result);
$date_added = $xpath->evaluate("./div/ul/li/span[contains(@class, 's-time')]", $result); $date_added = $xpath->evaluate("./div/ul/li/span[contains(@class, 's-time')]", $result);
// Skip broken results // Skip broken results
@ -93,35 +68,37 @@ class YahooNewsRequest extends EngineRequest {
$url = (preg_match('/\??&?(utm_).+?(&|$)$/i', $url, $found_url)) ? urldecode($found_url[1]) : $url; $url = (preg_match('/\??&?(utm_).+?(&|$)$/i', $url, $found_url)) ? urldecode($found_url[1]) : $url;
$url = sanitize(str_replace('?fr=sycsrp_catchall', '', $url)); $url = sanitize(str_replace('?fr=sycsrp_catchall', '', $url));
$description = ($description->length == 0) ? "No description was provided for this site." : limit_string_length(strip_newlines(sanitize($description[0]->textContent))); $description = ($description->length == 0) ? "No description was provided for this site." : limit_string_length(strip_newlines(sanitize($description[0]->textContent)));
$image = ($image->length == 0) ? null : sanitize($image[0]->textContent);
$source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))); $source = str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST)));
$date_added = ($date_added->length == 0) ? null : timezone_offset(strtotime(sanitize(preg_replace('/[^a-z0-9 ]+/i', '', $date_added[0]->textContent))), $this->opts->timezone); $timestamp = ($date_added->length == 0) ? null : strtotime(sanitize(preg_replace('/[^a-z0-9 ]+/i', '', $date_added[0]->textContent)));
// filter duplicate urls/results // filter duplicate urls/results
if(!empty($engine_temp)) { if(!empty($engine_temp)) {
if(in_array($url, array_column($engine_temp, 'url'))) continue; if(in_array($url, array_column($engine_temp, 'url'))) continue;
} }
// Ignore results that are too old // Fix up the image
if(isset($this->opts->result_range) && !is_null($date_added)) { if(!is_null($image)) {
if($date_added < $this->opts->result_range) continue; $image = explode('/http', $image);
$image = parse_url('http'.$image[1]);
$image = $image['scheme'].'://'.$image['host'].$image['path'];
} }
$engine_temp[] = array( $engine_temp[] = array(
'title' => $title, // string 'title' => $title, // string
'url' => $url, // string 'url' => $url, // string
'description' => $description, // string 'description' => $description, // string
'image' => $image, // string|null
'source' => $source, // string 'source' => $source, // string
'date_added' => $date_added, // int (timestamp) 'timestamp' => $timestamp, // int|null
'engine_rank' => $rank // int 'engine_rank' => $rank // int
); );
$rank -= 1; $rank -= 1;
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Yahoo News'; $engine_result['source'] = 'Yahoo News';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -12,27 +12,29 @@
class ImageSearch extends EngineRequest { class ImageSearch extends EngineRequest {
protected $requests; protected $requests;
public function __construct($opts, $mh) { public function __construct($search, $opts, $mh) {
$this->requests = array(); $this->requests = array();
if($opts->enable_yahooimages == 'on') { if($opts->enable_image_search == 'on') {
require ABSPATH.'engines/image/yahoo-images.php'; if($opts->enable_yahooimages == 'on') {
$this->requests[] = new YahooImageRequest($opts, $mh); require ABSPATH.'engines/image/yahoo-images.php';
} $this->requests[] = new YahooImageRequest($search, $opts, $mh);
}
if($opts->enable_openverse == 'on') {
require ABSPATH.'engines/image/openverse.php'; if($opts->enable_openverse == 'on') {
$this->requests[] = new OpenverseRequest($opts, $mh); require ABSPATH.'engines/image/openverse.php';
} $this->requests[] = new OpenverseRequest($search, $opts, $mh);
}
if($opts->enable_qwantimages == 'on') {
require ABSPATH.'engines/image/qwant-images.php'; if($opts->enable_qwantimages == 'on') {
$this->requests[] = new QwantImageRequest($opts, $mh); require ABSPATH.'engines/image/qwant-images.php';
$this->requests[] = new QwantImageRequest($search, $opts, $mh);
}
} }
} }
public function parse_results($response) { public function parse_results($response) {
$results = array(); $goosle_results = array();
if(count($this->requests) !== 0) { if(count($this->requests) !== 0) {
foreach($this->requests as $request) { foreach($this->requests as $request) {
@ -40,47 +42,54 @@ class ImageSearch extends EngineRequest {
$engine_result = $request->get_results(); $engine_result = $request->get_results();
if(!empty($engine_result)) { if(!empty($engine_result)) {
if(array_key_exists('did_you_mean', $engine_result)) { if(isset($engine_result['did_you_mean'])) {
$results['did_you_mean'] = $engine_result['did_you_mean']; $goosle_results['did_you_mean'] = $engine_result['did_you_mean'];
} }
if(array_key_exists('search_specific', $engine_result)) { if(isset($engine_result['search_specific'])) {
$results['search_specific'][] = $engine_result['search_specific']; $goosle_results['search_specific'][] = $engine_result['search_specific'];
} }
if(array_key_exists('search', $engine_result)) { if(isset($engine_result['search'])) {
// Count results per source $how_many_results = 0;
$results['sources'][$engine_result['source']] = $engine_result['amount'];
// Merge duplicates and apply relevance scoring // Merge duplicates and apply relevance scoring
foreach($engine_result['search'] as $result) { foreach($engine_result['search'] as $result) {
if(array_key_exists('search', $results)) { if(isset($goosle_results['search'])) {
$result_urls = array_column($results['search'], 'image_full', 'id'); $result_urls = array_column($goosle_results['search'], 'image_full', 'id');
$found_id = array_search($result['image_full'], $result_urls); // Return the result ID, or false if not found $found_id = array_search($result['image_full'], $result_urls); // Return the result ID, or false if not found
} else { } else {
$found_id = false; $found_id = false;
} }
$how_many_results++;
$social_media_multiplier = (is_social_media($result['url'])) ? ($request->opts->social_media_relevance / 10) : 1;
$goosle_rank = floor($result['engine_rank'] * floatval($social_media_multiplier));
if($found_id !== false) { if($found_id !== false) {
// Duplicate result from another engine // Duplicate result from another engine
$results['search'][$found_id]['goosle_rank'] += $result['engine_rank']; $goosle_results['search'][$found_id]['goosle_rank'] += $result['engine_rank'];
$results['search'][$found_id]['combo_source'][] = $engine_result['source']; $goosle_results['search'][$found_id]['combo_source'][] = $engine_result['source'];
} else { } else {
// First find, rank and add to results // First find, rank and add to results
// Replace anything but alphanumeric with a space $match_rank = match_count($result['url'], $request->search->query_terms);
$query_terms = explode(' ', preg_replace('/\s{2,}|[^a-z0-9]+/', ' ', strtolower($request->query))); $match_rank += match_count($result['alt'], $request->search->query_terms);
$match_rank = match_count($result['url'], $query_terms);
$match_rank += match_count($result['alt'], $query_terms);
$result['goosle_rank'] = $result['engine_rank'] + $match_rank; $result['goosle_rank'] = $goosle_rank + $match_rank;
$result['combo_source'][] = $engine_result['source']; $result['combo_source'][] = $engine_result['source'];
$result['id'] = md5($result['image_full']); $result['id'] = md5($result['image_full']);
$results['search'][$result['id']] = $result; // Add result to final results
$goosle_results['search'][$result['id']] = $result;
} }
unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank, $query_terms); unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank, $query_terms);
} }
// Count results per source
$goosle_results['sources'][$engine_result['source']] = $how_many_results;
unset($how_many_results);
} }
} }
} else { } else {
@ -88,95 +97,117 @@ class ImageSearch extends EngineRequest {
$http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : ''; $http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : '';
$github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request)." failed with error ".$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error')); $github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request)." failed with error ".$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error'));
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>." 'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>."
); );
} }
unset($request); unset($request);
} }
if(array_key_exists('search', $goosle_results)) {
// Re-order results based on rank
$keys = array_column($goosle_results['search'], 'goosle_rank');
array_multisort($keys, SORT_DESC, $goosle_results['search']);
// Count all results
$goosle_results['number_of_results'] = count($goosle_results['search']);
unset($keys);
} else {
// Add error if there are no search results
$goosle_results['error'][] = array(
"message" => "No results found. Please try with more specific or different keywords!"
);
}
} else { } else {
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Configuration issue!</strong> It appears that all Image Search engines are disabled. Please enable at least one in your config.php file.<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>." 'message' => "It appears that all Image Search engines are disabled or that searching for images is disabled."
); );
} }
if(array_key_exists('search', $results)) { return $goosle_results;
// Re-order results based on rank
$keys = array_column($results['search'], 'goosle_rank');
array_multisort($keys, SORT_DESC, $results['search']);
unset($keys);
} else {
// Add error if there are no search results
$results['error'][] = array(
"message" => "No results found. Please try with more specific or different keywords!"
);
}
return $results;
} }
public static function print_results($results, $opts) { public static function print_results($goosle_results, $search, $opts) {
/* /*
// Uncomment for debugging // Uncomment for debugging
echo '<pre>Settings: '; echo '<pre>Settings: ';
print_r($opts); print_r($opts);
echo '</pre>'; echo '</pre>';
echo "<pre>Search data: ";
print_r($search);
echo "</pre>";
echo '<pre>Search results: '; echo '<pre>Search results: ';
print_r($results); print_r($goosle_results);
echo '</pre>'; echo '</pre>';
*/ */
if(array_key_exists('search', $results)) { if(array_key_exists('search', $goosle_results)) {
// Pagination offset
if($opts->cache_type !== 'off') {
$offset = ((($search->page - 1) * $opts->search_results_per_page) + 1);
$goosle_results['search'] = array_slice($goosle_results['search'], $offset, $opts->search_results_per_page);
}
echo "<ul>"; echo "<ul>";
// Elapsed time // Elapsed time and search sources
$number_of_results = count($results['search']); echo "<li class=\"meta\">";
echo "<li class=\"timer\">Fetched ".$number_of_results." results in ".$results['time']." seconds.</li>"; echo " <p class=\"timer\">Fetched ".$goosle_results['number_of_results']." results in ".$goosle_results['time']." seconds.</p>";
if($opts->show_search_source == 'on') {
echo " <p class=\"sources\">".search_sources($goosle_results['sources'])."</p>";
}
echo "</li>";
// Format sources // Search suggestions
echo "<li class=\"sources\">".search_sources($results['sources'])."</li>"; if(array_key_exists('did_you_mean', $goosle_results)) {
echo "<li class=\"meta\">";
// Did you mean/Search suggestion echo " <p class=\"didyoumean\">Did you mean <a href=\"./results.php?q=".urlencode($goosle_results['did_you_mean'])."&t=".$search->type."&a=".$opts->hash."\">".$goosle_results['did_you_mean']."</a>?</p>";
if(array_key_exists("did_you_mean", $results)) { if(array_key_exists('search_specific', $goosle_results)) {
echo "<li class=\"suggestion\">Did you mean <a href=\"./results.php?q=".urlencode($results['did_you_mean'])."&t=".$opts->type."&a=".$opts->hash."\">".$results['did_you_mean']."</a>?".search_suggestion($opts, $results)."</li>"; echo " <p class=\"suggestion\">".search_suggestion($search, $opts, $goosle_results)."</p>";
}
echo "</li>";
} }
echo "</ul>"; echo "</ul>";
// Search results // Search results
echo "<div class=\"result-grid\">"; echo "<ul class=\"result-grid\">";
echo "<ul>";
foreach($results['search'] as $result) { foreach($goosle_results['search'] as $result) {
// Extra data // Extra data
$meta = $links = array(); $meta = array();
if(!empty($result['height']) && !is_null($result['width'])) $meta[] = $result['width']."&times;".$result['height']; if(!empty($result['height']) && !is_null($result['width'])) $meta[] = $result['width']."&times;".$result['height'];
if(!empty($result['filesize'])) $meta[] = human_filesize($result['filesize']); if(!empty($result['filesize'])) $meta[] = human_filesize($result['filesize']);
// Put result together // Put result together
echo "<li class=\"result image rank-".$result['goosle_rank']." id-".$result['id']."\">"; echo "<li class=\"result image rank-".$result['goosle_rank']." id-".$result['id']."\">";
echo " <div class=\"result-box\">"; echo " <div class=\"thumb\">";
echo " <a href=\"".$result['url']."\" target=\"_blank\" title=\"".$result['alt']."\"><img src=\"".$result['image_thumb']."\" alt=\"".$result['alt']."\" /></a>"; echo " <a href=\"".$result['url']."\" target=\"_blank\" title=\"".$result['alt']."\"><img src=\"".$result['image_thumb']."\" alt=\"".$result['alt']."\" /></a>";
echo " </div>"; echo " </div>";
echo " <div class=\"meta\">".implode(" - ", $meta)."<br /><a href=\"".$result['url']."\" target=\"_blank\">Website</a> - <a href=\"".$result['image_full']."\" target=\"_blank\">Image</a></div>"; echo " <div class=\"meta\"><p>".implode(" &bull; ", $meta)."</p><p><a href=\"".$result['url']."\" target=\"_blank\" title=\"Open website\">Website</a> &bull; <a href=\"".$result['image_full']."\" target=\"_blank\" title=\"Open image\">Image</a></p></div>";
echo "</li>"; echo "</li>";
} }
echo "</ul>"; echo "</ul>";
echo "</div>";
echo "<center><small>Goosle does not store or distribute image files.</small></center>"; // Pagination navigation
if($opts->cache_type !== 'off' && $goosle_results['number_of_results'] > $opts->search_results_per_page) {
echo "<p class=\"pagination\">".search_pagination($search, $opts, $goosle_results['number_of_results'])."</p>";
}
echo "<p class=\"text-center\"><small>Goosle does not store or distribute image files.</small></p>";
} }
// No results found // No results found
if(array_key_exists("error", $results)) { if(array_key_exists("error", $goosle_results)) {
foreach($results['error'] as $error) { foreach($goosle_results['error'] as $error) {
echo "<div class=\"error\">".$error['message']."</div>"; echo "<div class=\"error\">".$error['message']."</div>";
} }
} }
unset($results); unset($goosle_results);
} }
} }
?> ?>

View file

@ -10,86 +10,96 @@
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class MagnetSearch extends EngineRequest { class MagnetSearch extends EngineRequest {
protected $requests, $boxoffice; protected $requests;
public function __construct($opts, $mh) { public function __construct($search, $opts, $mh) {
$this->requests = array(); $this->requests = array();
// Extra functions to process magnet results if($opts->enable_magnet_search == 'on') {
require ABSPATH.'functions/tools-magnet.php'; // Extra functions to process magnet results
require ABSPATH.'functions/tools-magnet.php';
if($opts->enable_limetorrents == 'on') {
require ABSPATH.'engines/magnet/lime.php'; if($opts->enable_limetorrents == 'on') {
$this->requests[] = new LimeRequest($opts, $mh); require ABSPATH.'engines/magnet/lime.php';
} $this->requests[] = new LimeRequest($search, $opts, $mh);
}
if($opts->enable_piratebay == 'on') {
require ABSPATH.'engines/magnet/thepiratebay.php'; if($opts->enable_piratebay == 'on') {
$this->requests[] = new PirateBayRequest($opts, $mh); require ABSPATH.'engines/magnet/thepiratebay.php';
} $this->requests[] = new PirateBayRequest($search, $opts, $mh);
}
if($opts->enable_yts == 'on') {
require ABSPATH.'engines/magnet/yts.php'; if($opts->enable_yts == 'on') {
$this->requests[] = new YTSRequest($opts, $mh); if($search->safe !== 0) {
} require ABSPATH.'engines/magnet/yts.php';
$this->requests[] = new YTSRequest($search, $opts, $mh);
if($opts->enable_nyaa == 'on') { }
require ABSPATH.'engines/magnet/nyaa.php'; }
$this->requests[] = new NyaaRequest($opts, $mh);
} if($opts->enable_nyaa == 'on') {
require ABSPATH.'engines/magnet/nyaa.php';
if($opts->enable_sukebei == 'on') { $this->requests[] = new NyaaRequest($search, $opts, $mh);
require ABSPATH.'engines/magnet/sukebei.php'; }
$this->requests[] = new SukebeiRequest($opts, $mh);
} if($opts->enable_sukebei == 'on') {
if($opts->show_nsfw_magnets == 'on' || ($opts->show_nsfw_magnets == 'off' && $search->safe === 0)) {
if($opts->enable_eztv == 'on') { require ABSPATH.'engines/magnet/sukebei.php';
if(substr(strtolower($opts->query), 0, 2) == 'tt') { $this->requests[] = new SukebeiRequest($search, $opts, $mh);
require ABSPATH.'engines/magnet/eztv.php'; }
$this->requests[] = new EZTVRequest($opts, $mh); }
if($opts->enable_eztv == 'on') {
if(substr(strtolower($search->query), 0, 2) == 'tt') {
require ABSPATH.'engines/magnet/eztv.php';
$this->requests[] = new EZTVRequest($search, $opts, $mh);
}
} }
} }
} }
public function parse_results($response) { public function parse_results($response) {
$results = array(); $goosle_results = array();
if(count($this->requests) !== 0) { if(count($this->requests) !== 0) {
foreach($this->requests as $request) { foreach($this->requests as $request) {
if($request->request_successful()) { if($request->request_successful()) {
$engine_result = $request->get_results(); $engine_result = $request->get_results();
if(!empty($engine_result)) { if(!empty($engine_result)) {
if(array_key_exists('search', $engine_result)) { if(isset($engine_result['search'])) {
// Count results per source $how_many_results = 0;
$results['sources'][$engine_result['source']] = $engine_result['amount'];
// Merge duplicates and apply relevance scoring // Merge duplicates and apply relevance scoring
foreach($engine_result['search'] as $result) { foreach($engine_result['search'] as $result) {
if(array_key_exists('search', $results)) { // Safe search, skip nsfw?
$result_urls = array_column($results['search'], 'hash', 'id'); if($request->opts->show_nsfw_magnets == 'off' && $request->search->safe !== 0 && $result['nsfw']) continue;
if(isset($goosle_results['search'])) {
$result_urls = array_column($goosle_results['search'], 'hash', 'id');
$found_id = array_search($result['hash'], $result_urls); // Return the result ID, or false if not found $found_id = array_search($result['hash'], $result_urls); // Return the result ID, or false if not found
} else { } else {
$found_id = false; $found_id = false;
} }
$how_many_results++;
if($found_id !== false) { if($found_id !== false) {
// Duplicate result from another engine // Duplicate result from another engine
// If seeders or leechers mismatch, assume they're different peers // If seeders or leechers mismatch, assume they're different peers
if($results['search'][$found_id]['seeders'] != $result['seeders']) $results['search'][$found_id]['combo_seeders'] += intval($result['seeders']); if($goosle_results['search'][$found_id]['seeders'] != $result['seeders']) $goosle_results['search'][$found_id]['combo_seeders'] += intval($result['seeders']);
if($results['search'][$found_id]['leechers'] != $result['leechers']) $results['search'][$found_id]['combo_leechers'] += intval($result['leechers']); if($goosle_results['search'][$found_id]['leechers'] != $result['leechers']) $goosle_results['search'][$found_id]['combo_leechers'] += intval($result['leechers']);
$results['search'][$found_id]['combo_source'][] = $engine_result['source']; $goosle_results['search'][$found_id]['combo_source'][] = $engine_result['source'];
// If duplicate result has more info, add it // If duplicate result has more info, add it
if(is_null($results['search'][$found_id]['year']) && !is_null($result['year'])) $results['search'][$found_id]['year'] = $result['year']; if(is_null($goosle_results['search'][$found_id]['year']) && !is_null($result['year'])) $goosle_results['search'][$found_id]['year'] = $result['year'];
if(is_null($results['search'][$found_id]['category']) && !is_null($result['category'])) $results['search'][$found_id]['category'] = $result['category']; if(is_null($goosle_results['search'][$found_id]['category']) && !is_null($result['category'])) $goosle_results['search'][$found_id]['category'] = $result['category'];
if(is_null($results['search'][$found_id]['runtime']) && !is_null($result['runtime'])) $results['search'][$found_id]['runtime'] = $result['runtime']; if(is_null($goosle_results['search'][$found_id]['runtime']) && !is_null($result['runtime'])) $goosle_results['search'][$found_id]['runtime'] = $result['runtime'];
if(is_null($results['search'][$found_id]['url']) && !is_null($result['url'])) $results['search'][$found_id]['url'] = $result['url']; if(is_null($goosle_results['search'][$found_id]['url']) && !is_null($result['url'])) $goosle_results['search'][$found_id]['url'] = $result['url'];
if(is_null($results['search'][$found_id]['date_added']) && !is_null($result['date_added'])) $results['search'][$found_id]['date_added'] = $result['date_added']; if(is_null($goosle_results['search'][$found_id]['timestamp']) && !is_null($result['timestamp'])) $goosle_results['search'][$found_id]['timestamp'] = $result['timestamp'];
if(is_null($results['search'][$found_id]['quality']) && !is_null($result['quality'])) $results['search'][$found_id]['quality'] = $result['quality']; if(is_null($goosle_results['search'][$found_id]['quality']) && !is_null($result['quality'])) $goosle_results['search'][$found_id]['quality'] = $result['quality'];
if(is_null($results['search'][$found_id]['type']) && !is_null($result['type'])) $results['search'][$found_id]['type'] = $result['type']; if(is_null($goosle_results['search'][$found_id]['type']) && !is_null($result['type'])) $goosle_results['search'][$found_id]['type'] = $result['type'];
if(is_null($results['search'][$found_id]['audio']) && !is_null($result['audio'])) $results['search'][$found_id]['audio'] = $result['audio']; if(is_null($goosle_results['search'][$found_id]['audio']) && !is_null($result['audio'])) $goosle_results['search'][$found_id]['audio'] = $result['audio'];
} else { } else {
// First find, rank and add to results // First find, rank and add to results
// Ranks by combo_seeders instead of regular ranking // Ranks by combo_seeders instead of regular ranking
@ -98,11 +108,17 @@ class MagnetSearch extends EngineRequest {
$result['combo_source'][] = $engine_result['source']; $result['combo_source'][] = $engine_result['source'];
$result['id'] = md5($result['hash']); // Predictable/repeatable 'unique' string $result['id'] = md5($result['hash']); // Predictable/repeatable 'unique' string
$results['search'][$result['id']] = $result; // Add result to final results
$goosle_results['search'][$result['id']] = $result;
} }
unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank); unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank);
} }
// Count results per source
$goosle_results['sources'][$engine_result['source']] = $how_many_results;
unset($how_many_results);
} }
} }
} else { } else {
@ -110,46 +126,49 @@ class MagnetSearch extends EngineRequest {
$http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : ""; $http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : "";
$github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request)." failed with error ".$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error')); $github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request)." failed with error ".$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error'));
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>." 'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>."
); );
} }
unset($request); unset($request);
} }
if(array_key_exists('search', $goosle_results)) {
// Re-order results based on seeders
$keys = array_column($goosle_results['search'], 'combo_seeders');
array_multisort($keys, SORT_DESC, $goosle_results['search']);
// Count all results
$goosle_results['number_of_results'] = count($goosle_results['search']);
unset($keys);
} else {
// Add error if there are no search results
$goosle_results['error'][] = array(
'message' => "No results found. Please try with more specific or different keywords!"
);
}
} else { } else {
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Configuration issue!</strong> It appears that all Magnet Search engines are disabled. Please enable at least one in your config.php file.<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>." 'message' => "It appears that all Magnet Search engines are disabled or that searching for magnet links is disabled."
); );
} }
if(array_key_exists('search', $results)) { return $goosle_results;
// Re-order results based on seeders
$keys = array_column($results['search'], 'combo_seeders');
array_multisort($keys, SORT_DESC, $results['search']);
// Cap results
$results['search'] = array_slice($results['search'], 0, 200);
unset($keys);
} else {
// Add error if there are no search results
$results['error'][] = array(
'message' => "No results found. Please try with more specific or different keywords!"
);
}
return $results;
} }
public static function print_results($results, $opts) { public static function print_results($goosle_results, $search, $opts) {
/* /*
// Uncomment for debugging // Uncomment for debugging
echo '<pre>Settings: '; echo '<pre>Settings: ';
print_r($opts); print_r($opts);
echo '</pre>'; echo '</pre>';
echo "<pre>Search data: ";
print_r($search);
echo "</pre>";
echo '<pre>Search results: '; echo '<pre>Search results: ';
print_r($results); print_r($goosle_results);
echo '</pre>'; echo '</pre>';
*/ */
@ -157,87 +176,73 @@ echo '</pre>';
if($opts->show_yts_highlight == 'on') { if($opts->show_yts_highlight == 'on') {
require ABSPATH.'engines/boxoffice/yts.php'; require ABSPATH.'engines/boxoffice/yts.php';
echo "<div class=\"result-grid\">";
echo "<h2>Latest releases from YTS</h2>"; echo "<h2>Latest releases from YTS</h2>";
echo "<p>View these and more new releases on the <a href=\"./box-office.php?q=".$opts->query."&t=9&a=".$opts->hash."\">box office</a> page!</p>"; echo "<p>View these and more new releases on the <a href=\"./box-office.php?q=".$search->query."&t=9&a=".$opts->hash."\">box office</a> page!</p>";
echo "<ul>"; echo "<ul class=\"result-grid\">";
$highlights = array_slice(yts_boxoffice($opts, 'date_added'), 0, 8); $highlights = array_slice(yts_boxoffice($opts, 'date_added'), 0, 8);
foreach($highlights as $highlight) { foreach($highlights as $highlight) {
$thumb = (!empty($highlight['thumbnail'])) ? $highlight['thumbnail'] : $blank_thumb; $thumb = (!empty($highlight['thumbnail'])) ? $highlight['thumbnail'] : $opts->pixel;
echo "<li class=\"result highlight yts\">"; echo "<li class=\"result highlight yts\">";
echo " <div class=\"result-box\">"; echo " <div class=\"thumb\">";
echo " <a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['name']."\"><img src=\"".$thumb."\" alt=\"".$highlight['name']."\" /></a>"; echo " <a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['title']."\"><img src=\"".$thumb."\" alt=\"".$highlight['title']."\" /></a>";
echo " </div>"; echo " </div>";
echo " <span><center><a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['name']."\">".$highlight['name']."</a></center></span>"; echo " <span><center><a onclick=\"openpopup('highlight-".$highlight['id']."')\" title=\"More info: ".$highlight['title']."\">".$highlight['title']."</a></center></span>";
// HTML for popup // HTML for popup
echo " <div id=\"highlight-".$highlight['id']."\" class=\"goosebox\">"; echo highlight_popup($opts->hash, $highlight);
echo " <div class=\"goosebox-body\">";
echo " <h2>".$highlight['name']."</h2>";
echo " <p>".$highlight['summary']."</p>";
echo " <p><a href=\"./results.php?q=".urlencode($highlight['name']." ".$highlight['year'])."&a=".$opts->hash."&t=0\" title=\"Search on Goosle Web Search!\">Search on Goosle</a> &bull; <a href=\"./results.php?q=".urlencode($highlight['name']." ".$highlight['year'])."&a=".$opts->hash."&t=9\" title=\"Search on Goosle Magnet Search! For new additions results may be limited.\">Find more Magnet links</a></p>";
echo " <p><strong>Genre:</strong> ".$highlight['category']."<br /><strong>Released:</strong> ".$highlight['year']."<br /><strong>Rating:</strong> ".movie_star_rating($highlight['rating'])." <small>(".$highlight['rating']." / 10)</small></p>";
// List downloads
echo " <h3>Downloads:</h3>";
echo " <p>";
foreach($highlight['magnet_links'] as $magnet) {
if(!is_null($magnet['quality'])) $meta[] = $magnet['quality'];
if(!is_null($magnet['type'])) $meta[] = $magnet['type'];
$meta[] = human_filesize($magnet['filesize']);
echo "<button class=\"download\" onclick=\"location.href='".$magnet['magnet']."'\">".implode(' / ', $meta)."</button>";
unset($meta);
}
echo " </p>";
echo " <p><a onclick=\"closepopup()\">Close</a></p>";
echo " </div>";
echo " </div>";
echo "</li>"; echo "</li>";
unset($highlight, $magnet); unset($highlight);
} }
echo "</ul>"; echo "</ul>";
echo "</div>";
} }
// Main content // Main content
if(array_key_exists('search', $results)) { if(array_key_exists('search', $goosle_results)) {
// Is this a shared search? Move shared result to position 1 // Is this a shared search? Move shared result to position 1
if($opts->show_share_option == 'on' && !empty($opts->share)) { if($opts->show_share_option == 'on' && !empty($search->share)) {
$keys = array_keys($results['search']); $keys = array_keys($goosle_results['search']);
$found_id = array_search(md5($opts->share), $keys); // Return the shared key ID $found_id = array_search(md5($search->share), $keys); // Return the shared key ID
$found_id = $keys[$found_id]; // Get the shared ID $found_id = $keys[$found_id]; // Get the actual shared ID
$first = array($found_id => $results['search'][$found_id]); // Get the result
unset($results['search'][$found_id], $keys, $found_id); $first = array($found_id => $goosle_results['search'][$found_id]);
// Delete the result wherever it is
unset($goosle_results['search'][$found_id], $keys, $found_id);
// Add the result as the first item
$goosle_results['search'] = array_merge($first, $goosle_results['search']);
}
$results['search'] = array_merge($first, $results['search']); // Pagination offset
if($opts->cache_type !== 'off') {
$offset = ((($search->page - 1) * $opts->search_results_per_page) + 1);
$goosle_results['search'] = array_slice($goosle_results['search'], $offset, $opts->search_results_per_page);
} }
echo "<ul>"; echo "<ul>";
// Elapsed time // Elapsed time and search sources
$number_of_results = count($results['search']); echo "<li class=\"meta\">";
echo "<li class=\"timer\">Fetched ".$number_of_results." results in ".$results['time']." seconds.</li>"; echo " <p class=\"timer\">Fetched ".$goosle_results['number_of_results']." results in ".$goosle_results['time']." seconds.</p>";
if($opts->show_search_source == 'on') {
// Format sources echo " <p class=\"sources\">".search_sources($goosle_results['sources'])."</p>";
echo "<li class=\"sources\">".search_sources($results['sources'])."</li>"; }
echo "</li>";
// Search results // Search results
foreach($results['search'] as $result) { foreach($goosle_results['search'] as $result) {
// Extra data // Extra data
$base = $meta = array(); $base = $meta = array();
if(!empty($result['combo_seeders'])) $base[] = "<strong>Seeds:</strong> <span class=\"green\">".$result['combo_seeders']."</span>"; if(!empty($result['combo_seeders'])) $base[] = "<strong>Seeds:</strong> <span class=\"green\">".$result['combo_seeders']."</span>";
if(!empty($result['combo_leechers'])) $base[] = "<strong>Peers:</strong> <span class=\"red\">".$result['combo_leechers']."</span>"; if(!empty($result['combo_leechers'])) $base[] = "<strong>Peers:</strong> <span class=\"red\">".$result['combo_leechers']."</span>";
if(!empty($result['filesize'])) $base[] = "<strong>Size:</strong> ".$result['filesize']; if(!empty($result['filesize'])) $base[] = "<strong>Size:</strong> ".$result['filesize'];
if(!empty($result['date_added'])) $base[] = "<strong>Added on:</strong> ".date("M d, Y", $result['date_added']); if(!empty($result['timestamp'])) $base[] = "<strong>Added on:</strong> ".the_date("M d, Y", $result['timestamp']);
if(!empty($result['mpa_rating'])) $base[] = "<strong>MPA Rating:</strong> ".$result['mpa_rating'];
if(!empty($result['category'])) $meta[] = "<strong>Category:</strong> ".$result['category']; if(!empty($result['category'])) $meta[] = "<strong>Category:</strong> ".$result['category'];
if(!empty($result['year'])) $meta[] = "<strong>Year:</strong> ".$result['year']; if(!empty($result['year'])) $meta[] = "<strong>Year:</strong> ".$result['year'];
@ -249,7 +254,7 @@ echo '</pre>';
// Highlight the shared result // Highlight the shared result
$class = ""; $class = "";
if($opts->show_share_option == 'on') { if($opts->show_share_option == 'on') {
if(!empty($opts->share) && $result['hash'] == $opts->share) { if(!empty($search->share) && $result['hash'] == $search->share) {
$class = " shared"; $class = " shared";
} else { } else {
$base[] = "<a onclick=\"openpopup('result-".$result['id']."')\" title=\"Share magnet result\">Share</a>"; $base[] = "<a onclick=\"openpopup('result-".$result['id']."')\" title=\"Share magnet result\">Share</a>";
@ -258,28 +263,31 @@ echo '</pre>';
// Put result together // Put result together
echo "<li class=\"result magnet id-".$result['id'].$class."\">"; echo "<li class=\"result magnet id-".$result['id'].$class."\">";
echo " <div class=\"title\"><a href=\"".$result['magnet']."\"><h2>".stripslashes($result['name'])."</h2></a></div>"; echo " <div class=\"title\"><a href=\"".$result['magnet']."\"><h2>".stripslashes($result['title'])."</h2></a></div>";
echo " <div class=\"description\">"; echo " <div class=\"description\">";
echo " <p>".implode(" &bull; ", $base)."</p>"; echo " <p>".implode(" &bull; ", $base)."</p>";
echo " <p>".implode(" &bull; ", $meta)."</p>"; echo " <p>".implode(" &bull; ", $meta)."</p>";
echo " </div>";
// Result sources // Result sources
if($opts->show_search_source == 'on') { if($opts->show_search_source == 'on') {
// If available, add a link to the found torrent page // If available, add a link to the found torrent page
$url = (array_key_exists('url', $result)) ? " &bull; <a href=\"".$result['url']."\" target=\"_blank\" title=\"Careful - Site may contain intrusive popup ads and malware!\">torrent page</a>" : ""; $url = (!is_null($result['url'])) ? " &bull; <a href=\"".$result['url']."\" target=\"_blank\" title=\"Visit torrent page\">torrent page</a> <span class=\"tooltip tooltip-alert\"><span class=\"tooltiptext\"><strong>Careful!</strong> Site may contain intrusive popup ads and malware!</span></span>" : "";
echo " <div class=\"meta\">Found on ".replace_last_comma(implode(', ', $result['combo_source'])).$url."</div>"; echo " <p><small>Found on ".replace_last_comma(implode(', ', $result['combo_source'])).$url."</small></p>";
} }
echo " </div>";
// Share popup // Share popup
if($opts->show_share_option == 'on' && $result['hash'] != $opts->share) { if($opts->show_share_option == 'on' && $result['hash'] != $search->share) {
// Generate an encoded hash for sharing
$share_url = base64_url_encode($search->query.'||'.$search->type.'||'.$result['hash']);
// The actual popup
echo " <div id=\"result-".$result['id']."\" class=\"goosebox\">"; echo " <div id=\"result-".$result['id']."\" class=\"goosebox\">";
echo " <div class=\"goosebox-body\">"; echo " <div class=\"goosebox-body\">";
echo " <h2>Share magnet result</h2>"; echo " <h2>Share magnet result</h2>";
echo " <p>Tap or click on the field below to copy the magnet result to your clipboard.</p>"; echo " <p>Tap or click on the field below to copy the magnet result to your clipboard.</p>";
echo " <h3>Sharing: ".stripslashes($result['name'])."</h3>"; echo " <h3>Sharing: ".stripslashes($result['title'])."</h3>";
echo " <p><input tabindex=\"2\" type=\"text\" id=\"share-result-".$result['id']."\" class=\"share-field\" value=\"".share_encode($opts, $result['hash'])."\" /><button tabindex=\"1\" class=\"share-button\" onclick=\"clipboard('share-result-".$result['id']."')\">Copy magnet link</button></p>"; echo " <p><input tabindex=\"2\" type=\"text\" id=\"share-result-".$result['id']."\" class=\"share-field\" value=\"".get_base_url($opts->siteurl)."/results.php?s=".$share_url."\" /><button tabindex=\"1\" class=\"share-button\" onclick=\"clipboard('share-result-".$result['id']."')\">Copy magnet link</button></p>";
echo " <p><span id=\"share-result-".$result['id']."-response\"></span></p>"; echo " <p><span id=\"share-result-".$result['id']."-response\"></span></p>";
echo " <p><a onclick=\"closepopup()\">Close</a></p>"; echo " <p><a onclick=\"closepopup()\">Close</a></p>";
echo " </div>"; echo " </div>";
@ -292,12 +300,18 @@ echo '</pre>';
} }
echo "</ul>"; echo "</ul>";
echo "<center><small>Goosle does not index, offer or distribute torrent files.</small></center>";
// Pagination navigation
if($opts->cache_type !== 'off' && $goosle_results['number_of_results'] > $opts->search_results_per_page) {
echo "<p class=\"pagination\">".search_pagination($search, $opts, $goosle_results['number_of_results'])."</p>";
}
echo "<p class=\"text-center\"><small>Goosle does not index, offer or distribute torrent files.</small></p>";
} }
// No results found // No results found
if(array_key_exists('error', $results)) { if(array_key_exists('error', $goosle_results)) {
foreach($results['error'] as $error) { foreach($goosle_results['error'] as $error) {
echo "<div class=\"error\">".$error['message']."</div>"; echo "<div class=\"error\">".$error['message']."</div>";
} }
} }

View file

@ -12,32 +12,34 @@
class NewsSearch extends EngineRequest { class NewsSearch extends EngineRequest {
protected $requests, $special_request; protected $requests, $special_request;
public function __construct($opts, $mh) { public function __construct($search, $opts, $mh) {
$this->requests = array(); $this->requests = array();
if($opts->enable_qwantnews == 'on') { if($opts->enable_news_search == 'on') {
require ABSPATH.'engines/news/qwant-news.php'; if($opts->enable_qwantnews == 'on') {
$this->requests[] = new QwantNewsRequest($opts, $mh); require ABSPATH.'engines/news/qwant-news.php';
} $this->requests[] = new QwantNewsRequest($search, $opts, $mh);
}
if($opts->enable_yahoonews == 'on') {
require ABSPATH.'engines/news/yahoo-news.php'; if($opts->enable_yahoonews == 'on') {
$this->requests[] = new YahooNewsRequest($opts, $mh); require ABSPATH.'engines/news/yahoo-news.php';
} $this->requests[] = new YahooNewsRequest($search, $opts, $mh);
}
if($opts->enable_bravenews == 'on') {
require ABSPATH.'engines/news/brave-news.php'; if($opts->enable_bravenews == 'on') {
$this->requests[] = new BraveNewsRequest($opts, $mh); require ABSPATH.'engines/news/brave-news.php';
} $this->requests[] = new BraveNewsRequest($search, $opts, $mh);
}
if($opts->enable_hackernews == 'on') {
require ABSPATH.'engines/news/hackernews.php'; if($opts->enable_hackernews == 'on') {
$this->requests[] = new HackernewsRequest($opts, $mh); require ABSPATH.'engines/news/hackernews.php';
$this->requests[] = new HackernewsRequest($search, $opts, $mh);
}
} }
} }
public function parse_results($response) { public function parse_results($response) {
$results = array(); $goosle_results = array();
if(count($this->requests) !== 0) { if(count($this->requests) !== 0) {
foreach($this->requests as $request) { foreach($this->requests as $request) {
@ -45,72 +47,63 @@ class NewsSearch extends EngineRequest {
$engine_result = $request->get_results(); $engine_result = $request->get_results();
if(!empty($engine_result)) { if(!empty($engine_result)) {
if(array_key_exists('did_you_mean', $engine_result)) { if(isset($engine_result['search'])) {
$results['did_you_mean'] = $engine_result['did_you_mean']; $how_many_results = 0;
} $time = time();
if(array_key_exists('search_specific', $engine_result)) {
$results['search_specific'][] = $engine_result['search_specific'];
}
if(array_key_exists('search', $engine_result)) {
// Count results per source
$results['sources'][$engine_result['source']] = $engine_result['amount'];
// Merge duplicates and apply relevance scoring // Merge duplicates and apply relevance scoring
foreach($engine_result['search'] as $result) { foreach($engine_result['search'] as $result) {
if(array_key_exists('search', $results)) { if(isset($goosle_results['search'])) {
$result_urls = array_column($results['search'], 'url', 'id'); $result_urls = array_column($goosle_results['search'], 'url', 'id');
$found_id = array_search($result['url'], $result_urls); // Return the result ID, or false if not found $found_id = array_search($result['url'], $result_urls); // Return the result ID, or false if not found
} else { } else {
$found_id = false; $found_id = false;
} }
$how_many_results++;
$social_media_multiplier = (is_social_media($result['url'])) ? ($request->opts->social_media_relevance / 10) : 1; $social_media_multiplier = (is_social_media($result['url'])) ? ($request->opts->social_media_relevance / 10) : 1;
$goosle_rank = floor($result['engine_rank'] * floatval($social_media_multiplier)); $goosle_rank = floor($result['engine_rank'] * floatval($social_media_multiplier));
if($found_id !== false) { if($found_id !== false) {
// Duplicate result from another engine // Duplicate result from another engine
$results['search'][$found_id]['goosle_rank'] += $goosle_rank; $goosle_results['search'][$found_id]['goosle_rank'] += $goosle_rank;
$results['search'][$found_id]['combo_source'][] = $engine_result['source']; $goosle_results['search'][$found_id]['combo_source'][] = $engine_result['source'];
} else { } else {
// First find, rank and add to results // First find, rank and add to results
// Replace anything but alphanumeric with a space $match_rank = match_count($result['title'], $request->search->query_terms);
$query_terms = explode(' ', preg_replace('/\s{2,}|[^a-z0-9]+/', ' ', strtolower($request->query))); $match_rank += match_count($result['description'], $request->search->query_terms);
$match_rank = match_count($result['title'], $query_terms); $match_rank += match_count($result['url'], $request->search->query_terms);
$match_rank += match_count($result['description'], $query_terms);
$match_rank += match_count($result['url'], $query_terms);
if($result['date_added'] > $request->opts->result_range) { $time_rank = $time - $result['timestamp'];
$time_rank = time() - $result['date_added']; if($time_rank > 21600) { // Less than 6 hours old
if($time_rank > 7776001) { // More than 3 months old $match_rank += 8;
$match_rank += 1; } elseif($time_rank > 86400 && $time_rank < 21600) { // About a day old
} elseif($time_rank > 3888001 && $time_rank < 7776000) { $match_rank += 6;
$match_rank += 2; } elseif($time_rank > 604800 && $time_rank < 86400) { // Less than a week old, but more than a day
} elseif($time_rank > 1209600 && $time_rank < 3888000) { $match_rank += 4;
$match_rank += 4; } elseif($time_rank > 2592000 && $time_rank < 604800) { // Less than a month old, but more than a week
} elseif($time_rank > 604801 && $time_rank < 1209600) { $match_rank += 4;
$match_rank += 6; } elseif($time_rank > 31536000 && $time_rank < 2592000) { // Less than a year old, but more than a month
} elseif($time_rank > 86401 && $time_rank < 604800) { $match_rank += 2;
$match_rank += 8; } else { // More than a year old
} elseif($time_rank > 43201 && $time_rank < 86400) { $match_rank += 1;
$match_rank += 10;
} elseif($time_rank > 32601 && $time_rank < 43200) {
$match_rank += 12;
} else { // Less than 6 hours old
$match_rank += 14;
}
} }
$result['goosle_rank'] = $goosle_rank + $match_rank; $result['goosle_rank'] = $goosle_rank + $match_rank;
$result['combo_source'][] = $engine_result['source']; $result['combo_source'][] = $engine_result['source'];
$result['id'] = md5($result['url']); $result['id'] = md5($result['url']);
$results['search'][$result['id']] = $result; // Add result to final results
$goosle_results['search'][$result['id']] = $result;
} }
unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank, $time_rank, $query_terms); unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank, $time_rank, $query_terms);
} }
// Count results per source
$goosle_results['sources'][$engine_result['source']] = $how_many_results;
unset($how_many_results, $time);
} }
} }
} else { } else {
@ -118,84 +111,109 @@ class NewsSearch extends EngineRequest {
$http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : ''; $http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : '';
$github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request)." failed with error ".$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error')); $github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request)." failed with error ".$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error'));
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>." 'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>."
); );
} }
unset($request); unset($request);
} }
if(array_key_exists('search', $goosle_results)) {
// Re-order results based on rank
$keys = array_column($goosle_results['search'], 'goosle_rank');
array_multisort($keys, SORT_DESC, $goosle_results['search']);
// Count all results
$goosle_results['number_of_results'] = count($goosle_results['search']);
unset($keys);
} else {
// Add error if there are no search results
$goosle_results['error'][] = array(
'message' => "No results found. Please try with more specific or different keywords!"
);
}
} else { } else {
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Configuration issue!</strong> It appears that all Web Search engines are disabled. Please enable at least one in your config.php file.<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>." 'message' => "It appears that all News Search engines are disabled or that searching for news is disabled."
); );
} }
if(array_key_exists('search', $results)) { return $goosle_results;
// Re-order results based on rank
$keys = array_column($results['search'], 'goosle_rank');
array_multisort($keys, SORT_DESC, $results['search']);
unset($keys);
} else {
// Add error if there are no search results
$results['error'][] = array(
'message' => "No results found. Please try with more specific or different keywords!"
);
}
return $results;
} }
public static function print_results($results, $opts) { public static function print_results($goosle_results, $search, $opts) {
/* /*
// Uncomment for debugging // Uncomment for debugging
echo '<pre>Settings: '; echo '<pre>Settings: ';
print_r($opts); print_r($opts);
echo '</pre>'; echo '</pre>';
echo "<pre>Search data: ";
print_r($search);
echo "</pre>";
echo '<pre>Search results: '; echo '<pre>Search results: ';
print_r($results); print_r($goosle_results);
echo '</pre>'; echo '</pre>';
*/ */
if(array_key_exists('search', $results)) { if(array_key_exists('search', $goosle_results)) {
// Pagination offset
if($opts->cache_type !== 'off') {
$offset = ((($search->page - 1) * $opts->search_results_per_page) + 1);
$goosle_results['search'] = array_slice($goosle_results['search'], $offset, $opts->search_results_per_page);
}
echo "<ul>"; echo "<ul>";
// Elapsed time // Elapsed time and search sources
$number_of_results = count($results['search']); echo "<li class=\"meta\">";
echo "<li class=\"timer\">Fetched ".$number_of_results." results in ".$results['time']." seconds.</li>"; echo " <p class=\"timer\">Fetched ".$goosle_results['number_of_results']." results in ".$goosle_results['time']." seconds.</p>";
if($opts->show_search_source == 'on') {
// Format sources echo " <p class=\"sources\">".search_sources($goosle_results['sources'])."</p>";
echo "<li class=\"sources\">".search_sources($results['sources'])."</li>"; }
echo "</li>";
// Search results // Search results
foreach($results['search'] as $result) { foreach($goosle_results['search'] as $result) {
// Extra data // Extra data
$base = array(); $meta = array();
if(!empty($result['source'])) $base[] = "<strong>Source:</strong> ".$result['source']; if(!empty($result['source'])) $meta[] = "<strong>Source:</strong> ".$result['source'];
if(!empty($result['date_added'])) $base[] = "<strong>Posted:</strong> ".date("M d, Y", $result['date_added']); if(!empty($result['timestamp'])) $meta[] = "<strong>Posted:</strong> ".the_date("M d, Y", $result['timestamp']);
if($opts->show_search_source == 'on') $base[] = replace_last_comma(implode(', ', $result['combo_source'])); if($opts->show_search_source == 'on') $meta[] = replace_last_comma(implode(', ', $result['combo_source']));
if($opts->show_search_rank == 'on') $base[] = "Rank: ".$result['goosle_rank']; if($opts->show_search_rank == 'on') $meta[] = "Rank: ".$result['goosle_rank'];
$thumb = (!empty($result['image'])) ? $result['image'] : $opts->pixel;
echo "<li class=\"result news rank-".$result['goosle_rank']." id-".$result['id']."\">"; echo "<li class=\"result news rank-".$result['goosle_rank']." id-".$result['id']."\">";
echo " <div class=\"title\"><a href=\"".$result['url']."\" target=\"_blank\"><h2>".$result['title']."</h2></a></div>"; echo " <div class=\"image\"><a href=\"".$result['url']."\" target=\"_blank\" title=\"".$result['title']."\"><img src=\"".$thumb."\" /></a></div>";
echo " <div class=\"description\">"; echo " <div>";
echo " <p><small>".implode(' &bull; ', $base)."</small></p>"; echo " <div class=\"title\"><a href=\"".$result['url']."\" target=\"_blank\"><h2>".$result['title']."</h2></a></div>";
if(!empty($result['description'])) echo " <p>".$result['description']."</p>"; echo " <div class=\"description\">";
echo " <p><small>".implode(' &bull; ', $meta)."</small></p>";
echo " <p>".$result['description']."</p>";
echo " </div>";
echo " </div>"; echo " </div>";
echo "</li>"; echo "</li>";
unset($meta, $thumb);
} }
echo "</ul>"; echo "</ul>";
// Pagination navigation
if($opts->cache_type !== 'off' && $goosle_results['number_of_results'] > $opts->search_results_per_page) {
echo "<p class=\"pagination\">".search_pagination($search, $opts, $goosle_results['number_of_results'])."</p>";
}
} }
// Some error occured // Some error occured
if(array_key_exists('error', $results)) { if(array_key_exists('error', $goosle_results)) {
foreach($results['error'] as $error) { foreach($goosle_results['error'] as $error) {
echo "<div class=\"error\">".$error['message']."</div>"; echo "<div class=\"error\">".$error['message']."</div>";
} }
} }
unset($results); unset($goosle_results);
} }
} }
?> ?>

View file

@ -12,67 +12,79 @@
class Search extends EngineRequest { class Search extends EngineRequest {
protected $requests, $special_request; protected $requests, $special_request;
public function __construct($opts, $mh) { public function __construct($search, $opts, $mh) {
$this->requests = array(); $this->requests = array();
if($opts->enable_duckduckgo == 'on') { if($opts->enable_duckduckgo == 'on') {
require ABSPATH.'engines/search/duckduckgo.php'; require ABSPATH.'engines/search/duckduckgo.php';
$this->requests[] = new DuckDuckGoRequest($opts, $mh); $this->requests[] = new DuckDuckGoRequest($search, $opts, $mh);
} }
if($opts->enable_google == 'on') { if($opts->enable_google == 'on') {
require ABSPATH.'engines/search/google.php'; require ABSPATH.'engines/search/google.php';
$this->requests[] = new GoogleRequest($opts, $mh); $this->requests[] = new GoogleRequest($search, $opts, $mh);
} }
if($opts->enable_qwant == 'on') { if($opts->enable_qwant == 'on') {
require ABSPATH.'engines/search/qwant.php'; require ABSPATH.'engines/search/qwant.php';
$this->requests[] = new QwantRequest($opts, $mh); $this->requests[] = new QwantRequest($search, $opts, $mh);
} }
if($opts->enable_brave == 'on') { if($opts->enable_brave == 'on') {
require ABSPATH.'engines/search/brave.php'; require ABSPATH.'engines/search/brave.php';
$this->requests[] = new BraveRequest($opts, $mh); $this->requests[] = new BraveRequest($search, $opts, $mh);
} }
if($opts->enable_wikipedia == 'on') { if($opts->enable_wikipedia == 'on') {
require ABSPATH.'engines/search/wikipedia.php'; require ABSPATH.'engines/search/wikipedia.php';
$this->requests[] = new WikiRequest($opts, $mh); $this->requests[] = new WikiRequest($search, $opts, $mh);
} }
// Special searches /* --- SPECIAL SEARCHES --- */
$query_terms = explode(' ', $opts->query);
$query_terms[0] = strtolower($query_terms[0]);
// Currency converter // Currency converter
if($opts->special['currency'] == 'on' && count($query_terms) == 4 && (is_numeric($query_terms[0]) && ($query_terms[2] == 'to' || $query_terms[2] == 'in'))) { if($opts->special['currency'] == 'on') {
require ABSPATH.'engines/special/currency.php'; if($search->count_terms == 4 && (is_numeric($search->query_terms[0]) && ($search->query_terms[2] == 'to' || $search->query_terms[2] == 'in'))) {
$this->special_request = new CurrencyRequest($opts, null); require ABSPATH.'engines/special/currency.php';
$this->special_request = new CurrencyRequest($search, $opts, $mh);
}
} }
// Dictionary // Dictionary
if($opts->special['definition'] == 'on' && count($query_terms) == 2 && ($query_terms[0] == 'define' || $query_terms[0] == 'd' || $query_terms[0] == 'mean' || $query_terms[0] == 'meaning')) { if($opts->special['definition'] == 'on') {
require ABSPATH.'engines/special/definition.php'; if($search->count_terms == 2 && ($search->query_terms[0] == 'define' || $search->query_terms[0] == 'meaning')) {
$this->special_request = new DefinitionRequest($opts, null); require ABSPATH.'engines/special/definition.php';
$this->special_request = new DefinitionRequest($search, $opts, $mh);
}
} }
// IP Lookup // IP Lookup
if($opts->special['ipaddress'] == 'on' && ($query_terms[0] == 'ip' || $query_terms[0] == 'myip' || $query_terms[0] == 'ipaddress')) { if($opts->special['ipaddress'] == 'on') {
require ABSPATH.'engines/special/ipify.php'; if($search->count_terms == 1 && ($search->query_terms[0] == 'ip' || $search->query_terms[0] == 'myip' || $search->query_terms[0] == 'ipaddress')) {
$this->special_request = new ipRequest($opts, null); require ABSPATH.'engines/special/ipify.php';
$this->special_request = new ipRequest($search, $opts, $mh);
}
} }
// php.net search // php.net search
if($opts->special['phpnet'] == 'on' && count($query_terms) == 2 && $query_terms[0] == 'php') { if($opts->special['phpnet'] == 'on') {
require ABSPATH.'engines/special/php.php'; if($search->count_terms == 2 && $search->query_terms[0] == 'php') {
$this->special_request = new PHPnetRequest($opts, null); require ABSPATH.'engines/special/php.php';
$this->special_request = new PHPnetRequest($search, $opts, $mh);
}
} }
unset($query_terms); // wordpress.org search
if($opts->special['wordpress'] == 'on') {
if(($search->count_terms == 2 && ($search->query_terms[0] == 'wordpress' || $search->query_terms[0] == 'wp')) || ($search->count_terms == 3 && ($search->query_terms[0] == 'wordpress' || $search->query_terms[0] == 'wp') && $search->query_terms[1] == 'hook')) {
require ABSPATH.'engines/special/wordpress.php';
$this->special_request = new WordPressRequest($search, $opts, $mh);
}
}
} }
public function parse_results($response) { public function parse_results($response) {
$results = array(); $goosle_results = array();
if(count($this->requests) !== 0) { if(count($this->requests) !== 0) {
foreach($this->requests as $request) { foreach($this->requests as $request) {
@ -80,51 +92,55 @@ class Search extends EngineRequest {
$engine_result = $request->get_results(); $engine_result = $request->get_results();
if(!empty($engine_result)) { if(!empty($engine_result)) {
if(array_key_exists('did_you_mean', $engine_result)) { if(isset($engine_result['did_you_mean'])) {
$results['did_you_mean'] = $engine_result['did_you_mean']; $goosle_results['did_you_mean'] = $engine_result['did_you_mean'];
} }
if(array_key_exists('search_specific', $engine_result)) { if(isset($engine_result['search_specific'])) {
$results['search_specific'][] = $engine_result['search_specific']; $goosle_results['search_specific'][] = $engine_result['search_specific'];
} }
if(array_key_exists('search', $engine_result)) { if(isset($engine_result['search'])) {
// Count results per source $how_many_results = 0;
$results['sources'][$engine_result['source']] = $engine_result['amount'];
// Merge duplicates and apply relevance scoring // Merge duplicates and apply relevance scoring
foreach($engine_result['search'] as $result) { foreach($engine_result['search'] as $result) {
if(array_key_exists('search', $results)) { if(isset($goosle_results['search'])) {
$result_urls = array_column($results['search'], 'url', 'id'); $result_urls = array_column($goosle_results['search'], 'url', 'id');
$found_id = array_search($result['url'], $result_urls); // Return the result ID, or false if not found $found_id = array_search($result['url'], $result_urls); // Return the result ID, or false if not found
} else { } else {
$found_id = false; $found_id = false;
} }
$how_many_results++;
$social_media_multiplier = (is_social_media($result['url'])) ? ($request->opts->social_media_relevance / 10) : 1; $social_media_multiplier = (is_social_media($result['url'])) ? ($request->opts->social_media_relevance / 10) : 1;
$goosle_rank = floor($result['engine_rank'] * floatval($social_media_multiplier)); $goosle_rank = floor($result['engine_rank'] * floatval($social_media_multiplier));
if($found_id !== false) { if($found_id !== false) {
// Duplicate result from another engine // Duplicate result from another engine
$results['search'][$found_id]['goosle_rank'] += $goosle_rank; $goosle_results['search'][$found_id]['goosle_rank'] += $goosle_rank;
$results['search'][$found_id]['combo_source'][] = $engine_result['source']; $goosle_results['search'][$found_id]['combo_source'][] = $engine_result['source'];
} else { } else {
// First find, rank and add to results // First find, rank and add to results
// Replace anything but alphanumeric with a space $match_rank = match_count($result['title'], $request->search->query_terms);
$query_terms = explode(' ', preg_replace('/\s{2,}|[^a-z0-9]+/', ' ', strtolower($request->query))); $match_rank += match_count($result['description'], $request->search->query_terms);
$match_rank = match_count($result['title'], $query_terms); $match_rank += match_count($result['url'], $request->search->query_terms);
$match_rank += match_count($result['description'], $query_terms);
$match_rank += match_count($result['url'], $query_terms);
$result['goosle_rank'] = $goosle_rank + $match_rank; $result['goosle_rank'] = $goosle_rank + $match_rank;
$result['combo_source'][] = $engine_result['source']; $result['combo_source'][] = $engine_result['source'];
$result['id'] = md5($result['url']); $result['id'] = md5($result['url']);
$results['search'][$result['id']] = $result; // Add result to final results
$goosle_results['search'][$result['id']] = $result;
} }
unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank, $query_terms); unset($result, $result_urls, $found_id, $social_media_multiplier, $goosle_rank, $match_rank, $query_terms);
} }
// Count results per source
$goosle_results['sources'][$engine_result['source']] = $how_many_results;
unset($how_many_results);
} }
} }
} else { } else {
@ -132,120 +148,141 @@ class Search extends EngineRequest {
$http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : ''; $http_code_info = ($request_result['http_code'] > 200 && $request_result['http_code'] < 600) ? " - <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/".$request_result['http_code']."\" target=\"_blank\">What's this</a>?" : '';
$github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request).' failed with error '.$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error')); $github_issue_url = "https://github.com/adegans/Goosle/discussions/new?category=general&".http_build_query(array('title' => get_class($request).' failed with error '.$request_result['http_code'], 'body' => "```\nEngine: ".get_class($request)."\nError Code: ".$request_result['http_code']."\nRequest url: ".$request_result['url']."\n```", 'labels' => 'request-error'));
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>." 'message' => "<strong>Ohno! A search query ran into some trouble.</strong> Usually you can try again in a few seconds to get a result!<br /><strong>Engine:</strong> ".get_class($request)."<br /><strong>Error code:</strong> ".$request_result['http_code'].$http_code_info."<br /><strong>Request url:</strong> ".$request_result['url']."<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>, or <a href=\"".$github_issue_url."\" target=\"_blank\">ask your own question</a>."
); );
} }
unset($request); unset($request);
} }
// Check for Special result
if($this->special_request) {
$special_result = $this->special_request->get_results();
if($special_result) {
$goosle_results['special'] = $special_result;
}
unset($special_result);
}
if(array_key_exists('search', $goosle_results)) {
// Re-order results based on rank
$keys = array_column($goosle_results['search'], 'goosle_rank');
array_multisort($keys, SORT_DESC, $goosle_results['search']);
// Count all results
$goosle_results['number_of_results'] = count($goosle_results['search']);
unset($keys);
} else {
// Add error if there are no search results
$goosle_results['error'][] = array(
'message' => "No results found. Please try with more specific or different keywords!"
);
}
} else { } else {
$results['error'][] = array( $goosle_results['error'][] = array(
'message' => "<strong>Configuration issue!</strong> It appears that all Web Search engines are disabled. Please enable at least one in your config.php file.<br /><strong>Need help?</strong> Find <a href=\"https://github.com/adegans/Goosle/discussions\" target=\"_blank\">similar issues</a>." 'message' => "It appears that all Web Search engines are disabled. Please enable at least one in your config.php file."
); );
} }
// Check for Special result return $goosle_results;
if($this->special_request) {
$special_result = $this->special_request->get_results();
if($special_result) {
$results['special'] = $special_result;
}
unset($special_result);
}
if(array_key_exists('search', $results)) {
// Re-order results based on rank
$keys = array_column($results['search'], 'goosle_rank');
array_multisort($keys, SORT_DESC, $results['search']);
unset($keys);
} else {
// Add error if there are no search results
$results['error'][] = array(
'message' => "No results found. Please try with more specific or different keywords!"
);
}
return $results;
} }
public static function print_results($results, $opts) { public static function print_results($goosle_results, $search, $opts) {
/*
// Uncomment for debugging // Uncomment for debugging
/*
echo "<pre>Settings: "; echo "<pre>Settings: ";
print_r($opts); print_r($opts);
echo "</pre>"; echo "</pre>";
echo "<pre>Search data: ";
print_r($search);
echo "</pre>";
echo "<pre>Search results: "; echo "<pre>Search results: ";
print_r($results); print_r($goosle_results);
echo "</pre>"; echo "</pre>";
*/ */
if(array_key_exists('search', $results)) { if(array_key_exists('search', $goosle_results)) {
// Pagination offset
if($opts->cache_type !== 'off') {
$offset = ((($search->page - 1) * $opts->search_results_per_page) + 1);
$goosle_results['search'] = array_slice($goosle_results['search'], $offset, $opts->search_results_per_page);
}
echo "<ul>"; echo "<ul>";
// Elapsed time // Elapsed time and search sources
$number_of_results = count($results['search']); echo "<li class=\"meta\">";
echo "<li class=\"timer\">Fetched ".$number_of_results." results in ".$results['time']." seconds.</li>"; echo " <p class=\"timer\">Fetched ".$goosle_results['number_of_results']." results in ".$goosle_results['time']." seconds.</p>";
if($opts->show_search_source == 'on') {
echo " <p class=\"sources\">".search_sources($goosle_results['sources'])."</p>";
}
echo "</li>";
// Format sources // Search suggestions
echo "<li class=\"sources\">".search_sources($results['sources'])."</li>"; if(array_key_exists('did_you_mean', $goosle_results)) {
echo "<li class=\"meta\">";
// Did you mean/Search suggestion echo " <p class=\"didyoumean\">Did you mean <a href=\"./results.php?q=".urlencode($goosle_results['did_you_mean'])."&t=".$search->type."&a=".$opts->hash."\">".$goosle_results['did_you_mean']."</a>?</p>";
if(array_key_exists('did_you_mean', $results)) { if(array_key_exists('search_specific', $goosle_results)) {
echo "<li class=\"suggestion\">Did you mean <a href=\"./results.php?q=".urlencode($results['did_you_mean'])."&t=".$opts->type."&a=".$opts->hash."\">".$results['did_you_mean']."</a>?".search_suggestion($opts, $results)."</li>"; echo " <p class=\"suggestion\">".search_suggestion($search, $opts, $goosle_results)."</p>";
}
echo "</li>";
} }
// Special result // Special result
if(array_key_exists('special', $results)) { if(array_key_exists('special', $goosle_results)) {
echo "<li class=\"result-special web\">"; echo "<li class=\"result-special web\">";
echo " <div class=\"title\"><h2>".$results['special']['title']."</h2></div>"; echo " <div class=\"title\"><h2>".$goosle_results['special']['title']."</h2></div>";
echo " <div class=\"description\">".$results['special']['text']."</div>"; // <p> is in the engine files echo " <div class=\"description\">".$goosle_results['special']['text']."</div>"; // <p> is in the engine files
if(array_key_exists('source', $results['special'])) { echo " <div class=\"source\"><a href=\"".$goosle_results['special']['source']."\" target=\"_blank\">".$goosle_results['special']['source']."</a></div>";
echo " <div class=\"source\"><a href=\"".$results['special']['source']."\" target=\"_blank\">".$results['special']['source']."</a></div>"; if(array_key_exists('note', $goosle_results['special'])) {
echo " <div class=\"note\"><small><em>".$goosle_results['special']['note']."</em></small></div>";
} }
echo "</li>"; echo "</li>";
} }
// Search results // Search results
foreach($results['search'] as $result) { foreach($goosle_results['search'] as $result) {
if($opts->enable_magnet_search == 'on' && $opts->imdb_id_search == 'on') { // Extra data
if(stristr($result['url'], 'imdb.com') !== false && preg_match_all('/(?:tt[0-9]+)/i', $result['url'], $imdb_result)) { $meta = array();
$result['description'] .= "<br /><strong>Goosle detected an IMDb ID for this result, search for <a href=\"./results.php?q=".$imdb_result[0][0]."&a=".$opts->hash."&t=9\" title=\"A Magnet link is a method of downloading movies and tv-shows.\">Magnet links</a>?</strong>"; if($opts->show_search_source == 'on') $meta[] = replace_last_comma(implode(', ', $result['combo_source'])).".";
} if($opts->show_search_rank == 'on') $meta[] = "Rank: ".$result['goosle_rank'];
}
echo "<li class=\"result web rank-".$result['goosle_rank']." id-".$result['id']."\">"; echo "<li class=\"result web rank-".$result['goosle_rank']." id-".$result['id']."\">";
echo " <div class=\"url\"><a href=\"".$result['url']."\" target=\"_blank\">".get_formatted_url($result['url'])."</a></div>"; echo " <div class=\"url\"><a href=\"".$result['url']."\" target=\"_blank\">".search_formatted_url($result['url'])."</a></div>";
echo " <div class=\"title\"><a href=\"".$result['url']."\" target=\"_blank\"><h2>".$result['title']."</h2></a></div>"; echo " <div class=\"title\"><a href=\"".$result['url']."\" target=\"_blank\"><h2>".$result['title']."</h2></a></div>";
echo " <div class=\"description\">"; echo " <div class=\"description\">";
echo " <p>".$result['description']."</p>"; echo " <p>".$result['description']."</p>";
echo " </div>"; if($opts->enable_magnet_search == 'on' && $opts->imdb_id_search == 'on') {
if(stristr($result['url'], 'imdb.com') !== false && preg_match_all('/(?:tt[0-9]+)/i', $result['url'], $imdb_result)) {
if($opts->show_search_source == 'on') { echo " <p><strong>Goosle detected an IMDb ID for this result, search for <a href=\"./results.php?q=".$imdb_result[0][0]."&a=".$opts->hash."&t=9\" title=\"Search for Magnet links\">Magnet links</a>?</strong> <span class=\"tooltip tooltip-question\"><span class=\"tooltiptext\">A Magnet link is a special link for torrent clients to download software, music, movies and tv-shows.</span></span></p>";
echo " <div class=\"meta\">";
echo " Found on ".replace_last_comma(implode(', ', $result['combo_source'])).".";
if($opts->show_search_rank == 'on') {
echo " [rank: ".$result['goosle_rank']."]";
} }
echo " </div>";
} }
echo " <p><small>".implode(' &bull; ', $meta)."</small></p>";
echo " </div>";
echo "</li>"; echo "</li>";
unset($meta);
} }
echo "</ul>"; echo "</ul>";
// Pagination navigation
if($opts->cache_type !== 'off' && $goosle_results['number_of_results'] > $opts->search_results_per_page) {
echo "<p class=\"pagination\">".search_pagination($search, $opts, $goosle_results['number_of_results'])."</p>";
}
} }
// Some error occured // Some error occured
if(array_key_exists('error', $results)) { if(array_key_exists('error', $goosle_results)) {
foreach($results['error'] as $error) { foreach($goosle_results['error'] as $error) {
echo "<div class=\"error\">".$error['message']."</div>"; echo "<div class=\"error\">".$error['message']."</div>";
} }
} }
unset($results); unset($goosle_results);
} }
} }
?> ?>

View file

@ -11,27 +11,14 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class BraveRequest extends EngineRequest { class BraveRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search ignore (not supported)
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) {
$query = trim(str_replace($matches[0], '', $query));
}
unset($matches);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://search.brave.com/search?'.http_build_query(array( $url = 'https://search.brave.com/search?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
'offset' => 0, // Start on 'page' 1 of results (0 = 1) 'offset' => 0, // Start on 'page' 1 of results (0 = 1)
'show_local' => 0, // Localize results (0 = no localization) 'show_local' => 0, // Localize results (0 = no localization)
'spellcheck' => 0, // No spellcheck on your query 'spellcheck' => 0, // No spellcheck on your query
'source' => 'web' // Where are you searching from? (Web) 'source' => 'web' // Where are you searching from? (Web)
)); ));
unset($query);
return $url; return $url;
} }
@ -88,10 +75,8 @@ class BraveRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Brave'; $engine_result['source'] = 'Brave';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,29 +11,21 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class DuckDuckGoRequest extends EngineRequest { class DuckDuckGoRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search override // Safe search override
$safe = '-1'; if($this->search->safe == 0) {
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) { $safe = '-2';
if($matches[2] == 'on') $safe = '1'; } else if($this->search->safe == 2) {
if($matches[2] == 'off') $safe = '-2'; $safe = '1';
$query = trim(str_replace($matches[0], '', $query)); } else {
$safe = '-1';
} }
unset($matches);
// Is there no query left? Bail!
if(empty($query)) return false;
// Set locale // Set locale
$language = (preg_match('/[a-z]{2}-[a-z]{2}/i', $this->opts->duckduckgo_language) && strlen($this->opts->duckduckgo_language) == 5) ? strtolower($this->opts->duckduckgo_language) : 'en_gb'; $language = (preg_match('/[a-z]{2}-[a-z]{2}/i', $this->opts->duckduckgo_language) && strlen($this->opts->duckduckgo_language) == 5) ? strtolower($this->opts->duckduckgo_language) : 'en_gb';
// Is there no query left? Bail!
if(empty($query)) return false;
// All parameters and values: https://duckduckgo.com/duckduckgo-help-pages/settings/params/ // All parameters and values: https://duckduckgo.com/duckduckgo-help-pages/settings/params/
$url = 'https://html.duckduckgo.com/html/?'.http_build_query(array( $url = 'https://html.duckduckgo.com/html/?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
'kp' => $safe, // Safe search (1 = on, -1 = moderate, -2 = off 'kp' => $safe, // Safe search (1 = on, -1 = moderate, -2 = off
'kl' => $language, // Language region 'kl' => $language, // Language region
'kz' => '-1', // Instant answers (1 = on, -1 = off) 'kz' => '-1', // Instant answers (1 = on, -1 = off)
@ -48,7 +40,7 @@ class DuckDuckGoRequest extends EngineRequest {
'k1' => '-1' // Ads (1 = on, -1 = off) 'k1' => '-1' // Ads (1 = on, -1 = off)
)); ));
unset($query, $safe, $language); unset($safe, $language);
return $url; return $url;
} }
@ -115,10 +107,8 @@ class DuckDuckGoRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'DuckDuckGo'; $engine_result['source'] = 'DuckDuckGo';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,24 +11,10 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class GoogleRequest extends EngineRequest { class GoogleRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search override
$safe = '1';
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) {
if($matches[2] == 'on') $safe = '2';
if($matches[2] == 'off') $safe = '0';
$query = trim(str_replace($matches[0], '', $query));
}
unset($matches);
// Is there no query left? Bail!
if(empty($query)) return false;
// Including the preferred language variable breaks the page result, and with that the crawler! // Including the preferred language variable breaks the page result, and with that the crawler!
$url = 'https://www.google.com/search?'.http_build_query(array( $url = 'https://www.google.com/search?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
'safe' => $safe, // Safe search (0 = off, 1 = moderate, 2 = on/strict) 'safe' => $this->search->safe, // Safe search (0 = off, 1 = moderate, 2 = on/strict)
'num' => 30, // Number of results per page 'num' => 30, // Number of results per page
'pws' => 0, // Personalized search results (0 = off) 'pws' => 0, // Personalized search results (0 = off)
'udm' => 14, // A view for simpler/non-ai results 'udm' => 14, // A view for simpler/non-ai results
@ -37,8 +23,6 @@ class GoogleRequest extends EngineRequest {
'sclient' => 'web' // Where are you searching from 'sclient' => 'web' // Where are you searching from
)); ));
unset($query, $safe);
return $url; return $url;
} }
@ -105,10 +89,8 @@ class GoogleRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Google'; $engine_result['source'] = 'Google';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,34 +11,20 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class QwantRequest extends EngineRequest { class QwantRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search override
$safe = '1'; // Moderate results
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) {
if($matches[2] == 'on') $safe = '2';
if($matches[2] == 'off') $safe = '0';
$query = trim(str_replace($matches[0], '', $query));
}
unset($matches);
// Set locale // Set locale
$language = (preg_match('/[a-z]{2}_[a-z]{2}/i', $this->opts->qwant_language) && strlen($this->opts->qwant_language) == 5) ? strtolower($this->opts->qwant_language) : 'en_gb'; $language = (preg_match('/[a-z]{2}_[a-z]{2}/i', $this->opts->qwant_language) && strlen($this->opts->qwant_language) == 5) ? strtolower($this->opts->qwant_language) : 'en_gb';
// Is there no query left? Bail!
if(empty($query)) return false;
// Based on https://github.com/locness3/qwant-api-docs and variables from qwant website // Based on https://github.com/locness3/qwant-api-docs and variables from qwant website
$url = 'https://api.qwant.com/v3/search/web?'.http_build_query(array( $url = 'https://api.qwant.com/v3/search/web?'.http_build_query(array(
'q' => $query, // Search query 'q' => $this->search->query, // Search query
't' => 'web', // Type of search, web search 't' => 'web', // Type of search, web search
'safesearch' => $safe, // Safe search filter (0 = off, 1 = normal, 2 = strict) 'safesearch' => $this->search->safe, // Safe search filter (0 = off, 1 = normal, 2 = strict)
'locale' => $language, // In which language should the search be done 'locale' => $language, // In which language should the search be done
'count' => 10, // How many results? (Maximum 10) 'count' => 10, // How many results? (Maximum 10)
'device' => 'desktop' // What kind of device are we searching from? 'device' => 'desktop' // What kind of device are we searching from?
)); ));
unset($query, $safe, $language); unset($query, $language);
return $url; return $url;
} }
@ -89,10 +75,8 @@ class QwantRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Qwant'; $engine_result['source'] = 'Qwant';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -11,30 +11,19 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class WikiRequest extends EngineRequest { class WikiRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Safe search ignore
if(preg_match('/(safe:)(on|off)/i', $query, $matches)) {
$query = trim(str_replace($matches[0], '', $query));
}
unset($matches);
// Set locale // Set locale
$language = (strlen($this->opts->wikipedia_language) == 2) ? strtolower($this->opts->wikipedia_language) : 'en'; $language = (strlen($this->opts->wikipedia_language) == 2) ? strtolower($this->opts->wikipedia_language) : 'en';
// Is there no query left? Bail!
if(empty($query)) return false;
// Variables based on https://www.mediawiki.org/wiki/API:Search // Variables based on https://www.mediawiki.org/wiki/API:Search
$url = 'https://'.$language.'.wikipedia.org/w/api.php?'.http_build_query(array( $url = 'https://'.$language.'.wikipedia.org/w/api.php?'.http_build_query(array(
'srsearch' => $query, // Search query 'srsearch' => $this->search->query, // Search query
'action' => 'query', // Search type (via a query?) 'action' => 'query', // Search type (via a query?)
'list' => 'search', // Full text search 'list' => 'search', // Full text search
'format' => 'json', // Return format (Must be json) 'format' => 'json', // Return format (Must be json)
'srlimit' => 10 // How many search results to get, ideally as few as possible since it's just static wiki pages (max 500) 'srlimit' => 10 // How many search results to get, ideally as few as possible since it's just static wiki pages (max 500)
)); ));
unset($query, $language); unset($language);
return $url; return $url;
} }
@ -79,10 +68,8 @@ class WikiRequest extends EngineRequest {
} }
// Base info // Base info
$number_of_results = count($engine_temp); if(!empty($engine_temp)) {
if($number_of_results > 0) {
$engine_result['source'] = 'Wikipedia'; $engine_result['source'] = 'Wikipedia';
$engine_result['amount'] = $number_of_results;
$engine_result['search'] = $engine_temp; $engine_result['search'] = $engine_temp;
} }

View file

@ -43,11 +43,10 @@ class CurrencyRequest extends EngineRequest {
// [2] = (to|in) // [2] = (to|in)
// [3] = TO CURRENCY // [3] = TO CURRENCY
$query_terms = explode(' ', $this->query); $amount = floatval($this->search->query_terms[0]);
$amount = floatval($query_terms[0]); $amount_currency = strtoupper($this->search->query_terms[1]);
$amount_currency = strtoupper($query_terms[1]); $conversion_currency = strtoupper($this->search->query_terms[3]);
$conversion_currency = strtoupper($query_terms[3]); $last_update = the_date('M d, Y H:i', strtotime(sanitize($json_response['lastupdate'])));
$last_update = date('M d, Y H:i:s', timezone_offset(strtotime(sanitize($json_response['lastupdate'])), $this->opts->timezone));
// Unknown/misspelled currencies // Unknown/misspelled currencies
if(!array_key_exists($amount_currency, $json_response['rates']) || !array_key_exists($conversion_currency, $json_response['rates'])) { if(!array_key_exists($amount_currency, $json_response['rates']) || !array_key_exists($conversion_currency, $json_response['rates'])) {
@ -58,13 +57,14 @@ class CurrencyRequest extends EngineRequest {
$conversion = round(($json_response['rates'][$conversion_currency] / $json_response['rates'][$amount_currency]) * $amount, 2); $conversion = round(($json_response['rates'][$conversion_currency] / $json_response['rates'][$amount_currency]) * $amount, 2);
$one_to_n = round(($json_response['rates'][$conversion_currency] / $json_response['rates'][$amount_currency]) * 1, 2); $one_to_n = round(($json_response['rates'][$conversion_currency] / $json_response['rates'][$amount_currency]) * 1, 2);
// Return result
$engine_result = array( $engine_result = array(
'title' => "Currency conversion: ".$amount." ".$amount_currency." = ".$conversion." ".$conversion_currency, 'title' => "Currency conversion: ".$amount." ".$amount_currency." = ".$conversion." ".$conversion_currency,
'text' => "<p>1 $amount_currency = $one_to_n $conversion_currency</p><p><small>Updated: $last_update (GMT/UTC+0)</small></p>", 'text' => "<p>1 ".$amount_currency." = ".$one_to_n." ".$conversion_currency."</p><p><small>Updated: ".$last_update."</small></p>",
'source' => "https://moneyconvert.net/" 'source' => "https://moneyconvert.net/"
); );
unset($response, $json_response, $query_terms, $amount, $amount_currency, $conversion, $one_to_n, $conversion_currency, $last_update); unset($response, $json_response, $amount, $amount_currency, $conversion, $one_to_n, $conversion_currency, $last_update);
return $engine_result; return $engine_result;
} }

View file

@ -11,18 +11,9 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class DefinitionRequest extends EngineRequest { class DefinitionRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query); // [0] = (define|meaning)
$query_terms = explode(' ', $query);
// [0] = (define|d|mean|meaning)
// [1] = WORD // [1] = WORD
$url = 'https://api.dictionaryapi.dev/api/v2/entries/en/'.$this->search->query_terms[1];
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://api.dictionaryapi.dev/api/v2/entries/en/'.$query_terms[1];
unset($query, $query_terms);
return $url; return $url;
} }
@ -46,10 +37,12 @@ class DefinitionRequest extends EngineRequest {
if(empty($json_response)) return $engine_result; if(empty($json_response)) return $engine_result;
// No results // No results
if(!array_key_exists('title', $json_response)) return $engine_result; if(isset($json_response['title']) && $json_response['title'] == 'No Definitions Found') return $engine_result;
// Grab first result if there are multiple $result = $json_response[0]; // Always grab the first result
$result = $json_response[0];
// Incomplete listing? Bail!
if(!array_key_exists('word', $result)) return $engine_result;
// Find a phonetic spelling // Find a phonetic spelling
if(isset($result['phonetic'])) { if(isset($result['phonetic'])) {
@ -81,6 +74,7 @@ class DefinitionRequest extends EngineRequest {
unset($meaning); unset($meaning);
} }
// Return result
$engine_result = array( $engine_result = array(
'title' => "Definition for: ".sanitize($result['word'])." <span>[".sanitize($phonetic)."]</span>", 'title' => "Definition for: ".sanitize($result['word'])." <span>[".sanitize($phonetic)."]</span>",
'text' => $formatted_response, 'text' => $formatted_response,

View file

@ -34,10 +34,12 @@ class ipRequest extends EngineRequest {
// No response // No response
if(empty($json_response)) return $engine_result; if(empty($json_response)) return $engine_result;
// Return result
$engine_result = array( $engine_result = array(
'title' => "Your IP Address: ".$_SERVER["REMOTE_ADDR"], 'title' => "Your IP Address: ".$_SERVER["REMOTE_ADDR"],
'text' => "<p>All requests via Goosle use this as your IP Address: ".sanitize($json_response['ip'])."<br /><small>Goosle is not a proxy server. This test does <em>NOT</em> guarantee any degree of privacy. Any site that you visit through Goosle Search Results will see your actual IP Address.</small></p>", 'text' => "<p>All requests via Goosle use this as your IP Address: ".sanitize($json_response['ip'])."</p>",
'source' => "https://www.ipify.org/" 'source' => "https://www.ipify.org/",
'note' => "Goosle is not a proxy server. Any website that you visit through Goosle Search Results will see your actual IP Address."
); );
unset($response, $json_response); unset($response, $json_response);

View file

@ -11,14 +11,8 @@
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
class PHPnetRequest extends EngineRequest { class PHPnetRequest extends EngineRequest {
public function get_request_url() { public function get_request_url() {
$query = str_replace('%22', '\"', $this->query);
// Format query/url for php.net // Format query/url for php.net
$query = str_replace('php ', '', $query); $query = str_replace('_', '-', $this->search->query_terms[1]);
$query = str_replace('_', '-', $query);
// Is there no query left? Bail!
if(empty($query)) return false;
$url = 'https://www.php.net/manual/function.'.urlencode($query).'.php'; $url = 'https://www.php.net/manual/function.'.urlencode($query).'.php';
@ -41,31 +35,39 @@ class PHPnetRequest extends EngineRequest {
if(!$xpath) return $engine_result; if(!$xpath) return $engine_result;
// Scrape the results // Scrape the results
$scrape = $xpath->query("//div/section/div[@class='refentry']"); $scrape = $xpath->query("//div[@class='refentry']");
// No results // No results
if(count($scrape) == 0) return $engine_result; if(count($scrape) == 0) return $engine_result;
$query = str_replace('%22', '', $this->query); $query = str_replace('_', '-', $this->search->query_terms[1]);
$query = str_replace('php ', '', $query);
$query = str_replace('_', '-', $query);
foreach($scrape as $result) { // Process scrape
$title = $xpath->query(".//div/h1[@class='refname']")[0]->textContent; $title = $xpath->evaluate(".//div/h1[@class='refname']", $scrape[0]);
if(is_null($title)) return $engine_result; if($title->length == 0) return $engine_result;
$php_versions = $xpath->query(".//div/p[@class='verinfo']")[0]->textContent; $php_versions = $xpath->evaluate(".//div/p[@class='verinfo']", $scrape[0]);
$purpose = $xpath->query(".//div/p[@class='refpurpose']")[0]->textContent; $purpose = $xpath->evaluate(".//div/p[@class='refpurpose']", $scrape[0]);
$usage = $xpath->query(".//div[@class='refsect1 description']/div[@class='methodsynopsis dc-description']")[0]->textContent; $usage = $xpath->evaluate(".//div[@class='refsect1 description']/div[@class='methodsynopsis dc-description']", $scrape[0]);
$summary = $xpath->query(".//div[@class='refsect1 description']/p[@class='para rdfs-comment']")[0]->textContent; $summary = $xpath->evaluate(".//div[@class='refsect1 description']/p[@class='para rdfs-comment']", $scrape[0]);
$engine_result = array ( $title = sanitize($title[0]->textContent);
// Required $php_versions = ($php_versions->length > 0) ? sanitize($php_versions[0]->textContent) : "";
'title' => "Function: ".sanitize($title), $purpose = ($purpose->length > 0) ? sanitize($purpose[0]->textContent) : "";
'text' => "<p><em><small>".sanitize($php_versions)."</small></em></p><p>".sanitize($purpose)."</p><p>".highlight_string("<?php ".sanitize($usage)." ?>", 1)."</p><p>".$summary."</p>", $usage = ($usage->length > 0) ? sanitize($usage[0]->textContent) : "";
'source' => "https://www.php.net/manual/function.".urlencode($query).".php" $summary = ($summary->length > 0) ? sanitize($summary[0]->textContent) : "";
);
} // Clean up string
$usage = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $usage);
// Return result
$engine_result = array (
// Required
'title' => "Function: ".$title,
'text' => "<p><em><small>".$php_versions."</small></em></p><p>".$purpose."</p><p>".highlight_string("<?php ".htmlspecialchars_decode($usage)." ?>", 1)."</p><p>".$summary."</p>",
'source' => "https://www.php.net/manual/function.".urlencode($query).".php",
'note' => "Description may be incomplete. Always check the documentation page for more information."
);
unset($response, $xpath, $scrape); unset($response, $xpath, $scrape);
return $engine_result; return $engine_result;

View file

@ -0,0 +1,92 @@
<?php
/* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works.
*
* COPYRIGHT NOTICE
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
*
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use.
------------------------------------------------------------------------------------ */
class WordPressRequest extends EngineRequest {
public function get_request_url() {
// What are we looking for?
if($this->search->query_terms[1] == 'hook') {
// https://developer.wordpress.org/reference/hooks/HOOK_OR_FILTER_NAME/
$type = 'hooks';
$query = $this->search->query_terms[2];
} else {
// https://developer.wordpress.org/reference/functions/FUNCTION_NAME/
$type = 'functions';
$query = $this->search->query_terms[1];
}
$url = 'https://developer.wordpress.org/reference/'.$type.'/.'.urlencode($query).'/';
unset($query, $type);
return $url;
}
public function get_request_headers() {
return array(
'Accept' => 'text/html, application/xhtml+xml, application/xml;q=0.8, */*;q=0.7'
);
}
public function parse_results($response) {
$engine_result = array();
$xpath = get_xpath($response);
// No response
if(!$xpath) return $engine_result;
// Scrape the results
$scrape = $xpath->query("//div/main/article");
// No results
if(count($scrape) == 0) return $engine_result;
if($this->search->query_terms[1] == 'hook') {
$type = 'hooks';
$query = $this->search->query_terms[2];
} else {
$type = 'functions';
$query = $this->search->query_terms[1];
}
// Process scrape
$usage = $xpath->evaluate(".//h1[@class='wp-block-wporg-code-reference-title']", $scrape[0]);
if($usage->length == 0) return $engine_result;
$purpose = $xpath->evaluate(".//section[@class='wp-block-wporg-code-reference-summary']", $scrape[0]);
$description = $xpath->evaluate(".//section[contains(@class, 'wp-block-wporg-code-reference-explanation')]/p[1]", $scrape[0]);
if($description->length == 0) $description = $xpath->evaluate(".//section[contains(@class, 'wp-block-wporg-code-reference-description')]/p[1]", $scrape[0]);
$introduced = $xpath->evaluate(".//section[@class='wp-block-wporg-code-reference-changelog']//tbody", $scrape[0]);
$title = sanitize($query);
$purpose = ($purpose->length > 0) ? sanitize($purpose[0]->textContent) : "";
$description = ($description->length > 0) ? sanitize($description[0]->textContent) : "";
$usage = ($usage->length > 0) ? sanitize($usage[0]->textContent) : "";
$introduced = ($introduced->length > 0) ? sanitize($introduced[0]->lastChild->firstElementChild->textContent) : "(Unknown)";
// Clean up string
$usage = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $usage);
// Return result
$engine_result = array (
// Required
'title' => ucfirst($type).": ".$title,
'text' => "<p><em><small>Since WordPress ".$introduced."</small></em></p><p>".$purpose."</p><p>".highlight_string("<?php ".htmlspecialchars_decode($usage)." ?>", 1)."</p><p>".$description."</p>",
'source' => "https://developer.wordpress.org/reference/".$type."/".urlencode($query)."/",
'note' => "Description may be incomplete. Always check the documentation page for more information."
);
unset($response, $xpath, $scrape);
return $engine_result;
}
}
?>

50
error.php Normal file
View file

@ -0,0 +1,50 @@
<?php
/* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works.
*
* COPYRIGHT NOTICE
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
*
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use.
------------------------------------------------------------------------------------ */
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
require ABSPATH.'functions/tools.php';
$opts = load_opts();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Goosle Search</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="robots" content="noodp,noydir" />
<meta name="referrer" content="no-referrer"/>
<meta name="description" content="Get your Goosle on! - The best meta search engine for private and fast search results!" />
<meta property="og:site_name" content="Goosle Search" />
<meta property="og:title" content="Goosle Search error page" />
<meta property="og:description" content="Get your Goosle on! - The best meta search engine for private and fast search results!" />
<meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/error.php" />
<meta property="og:image" content="<?php echo get_base_url($opts->siteurl); ?>/assets/images/goosle.webp" />
<meta property="og:type" content="website" />
<link rel="icon" href="favicon.ico" />
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
<link rel="canonical" href="<?php echo get_base_url($opts->siteurl); ?>/error.php" />
<link rel="stylesheet" type="text/css" href="<?php echo get_base_url($opts->siteurl); ?>/assets/css/styles.css"/>
<link rel="stylesheet" type="text/css" href="<?php echo get_base_url($opts->siteurl); ?>/assets/css/<?php echo $opts->colorscheme; ?>.css"/>
</head>
<body class="startpage">
<div class="auth-error">
<p>You can't use <span class="goosle-g">G</span>oosle without an authorization key!</p>
<p>Contact the website administrator for more information.</p>
</div>
</body>
</html>

View file

@ -123,10 +123,10 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
</div> </div>
<?php <?php } else { ?>
} else { <div class="auth-error">Redirecting</div>
echo "<div class=\"auth-error\">Goosle</div>"; <meta http-equiv="refresh" content="1; url=<?php echo get_base_url($opts->siteurl); ?>/error.php" />
} <?php } ?>
?>
</body> </body>
</html> </html>

View file

@ -10,12 +10,11 @@
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
abstract class EngineRequest { abstract class EngineRequest {
protected $query, $ch, $mh, $opts, $url, $headers; protected $ch, $mh, $search, $opts, $url, $headers;
function __construct($opts, $mh) { function __construct($search, $opts, $mh) {
$this->query = $opts->query;
$this->mh = $mh; $this->mh = $mh;
// Must be in this order :-/ $this->search = $search;
$this->opts = $opts; $this->opts = $opts;
$this->url = $this->get_request_url(); $this->url = $this->get_request_url();
@ -126,6 +125,6 @@ abstract class EngineRequest {
return $results; return $results;
} }
public static function print_results($results, $opts) {} public static function print_results($results, $search, $opts) {}
} }
?> ?>

View file

@ -10,6 +10,103 @@
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
/*--------------------------------------
// Magnet popup for movies and tv-shows
--------------------------------------*/
function highlight_popup($opts_hash, $highlight) {
$meta = $magnet_meta = array();
$search_query = urlencode($highlight['title']." ".$highlight['year']);
if(isset($highlight['category'])) $meta[] = "<strong>Genre:</strong> ".$highlight['category'];
if(isset($highlight['language'])) $meta[] = "<strong>Language:</strong> ".get_language($highlight['language']);
if(isset($highlight['year'])) $meta[] = "<strong>Released:</strong> ".$highlight['year'];
if(isset($highlight['rating'])) $meta[] = "<strong>Rating:</strong> ".movie_star_rating($highlight['rating'])." <small>(".$highlight['rating']." / 10)</small>";
if(isset($highlight['mpa_rating'])) $meta[] = "<strong>MPA Rating:</strong> ".movie_mpa_rating($highlight['mpa_rating']);
$output = "<div id=\"highlight-".$highlight['id']."\" class=\"goosebox\">";
$output .= " <div class=\"goosebox-body\">";
$output .= " <h2>".$highlight['title']."</h2>";
if(isset($highlight['summary'])) {
$output .= " <p>".$highlight['summary']."</p>";
}
$output .= " <p><a href=\"./results.php?q=".$search_query."&a=".$opts_hash."&t=0\" title=\"Search on Goosle Web Search!\">Search on Goosle</a> &bull; <a href=\"./results.php?q=".$search_query."&a=".$opts_hash."&t=9\" title=\"Search on Goosle Magnet Search! For new additions results may be limited.\">Find more Magnet links</a></p>";
if(!empty($meta)) {
$output .= " <p>".implode('<br />', $meta)."</p>";
}
unset($meta);
// List downloads
$output .= " <h3>Downloads:</h3>";
$output .= " <p>";
foreach($highlight['magnet_links'] as $magnet) {
if(isset($magnet['quality'])) $magnet_meta[] = $magnet['quality'];
if(isset($magnet['audio'])) $magnet_meta[] = $magnet['audio'];
if(isset($magnet['type'])) $magnet_meta[] = $magnet['type'];
$magnet_meta[] = human_filesize($magnet['filesize']);
$output .= "<button class=\"download\" onclick=\"location.href='".$magnet['magnet']."'\">".implode(' / ', $magnet_meta)."</button>";
unset($magnet_meta);
}
$output .= " </p>";
$output .= " <p><a onclick=\"closepopup()\">Close</a></p>";
$output .= " </div>";
$output .= "</div>";
unset($highlight, $magnet, $magnet_meta);
return $output;
}
/*--------------------------------------
// Detect NSFW results by keywords in the title
// True = nsfw, false = not nsfw
--------------------------------------*/
function detect_nsfw($string) {
// Forbidden terms
//Basic pattern: ^cum[-_\s]?play(ing|ed|s)?
$nsfw_keywords = array(
'/(deepthroat|gangbang|cowgirl|dildo|fuck|cuckold|anal|humpfinger|kiss|pegg|fist|ballbust|twerk|dogg|squirt)(ing|ed|s)?/',
'/(yaoi|porn|gonzo|erotica|blowbang|bukkake|gokkun|onlyfans|fansly|manyvids|softcore|hardcore|latex|lingerie|interracial|bdsm|chastity|hogtied|kinky|bondage|shibari|hitachi|upskirt)/',
'/(cock|creampie|cameltoe|enema|nipple|sybian|vibrator|cougar|threesome|foursome|pornstar|escort)(s)?/',
'/(cmnf|cfnm|pov|cbt|bbw|pawg|ssbbw|joi|cei)/',
'/(blow|rim|foot|hand)job(s)?/',
'/(org|puss)(y|ies)\s?/',
'/hentai(ed)?/',
'/jerk(ing)?[-_\s]?off/',
'/tw(i|u)nk(s)?/',
'/cum(bot|ming|s)?/',
'/porn(hub)?/',
'/(m|g)ilf(s)?/',
'/clit(oris|s)?/',
'/tit(ties|s)/',
'/strap[-_\s]?on(ed|s)?/',
'/webcam(ming|s)?/',
'/doggy(style)?/',
'/(masturbat|penetrat)(e|ion|ing|ed)/',
'/face(fuck|sit)?(ing|ting|ed|s)?/',
'/gap(e|ing|ed)?/',
'/scissor(ing|ed)?/',
'/(fetish|penis|ass)(es)?/',
'/(fem|lez|male)dom/',
'/futa(nari)?/',
'/orgasm(ing|ed|s)?/',
'/(slave|pet)[-_\s]?play(ing|ed|s)?/',
'/submissive(d|s)?/',
'/tied[-_\s]?(up)?/',
'/glory[-_\s]?hole(d|s)?/',
'/swing(er|ers|ing)?/',
);
// Replace everything but letters with a space
$string = preg_replace('/\s{2,}|[^a-z0-9]+/', ' ', strtolower($string));
preg_replace($nsfw_keywords, '*', $string, -1 , $count);
return ($count > 0) ? true : false;
}
/*-------------------------------------- /*--------------------------------------
// Depect video quality (720p/1080i etc.) // Depect video quality (720p/1080i etc.)
// Try to standardize terms // Try to standardize terms
@ -73,7 +170,9 @@ function find_video_codec($string) {
$return[] = trim(strtoupper($hdr)); $return[] = trim(strtoupper($hdr));
} }
return implode(' ', $return); if(count($return) > 0) return implode(' ', $return);
return null;
} }
/*-------------------------------------- /*--------------------------------------
@ -123,7 +222,9 @@ function find_audio_codec($string) {
$return[] = ucfirst(trim(strtolower($codec2))); $return[] = ucfirst(trim(strtolower($codec2)));
} }
return implode(' ', $return); if(count($return) > 0) return implode(' ', $return);
return null;
} }
/*-------------------------------------- /*--------------------------------------
@ -140,6 +241,37 @@ function movie_star_rating($rating) {
return $star_rating; return $star_rating;
} }
/*--------------------------------------
// Create visual MPA rating for some magnet results
--------------------------------------*/
function movie_mpa_rating($rating) {
// As described here: https://en.wikipedia.org/wiki/Motion_Picture_Association_film_rating_system
if($rating == "G") {
$rating = "<span class=\"mpa-g\"><strong>G - General Audiences</strong></span> &bull; <em>Suitable for all ages.</em>";
} else if("PG") {
$rating = "<span class=\"mpa-pg\"><strong>PG - Parental Guidance Suggested</strong></span> &bull; <em>May not be suitable for children.</em>";
} else if("PG-13") {
$rating = "<span class=\"mpa-pg13\"><strong>PG-13 - Parents Strongly Cautioned</strong></span> &bull; <em>May be inappropriate for children under 13.</em>";
} else if("R") {
$rating = "<span class=\"mpa-r\"><strong>R - Restricted</strong></span> &bull; <em>Persons under 17 require accompanying adult.</em>";
} else if("NC-17") {
$rating = "<span class=\"mpa-nc17\"><strong>NC-17 - Adults Only</strong></span> &bull; <em>Not suitable for persons under 17.</em>";
} else {
$rating = "<span>".$rating."</span>";
}
return $rating;
}
/*--------------------------------------
// Return the language based on the ISO name
--------------------------------------*/
function get_language($string) {
$languages = array("ab" => "Abkhaz", "aa" => "Afar", "af" => "Afrikaans", "ak" => "Akan", "sq" => "Albanian", "am" => "Amharic", "ar" => "Arabic", "an" => "Aragonese", "hy" => "Armenian", "as" => "Assamese", "av" => "Avaric", "ae" => "Avestan", "ay" => "Aymara", "az" => "Azerbaijani", "bm" => "Bambara", "ba" => "Bashkir", "eu" => "Basque", "be" => "Belarusian", "bn" => "Bengali", "bh" => "Bihari", "bi" => "Bislama", "bs" => "Bosnian", "br" => "Breton", "bg" => "Bulgarian", "my" => "Burmese", "ca" => "Catalan", "ch" => "Chamorro", "ce" => "Chechen", "ny" => "Nyanja", "zh" => "Chinese", "cn" => "Chinese", "cv" => "Chuvash", "kw" => "Cornish", "co" => "Corsican", "cr" => "Cree", "hr" => "Croatian", "cs" => "Czech", "da" => "Danish", "dv" => "Maldivian;", "nl" => "Dutch", "en" => "English", "eo" => "Esperanto", "et" => "Estonian", "ee" => "Ewe", "fo" => "Faroese", "fj" => "Fijian", "fi" => "Finnish", "fr" => "French", "ff" => "Fulah", "gl" => "Galician", "ka" => "Georgian", "de" => "German", "el" => "Greek, Modern", "gn" => "Guaraní", "gu" => "Gujarati", "ht" => "Haitian Creole", "ha" => "Hausa", "he" => "Hebrew (modern)", "hz" => "Herero", "hi" => "Hindi", "ho" => "Hiri Motu", "hu" => "Hungarian", "ia" => "Interlingua", "id" => "Indonesian", "ie" => "Interlingue", "ga" => "Irish", "ig" => "Igbo", "ik" => "Inupiaq", "io" => "Ido", "is" => "Icelandic", "it" => "Italian", "iu" => "Inuktitut", "ja" => "Japanese", "jv" => "Javanese", "kl" => "Kalaallisut", "kn" => "Kannada", "kr" => "Kanuri", "ks" => "Kashmiri", "kk" => "Kazakh", "km" => "Khmer", "ki" => "Kikuyu", "rw" => "Kinyarwanda", "ky" => "Kirghiz, Kyrgyz", "kv" => "Komi", "kg" => "Kongo", "ko" => "Korean", "ku" => "Kurdish", "kj" => "Kwanyama", "la" => "Latin", "lb" => "Luxembourgish", "lg" => "Luganda", "li" => "Limburgish, Limburgan, Limburger", "ln" => "Lingala", "lo" => "Lao", "lt" => "Lithuanian", "lu" => "Luba-Katanga", "lv" => "Latvian", "gv" => "Manx", "mk" => "Macedonian", "mg" => "Malagasy", "ms" => "Malay", "ml" => "Malayalam", "mt" => "Maltese", "mi" => "Māori", "mr" => "Marathi", "mh" => "Marshallese", "mn" => "Mongolian", "na" => "Nauru", "nv" => "Navajo, Navaho", "nb" => "Norwegian Bokmål", "nd" => "North Ndebele", "ne" => "Nepali", "ng" => "Ndonga", "nn" => "Norwegian Nynorsk", "no" => "Norwegian", "ii" => "Nuosu", "nr" => "South Ndebele", "oc" => "Occitan", "oj" => "Ojibwe, Ojibwa", "cu" => "Old Slavonic", "om" => "Oromo", "or" => "Oriya", "os" => "Ossetian", "pa" => "Punjabi", "pi" => "Pāli", "fa" => "Persian", "pl" => "Polish", "ps" => "Pashto, Pushto", "pt" => "Portuguese", "qu" => "Quechua", "rm" => "Romansh", "rn" => "Kirundi", "ro" => "Romanian", "ru" => "Russian", "sa" => "Sanskrit", "sc" => "Sardinian", "sd" => "Sindhi", "se" => "Northern Sami", "sm" => "Samoan", "sg" => "Sango", "sr" => "Serbian", "gd" => "Gaelic", "sn" => "Shona", "si" => "Sinhala", "sk" => "Slovak", "sl" => "Slovene", "so" => "Somali", "st" => "Southern Sotho", "es" => "Spanish", "su" => "Sundanese", "sw" => "Swahili", "ss" => "Swati", "sv" => "Swedish", "ta" => "Tamil", "te" => "Telugu", "tg" => "Tajik", "th" => "Thai", "ti" => "Tigrinya", "bo" => "Tibetan Standard, Tibetan, Central", "tk" => "Turkmen", "tl" => "Tagalog", "tn" => "Tswana", "to" => "Tonga", "tr" => "Turkish", "ts" => "Tsonga", "tt" => "Tatar", "tw" => "Twi", "ty" => "Tahitian", "ug" => "Uighur, Uyghur", "uk" => "Ukrainian", "ur" => "Urdu", "uz" => "Uzbek", "ve" => "Venda", "vi" => "Vietnamese", "vo" => "Volapük", "wa" => "Walloon", "cy" => "Welsh", "wo" => "Wolof", "fy" => "Western Frisian", "xh" => "Xhosa", "yi" => "Yiddish", "yo" => "Yoruba", "za" => "Zhuang, Chuang");
return $languages[$string];
}
/*-------------------------------------- /*--------------------------------------
// Detect TV show Seasons and Episodes in results // Detect TV show Seasons and Episodes in results
--------------------------------------*/ --------------------------------------*/
@ -154,5 +286,4 @@ function is_season_or_episode($search_query, $result_query) {
return true; return true;
} }
?> ?>

View file

@ -1,80 +0,0 @@
<?php
/* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works.
*
* COPYRIGHT NOTICE
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
*
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use.
------------------------------------------------------------------------------------ */
/*--------------------------------------
// Do periodic update check
--------------------------------------*/
function check_update() {
$cache_file = ABSPATH.'cache/version.data';
// Currently installed version
$current_version = "1.5.1";
if(!is_file($cache_file)) {
// Create update cache file if it doesn't exist
$version = array('current' => $current_version, 'latest' => '0.0', 'checked' => 0, 'url' => '');
file_put_contents($cache_file, serialize($version));
} else {
// Get update information
$version = unserialize(file_get_contents($cache_file));
}
// TODO: Remove in a future version
if(!isset($version['current'])) $version['current'] = "1.5.1";
// Update check, every week
if($version['checked'] < time() - 604800) {
$response = do_curl_request(
'https://api.github.com/repos/adegans/goosle/releases/latest', // (string) Where?
array('Accept: application/json, */*;q=0.7', 'User-Agent: goosle/'.$version['current'].';'), // (array) User agent + Headers
'get', // (string) post/get
null // (assoc array|null) Post body
);
$json_response = json_decode($response, true);
// Got a response? Store it!
if(!empty($json_response)) {
// Update version info
$version = array('current' => $version['current'], 'latest' => $json_response['tag_name'], 'checked' => time(), 'url' => $json_response['html_url']);
file_put_contents($cache_file, serialize($version));
}
}
}
/*--------------------------------------
// Show version in footer
--------------------------------------*/
function show_version() {
$cache_file = ABSPATH.'cache/version.data';
if(is_file($cache_file)) {
// Get update information
$version = unserialize(file_get_contents($cache_file));
// TODO: Remove in a future version
if(!isset($version['current'])) $version['current'] = "1.5.1";
// Format current version for footer
$show_version = "<a href=\"https://github.com/adegans/Goosle/\" target=\"_blank\">Goosle ".$version['current']."</a>.";
// Check if a newer version is available and add it to the version display
if(version_compare($version['current'], $version['latest'], '<')) {
$show_version .= " <a href=\"".$version['url']."\" target=\"_blank\" class=\"update\">Version ".$version['latest']." is available!</a>";
}
} else {
// If the update cache doesn't exist...
$show_version = "<a href=\"https://github.com/adegans/Goosle/\" target=\"_blank\">Goosle</a>.";
}
return $show_version;
}
?>

View file

@ -13,8 +13,8 @@
/*-------------------------------------- /*--------------------------------------
// Verify the hash, or not, and let people in, or not // Verify the hash, or not, and let people in, or not
--------------------------------------*/ --------------------------------------*/
function verify_hash($use_hash, $hash, $auth) { function verify_hash($use_hash, $hash, $auth, $is_shared = null) {
if(($use_hash == 'on' && strtolower($hash) === strtolower($auth)) || $use_hash == 'off') return true; if(($use_hash == 'on' && strtolower($hash) === strtolower($auth)) || $use_hash == 'off' || !empty($is_shared)) return true;
return false; return false;
} }
@ -35,38 +35,143 @@ function load_opts() {
$opts = require $config_file; $opts = require $config_file;
// From the url/request // From the url/request
if(!isset($_REQUEST['s'])) { $opts->user_auth = (isset($_REQUEST['a'])) ? sanitize($_REQUEST['a']) : '';
$opts->query = (isset($_REQUEST['q'])) ? trim($_REQUEST['q']) : ''; $opts->pixel = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
$opts->type = (isset($_REQUEST['t'])) ? sanitize($_REQUEST['t']) : 0;
$opts->user_auth = (isset($_REQUEST['a'])) ? sanitize($_REQUEST['a']) : '';
$opts->share = '';
} else {
$share_string = explode('||', base64_url_decode(sanitize($_REQUEST['s'])));
if(is_array($share_string) && count($share_string) === 4) {
$opts->query = trim($share_string[2]);
$opts->type = sanitize($share_string[0]);
$opts->user_auth = sanitize($share_string[1]);
$opts->share = sanitize($share_string[3]);
}
unset($share_string);
}
// Force a few defaults and safeguards // Force a few defaults and safeguards
if(empty($opts->colorscheme)) $opts->colorscheme = 'default'; if(empty($opts->colorscheme)) $opts->colorscheme = 'default';
if($opts->cache_type == 'file' && !is_dir(ABSPATH.'cache/')) $opts->cache_type = 'off'; if($opts->cache_type == 'file' && !is_dir(ABSPATH.'cache/')) $opts->cache_type = 'off';
if($opts->cache_type == 'apcu' && !function_exists('apcu_exists')) $opts->cache_type = 'off'; if($opts->cache_type == 'apcu' && !function_exists('apcu_exists')) $opts->cache_type = 'off';
if($opts->enable_image_search == 'off' && $opts->type == 1) $opts->type = 0;
if($opts->enable_magnet_search == 'off' && $opts->type == 9) $opts->type = 0;
if($opts->cache_time < 1 || ($opts->cache_type == 'apcu' && $opts->cache_time > 8) || ($opts->cache_type == 'file' && $opts->cache_time > 48)) $opts->cache_time = 8; if($opts->cache_time < 1 || ($opts->cache_type == 'apcu' && $opts->cache_time > 8) || ($opts->cache_type == 'file' && $opts->cache_time > 48)) $opts->cache_time = 8;
if(!is_numeric($opts->search_results_per_page) || ($opts->search_results_per_page < 8 || $opts->search_results_per_page > 160)) $opts->social_media_relevance = 24;
if(!is_numeric($opts->social_media_relevance) || ($opts->social_media_relevance > 10 || $opts->social_media_relevance < 0)) $opts->social_media_relevance = 8; if(!is_numeric($opts->social_media_relevance) || ($opts->social_media_relevance > 10 || $opts->social_media_relevance < 0)) $opts->social_media_relevance = 8;
// Remove ! at the start of queries to prevent DDG Bangs (!g, !c and crap like that)
if(substr($opts->query, 0, 1) == '!') $opts->query = substr($opts->query, 1);
return $opts; return $opts;
} }
} }
/*--------------------------------------
// Process search query
--------------------------------------*/
function load_search() {
global $opts;
$search = new stdClass();
// From the url/request
if(!isset($_REQUEST['s'])) {
// Regular search
$search->query = (isset($_REQUEST['q'])) ? trim($_REQUEST['q']) : '';
$search->type = (isset($_REQUEST['t'])) ? sanitize($_REQUEST['t']) : 0;
$search->share = null;
} else {
// Shared result
$share_string = explode('||', base64_url_decode(sanitize($_REQUEST['s'])));
if(is_array($share_string) && count($share_string) === 3) {
$search->query = sanitize($share_string[0]);
$search->type = sanitize($share_string[1]);
$search->share = sanitize($share_string[2]);
} else {
$search->query = '';
$search->type = 0;
$search->share = null;
}
unset($share_string);
}
// Set pagination page
$search->page = (isset($_REQUEST['p'])) ? sanitize($_REQUEST['p']) : 1;
// Remove ! at the start of queries to prevent DDG Bangs (!g, !c and crap like that)
if(substr($search->query, 0, 1) == '!') $search->query = substr($search->query, 1);
// Preserve quotes
$search->query = str_replace('%22', '\"', $search->query);
// Special searches and filters
$search->query_terms = explode(' ', strtolower($search->query)); // Break up query
$search->count_terms = count($search->query_terms); // How many keywords?
// Safe search override
// 0 = off, 1 = normal (default), 2 = on/strict
$search->safe = 1;
if($search->query_terms[0] == 'safe:on') {
$search->safe = 2;
$search->query = trim(str_replace($search->query_terms[0], '', $search->query));
}
if($search->query_terms[0] == 'safe:off' || $search->query_terms[0] == 'xxx' || $search->query_terms[0] == 'porn') {
$search->safe = 0;
$search->query = trim(str_replace($search->query_terms[0], '', $search->query));
}
// Maybe count stats?
if(!empty($search->query)) count_stats();
return $search;
}
/*--------------------------------------
// Do some stats
--------------------------------------*/
function load_stats() {
$stats_file = ABSPATH.'cache/stats.data';
if(!is_file($stats_file)) {
// Create stats file if it doesn't exist
$stats = array('started' => mktime(0, 0, 0, date('m'), date('d'), date('Y')), 'days_active' => 0, 'all_queries' => 0, 'avg_per_day' => 0);
file_put_contents($stats_file, serialize($stats));
} else {
// Get stats
$stats = unserialize(file_get_contents($stats_file));
}
return $stats;
}
function count_stats() {
$stats = load_stats();
// Calculate average searches per day
$new_day = (mktime(0, 0, 0, date('m'), date('d'), date('Y')) - $stats['started']) / 86400;
if($new_day > $stats['days_active']) {
$stats['days_active'] = $stats['days_active'] + 1;
$stats['avg_per_day'] = $stats['all_queries'] / $stats['days_active'];
}
// Count query
$stats['all_queries'] = $stats['all_queries'] + 1;
// Save stats
$stats_file = ABSPATH.'cache/stats.data';
file_put_contents($stats_file, serialize($stats));
}
/*--------------------------------------
// Show version in footer
--------------------------------------*/
function show_version() {
$version_file = ABSPATH.'cache/version.data';
if(is_file($version_file)) {
// Get version information
$version = unserialize(file_get_contents($version_file));
// Format current version for footer
$show_version = "<a href=\"https://github.com/adegans/Goosle/\" target=\"_blank\">Goosle ".$version['current']."</a>.";
// Check if a newer version is available and add it to the version display
if(version_compare($version['current'], $version['latest'], '<')) {
$show_version .= " <a href=\"".$version['url']."\" target=\"_blank\" class=\"update\">Version ".$version['latest']." is available!</a>";
}
} else {
// If the update cache doesn't exist...
$show_version = "<a href=\"https://github.com/adegans/Goosle/\" target=\"_blank\">Goosle</a>.";
}
return $show_version;
}
/*-------------------------------------- /*--------------------------------------
// Standardized cURL requests that support both POST and GET // Standardized cURL requests that support both POST and GET
// For Box Office, Update checks and oAUTH // For Box Office, Update checks and oAUTH
@ -100,6 +205,7 @@ function do_curl_request($url, $headers, $method, $post_fields) {
return $response; return $response;
} }
/*-------------------------------------- /*--------------------------------------
// Load pages into a DOM // Load pages into a DOM
--------------------------------------*/ --------------------------------------*/
@ -113,20 +219,6 @@ function get_xpath($response) {
return $xpath; return $xpath;
} }
/*--------------------------------------
// Format search result urls
--------------------------------------*/
function get_formatted_url($url) {
$url = parse_url($url);
$formatted_url = $url['scheme'] . '://' . $url['host'];
if(array_key_exists('path', $url)) {
$formatted_url .= str_replace('/', ' &rsaquo; ', urldecode(str_replace('%20', ' ', rtrim($url['path'], '/'))));
}
return $formatted_url;
}
/*-------------------------------------- /*--------------------------------------
// Get Goosle's base url // Get Goosle's base url
--------------------------------------*/ --------------------------------------*/
@ -138,7 +230,7 @@ function get_base_url($siteurl) {
} }
/*-------------------------------------- /*--------------------------------------
// URL Safe base64 encoding // URL Safe base64 encoding and decoding
--------------------------------------*/ --------------------------------------*/
function base64_url_encode($input) { function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '-_.'); return strtr(base64_encode($input), '+/=', '-_.');
@ -148,10 +240,6 @@ function base64_url_decode($input) {
return base64_decode(strtr($input, '-_.', '+/=')); return base64_decode(strtr($input, '-_.', '+/='));
} }
function share_encode($opts, $magnet_hash) {
return get_base_url($opts->siteurl).'/results.php?s='.base64_url_encode($opts->type.'||'.$opts->hash.'||'.$opts->query.'||'.$magnet_hash);
}
/*-------------------------------------- /*--------------------------------------
// Result Caching // Result Caching
--------------------------------------*/ --------------------------------------*/
@ -266,7 +354,7 @@ function strip_newlines($string) {
return preg_replace('/<br>|\n/', '', $string); return preg_replace('/<br>|\n/', '', $string);
} }
function limit_string_length($string, $length = 100, $append = '&hellip;') { function limit_string_length($string, $length = 200, $append = '&hellip;') {
$string = trim($string); $string = trim($string);
if(str_word_count($string, 0) > $length) { if(str_word_count($string, 0) > $length) {
@ -317,9 +405,9 @@ function is_social_media($string) {
|| preg_match('/(?:https?:)?\/\/(?:[\w]+\.)?linkedin\.com\/(?P<company_type>(company)|(school))\/(?P<company_permalink>[A-z0-9-À-ÿ\.]+)\/?/', $string) || preg_match('/(?:https?:)?\/\/(?:[\w]+\.)?linkedin\.com\/(?P<company_type>(company)|(school))\/(?P<company_permalink>[A-z0-9-À-ÿ\.]+)\/?/', $string)
|| preg_match('/(?:https?:)?\/\/(?:[\w]+\.)?linkedin\.com\/feed\/update\/urn:li:activity:(?P<activity_id>[0-9]+)\/?/', $string) || preg_match('/(?:https?:)?\/\/(?:[\w]+\.)?linkedin\.com\/feed\/update\/urn:li:activity:(?P<activity_id>[0-9]+)\/?/', $string)
|| preg_match('/(?:https?:)?\/\/(?:[\w]+\.)?linkedin\.com\/in\/(?P<permalink>[\w\-\_À-ÿ%]+)\/?/', $string) || preg_match('/(?:https?:)?\/\/(?:[\w]+\.)?linkedin\.com\/in\/(?P<permalink>[\w\-\_À-ÿ%]+)\/?/', $string)
// || preg_match('/(?:https?:)?\/\/(?:[A-z]+\.)?youtube.com\/(?:c(?:hannel)?)\/(?P<id>[A-z0-9-\_]+)\/?/', $string) || preg_match('/(?:https?:)?\/\/(?:[A-z]+\.)?youtube.com\/(?:c(?:hannel)?)\/(?P<id>[A-z0-9-\_]+)\/?/', $string)
|| preg_match('/(?:https?:)?\/\/(?:[A-z]+\.)?youtube.com\/(?:u(?:ser)?)\/(?P<username>[A-z0-9]+)\/?/', $string) || preg_match('/(?:https?:)?\/\/(?:[A-z]+\.)?youtube.com\/(?:u(?:ser)?)\/(?P<username>[A-z0-9]+)\/?/', $string)
// || preg_match('/(?:https?:)?\/\/(?:(?:www\.)?youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)(?P<id>[A-z0-9\-\_]+)/', $string) || preg_match('/(?:https?:)?\/\/(?:(?:www\.)?youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)(?P<id>[A-z0-9\-\_]+)/', $string)
) return true; ) return true;
return false; return false;
@ -328,23 +416,21 @@ function is_social_media($string) {
/*-------------------------------------- /*--------------------------------------
// Search suggestions // Search suggestions
--------------------------------------*/ --------------------------------------*/
function search_suggestion($opts, $results) { function search_suggestion($search, $opts, $results) {
$specific_result = $specific_result2 = ''; $specific_result = $specific_result2 = '';
if(array_key_exists('search_specific', $results)) { if(($search->type == 0 || $search->type == 1) && count($results['search_specific']) > 1) {
if($opts->type == 3 && count($results['search_specific']) > 1) { // Format query url
// Format query url $search_specific_url2 = "./results.php?q=".urlencode($results['search_specific'][1])."&t=".$search->type."&a=".$opts->hash;
$search_specific_url2 = './results.php?q='.urlencode($results['search_specific'][1]).'&t='.$opts->type.'&a='.$opts->hash; $specific_result2 = " or <a href=\"".$search_specific_url2."\">".$results['search_specific'][1]."</a>";
$specific_result2 = ' or <a href="'.$search_specific_url2.'">'.$results['search_specific'][1].'</a>';
}
// Format query url
$search_specific_url = './results.php?q='.urlencode($results['search_specific'][0]).'&t='.$opts->type.'&a='.$opts->hash;
$specific_result = '<br /><small>Or instead search for <a href="'.$search_specific_url.'">'.$results['search_specific'][0].'</a>'.$specific_result2.'.</small>';
unset($search_specific_url, $search_specific_url2, $specific_result2);
} }
// Format query url
$search_specific_url = "./results.php?q=".urlencode($results['search_specific'][0])."&t=".$search->type."&a=".$opts->hash;
$specific_result = "Or instead search for <a href=\"".$search_specific_url."\">".$results['search_specific'][0]."</a>".$specific_result2.".";
unset($search_specific_url, $search_specific_url2, $specific_result2);
return $specific_result; return $specific_result;
} }
@ -364,6 +450,46 @@ function search_sources($results) {
return $sources; return $sources;
} }
/*--------------------------------------
// Format search result urls
--------------------------------------*/
function search_formatted_url($url) {
$url = parse_url($url);
$formatted_url = $url['scheme'] . '://' . $url['host'];
if(array_key_exists('path', $url)) {
$formatted_url .= str_replace('/', ' &rsaquo; ', urldecode(str_replace('%20', ' ', rtrim($url['path'], '/'))));
}
return $formatted_url;
}
/*--------------------------------------
// Results pagination
--------------------------------------*/
function search_pagination($search, $opts, $number_of_results) {
$number_of_pages = ceil($number_of_results / $opts->search_results_per_page);
$pagination = "";
if($search->page > 1) {
$prev = $search->page - 1;
$pagination .= "<a href=\"".get_base_url($opts->siteurl)."/results.php?q=".urlencode($search->query)."&t=".$search->type."&a=".$opts->hash."&p=".$prev."\" title=\"Previous page\"><span class=\"arrow-left\"></span></a> ";
}
for($page = 1; $page <= $number_of_pages; $page++) {
$class = ($search->page == $page) ? "current" : "";
$pagination .= "<a href=\"".get_base_url($opts->siteurl)."/results.php?q=".urlencode($search->query)."&t=".$search->type."&a=".$opts->hash."&p=".$page."\" class=\"".$class."\" title=\"To page ".$page."\">".$page."</a> ";
}
if($search->page < $number_of_pages) {
$next = $search->page + 1;
$pagination .= "<a href=\"".get_base_url($opts->siteurl)."/results.php?q=".urlencode($search->query)."&t=".$search->type."&a=".$opts->hash."&p=".$next."\" title=\"Next page\"><span class=\"arrow-right\"></span></a> ";
}
return $pagination;
}
/*-------------------------------------- /*--------------------------------------
// Find and replace the last comma in a string // Find and replace the last comma in a string
--------------------------------------*/ --------------------------------------*/
@ -386,20 +512,29 @@ function human_filesize($bytes, $dec = 2) {
return sprintf("%.{$dec}f ", $bytes / pow(1024, $factor)) . @$size[$factor]; return sprintf("%.{$dec}f ", $bytes / pow(1024, $factor)) . @$size[$factor];
} }
/*-------------------------------------- /*--------------------------------------
// Apply timezone setting // Output and format dates in local time
--------------------------------------*/ --------------------------------------*/
function timezone_offset($timestamp, $timezone_offset) { function the_date($format, $timestamp = null) {
if(strpos($timezone_offset, 'UTC') === false) return $timestamp; global $opts;
if($timezone_offset == 'UTC') return $timestamp;
$offset = preg_replace('/UTC\+?/i', '', $opts->timezone);
if(empty($offset)) $offset = 0;
if(is_null($timestamp) || !is_numeric($timestamp)) $timestamp = time();
$hours = (int) $offset;
$minutes = ($offset - $hours);
$sign = ($offset < 0) ? '-' : '+';
$abs_hour = abs($hours);
$abs_mins = abs($minutes * 60);
$datetime = date_create('@'.$timestamp);
$datetime->setTimezone(new DateTimeZone(sprintf('%s%02d:%02d', $sign, $abs_hour, $abs_mins)));
$timezone_offset = intval(substr($timezone_offset, 3)); return $datetime->format($format);
if($timezone_offset > 0) {
return abs($timestamp + (intval(substr($timezone_offset, 1)) * 3600));
}
if($timezone_offset < 0) {
return abs($timestamp - (intval(substr($timezone_offset, 1)) * 3600));
}
} }
/*-------------------------------------- /*--------------------------------------

View file

@ -3,10 +3,8 @@ if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php'; require ABSPATH.'functions/tools.php';
require ABSPATH.'functions/tools-update.php';
$opts = load_opts(); $opts = load_opts();
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works. * Goosle - The fast, privacy oriented search tool that just works.
* *
@ -18,24 +16,61 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
* liability that might arise from its use. * liability that might arise from its use.
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
* Includes: * Includes:
* - Checking for updates. * - Check for updates.
* - Clearing out old cached results when using the file cache. * - Clear out old cached results when using the file cache.
* - Renewing access token for Openverse (Expires every 12 hours) * - Renew access token for Openverse (Expires every 12 hours)
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
if(verify_hash($opts->hash_auth, $opts->hash, $auth)) { if(verify_hash('on', $opts->hash, $opts->user_auth)) {
// Check for updates /*--------------------------------------
check_update(); // Do update check
echo "Update cache updated!<br />"; --------------------------------------*/
$version_file = ABSPATH.'cache/version.data';
// Currently installed version
$current_version = "1.6";
if(!is_file($version_file)) {
// Create update cache file if it doesn't exist
$version = array('current' => $current_version, 'latest' => '0.0', 'checked' => 0, 'url' => '');
file_put_contents($version_file, serialize($version));
} else {
// Get update information
$version = unserialize(file_get_contents($version_file));
}
// Update check, every week
if($version['checked'] < time() - 604800) {
$response = do_curl_request(
'https://api.github.com/repos/adegans/goosle/releases/latest', // (string) Where?
array('Accept: application/json, */*;q=0.7', 'User-Agent: goosle/'.$version['current'].';'), // (array) User agent + Headers
'get', // (string) post/get
null // (assoc array|null) Post body
);
$json_response = json_decode($response, true);
// Got a response? Store it!
if(!empty($json_response)) {
// Update version info
$version = array('current' => $version['current'], 'latest' => $json_response['tag_name'], 'checked' => time(), 'url' => $json_response['html_url']);
file_put_contents($version_file, serialize($version));
echo "<p>- Checked for updates and update cache updated!</p>";
}
}
/*--------------------------------------
// Clear out old cached files? // Clear out old cached files?
--------------------------------------*/
if($opts->cache_type == 'file') { if($opts->cache_type == 'file') {
delete_cached_results($opts->cache_time); delete_cached_results($opts->cache_time);
echo "Expired file cache results deleted!<br />"; echo "<p>- Expired file cache results deleted!</p>";
} }
// Possibly renew the Openverse access token /*--------------------------------------
// Renew the Openverse access token
--------------------------------------*/
if($opts->enable_image_search == 'on' && $opts->enable_openverse == 'on') { if($opts->enable_image_search == 'on' && $opts->enable_openverse == 'on') {
$token_file = ABSPATH.'cache/token.data'; $token_file = ABSPATH.'cache/token.data';
@ -62,16 +97,16 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
oauth_store_token($token_file, 'openverse', array('client_id' => $registration['client_id'], 'client_secret' => $registration['client_secret'], 'access_token' => $json_response['access_token'], 'expires' => $json_response['expires_in'])); oauth_store_token($token_file, 'openverse', array('client_id' => $registration['client_id'], 'client_secret' => $registration['client_secret'], 'access_token' => $json_response['access_token'], 'expires' => $json_response['expires_in']));
echo "New Openverse token stored!<br />"; echo "<p>- New Openverse token stored!</p>";
} }
} }
unset($response, $json_response); unset($response, $json_response);
} }
} }
} }
echo "No errors on this page? We're done!<br />"; echo "<p><strong>Are there no errors on this page? We're done, you can close the tab/browser.</strong></p>";
} else { } else {
echo "Unauthorized!"; echo "<p>!! Unauthorized !!</p>";
} }
exit; exit;

View file

@ -1,12 +1,4 @@
<?php <?php
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
require ABSPATH.'functions/tools-update.php';
$opts = load_opts();
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works. * Goosle - The fast, privacy oriented search tool that just works.
* *
@ -17,6 +9,14 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
* By using this code you agree to indemnify Arnan de Gans from any * By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
$opts = load_opts();
$search = load_search();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -29,7 +29,7 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
<meta name="referrer" content="no-referrer"/> <meta name="referrer" content="no-referrer"/>
<meta name="description" content="Learn how to use Goosle, the best meta search engine!" /> <meta name="description" content="Learn how to use Goosle, the best meta search engine!" />
<meta property="og:site_name" content="Goosle Search Help" /> <meta property="og:site_name" content="Goosle Search" />
<meta property="og:title" content="Goosle Search Help" /> <meta property="og:title" content="Goosle Search Help" />
<meta property="og:description" content="Learn how to use Goosle, the best meta search engine!" /> <meta property="og:description" content="Learn how to use Goosle, the best meta search engine!" />
<meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/help.php" /> <meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/help.php" />
@ -45,30 +45,30 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
<body class="helppage"> <body class="helppage">
<?php <?php
if(verify_hash($opts->hash_auth, $opts->hash, $auth)) { if(verify_hash($opts->hash_auth, $opts->hash, $opts->user_auth)) {
?> ?>
<div class="header"> <div class="header">
<form action="results.php" method="get" autocomplete="off"> <form action="results.php" method="get" autocomplete="off">
<h1 class="logo"><a href="./?a=<?php echo $opts->hash; ?>"><span class="goosle-g">G</span>oosle</a></h1> <h1 class="logo"><a href="./?a=<?php echo $opts->hash; ?>"><span class="goosle-g">G</span>oosle</a></h1>
<input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($opts->query) > 0) ? htmlspecialchars($opts->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" /> <input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($search->query) > 0) ? htmlspecialchars($search->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" />
<input type="hidden" name="t" value="<?php echo $opts->type; ?>"/> <input type="hidden" name="t" value="<?php echo $search->type; ?>"/>
<input type="hidden" name="a" value="<?php echo $opts->hash; ?>"> <input type="hidden" name="a" value="<?php echo $opts->user_auth; ?>">
</form> </form>
<div class="navigation"> <div class="navigation">
<a class="<?php echo ($opts->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=0">Search</a> <a class="<?php echo ($search->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=0">Search</a>
<?php if($opts->enable_image_search == 'on') { ?> <?php if($opts->enable_image_search == 'on') { ?>
<a class="<?php echo ($opts->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=1" >Images</a> <a class="<?php echo ($search->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=1" >Images</a>
<?php } ?> <?php } ?>
<?php if($opts->enable_news_search == 'on') { ?> <?php if($opts->enable_news_search == 'on') { ?>
<a class="<?php echo ($opts->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=2">News</a> <a class="<?php echo ($search->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=2">News</a>
<?php } ?> <?php } ?>
<?php if($opts->enable_magnet_search == 'on') { ?> <?php if($opts->enable_magnet_search == 'on') { ?>
<a class="<?php echo ($opts->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=9">Magnet links</a> <a class="<?php echo ($search->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=9">Magnet links</a>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
@ -85,8 +85,15 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<p>To try and provide the best results first. Goosle has a simple algorithm to rank results for Web and Image search. It works a little like a scoring system. A result with more points gets a higher ranking.</p> <p>To try and provide the best results first. Goosle has a simple algorithm to rank results for Web and Image search. It works a little like a scoring system. A result with more points gets a higher ranking.</p>
<p>If a website or image is found through multiple search engines it will score higher. Also the amount of matching words in the title and SEO description and a few other bits and bops from the results are considered.</p> <p>If a website or image is found through multiple search engines it will score higher. Also the amount of matching words in the title and SEO description and a few other bits and bops from the results are considered.</p>
<h3>Safe search</h3>
<p>Search defaults to Moderate Safe mode. To override the safe mode, prefix your search with <strong>safe:on</strong> or <strong>safe:off</strong> (example: <strong>safe:off geese gone wild</strong>).<br /><strong>On</strong> will use 'Strict' mode, while <strong>off</strong> will disable safe searching, this may yield results that are unsuitable for workspaces or minors.</p>
<?php if($opts->show_nsfw_magnets == 'off') { ?>
<p>The Not Suitable For Work (NSFW) filter for Magnet results is enabled. This is an attempt to hide adult content from results. Some search engines have categories that can be filtered out. Others rely on keyword matches. Goosle has an extensive list of 'dirty' keywords to try and find adult content and then ignore it. To override the setting use the <strong>safe:off</strong>, <strong>xxx</strong> or <strong>porn</strong> prefix.<br />
For example: Search for <strong>xxx goose on goose action</strong> or <strong>safe:off dirty geese</strong> to include adult content in the results.</p>
<?php } ?>
<h2>Web search</h2> <h2>Web search</h2>
<p>Search defaults to Moderate Safe mode. To override the safe mode, prefix your search with <strong>safe:on</strong> or <strong>safe:off</strong> (example: <strong>safe:on white goose</strong>).<br /><strong>On</strong> will use 'Strict' mode, while <strong>off</strong> will disable safe searching, this may yield results that are unsuitable for workspaces or minors.</p>
<h3>Special Searches</h3> <h3>Special Searches</h3>
<?php if($opts->special['currency'] == 'on') { ?> <?php if($opts->special['currency'] == 'on') { ?>
@ -97,7 +104,7 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<?php if($opts->special['definition'] == 'on') { ?> <?php if($opts->special['definition'] == 'on') { ?>
<h4>Word Definition</h4> <h4>Word Definition</h4>
<p>Look up the meaning of single words. Prefix the word you want to look up with any of the following keywords; <strong>d</strong>, <strong>define</strong>, <strong>mean</strong> or <strong>meaning</strong>.<br /> <p>Look up the meaning of single words. Prefix the word you want to look up with any of the following keywords; <strong>define</strong>, <strong>meaning</strong>.<br />
For example: Searching for <strong>define goose</strong> will do a web search for 'goose' but will also show a dictionary definition highlighted above the search results.</p> For example: Searching for <strong>define goose</strong> will do a web search for 'goose' but will also show a dictionary definition highlighted above the search results.</p>
<?php } ?> <?php } ?>
@ -113,6 +120,12 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
For example: Searching for <strong>php in_array</strong> or <strong>php trim</strong> will show you a brief description, compatible PHP versions and the basic syntax for that function.</p> For example: Searching for <strong>php in_array</strong> or <strong>php trim</strong> will show you a brief description, compatible PHP versions and the basic syntax for that function.</p>
<?php } ?> <?php } ?>
<?php if($opts->special['wordpress'] == 'on') { ?>
<h4>WordPress documentation Search</h4>
<p>Prefix your search with <strong>wordpress</strong> or <strong>wp</strong> to search on wordpress.org for a WordPress function. You can also search for hooks or filters by adding 'hook' as the 2nd keyword.<br />
For example: Searching for <strong>wordpress the_content</strong> or <strong>wp hook admin_init</strong> will show you a brief description and the basic syntax for that function or hook/filter.</p>
<?php } ?>
<p><em><strong>Note:</strong> Special Searches do not work for image, news and magnet search.</em></p> <p><em><strong>Note:</strong> Special Searches do not work for image, news and magnet search.</em></p>
<?php if($opts->enable_image_search == 'on') { ?> <?php if($opts->enable_image_search == 'on') { ?>
@ -120,15 +133,12 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<p>The number of results is not limited but typically yields about 60-100 images. If you've enabled Openverse and Qwant this number in creases a lot, optimally up-to about 150 images.</p> <p>The number of results is not limited but typically yields about 60-100 images. If you've enabled Openverse and Qwant this number in creases a lot, optimally up-to about 150 images.</p>
<p>Goosle Image Search links directly to the web page where the image is displayed, but also tries to link to the actual image itself.</p> <p>Goosle Image Search links directly to the web page where the image is displayed, but also tries to link to the actual image itself.</p>
<p>You can search for images in a general size by adding <strong>size:small</strong>, <strong>size:medium</strong>, <strong>size:large</strong> or <strong>size:xlarge</strong> to the beginning of your search query (example: <strong>size:small huge goose</strong>).</p> <p>You can search for images in a general size by adding <strong>size:small</strong>, <strong>size:medium</strong>, <strong>size:large</strong> or <strong>size:xlarge</strong> to the beginning of your search query (example: <strong>size:small huge goose</strong>).</p>
<p>Image search defaults to Moderate Safe mode. To override the safe mode, prefix your search with <strong>safe:on</strong> or <strong>safe:off</strong> (example: <strong>safe:off geese gone wild</strong>).<br /><strong>On</strong> will use 'Strict' mode, while <strong>off</strong> will disable safe searching, this may yield results that are unsuitable for workspaces or minors.</p>
<p>The result counts for may seem off, for example you get 50 results with 20 from Qwant Images and 60 from Yahoo! Images. Logically this should mean you should see 80 results. However, this simply means that 30 results were found on both search engines and were merged, resulting in 50 results.</p> <p>The result counts for may seem off, for example you get 50 results with 20 from Qwant Images and 60 from Yahoo! Images. Logically this should mean you should see 80 results. However, this simply means that 30 results were found on both search engines and were merged, resulting in 50 results.</p>
<?php } ?> <?php } ?>
<?php if($opts->enable_news_search == 'on') { ?> <?php if($opts->enable_news_search == 'on') { ?>
<h2>News search</h2> <h2>News search</h2>
<p>Look for current and revent news through News Search. Search for any topic and you'll find news from the last month.</p> <p>Look for current and recent news through News Search. Search for any topic and you'll find news from the last 30 days. Search is loosely ranked by post date. Newer news ranks higher.<p>
<p>For current news prefix your search with <strong>today</strong>, <strong>now</strong> or <strong>yesterday</strong> or simply search for those single words if you want 'global' news for today. For example <strong>today where is the goose</strong>. You can also use <strong>recent</strong>, <strong>week</strong>, <strong>month</strong>, <strong>this month</strong>, <strong>year</strong> or <strong>this year</strong>. For example: <strong>recent geese migration</strong>.</p>
<p>Keep in mind: Using these limiting prefixes Goosle will filter out any results that are outside of your search which may result in less or no results at all.</p>
<?php } ?> <?php } ?>
<?php if($opts->enable_magnet_search == 'on') { ?> <?php if($opts->enable_magnet_search == 'on') { ?>
@ -138,17 +148,22 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<p>Goosle will try to provide useful information about the download, which includea; Seeders/Leechers, A link to the torrent page, Download Category, Release year. But may also include the Movie quality (720p, 4K etc.), Movie Runtime and the Download Size along with some other bits and bops if available. Not every website makes this available and all results take a best effort approach.</p> <p>Goosle will try to provide useful information about the download, which includea; Seeders/Leechers, A link to the torrent page, Download Category, Release year. But may also include the Movie quality (720p, 4K etc.), Movie Runtime and the Download Size along with some other bits and bops if available. Not every website makes this available and all results take a best effort approach.</p>
<h3>Searching for TV Shows</h3>
<p>To do a specific search on The Pirate Bay and EZTV you search for IMDb Title IDs. These are numeric IDs prefixed with <strong>tt</strong>. This kind of search is useful when you're looking for a tv show that doesn't have a unique name, or simply if you want to use a specialized tracker for tv shows.</p>
<p>If you know the IMDb Title ID you can search for it through the Magnet search.</p>
<?php if($opts->imdb_id_search == 'on') { ?> <?php if($opts->imdb_id_search == 'on') { ?>
<h3>Searching for TV Shows</h3> <p>If you don't know the Title ID you can do a regular search for <strong>imdb [tv show name]</strong>, for example <strong>imdb Duck and Goose</strong>.<br />
<p>To do a specific search on The Pirate Bay and EZTV you search for IMDb Title IDs. These are numeric IDs prefixed with <strong>tt</strong>. This kind of search is useful when you're looking for a tv show that doesn't have a unique name, or simply if you want to use a specialized tracker for tv shows.</p>
<p>If you already know the Title ID you can search for it through the Magnet search.<br />
If you don't know the Title ID you can do a regular search for <strong>imdb [tv show name]</strong>, for example <strong>imdb Duck and Goose</strong>.<br />
Goosle will detect the IMDb ID from the search results and highlight it in the result as a link. This link offers you to search for downloads through a Magnet Search.</p> Goosle will detect the IMDb ID from the search results and highlight it in the result as a link. This link offers you to search for downloads through a Magnet Search.</p>
<?php } ?> <?php } ?>
<?php if($opts->show_share_option == 'on') { ?> <?php if($opts->show_share_option == 'on') { ?>
<h3>Sharing results</h3> <h3>Sharing results</h3>
<p>You can share a specific Magnet result by clicking on the <strong>share</strong> link that's behind the result information. In the little popup that opens you can copy the result and share or store it anywhere you can paste text - For example in a messenger. This special link will perform the same search as you did yourself and highlight the result that you want to share. Keep in mind that if you run a private installation of Goosle you might be giving uninvited guests access to it, so be mindful of where you post the link.</p> <p>You can share a specific Magnet result by clicking on the <strong>share</strong> link that's behind the result information. In the popup that opens you can copy the link and share or store it anywhere you can paste text - For example in a messenger or note. This special link will perform the same search as you did yourself and highlight the result that you want to share.</p>
<?php if($opts->hash_auth == 'off') { ?>
<p>The links can be shared with anyone since you do not run a private Goosle. Anyone who has the shared link can see the results.</p>
<?php } else { ?>
<p>The links can be shared with anyone but keep in mind that since you run a private installation you might be giving uninvited guests access to it. To prevent this from happening the share link does NOT include the passphrase hash. This means that any guests can see your shared results but searching for new things will not work for them.</p>
<?php } ?>
<?php } ?> <?php } ?>
<h3>Finding specific TV Show episodes and seasons</h3> <h3>Finding specific TV Show episodes and seasons</h3>
@ -160,14 +175,14 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<h3>The box office</h3> <h3>The box office</h3>
<p>Along with Magnet search a Box Office page also appears. This is an overview page of the latest movies and other new downloads available on a few supported torrent sites. The shown results are cached just like regular search results.</p> <p>Along with Magnet search a Box Office page also appears. This is an overview page of the latest movies and other new downloads available on a few supported torrent sites. The shown results are cached just like regular search results.</p>
<p><em><strong>Note:</strong> The things you find through magnet search are not always legal to download due to copyright or local restrictions. If possible, always try to get a legal copy if you found a use for what you downloaded!</em></p> <p><em><strong>Note:</strong> The things you find through magnet search are not always legal to download due to copyright or local restrictions. If possible, try to get a legal copy if you found a use for what you downloaded!</em></p>
<?php } ?> <?php } ?>
<h2>Default search engine</h2> <h2>Default search engine</h2>
<p>In some browsers you can add a custom search engine. To do so use the following link: <strong>https://example.com/results.php?q=%s</strong>.</p> <p>In some browsers you can add a custom search engine. To do so follow the browsers instruction and use the following link: <strong>https://example.com/results.php?q=%s</strong>.</p>
<p>Or if you use the Auth Hash as a password add the <strong>a</strong> argument, like so: <strong>https://example.com/results.php?a=YOUR_HASH&q=%s</strong>.</p> <p>Or if you use the Auth Hash as a password add the <strong>a</strong> argument, like so: <strong>https://example.com/results.php?a=YOUR_HASH&q=%s</strong>. Obviously replace example.com with your actual goosle addesss.</p>
<p>Most browsers ask that you add <strong>%s</strong> for the search query as shown in the examples. If your browser has a different value for this simply replace %s with what your browser requires. <p>Most browsers will instruct you to add <strong>%s</strong> for the search query as shown in the examples. If your browser has a different value for this simply replace %s with what your browser requires.
<h2>Colorschemes</h2> <h2>Colorschemes</h2>
<p>Goose comes with several colorschemes, configurable through the config.php file.</p> <p>Goose comes with several colorschemes, configurable through the config.php file.</p>
@ -177,7 +192,7 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<li>"default" A dark headers and main backgrounds with light search results.</li> <li>"default" A dark headers and main backgrounds with light search results.</li>
<li>"light" More light elements.</li> <li>"light" More light elements.</li>
<li>"dark" More dark elements, some apps would call this dark mode.</li> <li>"dark" More dark elements, some apps would call this dark mode.</li>
<li>"auto" Let the browser decide what to use. This is typically linked to your device its darkmode setting.</li> <li>"auto" Let the browser decide what to use. This is typically linked to the darkmode setting of your device.</li>
</ol> </ol>
<p><small><strong>Acknowledgements:</strong><br />Goosle started as a fork of LibreY, and takes some design cues from DuckDuckGo.com. Goosle is created by <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a> with the intent to make search more productive and fun.</small></p> <p><small><strong>Acknowledgements:</strong><br />Goosle started as a fork of LibreY, and takes some design cues from DuckDuckGo.com. Goosle is created by <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a> with the intent to make search more productive and fun.</small></p>
@ -185,17 +200,17 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<div class="footer grid-container"> <div class="footer grid-container">
<div class="footer-grid"> <div class="footer-grid">
&copy; <?php echo date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>. &copy; <?php echo the_date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>.
</div> </div>
<div class="footer-grid"> <div class="footer-grid">
<a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->hash; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> <a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->hash; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> - <a href="./stats.php?a=<?php echo $opts->hash; ?>">Stats</a>
</div> </div>
</div> </div>
<?php <?php } else { ?>
} else { <div class="auth-error">Redirecting</div>
echo "<div class=\"auth-error\">Goosle</div>"; <meta http-equiv="refresh" content="1; url=<?php echo get_base_url($opts->siteurl); ?>/error.php" />
} <?php } ?>
?>
</body> </body>
</html> </html>

View file

@ -1,10 +1,4 @@
<?php <?php
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
require ABSPATH.'functions/tools.php';
$opts = load_opts();
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works. * Goosle - The fast, privacy oriented search tool that just works.
* *
@ -15,6 +9,12 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
* By using this code you agree to indemnify Arnan de Gans from any * By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
require ABSPATH.'functions/tools.php';
$opts = load_opts();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -43,7 +43,7 @@ $auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
<body class="startpage"> <body class="startpage">
<?php <?php
if(verify_hash($opts->hash_auth, $opts->hash, $auth)) { if(verify_hash($opts->hash_auth, $opts->hash, $opts->user_auth)) {
?> ?>
<div class="content"> <div class="content">
@ -75,10 +75,10 @@ if(verify_hash($opts->hash_auth, $opts->hash, $auth)) {
<?php } ?> <?php } ?>
</div> </div>
<?php <?php } else { ?>
} else { <div class="auth-error">Redirecting</div>
echo "<div class=\"auth-error\">Goosle</div>"; <meta http-equiv="refresh" content="1; url=<?php echo get_base_url($opts->siteurl); ?>/error.php" />
} <?php } ?>
?>
</body> </body>
</html> </html>

View file

@ -1,10 +1,10 @@
<h1><center>Goosle</center></h1> <h1>Goosle</h1>
<h2><center>The best Meta Search Engine to find everything</center></h2> <h2>The best Meta Search Engine to find everything</h2>
Goosle is a fast, privacy oriented search tool that just works. \ Goosle is a fast, privacy oriented search tool that just works. \
It's kept simple so everyone can use it and to make sure it works on most webservers. It's kept simple so everyone can use it and to make sure it works on most webservers.
If you're tired of traditional results from one site like Google search or DuckDuckGo and want to see more at once, Goosle has your back! Goosle searches on several search engine at the same time and shows you the most relevant results through a neat, clean interface. Goosle has **no** distractions, **no** trackers, **no** cookies and **no** bloated libraries, frameworks, dependencies or other things that slow you down. If you're tired of traditional results from one site like Google search or DuckDuckGo and want to see more at once, Goosle has your back! Goosle searches on several search engine at the same time and shows you the most relevant results through a neat, clean interface. Goosle has **no** distractions, **no** trackers, **no** cookies and **no** bloated libraries, frameworks, dependencies or other things that slow you down.
Goosle does Image search which shows results from Yahoo! Images and Openverse. Goosle does Image search which shows results from Yahoo! Images and Openverse.
@ -76,11 +76,12 @@ Execute this cronjob a couple of times per day, recommended is every 8 hours.
Without it, Openverse access will expire and you have to generate a new key every few hours. Without it, Openverse access will expire and you have to generate a new key every few hours.
For low traffic setups or if you do not use Openverse a longer interval of once a day is fine. For low traffic setups or if you do not use Openverse a longer interval of once a day is fine.
If you've enabled the access hash as a password, don't forget to include ?a=YOUR_HASH to the url. The access hash is always required as an access token, don't forget to include ?a=YOUR_HASH to the url.
Cron jobs are usually set up from your hosting dashboard, or through something like DirectAdmin, cPanel or WHM. Cron jobs are commonly set up from your hosting dashboard, or through something like DirectAdmin, cPanel or WHM.
Ask your hosting provider where to find the Cron job scheduler or have them set it up for you if you don't see it. Ask your hosting provider where to find the Cron job scheduler or have them set it up for you if you don't see it.
You can also use something like [cron-job.org](https://cron-job.org/) to trigger the background task remotely. You can also use something like [cron-job.org](https://cron-job.org/) to trigger the background task remotely.
To test, you can also load the url in your browser and trigger the script that way. Look for the onscreen prompts to see what routines are executed.
### Usage examples ### Usage examples
Example for 10 minutes past every 3 hours \ Example for 10 minutes past every 3 hours \
@ -92,7 +93,7 @@ Example for 5 minutes past every 8 hours (I use this on my Goosle) \
Example for every midnight \ Example for every midnight \
`0 0 * * * wget -qO - https://example.com/goosle-cron.php?a=YOUR_HASH` `0 0 * * * wget -qO - https://example.com/goosle-cron.php?a=YOUR_HASH`
Why a few minutes past the hour? Because commonly people run stuff exactly on the hour or some other predictable interval like 15 or 30 minutes. Running things a few minutes later spreads server load. Why a few minutes past the hour? Because most people run stuff exactly on the hour or some other predictable interval like 15 or 30 minutes. Running things a few minutes later spreads server load.
## Authorizing access to the Openverse search API ## Authorizing access to the Openverse search API
This is required to use Openverse Image Search. This is required to use Openverse Image Search.
@ -121,9 +122,39 @@ You can post your questions on Github Discussions or say hi on [Mastodon](https:
### Known "issues" ### Known "issues"
- Duckduckgo sometimes returns a 202 header and no results. I'm not sure what causes that but suspect it's something to do with quotas or a service limitation on their end. - Duckduckgo sometimes returns a 202 header and no results. I'm not sure what causes that but suspect it's something to do with quotas or a service limitation on their end.
- Some crawlers for Magnet searches may return empty results. These are likely quota limits on their end. - Some crawlers for Magnet searches may return empty results. These are likely quota limits on their end.
- Sometimes TV Show episodes on the box office are not properly merged despite all required data matching.
## Changelog ## Changelog
1.6 - July 15, 2024
- NOTICE: config.default.php has changed, update your config.php!!
- [change] Moved magnet popups into combined function
- [change] Better handling of EZTV TV Show data
- [change] Better handling of YTS movie data
- [change] Added 6 new public trackers for Magnets
- [change] Removed regularly unresponsive trackers for Magnets
- [change] Search query string processed before search so all engines don't have to do it individually
- [change] Updated help page
- [new] Special searches can have a note/disclaimer in the lower right corner
- [new] Results pagination for all search tabs (Requires caching to be enabled)
- [new] WordPress function, hook and filter lookup as a special search (See help page)
- [new] Language meta data for some Magnet results
- [new] Try to detect audio codec for EZTV results
- [new] Show MPA Rating for some movie results
- [new] Filter to include NSFW Magnet results or not
- [new] Override NSFW filter with prefix keywords (see config.php)
- [new] Simple search stat counter (Link in footer)
- [tweak] Muted the blue and white text in dark theme a tiny bit
- [tweak] Better light blue header in light theme
- [tweak] Added title and alt attributes to relevant links/images
- [tweak] Removed Magnet search limit of 200 results
- [fix] HTML rendering issues for `<center>` tags in paragraphs
- [fix] Start page buttons in light theme now use the right css variables
- [fix] Properly decode quotes in code snippers for PHP special search
- [fix] Image, News and Magnet search no longer work if they're disabled in config.php
- [fix] 2nd search suggestion not showing if it's available
- [fix] Removed non-functional checking if query is empty in every engine
- [fix] Correctly uses user provided auth hash to keep searching
- [fix] Correctly 'expire' share links for guests so they can not use Goosle beyond seeing the shared results
1.5.1 - June 22, 2024 1.5.1 - June 22, 2024
- [fix] Updated help.php, removed incorrect colorscheme information - [fix] Updated help.php, removed incorrect colorscheme information
- [fix] Typo in text output for goosle-cron.php - [fix] Typo in text output for goosle-cron.php
@ -305,4 +336,4 @@ Goosle started as a fork of LibreY, and ended up as a rewrite and something diff
Search results take design cues from DuckDuckGo and the magnet search has been modified to show more useful information where possible. \ Search results take design cues from DuckDuckGo and the magnet search has been modified to show more useful information where possible. \
Goosle does not index, store or distribute torrent files. If you like, or found a use for, what you downloaded, you should probably buy a legal copy of it. Goosle does not index, store or distribute torrent files. If you like, or found a use for, what you downloaded, you should probably buy a legal copy of it.
The name Goosle comes from my last name with an L added in. Translate it from Dutch. The name Goosle comes from my last name with an L added in. Translate it from Dutch.

View file

@ -1,17 +1,4 @@
<?php <?php
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
require ABSPATH.'functions/search_engine.php';
require ABSPATH.'functions/tools-update.php';
// Blue pixel
$blank_thumb = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOUX3LxDAAE4AJiVKIoaQAAAABJRU5ErkJggg==';
$opts = load_opts();
$auth = (isset($_GET['a'])) ? sanitize($_GET['a']) : $opts->user_auth;
$start_time = microtime(true);
/* ------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works. * Goosle - The fast, privacy oriented search tool that just works.
* *
@ -22,6 +9,16 @@ $start_time = microtime(true);
* By using this code you agree to indemnify Arnan de Gans from any * By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use. * liability that might arise from its use.
------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------ */
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
require ABSPATH.'functions/search_engine.php';
$opts = load_opts();
$search = load_search();
$start_time = microtime(true);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -34,7 +31,7 @@ $start_time = microtime(true);
<meta name="referrer" content="no-referrer"/> <meta name="referrer" content="no-referrer"/>
<meta name="description" content="Check out these Goosle search results!" /> <meta name="description" content="Check out these Goosle search results!" />
<meta property="og:site_name" content="Goosle Search results" /> <meta property="og:site_name" content="Goosle Search" />
<meta property="og:title" content="The best meta search engine" /> <meta property="og:title" content="The best meta search engine" />
<meta property="og:description" content="Check out these Goosle search results!" /> <meta property="og:description" content="Check out these Goosle search results!" />
<meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/results.php" /> <meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/results.php" />
@ -48,7 +45,7 @@ $start_time = microtime(true);
<link rel="stylesheet" type="text/css" href="<?php echo get_base_url($opts->siteurl); ?>/assets/css/<?php echo $opts->colorscheme; ?>.css"/> <link rel="stylesheet" type="text/css" href="<?php echo get_base_url($opts->siteurl); ?>/assets/css/<?php echo $opts->colorscheme; ?>.css"/>
<?php <?php
if($opts->type == "9") { if($search->type == "9") {
echo " <script src='".get_base_url($opts->siteurl)."/assets/js/goose.js' id='goosebox-js'></script>"; echo " <script src='".get_base_url($opts->siteurl)."/assets/js/goose.js' id='goosebox-js'></script>";
} }
?> ?>
@ -56,53 +53,53 @@ $start_time = microtime(true);
<body class="resultspage"> <body class="resultspage">
<?php <?php
if(verify_hash($opts->hash_auth, $opts->hash, $auth)) { if(verify_hash($opts->hash_auth, $opts->hash, $opts->user_auth, $search->share)) {
?> ?>
<div class="header"> <div class="header">
<form action="results.php" method="get" autocomplete="off"> <form action="results.php" method="get" autocomplete="off">
<h1 class="logo"><a href="./?a=<?php echo $opts->hash; ?>"><span class="goosle-g">G</span>oosle</a></h1> <h1 class="logo"><a href="./?a=<?php echo $opts->hash; ?>"><span class="goosle-g">G</span>oosle</a></h1>
<input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($opts->query) > 0) ? htmlspecialchars($opts->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" /> <input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($search->query) > 0) ? htmlspecialchars($search->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" />
<input type="hidden" name="t" value="<?php echo $opts->type; ?>"/> <input type="hidden" name="t" value="<?php echo $search->type; ?>"/>
<input type="hidden" name="a" value="<?php echo $opts->hash; ?>"> <input type="hidden" name="a" value="<?php echo $opts->user_auth; ?>">
</form> </form>
<div class="navigation"> <div class="navigation">
<a class="<?php echo ($opts->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=0">Search</a> <a class="<?php echo ($search->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=0">Search</a>
<?php if($opts->enable_image_search == 'on') { ?> <?php if($opts->enable_image_search == 'on') { ?>
<a class="<?php echo ($opts->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=1" >Images</a> <a class="<?php echo ($search->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=1" >Images</a>
<?php } ?> <?php } ?>
<?php if($opts->enable_news_search == 'on') { ?> <?php if($opts->enable_news_search == 'on') { ?>
<a class="<?php echo ($opts->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=2">News</a> <a class="<?php echo ($search->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=2">News</a>
<?php } ?> <?php } ?>
<?php if($opts->enable_magnet_search == 'on') { ?> <?php if($opts->enable_magnet_search == 'on') { ?>
<a class="<?php echo ($opts->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $opts->query; ?>&a=<?php echo $opts->hash; ?>&t=9">Magnet links</a> <a class="<?php echo ($search->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=9">Magnet links</a>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
<?php <?php
if(!empty($opts->query)) { if(!empty($search->query)) {
// Curl // Curl
$mh = curl_multi_init(); $mh = curl_multi_init();
// Load search script // Load search script
if($opts->type == 0) { if($search->type == 0) {
require ABSPATH.'engines/search.php'; require ABSPATH.'engines/search.php';
$search = new Search($opts, $mh); $search_results = new Search($search, $opts, $mh);
} else if($opts->type == 1) { } else if($search->type == 1) {
require ABSPATH.'engines/search-image.php'; require ABSPATH.'engines/search-image.php';
$search = new ImageSearch($opts, $mh); $search_results = new ImageSearch($search, $opts, $mh);
} else if($opts->type == 2) { } else if($search->type == 2) {
require ABSPATH.'engines/search-news.php'; require ABSPATH.'engines/search-news.php';
$search = new NewsSearch($opts, $mh); $search_results = new NewsSearch($search, $opts, $mh);
} else if($opts->type == 9) { } else if($search->type == 9) {
require ABSPATH.'engines/search-magnet.php'; require ABSPATH.'engines/search-magnet.php';
$search = new MagnetSearch($opts, $mh); $search_results = new MagnetSearch($search, $opts, $mh);
} }
$running = null; $running = null;
@ -114,7 +111,7 @@ if(!empty($opts->query)) {
} }
} while ($running && $status == CURLM_OK); } while ($running && $status == CURLM_OK);
$results = $search->get_results(); $results = $search_results->get_results();
curl_multi_close($mh); curl_multi_close($mh);
@ -122,11 +119,11 @@ if(!empty($opts->query)) {
$results['time'] = number_format(microtime(true) - $start_time, 5, '.', ''); $results['time'] = number_format(microtime(true) - $start_time, 5, '.', '');
// Echoes results and special searches // Echoes results and special searches
$search->print_results($results, $opts); $search_results->print_results($results, $search, $opts);
} else { } else {
echo "<div class=\"warning\">"; echo "<div class=\"warning\">";
echo " <h3>Search query can not be empty!</h3>"; echo " <h3>Search query can not be empty!</h3>";
echo " <p>Not sure what went wrong? Learn more about <a href=\"./help.php?a=".$opts->hash."\" title=\"how to use Goosle!\">how to use Goosle</a>.</p>"; echo " <p>Not sure what went wrong? Learn more about <a href=\"./help.php?a=".$opts->user_auth."\" title=\"how to use Goosle!\">how to use Goosle</a>.</p>";
echo "</div>"; echo "</div>";
} }
?> ?>
@ -134,17 +131,17 @@ if(!empty($opts->query)) {
<div class="footer grid-container"> <div class="footer grid-container">
<div class="footer-grid"> <div class="footer-grid">
&copy; <?php echo date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>. &copy; <?php echo the_date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>.
</div> </div>
<div class="footer-grid"> <div class="footer-grid">
<a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->hash; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> <a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->hash; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> - <a href="./stats.php?a=<?php echo $opts->hash; ?>">Stats</a>
</div> </div>
</div> </div>
<?php <?php } else { ?>
} else { <div class="auth-error">Redirecting</div>
echo "<div class=\"auth-error\">Goosle</div>"; <meta http-equiv="refresh" content="1; url=<?php echo get_base_url($opts->siteurl); ?>/error.php" />
} <?php } ?>
?>
</body> </body>
</html> </html>

99
stats.php Normal file
View file

@ -0,0 +1,99 @@
<?php
/* ------------------------------------------------------------------------------------
* Goosle - The fast, privacy oriented search tool that just works.
*
* COPYRIGHT NOTICE
* Copyright 2023-2024 Arnan de Gans. All Rights Reserved.
*
* COPYRIGHT NOTICES AND ALL THE COMMENTS SHOULD REMAIN INTACT.
* By using this code you agree to indemnify Arnan de Gans from any
* liability that might arise from its use.
------------------------------------------------------------------------------------ */
if(!defined('ABSPATH')) define('ABSPATH', $_SERVER['DOCUMENT_ROOT'] . '/');
date_default_timezone_set('UTC');
require ABSPATH.'functions/tools.php';
$opts = load_opts();
$search = load_search();
$stats = load_stats();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Goosle Search Usage Stats</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="robots" content="noodp,noydir" />
<meta name="referrer" content="no-referrer"/>
<meta name="description" content="How many searches did Google handle?" />
<meta property="og:site_name" content="Goosle Search" />
<meta property="og:title" content="Goosle Search Usage Stats" />
<meta property="og:description" content="How many searches did Google handle?" />
<meta property="og:url" content="<?php echo get_base_url($opts->siteurl); ?>/stats.php" />
<meta property="og:image" content="<?php echo get_base_url($opts->siteurl); ?>/assets/images/goosle.webp" />
<meta property="og:type" content="website" />
<link rel="icon" href="favicon.ico" />
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
<link rel="canonical" href="<?php echo get_base_url($opts->siteurl); ?>/stats.php" />
<link rel="stylesheet" type="text/css" href="<?php echo get_base_url($opts->siteurl); ?>/assets/css/styles.css"/>
<link rel="stylesheet" type="text/css" href="<?php echo get_base_url($opts->siteurl); ?>/assets/css/<?php echo $opts->colorscheme; ?>.css"/>
</head>
<body class="statspage">
<?php
if(verify_hash($opts->hash_auth, $opts->hash, $opts->user_auth)) {
?>
<div class="header">
<form action="results.php" method="get" autocomplete="off">
<h1 class="logo"><a href="./?a=<?php echo $opts->hash; ?>"><span class="goosle-g">G</span>oosle</a></h1>
<input tabindex="1" class="search-field" type="search" value="<?php echo (strlen($search->query) > 0) ? htmlspecialchars($search->query) : "" ; ?>" name="q" /><input tabindex="2" class="button" type="submit" value="Search" />
<input type="hidden" name="t" value="<?php echo $search->type; ?>"/>
<input type="hidden" name="a" value="<?php echo $opts->user_auth; ?>">
</form>
<div class="navigation">
<a class="<?php echo ($search->type == '0') ? 'active ' : ''; ?>tab-search" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=0">Search</a>
<?php if($opts->enable_image_search == 'on') { ?>
<a class="<?php echo ($search->type == '1') ? 'active ' : ''; ?>tab-image" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=1" >Images</a>
<?php } ?>
<?php if($opts->enable_news_search == 'on') { ?>
<a class="<?php echo ($search->type == '2') ? 'active ' : ''; ?>tab-news" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=2">News</a>
<?php } ?>
<?php if($opts->enable_magnet_search == 'on') { ?>
<a class="<?php echo ($search->type == '9') ? 'active ' : ''; ?>tab-magnet" href="./results.php?q=<?php echo $search->query; ?>&a=<?php echo $opts->user_auth; ?>&t=9">Magnet links</a>
<?php } ?>
</div>
</div>
<div class="content">
<h1>Searches</h1>
<p class="text-xxl text-center"><?php echo number_format($stats['all_queries'], 0); ?></p>
<h2>Average per day</h2>
<p class="text-xl text-center"><?php echo number_format($stats['avg_per_day'], 2); ?></p>
</div>
<div class="footer grid-container">
<div class="footer-grid">
&copy; <?php echo the_date('Y'); ?> <?php echo show_version(); ?> By <a href="https://ajdg.solutions/" target="_blank">Arnan de Gans</a>.
</div>
<div class="footer-grid">
<a href="./?a=<?php echo $opts->hash; ?>">Start</a> - <a href="./box-office.php?a=<?php echo $opts->hash; ?>&t=9">Box office</a> - <a href="./help.php?a=<?php echo $opts->hash; ?>">Help</a> - <a href="./stats.php?a=<?php echo $opts->hash; ?>">Stats</a>
</div>
</div>
<?php } else { ?>
<div class="auth-error">Redirecting</div>
<meta http-equiv="refresh" content="1; url=<?php echo get_base_url($opts->siteurl); ?>/error.php" />
<?php } ?>
</body>
</html>