├── README.md ├── SQL-DB ├── khoj-db-empty.sql └── readme.md ├── ai.php ├── api └── index.php ├── assets ├── css │ ├── design.css │ ├── grid.css │ ├── home.css │ ├── search.css │ ├── settings.css │ └── special.css └── img │ ├── khoj.png │ └── logo.png ├── code-formatted.php ├── config └── config.php ├── get.php ├── index.php ├── lang ├── en.php ├── hi.php ├── kd.php ├── lang.php ├── mr.php └── sa.php ├── news ├── en │ └── index.php ├── hi │ └── index.php ├── index.php └── mr │ └── index.php ├── opensearch.xml ├── provider ├── apisites.php ├── get.php ├── github.php ├── images.php ├── sites.php ├── special.php └── video.php ├── search.php ├── settings ├── index.php └── saved.html ├── spider ├── auth.php ├── index.php ├── login.php ├── parser │ ├── en.php │ ├── hi.php │ ├── mr.php │ └── parser.php └── protected.php └── theme ├── body.php ├── footer.php └── header.php /README.md: -------------------------------------------------------------------------------- 1 | # Khoj: A Search Engine with Crawler Written in PHP 2 | 3 | Khoj is a web-based search engine built using PHP, MySQL, and Ajax. It includes a web crawler that can index and retrieve information from websites, as well as a search interface that allows users to search for specific keywords. 4 | 5 | ## Video : 6 | 7 | https://www.youtube.com/watch?v=2xLREplhAyY 8 | 9 | ## Features 10 | - Web crawler that can index and retrieve information from websites 11 | - Search interface that allows users to search for specific keywords 12 | - Image /Video/Sites 13 | - Lightweight and easy to use 14 | - Uses PHP, MySQL, and Ajax 15 | ### Upcoming Features 16 | - Chat interface using langchain + gemini pro api 17 | - chrome extension 18 | 19 | 20 | 21 | ## Requirements 22 | - PHP 7.0 or higher 23 | - MySQL 5.6 or higher 24 | - Apache web server 25 | 26 | ## Installation 27 | Clone the repository using the following command: 28 | 29 | ```git clone https://github.com/Ajinkgupta/khoj.git``` 30 | Create a MySQL database for Khoj and import the db.sql file included in the repository. You can use the following commands to do so: 31 | 32 | 33 | ```mysql -u username -p 34 | CREATE DATABASE khoj; 35 | USE khoj; 36 | source /path/to/db.sql;``` 37 | 38 | 39 | Configure the database credentials in the config.php file by modifying the following lines: 40 | 41 | ``` 42 | $host = "localhost"; 43 | $user = "username"; 44 | $password = "password"; 45 | $database = "khoj";``` 46 | Replace username and password with your MySQL username and password, respectively. 47 | 48 | Upload the project files to your web server. 49 | 50 | Open the index.php file in your web browser to use the search engine. 51 | 52 | 53 | ## Usage 54 | - Enter a keyword in the search bar and click the search button. 55 | - The search engine will retrieve relevant results from the indexed websites. 56 | - Click on a search result to view the website. 57 | -------------------------------------------------------------------------------- /SQL-DB/khoj-db-empty.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 5.2.1 3 | -- https://www.phpmyadmin.net/ 4 | -- 5 | -- Host: 127.0.0.1:3306 6 | -- Generation Time: Mar 08, 2024 at 06:21 PM 7 | -- Server version: 10.6.16-MariaDB-0ubuntu0.22.04.1 8 | -- PHP Version: 8.1.27 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | START TRANSACTION; 12 | SET time_zone = "+00:00"; 13 | 14 | 15 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 16 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 17 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 18 | /*!40101 SET NAMES utf8mb4 */; 19 | 20 | -- 21 | -- Database: `khoj` 22 | -- 23 | 24 | -- -------------------------------------------------------- 25 | 26 | -- 27 | -- Table structure for table `images` 28 | -- 29 | 30 | CREATE TABLE `images` ( 31 | `id` int(11) NOT NULL, 32 | `siteUrl` varchar(512) NOT NULL, 33 | `imageUrl` varchar(512) NOT NULL, 34 | `alt` varchar(512) NOT NULL, 35 | `title` varchar(512) NOT NULL, 36 | `clicks` int(11) NOT NULL DEFAULT 0, 37 | `broken` tinyint(4) NOT NULL DEFAULT 0 38 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 39 | 40 | -- -------------------------------------------------------- 41 | 42 | -- 43 | -- Table structure for table `news_english` 44 | -- 45 | 46 | CREATE TABLE `news_english` ( 47 | `id` int(11) NOT NULL, 48 | `guid` varchar(255) DEFAULT NULL, 49 | `title` text DEFAULT NULL, 50 | `link` varchar(255) DEFAULT NULL, 51 | `pubDate` datetime DEFAULT NULL, 52 | `thumbnail_url` varchar(255) DEFAULT NULL, 53 | `description` text DEFAULT NULL, 54 | `content_encoded` text DEFAULT NULL 55 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 56 | 57 | -- -------------------------------------------------------- 58 | 59 | -- 60 | -- Table structure for table `news_hindi` 61 | -- 62 | 63 | CREATE TABLE `news_hindi` ( 64 | `id` int(11) NOT NULL, 65 | `guid` varchar(255) DEFAULT NULL, 66 | `title` text DEFAULT NULL, 67 | `link` varchar(255) DEFAULT NULL, 68 | `pubDate` datetime DEFAULT NULL, 69 | `thumbnail_url` varchar(255) DEFAULT NULL, 70 | `description` text DEFAULT NULL, 71 | `content_encoded` text DEFAULT NULL 72 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 73 | 74 | -- -------------------------------------------------------- 75 | 76 | -- 77 | -- Table structure for table `news_marathi` 78 | -- 79 | 80 | CREATE TABLE `news_marathi` ( 81 | `id` int(11) NOT NULL, 82 | `title` varchar(255) NOT NULL, 83 | `category` varchar(100) DEFAULT NULL, 84 | `author` varchar(100) DEFAULT NULL, 85 | `pubDate` datetime DEFAULT NULL, 86 | `thumbnail_url` varchar(255) DEFAULT NULL, 87 | `description` text DEFAULT NULL, 88 | `creator` varchar(100) DEFAULT NULL 89 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 90 | 91 | -- -------------------------------------------------------- 92 | 93 | -- 94 | -- Table structure for table `sites` 95 | -- 96 | 97 | CREATE TABLE `sites` ( 98 | `id` int(11) NOT NULL, 99 | `url` varchar(512) NOT NULL, 100 | `title` varchar(512) NOT NULL, 101 | `description` text NOT NULL, 102 | `keywords` varchar(512) NOT NULL, 103 | `clicks` int(11) NOT NULL DEFAULT 0 104 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 105 | 106 | -- -------------------------------------------------------- 107 | 108 | -- 109 | -- Table structure for table `users` 110 | -- 111 | 112 | CREATE TABLE `users` ( 113 | `id` int(11) NOT NULL, 114 | `username` varchar(100) NOT NULL, 115 | `email` varchar(150) NOT NULL, 116 | `password` varchar(255) NOT NULL 117 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 118 | 119 | -- 120 | -- Indexes for dumped tables 121 | -- 122 | 123 | -- 124 | -- Indexes for table `images` 125 | -- 126 | ALTER TABLE `images` 127 | ADD PRIMARY KEY (`id`); 128 | 129 | -- 130 | -- Indexes for table `news_english` 131 | -- 132 | ALTER TABLE `news_english` 133 | ADD PRIMARY KEY (`id`); 134 | 135 | -- 136 | -- Indexes for table `news_hindi` 137 | -- 138 | ALTER TABLE `news_hindi` 139 | ADD PRIMARY KEY (`id`); 140 | 141 | -- 142 | -- Indexes for table `news_marathi` 143 | -- 144 | ALTER TABLE `news_marathi` 145 | ADD PRIMARY KEY (`id`); 146 | 147 | -- 148 | -- Indexes for table `sites` 149 | -- 150 | ALTER TABLE `sites` 151 | ADD PRIMARY KEY (`id`); 152 | 153 | -- 154 | -- Indexes for table `users` 155 | -- 156 | ALTER TABLE `users` 157 | ADD PRIMARY KEY (`id`); 158 | 159 | -- 160 | -- AUTO_INCREMENT for dumped tables 161 | -- 162 | 163 | -- 164 | -- AUTO_INCREMENT for table `images` 165 | -- 166 | ALTER TABLE `images` 167 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 168 | 169 | -- 170 | -- AUTO_INCREMENT for table `news_english` 171 | -- 172 | ALTER TABLE `news_english` 173 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 174 | 175 | -- 176 | -- AUTO_INCREMENT for table `news_hindi` 177 | -- 178 | ALTER TABLE `news_hindi` 179 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 180 | 181 | -- 182 | -- AUTO_INCREMENT for table `news_marathi` 183 | -- 184 | ALTER TABLE `news_marathi` 185 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 186 | 187 | -- 188 | -- AUTO_INCREMENT for table `sites` 189 | -- 190 | ALTER TABLE `sites` 191 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 192 | 193 | -- 194 | -- AUTO_INCREMENT for table `users` 195 | -- 196 | ALTER TABLE `users` 197 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 198 | COMMIT; 199 | 200 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 201 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 202 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 203 | -------------------------------------------------------------------------------- /SQL-DB/readme.md: -------------------------------------------------------------------------------- 1 | 2 | addded database 3 | 4 | Empty database 5 | -------------------------------------------------------------------------------- /ai.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | khoj 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 182 | 183 | 184 |
185 |
186 |
187 | 188 |
189 |
190 | 191 | 192 |
193 |
194 |
195 | 196 |
197 |
198 | 199 | 254 | 255 | 256 | -------------------------------------------------------------------------------- /api/index.php: -------------------------------------------------------------------------------- 1 | getResultsAsJson($page, $pageSize, $term); 19 | 20 | // Output the JSON results 21 | echo $resultsJson; 22 | } else { 23 | // If 'term' parameter is not provided, return an error message 24 | echo json_encode(["error" => "Missing 'term' parameter"]); 25 | } 26 | error_reporting(E_ALL); 27 | ini_set('display_errors', 1); -------------------------------------------------------------------------------- /assets/css/design.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fff; /* White background */ 3 | color: #333; /* Dark text color */ 4 | } 5 | 6 | .home-page { 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | padding: 20px; /* Added some padding for better spacing */ 11 | } 12 | 13 | .logo-home { 14 | display: flex; 15 | justify-content: center; 16 | align-items: center; 17 | padding-top: 70px; 18 | } 19 | 20 | .heading { 21 | font-weight: 300; /* Reduced font weight */ 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | padding: 20px 0; /* Simplified padding */ 26 | color: #333; /* Dark text color */ 27 | } 28 | 29 | .searchContainer { 30 | max-width: 90vw; 31 | } 32 | 33 | .searchbar { 34 | padding: 5px; 35 | border: none; 36 | outline: none; 37 | border-radius: 25px; 38 | background-color: #f4f4f4; /* Light gray background */ 39 | color: #333; /* Dark text color */ 40 | max-width: 90vw; 41 | width: 700px; 42 | } 43 | 44 | .searchBox { 45 | padding: 10px; 46 | font-size: 16px; 47 | border: none; 48 | outline: none; 49 | border-radius: 25px; 50 | background-color: #f4f4f4; 51 | color: #333; 52 | width: 80%; 53 | } 54 | 55 | .searchButton { 56 | padding: 10px; 57 | padding-right: 0px; 58 | float: right; 59 | font-size: 16px; 60 | border: none; 61 | outline: none; 62 | border-radius: 25px; 63 | background-color: #f4f4f4; 64 | color: #333; 65 | width: 15%; 66 | max-width: 50px; 67 | } 68 | 69 | .menu { 70 | padding-top: 20px; 71 | display: flex; 72 | justify-content: center; 73 | } 74 | 75 | .menu-item { 76 | text-decoration: none; 77 | color: #333; 78 | padding: 10px 15px; 79 | border: 2px solid #f4c430; 80 | border-radius: 10px; 81 | margin-right: 10px; 82 | } 83 | 84 | .menu-item:hover { 85 | background-color: #f4c430; 86 | } 87 | 88 | .active { 89 | background-color: #f4c430; 90 | } 91 | 92 | .mainResultsSection { 93 | padding: 10px; 94 | margin: 0 -5px; 95 | } 96 | 97 | .mainResultsSection:after { 98 | content: ""; 99 | display: table; 100 | clear: both; 101 | } 102 | 103 | .resultContainer { 104 | margin-left: 20px; 105 | border: 1px solid #ccc; /* Add a 1px solid border around each result */ 106 | border-radius: 10px; 107 | padding: 10px; 108 | margin-top: 10px; 109 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 110 | background: #fff; 111 | color: #333; 112 | word-wrap: break-word; 113 | float: left; 114 | width: 45%; 115 | padding: 0 10px; 116 | min-height: 130px; 117 | } 118 | 119 | .title { 120 | margin-bottom: 5px; 121 | } 122 | 123 | .title a { 124 | text-decoration: none; 125 | color: #333; 126 | } 127 | 128 | .title a:visited { 129 | color: #800080; 130 | } 131 | 132 | .title a:hover, 133 | .resultsCount { 134 | color: #f4c430; 135 | } 136 | 137 | .url { 138 | color: #808080; 139 | margin-bottom: 5px; 140 | } 141 | 142 | .description { 143 | color: #333; 144 | } 145 | 146 | @media screen and (max-width: 600px) { 147 | .resultContainer { 148 | width: 88%; 149 | display: block; 150 | margin-bottom: 20px; 151 | } 152 | } 153 | 154 | .paginationContainer { 155 | display: flex; 156 | justify-content: center; 157 | align-items: center; 158 | } 159 | 160 | .pageNumber { 161 | display: inline-block; 162 | padding: 5px 10px; 163 | border-radius: 10px; 164 | border: 1px solid #333; 165 | margin: 0 5px; 166 | } 167 | 168 | /* Additional Styles for Grid Layout */ 169 | .grid { 170 | columns: 18rem; 171 | gap: 1rem; 172 | counter-reset: grid; 173 | } 174 | 175 | .item + .item { 176 | margin-top: 1rem; 177 | } 178 | 179 | .item { 180 | break-inside: avoid; 181 | aspect-ratio: 4 / 3; 182 | background: #f4f4f4; /* Light gray background */ 183 | border-radius: 0.75rem; 184 | } 185 | 186 | .item img { 187 | width: 100%; 188 | border-top-right-radius: 0.75rem; 189 | border-top-left-radius: 0.75rem; 190 | } 191 | 192 | .item::before { 193 | counter-increment: grid; 194 | } 195 | 196 | .item a .details { 197 | padding: 10px; 198 | text-decoration: none; 199 | } 200 | 201 | .item a { 202 | text-decoration: none; 203 | } 204 | 205 | .item:nth-child(3n) { 206 | aspect-ratio: 1; 207 | background: #f4f4f4; 208 | } 209 | 210 | .item:nth-child(3n - 1) { 211 | aspect-ratio: 2 / 3; 212 | background: #f4f4f4; 213 | } 214 | -------------------------------------------------------------------------------- /assets/css/grid.css: -------------------------------------------------------------------------------- 1 | 2 | /* Additional Styles for Grid Layout */ 3 | .grid { 4 | columns: 18rem; 5 | gap: 1rem; 6 | counter-reset: grid; 7 | margin-top: 100px; 8 | } 9 | 10 | 11 | 12 | .item + .item { 13 | margin-top: 1rem; 14 | } 15 | 16 | .item { 17 | break-inside: avoid; 18 | border-radius: 10%; 19 | } 20 | 21 | 22 | .item img { 23 | 24 | margin: 20px 4%; 25 | background: #F2F3F7; 26 | cursor: pointer; 27 | transition: 0.3s ease; 28 | box-shadow: 29 | -8px -8px 20px 0px #fff9, 30 | -6px -6px 6px 0px #fff9, 31 | 8px 8px 20px 0px #0001, 32 | 5px 5px 6px 0px #0001, 33 | inset 0px 0px 0px 0px #fff9, 34 | inset 0px 0px 0px 0px #0001, 35 | inset 0px 0px 0px 0px #fff9, 36 | inset 0px 0px 0px 0px #0001; 37 | } 38 | 39 | .item img:active { 40 | box-shadow: 0px 0px 0px 0px #fff9, 41 | 0px 0px 0px 0px #fff9, 42 | 0px 0px 0px 0px #0001, 43 | 0px 0px 0px 0px #0001, 44 | inset -8px -8px 20px 0px #fff9, 45 | inset -5px -5px 6px 0px #fff9, 46 | inset 8px 8px 20px 0px #0003, 47 | inset 5px 5px 6px 0px #0001; 48 | } 49 | 50 | .item img { 51 | width: 100%; 52 | border-radius: 10%; 53 | } 54 | 55 | .item::before { 56 | counter-increment: grid; 57 | } 58 | 59 | 60 | .item a .details { 61 | 62 | text-decoration: none; 63 | display: none; 64 | } 65 | 66 | 67 | .item .details { 68 | text-decoration: none; 69 | display:none; 70 | } -------------------------------------------------------------------------------- /assets/css/home.css: -------------------------------------------------------------------------------- 1 | 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | 7 | } 8 | 9 | body{ 10 | background-color: #FCEED5;} 11 | .wrapper { 12 | width: 100%; 13 | height: 100vh; 14 | background-color: #FCEED5; 15 | float: left; 16 | font-family: 'Crimson Text', 'Times New Roman', serif; 17 | } 18 | 19 | .icon { 20 | width: 90%; 21 | margin: auto; 22 | } 23 | 24 | .icon p { 25 | font-size: 12px; 26 | font-weight: 800; 27 | color: #5a6674; 28 | position: absolute; 29 | margin-top: 10px; 30 | } 31 | 32 | .icon i { 33 | float: right; 34 | font-size: 12px; 35 | color: #5a6674; 36 | font-weight: 800; 37 | padding: 10px 2px 0 0; 38 | 39 | } 40 | 41 | .icon-2 { 42 | width: 90%; 43 | margin: 40px auto; 44 | } 45 | 46 | .icon-2 i { 47 | font-size: 20px; 48 | color: #5a6674; 49 | font-weight: 400; 50 | } 51 | 52 | .right-ell { 53 | float: right; 54 | margin: 5px 4% 0 0; 55 | } 56 | 57 | .khoj { 58 | width: 90%; 59 | margin: auto; 60 | text-align: center; 61 | font-weight: 700; 62 | letter-spacing: -6px; 63 | } 64 | 65 | 66 | .logo-home { 67 | width: 90%; 68 | margin: auto; 69 | text-align: center; 70 | } 71 | 72 | .logo-home img { 73 | width: 400px !important; 74 | } 75 | 76 | #search-results { 77 | width: 90%; 78 | margin: auto; 79 | 80 | } 81 | 82 | .search-form { 83 | border: 2px solid #ebecf0; 84 | background: linear-gradient(160deg, #f0f1f4 0%, #e4e6eb 100%); 85 | box-shadow: -3px -3px 6px 2px #ffffff, 5px 5px 8px 0px rgba(0, 0, 0, 0.17), 86 | 1px 2px 2px 0px rgba(0, 0, 0, 0.1); 87 | transition: 0.1s; 88 | 89 | position: relative; 90 | max-width: 90vw; 91 | width: 700px; 92 | padding: 10px; 93 | height: 60px; 94 | border-radius: 40px; 95 | margin-top: 10px; 96 | 97 | } 98 | 99 | .search-form:hover { 100 | box-shadow: 0 3px 4px rgba(0, 0, 0, 0.15); 101 | } 102 | 103 | .search-input { 104 | position: absolute; 105 | left: 35px; 106 | font-size: 14px; 107 | background: none; 108 | color: #5a6674; 109 | width: 90%; 110 | margin-left: 10px; 111 | height: 40px; 112 | border: none; 113 | appearance: none; 114 | outline: none; 115 | background: transparent; 116 | } 117 | 118 | .search-button { 119 | position: absolute; 120 | left: 18px; 121 | top: 18px; 122 | 123 | font-size: 18px; 124 | height: 20px; 125 | width: 10px; 126 | padding: 0; 127 | margin: 0; 128 | color: #5a6674; 129 | border: none; 130 | background: none; 131 | outline: none !important; 132 | cursor: pointer; 133 | } 134 | 135 | 136 | .icon-button { 137 | width: 90%; 138 | margin: auto; 139 | text-align: center; 140 | } 141 | 142 | .fa-gear{border: 2px solid #ebecf0; 143 | background: linear-gradient(160deg, #f0f1f4 0%, #e4e6eb 100%); 144 | box-shadow: -3px -3px 6px 2px #ffffff, 5px 5px 8px 0px rgba(0, 0, 0, 0.17), 145 | 1px 2px 2px 0px rgba(0, 0, 0, 0.1); 146 | padding:5px!important; 147 | transition: 0.1s; border-radius: 100px; font-size:30px!important;} 148 | 149 | .dropdown {border: 2px solid #ebecf0; 150 | background: linear-gradient(160deg, #f0f1f4 0%, #e4e6eb 100%); 151 | box-shadow: -3px -3px 6px 2px #ffffff, 5px 5px 8px 0px rgba(0, 0, 0, 0.17), 152 | 1px 2px 2px 0px rgba(0, 0, 0, 0.1); 153 | padding:5px!important; 154 | transition: 0.1s; border-radius: 100px; font-size:20px!important;} 155 | 156 | .fa-gear.active, 157 | .fa-gear:focus { 158 | border: 2px solid #fafafa; 159 | outline: none; 160 | box-shadow: inset -3px -3px 5px 0px #ffffff, -1px -1px 4px 0px #ffffff, 161 | inset 5px 5px 10px 0px rgba(0, 0, 0, 0.12), 162 | inset 2px 2px 3px 0px rgba(0, 0, 0, 0.07), 163 | 1px 2px 3px 0px rgba(0, 0, 0, 0.1); 164 | } 165 | 166 | 167 | 168 | 169 | 170 | .searchButton ,.searchBox ,.morph { 171 | background:white!important;} 172 | 173 | .button-icons { 174 | width: 50px; 175 | height: 50px; 176 | float: left; 177 | border-radius: 50%; 178 | margin: 20px 4%; 179 | text-align: center; 180 | line-height: 50px; 181 | background: #F2F3F7; 182 | cursor: pointer; 183 | transition: 0.3s ease; 184 | box-shadow: 185 | -8px -8px 20px 0px #fff9, 186 | -6px -6px 6px 0px #fff9, 187 | 8px 8px 20px 0px #0001, 188 | 5px 5px 6px 0px #0001, 189 | inset 0px 0px 0px 0px #fff9, 190 | inset 0px 0px 0px 0px #0001, 191 | inset 0px 0px 0px 0px #fff9, 192 | inset 0px 0px 0px 0px #0001; 193 | position: relative; 194 | } 195 | 196 | .button-icons:active { 197 | box-shadow: 0px 0px 0px 0px #fff9, 198 | 0px 0px 0px 0px #fff9, 199 | 0px 0px 0px 0px #0001, 200 | 0px 0px 0px 0px #0001, 201 | inset -8px -8px 20px 0px #fff9, 202 | inset -5px -5px 6px 0px #fff9, 203 | inset 8px 8px 20px 0px #0003, 204 | inset 5px 5px 6px 0px #0001; 205 | } 206 | 207 | .button-icons i { 208 | font-size: 20px; 209 | color: #097EFF; 210 | } 211 | 212 | .more { 213 | width: 18%; 214 | height: 50px; 215 | margin: 15px 40%; 216 | } 217 | 218 | .more i { 219 | color: #FD8416; 220 | font-size: 20px; 221 | line-height: 50px; 222 | } 223 | 224 | .button-icons p { 225 | position: absolute; 226 | font-size: 13px; 227 | color: #5a6674; 228 | font-weight: 600; 229 | top: 40px; 230 | left: 13px; 231 | } 232 | h1 { 233 | font-size: 36px; 234 | word-spacing: 10px; 235 | letter-spacing: 2px; 236 | } 237 | 238 | 239 | @media screen and (max-width: 768px) { 240 | h1 { 241 | font-size: 32px; 242 | } 243 | } 244 | 245 | @media screen and (max-width: 576px) { 246 | h1 { 247 | font-size: 28px; 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /assets/css/search.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | font-family: 'Noto Sans Devanagari', sans-serif; 4 | } 5 | .active{ background-color: #f4c430; 6 | color:black;} 7 | 8 | .khoj.fixed { 9 | position: fixed; 10 | top: 0; 11 | left: 0; 12 | right:0; 13 | z-index:999; 14 | } 15 | 16 | #result .siteResults { 17 | display: flex; 18 | flex-wrap: wrap; 19 | justify-content: space-between; 20 | } 21 | 22 | #result .resultContainer { 23 | 24 | border: 2px solid #ebecf0; 25 | background: linear-gradient(160deg, #f0f1f4 0%, #e4e6eb 100%); 26 | box-shadow: -3px -3px 6px 2px #ffffff, 5px 5px 8px 0px rgba(0, 0, 0, 0.17), 27 | 1px 2px 2px 0px rgba(0, 0, 0, 0.1); 28 | padding:5px!important; 29 | transition: 0.1s; border-radius: 20px; font-size:20px!important; 30 | width: calc(50% - 50px); /* Two columns, with spacing */ 31 | margin: 10px; 32 | 33 | 34 | 35 | 36 | } 37 | 38 | 39 | .resultcontainer:hover { 40 | box-shadow: 0px 0px 0px 0px #fff9, 41 | 0px 0px 0px 0px #fff9, 42 | 0px 0px 0px 0px #0001, 43 | 0px 0px 0px 0px #0001, 44 | inset -8px -8px 20px 0px #fff9, 45 | inset -5px -5px 6px 0px #fff9, 46 | inset 8px 8px 20px 0px #0003, 47 | inset 5px 5px 6px 0px #0001; 48 | } 49 | 50 | .title { 51 | font-size: 18px; 52 | } 53 | 54 | .url { 55 | color: #0077cc; 56 | white-space: nowrap; 57 | overflow: hidden; 58 | text-overflow: ellipsis; 59 | max-width: 100%; 60 | display: block; 61 | } 62 | 63 | 64 | .description { 65 | display: block; 66 | color: #555; 67 | padding:5px 0 50px 0; 68 | } 69 | 70 | @media (max-width: 468px) { 71 | .resultContainer { 72 | width: 100%; 73 | } 74 | } 75 | 76 | .resultContainer { 77 | /* Your existing styles */ 78 | position: relative; 79 | margin-bottom:30px; 80 | 81 | } 82 | .favicon-container { 83 | position: absolute; 84 | bottom: 10; 85 | left:10; 86 | display: flex; 87 | align-items: center; 88 | background: white; 89 | padding: 5px; 90 | border: 1px solid #ccc; 91 | border-radius: 30px; 92 | box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.1); 93 | color:black; 94 | } 95 | 96 | .saveButton { 97 | float:right; 98 | background: white; 99 | padding: 5px; 100 | border: 1px solid #ccc; 101 | border-radius: 30px; 102 | box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.1); 103 | color:black;} 104 | 105 | .loadMoreButton { 106 | 107 | background: white; 108 | padding: 5px; 109 | border: 1px solid #ccc; 110 | border-radius: 30px; 111 | box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.1); 112 | color:black;} 113 | 114 | .favicon { 115 | width: 32px; 116 | height: 32px; 117 | border-radius:50px; 118 | border:1 px solid orange; 119 | 120 | } -------------------------------------------------------------------------------- /assets/css/settings.css: -------------------------------------------------------------------------------- 1 | .reason { 2 | color: white; 3 | border-radius: 20px; 4 | margin-top: 10px; 5 | font-weight: 900; 6 | padding: 5px; 7 | background: #555; 8 | } 9 | 10 | body{ 11 | background-color: #FCEED5 !important;} 12 | .clear-button { 13 | background: orange; 14 | } -------------------------------------------------------------------------------- /assets/css/special.css: -------------------------------------------------------------------------------- 1 | .special-results { 2 | background: #f4f4f4; /* Background color for the card */ 3 | padding: 20px; /* Padding inside the card */ 4 | border: 1px solid #ccc; /* Border */ 5 | border-radius: 10px; /* Rounded corners */ 6 | transition: 0.3s ease; 7 | box-shadow: 8 | -8px -8px 20px 0px #fff9, 9 | -6px -6px 6px 0px #fff9, 10 | 8px 8px 20px 0px #0001, 11 | 5px 5px 6px 0px #0001, 12 | inset 0px 0px 0px 0px #fff9, 13 | inset 0px 0px 0px 0px #0001, 14 | inset 0px 0px 0px 0px #fff9, 15 | inset 0px 0px 0px 0px #0001; 16 | 17 | margin-bottom:20px; 18 | } 19 | 20 | 21 | 22 | 23 | h2 { 24 | font-size: 20px; /* Heading font size */ 25 | color: #333; /* Heading text color */ 26 | } 27 | 28 | p { 29 | font-size: 16px; /* Paragraph font size */ 30 | color: #555; /* Paragraph text color */ 31 | } 32 | 33 | audio { 34 | margin-top: 10px; /* Spacing for audio player */ 35 | } 36 | -------------------------------------------------------------------------------- /assets/img/khoj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ajinkgupta/khoj-Ai-Search-Engine/67195f74bcbe5fff901afb0f363b1f4efaadee4b/assets/img/khoj.png -------------------------------------------------------------------------------- /assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ajinkgupta/khoj-Ai-Search-Engine/67195f74bcbe5fff901afb0f363b1f4efaadee4b/assets/img/logo.png -------------------------------------------------------------------------------- /code-formatted.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= $translations['title'] ?> 6 | 7 | 8 | 9 | 10 | 12 | 13 | 14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 |
22 | 28 |
29 |
30 |
31 |
32 |
33 | <?= $translations['logo_alt'] ?> 34 |
35 |

