Detect text files for unknown file types
[phorkie.git] / README.rst
1 ************************************
2 phorkie - PHP and Git based pastebin
3 ************************************
4 Self-hosted pastebin software written in PHP.
5 Pastes are editable, may have multiple files and are stored in git repositories.
6
7 Project page: http://sourceforge.net/p/phorkie/
8
9 .. contents:: Table of Contents
10
11 ========
12 Features
13 ========
14 - every paste is a git repository
15
16   - repositories can be cloned
17   - clone url can be displayed
18   - remote pastes can be forked (rel="vcs-git" and gist.github.com)
19   - single click forking of forks on different servers to your own
20 - paste editing
21
22   - add new files
23   - delete existing files
24   - replace file with upload
25 - embedding of pastes in your blog (via JavaScript or oEmbed)
26 - multiple files in one paste
27   - option to edit single files in a multi-file paste
28 - syntax highlighting with GeSHi
29 - rST and Markdown rendering
30 - image upload + display
31 - OpenID authentication
32 - external tool support
33
34   - xmllint
35   - php syntax check
36 - history in the sidebar
37
38   - old files can be downloaded easily
39 - search across pastes: description, file names and file content
40
41   - options: quoting, logical and, or, not, partial words
42 - webhook support - get notified when pastes are created, edited or deleted
43 - atom feed for new and updated pastes
44 - notifies remote instances via linkbacks when a paste has been forked
45 - text file detection for unknown file types
46
47
48 ============
49 Installation
50 ============
51
52 .phar
53 =====
54 Download ``phorkie-0.6.1.phar`` and put it in your web server's document root
55 directory.
56
57 No further setup needed.
58
59 .. note:: Only valid if your webserver is configured to let
60    PHP handle ``.phar`` files.
61
62    Unfortunately, no Linux distribution has this activated by default.
63    You can do it yourself, though - see
64    `Enable .phar handling in your web server`__.
65
66 .. warning:: PHP has some bugs in its .phar handling code (e.g. with FPM).
67
68    So currently, the ``.phar`` option is considered experimental.
69
70 __ http://cweiske.de/tagebuch/phar-webserver.htm
71
72
73 Zip package
74 ===========
75 1. Unzip the phorkie release file::
76
77    $ tar xjvf phorkie-0.6.1.tar.bz2
78
79 2. Create the git directories::
80
81    $ mkdir -p www/repos/git www/repos/work
82    $ chmod og+w www/repos/git www/repos/work
83
84 3. Install dependencies_
85
86 4. Copy ``data/config.php.dist`` to ``data/config.php`` and adjust it
87    to your needs::
88
89    $ cp data/config.php.dist data/config.php
90    $ $EDITOR data/config.php
91
92    Look at ``config.default.php`` for values that you may adjust.
93
94 5. Set your web server's document root to ``/path/to/phorkie/www/``
95    Alternatively, you can add a symlink to the ``www`` folder into your
96    web server's existing document root tree (being careful to keep
97    main phorkie folder outside the document root for security purposes)
98    and ensure you set the ``baseurl`` config option appropriately. You
99    must also set the ``RewriteBase`` in the ``.htaccess`` file or adjust
100    the nginx configuration accordingly.
101
102 6. Open http://yourhost/setup in your web browser to see if everything
103    is working fine.
104
105 7. Go to http://yourhost/
106
107 8. If you like phorkie, send a mail to `cweiske+phorkie@cweiske.de`__
108
109 __ mailto:cweiske+phorkie@cweiske.de
110
111
112 Dependencies
113 ============
114 phorkie stands on the shoulders of giants.
115
116 It requires the following programs to be installed
117 on your machine:
118
119 - Git v1.7.5 or later
120 - PHP v5.3.0 or later
121
122   - optionally the ``mbstring`` extension
123 - PEAR v1.9.2 or later
124
125 ::
126
127   $ pear install versioncontrol_git-alpha
128   $ pear install services_libravatar-alpha
129   $ pear install http_request2
130   $ pear install pager
131   $ pear install date_humandiff-alpha
132   $ pear install openid-alpha
133
134   $ pear channel-discover pear.twig-project.org
135   $ pear install twig/Twig
136
137   $ pear channel-discover pear.geshi.org
138   $ pear install geshi/geshi
139
140   $ pear channel-discover zustellzentrum.cweiske.de
141   $ pear install zz/mime_type_plaindetect-alpha
142
143   $ pear channel-discover pear.michelf.ca
144   $ pear install michelf/Markdown
145
146   $ pear channel-discover pear2.php.net
147   $ pear install pear2/pear2_services_linkback-alpha
148
149
150 You can use composer to install all dependencies automatically::
151
152   $ composer install
153
154 Note that the ``.phar`` package already contains all dependencies.
155
156
157 ======
158 Search
159 ======
160
161 phorkie makes use of an Elasticsearch__ installation, if you have one.
162
163 It is used to provide search capabilities and the list of recent pastes.
164
165 Elasticsearch version 2.0 is supported.
166
167 You have to install the `delete-by-query`__ plugin::
168
169     $ cd /usr/share/elasticsearch
170     $ bin/plugin install delete-by-query
171
172 __ http://www.elasticsearch.org/
173 __ https://www.elastic.co/guide/en/elasticsearch/plugins/2.0/plugins-delete-by-query.html
174
175
176 Setup
177 =====
178 Edit ``config.php``, setting the ``elasticsearch`` property to the HTTP URL
179 of the index, e.g. ::
180
181   http://localhost:9200/phorkie/
182
183 You must use a search namespace with Elasticsearch such as ``phorkie/``.
184 Run the index script to import all existing pastes into the index::
185
186   php scripts/index.php
187
188 That's all. Open phorkie in your browser, and you'll notice the search box
189 in the top menu.
190
191
192 Reset
193 =====
194 In case something really went wrong and you need to reset the search
195 index, run the following command::
196
197   $ curl -XDELETE http://localhost:9200/phorkie/
198   {"ok":true,"acknowledged"}
199
200 Phorkie will automatically re-index everything when ``setupcheck`` is enabled
201 in the configuration file.
202
203 You may also manually run the reindexing script with::
204
205   $ php scripts/index.php
206
207
208 =====
209 HowTo
210 =====
211
212 Make git repositories clonable
213 ==============================
214
215 HTTP
216 ----
217 By default, the pastes are clonable via ``http`` as long as the ``repos/git/``
218 directory is within the ``www/`` directory.
219
220 No further setup needed.
221
222
223 git-daemon
224 ----------
225 You may use ``git-daemon`` to provide public ``git://`` clone urls.
226 Install the ``git-daemon-run`` package on Debian/Ubuntu.
227
228 Make the repositories available by symlinking the paste repository
229 directory (``$GLOBALS['phorkie']['cfg']['repos']`` setting) into
230 ``/var/cache/git``, e.g.::
231
232   $ ln -s /home/user/www/paste/repos/git /var/cache/git/paste
233
234 Edit your ``config.php`` and set the ``$GLOBALS['phorkie']['cfg']['git']['public']``
235 setting to ``git://$yourhostname/git/paste/``.
236 The rest will be appended automatically.
237
238
239 You're on your own to setup writable repositories.
240
241
242 Protect your site with OpenID
243 =============================
244 You have the option of enabling OpenID authentication to help secure your
245 pastes on phorkie.
246 Set the ``$GLOBALS['phorkie']['auth']`` values in the
247 ``data/config.php`` file as desired.
248
249 There are two different types of security you can apply.
250 First, you can restrict to one of three ``securityLevels``:
251
252 - completely open (``0``)
253 - protection of write-enabled functions such as add, edit, etc. (``1``)
254 - full site protection (``2``)
255
256 Additionally, you can restrict your site to ``listedUsersOnly``.
257 You will need to add the individual OpenID urls to the
258 ``$GLOBALS['phorkie']['auth']['users']`` variable.
259
260
261 Get information about paste editors
262 ===================================
263 Phorkie stores the user's OpenID or IP address (when not logged in) when
264 a paste is edited.
265 It is possible to get this information for each single commit::
266
267     // IP / OpenID for the latest commit
268     $ git notes --ref=identity show
269     127.0.0.1
270
271     // show IP / OpenID for a given commit
272     $ git notes --ref=identity show 29f82a
273     http://cweiske.de/
274
275
276 Notifications via webhooks
277 ==========================
278 Depending on how you use phorkie, it might be nice to notify some other service
279 when pastes are added or updated.
280 Phorkie contains a simply mechanism to post data to a given URL which
281 you can then use as needed.
282
283 The data are json-encoded POSTed to the URLs contained in the
284 ``$GLOBALS['phorkie']['cfg']['webhooks']`` setting array, with
285 a MIME type of ``application/vnd.phorkie.webhook+json``::
286
287   {
288       'event': 'create',
289       'author': {
290           'name':'Anonymous',
291           'email': 'anonymous@phorkie',
292       },
293       'repository': {
294           'name': 'webhooktest',
295           'url': 'http://example.org/33',
296           'description': 'webhooktest',
297           'owner': {
298               'name': 'Anonymous',
299               'email': 'anonymous@phorkie',
300           }
301       }
302   }
303
304 The event may be ``create``, ``edit`` or ``delete``.
305
306
307 =================
308 Technical details
309 =================
310
311
312 URLs
313 ====
314
315 ``/``
316   Index page.
317 ``/[0-9]+``
318   Display page for paste
319 ``/[0-9]+/edit``
320   Edit the paste
321 ``/[0-9]+/edit/(.+)``
322   Edit a single file of the paste
323 ``/[0-9]+/embed``
324   JavaScript code that embeds the whole paste in a HTML page
325 ``/[0-9]+/embed/(.+)``
326   JavaScript code that embeds a single file in a HTML page
327 ``/[0-9]+/raw/(.+)``
328   Display raw file contents
329 ``/[0-9]+/tool/[a-zA-Z]+/(.+)``
330   Run a tool on the given file
331 ``/[0-9]+/rev/[a-z0-9]+``
332   Show specific revision of the paste
333 ``/[0-9]+/delete``
334   Delete the paste
335 ``/[0-9]+/doap``
336   Show DOAP document for paste
337 ``/[0-9]+/fork``
338   Create a fork of the paste
339 ``/search?q=..(&page=[0-9]+)?``
340   Search for term, with optional page
341 ``/list(/[0-9]+)?``
342   List all pastes, with optional page
343 ``/fork-remote``
344   Fork a remote URL
345 ``/help``
346   Show help page
347 ``/new``
348   Shows form for new paste
349 ``/login``
350   Login page for protecting site
351 ``/setup``
352   Check if everything is setup correctly and all dependencies are installed
353 ``/user``
354   Edit logged-in user information
355
356
357 Internal directory layout
358 =========================
359 ::
360
361   repos/
362     work/
363       1/ - work directory for paste #1
364       2/ - work directory for paste #2
365     git/
366       1.git/ - git repository for paste #1
367         description - Description for the repository
368       2.git/ - git repository for paste #2
369
370 nginx rewrites
371 ==============
372 If you use nginx, place the following lines into your ``server`` block:
373
374 ::
375
376   if (!-e $request_uri) {
377     rewrite ^/([0-9]+)$ /display.php?id=$1;
378     rewrite ^/([0-9]+)/delete$ /delete.php?id=$1;
379     rewrite ^/([0-9]+)/delete/confirm$ /delete.php?id=$1&confirm=1;
380     rewrite ^/([0-9]+)/doap$ /doap.php?id=$1;
381     rewrite ^/([0-9]+)/edit$ /edit.php?id=$1;
382     rewrite ^/([0-9]+)/edit/(.+)$ /edit.php?id=$1&file=$2;
383     rewrite ^/([0-9]+)/embed$ /embed.php?id=$1;
384     rewrite ^/([0-9]+)/embed/(.+)$ /embed.php?id=$1&file=$2;
385     rewrite ^/([0-9]+)/fork$ /fork.php?id=$1;
386     rewrite ^/([0-9]+)/raw/(.+)$ /raw.php?id=$1&file=$2;
387     rewrite ^/([0-9]+)/rev/(.+)$ /revision.php?id=$1&rev=$2;
388     rewrite ^/([0-9]+)/rev-raw/(.+)/(.+)$ /raw.php?id=$1&rev=$2&file=$3;
389     rewrite ^/([0-9]+)/tool/([^/]+)/(.+)$ /tool.php?id=$1&tool=$2&file=$3;
390
391     rewrite ^/fork-remote$ /fork-remote.php;
392     rewrite ^/help$ /help.php;
393     rewrite ^/new$ /new.php;
394
395     rewrite ^/feed/new$ /feed-new.php;
396     rewrite ^/feed/updated$ /feed-updated.php;
397
398     rewrite ^/list$ /list.php;
399     rewrite ^/list/([0-9]+)$ /list.php?page=$1;
400
401     rewrite ^/search$ /search.php;
402     rewrite ^/search/([0-9]+)$ /search.php?page=$1;
403
404     rewrite ^/login$ /login.php;
405     rewrite ^/setup$ /setup.php;
406     rewrite ^/user$ /user.php;
407   }
408
409 Lighttpd rewrites
410 =================
411
412 ::
413
414     url.rewrite-once += (
415         "^/([0-9]+)$" => "/display.php?id=$1",
416         "^/([0-9]+)/delete$" => "/delete.php?id=$1",
417         "^/([0-9]+)/delete/confirm" => "/delete.php?&id=$1&confirm=1",
418         "^/([0-9]+)/doap$" => "/doap.php?id=$1",
419         "^/([0-9]+)/edit$" => "/edit.php?id=$1",
420         "^/([0-9]+)/edit/(.+)" => "/edit.php?id=$1&file=$2",
421         "^/([0-9]+)/embed$" => "/embed.php?id=$1",
422         "^/([0-9]+)/embed/(.+)$" => "/embed.php?id=$1",
423         "^/([0-9]+)/fork$" => "/fork.php?id=$1",
424         "^/([0-9]+)/raw/(.+)$" => "/raw.php?id=$1&file=$2",
425         "^/([0-9]+)/rev/(.+)$" => "/revision.php?id=$1&rev=$2",
426         "^/([0-9]+)/rev-raw/(.+)/(.+)$" => "/raw.php?id=$1&rev=$2&file=$3",
427         "^/([0-9]+)/tool/([^/]+)/(.+)$" => "/tool.php?id=$1&tool=$2&file=$3",
428
429         "^/fork-remote$" => "/fork-remote.php",
430         "^/help$" => "/help.php",
431         "^/new$" => "/new.php",
432
433         "^/feed/new$" => "/feed-new.php",
434         "^/feed/updated$" => "/feed-updated.php",
435
436         "^/list$" => "/list.php",
437         "^/list/([0-9]+)$" => "/list.php?page=$1",
438
439         "^/search$" => "/search.php",
440         "^/search/([0-9]+)$" => "/search.php?page=$1",
441
442         "^/login$" => "/login.php",
443         "^/setup$" => "/setup.php",
444         "^/user$" => "/user.php"
445     )
446
447
448 ===========
449 Development
450 ===========
451
452 Releasing a new version
453 =======================
454
455 #. Update ``ChangeLog``, ``NEWS.rst``, ``build.xml`` and ``README.rst``.
456 #. Update local dependencies::
457
458     $ phing collectdeps
459 #. Build ``.tar.bz2`` and ``.phar`` release files with::
460
461     $ phing zip
462     $ phing phar
463 #. Test.
464 #. Tag the release in git
465 #. Upload release to sourceforge::
466
467     $ phing deploy-sf