├── 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 | Send
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 |
19 |
31 |
32 |
33 |
34 |
35 |
= $translations['heading'] ?>
36 |
37 |
43 |
44 |
45 |
46 |
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 |
= $translations['result_count'] ?>
147 |
148 |
149 |
150 |
153 |
154 |
155 |
156 |
157 |
×
158 |
159 |
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 |
27 |
41 |
42 |
44 |
= $translations['heading'] ?>
45 |
46 |
47 |
48 |
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 |
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 |
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 |
28 |
40 |
41 |
42 |
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 "
";
110 |
111 | // If there are more news items, display the "Load More" button
112 | if (count($news) > $initialItems) {
113 | echo "
";
114 | echo "$translations[load_more] ";
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 |
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 |
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 | Khoj Search
58 |
78 |
79 |
80 |
81 |
87 |
88 |
89 |
90 |
91 |
results found
92 |
93 |
94 |
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 |
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 .= "
";
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 |
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 ' ';
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 '
';
39 | echo '';
40 | echo 'Your browser does not support the audio element.';
41 | 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 |
65 |
$url
66 |
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 |
92 |
104 |
105 |
106 |
112 |
113 |
114 |
138 |
139 |
140 |
141 |
142 |
143 |
KHOJ AI
144 |
145 |
180 |
181 |
182 |
183 |
237 |
238 |
239 |
240 |
241 |
245 |
246 |
= $translations['result_count'] ?>
247 |
248 |
249 |
252 |
253 |
254 |
255 |
361 |
362 |
363 |
364 |
365 |
×
366 |
367 |
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 |
= $translations['settings'] ?>
25 |
26 |
43 |
44 |
45 |
46 |
= $translations['saved'] ?>
47 |
48 |
49 | = $translations['delete_all'] ?>
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 ";
126 | else if(insertLink($url, $title, $description, $keywords))
127 | echo "SUCCESS: $url ";
128 | else
129 | echo "ERROR: Failed to insert $url ";
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 ";
149 | else if(insertImage($url, $src, $alt, $title))
150 | echo "SUCCESS: $src ";
151 | else
152 | echo "ERROR: Failed to insert $src ";
153 | }
154 |
155 | }
156 |
157 | echo "URL: $url, Title: $title, Description: $description, keywords: $keywords "; //DEBUGGING sites
158 | echo "src: $src , alt: $alt, title: $title, url: $url "; //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 . " "); //DEBUGGING
193 | }
194 |
195 | array_shift($crawling);
196 |
197 | foreach($crawling as $site)
198 | followLinks($site);
199 | }
200 | ?>
201 |
202 |
203 |
204 |
205 | Khoj
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
Let us index your website
225 |
226 |
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 |
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 |
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 |
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 |
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
--------------------------------------------------------------------------------