36 | 37 |
38 | 39 | 42 |
43 | 44 | 45 |
46 |
47 |
48 | 49 |

50 | Flight

51 |
52 |
53 | 54 |

55 | Twitter

56 |
57 |
58 | 59 |

60 | Flight

61 |
62 |
63 | 64 |

65 | Taxi

66 |
67 |
68 | 69 |

70 | Android

71 |
72 |
73 | 74 |

75 | Gmail

76 |
77 |
78 | 79 |

80 | Hotels

81 |
82 |
83 | 84 |

85 | Events

86 |
87 | 88 |
89 |
90 |
91 | 92 | 93 | -------------------------------------------------------------------------------- /config/config.php: -------------------------------------------------------------------------------- 1 | setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 12 | 13 | } catch (PDOException $e) { 14 | echo "Connection failed: " . $e->getMessage(); 15 | } 16 | 17 | header('Content-Type: text/html; charset=utf-8'); 18 | ?> 19 | -------------------------------------------------------------------------------- /get.php: -------------------------------------------------------------------------------- 1 | getNumResults($term); 22 | } 23 | 24 | $resultsHtml = $resultsProvider->getResultsHtml($page, $pageSize, $term); 25 | 26 | if ($page > 1) { 27 | echo $resultsHtml; 28 | exit(); 29 | } 30 | ?> 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 139 | <?= $translations['title'] ?> 140 | 141 | 142 |
143 |
144 |
145 |
146 |

