4 Plugin URI: http://octo.it/yourls-gitweb/
\r
5 Description: Automatically redirect to a Gitweb installation if an appropriate Git object exists.
\r
7 Author: Florian "octo" Forster
\r
8 Author URI: http://octo.it/
\r
12 * yourls -- Gitweb plugin
\r
13 * Copyright (C) 2011 Florian Forster
\r
15 * Permission is hereby granted, free of charge, to any person obtaining a
\r
16 * copy of this software and associated documentation files (the "Software"),
\r
17 * to deal in the Software without restriction, including without limitation
\r
18 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
19 * and/or sell copies of the Software, and to permit persons to whom the
\r
20 * Software is furnished to do so, subject to the following conditions:
\r
22 * The above copyright notice and this permission notice shall be included in
\r
23 * all copies or substantial portions of the Software.
\r
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
31 * DEALINGS IN THE SOFTWARE.
\r
34 * Florian Forster <ff at octo.it>
\r
37 function gitweb_check_repository ($obj, $repo, $dir, $url) /* {{{ */
\r
42 $obj_name = shell_exec ('git --git-dir=' . escapeshellarg ($dir)
\r
43 . ' rev-parse ' . escapeshellarg ($obj)
\r
48 $obj_type = shell_exec ('git --git-dir=' . escapeshellarg ($dir)
\r
49 . ' cat-file -t ' . escapeshellarg ($obj_name)
\r
54 if ($obj_type == 'commit')
\r
56 $to_url = "$url?p=" . urlencode ($repo) . ';a=commitdiff;h=' . urlencode ($obj_name);
\r
57 yourls_redirect ($to_url, /* status = */ 301);
\r
60 elseif ($obj_type == 'tag')
\r
62 $to_url = "$url?p=" . urlencode ($repo) . ';a=tag;h=' . urlencode ($obj_name);
\r
63 yourls_redirect ($to_url, /* status = */ 301);
\r
67 elseif ($obj_type == 'tree')
\r
69 $to_url = "$url?p=" . urlencode ($repo) . ";a=tree;h=" . urlencode ($obj_name);
\r
70 yourls_redirect ($to_url, /* status = */ 301);
\r
73 elseif ($obj_type == 'blob')
\r
75 $to_url = "$url?p=" . urlencode ($repo) . ";a=blob;h=" . urlencode ($obj_name);
\r
76 yourls_redirect ($to_url, /* status = */ 301);
\r
81 error_log ("Gitweb plugin: Object \"$obj_name\" in repository \"$repo\" has unknown type \"$obj_type\".");
\r
84 } /* }}} function gitweb_check_repository */
\r
86 /* This callback function is called when the given keyword was not found in the
\r
87 * database. I'll see if this looks like an object identifier in a Git
\r
88 * repository and, if so, try to locate the object using the local
\r
90 function gitweb_redirect_keyword_not_found ($args) /* {{{ */
\r
92 $keyword = $args[0];
\r
94 if (!preg_match ('/^[0-9a-fA-F]{6,40}$/', $keyword))
\r
97 $base_directory = yourls_get_option ('gitweb_base_directory');
\r
98 if (!$base_directory)
\r
101 $base_url = yourls_get_option ('gitweb_base_url');
\r
105 $dh = opendir ($base_directory);
\r
109 while (($subdir = readdir ($dh)) !== false)
\r
111 /* Ignore all files and directories starting with a dot, including the
\r
112 * special directories "." and "..". */
\r
113 if (substr ($subdir, 0, 1) == '.')
\r
116 $absdir = "$base_directory/$subdir";
\r
117 if (!is_dir ($absdir))
\r
120 /* Ignore repositories which are private (i.e. not exported by the
\r
121 * git-daemon(1). We might leak information if we don't. */
\r
122 if (!file_exists ("$absdir/git-daemon-export-ok"))
\r
125 if (gitweb_check_repository ($keyword, $subdir, $absdir, $base_url))
\r
130 } /* }}} function gitweb_redirect_keyword_not_found */
\r
132 function gitweb_set_base_directory ($dir) /* {{{ */
\r
134 /* Remove trailing slashes. */
\r
135 $dir = preg_replace ('/\/+$/', '', $dir);
\r
137 if (!preg_match ('/^\//', $dir))
\r
139 print ("<p class=\"error\">Not an absolute path: "
\r
140 . htmlspecialchars ($dir)
\r
145 if (!is_dir ($dir))
\r
147 print ("<p class=\"error\">Not a directory: "
\r
148 . htmlspecialchars ($dir)
\r
153 /* Open the directory only to check its permissions. */
\r
154 $dh = opendir ($dir);
\r
157 print ("<p class=\"error\">Unable to open directory.</p>\n");
\r
162 yourls_update_option ('gitweb_base_directory', $dir);
\r
164 } /* }}} function gitweb_set_base_directory */
\r
166 function gitweb_set_base_url ($url) /* {{{ */
\r
168 if (!preg_match ('/https?:\/\//i', $url))
\r
170 print ("<p class=\"error\">This does not look like a valid URL: "
\r
171 . htmlspecialchars ($url)
\r
176 $url = preg_replace ('/\?.*/', '', $url);
\r
178 yourls_update_option ('gitweb_base_url', $url);
\r
180 } /* }}} function gitweb_set_base_directory */
\r
182 function gitweb_show_plugin_page () /* {{{ */
\r
185 <h2>Gitweb Plugin Administration Page</h2>
\r
186 <p>This plugin redirects to a Gitweb installation if a keyword wasn't
\r
187 found in the database, looks like a Git object ID and is found in a
\r
188 local Git repository.</p>
\r
191 if (isset ($_POST['base_directory']))
\r
192 gitweb_set_base_directory ($_POST['base_directory']);
\r
194 if (isset ($_POST['base_url']))
\r
195 gitweb_set_base_url ($_POST['base_url']);
\r
197 $base_directory = yourls_get_option ('gitweb_base_directory');
\r
198 if ($base_directory)
\r
199 $base_directory = htmlspecialchars ($base_directory);
\r
201 $base_url = yourls_get_option ('gitweb_base_url');
\r
203 $base_url = htmlspecialchars ($base_url);
\r
206 <form method="post">
\r
207 <table style="background-color: #cdcdcd; border-spacing: 1px;">
\r
209 <th style="border: 1px solid white; background: #C7E7FF; padding: 4px;"><label for="base_directory">Base directory</label></th>
\r
210 <td style="background-color: white; padding: 4px;"><input type="text" id="base_directory" name="base_directory" value="$base_directory" /></td>
\r
213 <th style="border: 1px solid white; background: #C7E7FF; padding: 4px;"><label for="base_url">Gitweb URL</label></th>
\r
214 <td style="background-color: white; padding: 4px;"><input type="text" id="base_url" name="base_url" value="$base_url" /></td>
\r
217 <td colspan="2" style="border: 1px solid white; background-color: #E3F3FF; text-align: right; padding: 4px;"><input type="submit" value="Update" class="button primary" /></td>
\r
222 } /* }}} function gitweb_show_plugin_page */
\r
224 function gitweb_register_plugin_page () /* {{{ */
\r
226 yourls_register_plugin_page ('gitweb_page', 'Gitweb',
\r
227 'gitweb_show_plugin_page');
\r
228 } /* }}} function gitweb_register_plugin_page */
\r
230 yourls_add_action ('plugins_loaded', 'gitweb_register_plugin_page');
\r
231 yourls_add_action ('redirect_keyword_not_found', 'gitweb_redirect_keyword_not_found');
\r
233 /* vim: set sw=2 sts=2 et fdm=marker : */
\r