147 | 148 | 149 |
150 |
151 |
152 |
153 |
154 |
155 | 156 | 160 |
161 | 317 | 318 | 319 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <?= $translations['title'] ?> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 |
23 |
24 |
25 | 26 |
27 |
28 |
29 |
30 | 38 |
39 |
40 |
41 |
42 | <?= $translations['logo_alt'] ?> 44 |

45 |
46 |
47 |
48 |
49 | 51 | 54 |
55 |
56 |
57 | 80 | 86 |
87 |
88 | 89 | 99 | 108 | 109 | -------------------------------------------------------------------------------- /lang/en.php: -------------------------------------------------------------------------------- 1 | 'SEARCH', 4 | 'heading' => 'Search without a trace', 5 | 'search_placeholder' => 'Search securely ...', 6 | 'logo_title' => 'Site Logo', 7 | 'logo_alt' => 'Site logo', 8 | 'description' => 'Search the Web without being tracked with SEARCH.', 9 | 'keywords' => 'search engine, Search, websites', 10 | 'button_text' => 'Search', 11 | 'latest_news' => 'Latest News', 12 | 'result_count' => 'Results Found', 13 | 'load_more' => 'Load More', 14 | 'save' => 'Save', 15 | 'saved' => 'Saved', 16 | 'settings' => 'Search Settings', 17 | 'settings_text' => 'Click the button below to clear all local storage and sessions', 18 | 'end' => 'End Session', 19 | 'choose_lang' => 'Select Language', 20 | 'delete_all' => 'Delete All', 21 | 'not_saved_found' => 'No saved results found', 22 | 'news_title' => 'News - SEARCH', 23 | 'no_news' => 'No news items found', 24 | ]; 25 | ?> 26 | -------------------------------------------------------------------------------- /lang/hi.php: -------------------------------------------------------------------------------- 1 | 'खोज', 4 | 'heading' => 'बिना किसी परेशानी के खोजें', 5 | 'search_placeholder' => 'सुरक्षित रूप से खोजें...', 6 | 'logo_title' => 'साइट का लोगो', 7 | 'logo_alt' => 'साइट का लोगो', 8 | 'description' => 'खोजें वेब , KHOJ के साथ।', 9 | 'keywords' => 'खोज इंजन, KHOJ, वेबसाइटें', 10 | 'button_text' => 'खोजें', 11 | 'latest_news' => 'नवीनतम समाचार', 12 | 'result_count' => 'परिणाम मिले', 13 | 'load_more' => 'और लोड करें', 14 | 'save' => 'सहेजें', 15 | 'saved' => 'सहेजा गया', 16 | 'settings' => 'खोज सेटिंग्स', 17 | 'settings_text' => 'स्थानीय संग्रह और सत्र सभी को साफ करने के लिए नीचे दिए गए बटन पर क्लिक करें', 18 | 'end' => 'सत्र समाप्त करें', 19 | 'choose_lang' => 'भाषा चुनें', 20 | 'delete_all' => 'सभी को हटाएं', 21 | 'not_saved_found' => 'कोई सहेजे गए परिणाम नहीं मिले', 22 | 'news_title' => 'समाचार - खोज', 23 | 'no_news' => 'कोई समाचार मद्दित नहीं मिले', 24 | ]; 25 | ?> 26 | -------------------------------------------------------------------------------- /lang/kd.php: -------------------------------------------------------------------------------- 1 | 'ಖೋಜ್', 4 | 'heading' => 'ಕುರುಹು ಇಲ್ಲದೆ ಹುಡುಕಿ', 5 | 'search_placeholder' => 'ಸುರಕ್ಷಿತವಾಗಿ ಹುಡುಕಿ...', 6 | 'logo_title' => 'ಸೈಟ್ ಲೋಗೋ', 7 | 'logo_alt' => 'ಸೈಟ್ ಲೋಗೋ', 8 | 'description' => 'KHOJ ನೊಂದಿಗೆ ಟ್ರ್ಯಾಕ್ ಮಾಡದೆಯೇ ವೆಬ್ ಅನ್ನು ಹುಡುಕಿ.', 9 | 'keywords' => 'ಸರ್ಚ್ ಇಂಜಿನ್, KHOJ, ವೆಬ್‌ಸೈಟ್‌ಗಳು', 10 | 'button_text' => 'ಹುಡುಕಾಟ', 11 | 'latest_news' => 'ಇತ್ತೀಚಿನ ಸುದ್ದಿ', 12 | 'result_count' => 'ಫಲಿತಾಂಶಗಳು ಕಂಡುಬಂದಿವೆ', 13 | 'load_more' => 'ಇನ್ನಷ್ಟು ಲೋಡ್ ಮಾಡಿ', 14 | 'save' => 'ಉಳಿಸು', 15 | 'saved' => 'ಉಳಿಸಲಾಗಿದೆ', 16 | 'settings' => 'ಹುಡುಕಾಟ ಸೆಟ್ಟಿಂಗ್‌ಗಳು', 17 | 'settings_text' => 'ಎಲ್ಲಾ ಸ್ಥಳೀಯ ಸಂಗ್ರಹಣೆ ಮತ್ತು ಸೆಷನ್‌ಗಳನ್ನು ತೆರವುಗೊಳಿಸಲು ಕೆಳಗಿನ ಬಟನ್ ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿ', 18 | 'end' => 'ಅಧಿವೇಶನ ಅಂತ್ಯ', 19 | 'choose_lang' => 'ಭಾಷೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ', 20 | 'delete_all' => 'ಎಲ್ಲವನ್ನೂ ಅಳಿಸಿ', 21 | 'not_saved_found' => 'ಯಾವುದೇ ಉಳಿಸಿದ ಫಲಿತಾಂಶಗಳು ಕಂಡುಬಂದಿಲ್ಲ', 22 | 'news_title' => 'ಸುದ್ದಿ - KHOJ', 23 | 'no_news' => 'ಯಾವುದೇ ಸುದ್ದಿ ಐಟಂಗಳು ಕಂಡುಬಂದಿಲ್ಲ', 24 | ]; 25 | ?> 26 | -------------------------------------------------------------------------------- /lang/lang.php: -------------------------------------------------------------------------------- 1 | 32 | 33 | -------------------------------------------------------------------------------- /lang/mr.php: -------------------------------------------------------------------------------- 1 | 'खोज', 4 | 'heading' => 'ट्रेसशिवाय शोधा', 5 | 'search_placeholder' => 'सुरक्षितपणे शोधा...', 6 | 'logo_title' => 'साइट लोगो', 7 | 'logo_alt' => 'साइट लोगो', 8 | 'description' => 'KHOJ सह ट्रॅक न करता वेबवर शोधा.', 9 | 'keywords' => 'शोध इंजिन, KHOJ, वेबसाइट्स', 10 | 'button_text' => 'शोधा', 11 | 'latest_news' => 'ताज्या बातम्या', 12 | 'result_count' => 'परिणाम सापडले', 13 | 'load_more' => 'अधिक लोड करा', 14 | 'save' => 'जतन करा', 15 | 'saved' => 'सेव्ह केले', 16 | 'settings' => 'शोध सेटिंग्ज', 17 | 'settings_text' => 'सर्व स्थानिक स्टोरेज आणि सत्रे साफ करण्यासाठी खालील बटणावर क्लिक करा', 18 | 'end' => 'सत्र समाप्त करा', 19 | 'choose_lang' => 'भाषा निवडा', 20 | 'delete_all' => 'सर्व हटवा', 21 | 'not_saved_found' => 'जतन केलेले परिणाम आढळले नाहीत', 22 | 'news_title' => 'बातमी - KHOJ', 23 | 'no_news' => 'कोणत्याही बातम्या आढळल्या नाहीत', 24 | ]; 25 | ?> 26 | -------------------------------------------------------------------------------- /lang/sa.php: -------------------------------------------------------------------------------- 1 | 'खोज', 4 | 'heading' => 'लेशं विना अन्वेषणम्', 5 | 'search_placeholder' => 'सुरक्षिततया अन्वेषणं कुर्वन्तु ...', 6 | 'logo_title' => 'साइट् लोगो', 7 | 'logo_alt' => 'साइट् लोगो', . 8 | 'description' => 'KHOJ इत्यनेन अनुसृत्य विना जालपुटं अन्वेष्टुम्।', 9 | 'keywords' => 'अन्वेषणयन्त्रम्, KHOJ, वेबसाइट्', 10 | 'button_text' => 'अन्वेषण', . 11 | 'latest_news' => 'नवीनतम समाचार', 12 | 'result_count' => 'परिणामाः प्राप्ताः', 13 | 'load_more' => 'अधिकं भारयतु', 14 | 'save' => 'रक्षतु', . 15 | 'saved' => 'रक्षित', . 16 | 'settings' => 'अन्वेषणसेटिंग्स्', . 17 | 'settings_text' => 'सर्वं स्थानीयं भण्डारणं सत्रं च स्वच्छं कर्तुं अधोलिखितं बटनं नुदन्तु', 18 | 'end' => 'सत्रसमाप्ति', . 19 | 'choose_lang' => 'भाषा चिनोतु', 20 | 'delete_all' => 'सर्वं विलोपयतु', 21 | 'not_saved_found' => 'न रक्षितं परिणामं न प्राप्तम्', 22 | 'news_title' => 'समाचार - KHOJ', 23 | 'no_news' => 'वार्ता न प्राप्ता', 24 | ]; 25 | ?> 26 | -------------------------------------------------------------------------------- /news/en/index.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 11 | $stmt->execute([$id]); 12 | $article = $stmt->fetch(); 13 | 14 | // Check if the main article exists 15 | if ($article) { 16 | $title = $article['title']; 17 | $link = $article['link']; 18 | $pubDate = $article['pubDate']; 19 | $thumbnail_url = $article['thumbnail_url']; 20 | $description = htmlspecialchars_decode($article['description']); 21 | $content_encoded = htmlspecialchars_decode($article['content_encoded']); 22 | 23 | // Fetch three random similar articles (you may need to adjust the query as needed) 24 | $sqlSimilar = "SELECT * FROM news_english WHERE id != ? ORDER BY RAND() LIMIT 3"; 25 | $stmtSimilar = $con->prepare($sqlSimilar); 26 | $stmtSimilar->execute([$id]); 27 | $similarArticles = $stmtSimilar->fetchAll(); 28 | 29 | // HTML for displaying the article and similar articles with Tailwind CSS 30 | echo " 31 | 32 | 33 | 34 | 35 | 36 | $title 37 | 38 | 39 |
40 |
41 |
42 |

$title

43 |
44 | Published Date: $pubDate
45 |
46 | News Thumbnail 47 |
48 | $description 49 |
50 |
51 | $content_encoded 52 |
53 |
54 |
55 |

Similar Articles

56 |
57 | "; 58 | foreach ($similarArticles as $similarArticle) { 59 | $similarTitle = $similarArticle['title']; 60 | $similarLink = $similarArticle['id']; 61 | $similarThumbnail = $similarArticle['thumbnail_url']; 62 | echo ""; 70 | } 71 | echo " 72 |
73 |
74 |
75 |
76 | 77 | "; 78 | } else { 79 | echo "Article not found."; 80 | } 81 | } else { 82 | echo "Invalid request. Please provide an 'id' parameter."; 83 | } 84 | ?> 85 | -------------------------------------------------------------------------------- /news/hi/index.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 11 | $stmt->execute([$id]); 12 | $article = $stmt->fetch(); 13 | 14 | // Check if the main article exists 15 | if ($article) { 16 | $title = $article['title']; 17 | $link = $article['link']; 18 | $pubDate = $article['pubDate']; 19 | $thumbnail_url = $article['thumbnail_url']; 20 | $description = htmlspecialchars_decode($article['description']); 21 | $content_encoded = htmlspecialchars_decode($article['content_encoded']); 22 | 23 | // Fetch three random similar articles (you may need to adjust the query as needed) 24 | $sqlSimilar = "SELECT * FROM news_hindi WHERE id != ? ORDER BY RAND() LIMIT 3"; 25 | $stmtSimilar = $con->prepare($sqlSimilar); 26 | $stmtSimilar->execute([$id]); 27 | $similarArticles = $stmtSimilar->fetchAll(); 28 | 29 | // HTML for displaying the article and similar articles with Tailwind CSS 30 | echo " 31 | 32 | 33 | 34 | 35 | 36 | $title 37 | 38 | 39 |
40 |
41 |
42 |

$title

43 |
44 | Published Date: $pubDate
45 |
46 | News Thumbnail 47 |
48 | $description 49 |
50 |
51 | $content_encoded 52 |
53 |
54 |
55 |

Similar Articles

56 |
57 | "; 58 | foreach ($similarArticles as $similarArticle) { 59 | $similarTitle = $similarArticle['title']; 60 | $similarLink = $similarArticle['id']; 61 | $similarThumbnail = $similarArticle['thumbnail_url']; 62 | echo ""; 70 | } 71 | echo " 72 |
73 |
74 |
75 |
76 | 77 | "; 78 | } else { 79 | echo "Article not found."; 80 | } 81 | } else { 82 | echo "Invalid request. Please provide an 'id' parameter."; 83 | } 84 | ?> 85 | -------------------------------------------------------------------------------- /news/index.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | <?= $translations['news_title'] ?> 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 | 37 |
38 |
39 |
40 |
41 |
42 |
43 | 44 | 47 |
48 |
49 |
50 | 67 | 70 | 'news_english', 74 | 'mr' => 'news_marathi', 75 | 'hi' => 'news_hindi', 76 | 'sa' => 'news_hindi', // Display Hindi news when Sanskrit is selected 77 | ]; 78 | 79 | // Check if the selected language is in the list and display news accordingly 80 | if (isset($tables[$selectedLanguage])) { 81 | $tableName = $tables[$selectedLanguage]; 82 | 83 | // Fetch news data from the corresponding table 84 | $sql = "SELECT * FROM $tableName ORDER BY pubDate DESC"; // Adjust the query as needed 85 | $stmt = $con->prepare($sql); 86 | $stmt->execute(); 87 | $news = $stmt->fetchAll(); 88 | 89 | // Define the number of initial news items to display and the increment for "Load More" 90 | $initialItems = 12; 91 | $increment = 12; 92 | 93 | // Check if there are news items 94 | if (!empty($news)) { 95 | echo "
"; 96 | echo "

$translations[latest_news]

"; 97 | echo "
"; 98 | for ($i = 0; $i < $initialItems && $i < count($news); $i++) { 99 | $item = $news[$i]; 100 | $thumbnail_url = $item['thumbnail_url']; 101 | $title = $item['title']; 102 | $id = $item['id']; 103 | echo ""; 104 | echo "News Thumbnail"; 105 | echo "
"; 106 | echo "

$title

"; 107 | echo "
"; 108 | } 109 | echo "
"; 110 | 111 | // If there are more news items, display the "Load More" button 112 | if (count($news) > $initialItems) { 113 | echo "
"; 114 | echo ""; 115 | echo "
"; 116 | } 117 | } else { 118 | echo "$translations[no_news]"; 119 | } 120 | } 121 | ?> 122 | 123 | 124 |
125 |
126 | 127 | 165 | 166 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /news/mr/index.php: -------------------------------------------------------------------------------- 1 | prepare($sql); 11 | $stmt->execute([$id]); 12 | $article = $stmt->fetch(); 13 | 14 | // Check if the main article exists 15 | if ($article) { 16 | $title = $article['title']; 17 | $category = $article['category']; 18 | $author = $article['author']; 19 | $pubDate = $article['pubDate']; 20 | $thumbnail_url = $article['thumbnail_url']; 21 | $description = htmlspecialchars_decode($article['description']); 22 | $creator = $article['creator']; 23 | 24 | // Fetch three random similar articles (you may need to adjust the query as needed) 25 | $sqlSimilar = "SELECT * FROM news_marathi WHERE id != ? ORDER BY RAND() LIMIT 3"; 26 | $stmtSimilar = $con->prepare($sqlSimilar); 27 | $stmtSimilar->execute([$id]); 28 | $similarArticles = $stmtSimilar->fetchAll(); 29 | 30 | // HTML for displaying the article and similar articles with Tailwind CSS 31 | echo " 32 | 33 | 34 | 35 | 36 | 37 | $title 38 | 39 | 40 |
41 |
42 |
43 |

$title

44 |
45 | Category: $category
46 | Author: $author
47 | Published Date: $pubDate
48 | Creator: $creator 49 |
50 | News Thumbnail 51 |
52 | $description 53 |
54 |
55 |
56 |

Similar Articles

57 |
58 | "; 59 | foreach ($similarArticles as $similarArticle) { 60 | $similarTitle = $similarArticle['title']; 61 | $similarCategory = $similarArticle['category']; 62 | $similarThumbnail = $similarArticle['thumbnail_url']; 63 | echo "
64 | News Thumbnail 65 |
66 | $similarCategory 67 |

$similarTitle

68 |
69 |
"; 70 | } 71 | echo " 72 |
73 |
74 |
75 |
76 | 77 | "; 78 | } else { 79 | echo "Article not found."; 80 | } 81 | } else { 82 | echo "Invalid request. Please provide an 'id' parameter."; 83 | } 84 | ?> 85 | -------------------------------------------------------------------------------- /opensearch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KHOJ 5 | KHOJ 6 | 7 | UTF-8 8 | 9 | -------------------------------------------------------------------------------- /provider/apisites.php: -------------------------------------------------------------------------------- 1 | con = $con; 9 | } 10 | 11 | public function getResultsAsJson($page, $pageSize, $term) 12 | { 13 | // Calculate the starting point for results 14 | $fromLimit = ($page - 1) * $pageSize; 15 | 16 | // Prepare the database query with pagination 17 | $query = $this->con->prepare("SELECT * 18 | FROM sites WHERE title LIKE :term 19 | OR url LIKE :term 20 | OR keywords LIKE :term 21 | OR description LIKE :term 22 | ORDER BY clicks DESC 23 | LIMIT :fromLimit, :pageSize"); 24 | 25 | $searchTerm = "%" . $term . "%"; 26 | $query->bindParam(":term", $searchTerm); 27 | $query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT); 28 | $query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT); 29 | $query->execute(); 30 | 31 | $results = []; 32 | $id = 1; // Start with ID 1 33 | 34 | while ($row = $query->fetch(PDO::FETCH_ASSOC)) { 35 | $url = stripslashes($row["url"]); // Remove backslashes 36 | $title = $row["title"]; 37 | $description = $row["description"]; 38 | 39 | $resultItem = [ 40 | "id" => $id, 41 | "url" => $url, 42 | "title" => $title, 43 | "description" => $description, 44 | ]; 45 | 46 | $results[] = $resultItem; 47 | $id++; 48 | } 49 | 50 | return json_encode($results, JSON_PRETTY_PRINT); 51 | } 52 | } 53 | ?> 54 | -------------------------------------------------------------------------------- /provider/get.php: -------------------------------------------------------------------------------- 1 | getNumResults($term); 33 | } 34 | 35 | // For both initial search and "Load More," get and display the results 36 | $resultsHtml = $resultsProvider->getResultsHtml($page, $pageSize, $term); 37 | 38 | // If it's a "Load More" request, return only the results HTML 39 | if ($page > 1) { 40 | echo $resultsHtml; 41 | exit(); 42 | } 43 | ?> 44 | 45 | 46 | 47 | 48 | 49 | 50 | 55 | 56 | 57 | <?php if(isset($term) && $term != '') echo($term . ' | '); ?>Khoj Search 58 | 78 | 79 | 80 | 81 |
82 | 83 | 86 |
87 | 88 | 89 |
90 |
91 |

results found

92 | 93 |
94 |
95 |
96 |
97 |
98 | 99 | 100 | 101 | 102 | 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /provider/github.php: -------------------------------------------------------------------------------- 1 | searchRepositories($term); 10 | } 11 | 12 | private function searchRepositories($term) 13 | { 14 | // URL for the GitHub API with the search term 15 | $apiUrl = "https://api.github.com/search/repositories?q=" . urlencode($term); 16 | 17 | // Set up cURL to make the HTTP request 18 | $ch = curl_init(); 19 | curl_setopt($ch, CURLOPT_URL, $apiUrl); 20 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 21 | curl_setopt($ch, CURLOPT_HTTPHEADER, [ 22 | 'User-Agent: KHOJ', // Add a user agent header 23 | ]); 24 | 25 | $response = curl_exec($ch); 26 | 27 | // Check for cURL errors 28 | if (curl_errno($ch)) { 29 | $this->githubResults = false; 30 | } 31 | 32 | // Close the cURL handle 33 | curl_close($ch); 34 | 35 | // Decode the JSON response 36 | $data = json_decode($response, true); 37 | 38 | if (!$data) { 39 | $this->githubResults = false; 40 | } else { 41 | // Extract and format the data you need 42 | $results = []; 43 | if (isset($data['items']) && is_array($data['items'])) { 44 | foreach ($data['items'] as $item) { 45 | $result = [ 46 | 'name' => $item['name'], 47 | 'html_url' => $item['html_url'], 48 | 'description' => $item['description'], 49 | ]; 50 | $results[] = $result; 51 | } 52 | } 53 | $this->githubResults = $results; 54 | } 55 | } 56 | 57 | public function getResultsHtml() 58 | { 59 | if ($this->githubResults) { 60 | $resultsHtml = "
"; 61 | foreach ($this->githubResults as $result) { 62 | $name = $result['name']; 63 | $url = $result['html_url']; 64 | $description = $result['description']; 65 | 66 | $resultHtml = "
67 |

68 | 69 | $name 70 | 71 |

72 | $url 73 | $description 74 |
"; 75 | 76 | $resultsHtml .= $resultHtml; 77 | } 78 | $resultsHtml .= "
"; 79 | } else { 80 | $resultsHtml = "Error retrieving GitHub data."; 81 | } 82 | 83 | return $resultsHtml; 84 | } 85 | 86 | public function getNumResults() 87 | { 88 | // The number of GitHub search results is the count of items in the result 89 | return count($this->githubResults); 90 | } 91 | } 92 | ?> -------------------------------------------------------------------------------- /provider/images.php: -------------------------------------------------------------------------------- 1 | con = $con; 9 | } 10 | 11 | public function getNumResults($term) 12 | { 13 | $query = $this->con->prepare("SELECT COUNT(*) as total 14 | FROM images 15 | WHERE (title LIKE :term 16 | OR alt LIKE :term) 17 | AND broken=0"); 18 | 19 | $searchTerm = "%" . $term . "%"; 20 | $query->bindParam(":term", $searchTerm); 21 | $query->execute(); 22 | 23 | $row = $query->fetch(PDO::FETCH_ASSOC); 24 | return $row["total"]; 25 | } 26 | 27 | public function getResultsHtml($page, $pageSize, $term) 28 | { 29 | $fromLimit = ($page - 1) * $pageSize; 30 | 31 | $query = $this->con->prepare("SELECT * 32 | FROM images 33 | WHERE (title LIKE :term 34 | OR alt LIKE :term) 35 | AND broken=0 36 | ORDER BY clicks DESC 37 | LIMIT :fromLimit, :pageSize"); 38 | 39 | $searchTerm = "%" . $term . "%"; 40 | $query->bindParam(":term", $searchTerm); 41 | $query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT); 42 | $query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT); 43 | $query->execute(); 44 | 45 | $resultsHtml = "
"; 46 | 47 | $count = 0; 48 | while ($row = $query->fetch(PDO::FETCH_ASSOC)) 49 | { 50 | $count++; 51 | $id = $row["id"]; 52 | $imageUrl = $row["imageUrl"]; 53 | $siteUrl = $row["siteUrl"]; 54 | $title = $row["title"]; 55 | $alt = $row["alt"]; 56 | 57 | if ($title) 58 | $displayText = $title; 59 | else if ($alt) 60 | $displayText = $alt; 61 | else 62 | $displayText = $imageUrl; 63 | 64 | $resultsHtml .= "
65 | 67 | 68 | $displayText 69 | 70 |
"; 71 | } 72 | 73 | $resultsHtml .= "
"; 74 | 75 | return $resultsHtml; 76 | } 77 | } 78 | ?> 79 | -------------------------------------------------------------------------------- /provider/sites.php: -------------------------------------------------------------------------------- 1 | con = $con; 9 | } 10 | 11 | public function getNumResults($term) 12 | { 13 | $query = $this->con->prepare("SELECT COUNT(*) as total 14 | FROM sites WHERE title LIKE :term 15 | OR url LIKE :term 16 | OR keywords LIKE :term 17 | OR description LIKE :term"); 18 | 19 | $searchTerm = "%" . $term . "%"; 20 | $query->bindParam(":term", $searchTerm); 21 | $query->execute(); 22 | 23 | $row = $query->fetch(PDO::FETCH_ASSOC); 24 | return $row["total"]; 25 | } 26 | 27 | public function getResultsHtml($page, $pageSize, $term) 28 | { 29 | 30 | $fromLimit = ($page - 1) * $pageSize; 31 | 32 | $query = $this->con->prepare("SELECT * 33 | FROM sites WHERE title LIKE :term 34 | OR url LIKE :term 35 | OR keywords LIKE :term 36 | OR description LIKE :term 37 | ORDER BY clicks DESC 38 | LIMIT :fromLimit, :pageSize"); 39 | 40 | $searchTerm = "%" . $term . "%"; 41 | $query->bindParam(":term", $searchTerm); 42 | $query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT); 43 | $query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT); 44 | $query->execute(); 45 | 46 | $resultsHtml = "
"; 47 | 48 | while ($row = $query->fetch(PDO::FETCH_ASSOC)) 49 | { 50 | $id = $row["id"]; 51 | $url = $row["url"]; 52 | $title = $row["title"]; 53 | $description = $row["description"]; 54 | 55 | $title = $this->trimField($title, 500); 56 | $description = $this->trimField($description, 500); 57 | $decodedDescription = $this->decodetext($description); // Decodes HTML entities 58 | 59 | $resultsHtml .= "
60 |

61 | 62 | $title 63 | 64 |

65 | $url 66 | $decodedDescription 67 |
"; 68 | } 69 | 70 | $resultsHtml .= "
"; 71 | 72 | return $resultsHtml; 73 | } 74 | 75 | private function trimField($string, $characterLimit) 76 | { 77 | $dots = strlen($string) > $characterLimit ? "..." : ""; 78 | return substr($string, 0, $characterLimit) . $dots; 79 | } 80 | 81 | private function decodetext($string) 82 | { 83 | return html_entity_decode($string, ENT_QUOTES | ENT_HTML5, 'UTF-8'); 84 | } 85 | } 86 | ?> 87 | -------------------------------------------------------------------------------- /provider/special.php: -------------------------------------------------------------------------------- 1 | '; 6 | echo '

Generated QR Code

'; 7 | echo 'Generated QR Code'; 8 | echo ''; 9 | } 10 | 11 | function getCurrentDateTime($timezone) { 12 | date_default_timezone_set($timezone); 13 | $currentDateTime = date('Y-m-d H:i:s'); 14 | echo '
'; 15 | echo '

Date and Time

'; 16 | echo '

Current date and time: ' . $currentDateTime . '

'; 17 | echo '
'; 18 | } 19 | 20 | function defineWord($word) { 21 | $url = "https://api.dictionaryapi.dev/api/v2/entries/en/" . urlencode($word); 22 | $response = file_get_contents($url); 23 | 24 | if ($response) { 25 | $data = json_decode($response); 26 | 27 | if (is_array($data) && count($data) > 0) { 28 | $entry = $data[0]; 29 | echo '
'; 30 | echo '

Word Definition

'; 31 | echo '

Word: ' . $entry->word . '

'; 32 | 33 | if (isset($entry->phonetics) && is_array($entry->phonetics)) { 34 | echo '

Phonetics:

'; 35 | foreach ($entry->phonetics as $phonetic) { 36 | echo '

Pronunciation: ' . $phonetic->text . '

'; 37 | if (!empty($phonetic->audio)) { 38 | echo ''; 42 | } 43 | } 44 | } 45 | 46 | if (isset($entry->meanings) && is_array($entry->meanings)) { 47 | echo '

Meanings:

'; 48 | foreach ($entry->meanings as $meaning) { 49 | echo '

Part of Speech: ' . $meaning->partOfSpeech . '

'; 50 | if (isset($meaning->definitions) && is_array($meaning->definitions)) { 51 | foreach ($meaning->definitions as $definition) { 52 | echo '

Definition: ' . $definition->definition . '

'; 53 | if (isset($definition->example)) { 54 | echo '

Example: ' . $definition->example . '

'; 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | echo '
'; 62 | } else { 63 | echo '
'; 64 | echo '

Word Definition

'; 65 | echo '

No definition found for: ' . $word . '

'; 66 | echo '
'; 67 | } 68 | } else { 69 | echo 'Unable to retrieve word definition.'; 70 | } 71 | } 72 | 73 | function getRandomQuote() { 74 | $url = "https://api.quotable.io/random"; 75 | 76 | $data = json_decode(file_get_contents($url)); 77 | 78 | if (isset($data->content) && isset($data->author)) { 79 | $quote = $data->content; 80 | $author = $data->author; 81 | echo '
'; 82 | echo '

Random Quote

'; 83 | echo '

' . $quote . '

'; 84 | echo '

- ' . $author . '

'; 85 | echo '
'; 86 | } 87 | } 88 | 89 | if (isset($_GET['term'])) { 90 | $searchTerm = $_GET['term']; 91 | 92 | if (strpos($searchTerm, "qrcode:") === 0) { 93 | $urlToEncode = trim(substr($searchTerm, strlen("qrcode:"))); 94 | generateQRCode($urlToEncode); 95 | } elseif (strpos($searchTerm, "datetime:") === 0) { 96 | getCurrentDateTime($searchTerm); 97 | } elseif (strpos($searchTerm, "define:") === 0) { 98 | $wordToDefine = trim(substr($searchTerm, strlen("define:"))); 99 | defineWord($wordToDefine); 100 | } elseif (strpos($searchTerm, "quote:") === 0) { 101 | getRandomQuote(); 102 | } else { 103 | 104 | } 105 | } 106 | 107 | ?> 108 | -------------------------------------------------------------------------------- /provider/video.php: -------------------------------------------------------------------------------- 1 | searchVideos($apiHost, $apiKey); 10 | } 11 | 12 | private function searchVideos($apiHost, $apiKey) 13 | { 14 | $searchTerm = isset($_GET['term']) ? $_GET['term'] : ""; 15 | $searchTermEncoded = urlencode($searchTerm); 16 | 17 | $curl = curl_init(); 18 | 19 | curl_setopt_array($curl, [ 20 | CURLOPT_URL => "https://youtube-search-results.p.rapidapi.com/youtube-search/?q=$searchTermEncoded", 21 | CURLOPT_RETURNTRANSFER => true, 22 | CURLOPT_ENCODING => "", 23 | CURLOPT_MAXREDIRS => 10, 24 | CURLOPT_TIMEOUT => 30, 25 | CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 26 | CURLOPT_CUSTOMREQUEST => "GET", 27 | CURLOPT_HTTPHEADER => [ 28 | "X-RapidAPI-Host: https://youtube-search-results.p.rapidapi.com", 29 | "X-RapidAPI-Key: 4d5fdb515amsh34d74db809e079ep1408b3jsnb23a68d88dc9" 30 | ], 31 | ]); 32 | 33 | $response = curl_exec($curl); 34 | $err = curl_error($curl); 35 | curl_close($curl); 36 | 37 | if ($err) { 38 | $this->videos = false; 39 | } else { 40 | $videos = json_decode($response, true); 41 | 42 | if (isset($videos['items']) && is_array($videos['items'])) { 43 | $this->videos = $videos['items']; 44 | } else { 45 | $this->videos = false; 46 | } 47 | } 48 | } 49 | 50 | public function getResultsHtml() 51 | { 52 | if ($this->videos) { 53 | $resultsHtml = "
"; 54 | foreach ($this->videos as $video) { 55 | $title = $video['title']; 56 | $url = "https://www.youtube.com/watch?v=" . $video['id']; 57 | $thumbnail = $video['bestThumbnail']['url']; 58 | 59 | $resultHtml = "
60 |

61 | 62 | $title 63 | 64 |

65 | $url 66 | Video Thumbnail 67 |
"; 68 | 69 | $resultsHtml .= $resultHtml; 70 | } 71 | $resultsHtml .= "
"; 72 | } else { 73 | $resultsHtml = "No videos found."; 74 | } 75 | 76 | return $resultsHtml; 77 | } 78 | 79 | public function getNumResults() 80 | { 81 | if (is_array($this->videos)) { 82 | return count($this->videos); 83 | } else { 84 | return 0; 85 | } 86 | } 87 | } 88 | ?> 89 | -------------------------------------------------------------------------------- /search.php: -------------------------------------------------------------------------------- 1 | getNumResults($term); 36 | } 37 | 38 | $resultsHtml = $resultsProvider->getResultsHtml($page, $pageSize, $term); 39 | 40 | if ($page > 1) { 41 | echo $resultsHtml; 42 | exit(); 43 | } 44 | ?> 45 | 46 | 47 | 48 | 49 | 50 | 51 | <?= $translations['title'] ?> 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 84 | 85 | 86 | 87 |
88 |
89 |
90 | 91 |
92 |
93 |
94 |
95 | 101 |
102 |
103 |
104 |
105 |
106 |
107 | 108 | 111 |
112 |
113 |
114 | 138 |
139 | 140 |
141 |
142 | 143 | KHOJ AI   144 | 145 | 180 | 181 |
182 | 183 | 237 |
238 | 239 | 240 |
241 | 245 | 246 |

247 | 248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 | 361 | 362 | 363 | 364 | 368 | 369 | 403 | 404 | 466 | 467 | 468 | -------------------------------------------------------------------------------- /settings/index.php: -------------------------------------------------------------------------------- 1 | window.localStorage.clear();'; 7 | header('Location: ../index.php'); 8 | exit; 9 | } 10 | ?> 11 | 12 | 13 | 14 | 15 | 16 | 17 | <?= $translations['settings'] ?> 18 | 19 | 20 | 21 | 22 | 23 |
24 |

25 | 26 |
27 |
28 |

:

29 | 30 |
31 | 32 |
33 |
: 34 | 40 |
41 |
42 |
43 |
44 | 45 |
46 |

47 | 48 |
49 | 50 |
51 | 52 |
53 | 54 |
55 |
56 | 57 | 90 | 91 | -------------------------------------------------------------------------------- /settings/saved.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Saved Results 6 | 52 | 53 | 54 |

Saved Results

55 | 56 |
57 | 58 |
59 | 60 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /spider/auth.php: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /spider/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM sites WHERE url = :url"); 18 | 19 | $query->bindParam(":url", $url); 20 | $query->execute(); 21 | 22 | return $query->rowCount() != 0; 23 | } 24 | 25 | function imageExists($src) 26 | { 27 | global $con; 28 | 29 | $query = $con->prepare("SELECT * FROM images WHERE imageUrl = :src"); 30 | 31 | $query->bindParam(":src", $src); 32 | $query->execute(); 33 | 34 | return $query->rowCount() != 0; 35 | } 36 | 37 | 38 | function insertLink($url, $title, $description, $keywords) 39 | { 40 | global $con; 41 | 42 | $query = $con->prepare("INSERT INTO sites(url, title, description, keywords) 43 | VALUES(:url, :title, :description, :keywords)"); 44 | 45 | $query->bindParam(":url", $url); 46 | $query->bindParam(":title", $title); 47 | $query->bindParam(":description", $description); 48 | $query->bindParam(":keywords", $keywords); 49 | 50 | return $query->execute(); 51 | } 52 | 53 | function insertImage($url, $src, $alt, $title) 54 | { 55 | global $con; 56 | 57 | $query = $con->prepare("INSERT INTO images(siteUrl, imageUrl, alt, title) 58 | VALUES(:siteUrl, :imageUrl, :alt, :title)"); 59 | 60 | $query->bindParam(":siteUrl", $url); 61 | $query->bindParam(":imageUrl", $src); 62 | $query->bindParam(":alt", $alt); 63 | $query->bindParam(":title", $title); 64 | 65 | return $query->execute(); 66 | } 67 | 68 | /* Converts relative link to absolute link */ 69 | function createLink($src, $url) 70 | { 71 | $scheme = parse_url($url)["scheme"]; // http 72 | $host = parse_url($url)["host"]; 73 | 74 | if(substr($src, 0, 2) == "//") 75 | $src = $scheme . ":" . $src; 76 | else if(substr($src, 0, 1) == "/") 77 | $src = $scheme . "://" . $host . $src; 78 | else if(substr($src, 0, 2) == "./") 79 | $src = $scheme . "://" . $host . dirname(parse_url($url)["path"]) . substr($src, 1); 80 | else if(substr($src, 0, 3) == "../") 81 | $src = $scheme . "://" . $host . "/" . $src; 82 | else if(substr($src, 0, 5) != "https" && substr($src, 0, 4) != "http") 83 | $src = $scheme . "://" . $host . "/" . $src; 84 | 85 | return $src; 86 | } 87 | 88 | function getDetails($url) 89 | { 90 | global $alreadyFoundImages; 91 | 92 | $parser = new DomDocumentParser($url); 93 | 94 | $titleArray = $parser->getTitleTags(); 95 | 96 | if(sizeof($titleArray) == 0 || $titleArray->item(0) == NULL) 97 | return; 98 | 99 | //Replace linebreak 100 | $title = $titleArray->item(0)->nodeValue; 101 | $title = str_replace("\n", "", $title); 102 | 103 | //Return if no 104 | if($title == "") 105 | return; 106 | 107 | $description = ""; 108 | $keywords = ""; 109 | 110 | $metasArray = $parser->getMetatags(); 111 | 112 | foreach($metasArray as $meta) 113 | { 114 | if($meta->getAttribute("name") == "description") 115 | $description = $meta->getAttribute("content"); 116 | 117 | if($meta->getAttribute("name") == "keywords") 118 | $keywords = $meta->getAttribute("content"); 119 | } 120 | 121 | $description = str_replace("\n", "", $description); 122 | $keywords = str_replace("\n", "", $keywords); 123 | 124 | if(linkExists($url)) 125 | echo "$url already exists<br>"; 126 | else if(insertLink($url, $title, $description, $keywords)) 127 | echo "SUCCESS: $url<br>"; 128 | else 129 | echo "ERROR: Failed to insert $url<br>"; 130 | 131 | $imageArray = $parser->getImages(); 132 | foreach($imageArray as $image) 133 | { 134 | $src = $image->getAttribute("src"); 135 | $alt = $image->getAttribute("alt"); 136 | $title = $image->getAttribute("title"); 137 | 138 | if(!$title && !$alt) 139 | continue; 140 | 141 | $src = createLink($src, $url); 142 | 143 | if(!in_array($src, $alreadyFoundImages)) 144 | { 145 | $alreadyFoundImages[] = $src; 146 | 147 | if(imageExists($src)) 148 | echo "$src already exists<br>"; 149 | else if(insertImage($url, $src, $alt, $title)) 150 | echo "SUCCESS: $src<br>"; 151 | else 152 | echo "ERROR: Failed to insert $src<br>"; 153 | } 154 | 155 | } 156 | 157 | echo "<b>URL:</b> $url, <b>Title:</b> $title, <b>Description:</b> $description, <b>keywords:</b> $keywords<br>"; //DEBUGGING sites 158 | echo "<b>src:</b> <a href=$src>$src</a>, <b>alt:</b> $alt, <b>title:</b> $title, <b>url:</b> $url<br>"; //DEBUGGING images 159 | } 160 | 161 | function followLinks($url) 162 | { 163 | global $alreadyCrawled; 164 | global $crawling; 165 | 166 | $parser = new DomDocumentParser($url); 167 | 168 | $linkList = $parser->getLinks(); 169 | 170 | 171 | foreach($linkList as $link) 172 | { 173 | $href = $link->getAttribute("href"); 174 | 175 | // Filter hrefs 176 | if(strpos($href, "#") !== false) 177 | continue; 178 | else if(substr($href, 0, 11) == "javascript:") 179 | continue; 180 | 181 | $href = createLink($href, $url); 182 | 183 | if(!in_array($href, $alreadyCrawled)) 184 | { 185 | $alreadyCrawled[] = $href; 186 | $crawling[] = $href; 187 | 188 | getDetails($href); 189 | } 190 | //else return; //DEBUGGING 191 | 192 | echo ($href . "<br>"); //DEBUGGING 193 | } 194 | 195 | array_shift($crawling); 196 | 197 | foreach($crawling as $site) 198 | followLinks($site); 199 | } 200 | ?> 201 | 202 | <!DOCTYPE html> 203 | <html> 204 | <head> 205 | <title>Khoj 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 |
217 | 218 |
219 |
220 | Site logo 221 | 222 | 223 |
224 |

Let us index your website

225 | 226 |
227 |
228 | 229 | 234 |
235 |
236 | 237 |
238 |
239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /spider/login.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Login Page 5 | 6 | 7 |

Login

8 |
9 | 10 |
11 | 12 |
13 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /spider/parser/en.php: -------------------------------------------------------------------------------- 1 | connect_error) { 16 | die("Connection failed: " . $conn->connect_error); 17 | } 18 | 19 | // Handle form submission 20 | if ($_SERVER["REQUEST_METHOD"] == "POST") { 21 | // Get the RSS URL from the form 22 | $rss_url = $_POST["rss_url"]; 23 | 24 | // Set a User-Agent header to mimic a web browser request 25 | $options = stream_context_create([ 26 | 'http' => [ 27 | 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 28 | ], 29 | ]); 30 | 31 | // Fetch the RSS feed 32 | $rss_feed = file_get_contents($rss_url, false, $options); 33 | 34 | // Parse the RSS feed 35 | $xml = simplexml_load_string($rss_feed); 36 | 37 | if ($xml) { 38 | $items = $xml->channel->item; 39 | 40 | foreach ($items as $item) { 41 | $guid = $conn->real_escape_string((string) $item->guid); 42 | $title = $conn->real_escape_string((string) $item->title); 43 | $link = $conn->real_escape_string((string) $item->link); 44 | $pubDate = date('Y-m-d H:i:s', strtotime((string) $item->pubDate)); 45 | 46 | $mediaContent = $item->children('media', true)->content; 47 | $thumbnail_url = $conn->real_escape_string((string) $mediaContent->attributes()->url); 48 | 49 | $description = $conn->real_escape_string((string) $item->description); 50 | 51 | $contentEncoded = $conn->real_escape_string((string) $item->children('content', true)->encoded); 52 | 53 | $sql = "INSERT INTO news_english (guid, title, link, pubDate, thumbnail_url, description, content_encoded) VALUES ('$guid', '$title', '$link', '$pubDate', '$thumbnail_url', '$description', '$contentEncoded')"; 54 | 55 | if ($conn->query($sql) === TRUE) { 56 | echo "Item inserted successfully
"; 57 | } else { 58 | echo "Error: " . $sql . "
" . $conn->error; 59 | } 60 | } 61 | } else { 62 | echo "Failed to parse the RSS feed."; 63 | } 64 | } 65 | 66 | // Close the database connection 67 | $conn->close(); 68 | ?> 69 | 70 | 71 | 72 | English news Parser 73 | 74 | 75 |

English news Parser

76 |
77 | 78 | 79 | 80 |
81 | 82 | 83 | -------------------------------------------------------------------------------- /spider/parser/hi.php: -------------------------------------------------------------------------------- 1 | connect_error) { 15 | die("Connection failed: " . $conn->connect_error); 16 | } 17 | 18 | // Handle form submission 19 | if ($_SERVER["REQUEST_METHOD"] == "POST") { 20 | // Get the RSS URL from the form 21 | $rss_url = $_POST["rss_url"]; 22 | 23 | // Set a User-Agent header to mimic a web browser request 24 | $options = stream_context_create([ 25 | 'http' => [ 26 | 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 27 | ], 28 | ]); 29 | 30 | // Fetch the RSS feed 31 | $rss_feed = file_get_contents($rss_url, false, $options); 32 | 33 | // Parse the RSS feed 34 | $xml = simplexml_load_string($rss_feed); 35 | 36 | if ($xml) { 37 | $items = $xml->channel->item; 38 | 39 | foreach ($items as $item) { 40 | $guid = $conn->real_escape_string((string) $item->guid); 41 | $title = $conn->real_escape_string((string) $item->title); 42 | $link = $conn->real_escape_string((string) $item->link); 43 | $pubDate = date('Y-m-d H:i:s', strtotime((string) $item->pubDate)); 44 | 45 | $mediaContent = $item->children('media', true)->content; 46 | $thumbnail_url = $conn->real_escape_string((string) $mediaContent->attributes()->url); 47 | 48 | $description = $conn->real_escape_string((string) $item->description); 49 | 50 | $contentEncoded = $conn->real_escape_string((string) $item->children('content', true)->encoded); 51 | 52 | $sql = "INSERT INTO news_hindi (guid, title, link, pubDate, thumbnail_url, description, content_encoded) VALUES ('$guid', '$title', '$link', '$pubDate', '$thumbnail_url', '$description', '$contentEncoded')"; 53 | 54 | if ($conn->query($sql) === TRUE) { 55 | echo "Item inserted successfully
"; 56 | } else { 57 | echo "Error: " . $sql . "
" . $conn->error; 58 | } 59 | } 60 | } else { 61 | echo "Failed to parse the RSS feed."; 62 | } 63 | } 64 | 65 | // Close the database connection 66 | $conn->close(); 67 | ?> 68 | 69 | 70 | 71 | Hindi News Parser 72 | 73 | 74 |

Hindi News Parse

75 |
76 | 77 | 78 | 79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /spider/parser/mr.php: -------------------------------------------------------------------------------- 1 | connect_error) { 16 | die("Connection failed: " . $conn->connect_error); 17 | } 18 | 19 | // Handle form submission 20 | if ($_SERVER["REQUEST_METHOD"] == "POST") { 21 | // Get the RSS URL from the form 22 | $rss_url = $_POST["rss_url"]; 23 | 24 | // Set a User-Agent header to mimic a web browser request 25 | $options = stream_context_create([ 26 | 'http' => [ 27 | 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 28 | ], 29 | ]); 30 | 31 | // Fetch the RSS feed 32 | $rss_feed = file_get_contents($rss_url, false, $options); 33 | 34 | // Parse the RSS feed 35 | $xml = simplexml_load_string($rss_feed); 36 | 37 | if ($xml) { 38 | $items = $xml->channel->item; 39 | 40 | foreach ($items as $item) { 41 | $title = $conn->real_escape_string($item->title); 42 | $category = $conn->real_escape_string($item->category); 43 | $pubDate = date('Y-m-d H:i:s', strtotime($item->pubDate)); 44 | 45 | // Fetch the thumbnail_url for each item within the loop 46 | $mediaThumbnail = $item->children('media', true)->thumbnail; 47 | $thumbnail_url = $conn->real_escape_string((string) $mediaThumbnail->attributes()->url); 48 | 49 | $description = $conn->real_escape_string($item->description); 50 | $creator = $conn->real_escape_string($item->children('dc', true)->creator); 51 | 52 | $sql = "INSERT INTO news_marathi (title, category, author, pubDate, thumbnail_url, description, creator) VALUES ('$title', '$category', '$creator', '$pubDate', '$thumbnail_url', '$description', '$creator')"; 53 | 54 | if ($conn->query($sql) === TRUE) { 55 | echo "Item inserted successfully
"; 56 | } else { 57 | echo "Error: " . $sql . "
" . $conn->error; 58 | } 59 | } 60 | } else { 61 | echo "Failed to parse the RSS feed."; 62 | } 63 | } 64 | 65 | // Close the database connection 66 | $conn->close(); 67 | ?> 68 | 69 | 70 | 71 | Marathi news Parser 72 | 73 | 74 |

Marathi news Parser

75 |
76 | 77 | 78 | 79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /spider/parser/parser.php: -------------------------------------------------------------------------------- 1 | array('method'=>"GET", 'header'=>"User-Agent: Khojbot/0.1\n") 10 | ); 11 | $context = stream_context_create($options); 12 | 13 | $this->doc = new DomDocument(); 14 | @$this->doc->loadHTML(file_get_contents($url, false, $context)); 15 | } 16 | 17 | public function getlinks() 18 | { 19 | return $this->doc->getElementsByTagName("a"); 20 | } 21 | 22 | public function getTitleTags() 23 | { 24 | return $this->doc->getElementsByTagName("title"); 25 | } 26 | 27 | public function getMetaTags() 28 | { 29 | return $this->doc->getElementsByTagName("meta"); 30 | } 31 | 32 | public function getImages() 33 | { 34 | return $this->doc->getElementsByTagName("img"); 35 | } 36 | 37 | } 38 | ?> -------------------------------------------------------------------------------- /spider/protected.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/body.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ajinkgupta/khoj-Ai-Search-Engine/67195f74bcbe5fff901afb0f363b1f4efaadee4b/theme/body.php -------------------------------------------------------------------------------- /theme/footer.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ajinkgupta/khoj-Ai-Search-Engine/67195f74bcbe5fff901afb0f363b1f4efaadee4b/theme/footer.php -------------------------------------------------------------------------------- /theme/header.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ajinkgupta/khoj-Ai-Search-Engine/67195f74bcbe5fff901afb0f363b1f4efaadee4b/theme/header.php --------------------------------------------------------------------------------